Skip to content

Commit

Permalink
Fix for #1599: JDT super trait property resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Oct 3, 2024
1 parent 4e67ec3 commit 54ec8bd
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -440,17 +440,40 @@ public void testProperty23() {
String source =
"class C implements T {\n" +
" void meth() {\n" +
" def arr = numbers\n" +
" def anArray = numbers\n" +
" }\n" +
"}\n";
//@formatter:on

assertDeclType(source, "numbers", "T");
assertExprType(source, "numbers", "java.lang.Number[]");
assertExprType(source, "anArray", "java.lang.Number[]");
}

@Test
@Test // https://github.com/groovy/groovy-eclipse/issues/1599
public void testProperty24() {
createUnit("T",
"import java.beans.BeanInfo\n" +
"trait T {\n" +
" Map<BeanInfo,Number[]> numbers\n" +
"}\n");

//@formatter:off
String source =
"class C implements T {\n" +
" void meth() {\n" +
" def anArray = numbers['k']\n" +
" }\n" +
"}\n";
//@formatter:on

assertDeclType(source, "numbers", "T");
assertExprType(source, "numbers", "java.util.Map<java.beans.BeanInfo,java.lang.Number[]>");
assertExprType(source, "anArray", "java.lang.Number[]");
}

@Test
public void testProperty25() {
createUnit("T",
"trait T {\n" +
" static Number number\n" +
Expand Down Expand Up @@ -483,7 +506,7 @@ public void testProperty24() {
}

@Test
public void testProperty25() {
public void testProperty26() {
createUnit("T",
"trait T {\n" +
" static final Number number = 1\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,9 +626,9 @@ public List<PropertyNode> getProperties() {
List<PropertyNode> nodes = super.getProperties();

for (PropertyNode node : groovyTypeDecl.getClassNode().getProperties()) {
FieldNode field = getField(node.getName());
FieldNode field = getDeclaredField(node.getName());
if (field == null) {
field = new FieldNode(node.getName(), Flags.AccPrivate | (node.getModifiers() & Flags.AccStatic + Flags.AccFinal), resolver.resolve(node.getType().getName()), this, null);
field = new FieldNode(node.getName(), Flags.AccPrivate | (node.getModifiers() & Flags.AccStatic + Flags.AccFinal), resolveType(node.getType()), this, null);
field.setDeclaringClass(this);
field.setSourcePosition(node.getField());
field.setSynthetic(true);
Expand All @@ -639,6 +639,7 @@ public List<PropertyNode> getProperties() {
PropertyNode clone = new PropertyNode(field, node.getModifiers(), null, null);
clone.setDeclaringClass(this);
clone.setSourcePosition(node);
// TODO: propagate annotations

nodes.add(clone);
}
Expand Down Expand Up @@ -667,6 +668,53 @@ public List<PropertyNode> getProperties() {
return Collections.unmodifiableList(super.getProperties());
}

private ClassNode resolveType(ClassNode cn) {
int dims = 0;
while (cn.isArray()) { dims += 1;
cn = cn.getComponentType();
}
String name = cn.getName();
if (groovyTypeDecl != null) {
String[] tokens = name.split("\\.");
ClassNode known = groovyTypeDecl.getClassNode().getModule().getImportType(tokens[0]);
if (known != null) {
tokens[0] = known.getName();
name = String.join(".", tokens);
}
}
ClassNode type = resolver.resolve(name);

type = type.getPlainNodeReference(); // "Map<K,V>" to "Map --> Map<K,V>"

GenericsType[] gt = cn.getGenericsTypes();
if (gt != null) {
GenericsType[] types = new GenericsType[gt.length];
for (int i = 0; i < gt.length; i += 1) {
if (!gt[i].isWildcard()) {
types[i] = new GenericsType(resolveType(gt[i].getType()));
} else {
ClassNode lowerBound = gt[i].getLowerBound();
if (lowerBound != null) lowerBound = resolveType(lowerBound);
ClassNode[] upperBounds = gt[i].getUpperBounds();
if (upperBounds != null) {
upperBounds = upperBounds.clone();
Arrays.asList(upperBounds).replaceAll(this::resolveType);
}
types[i] = new GenericsType(ClassHelper.makeWithoutCaching("?"), upperBounds, lowerBound);
types[i].setWildcard(true);
}
types[i].setResolved(true);
}
type.setGenericsTypes(types);
}

while (dims-- > 0) {
type = type.makeArray();
}

return type;
}

private static boolean isGenerated(MethodNode mn) {
for (AnnotationNode an : mn.getAnnotations()) {
if (an.getClassNode().getName().equals("groovy.transform.Generated")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ public ClassNode resolve(String name) {
synchronized (this) {
ClassNode previousClass = currentClass;
try {
currentClass = compilationUnit.getFirstClassNode().getPlainNodeReference();
currentClass = modules.get(0).getClasses().get(0);

ClassNode type = ClassHelper.makeWithoutCaching(name);
if (super.resolve(type, true, true, true)) {
Expand Down

0 comments on commit 54ec8bd

Please sign in to comment.