Groovy Documentation

org.codehaus.groovy.transform.stc
[Java] Class StaticTypeCheckingVisitor

java.lang.Object
  org.codehaus.groovy.ast.CodeVisitorSupport
      org.codehaus.groovy.ast.ClassCodeVisitorSupport
          org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor

public class StaticTypeCheckingVisitor
extends ClassCodeVisitorSupport

The main class code visitor responsible for static type checking. It will perform various inspections like checking assignment types, type inference, ... Eventually, class nodes may be annotated with inferred type information.

Authors:
Cedric Champeau
Jochen Theodorou


Nested Class Summary
protected static interface StaticTypeCheckingVisitor.SignatureCodec

protected static class StaticTypeCheckingVisitor.SignatureCodecFactory

 
Field Summary
static MethodNode CLOSURE_CALL_NO_ARG

static MethodNode CLOSURE_CALL_ONE_ARG

static MethodNode CLOSURE_CALL_VARGS

 
Constructor Summary
StaticTypeCheckingVisitor(SourceUnit source, ClassNode cn, TypeCheckerPluginFactory pluginFactory)

 
Method Summary
protected void addError(java.lang.String msg, ASTNode expr)

protected void addStaticTypeError(java.lang.String msg, ASTNode expr)

protected void addTypeCheckingInfoAnnotation(MethodNode node)

protected void checkForbiddenSpreadArgument(ArgumentListExpression argumentList)

protected boolean existsProperty(PropertyExpression pexp, boolean checkForReadOnly, ClassCodeVisitorSupport visitor)

protected java.util.List findMethod(ClassNode receiver, java.lang.String name, ClassNode... args)

protected MethodNode findMethodOrFail(Expression expr, ClassNode receiver, java.lang.String name, ClassNode... args)

protected java.util.List findMethodsWithGenerated(ClassNode receiver, java.lang.String name)

protected ClassNode getInferredReturnTypeFromWithClosureArgument(Expression callArguments)

In the case of a Object.with { ... } call, this method is supposed to retrieve the inferred closure return type.

protected SourceUnit getSourceUnit()

Sets an alternative error collector.

protected ClassNode getType(ASTNode exp)

protected ClassNode[] getTypeCheckingAnnotations()

protected boolean hasSetter(PropertyExpression pexp)

protected ClassNode inferComponentType(ClassNode containerType, ClassNode indexType)

static ClassNode inferLoopElementType(ClassNode collectionType)

boolean isSkipMode(AnnotatedNode node)

void performSecondPass()

void setErrorCollector(ErrorCollector errorCollector)

void setMethodsToBeVisited(java.util.Set methodsToBeVisited)

protected boolean shouldSkipClassNode(ClassNode node)

Returns the list of type checking annotations class nodes.

protected boolean shouldSkipMethodNode(MethodNode node)

void visitAttributeExpression(AttributeExpression expression)

void visitBinaryExpression(BinaryExpression expression)

void visitBitwiseNegationExpression(BitwiseNegationExpression expression)

void visitCastExpression(CastExpression expression)

void visitClass(ClassNode node)

void visitClassExpression(ClassExpression expression)

void visitClosureExpression(ClosureExpression expression)

void visitConstructorCallExpression(ConstructorCallExpression call)

protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor)

void visitField(FieldNode node)

Given a loop collection type, returns the inferred type of the loop element.

void visitForLoop(ForStatement forLoop)

void visitIfElse(IfStatement ifElse)

void visitMethod(MethodNode node)

void visitMethodCallExpression(MethodCallExpression call)

void visitPostfixExpression(PostfixExpression expression)

void visitPrefixExpression(PrefixExpression expression)

void visitPropertyExpression(PropertyExpression pexp)

void visitRangeExpression(RangeExpression expression)

void visitReturnStatement(ReturnStatement statement)

void visitStaticMethodCallExpression(StaticMethodCallExpression call)

void visitTernaryExpression(TernaryExpression expression)

void visitTryCatchFinally(TryCatchStatement statement)

void visitUnaryMinusExpression(UnaryMinusExpression expression)

void visitUnaryPlusExpression(UnaryPlusExpression expression)

void visitVariableExpression(VariableExpression vexp)

void visitWhileLoop(WhileStatement loop)

 
Methods inherited from class ClassCodeVisitorSupport
visitMethod, visitField, visitProperty, visitConstructor, visitReturnStatement, visitBlockStatement, visitForLoop, visitSwitch, visitWhileLoop, visitClass, visitPackage, visitDoWhileLoop, visitExpressionStatement, visitAnnotations, visitCatchStatement, visitIfElse, visitAssertStatement, visitCaseStatement, visitSynchronizedStatement, visitThrowStatement, visitDeclarationExpression, visitImports, visitBreakStatement, visitContinueStatement, visitTryCatchFinally, visitPropertyExpression, visitConstantExpression, visitListExpression, visitClassExpression, visitBytecodeExpression, visitMethodCallExpression, visitStaticMethodCallExpression, visitConstructorCallExpression, visitBinaryExpression, visitTernaryExpression, visitShortTernaryExpression, visitPostfixExpression, visitPrefixExpression, visitBooleanExpression, visitNotExpression, visitClosureExpression, visitTupleExpression, visitArrayExpression, visitMapExpression, visitMapEntryExpression, visitRangeExpression, visitSpreadExpression, visitSpreadMapExpression, visitMethodPointerExpression, visitUnaryMinusExpression, visitUnaryPlusExpression, visitBitwiseNegationExpression, visitCastExpression, visitVariableExpression, visitAttributeExpression, visitFieldExpression, visitGStringExpression, visitArgumentlistExpression, visitClosureListExpression, wait, wait, wait, equals, toString, hashCode, getClass, notify, notifyAll
 
Methods inherited from class CodeVisitorSupport
visitPropertyExpression, visitConstantExpression, visitReturnStatement, visitListExpression, visitClassExpression, visitBlockStatement, visitForLoop, visitSwitch, visitWhileLoop, visitDoWhileLoop, visitExpressionStatement, visitBytecodeExpression, visitCatchStatement, visitIfElse, visitAssertStatement, visitCaseStatement, visitSynchronizedStatement, visitThrowStatement, visitDeclarationExpression, visitBreakStatement, visitContinueStatement, visitTryCatchFinally, visitMethodCallExpression, visitStaticMethodCallExpression, visitConstructorCallExpression, visitBinaryExpression, visitTernaryExpression, visitShortTernaryExpression, visitPostfixExpression, visitPrefixExpression, visitBooleanExpression, visitNotExpression, visitClosureExpression, visitTupleExpression, visitArrayExpression, visitMapExpression, visitMapEntryExpression, visitRangeExpression, visitSpreadExpression, visitSpreadMapExpression, visitMethodPointerExpression, visitUnaryMinusExpression, visitUnaryPlusExpression, visitBitwiseNegationExpression, visitCastExpression, visitVariableExpression, visitAttributeExpression, visitFieldExpression, visitGStringExpression, visitArgumentlistExpression, visitClosureListExpression, wait, wait, wait, equals, toString, hashCode, getClass, notify, notifyAll
 

Field Detail

CLOSURE_CALL_NO_ARG

public static final MethodNode CLOSURE_CALL_NO_ARG


CLOSURE_CALL_ONE_ARG

public static final MethodNode CLOSURE_CALL_ONE_ARG


CLOSURE_CALL_VARGS

public static final MethodNode CLOSURE_CALL_VARGS


 
Constructor Detail

StaticTypeCheckingVisitor

public StaticTypeCheckingVisitor(SourceUnit source, ClassNode cn, TypeCheckerPluginFactory pluginFactory)


 
Method Detail

addError

} catch (IOException e) {
protected void addError(java.lang.String msg, ASTNode expr)


addStaticTypeError

protected void addStaticTypeError(java.lang.String msg, ASTNode expr)


addTypeCheckingInfoAnnotation

protected void addTypeCheckingInfoAnnotation(MethodNode node)


checkForbiddenSpreadArgument

protected void checkForbiddenSpreadArgument(ArgumentListExpression argumentList)


existsProperty

protected boolean existsProperty(PropertyExpression pexp, boolean checkForReadOnly, ClassCodeVisitorSupport visitor)


findMethod

protected java.util.List findMethod(ClassNode receiver, java.lang.String name, ClassNode... args)


findMethodOrFail

protected MethodNode findMethodOrFail(Expression expr, ClassNode receiver, java.lang.String name, ClassNode... args)


findMethodsWithGenerated

protected java.util.List findMethodsWithGenerated(ClassNode receiver, java.lang.String name)


getInferredReturnTypeFromWithClosureArgument

protected ClassNode getInferredReturnTypeFromWithClosureArgument(Expression callArguments)
In the case of a Object.with { ... } call, this method is supposed to retrieve the inferred closure return type.
Parameters:
callArguments - the argument list from the Object#with(Closure) call, ie. a single closure expression
Returns:
the inferred closure return type or null


getSourceUnit

protected SourceUnit getSourceUnit()
Sets an alternative error collector. This can be useful when you want to run static type checking "silently", for example, without failing if errors are found.
Parameters:
errorCollector - an error collector


getType

protected ClassNode getType(ASTNode exp)


getTypeCheckingAnnotations

protected ClassNode[] getTypeCheckingAnnotations()


hasSetter

protected boolean hasSetter(PropertyExpression pexp)


inferComponentType

protected ClassNode inferComponentType(ClassNode containerType, ClassNode indexType)


inferLoopElementType

public static ClassNode inferLoopElementType(ClassNode collectionType)


isSkipMode

public boolean isSkipMode(AnnotatedNode node)


performSecondPass

public void performSecondPass()


setErrorCollector

public void setErrorCollector(ErrorCollector errorCollector)


setMethodsToBeVisited

public void setMethodsToBeVisited(java.util.Set methodsToBeVisited)


shouldSkipClassNode

protected boolean shouldSkipClassNode(ClassNode node)
Returns the list of type checking annotations class nodes. Subclasses may override this method in order to provide additional classes which must be looked up when checking if a method or a class node should be skipped.

The default implementation returns TypeChecked.

Returns:
array of class nodes


shouldSkipMethodNode

protected boolean shouldSkipMethodNode(MethodNode node)


visitAttributeExpression

public void visitAttributeExpression(AttributeExpression expression)


visitBinaryExpression

// so we use the reversedExpression and get the target method from it
public void visitBinaryExpression(BinaryExpression expression)


visitBitwiseNegationExpression

}
public void visitBitwiseNegationExpression(BitwiseNegationExpression expression)


visitCastExpression

ClassNode rightRedirect = right.redirect();
public void visitCastExpression(CastExpression expression)


visitClass

classNode = node;
public void visitClass(ClassNode node)


visitClassExpression

if (vexp.getName().equals("this")) storeType(vexp, classNode);
public void visitClassExpression(ClassExpression expression)


visitClosureExpression

startMethodInference(node, errorCollector);
public void visitClosureExpression(ClosureExpression expression)


visitConstructorCallExpression

Map typesBeforeVisit = null;
public void visitConstructorCallExpression(ConstructorCallExpression call)


visitConstructorOrMethod

if (node != null) {
protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor)


visitField

componentType = genericsTypes[0].getType();
public void visitField(FieldNode node)
Given a loop collection type, returns the inferred type of the loop element. Used, for example, to infer the element type of a (for e in list) loop.
Parameters:
collectionType - the type of the collection
Returns:
the inferred component type


visitForLoop

@Override
public void visitForLoop(ForStatement forLoop)


visitIfElse

if (exp instanceof VariableExpression && ((VariableExpression) exp).isClosureSharedVariable() && isPrimitiveType(cn)) {
public void visitIfElse(IfStatement ifElse)


visitMethod

public void visitMethod(MethodNode node)


visitMethodCallExpression

// generic return type of the closure declaration
public void visitMethodCallExpression(MethodCallExpression call)


visitPostfixExpression

MethodNode old = this.methodNode;
public void visitPostfixExpression(PostfixExpression expression)


visitPrefixExpression

ClassNode inferred = previousType == null ? type : lowestUpperBound(type, previousType);
public void visitPrefixExpression(PrefixExpression expression)


visitPropertyExpression

if (!existsProperty(expression, true)) {
public void visitPropertyExpression(PropertyExpression pexp)


visitRangeExpression

ClassNode rType = getType(rightExpression);
public void visitRangeExpression(RangeExpression expression)


visitReturnStatement

if (expressions.size() == 1) {
public void visitReturnStatement(ReturnStatement statement)


visitStaticMethodCallExpression

withReceiverList.removeFirst();
public void visitStaticMethodCallExpression(StaticMethodCallExpression call)


visitTernaryExpression

newExpr.setSourcePosition(expr);
public void visitTernaryExpression(TernaryExpression expression)


visitTryCatchFinally

if (!isPrimitiveType(leftRedirect) || !isPrimitiveType(rightRedirect)) {
public void visitTryCatchFinally(TryCatchStatement statement)


visitUnaryMinusExpression

}
public void visitUnaryMinusExpression(UnaryMinusExpression expression)


visitUnaryPlusExpression

MethodNode mn = findMethodOrFail(expression, type, name);
public void visitUnaryPlusExpression(UnaryPlusExpression expression)


visitVariableExpression

}
public void visitVariableExpression(VariableExpression vexp)


visitWhileLoop

String name = type == PLUS_PLUS ? "next" : type == MINUS_MINUS ? "previous" : null;
public void visitWhileLoop(WhileStatement loop)


 

Groovy Documentation