Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(noclasspath): Gets package of types in the class declaration. #477

Merged
merged 1 commit into from
Jan 11, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,10 @@ public <T> CtTypeReference<T> getTypeReference(TypeBinding binding) {
ref = factory.Core().createTypeReference();
}
ref.setSimpleName(new String(binding.readableName()));
final CtReference declaring = references.getDeclaringReferenceFromImports(binding.sourceName());
if (declaring instanceof CtPackageReference) {
ref.setPackage((CtPackageReference) declaring);
}
} else if (binding instanceof SpoonReferenceBinding) {
ref = factory.Core().createTypeReference();
ref.setSimpleName(new String(binding.sourceName()));
Expand Down Expand Up @@ -1024,15 +1028,19 @@ CtType<?> createType(TypeDeclaration typeDeclaration) {
CtEnum<?> e = factory.Core().createEnum();
if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
e.addSuperInterface(references.getTypeReference(ref.resolvedType));
final CtTypeReference<Object> currentInterface = references.getTypeReference(ref.resolvedType);
e.addSuperInterface(currentInterface);
insertGenericTypesInNoClasspathFromJDTInSpoon(ref, currentInterface);
}
}
type = e;
} else if ((typeDeclaration.modifiers & ClassFileConstants.AccInterface) != 0) {
CtInterface<?> interf = factory.Core().createInterface();
if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
interf.addSuperInterface(references.getTypeReference(ref.resolvedType));
final CtTypeReference<Object> currentInterface = references.getTypeReference(ref.resolvedType);
interf.addSuperInterface(currentInterface);
insertGenericTypesInNoClasspathFromJDTInSpoon(ref, currentInterface);
}
}
if (typeDeclaration.typeParameters != null) {
Expand Down Expand Up @@ -1060,7 +1068,9 @@ CtType<?> createType(TypeDeclaration typeDeclaration) {
}
}
if (typeDeclaration.superclass != null) {
cl.setSuperclass(references.getTypeReference(typeDeclaration.superclass.resolvedType));
final CtTypeReference<Object> superClass = references.getTypeReference(typeDeclaration.superclass.resolvedType);
cl.setSuperclass(superClass);
insertGenericTypesInNoClasspathFromJDTInSpoon(typeDeclaration.superclass, superClass);
}

// If the current class is an anonymous class with a super interface and generic types, we add generic
Expand All @@ -1080,7 +1090,9 @@ CtType<?> createType(TypeDeclaration typeDeclaration) {

if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
cl.addSuperInterface(references.getTypeReference(ref.resolvedType));
final CtTypeReference<Object> currentInterface = references.getTypeReference(ref.resolvedType);
cl.addSuperInterface(currentInterface);
insertGenericTypesInNoClasspathFromJDTInSpoon(ref, currentInterface);
}
}
if (typeDeclaration.typeParameters != null) {
Expand Down Expand Up @@ -1108,6 +1120,16 @@ CtType<?> createType(TypeDeclaration typeDeclaration) {
return type;
}

private void insertGenericTypesInNoClasspathFromJDTInSpoon(TypeReference original, CtTypeReference<Object> type) {
if (original.resolvedType instanceof ProblemReferenceBinding && original.getTypeArguments() != null) {
for (TypeReference[] typeReferences : original.getTypeArguments()) {
for (TypeReference typeReference : typeReferences) {
type.addActualTypeArgument(references.getTypeReference(typeReference.resolvedType));
}
}
}
}

class SpoonReferenceBinding extends ReferenceBinding {
private ReferenceBinding enclosingType;

Expand Down Expand Up @@ -3232,19 +3254,18 @@ public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope

return true;
} else {
CtType<?> type = createType(typeDeclaration);

type.setDocComment(getJavaDoc(typeDeclaration.javadoc, scope.referenceContext));

CtPackage pack = null;
if (typeDeclaration.binding.fPackage.shortReadableName() != null && typeDeclaration.binding.fPackage.shortReadableName().length > 0) {
pack = factory.Package().getOrCreate(new String(typeDeclaration.binding.fPackage.shortReadableName()));
} else {
pack = factory.Package().getOrCreate(CtPackage.TOP_LEVEL_PACKAGE_NAME);
}
pack.addType(type);
context.enter(pack, typeDeclaration);
context.compilationunitdeclaration = scope.referenceContext;
CtType<?> type = createType(typeDeclaration);
pack.addType(type);

type.setDocComment(getJavaDoc(typeDeclaration.javadoc, scope.referenceContext));
context.enter(type, typeDeclaration);

// AST bug HACK
Expand Down
28 changes: 27 additions & 1 deletion src/test/java/spoon/test/reference/TypeReferenceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ public void testRecursiveTypeReferenceInGenericType() throws Exception {
public void testPackageInNoClasspath () {
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/noclasspath/Demo.java");
launcher.setSourceOutputDirectory("./target/class");
launcher.setSourceOutputDirectory("./target/class-declaration");
launcher.getEnvironment().setNoClasspath(true);
launcher.run();

Expand Down Expand Up @@ -292,6 +292,32 @@ public void testPackageInNoClasspath () {
assertTrue("Reference to Joiner is missing", containsJoinerReference);
}

@Test
public void testTypeReferenceSpecifiedInClassDeclarationInNoClasspath() throws Exception {
// contract: Gets the import of a type specified in the declaration of a class.
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/noclasspath/Demo.java");
launcher.setSourceOutputDirectory("./target/class-declaration");
launcher.getEnvironment().setNoClasspath(true);
launcher.run();

final CtClass<Object> aClass = launcher.getFactory().Class().get("Demo");

assertNotNull(aClass.getSuperclass());
assertEquals("com.google.common.base.Function", aClass.getSuperclass().getQualifiedName());
assertEquals(2, aClass.getSuperclass().getActualTypeArguments().size());
assertEquals("java.lang.String", aClass.getSuperclass().getActualTypeArguments().get(0).toString());
assertEquals("java.lang.String", aClass.getSuperclass().getActualTypeArguments().get(1).toString());

assertEquals(1, aClass.getSuperInterfaces().size());
for (CtTypeReference<?> superInterface : aClass.getSuperInterfaces()) {
assertEquals("com.google.common.base.Function", superInterface.getQualifiedName());
assertEquals(2, superInterface.getActualTypeArguments().size());
assertEquals("java.lang.String", superInterface.getActualTypeArguments().get(0).toString());
assertEquals("java.lang.String", superInterface.getActualTypeArguments().get(1).toString());
}
}

class A {
class Tacos<K> {
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/spoon/test/variable/AccessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,6 @@ public void testVariableAccessInNoClasspath() throws Exception {
}

assertEquals("java.lang.Class mclass = ((java.lang.Class)(org.argouml.model.ModelFacade.USE_CASE))", elements.get(0).getParent().toString());
assertEquals("new PropPanelButton(this , buttonPanel , _navUpIcon , org.argouml.i18n.Translator.localize(\"UMLMenu\", \"button.go-up\") , \"navigateNamespace\" , null)", elements.get(2).getParent().toString());
assertEquals("new org.argouml.uml.ui.PropPanelButton(this , buttonPanel , _navUpIcon , org.argouml.i18n.Translator.localize(\"UMLMenu\", \"button.go-up\") , \"navigateNamespace\" , null)", elements.get(2).getParent().toString());
}
}
3 changes: 2 additions & 1 deletion src/test/resources/noclasspath/Demo.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import com.google.common.base.Joiner;
import com.google.common.base.Function;

public class Demo {
public class Demo extends Function<String, String> implements Function<String, String> {

public static void main(String[] args) {
Joiner.on();
Expand Down