Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
258 changes: 134 additions & 124 deletions src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,15 @@ public void visitField(final FieldNode node) {
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
genericParameterNames = Collections.emptyMap();
}

if (!fieldTypesChecked.contains(node)) {
ClassNode t = node.getOriginType();
resolveOrFail(t, t);
try {
if (!fieldTypesChecked.contains(node)) {
ClassNode t = node.getOriginType();
resolveOrFail(t, t);
}
super.visitField(node);
} finally {
genericParameterNames = oldNames;
}
super.visitField(node);

genericParameterNames = oldNames;
}

@Override
Expand All @@ -287,14 +288,15 @@ public void visitProperty(final PropertyNode node) {
if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
genericParameterNames = Collections.emptyMap();
}
try {
ClassNode t = node.getOriginType();
resolveOrFail(t, t);
fieldTypesChecked.add(node.getField());

ClassNode t = node.getOriginType();
resolveOrFail(t, t);
fieldTypesChecked.add(node.getField());

super.visitProperty(node);

genericParameterNames = oldNames;
super.visitProperty(node);
} finally {
genericParameterNames = oldNames;
}
}

private static boolean canSeeTypeVars(final int mods, final ClassNode node) {
Expand All @@ -303,39 +305,39 @@ private static boolean canSeeTypeVars(final int mods, final ClassNode node) {

@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
MethodNode oldMethod = currentMethod;
VariableScope oldScope = currentScope;
currentScope = node.getVariableScope();
Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
genericParameterNames =
canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())
? new HashMap<>(genericParameterNames) : new HashMap<>();
try {
resolveGenericsHeader(node.getGenericsTypes());

resolveGenericsHeader(node.getGenericsTypes());

{
ClassNode t = node.getReturnType();
resolveOrFail(t, t);
}
for (Parameter p : node.getParameters()) {
p.setInitialExpression(transform(p.getInitialExpression()));
ClassNode t = p.getOriginType();
resolveOrFail(t, t);
visitAnnotations(p);
}
if (node.getExceptions() != null) {
for (ClassNode t : node.getExceptions()) {
{
ClassNode t = node.getReturnType();
resolveOrFail(t, t);
}
}

MethodNode oldCurrentMethod = currentMethod;
currentMethod = node;

super.visitConstructorOrMethod(node, isConstructor);
for (Parameter p : node.getParameters()) {
p.setInitialExpression(transform(p.getInitialExpression()));
ClassNode t = p.getOriginType();
resolveOrFail(t, t);
visitAnnotations(p);
}
if (node.getExceptions() != null) {
for (ClassNode t : node.getExceptions()) {
resolveOrFail(t, t);
}
}

currentMethod = oldCurrentMethod;
genericParameterNames = oldNames;
currentScope = oldScope;
currentMethod = node;
super.visitConstructorOrMethod(node, isConstructor);
} finally {
genericParameterNames = oldNames;
currentMethod = oldMethod;
currentScope = oldScope;
}
}

private void resolveOrFail(final ClassNode type, final ASTNode node) {
Expand Down Expand Up @@ -1249,107 +1251,112 @@ private void checkAnnotationMemberValue(final Expression value) {

@Override
public void visitClass(final ClassNode node) {
ClassNode oldNode = currentClass;
currentClass = node;

ModuleNode module = node.getModule();
if (!module.hasImportsResolved()) {
for (ImportNode importNode : module.getImports()) {
currentImport = importNode;
ClassNode type = importNode.getType();
if (resolve(type, false, false, true)) {
currentImport = null;
continue;
}
currentImport = null;
addError("unable to resolve class " + type.getName(), type);
}
for (ImportNode importNode : module.getStarImports()) {
if (importNode.getLineNumber() > 0) {
ClassNode oldNode = currentClass; currentClass = node;
Map<GenericsTypeName, GenericsType> outerNames = null;
try {
ModuleNode module = node.getModule();
if (!module.hasImportsResolved()) {
for (ImportNode importNode : module.getImports()) {
currentImport = importNode;
String importName = importNode.getPackageName();
importName = importName.substring(0, importName.length()-1);
ClassNode type = ClassHelper.makeWithoutCaching(importName);
if (resolve(type, false, false, true)) {
importNode.setType(type);
try {
ClassNode type = importNode.getType();
if (!resolve(type, false, false, true)) {
addError("unable to resolve class " + type.getName(), type);
}
} finally {
currentImport = null;
}
currentImport = null;
}
}
for (ImportNode importNode : module.getStaticImports().values()) {
ClassNode type = importNode.getType();
if (!resolve(type, true, true, true))
addError("unable to resolve class " + type.getName(), type);
}
for (ImportNode importNode : module.getStaticStarImports().values()) {
ClassNode type = importNode.getType();
if (!resolve(type, true, true, true))
addError("unable to resolve class " + type.getName(), type);
}
for (ImportNode importNode : module.getStarImports()) {
if (importNode.getLineNumber() > 0) {
currentImport = importNode;
try {
String importName = importNode.getPackageName();
importName = importName.substring(0, importName.length()-1);
ClassNode type = ClassHelper.makeWithoutCaching(importName);
if (resolve(type, false, false, true)) {
importNode.setType(type);
}
} finally {
currentImport = null;
}
}
}
for (ImportNode importNode : module.getStaticImports().values()) {
ClassNode type = importNode.getType();
if (!resolve(type, true, true, true))
addError("unable to resolve class " + type.getName(), type);
}
for (ImportNode importNode : module.getStaticStarImports().values()) {
ClassNode type = importNode.getType();
if (!resolve(type, true, true, true))
addError("unable to resolve class " + type.getName(), type);
}

module.setImportsResolved(true);
}
module.setImportsResolved(true);
}

//
//

if (phase < 2) node.putNodeMetaData(AnnotationNode[].class, new LinkedHashSet<>());
if (phase < 2) node.putNodeMetaData(AnnotationNode[].class, new LinkedHashSet<>());

Map<GenericsTypeName, GenericsType> outerNames = null;
if (node instanceof InnerClassNode) {
outerNames = genericParameterNames;
genericParameterNames = new HashMap<>();
if (!Modifier.isStatic(node.getModifiers()))
genericParameterNames.putAll(outerNames); // outer names visible
} else {
genericParameterNames.clear(); // outer class: new generic namespace
}
resolveGenericsHeader(node.getGenericsTypes());
switch (phase) { // GROOVY-9866, GROOVY-10466
case 0:
case 1:
ClassNode sn = node.getUnresolvedSuperClass();
if (sn != null) {
resolveOrFail(sn, "", node, true);
}
for (ClassNode in : node.getInterfaces()) {
resolveOrFail(in, "", node, true);
if (node instanceof InnerClassNode) {
outerNames = genericParameterNames;
genericParameterNames = new HashMap<>();
if (!Modifier.isStatic(node.getModifiers()))
genericParameterNames.putAll(outerNames); // outer names visible
} else {
genericParameterNames.clear(); // outer class: new generic namespace
}
resolveGenericsHeader(node.getGenericsTypes());
switch (phase) { // GROOVY-9866, GROOVY-10466
case 0:
case 1:
ClassNode sn = node.getUnresolvedSuperClass();
if (sn != null) {
resolveOrFail(sn, "", node, true);
}
for (ClassNode in : node.getInterfaces()) {
resolveOrFail(in, "", node, true);
}

if (sn != null) checkCyclicInheritance(node, sn);
for (ClassNode in : node.getInterfaces()) {
checkCyclicInheritance(node, in);
}
case 2:
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
InnerClassNode cn = it.next();
if (cn.isAnonymous()) {
MethodNode enclosingMethod = cn.getEnclosingMethod();
if (enclosingMethod != null) {
resolveGenericsHeader(enclosingMethod.getGenericsTypes()); // GROOVY-6977
if (sn != null) checkCyclicInheritance(node, sn);
for (ClassNode in : node.getInterfaces()) {
checkCyclicInheritance(node, in);
}
case 2:
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
InnerClassNode cn = it.next();
if (cn.isAnonymous()) {
MethodNode enclosingMethod = cn.getEnclosingMethod();
if (enclosingMethod != null) {
resolveGenericsHeader(enclosingMethod.getGenericsTypes()); // GROOVY-6977
}
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
}
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
}
}
if (phase == 1) break; // resolve other class headers before members, et al.
if (phase == 1) break; // resolve other class headers before members, et al.

// initialize scopes/variables now that imports and super types are resolved
new VariableScopeVisitor(source).visitClass(node);
// initialize scopes/variables now that imports and super types are resolved
new VariableScopeVisitor(source).visitClass(node);

visitPackage(node.getPackage());
visitImports(node.getModule());
visitAnnotations(node);
visitPackage(node.getPackage());
visitImports(node.getModule());
visitAnnotations(node);

@SuppressWarnings("unchecked") // grab the collected annotations and stop collecting
var headerAnnotations = (Set<AnnotationNode>) node.putNodeMetaData(AnnotationNode[].class, null);
@SuppressWarnings("unchecked") // grab the collected annotations and stop collecting
var headerAnnotations = (Set<AnnotationNode>) node.putNodeMetaData(AnnotationNode[].class, null);

node.visitContents(this);
visitObjectInitializerStatements(node);
// GROOVY-10750, GROOVY-11179: resolve and inline
headerAnnotations.forEach(this::visitAnnotation);
node.visitContents(this);
visitObjectInitializerStatements(node);
// GROOVY-10750, GROOVY-11179: resolve and inline
headerAnnotations.forEach(this::visitAnnotation);
}
} finally {
if (outerNames != null) genericParameterNames = outerNames;
currentClass = oldNode;
}
if (outerNames != null) genericParameterNames = outerNames;
currentClass = oldNode;
}

private void addFatalError(final String text, final ASTNode node) {
Expand Down Expand Up @@ -1401,8 +1408,11 @@ public void visitForLoop(final ForStatement forLoop) {
public void visitBlockStatement(final BlockStatement block) {
VariableScope oldScope = currentScope;
currentScope = block.getVariableScope();
super.visitBlockStatement(block);
currentScope = oldScope;
try {
super.visitBlockStatement(block);
} finally {
currentScope = oldScope;
}
}

private boolean resolveGenericsTypes(final GenericsType[] types) {
Expand Down
Loading