Skip to content

Commit

Permalink
[fix #465] Missing package in type reference with noclasspath mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tdurieux committed Dec 27, 2015
1 parent 33272e3 commit b27b6b7
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 5 deletions.
39 changes: 38 additions & 1 deletion src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2391,10 +2391,36 @@ public boolean visit(MessageSend messageSend, BlockScope scope) {
ref.setType(references.getTypeReference(messageSend.expectedType()));
if (messageSend.receiver.resolvedType == null) {
// It is crisis dude! static context, we don't have much more information.
if (messageSend.receiver instanceof SingleNameReference || messageSend.receiver instanceof QualifiedNameReference) {
if (messageSend.receiver instanceof SingleNameReference) {
final CtTypeReference<Object> typeReference = factory.Core().createTypeReference();
typeReference.setSimpleName(messageSend.receiver.toString());
if (context.compilationunitdeclaration != null && context.compilationunitdeclaration.imports != null) {
for (ImportReference anImport : context.compilationunitdeclaration.imports) {
if (CharOperation.equals(anImport.getImportName()[anImport.getImportName().length - 1], ((SingleNameReference) messageSend.receiver).token)) {
char[][] packageName = CharOperation.subarray(anImport.getImportName(), 0, anImport.getImportName().length - 1);
CtPackageReference packageRef = factory.Core().createPackageReference();
packageRef.setSimpleName(CharOperation.toString(packageName));
typeReference.setPackage(packageRef);
break;
}
}
}
ref.setDeclaringType(typeReference);
} else if (messageSend.receiver instanceof QualifiedNameReference) {
QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) messageSend.receiver;

char[][] packageName = CharOperation.subarray(qualifiedNameReference.tokens, 0, qualifiedNameReference.tokens.length - 2);
char[][] className = CharOperation.subarray(qualifiedNameReference.tokens, qualifiedNameReference.tokens.length - 2, qualifiedNameReference.tokens.length - 1);
if (packageName.length > 0) {
final PackageBinding aPackage = context.compilationunitdeclaration.scope.environment.createPackage(packageName);
final MissingTypeBinding declaringType = context.compilationunitdeclaration.scope.environment.createMissingType(aPackage, className);

ref.setDeclaringType(references.getTypeReference(declaringType));
} else {
final CtTypeReference<Object> typeReference = factory.Core().createTypeReference();
typeReference.setSimpleName(messageSend.receiver.toString());
ref.setDeclaringType(typeReference);
}
}
} else {
ref.setDeclaringType(references.getTypeReference(messageSend.receiver.resolvedType));
Expand Down Expand Up @@ -2827,6 +2853,17 @@ public boolean visit(SingleNameReference singleNameReference, BlockScope scope)
final CtTypeAccess<Object> ta = factory.Core().createTypeAccess();
final CtTypeReference<Object> typeReference = factory.Core().createTypeReference();
typeReference.setSimpleName(new String(singleNameReference.binding.readableName()));
if (context.compilationunitdeclaration != null && context.compilationunitdeclaration.imports != null) {
for (ImportReference anImport : context.compilationunitdeclaration.imports) {
if (CharOperation.equals(anImport.getImportName()[anImport.getImportName().length - 1], singleNameReference.token)) {
char[][] packageName = CharOperation.subarray(anImport.getImportName(), 0, anImport.getImportName().length - 1);
CtPackageReference packageRef = factory.Core().createPackageReference();
packageRef.setSimpleName(CharOperation.toString(packageName));
typeReference.setPackage(packageRef);
break;
}
}
}
ta.setType(typeReference);
context.enter(ta, singleNameReference);
return true;
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/spoon/test/imports/ImportTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,13 @@ public boolean matches(CtInvocation<?> element) {
assertCorrectInvocation(new Expected().name("staticD").target("pack2.C.D").declaringType("D").typeIsNull(false), elements.get(11));

// Invocation for a static method with the declaring class specified and an import *.
assertCorrectInvocation(new Expected().name("staticE").target("E").declaringType("E").typeIsNull(true), elements.get(12));
assertCorrectInvocation(new Expected().name("staticE").target("pack3.E").declaringType("E").typeIsNull(true), elements.get(12));

// Invocation for a static method without the declaring class specified and an import *.
assertCorrectInvocationWithLimit(new Expected().name("staticE").typeIsNull(true), elements.get(13));

// Invocation for a static method with the declaring class specified, a return type and an import *.
assertCorrectInvocation(new Expected().name("staticE").target("E").declaringType("E").typeIsNull(false), elements.get(14));
assertCorrectInvocation(new Expected().name("staticE").target("pack3.E").declaringType("E").typeIsNull(false), elements.get(14));

// Invocation for a static method without the declaring class specified, a return type and an import *.
assertCorrectInvocationWithLimit(new Expected().name("staticE").typeIsNull(false), elements.get(15));
Expand Down
36 changes: 36 additions & 0 deletions src/test/java/spoon/test/reference/TypeReferenceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import spoon.test.reference.testclasses.EnumValue;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
Expand Down Expand Up @@ -256,6 +258,40 @@ public void testRecursiveTypeReferenceInGenericType() throws Exception {
assertTrue(circularRef instanceof CtCircularTypeReference);
}

@Test
public void testPackageInNoClasspath () {
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/resources/noclasspath/Demo.java");
launcher.setSourceOutputDirectory("./target/class");
launcher.getEnvironment().setNoClasspath(true);
launcher.run();

final CtClass<Object> aClass = launcher.getFactory().Class().get("Demo");
final Set<CtTypeReference<?>> referencedTypes = aClass.getReferencedTypes();

boolean containsDemoReference = false;
boolean containsVoidReference = false;
boolean containsStringReference = false;
boolean containsJoinerReference = false;

for (Iterator<CtTypeReference<?>> iterator = referencedTypes.iterator(); iterator.hasNext(); ) {
CtTypeReference<?> reference = iterator.next();
if (reference.toString().equals("Demo")) {
containsDemoReference = true;
} else if (reference.toString().equals("void")) {
containsVoidReference = true;
} else if (reference.toString().equals("java.lang.String")) {
containsStringReference = true;
} else if (reference.toString().equals("com.google.common.base.Joiner")) {
containsJoinerReference = true;
}
}
assertTrue("Reference to Demo is missing", containsDemoReference);
assertTrue("Reference to void is missing", containsVoidReference);
assertTrue("Reference to String is missing", containsStringReference);
assertTrue("Reference to Joiner is missing", containsJoinerReference);
}

class A {
class Tacos<K> {
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/spoon/test/variable/AccessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public void testVariableAccessInNoClasspath() throws Exception {
assertNotNull(element.getVariable());
}

assertEquals("java.lang.Class mclass = ((java.lang.Class)(ModelFacade.USE_CASE))", elements.get(0).getParent().toString());
assertEquals("new PropPanelButton(this , buttonPanel , _navUpIcon , Translator.localize(\"UMLMenu\", \"button.go-up\") , \"navigateNamespace\" , null)", elements.get(2).getParent().toString());
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());
}
}
8 changes: 8 additions & 0 deletions src/test/resources/noclasspath/Demo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import com.google.common.base.Joiner;

public class Demo {

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

0 comments on commit b27b6b7

Please sign in to comment.