From 242ef15ad21514f01b91acfee8ee5c1002380346 Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Sun, 13 Sep 2020 15:30:48 -0500 Subject: [PATCH] Fix for #1159: provide outer class link for inner type built from Class --- .../org/codehaus/groovy/ast/ClassHelper.java | 19 ++++++++++---- .../org/codehaus/groovy/ast/ClassNode.java | 10 ++++++- .../groovy/ast/expr/ClassExpression.java | 4 +-- .../trait/SuperCallTraitTransformer.java | 2 +- .../org/codehaus/groovy/ast/ClassHelper.java | 19 ++++++++++---- .../org/codehaus/groovy/ast/ClassNode.java | 10 ++++++- .../groovy/ast/expr/ClassExpression.java | 4 +-- .../trait/SuperCallTraitTransformer.java | 2 +- .../org/codehaus/groovy/ast/ClassHelper.java | 17 +++++++++--- .../org/codehaus/groovy/ast/ClassNode.java | 10 ++++++- .../groovy/ast/expr/ClassExpression.java | 4 +-- .../trait/SuperCallTraitTransformer.java | 6 ++--- .../test/ui/SemanticHighlightingTests.groovy | 26 +++++++++++++++++++ ...emanticHighlightingReferenceRequestor.java | 2 +- 14 files changed, 107 insertions(+), 28 deletions(-) diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassHelper.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassHelper.java index 09925a8efb..9821747a52 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassHelper.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassHelper.java @@ -145,17 +145,26 @@ public class ClassHelper { public static final String OBJECT = "java.lang.Object"; public static ClassNode makeCached(Class c) { - final SoftReference classNodeSoftReference = ClassHelperCache.classCache.get(c); ClassNode classNode; + final SoftReference classNodeSoftReference = ClassHelperCache.classCache.get(c); if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) { - // GRECLIPSE edit - classNode = new /*ClassNode*/ImmutableClassNode(c); + /* GRECLIPSE edit + classNode = new ClassNode(c); + */ + if (!c.isMemberClass()) { + classNode = new ImmutableClassNode(c); + } else { + classNode = new ImmutableClassNode(c) { + @Override + public ClassNode getOuterClass() { + return makeCached(clazz.getEnclosingClass()); + } + }; + } // GRECLIPSE end ClassHelperCache.classCache.put(c, new SoftReference(classNode)); - VMPluginFactory.getPlugin().setAdditionalClassInformation(classNode); } - return classNode; } diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassNode.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassNode.java index b341726404..6d2f6277d6 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassNode.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/ClassNode.java @@ -1685,8 +1685,16 @@ public int getNameStart2() { return nameStart > 0 ? nameStart : getStart(); } - public void setNameStart2(int offset) { + public void setNameStart2(final int offset) { nameStart = offset; } + + @Override + public void setSourcePosition(final ASTNode node) { + super.setSourcePosition(node); + if (node instanceof ClassNode) { + setNameStart2(((ClassNode) node).getNameStart2()); + } + } // GRECLIPSE end } diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/expr/ClassExpression.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/expr/ClassExpression.java index 0060f755c5..78e596efc7 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/expr/ClassExpression.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/ast/expr/ClassExpression.java @@ -45,11 +45,11 @@ public String getText() { } // GRECLIPSE add - public void setSourcePosition(ASTNode node) { + public void setSourcePosition(final ASTNode node) { super.setSourcePosition(node); // propagate source position if (getType().getEnd() <= 0) - getType().setSourcePosition(this); + getType().setSourcePosition(node); } // GRECLIPSE end diff --git a/base/org.codehaus.groovy24/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java b/base/org.codehaus.groovy24/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java index 5176ef0e5b..815dc00b58 100644 --- a/base/org.codehaus.groovy24/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java +++ b/base/org.codehaus.groovy24/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java @@ -175,7 +175,7 @@ private Expression transformPropertyExpression(final PropertyExpression exp) { ? thisPropX(false, "class") : varX("this") ) ); - methodCall.getObjectExpression().setSourcePosition(classExpression); + methodCall.getObjectExpression().setSourcePosition(traitType); methodCall.getMethod().setSourcePosition(exp.getProperty()); methodCall.setMethodTarget(methodNode); methodCall.setImplicitThis(false); diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassHelper.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassHelper.java index a25b79b31c..1fe730e9e6 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassHelper.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassHelper.java @@ -146,17 +146,26 @@ public class ClassHelper { public static final String OBJECT = "java.lang.Object"; public static ClassNode makeCached(Class c) { - final SoftReference classNodeSoftReference = ClassHelperCache.classCache.get(c); ClassNode classNode; + final SoftReference classNodeSoftReference = ClassHelperCache.classCache.get(c); if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) { - // GRECLIPSE edit - classNode = new ImmutableClassNode(c); + /* GRECLIPSE edit + classNode = new ClassNode(c); + */ + if (!c.isMemberClass()) { + classNode = new ImmutableClassNode(c); + } else { + classNode = new ImmutableClassNode(c) { + @Override + public ClassNode getOuterClass() { + return makeCached(clazz.getEnclosingClass()); + } + }; + } // GRECLIPSE end ClassHelperCache.classCache.put(c, new SoftReference(classNode)); - VMPluginFactory.getPlugin().setAdditionalClassInformation(classNode); } - return classNode; } diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassNode.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassNode.java index a5133763b6..3ca89bba40 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassNode.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/ClassNode.java @@ -1675,8 +1675,16 @@ public int getNameStart2() { return nameStart > 0 ? nameStart : getStart(); } - public void setNameStart2(int offset) { + public void setNameStart2(final int offset) { nameStart = offset; } + + @Override + public void setSourcePosition(final ASTNode node) { + super.setSourcePosition(node); + if (node instanceof ClassNode) { + setNameStart2(((ClassNode) node).getNameStart2()); + } + } // GRECLIPSE end } diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/expr/ClassExpression.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/expr/ClassExpression.java index 0060f755c5..78e596efc7 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/expr/ClassExpression.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/expr/ClassExpression.java @@ -45,11 +45,11 @@ public String getText() { } // GRECLIPSE add - public void setSourcePosition(ASTNode node) { + public void setSourcePosition(final ASTNode node) { super.setSourcePosition(node); // propagate source position if (getType().getEnd() <= 0) - getType().setSourcePosition(this); + getType().setSourcePosition(node); } // GRECLIPSE end diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java index 87c7b8faa4..f8b285387b 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java @@ -176,7 +176,7 @@ private Expression transformPropertyExpression(final PropertyExpression exp) { ? thisPropX(false, "class") : varX("this") ) ); - methodCall.getObjectExpression().setSourcePosition(classExpression); + methodCall.getObjectExpression().setSourcePosition(traitType); methodCall.getMethod().setSourcePosition(exp.getProperty()); methodCall.setMethodTarget(methodNode); methodCall.setImplicitThis(false); diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java index 5966879f9c..3f426c75c4 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassHelper.java @@ -190,11 +190,22 @@ public class ClassHelper { public static final String OBJECT = "java.lang.Object"; public static ClassNode makeCached(Class c) { - final SoftReference classNodeSoftReference = ClassHelperCache.classCache.get(c); ClassNode classNode; + final SoftReference classNodeSoftReference = ClassHelperCache.classCache.get(c); if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) { - // GRECLIPSE edit - classNode = new ImmutableClassNode(c); + /* GRECLIPSE edit + classNode = new ClassNode(c); + */ + if (!c.isMemberClass()) { + classNode = new ImmutableClassNode(c); + } else { + classNode = new ImmutableClassNode(c) { + @Override + public ClassNode getOuterClass() { + return makeCached(clazz.getEnclosingClass()); + } + }; + } // GRECLIPSE end ClassHelperCache.classCache.put(c, new SoftReference(classNode)); VMPluginFactory.getPlugin().setAdditionalClassInformation(classNode); diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassNode.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassNode.java index f9d053fd2f..ff2c3ecf77 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassNode.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/ClassNode.java @@ -1621,8 +1621,16 @@ public int getNameStart2() { return nameStart > 0 ? nameStart : getStart(); } - public void setNameStart2(int offset) { + public void setNameStart2(final int offset) { nameStart = offset; } + + @Override + public void setSourcePosition(final ASTNode node) { + super.setSourcePosition(node); + if (node instanceof ClassNode) { + setNameStart2(((ClassNode) node).getNameStart2()); + } + } // GRECLIPSE end } diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ClassExpression.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ClassExpression.java index 0060f755c5..78e596efc7 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ClassExpression.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/expr/ClassExpression.java @@ -45,11 +45,11 @@ public String getText() { } // GRECLIPSE add - public void setSourcePosition(ASTNode node) { + public void setSourcePosition(final ASTNode node) { super.setSourcePosition(node); // propagate source position if (getType().getEnd() <= 0) - getType().setSourcePosition(this); + getType().setSourcePosition(node); } // GRECLIPSE end diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java index 8eeaea975f..25cf716181 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java @@ -112,8 +112,8 @@ private Expression transformBinaryExpression(final BinaryExpression exp) { bin.getRightExpression() ) ); - setterCall.getObjectExpression().setSourcePosition(leftExpression.getObjectExpression()); setterCall.getMethod().setSourcePosition(leftExpression.getProperty()); + setterCall.getObjectExpression().setSourcePosition(traitType); setterCall.setSpreadSafe(leftExpression.isSpreadSafe()); setterCall.setImplicitThis(false); return setterCall; @@ -150,7 +150,7 @@ private Expression transformPropertyExpression(final PropertyExpression exp) { ? thisPropX(false, "class") : varX("this") ) ); - methodCall.getObjectExpression().setSourcePosition(((PropertyExpression) exp.getObjectExpression()).getObjectExpression()); + methodCall.getObjectExpression().setSourcePosition(traitType); methodCall.getMethod().setSourcePosition(exp.getProperty()); methodCall.setSpreadSafe(exp.isSpreadSafe()); methodCall.setMethodTarget(methodNode); @@ -207,7 +207,7 @@ private Expression transformMethodCallExpression(final MethodCallExpression exp) transform(exp.getMethod()), newArgs ); - newCall.getObjectExpression().setSourcePosition(((PropertyExpression) exp.getObjectExpression()).getObjectExpression()); + newCall.getObjectExpression().setSourcePosition(traitType); newCall.setSpreadSafe(exp.isSpreadSafe()); newCall.setImplicitThis(false); return newCall; diff --git a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy index 56b9be1516..e5b35da12a 100644 --- a/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy +++ b/ide-test/org.codehaus.groovy.eclipse.tests/src/org/codehaus/groovy/eclipse/test/ui/SemanticHighlightingTests.groovy @@ -3911,6 +3911,32 @@ final class SemanticHighlightingTests extends GroovyEclipseTestSuite { new HighlightedTypedPosition(contents.lastIndexOf('toString'), 8, UNKNOWN)) } + @Test // https://github.com/groovy/groovy-eclipse/issues/1159 + void testTraits12() { + addGroovySource '''\ + |package p + |trait T { + | Number getFoo() { 'foo' } + |} + |'''.stripMargin(), 'T', 'p' + buildProject() + + String contents = '''\ + |class C implements p.T { + | void test() { + | p.T.super.getFoo() + | } + |} + |'''.stripMargin() + + assertHighlighting(contents, + new HighlightedTypedPosition(contents.indexOf('C'), 1, CLASS), + new HighlightedTypedPosition(contents.indexOf('T'), 1, TRAIT), + new HighlightedTypedPosition(contents.indexOf('test'), 4, METHOD), + new HighlightedTypedPosition(contents.lastIndexOf('T'), 1, TRAIT), + new HighlightedTypedPosition(contents.lastIndexOf('getFoo'), 6, STATIC_CALL)) + } + // private int counter diff --git a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java index c9492763af..a230119e6e 100644 --- a/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java +++ b/ide/org.codehaus.groovy.eclipse.ui/src/org/codehaus/groovy/eclipse/editor/highlighting/SemanticHighlightingReferenceRequestor.java @@ -131,7 +131,7 @@ public VisitStatus acceptASTNode(ASTNode node, TypeLookupResult result, IJavaEle } else if (node instanceof ClassNode) { // visit "Map" of "Map.Entry" separately if (((ClassNode) node).getNameEnd() < 1) { - checkOuterClass((ClassNode) node, outer -> { + checkOuterClass(result.type, outer -> { acceptASTNode(outer, new TypeLookupResult(outer, outer, outer, TypeLookupResult.TypeConfidence.EXACT, result.scope), enclosingElement); }); }