Skip to content

Commit

Permalink
fix(noclasspath): Handle type resolution of anonymous class with unre…
Browse files Browse the repository at this point in the history
…solved constructor (#3971)
  • Loading branch information
slarse authored Jun 1, 2021
1 parent 827161b commit 011be63
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ <T> CtTypeReference<T> getTypeReference(TypeReference ref) {
CtPackageReference packageReference = index >= 0 ? packageFactory.getOrCreate(concatSubArray(namesParameterized, index)).getReference() : packageFactory.topLevel();
inner.setPackage(packageReference);
}
if (!res.toStringDebug().replace(", ?", ",?").endsWith(nameParameterized)) {
if (!res.toStringDebug().replace(", ", ",").endsWith(nameParameterized)) {
// verify that we did not match a class that have the same name in a different package
return this.jdtTreeBuilder.getFactory().Type().createReference(typeName);
}
Expand Down
28 changes: 28 additions & 0 deletions src/test/java/spoon/test/constructorcallnewclass/NewClassTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

import org.junit.Before;
import org.junit.Test;
import spoon.FluentLauncher;
import spoon.Launcher;
import spoon.reflect.CtModel;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtTypeReference;
Expand All @@ -33,6 +36,10 @@

import java.util.List;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand Down Expand Up @@ -201,4 +208,25 @@ public void testCtNewClassInNoClasspath() {

canBeBuilt("./target/new-class", 8, true);
}

@Test
public void testBadConstructorCallToAnonymousGenericType() {
// contract: Spoon should be able to resolve the type of a constructor call to an anonymous
// subclass of a generic type, when the constructor does not exist.
// See https://github.com/INRIA/spoon/issues/3913 for details.

CtModel model = new FluentLauncher()
.inputResource("./src/test/resources/noclasspath/BadAnonymousClassOfNestedType.java")
.buildModel();
CtNewClass<?> newClass = model.filterChildren(CtNewClass.class::isInstance).first();
CtType<?> anonymousClass = newClass.getAnonymousClass();

CtType<?> expectedSuperclass = model
.getUnnamedModule()
.getFactory()
.Type()
.get("BadAnonymousClassOfNestedType$GenericType");
assertThat(anonymousClass.getQualifiedName(), startsWith("BadAnonymousClassOfNestedType"));
assertThat(anonymousClass.getSuperclass().getTypeDeclaration(), equalTo(expectedSuperclass));
}
}
12 changes: 12 additions & 0 deletions src/test/resources/noclasspath/BadAnonymousClassOfNestedType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
Test source file to reproduce the behavior reported in https://github.com/INRIA/spoon/issues/3913
*/
public final class BadAnonymousClassOfNestedType<K, V> {
public void test() {
new BadAnonymousClassOfNestedType.GenericType<K, V>(this) {
};
}

static class GenericType<K, V> {
}
}

0 comments on commit 011be63

Please sign in to comment.