[Checkers] r2622: modifying visitNewClass on TypeFromTree
Mahmood Ali
mahmood at MIT.EDU
Tue Jun 3 12:45:30 EDT 2008
Hi Telmo,
I haven't read your email thoroughly. I will look at the
implementation in a bit.
Handling NewClassTree in the framework requires extra attention,
especially if the user inserted annotations in the new class tree
expression. In IGJ, I am handling it as part of annotateImplicit. I
realize that it may be different for you.
Can you add a couple of tests for the new functionalities. It will
help us later once we revise the code.
- Mahmood
On Jun 2, 2008, at 6:35 PM, Telmo wrote:
> Hello.
> The current implementation of visitNewClass in TypeFromTree is:
>
> return f.fromTypeTree(node.getIdentifier);
>
>
> as opposed to the implementation of visitMethodInvocation, which is
>
> AnnotatedExecutableType ex = f.methodFromUse(node);
> return ex.getReturnType();
>
>
> I am moving the treatment of polymorphism on constructors from the
> TreePreAnnotator to constructorFromUse on the factory itself;
> conceivably I could move all the functionality away and have one
> less annotator.
>
> Namely, I need to be able to modify the generated object annotation
> from constructorFromUse. However, right now, this is not possible. A
> NewClassTree nct is parsed as follows:
>
> getAnnotatedType(nct) at AnnotatedTypeFactory
> fromExpression(nct) at AnnotatedTypeFactory
> fromTreeWithVisitor(nct) at AnnotatedTypeFactory (private)
> TypeFromExpression.visitNewClass(nct) at TypeFromTree
> fromTypeTree(nct.getIdentifier()) at {Javari}AnnotatedTypeFactory
> ...
> which gets a type result, based on nc.getIdentifier()
> annotateInheritedFromClass(result) at AnnotatedTypeFactory
> ...
>
> As you see, information about the receiver of the
> AnnotatedExecutableType is lost during the factory process, and it
> is impossible to fix it locally on the JavariChecker, other than by
> overriding fromExpression, which would be an ugly hack.
>
> constructorFromUse(node), however, is being called, from
> visitNewClass on BaseTypeVisitor. In other words, it is being used
> to check whether the arguments can be assigned to the parameters,
> but it is not being used to check for the "return value" of a
> constructor, as methodFromUse is.
>
> As non-intuitive as this is, Javari needs this feature, due to the
> polymorphism of new class trees. A possible replacement would be to
> change visitNewClass in TypeFromTree to:
>
> AnnotatedExecutableType ex = f.constructorFromUse(node);
> return ex.getReceiverType();
>
>
> and modify constructorFromUse on AnnotatedTypeFactory to:
>
>
> ExecutableElement ctor = InternalUtils.constructor(tree);
> AnnotatedTypeMirror type = fromTypeTree(tree.getIdentifier());
> annotateImplicit(tree.getIdentifier(), type);
> AnnotatedExecutableType exType = atypes.asMemberOf(type, ctor);
> Map<? extends AnnotatedTypeMirror, AnnotatedTypeMirror>
> receiverTypeMap
> = Collections.singletonMap<exType.getReceiverType(), type);
> return exType.substitute(receiverTypeMap);
>
>
> This doesn't break any of the other tests, and exposes the required
> functionality, by overriding constructorFromUse; namely, writing
> something that looks like
>
> ExecutableElement executableElt = InternalUtils.constructor(tree);
> AnnotatedExecutableType type = (AnnotatedExecutableType)
> fromElement(ExecutableElement);
> AnnotatedTypeMirror receiverType = type.getReceiverType();
> // use the original annotations
> AnnotatedTypeMirror returnType = fromTypeTree(tree.getIdentifier());
> annotateImplicit(tree.getIdentifier(), returnType());
> ...
> <javari polymorphic constructor code>
> ...
>
>
> There is lots of type rewriting being done, which makes the code
> somewhat slower. Also, now JavariAnnotatedTypeFactory must use
> InternalUtils, but that feels justifiable since it is performing a
> somewhat low level operation on the types.
>
> Any better ideas on how to implement this are welcome.
>
> -Telmo
More information about the checkers
mailing list