Skip to content

Commit

Permalink
GROOVY-11178
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Sep 16, 2023
1 parent 248fc1d commit 653f746
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
*/
package org.eclipse.jdt.core.groovy.tests.search;

import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isAtLeastGroovy;
import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isParrotParser;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import java.util.List;

Expand Down Expand Up @@ -502,6 +505,32 @@ public void testInnerTypes5() throws Exception {
assertEquals(secondContents.lastIndexOf("p.First"), match.getOffset());
}

@Test // GROOVY-11178
public void testTypeAnnotations() throws Exception {
assumeTrue(isParrotParser());

String firstContents =
"package p\n" +
"import java.lang.annotation.*\n" +
"@Target(ElementType.TYPE_USE)\n" +
"public @interface First {\n" +
"}\n";
String secondContents =
"package q\n" +
"import p.*\n" +
"Object o = new @First Object()\n";

List<SearchMatch> matches = searchForFirst(firstContents, secondContents, "p", "q");
if (!isAtLeastGroovy(50)) {
assertTrue(matches.isEmpty());
} else {
assertEquals(1, matches.size());
SearchMatch match = matches.get(0);
assertEquals("First".length(), match.getLength());
assertEquals(secondContents.indexOf("First"), match.getOffset());
}
}

@Test
public void testConstructorWithDefaultArgsInCompileStatic() throws Exception {
String firstContents =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3852,7 +3852,7 @@ public ClassNode visitCreatedName(final CreatedNameContext ctx) {
throw createParsingFailedException("Unsupported created name: " + ctx.getText(), ctx);
}

classNode.addAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt()));
classNode.addTypeAnnotations(this.visitAnnotationsOpt(ctx.annotationsOpt())); // GROOVY-11178

return classNode;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.codehaus.groovy.ast.RecordComponentNode;
import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
import org.codehaus.groovy.ast.expr.DeclarationExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.PropertyExpression;
Expand Down Expand Up @@ -156,8 +157,21 @@ public void visitDeclarationExpression(DeclarationExpression expression) {
visitTypeAnnotations(type);
extractTypeUseAnnotations(expression.getAnnotations(), type, LOCAL_VARIABLE_TARGET);
}
// GRECLIPSE add
expression.getRightExpression().visit(this);
// GRECLIPSE end
}

// GRECLIPSE add -- GROOVY-11178
@Override
public void visitConstructorCallExpression(ConstructorCallExpression expression) {
if (!expression.isSpecialCall()) {
visitTypeAnnotations(expression.getType());
}
super.visitConstructorCallExpression(expression);
}
// GRECLIPSE end

@Override
public void visitConstructor(ConstructorNode node) {
visitConstructorOrMethod(node, CONSTRUCTOR_TARGET);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ private void visitTypeReference(final ClassNode type, final boolean isAnnotation
tokens = splitName(type, useQualifiedName);
requestor.acceptAnnotationTypeReference(tokens, type.getStart(), type.getEnd());
} else {
if (useQualifiedName) visitAnnotations(type.getTypeAnnotations());
tokens = splitName(GroovyUtils.getBaseType(type), useQualifiedName);
requestor.acceptTypeReference(tokens, type.getStart(), type.getEnd());
visitTypeParameters(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ public void visitImport(ImportNode node) {
@Override
public void visitClass(ClassNode node) {
visitAnnotations(node.getAnnotations());
visitAnnotations(node.getTypeAnnotations());

// visit "<clinit>" statements before visitContents
MethodNode clinit = node.getMethod("<clinit>", Parameter.EMPTY_ARRAY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ public void visitJDT(final IType type, final ITypeRequestor requestor) {
// visit relocated @AnnotationCollector annotations
visitAnnotations(AnnotationCollectorTransform.getMeta(node));
}
visitAnnotations(node.getTypeAnnotations()); // declaration TYPE_USE

// visit name "node"
TypeLookupResult result = new TypeLookupResult(node, node, node, TypeConfidence.EXACT, scopes.getLast());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package org.codehaus.groovy.eclipse.test.actions

import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isAtLeastGroovy
import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isParrotParser

import groovy.test.NotYetImplemented

import org.junit.Test
Expand Down Expand Up @@ -580,6 +583,21 @@ final class OrganizeImportsTests extends OrganizeImportsTestSuite {
doContentsCompareTest(contents)
}

@Test // JSR 308
void testRetainImport14() {
String contents = '''\
|import p.T
|def m(List<@T ?> list) {}
|'''
if (!isParrotParser() || isAtLeastGroovy(40)) {
doContentsCompareTest(contents)
} else { // parses but annotation missed
doContentsCompareTest(contents, '''\
|def m(List<@T ?> list) {}
|''')
}
}

@Test
void testChoices() {
String contents = '''\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ class ASTView extends ViewPart {
}
if (outer.redirectNode && label ==~ /annotations|compileUnit|declaredConstructors|enclosingMethod|fields|hasInconsistentHierarchy|/ +
/innerClasses|interfaces|is(?!GenericsPlaceHolder|Synthetic(Public)?|UsingGenerics)\w+|methods|mixins|modifiers|/ +
/outerClasses|package|permittedSubclasses|properties|superClass|typeAnnotations/) {
/outerClasses|package|permittedSubclasses|properties|superClass/) {
return false
}
if (!outer.redirectNode && label ==~ /unresolved(Name|Interfaces|SuperClass)/) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ protected void visitTypeParameters(GenericsType[] generics, String typeName) {
if (generic.getStart() < 1) {
continue;
}
visitAnnotations(generic.getType().getTypeAnnotations());
if (!generic.isPlaceholder() && !generic.isWildcard()) {
handleTypeReference(generic.getType(), false);
}
Expand Down Expand Up @@ -668,6 +669,7 @@ private void handleStaticCall(ClassNode declaringClass, MethodCall call) {
* that the import will be retained if the type is resolved.
*/
private void handleTypeReference(ClassNode node, boolean isAnnotation) {
if (!isAnnotation) visitAnnotations(node.getTypeAnnotations());
ClassNode type = GroovyUtils.getBaseType(node);
if (ClassHelper.isPrimitiveType(type)) {
return;
Expand Down

0 comments on commit 653f746

Please sign in to comment.