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.
Modifiers | Name | Description |
---|---|---|
static class |
StaticTypeCheckingVisitor.SignatureCodecFactory |
|
protected class |
StaticTypeCheckingVisitor.VariableExpressionTypeMemoizer |
Constructor and description |
---|
StaticTypeCheckingVisitor
(SourceUnit source, ClassNode classNode) |
Type Params | Return Type | Name and description |
---|---|---|
|
protected void |
addAmbiguousErrorMessage(List<MethodNode> foundMethods, String name, ClassNode[] args, Expression expr) |
|
protected void |
addAssignmentError(ClassNode leftType, ClassNode rightType, Expression assignmentExpression) |
|
protected void |
addCategoryMethodCallError(Expression call) |
|
protected void |
addClosureReturnType(ClassNode returnType) |
|
void |
addError(String msg, ASTNode expr) |
|
protected void |
addNoMatchingMethodError(ClassNode receiver, String name, ClassNode[] args, Expression call) |
|
protected void |
addReceivers(List<Receiver<String>> receivers, Collection<Receiver<String>> owners, boolean implicitThis) |
|
protected void |
addStaticTypeError(String msg, ASTNode expr) |
|
void |
addTypeCheckingExtension(TypeCheckingExtension extension) |
|
protected void |
addTypeCheckingInfoAnnotation(MethodNode node) |
|
protected void |
addUnsupportedPreOrPostfixExpressionError(Expression expression) |
|
protected boolean |
areCategoryMethodCalls(List<MethodNode> foundMethods, String name, ClassNode[] args) |
|
protected boolean |
checkCast(ClassNode targetType, Expression source) |
|
protected void |
checkClosureParameters(Expression callArguments, ClassNode receiver) @deprecated this method is unused, replaced with DelegatesTo inference. |
|
protected void |
checkForbiddenSpreadArgument(ArgumentListExpression argumentList) |
|
protected void |
checkGroovyConstructorMap(Expression receiver, ClassNode receiverType, MapExpression mapExpression) |
|
protected void |
checkGroovyStyleConstructor(ClassNode node, ClassNode[] arguments) Checks that a constructor style expression is valid regarding the number of arguments and the argument types. |
|
protected MethodNode |
checkGroovyStyleConstructor(ClassNode node, ClassNode[] arguments, ASTNode source) Checks that a constructor style expression is valid regarding the number of arguments and the argument types. |
|
protected ClassNode |
checkReturnType(ReturnStatement statement) |
|
protected void |
collectAllInterfaceMethodsByName(ClassNode type, String name, List<MethodNode> methods) |
|
protected boolean |
existsProperty(PropertyExpression pexp, boolean checkForReadOnly) |
|
protected boolean |
existsProperty(PropertyExpression pexp, boolean readMode, ClassCodeVisitorSupport visitor) Checks whether a property exists on the receiver, or on any of the possible receiver classes (found in the temporary type information table) |
|
static String |
extractPropertyNameFromMethodName(String prefix, String methodName) Given a method name and a prefix, returns the name of the property that should be looked up, following the java beans rules. |
|
protected Object |
extractTemporaryTypeInfoKey(Expression expression) When instanceof checks are found in the code, we store temporary type information data in the TypeCheckingContext.temporaryIfBranchTypeInformation table. |
|
protected static ClassNode[] |
extractTypesFromParameters(Parameter[] parameters) |
|
protected ClassNode |
findCurrentInstanceOfClass(Expression expr, ClassNode type) A helper method which determines which receiver class should be used in error messages when a field or attribute is not found. |
|
BinaryExpression |
findInstanceOfNotReturnExpression(IfStatement ifElse) Check IfStatement matched pattern : Object var1; if (! |
|
protected List<MethodNode> |
findMethod(ClassNode receiver, String name, ClassNode... args) |
|
protected MethodNode |
findMethodOrFail(Expression expr, ClassNode receiver, String name, ClassNode... args) |
|
protected List<MethodNode> |
findMethodsWithGenerated(ClassNode receiver, String name) This method returns the list of methods named against the supplied parameter that are defined on the specified receiver, but it will also add "non existing" methods that will be generated afterwards by the compiler, for example if a method is using default values and that the specified class node isn't compiled yet. |
|
protected static String |
formatArgumentList(ClassNode[] nodes) |
|
protected ClassNode[] |
getArgumentTypes(ArgumentListExpression args) |
|
protected DelegationMetadata |
getDelegationMetadata(ClosureExpression expression) |
|
protected static ClassNode |
getGroupOperationResultType(ClassNode a, ClassNode b) |
|
protected ClassNode |
getInferredReturnType(ASTNode exp) Returns the inferred return type of a closure or a method, if stored on the AST node. |
|
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 ClassNode |
getOriginalDeclarationType(Expression lhs) |
|
protected ClassNode |
getResultType(ClassNode left, int op, ClassNode right, BinaryExpression expr) |
|
protected SourceUnit |
getSourceUnit() |
|
protected List<ClassNode> |
getTemporaryTypesForExpression(Expression objectExpression) |
|
protected ClassNode |
getType(ASTNode exp) |
|
protected ClassNode[] |
getTypeCheckingAnnotations() Returns array of type checking annotations. |
|
TypeCheckingContext |
getTypeCheckingContext() Returns the current type checking context. |
|
protected static boolean |
hasRHSIncompleteGenericTypeInfo(ClassNode inferredRightExpressionType) |
|
protected StaticTypeCheckingVisitor.SetterInfo |
hasSetter(PropertyExpression pexp) |
|
protected void |
inferClosureParameterTypes(ClassNode receiver, Expression arguments, ClosureExpression expression, Parameter param, MethodNode selectedMethod) This method is responsible for performing type inference on closure argument types whenever code like this is found: foo.collect { it.toUpperCase() } .
|
|
protected ClassNode |
inferComponentType(ClassNode containerType, ClassNode indexType) |
|
protected void |
inferDiamondType(ConstructorCallExpression cce, ClassNode lType) |
|
protected ClassNode |
inferListExpressionType(ListExpression list) |
|
static ClassNode |
inferLoopElementType(ClassNode collectionType) Returns the inferred loop element type given a loop collection type. |
|
protected ClassNode |
inferMapExpressionType(MapExpression map) |
|
protected ClassNode |
inferReturnTypeGenerics(ClassNode receiver, MethodNode method, Expression arguments) If a method call returns a parameterized type, then perform additional inference on the return type, so that the type gets actual type arguments. |
|
protected ClassNode |
inferReturnTypeGenerics(ClassNode receiver, MethodNode method, Expression arguments, GenericsType[] explicitTypeHints) If a method call returns a parameterized type, then perform additional inference on the return type, so that the type gets actual type arguments. |
|
void |
initialize() |
|
protected static boolean |
isClassInnerClassOrEqualTo(ClassNode toBeChecked, ClassNode start) |
|
protected boolean |
isClosureCall(String name, Expression objectExpression, Expression arguments) |
|
protected static boolean |
isNullConstant(Expression expression) |
|
protected boolean |
isSecondPassNeededForControlStructure(Map<VariableExpression, ClassNode> varOrigType, Map<VariableExpression, List<ClassNode>> oldTracker) |
|
boolean |
isSkipMode(AnnotatedNode node) |
|
protected boolean |
isSkippedInnerClass(AnnotatedNode node) Tests if a node is an inner class node, and if it is, then checks if the enclosing method is skipped. |
|
protected List<Receiver<String>> |
makeOwnerList(Expression objectExpression) Given an object expression (a receiver expression), generate the list of potential receiver types. |
|
void |
performSecondPass() |
|
protected Map<VariableExpression, ClassNode> |
popAssignmentTracking(Map<VariableExpression, List<ClassNode>> oldTracker) |
|
protected static String |
prettyPrintMethodList(List<MethodNode> nodes) |
|
protected Map<VariableExpression, List<ClassNode>> |
pushAssignmentTracking() |
|
protected void |
pushInstanceOfTypeInfo(Expression objectOfInstanceOf, Expression typeExpression) Stores information about types when [objectOfInstanceof instanceof typeExpression] is visited. |
|
protected void |
restoreVariableExpressionMetadata(Map<VariableExpression, ListHashMap> typesBeforeVisit) |
|
protected void |
saveVariableExpressionMetadata(Set<VariableExpression> closureSharedExpressions, Map<VariableExpression, ListHashMap> typesBeforeVisit) |
|
void |
setCompilationUnit(CompilationUnit compilationUnit) |
|
void |
setMethodsToBeVisited(Set<MethodNode> methodsToBeVisited) |
|
protected boolean |
shouldSkipClassNode(ClassNode node) |
|
protected boolean |
shouldSkipMethodNode(MethodNode node) |
|
protected void |
silentlyVisitMethodNode(MethodNode directMethodCallCandidate) visit a method call target, to infer the type. |
|
protected void |
startMethodInference(MethodNode node, ErrorCollector collector) |
|
protected ClassNode |
storeInferredReturnType(ASTNode node, ClassNode type) Stores the inferred return type of a closure or a method. |
|
protected void |
storeInferredTypeForPropertyExpression(PropertyExpression pexp, ClassNode flatInferredType) |
|
protected void |
storeTargetMethod(Expression call, MethodNode directMethodCallCandidate) |
|
protected void |
storeType(Expression exp, ClassNode cn) |
|
protected void |
typeCheckAssignment(BinaryExpression assignmentExpression, Expression leftExpression, ClassNode leftExpressionType, Expression rightExpression, ClassNode rightExpressionType) |
|
protected void |
typeCheckClosureCall(Expression arguments, ClassNode[] argumentTypes, Parameter[] parameters) |
|
protected MethodNode |
typeCheckMapConstructor(ConstructorCallExpression call, ClassNode receiver, Expression arguments) |
|
protected boolean |
typeCheckMethodsWithGenericsOrFail(ClassNode receiver, ClassNode[] arguments, MethodNode candidateMethod, Expression location) |
|
void |
visitAttributeExpression(AttributeExpression expression) |
|
void |
visitBinaryExpression(BinaryExpression expression) |
|
void |
visitBitwiseNegationExpression(BitwiseNegationExpression expression) |
|
void |
visitBlockStatement(BlockStatement block) |
|
void |
visitCaseStatement(CaseStatement statement) |
|
void |
visitCastExpression(CastExpression expression) |
|
void |
visitClass(ClassNode node) |
|
void |
visitClassExpression(ClassExpression expression) |
|
void |
visitClosingBlock(BlockStatement block) |
|
void |
visitClosureExpression(ClosureExpression expression) |
|
void |
visitConstructor(ConstructorNode node) |
|
void |
visitConstructorCallExpression(ConstructorCallExpression call) |
|
protected void |
visitConstructorOrMethod(MethodNode node, boolean isConstructor) |
|
void |
visitExpressionStatement(ExpressionStatement statement) |
|
void |
visitField(FieldNode node) |
|
void |
visitForLoop(ForStatement forLoop) |
|
void |
visitIfElse(IfStatement ifElse) |
|
void |
visitInstanceofNot(BinaryExpression be) |
|
void |
visitMethod(MethodNode node) |
|
protected void |
visitMethodCallArguments(ClassNode receiver, ArgumentListExpression arguments, boolean visitClosures, MethodNode selectedMethod) |
|
void |
visitMethodCallExpression(MethodCallExpression call) |
|
void |
visitMethodPointerExpression(MethodPointerExpression expression) |
|
void |
visitNotExpression(NotExpression expression) |
|
void |
visitPostfixExpression(PostfixExpression expression) |
|
void |
visitPrefixExpression(PrefixExpression expression) |
|
void |
visitProperty(PropertyNode node) |
|
void |
visitPropertyExpression(PropertyExpression pexp) |
|
void |
visitRangeExpression(RangeExpression expression) |
|
void |
visitReturnStatement(ReturnStatement statement) |
|
void |
visitStaticMethodCallExpression(StaticMethodCallExpression call) |
|
void |
visitSwitch(SwitchStatement statement) |
|
void |
visitTernaryExpression(TernaryExpression expression) |
|
void |
visitTryCatchFinally(TryCatchStatement statement) |
|
void |
visitUnaryMinusExpression(UnaryMinusExpression expression) |
|
void |
visitUnaryPlusExpression(UnaryPlusExpression expression) |
|
void |
visitVariableExpression(VariableExpression vexp) |
|
void |
visitWhileLoop(WhileStatement loop) |
|
protected static ClassNode |
wrapTypeIfNecessary(ClassNode type) Returns a wrapped type if, and only if, the provided class node is a primitive type. |
Checks that a constructor style expression is valid regarding the number of arguments and the argument types.
node
- the class node for which we will try to find a matching constructorarguments
- the constructor argumentsChecks that a constructor style expression is valid regarding the number of arguments and the argument types.
node
- the class node for which we will try to find a matching constructorarguments
- the constructor argumentsChecks whether a property exists on the receiver, or on any of the possible receiver classes (found in the temporary type information table)
pexp
- a property expressionreadMode
- if true, look for property read, else for property setvisitor
- if not null, when the property node is found, visit it with the provided visitorGiven a method name and a prefix, returns the name of the property that should be looked up, following the java beans rules. For example, "getName" would return "name", while "getFullName" would return "fullName". If the prefix is not found, returns null.
prefix
- the method name prefix ("get", "is", "set", ...)methodName
- the method nameWhen instanceof checks are found in the code, we store temporary type information data in the TypeCheckingContext.temporaryIfBranchTypeInformation table. This method computes the key which must be used to store this type info.
expression
- the expression for which to compute the keyA helper method which determines which receiver class should be used in error messages when a field or attribute is not found. The returned type class depends on whether we have temporary type information available (due to instanceof checks) and whether there is a single candidate in that case.
expr
- the expression for which an unknown field has been foundtype
- the type of the expression (used as fallback type)Check IfStatement matched pattern : Object var1; if (!(var1 instanceOf Runnable)){ return } // Here var1 instance of Runnable
Return expression , which contains instanceOf (without not) Return null, if not found
This method returns the list of methods named against the supplied parameter that are defined on the specified receiver, but it will also add "non existing" methods that will be generated afterwards by the compiler, for example if a method is using default values and that the specified class node isn't compiled yet.
receiver
- the receiver where to find methodsname
- the name of the methods to returnReturns the inferred return type of a closure or a method, if stored on the AST node. This method doesn't perform any type inference by itself.
exp
- a ClosureExpression or MethodNodeIn the case of a Object.with { ... } call, this method is supposed to retrieve the inferred closure return type.
callArguments
- the argument list from the Object#with(Closure) call, ie. a single closure expressionReturns array of type checking annotations. Subclasses may override this method in order to provide additional types which must be looked up when checking if a method or a class node should be skipped.
The default implementation returns TypeChecked.
Returns the current type checking context. The context is used internally by the type checker during type checking to store various state data.
This method is responsible for performing type inference on closure argument types whenever code like this is
found: foo.collect { it.toUpperCase() }
.
In this case, the type checker tries to find if the collect
method has its Closure argument
annotated with ClosureParams. If yes, then additional type inference can be performed
and the type of it
may be inferred.
expression
- a closure expression for which the argument types should be inferredparam
- the parameter where to look for a ClosureParams annotation.selectedMethod
- the method accepting a closure Returns the inferred loop element type given a loop collection type. Used,
for example, to infer the element type of a for (e in list)
loop.
collectionType
- the type of the collection If a method call returns a parameterized type, then perform additional
inference on the return type, so that the type gets actual type arguments.
For example, the method Arrays.asList(T...)
is parameterized with
T
, which can be deduced type arguments or call arguments.
method
- the method nodearguments
- the method call argumentsreceiver
- the object expression type If a method call returns a parameterized type, then perform additional
inference on the return type, so that the type gets actual type arguments.
For example, the method Arrays.asList(T...)
is parameterized with
T
, which can be deduced type arguments or call arguments.
method
- the method nodearguments
- the method call argumentsreceiver
- the object expression typeexplicitTypeHints
- type arguments (optional), for example Collections.<String>emptyList()
Tests if a node is an inner class node, and if it is, then checks if the enclosing method is skipped.
Given an object expression (a receiver expression), generate the list of potential receiver types.
objectExpression
- the receiver expressionStores information about types when [objectOfInstanceof instanceof typeExpression] is visited.
objectOfInstanceOf
- the expression which must be checked against instanceoftypeExpression
- the expression which represents the target typevisit a method call target, to infer the type. Don't report errors right away, that will be done by a later visitMethod call
Stores the inferred return type of a closure or a method. We are using a separate key to store inferred return type because the inferred type of a closure is Closure, which is different from the inferred type of the code of the closure.
node
- a ClosureExpression or a MethodNodetype
- the inferred return type of the codeReturns a wrapped type if, and only if, the provided class node is a primitive type. This method differs from ClassHelper#getWrapper(org.codehaus.groovy.ast.ClassNode) as it will return the same instance if the provided type is not a generic type.
Copyright © 2003-2021 The Apache Software Foundation. All rights reserved.