[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