Visitor to resolve types and convert VariableExpression to ClassExpressions if needed. The ResolveVisitor will try to find the Class for a ClassExpression and prints an error if it fails to do so. Constructions like C[], foo as C, (C) foo will force creation of a ClassExpression for C Note: the
| 95 | * Note: the method to start the resolving is {@link #startResolving(ClassNode,SourceUnit)}. |
| 96 | */ |
| 97 | public class ResolveVisitor extends ClassCodeExpressionTransformer { |
| 98 | // note: BigInteger and BigDecimal are also imported by default |
| 99 | // `java.util` is used much frequently, so place it before `java.io`, et al. |
| 100 | /** |
| 101 | * Default package imports available to Groovy source. |
| 102 | */ |
| 103 | public static final String[] DEFAULT_IMPORTS = {"java.lang.", "java.util.", "java.io.", "java.net.", "java.time.", "groovy.lang.", "groovy.util."}; |
| 104 | /** |
| 105 | * Shared empty array constant for import-prefix lookups. |
| 106 | */ |
| 107 | public static final String[] EMPTY_STRING_ARRAY = {}; |
| 108 | /** |
| 109 | * Placeholder name used for wildcard generic arguments. |
| 110 | */ |
| 111 | public static final String QUESTION_MARK = "?"; |
| 112 | |
| 113 | private final CompilationUnit compilationUnit; |
| 114 | private ClassNodeResolver classNodeResolver; |
| 115 | private SourceUnit source; |
| 116 | private ClassNode currentClass; |
| 117 | private ImportNode currentImport; |
| 118 | private MethodNode currentMethod; |
| 119 | private VariableScope currentScope; |
| 120 | |
| 121 | private Map<GenericsTypeName, GenericsType> genericParameterNames = new HashMap<>(); |
| 122 | private final Set<FieldNode> fieldTypesChecked = new HashSet<>(); |
| 123 | private boolean checkingVariableTypeInDeclaration; |
| 124 | private boolean inClosure, inPropertyExpression; |
| 125 | private boolean isTopLevelProperty = true; |
| 126 | /*package*/ int phase; // sub-divide visit |
| 127 | |
| 128 | /** |
| 129 | * A ConstructedNestedClass consists of an outer class and a name part, denoting a |
| 130 | * nested class with an unknown number of levels down. This allows resolve tests to |
| 131 | * skip this node for further inner class searches and combinations with imports, since |
| 132 | * the outer class we know is already resolved. |
| 133 | */ |
| 134 | private static class ConstructedNestedClass extends ClassNode { |
| 135 | final ClassNode knownEnclosingType; |
| 136 | |
| 137 | public ConstructedNestedClass(final ClassNode outer, final String inner) { |
| 138 | super(outer.getName() + "$" + inner.replace('.', '$'), Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE); |
| 139 | this.knownEnclosingType = outer; |
| 140 | this.isPrimaryNode = false; |
| 141 | } |
| 142 | |
| 143 | @Override |
| 144 | public String getUnresolvedName() { |
| 145 | // outer class (aka knownEnclosingType) may have aliased name that should be reflected here too |
| 146 | return super.getUnresolvedName().replace(knownEnclosingType.getName(), knownEnclosingType.getUnresolvedName()); |
| 147 | } |
| 148 | |
| 149 | @Override |
| 150 | public boolean hasPackageName() { |
| 151 | if (redirect() != this) return super.hasPackageName(); |
| 152 | return knownEnclosingType.hasPackageName(); |
| 153 | } |
| 154 |
nothing calls this directly
no test coverage detected