4th International Conference on Principles and Practices ... - MADOC
4th International Conference on Principles and Practices ... - MADOC
4th International Conference on Principles and Practices ... - MADOC
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
5. IMPLEMENTATION<br />
In order to present a proof of c<strong>on</strong>cept, we have integrated<br />
the type inference system in a Java compiler. The compiler<br />
itself has been implemented in Java by using the tools JLex<br />
[2] <strong>and</strong> jay [12].<br />
In its analysis phase the compiler parses a Java program<br />
<strong>and</strong> creates an Abstract Syntax Tree (subsequently called<br />
AST ). This AST forms, together with some other basic data<br />
structures, the input data for the Type Inference Algorithm<br />
(subsequently called TIA) described in secti<strong>on</strong> 4. The TIA<br />
calculates the missing type annotati<strong>on</strong>s <strong>and</strong> performs a general<br />
type checking. In doing so, it replaces the comm<strong>on</strong><br />
semantic check.<br />
5.1 Basic Data Structures<br />
5.1.1 TypePlaceholder<br />
All the types of the Java program to be compiled are represented<br />
in the AST by instances of subclasses of the abstract<br />
class Type. In order to allow programmers to omit<br />
type annotati<strong>on</strong>s for method declarati<strong>on</strong>s <strong>and</strong> local variable<br />
declarati<strong>on</strong>s, we have to extend the type hierarchy by introducing<br />
another subclass of Type.<br />
This subclass is an auxiliary data structure for the TIA. Its<br />
instances act as placeholders for the individual declarati<strong>on</strong><br />
types. The class is therefore called TypePlaceholder.<br />
5.1.2 TypeAssumpti<strong>on</strong><br />
The implementati<strong>on</strong> of the type assumpti<strong>on</strong>s described in<br />
secti<strong>on</strong> 4 is realized by the abstract class TypeAssumpti<strong>on</strong>.<br />
This class is, besides the AST, the main data structure for<br />
the TIA. It basically maps an identifier <strong>on</strong>to an assumed<br />
type by storing a String instance <strong>and</strong> a Type instance.<br />
At the beginning of the TIA an initial set of TypeAssumpti<strong>on</strong><br />
instances is created for all field declarati<strong>on</strong>s (field variables<br />
<strong>and</strong> methods). During the processing of the TIA when<br />
more <strong>and</strong> more knowledge about the types is gained, this set<br />
is extended by adding new TypeAssumpti<strong>on</strong> instances or by<br />
modifying old <strong>on</strong>es.<br />
5.1.3 Substituti<strong>on</strong><br />
While TypeAssumpti<strong>on</strong> is the implementati<strong>on</strong> for mapping<br />
an identifier <strong>on</strong>to a type, the class Substituti<strong>on</strong> maps<br />
a type placeholder <strong>on</strong>to a calculated type. A Substituti<strong>on</strong><br />
instance stores a TypePlaceholder reference <strong>and</strong> the corresp<strong>on</strong>ding<br />
Type instance which the placeholder will be replaced<br />
with. Normally for each unifier provided by the unificati<strong>on</strong><br />
algorithm (see secti<strong>on</strong> 3) a Substituti<strong>on</strong> instance is<br />
created.<br />
Through the method Substituti<strong>on</strong>.execute() the type replacement<br />
for this particular placeholder in the AST can be<br />
invoked (see secti<strong>on</strong> 5.2).<br />
5.2 Substituti<strong>on</strong> Based Approach<br />
The TIA theoretically described in secti<strong>on</strong> 4 follows an<br />
approach which is mainly based <strong>on</strong> type assumpti<strong>on</strong>s. The<br />
algorithm cyclically collects type informati<strong>on</strong> <strong>and</strong> unificati<strong>on</strong><br />
results in order to extend <strong>and</strong> specify existing sets of<br />
type assumpti<strong>on</strong>s.<br />
Type substituti<strong>on</strong>s however play a minor role in this approach<br />
<strong>and</strong> are <strong>on</strong>ly used as an auxiliary means. The unifiers<br />
provided by the unificati<strong>on</strong> algorithm are usually discarded<br />
after their type substituti<strong>on</strong> has been applied <strong>on</strong> the sets of<br />
type assumpti<strong>on</strong>s.<br />
The TIA’s output data structure c<strong>on</strong>sists of multiple sets<br />
of type assumpti<strong>on</strong>s which represent a theoretical image of<br />
the Java program’s type c<strong>on</strong>figurati<strong>on</strong>. Type unifiers or type<br />
substituti<strong>on</strong>s are not part of the output data structure.<br />
This assumpti<strong>on</strong> based approach is very difficult to implement<br />
as such a set of type assumpti<strong>on</strong>s as a whole cannot be<br />
applied to the AST. The type informati<strong>on</strong> must be broken<br />
down into small, executable instructi<strong>on</strong>s. These instructi<strong>on</strong>s<br />
are identical to the type substituti<strong>on</strong>s, though. For the implementati<strong>on</strong><br />
it is crucial to add all type substituti<strong>on</strong>s as<br />
Substituti<strong>on</strong> instances to the TIA’s output data!<br />
The implementati<strong>on</strong> still uses, according to the TIA’s<br />
specificati<strong>on</strong>, type assumpti<strong>on</strong>s for calculating types, but<br />
in terms of modifying the AST, type substituti<strong>on</strong>s are more<br />
important.<br />
Therefore the implemented TIA returns a data structure<br />
c<strong>on</strong>sisting of multiple tuples of TypeAssumpti<strong>on</strong> sets <strong>and</strong><br />
Substituti<strong>on</strong> sets. Each tuple represents a possible type c<strong>on</strong>figurati<strong>on</strong><br />
for the Java program.<br />
5.3 Applying the Output Data<br />
The questi<strong>on</strong> facing our implementati<strong>on</strong> is, how to apply<br />
such a set of type substituti<strong>on</strong>s returned by the TIA to the<br />
AST.<br />
The most obvious soluti<strong>on</strong> would be to use the set of type<br />
substituti<strong>on</strong>s as input data for a sec<strong>on</strong>d algorithm which<br />
is resp<strong>on</strong>sible for applying them to the AST. C<strong>on</strong>sidering<br />
that the whole AST would have to be traversed again, the<br />
performance of this soluti<strong>on</strong> would not be very good.<br />
Therefore we choose a totally different approach which<br />
is based <strong>on</strong> the Observer Design Pattern [7]. According to<br />
this design pattern, many observers (also called listeners)<br />
register themselves at an object they are interested in, so<br />
that they can be notified about its state changes.<br />
In our case the observers are all the AST comp<strong>on</strong>ents<br />
which store a TypePlaceholder object. Such a comp<strong>on</strong>ent<br />
registers itself as an observer at the TypePlaceholder whose<br />
state changes it is interested in. The state changes are<br />
the type replacements <strong>and</strong> substituti<strong>on</strong>s respectively. Such<br />
an observer is represented by the interface ITypeReplacementListener<br />
<strong>and</strong> is notified by a method call to its interface<br />
method replaceType(ReplaceTypeEvent e). The observer can<br />
then replace its TypePlaceholder with the new type it receives<br />
via the ReplaceTypeEvent.<br />
Each TypePlaceholder stores its ITypeReplacementListeners<br />
in a Vector called m ReplacementListeners <strong>and</strong> notifies<br />
all registered observers when the method fireReplaceType-<br />
Event() is called (see figure 4).<br />
As all observers are stored in a field variable of TypePlaceholder,<br />
it is important that all observers who are interested<br />
in a type placeholder A register at the same TypePlaceholder<br />
instance representing A. This means that within the AST<br />
there must not be more than <strong>on</strong>e instance for the type placeholder<br />
A.<br />
In order to achieve this, we prohibit the creati<strong>on</strong> of Type-<br />
Placeholder objects by defining its c<strong>on</strong>structor private. Instead<br />
we provide the static Factory Method [7] TypePlaceholder.fresh()<br />
which creates a new TypePlaceholder object<br />
<strong>and</strong> stores it in a central registry. An existing TypePlaceholder<br />
can be retrieved from the registry by the static method<br />
TypePlaceholder.getInstance(String name).<br />
So the following happens after the TIA has finished. The<br />
180