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

Leventov/pr 705 #5

Closed
wants to merge 3 commits into from
Closed
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
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtPackage.java
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,10 @@ public interface CtPackage extends CtNamedElement, CtShadowable {

@Override
CtPackage clone();

/**
* Returns {@code true} if this is an <i>unnamed</i> Java package.
* See JLS §7.4.2. Unnamed Packages.
*/
boolean isUnnamedPackage();
}
3 changes: 3 additions & 0 deletions src/main/java/spoon/reflect/factory/PackageFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public CtPackage create(CtPackage parent, String simpleName) {
* the full name of the package
*/
public CtPackage getOrCreate(String qualifiedName) {
if (qualifiedName.isEmpty()) {
return factory.getModel().getRootPackage();
}
StringTokenizer token = new StringTokenizer(qualifiedName, CtPackage.PACKAGE_SEPARATOR);
CtPackage last = factory.getModel().getRootPackage();

Expand Down
12 changes: 10 additions & 2 deletions src/main/java/spoon/reflect/factory/TypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
import spoon.support.visitor.java.JavaReflectionTreeBuilder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
Expand All @@ -42,6 +44,10 @@
*/
public class TypeFactory extends SubFactory {

private static final Set<String> NULL_PACKAGE_CLASSES = new HashSet<String>(
Arrays.asList("void", "boolean", "byte", "short", "char", "int", "float", "long",
"double"));

public final CtTypeReference<?> NULL_TYPE = createReference(CtTypeReference.NULL_TYPE_NAME);
public final CtTypeReference<Void> VOID = createReference(Void.class);
public final CtTypeReference<String> STRING = createReference(String.class);
Expand Down Expand Up @@ -319,6 +325,8 @@ public <T> CtTypeReference<T> createReference(String qualifiedName) {
ref.setDeclaringType(createReference(getDeclaringTypeName(qualifiedName)));
} else if (hasPackage(qualifiedName) > 0) {
ref.setPackage(factory.Package().createReference(getPackageName(qualifiedName)));
} else if (!NULL_PACKAGE_CLASSES.contains(qualifiedName)) {
ref.setPackage(factory.Package().topLevel());
}
ref.setSimpleName(getSimpleName(qualifiedName));
return ref;
Expand Down Expand Up @@ -377,7 +385,7 @@ public boolean matches(CtNewClass element) {
if (packageIndex > 0) {
pack = factory.Package().get(qualifiedName.substring(0, packageIndex));
} else {
pack = factory.Package().get(CtPackage.TOP_LEVEL_PACKAGE_NAME);
pack = factory.Package().getRootPackage();
}

if (pack == null) {
Expand Down Expand Up @@ -462,7 +470,7 @@ protected String getPackageName(String qualifiedName) {
if (hasPackage(qualifiedName) >= 0) {
return qualifiedName.substring(0, hasPackage(qualifiedName));
}
return CtPackage.TOP_LEVEL_PACKAGE_NAME;
return "";
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/spoon/reflect/reference/CtPackageReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ public interface CtPackageReference extends CtReference {
*/
void replace(CtPackageReference packageReference);

/**
* Returns {@code true} if this is a reference to an <i>unnamed</i>
* Java package. See JLS §7.4.2. Unnamed Packages.
*/
boolean isUnnamedPackage();

@Override
CtPackageReference clone();
}
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public String getPackageDeclaration() {
a.accept(this);
}

if (!context.currentTopLevel.getPackage().getQualifiedName().equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
if (!context.currentTopLevel.getPackage().isUnnamedPackage()) {
write("package " + context.currentTopLevel.getPackage().getQualifiedName() + ";");
}
String ret = sbf.toString();
Expand Down Expand Up @@ -1886,7 +1886,7 @@ public <T, A extends T> void visitCtOperatorAssignment(CtOperatorAssignment<T, A
}

public void visitCtPackage(CtPackage ctPackage) {
if (!ctPackage.getQualifiedName().equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
if (!ctPackage.isUnnamedPackage()) {
write("package " + ctPackage.getQualifiedName() + ";");
} else {
write("// default package (CtPackage.TOP_LEVEL_PACKAGE_NAME in Spoon= unnamed package)\n");
Expand Down Expand Up @@ -2086,7 +2086,7 @@ private void visitCtTypeReference(CtTypeReference<?> ref, boolean withGenerics)
}
} else {
if (ref.getPackage() != null && !importsContext.isImported(ref)) {
if (!CtPackage.TOP_LEVEL_PACKAGE_NAME.equals(ref.getPackage().getSimpleName())) {
if (!ref.getPackage().isUnnamedPackage()) {
scan(ref.getPackage()).write(CtPackage.PACKAGE_SEPARATOR);
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/spoon/reflect/visitor/ImportScannerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,11 @@ private Collection<CtTypeReference<?>> getImports(
if (imports.isEmpty()) {
return Collections.EMPTY_LIST;
}
CtPackageReference pack = ((CtTypeReference<?>) imports
.get(simpleType.getSimpleName())).getPackage();
CtPackageReference pack = simpleType.getPackage().getReference();
List<CtTypeReference<?>> refs = new ArrayList<>();
for (CtTypeReference<?> ref : imports.values()) {
// ignore non-top-level type
if (ref.getPackage() != null) {
if (ref.getPackage() != null && !ref.getPackage().isUnnamedPackage()) {
// ignore java.lang package
if (!ref.getPackage().getSimpleName().equals("java.lang")) {
// ignore type in same package
Expand All @@ -218,6 +217,10 @@ private boolean addImport(CtTypeReference<?> ref) {
if (imports.containsKey(ref.getSimpleName())) {
return isImported(ref);
}
// don't import unnamed package elements
if (ref.getPackage() == null || ref.getPackage().isUnnamedPackage()) {
return false;
}
imports.put(ref.getSimpleName(), ref);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/spoon/support/JavaOutputProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public void createJavaFile(CtType<?> element) {

// create package directory
File packageDir;
if (pack.getQualifiedName().equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
if (pack.isUnnamedPackage()) {
packageDir = new File(directory.getAbsolutePath());
} else {
// Create current package dir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ protected void generateProcessedSourceFilesUsingCUs() {

// create package directory
File packageDir;
if (pack.getQualifiedName().equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
if (pack.isUnnamedPackage()) {
packageDir = new File(outputDirectory.getAbsolutePath());
} else {
// Create current package directory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private void addVirtualJavaFile(List<CompilationUnit> unitList, CtType<?> ctType

// create package directory
File packageDir;
if (CtPackage.TOP_LEVEL_PACKAGE_NAME.equals(pack.getQualifiedName())) {
if (pack.isUnnamedPackage()) {
packageDir = new File(directory.getAbsolutePath());
} else {
packageDir = new File(directory.getAbsolutePath() + File.separatorChar + pack.getQualifiedName().replace('.', File.separatorChar));
Expand Down
42 changes: 24 additions & 18 deletions src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ public <T> CtExecutableReference<T> getExecutableReference(MethodBinding exec) {
public CtPackageReference getPackageReference(PackageBinding reference) {
String name = new String(reference.shortReadableName());
if (name.length() == 0) {
return null;
return factory.Package().topLevel();
}
CtPackageReference ref = factory.Core().createPackageReference();
ref.setSimpleName(name);
Expand Down Expand Up @@ -743,7 +743,7 @@ private <T> void insertGenericTypesInNoClasspathFromJDTInSpoon(TypeReference ori
}

/**
* JDT doesn't returns a correct AST with the resolved type of the reference.
* JDT doesn't return a correct AST with the resolved type of the reference.
* This method try to build a correct Spoon AST from the name of the JDT
* reference, thanks to the parsing of the string, the name parameterized from
* the JDT reference and java convention.
Expand Down Expand Up @@ -1030,9 +1030,7 @@ public <T> CtTypeReference<T> getTypeReference(TypeBinding binding) {
ref.setImplicit(isImplicit || !JDTTreeBuilder.this.context.isLambdaParameterImplicitlyTyped);
ref.setSimpleName(new String(binding.readableName()));
final CtReference declaring = references.getDeclaringReferenceFromImports(binding.sourceName());
if (declaring instanceof CtPackageReference) {
ref.setPackage((CtPackageReference) declaring);
}
setPackageOrDeclaringType(ref, declaring);
} else if (binding instanceof SpoonReferenceBinding) {
ref = factory.Core().createTypeReference();
ref.setSimpleName(new String(binding.sourceName()));
Expand Down Expand Up @@ -1152,6 +1150,22 @@ public List<CtTypeReference<?>> getBoundedTypesReferences(TypeBinding[] genericT
}
}

/**
* Sets {@code declaring} as inner of {@code ref}, as either the package or the declaring type
*/
private void setPackageOrDeclaringType(CtTypeReference<?> ref, CtReference declaring) {
if (declaring instanceof CtPackageReference) {
ref.setPackage((CtPackageReference) declaring);
} else if (declaring instanceof CtTypeReference) {
ref.setDeclaringType((CtTypeReference) declaring);
} else if (declaring == null) {
ref.setPackage(factory.Package().topLevel());
} else {
throw new AssertionError(
"unexpected declaring type: " + declaring.getClass() + " of " + declaring);
}
}

public static Set<ModifierKind> getModifiers(int mod) {
Set<ModifierKind> ret = EnumSet.noneOf(ModifierKind.class);
if ((mod & ClassFileConstants.AccPublic) != 0) {
Expand Down Expand Up @@ -2933,15 +2947,12 @@ public boolean visit(MessageSend messageSend, BlockScope scope) {
CtTypeReference<Object> typeReference = factory.Core().createTypeReference();
typeReference.setSimpleName(messageSend.receiver.toString());
final CtReference declaring = references.getDeclaringReferenceFromImports(((SingleNameReference) messageSend.receiver).token);
if (declaring instanceof CtPackageReference) {
typeReference.setPackage((CtPackageReference) declaring);
} else if (declaring instanceof CtTypeReference) {
typeReference = (CtTypeReference<Object>) declaring;
}
setPackageOrDeclaringType(typeReference, declaring);
ref.setDeclaringType(typeReference);
} else if (messageSend.receiver instanceof QualifiedNameReference) {
QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) messageSend.receiver;

// TODO try to determine package/class boundary by upper case
char[][] packageName = CharOperation.subarray(qualifiedNameReference.tokens, 0, qualifiedNameReference.tokens.length - 1);
char[][] className = CharOperation.subarray(qualifiedNameReference.tokens, qualifiedNameReference.tokens.length - 1, qualifiedNameReference.tokens.length);
if (packageName.length > 0) {
Expand Down Expand Up @@ -3064,8 +3075,7 @@ public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
@Override
public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
CtLiteral<Object> lit = factory.Core().createLiteral();
CtTypeReference<Object> ref = factory.Core().createTypeReference();
ref.setSimpleName(CtTypeReference.NULL_TYPE_NAME);
CtTypeReference ref = factory.Type().nullType();
lit.setType(ref);
context.enter(lit, nullLiteral);
return true;
Expand Down Expand Up @@ -3415,11 +3425,7 @@ public boolean visit(SingleNameReference singleNameReference, BlockScope scope)
CtTypeReference<Object> typeReference = factory.Core().createTypeReference();
typeReference.setSimpleName(new String(singleNameReference.binding.readableName()));
final CtReference declaring = references.getDeclaringReferenceFromImports(singleNameReference.token);
if (declaring instanceof CtPackageReference) {
typeReference.setPackage((CtPackageReference) declaring);
} else if (declaring instanceof CtTypeReference) {
typeReference = (CtTypeReference<Object>) declaring;
}
setPackageOrDeclaringType(typeReference, declaring);
final CtTypeAccess<Object> ta = factory.Code().createTypeAccess(typeReference);
context.enter(ta, singleNameReference);
return true;
Expand Down Expand Up @@ -3745,7 +3751,7 @@ public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope
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 = factory.Package().getRootPackage();
}
context.enter(pack, typeDeclaration);
context.compilationunitdeclaration = scope.referenceContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ public Set<CtPackage> getPackages() {

@Override
public String getQualifiedName() {
if (getDeclaringPackage() == null || TOP_LEVEL_PACKAGE_NAME.equals(
((CtPackageImpl) getDeclaringPackage()).simpleName)) {
if (getDeclaringPackage() == null || getDeclaringPackage().isUnnamedPackage()) {
return getSimpleName();
} else {
return getDeclaringPackage().getQualifiedName() + "." + getSimpleName();
}
return getDeclaringPackage().getQualifiedName() + "." + getSimpleName();
}

@Override
Expand Down Expand Up @@ -221,4 +221,9 @@ public <E extends CtShadowable> E setShadow(boolean isShadow) {
public CtPackage clone() {
return (CtPackage) super.clone();
}

@Override
public boolean isUnnamedPackage() {
return TOP_LEVEL_PACKAGE_NAME.equals(getSimpleName());
}
}
11 changes: 6 additions & 5 deletions src/main/java/spoon/support/reflect/declaration/CtTypeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -655,15 +655,16 @@ public List<CtMethod<?>> getMethodsByName(String name) {
@Override
public String getQualifiedName() {
if (isTopLevel()) {
if ((getPackage() != null) && !getPackage().getSimpleName().equals(CtPackage.TOP_LEVEL_PACKAGE_NAME)) {
if (getPackage() != null && !getPackage().isUnnamedPackage()) {
return getPackage().getQualifiedName() + "." + getSimpleName();
} else {
return getSimpleName();
}
return getSimpleName();
}
if (getDeclaringType() != null) {
} else if (getDeclaringType() != null) {
return getDeclaringType().getQualifiedName() + INNERTTYPE_SEPARATOR + getSimpleName();
} else {
return getSimpleName();
}
return getSimpleName();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,9 @@ protected AnnotatedElement getActualAnnotatedElement() {
public CtPackageReference clone() {
return (CtPackageReference) super.clone();
}

@Override
public boolean isUnnamedPackage() {
return getSimpleName().isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public CtPackageReference getPackage() {
public String getQualifiedName() {
if (getDeclaringType() != null) {
return getDeclaringType().getQualifiedName() + CtType.INNERTTYPE_SEPARATOR + getSimpleName();
} else if (getPackage() != null && !CtPackage.TOP_LEVEL_PACKAGE_NAME.equals(getPackage().getSimpleName())) {
} else if (getPackage() != null && !getPackage().isUnnamedPackage()) {
return getPackage().getSimpleName() + CtPackage.PACKAGE_SEPARATOR + getSimpleName();
} else {
return getSimpleName();
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 @@ -204,13 +204,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("pack3.E").declaringType("E").typeIsNull(true), elements.get(12));
assertCorrectInvocation(new Expected().name("staticE").target("pack3.E.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("pack3.E").declaringType("E").typeIsNull(false), elements.get(14));
assertCorrectInvocation(new Expected().name("staticE").target("pack3.E.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
6 changes: 3 additions & 3 deletions src/test/java/spoon/test/parent/ParentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,15 @@ public void testParentOfCtPackageReference() throws Exception {

final CtType<Object> panini = launcher.getFactory().Type().get("Panini");

CtPackage pack2 = (CtPackage) panini.getPackage().getParent();
assertNotNull(pack2);
CtElement topLevelParent = panini.getPackage().getParent();
assertNotNull(topLevelParent);
assertEquals(CtPackage.TOP_LEVEL_PACKAGE_NAME, panini.getPackage().getSimpleName());
CtPackage pack1 = factory.Package().getRootPackage();

// the factory are not the same
assertNotEquals(factory, launcher.getFactory());
// so the root packages are not deeply equals
assertNotEquals(pack1, pack2);
assertNotEquals(pack1, topLevelParent);

final CtTypeReference<?> burritos = panini.getReferences(new ReferenceTypeFilter<CtTypeReference<?>>(CtTypeReference.class) {
@Override
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/spoon/test/reference/TypeReferenceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ public void testAnonymousClassesHaveAnEmptyStringForItsNameInNoClasspath() throw
final CtClass<Object> aClass = launcher.getFactory().Class().get("A");
final CtClass anonymousClass = aClass.getElements(new TypeFilter<>(CtNewClass.class)).get(0).getAnonymousClass();
assertEquals("1", anonymousClass.getReference().getSimpleName());
assertEquals(7, aClass.getReferencedTypes().size());
assertEquals(6, aClass.getReferencedTypes().size());
}

@Test
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/spoon/testing/CtElementAssertTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public void testEqualityBetweenTwoCtElement() throws Exception {
expected.setSimpleName("i");
expected.setType(factory.Type().INTEGER_PRIMITIVE);
expected.addModifier(ModifierKind.PUBLIC);
assertThat(type.getField("i")).isEqualTo(expected);
CtField<?> f = type.getField("i");
assertThat(f).isEqualTo(expected);
}

@Test
Expand Down