Detecting Invalid Messages within a Method Definition

Detecting Invalid Messages within a Method Definition

Authors:


Motivation

Part of the power of Smalltalk is its dynamic binding characteristic. The programmer does not need to declare the classes of objects referenced in method definitions. This capability enhances reusability and accelerates proto-typing. Unfortunately, the tradeoff is that Smalltalk applications are more prone to run-time errors. Because the Smalltalk compiler does not check the validity of messages sent to objects within a method definition, errors such as sending undefined or misspelled messages can not be caught during compilation. While not all mistakes can be trapped, many can be caught by inspecting of the source code.

We have implemented a Smalltalk class to inspect the source string of method definitions to look for undefined and misspelled selectors, and to deduce the possible set of classes that referenced objects could belong to.

Message Validation

Each method definition generally contain the following objects:

The first step in validating messages within a method definition is parsing. We must be able to identify each object and the messages being sent to them. This is most easily done for self and super because we already know the classes they belong to. For other objects, more advanced string parsing techniques are necessary. After parsing we stored our parsed messages in a dictionary where the key is the name of the object variable and the value is a collection of messages sent to the object variables within the method.

The next step is to go through the dictionary one object variable at a time. For each message sent to the object variable, we first check to see that all the messages sent to the object are defined. We remove the undefined messages from the collection and print the error to the transcript. For each of the messages remaining in the collection, we find the set of possible classes that can understand the message, one set for each message. After having generated all the sets, we find the intersection. The set of classes in the intersection shows the possible classes the object could belong to. If the intersection is empty, then the object cannot belong to any defined class. We print the class in the intersection to the transcript and warn of any empty intersections.

The implementation is simplified for self and super since we already know the classes they belong to. All that we need to do is to make sure that all the messages sent to self or super are understood by their respective classes.

Examples

We now provide some common mistakes found in method definitions. Smalltalk compilers overlook these mistakes during compilation thereby suppressing their malfeasance until run-time. We will show how our validation technique would trap these errors using the source string of method definitions.

Suppose that we have a class called Person with two methods defined, sleep and walk, and we would like to define a third method called sleepWalking as follows

sleepWalking
 self sleep
 self walk.

The Smalltalk compiler would compile this method without any complaints. If we then pass this method through the validation process, the transcript would show the following error messages

ERROR:  Method sleepWalking in Class: Person has the following problems

***Messages not understood by any class of objects!***
 self

If we recheck the method definition, we would observe that we neglected to put a period after sleep, which leads the validation procedure to treat self as a single method being sent to self sleep.

Besides missing periods, another common problem is misspelling of selectors. Suppose we typed the following to define sleepWalking

sleepWalking
 self sleeep.
 self walk.

Again, Smalltalk would compile the method without detecting any problems, but the validation process would generate the following error messages in the transcript

ERROR:  Method sleepWalking in Class: Person has the following problems

***Messages not understood by any class of objects!***
sleeep

***Messages not understood by self.***
sleeep

We now provide an example where the validation process deduces a possible set of classes that a variable can belong to based on the messages it receives. Suppose we have a class with the following method definition

drawThings: anArgument
 anArgument black.
 anArgument circle: 5.
 anArgument white.
 anArgument dragon: 10.

The validation checker collects the selectors #(black circle: white dragon:) and prints a collection of classes that can understand this set of selectors to the transcript as in the following

***The possible classes for variable named: anArgument***
 Pen
 RecordingPen