Skip to content

Commit 52a2a67

Browse files
committed
GROOVY-9866, GROOVY-10466
1 parent 32b675c commit 52a2a67

File tree

7 files changed

+108
-30
lines changed

7 files changed

+108
-30
lines changed

base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilationUnit.java

+31-6
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,35 @@ public void call(SourceUnit source, GeneratorContext context,
205205
ev.visitClass(classNode);
206206
}
207207
}, Phases.CONVERSION);
208+
/* GRECLIPSE edit -- GROOVY-9866, GROOVY-10466
208209
addPhaseOperation(resolve, Phases.SEMANTIC_ANALYSIS);
210+
*/
211+
addPhaseOperation(new SourceUnitOperation() {
212+
@Override
213+
public void call(final SourceUnit source) {
214+
try {
215+
resolveVisitor.phase = 1; // resolve head of each class
216+
resolveVisitor.setClassNodeResolver(classNodeResolver);
217+
for (ClassNode classNode : source.getAST().getClasses())
218+
resolveVisitor.startResolving(classNode, source);
219+
} finally {
220+
resolveVisitor.phase = 0;
221+
}
222+
}
223+
}, Phases.SEMANTIC_ANALYSIS);
224+
addPhaseOperation(new SourceUnitOperation() {
225+
@Override
226+
public void call(final SourceUnit source) {
227+
try {
228+
resolveVisitor.phase = 2; // resolve body of each class
229+
for (ClassNode classNode : source.getAST().getClasses())
230+
resolveVisitor.startResolving(classNode, source);
231+
} finally {
232+
resolveVisitor.phase = 0;
233+
}
234+
}
235+
}, Phases.SEMANTIC_ANALYSIS);
236+
// GRECLIPSE end
209237
addPhaseOperation(staticImport, Phases.SEMANTIC_ANALYSIS);
210238
addPhaseOperation(new PrimaryClassNodeOperation() {
211239
@Override
@@ -678,23 +706,20 @@ protected boolean dequeued() throws CompilationFailedException {
678706
return dequeue;
679707
}
680708

681-
/**
682-
* Resolves all types
683-
*/
709+
/* GRECLIPSE edit -- GROOVY-4386, GROOVY-9866, GROOVY-10466, et al.
684710
private final SourceUnitOperation resolve = new SourceUnitOperation() {
685711
public void call(SourceUnit source) throws CompilationFailedException {
686712
List<ClassNode> classes = source.ast.getClasses();
687713
for (ClassNode node : classes) {
688-
/* GRECLIPSE edit -- GROOVY-4386, et al.
689714
VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
690715
scopeVisitor.visitClass(node);
691-
*/
716+
692717
resolveVisitor.setClassNodeResolver(classNodeResolver);
693718
resolveVisitor.startResolving(node, source);
694719
}
695-
696720
}
697721
};
722+
*/
698723

699724
private final PrimaryClassNodeOperation staticImport = new PrimaryClassNodeOperation() {
700725
public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {

base/org.codehaus.groovy25/src/org/codehaus/groovy/control/ResolveVisitor.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
113113
private Set<FieldNode> fieldTypesChecked;
114114
// GRECLIPSE add
115115
private Set<String> resolutionFailed;
116+
int phase; //sub-divide visit
116117
// GRECLIPSE end
117118
private boolean checkingVariableTypeInDeclaration;
118119
private ImportNode currImportNode;
@@ -1546,9 +1547,8 @@ public void visitClass(ClassNode node) {
15461547

15471548
currentClass = node;
15481549
// GRECLIPSE add
1549-
if (commencingResolution()) try {
1550+
if (phase == 2 || commencingResolution()) try {
15501551
// GRECLIPSE end
1551-
15521552
if (node instanceof InnerClassNode) {
15531553
if (Modifier.isStatic(node.getModifiers())) {
15541554
genericParameterNames = new HashMap<GenericsTypeName, GenericsType>();
@@ -1634,7 +1634,7 @@ public void visitClass(ClassNode node) {
16341634
}
16351635
module.setImportsResolved(true);
16361636
}
1637-
1637+
switch (phase) { case 0: case 1: // GROOVY-9866, GROOVY-10466
16381638
ClassNode sn = node.getUnresolvedSuperClass();
16391639
if (sn != null) resolveOrFail(sn, node, true);
16401640

@@ -1657,6 +1657,7 @@ public void visitClass(ClassNode node) {
16571657
}
16581658
}
16591659
}
1660+
case 2:
16601661
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
16611662
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
16621663
InnerClassNode cn = it.next();
@@ -1668,13 +1669,14 @@ public void visitClass(ClassNode node) {
16681669
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
16691670
}
16701671
}
1672+
if (phase == 1) break; // resolve other class headers before members, et al.
16711673
// initialize scopes/variables now that imports and super types are resolved
16721674
new VariableScopeVisitor(source).visitClass(node);
16731675
// GRECLIPSE end
16741676
super.visitClass(node);
1675-
16761677
// GRECLIPSE add
16771678
finishedResolution();
1679+
}
16781680
} finally {
16791681
if (currentClass == node)
16801682
// GRECLIPSE end
@@ -1864,6 +1866,9 @@ private void resolveGenericsHeader(GenericsType[] types, GenericsType rootType,
18641866
if (bounds != null) {
18651867
boolean nameAdded = false;
18661868
for (ClassNode upperBound : bounds) {
1869+
// GRECLIPSE add
1870+
if (upperBound.hasInconsistentHierarchy()) continue;
1871+
// GRECLIPSE end
18671872
if (!isWild) {
18681873
if (!nameAdded && upperBound != null || !resolve(classNode)) {
18691874
if (toDealWithGenerics) {

base/org.codehaus.groovy30/src/org/codehaus/groovy/control/CompilationUnit.java

+25-7
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,29 @@ private void addPhaseOperations() {
205205
GroovyClassVisitor visitor = new EnumVisitor(this, source);
206206
visitor.visitClass(classNode);
207207
}, Phases.CONVERSION);
208-
208+
/* GRECLIPSE edit -- GROOVY-9866, GROOVY-10466
209209
addPhaseOperation(resolve, Phases.SEMANTIC_ANALYSIS);
210-
210+
*/
211+
addPhaseOperation(source -> {
212+
try {
213+
resolveVisitor.phase = 1; // resolve head of each class
214+
resolveVisitor.setClassNodeResolver(classNodeResolver);
215+
for (ClassNode classNode : source.getAST().getClasses())
216+
resolveVisitor.startResolving(classNode, source);
217+
} finally {
218+
resolveVisitor.phase = 0;
219+
}
220+
}, Phases.SEMANTIC_ANALYSIS);
221+
addPhaseOperation(source -> {
222+
try {
223+
resolveVisitor.phase = 2; // resolve body of each class
224+
for (ClassNode classNode : source.getAST().getClasses())
225+
resolveVisitor.startResolving(classNode, source);
226+
} finally {
227+
resolveVisitor.phase = 0;
228+
}
229+
}, Phases.SEMANTIC_ANALYSIS);
230+
// GRECLIPSE end
211231
addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
212232
GroovyClassVisitor visitor = new StaticImportVisitor(classNode, source);
213233
visitor.visitClass(classNode);
@@ -739,19 +759,17 @@ protected boolean dequeued() throws CompilationFailedException {
739759
return dequeue;
740760
}
741761

742-
/**
743-
* Resolves all types.
744-
*/
762+
/* GRECLIPSE edit -- GROOVY-4386, GROOVY-9866, GROOVY-10466, et al.
745763
private final ISourceUnitOperation resolve = (final SourceUnit source) -> {
746764
for (ClassNode classNode : source.getAST().getClasses()) {
747-
/* GRECLIPSE edit -- GROOVY-4386, et al.
748765
GroovyClassVisitor visitor = new VariableScopeVisitor(source);
749766
visitor.visitClass(classNode);
750-
*/
767+
751768
resolveVisitor.setClassNodeResolver(classNodeResolver);
752769
resolveVisitor.startResolving(classNode, source);
753770
}
754771
};
772+
*/
755773

756774
/**
757775
* Runs {@link #classgen()} on a single {@code ClassNode}.

base/org.codehaus.groovy30/src/org/codehaus/groovy/control/ResolveVisitor.java

+9-4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
114114
private Set<FieldNode> fieldTypesChecked;
115115
// GRECLIPSE add
116116
private Set<String> resolutionFailed;
117+
int phase; //sub-divide visit
117118
// GRECLIPSE end
118119
private boolean checkingVariableTypeInDeclaration;
119120
private ImportNode currImportNode;
@@ -1545,9 +1546,8 @@ public void visitClass(final ClassNode node) {
15451546

15461547
currentClass = node;
15471548
// GRECLIPSE add
1548-
if (commencingResolution()) try {
1549+
if (phase == 2 || commencingResolution()) try {
15491550
// GRECLIPSE end
1550-
15511551
if (node instanceof InnerClassNode) {
15521552
if (Modifier.isStatic(node.getModifiers())) {
15531553
genericParameterNames = new HashMap<>();
@@ -1618,7 +1618,7 @@ public void visitClass(final ClassNode node) {
16181618
}
16191619
module.setImportsResolved(true);
16201620
}
1621-
1621+
switch (phase) { case 0: case 1: // GROOVY-9866, GROOVY-10466
16221622
ClassNode sn = node.getUnresolvedSuperClass();
16231623
if (sn != null) {
16241624
resolveOrFail(sn, "", node, true);
@@ -1641,6 +1641,7 @@ public void visitClass(final ClassNode node) {
16411641
}
16421642
}
16431643
// GRECLIPSE add
1644+
case 2:
16441645
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
16451646
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
16461647
InnerClassNode cn = it.next();
@@ -1652,13 +1653,14 @@ public void visitClass(final ClassNode node) {
16521653
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
16531654
}
16541655
}
1656+
if (phase == 1) break; // resolve other class headers before members, et al.
16551657
// initialize scopes/variables now that imports and super types are resolved
16561658
new VariableScopeVisitor(source).visitClass(node);
16571659
// GRECLIPSE end
16581660
super.visitClass(node);
1659-
16601661
// GRECLIPSE add
16611662
finishedResolution();
1663+
}
16621664
} finally {
16631665
if (currentClass == node)
16641666
// GRECLIPSE end
@@ -1807,6 +1809,9 @@ private void resolveGenericsHeader(final GenericsType[] types, final GenericsTyp
18071809
if (bounds != null) {
18081810
boolean nameAdded = false;
18091811
for (ClassNode upperBound : bounds) {
1812+
// GRECLIPSE add
1813+
if (upperBound.hasInconsistentHierarchy()) continue;
1814+
// GRECLIPSE end
18101815
if (!isWild) {
18111816
if (!nameAdded && upperBound != null || !resolve(classNode)) {
18121817
if (toDealWithGenerics) {

base/org.codehaus.groovy40/src/org/codehaus/groovy/control/CompilationUnit.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,34 @@ private void addPhaseOperations() {
205205
GroovyClassVisitor visitor = new EnumVisitor(this, source);
206206
visitor.visitClass(classNode);
207207
}, Phases.CONVERSION);
208-
208+
/* GRECLIPSE edit -- GROOVY-9866, GROOVY-10466
209209
addPhaseOperation(source -> {
210210
resolveVisitor.setClassNodeResolver(classNodeResolver);
211211
for (ClassNode classNode : source.getAST().getClasses()) {
212212
resolveVisitor.startResolving(classNode, source);
213213
}
214214
}, Phases.SEMANTIC_ANALYSIS);
215-
215+
*/
216+
addPhaseOperation(source -> {
217+
try {
218+
resolveVisitor.phase = 1; // resolve head of each class
219+
resolveVisitor.setClassNodeResolver(classNodeResolver);
220+
for (ClassNode classNode : source.getAST().getClasses())
221+
resolveVisitor.startResolving(classNode, source);
222+
} finally {
223+
resolveVisitor.phase = 0;
224+
}
225+
}, Phases.SEMANTIC_ANALYSIS);
226+
addPhaseOperation(source -> {
227+
try {
228+
resolveVisitor.phase = 2; // resolve body of each class
229+
for (ClassNode classNode : source.getAST().getClasses())
230+
resolveVisitor.startResolving(classNode, source);
231+
} finally {
232+
resolveVisitor.phase = 0;
233+
}
234+
}, Phases.SEMANTIC_ANALYSIS);
235+
// GRECLIPSE end
216236
addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
217237
GroovyClassVisitor visitor = new StaticImportVisitor(classNode, source);
218238
visitor.visitClass(classNode);

base/org.codehaus.groovy40/src/org/codehaus/groovy/control/ResolveVisitor.java

+11-6
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
116116
private boolean checkingVariableTypeInDeclaration;
117117
private boolean inClosure, inPropertyExpression;
118118
private boolean isTopLevelProperty = true;
119+
/*package*/ int phase; // sub-divide visit
119120

120121
/**
121122
* A ConstructedNestedClass consists of an outer class and a name part, denoting a
@@ -478,7 +479,6 @@ protected boolean resolveNestedClass(final ClassNode type) {
478479
// GROOVY-4043: for type "X", try "A$X" with each type in the class hierarchy (except for Object)
479480
for (; cn != null && cycleCheck.add(cn) && !isObjectType(cn); cn = cn.getSuperClass()) {
480481
if (setRedirect(type, cn)) return true;
481-
// GROOVY-9866: unresolvable interfaces
482482
}
483483

484484
// Another case we want to check here is if we are in a
@@ -1390,7 +1390,7 @@ public void visitClass(final ClassNode node) {
13901390
ClassNode oldNode = currentClass;
13911391
currentClass = node;
13921392
// GRECLIPSE add
1393-
if (commencingResolution()) try {
1393+
if (phase == 2 || commencingResolution()) try {
13941394
// GRECLIPSE end
13951395
ModuleNode module = node.getModule();
13961396
if (!module.hasImportsResolved()) {
@@ -1451,7 +1451,7 @@ public void visitClass(final ClassNode node) {
14511451
genericParameterNames = new HashMap<>();
14521452
}
14531453
resolveGenericsHeader(node.getGenericsTypes());
1454-
1454+
switch (phase) { case 0: case 1: // GROOVY-9866, GROOVY-10466
14551455
ClassNode sn = node.getUnresolvedSuperClass();
14561456
if (sn != null) {
14571457
resolveOrFail(sn, "", node, true);
@@ -1473,7 +1473,7 @@ public void visitClass(final ClassNode node) {
14731473
}
14741474
}
14751475
}
1476-
1476+
case 2:
14771477
// VariableScopeVisitor visits anon. inner class body inline, so resolve now
14781478
for (Iterator<InnerClassNode> it = node.getInnerClasses(); it.hasNext(); ) {
14791479
InnerClassNode cn = it.next();
@@ -1485,14 +1485,17 @@ public void visitClass(final ClassNode node) {
14851485
resolveOrFail(cn.getUnresolvedSuperClass(false), cn); // GROOVY-9642
14861486
}
14871487
}
1488+
if (phase == 1) break; // resolve other class headers before members, et al.
14881489
// initialize scopes/variables now that imports and super types are resolved
14891490
new VariableScopeVisitor(source).visitClass(node);
14901491

14911492
visitTypeAnnotations(node);
14921493
super.visitClass(node);
1493-
14941494
// GRECLIPSE add
14951495
finishedResolution();
1496+
// GRECLIPSE end
1497+
}
1498+
// GRECLIPSE add
14961499
} finally {
14971500
if (currentClass == node)
14981501
// GRECLIPSE end
@@ -1612,7 +1615,9 @@ private void resolveGenericsHeader(final GenericsType[] types, final GenericsTyp
16121615
boolean nameAdded = false;
16131616
for (ClassNode upperBound : type.getUpperBounds()) {
16141617
if (upperBound == null) continue;
1615-
1618+
// GRECLIPSE add
1619+
if (upperBound.hasInconsistentHierarchy()) continue;
1620+
// GRECLIPSE end
16161621
if (!isWildcardGT) {
16171622
if (!nameAdded || !resolve(typeType)) {
16181623
if (dealWithGenerics) {

base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/JDTResolver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ public void startResolving(ClassNode classNode, SourceUnit sourceUnit) {
193193
nodeCache = new IdentityHashMap<>();
194194
}
195195
try {
196-
unresolvables.put(classNode.getModule().getMainClassName(), new HashSet<>());
196+
unresolvables.computeIfAbsent(classNode.getModule().getMainClassName(), x -> new HashSet<>());
197197
super.startResolving(classNode, sourceUnit);
198198
} catch (AbortResolutionException ignore) {
199199
// probably syntax error(s)

0 commit comments

Comments
 (0)