Tobias Gutzmann - 2008-08-12

for those who are interested, I put an inofficial beta release on my webaccount, you can download it here:
w3.msi.vxu.se/users/tgumsi/files/recoder-0.90beta.zip

It parses the entire JDK sources (almost 8000 source files) and resolves references in about one minute and 10 seconds, on my 3 year old computer. One exception is the file com.sun.jmx.mbeanserver.OpenConverter.java, which seems to be invalid source code. However, javac accepts the file due to a bug. You can read about this here:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6400189

There are plenty of bugfixes, so a release is (eventually) recommended; however, there are also many changes in the API, some of which require client applications to be adapted. I am still working on writing the documentation. The final 0.90 version will be released at the end of August or beginning of September, after I am back from my vacation ;-) It will contain some code cleanup, better documentation, a new webpage, as well as any feedback I get to the beta release taken care of ;-)

Feel free to post further comments here, or add bugs to the bug tracker.

I post some information about the most important changes below. For information on the bugs fixed, please see the Changelog.txt contained in the zip-file.

======================

ArrayType is now a subtype of ClassType. This comes with some implications; consider the following example:

Type t = ...;
if (t instanceof ClassType) {
// do something
} else if (t instanceof ArrayType) {
// do somethings else
}

will now never execute the second if-statement; code needs, unfortunately, be examined and changed manually. Luckily, this is straigt forward - exchange the order of if-statements - and a simple text search on your source code for "instanceof ArrayType" should do the trick. For Recoder, performing the required changes took less than 30 minutes.

On the other hand, unified handling of "regular" ClassTypes and ArrayTypes brings some advantages; for example, the length-field of arrays is now handled just like regular fields, and ArrayLengthReference could be removed entirely from the code. Further, this change was the cleanest way to implement the co-variant return type of the clone() method for arrays: clone() performed on an expression of type String[] returns String[] as of Java5.

=====================

There are a couple of new classes in the recoder.abstraction package.

DummyGetClassMethod

this class is a representation for java.lang.Object.getClass(). The problem is that java.lang.Object.getClass() is final, but the return type is Class<T>, where T is the static type of expr in an invocation expr.getClass();

ErasedType

if querying an Declaration like

List l;

now returns ErasedType instead of the ClassDeclaration list. See erased types in the Java Language Specification for more information.

ErasedMethod, ErasedConstructor, and ErasedField

wrapper for methods, constructors, and fields of an ErasedType.

ParameterizedMethod, ParameterizedConstructor, and ParameterizedField

wrapper for methods, constructors, and fields of a ParameterizedType.

ResolvedGenericMethod

The return types of a generic method invocation, i.e., those that have their own type parameters, are wrapped into

TypeArgument.CapturedTypeArgument

The capture of a (wildcard) type argument. In earlier versions, Recoder (simplified said) performed this mapping when "converting" a TypeArgument to a ClassType:

T<?> -> T<Object>
T<? extends U> -> T<U>
T<? super U> -> T<Object>
T<U> -> T<U>

As of 0.90, Recoder wraps TypeArguments into a CapturedTypeArguments and handles the different wildcard modes appropriately.

=========================

getSupertypes()
e.g., the generic type List<String> has it's erased type List as a supertype. Recoder now returns such types as supertypes. You can get rid of them by calling
List<ClassType> removeErasedTypesFormList(List<? extends ClassType>)
on ProgramModelInfo.