Skip to content

Commit

Permalink
fix NPE with duplicate inner class (#2972)
Browse files Browse the repository at this point in the history
  • Loading branch information
Charmik authored and nharrand committed May 27, 2019
1 parent b50229c commit 975a348
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,9 @@ public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope s
CtConstructor<Object> c = factory.Core().createConstructor();
// if the source start of the class is equals to the source start of the constructor
// it means that the constructor is implicit.
c.setImplicit(scope.referenceContext.sourceStart() == constructorDeclaration.sourceStart());
if (scope != null && scope.referenceContext != null) {
c.setImplicit(scope.referenceContext.sourceStart() == constructorDeclaration.sourceStart());
}
if (constructorDeclaration.binding != null) {
c.setExtendedModifiers(getModifiers(constructorDeclaration.binding.modifiers, true, true));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ CtType<?> createType(TypeDeclaration typeDeclaration) {
if (typeDeclaration.superclass != null) {
((CtClass) type).setSuperclass(jdtTreeBuilder.references.buildTypeReference(typeDeclaration.superclass, typeDeclaration.scope));
}
if (typeDeclaration.binding.isAnonymousType() || (typeDeclaration.binding instanceof LocalTypeBinding && typeDeclaration.binding.enclosingMethod() != null)) {
if (typeDeclaration.binding != null && (typeDeclaration.binding.isAnonymousType() || (typeDeclaration.binding instanceof LocalTypeBinding && typeDeclaration.binding.enclosingMethod() != null))) {
type.setSimpleName(computeAnonymousName(typeDeclaration.binding.constantPoolName()));
} else {
type.setSimpleName(new String(typeDeclaration.name));
Expand Down
26 changes: 26 additions & 0 deletions src/test/java/spoon/test/compilation/CompilationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@
import spoon.Launcher;
import spoon.SpoonException;
import spoon.SpoonModelBuilder;
import spoon.reflect.CtModel;
import spoon.reflect.code.BinaryOperatorKind;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtReturn;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.ModifierKind;
import spoon.reflect.factory.CodeFactory;
Expand Down Expand Up @@ -522,4 +524,28 @@ public void testBuildAstWithSyntheticMethodsSwapOrder() {
CtType t=launcher.getFactory().Type().get("ClassWithSyntheticEnumNotParsable");
assertEquals(2, t.getMethods().size());
}

@Test
public void buildAstWithDuplicateClass() {
// contract: one can have inner classes with the same name
File testFile = new File(
"src/test/resources/duplicateClass/DuplicateInnerClass.java");
String absoluteTestPath = testFile.getAbsolutePath();

Launcher launcher = new Launcher();
launcher.addInputResource(absoluteTestPath);
final CtModel model = launcher.buildModel();
final List<String> pkgNames = model.getElements(new TypeFilter<>(CtPackage.class))
.stream()
.map(CtPackage::getQualifiedName)
.collect(Collectors.toList());
assertTrue(pkgNames.contains("P.F.G"));
final List<String> classNames = model.getElements(new TypeFilter<>(CtType.class))
.stream()
.map(CtType::getQualifiedName)
.collect(Collectors.toList());
assertTrue(classNames.contains("P.F.G.DuplicateInnerClass"));
assertTrue(classNames.contains("P.F.G.DuplicateInnerClass$B"));
assertTrue(classNames.contains("P.F.G.DuplicateInnerClass$B$B"));
}
}
15 changes: 15 additions & 0 deletions src/test/resources/duplicateClass/DuplicateInnerClass.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package P.F.G;

/**
* @author Charm
*/

public interface DuplicateInnerClass {

abstract class B {

private static class B implements DuplicateInnerClass {

}
}
}

0 comments on commit 975a348

Please sign in to comment.