Skip to content

Commit

Permalink
feat(CtUnresolvedImport): keep all imports in noClassPath mode (#2936)
Browse files Browse the repository at this point in the history
  • Loading branch information
nharrand authored and monperrus committed May 16, 2019
1 parent 5b34164 commit d0aebbb
Show file tree
Hide file tree
Showing 19 changed files with 396 additions and 13 deletions.
6 changes: 4 additions & 2 deletions spoon-pom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,11 @@
<include>src/main/java/**</include>
<!-- We also want to check the license in templates to generate files with the proper header -->
<include>src/test/java/spoon/generating/clone/*</include>
<!-- excluding the code coming from Javaparser -->
<exclude>src/main/java/spoon/javadoc/internal/*</exclude>
</includes>
<excludes>
<!-- excluding the code coming from Javaparser -->
<exclude>src/main/java/spoon/javadoc/internal/*</exclude>
</excludes>
</configuration>
<executions>
<execution>
Expand Down
89 changes: 89 additions & 0 deletions src/main/java/spoon/experimental/CtUnresolvedImport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* Copyright (C) 2006-2019 INRIA and contributors
*
* Spoon is available either under the terms of the MIT License (see LICENSE-MIT.txt) of the Cecill-C License (see LICENSE-CECILL-C.txt). You as the user are entitled to choose the terms under which to adopt Spoon.
*/
package spoon.experimental;

import spoon.SpoonException;
import spoon.reflect.declaration.CtImport;
import spoon.reflect.declaration.CtImportKind;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtReference;
import spoon.reflect.visitor.CtImportVisitor;
import spoon.reflect.visitor.CtVisitor;
import spoon.support.reflect.declaration.CtElementImpl;

public class CtUnresolvedImport extends CtElementImpl implements CtImport {

public CtUnresolvedImport() {
}

private boolean isStatic;

public void setStatic(boolean isStatic) {
this.isStatic = isStatic;
}

public boolean isStatic() {
return isStatic;
}

private String unresolvedReference;

public void setUnresolvedReference(String reference) {
this.unresolvedReference = reference;
}

public String getUnresolvedReference() {
return unresolvedReference;
}

@Override
public CtImportKind getImportKind() {
return CtImportKind.UNRESOLVED;
}

@Override
public CtReference getReference() {
return null;
}

@Override
public <T extends CtImport> T setReference(CtReference reference) {
throw new SpoonException("UnrseolvedImport reference cannot be set. Use CtImportImpl instead");
}

@Override
public void accept(CtImportVisitor visitor) {

}

@Override
public void accept(CtVisitor visitor) {
visitor.visitCtImport(this);
}

@Override
public CtUnresolvedImport clone() {
Factory factory = getFactory();
return (CtUnresolvedImport) factory.createUnresolvedImport(unresolvedReference, isStatic);
}

@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (!(o instanceof CtUnresolvedImport)) {
return false;
}
CtUnresolvedImport other = (CtUnresolvedImport) o;
return other.isStatic() == isStatic && other.getUnresolvedReference().equals(unresolvedReference);
}

@Override
public int hashCode() {
return unresolvedReference.hashCode() + (isStatic ? 1 : 0);
}
}
12 changes: 7 additions & 5 deletions src/main/java/spoon/reflect/declaration/CtImportKind.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
package spoon.reflect.declaration;

public enum CtImportKind {
TYPE,
ALL_TYPES,
ALL_STATIC_MEMBERS,
FIELD,
METHOD
TYPE, // import my.package.Type;
ALL_TYPES, // import my.package.*;
ALL_STATIC_MEMBERS, // import static my.package.Type.*;
FIELD, // import static my.package.Type.f;
METHOD, // import static my.package.Type.m;
UNRESOLVED // Any of the above when in mode no classpath and the reference cannot be resolved.
// It is then stored as a pure String that will be printed as is when pretty printed.
}
7 changes: 7 additions & 0 deletions src/main/java/spoon/reflect/factory/CoreFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,13 @@ BodyHolderSourcePosition createBodyHolderSourcePosition(
*/
CtImport createImport();

/**
* Creates an unresolved import.
* CtUnresolvedImport stores the original content of the imort as a String in order to be able
* to restituate it when pretty printing.
*/
CtImport createUnresolvedImport();

/**
* Creates a package declaration.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/spoon/reflect/factory/Factory.java
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,11 @@ public interface Factory {
*/
CtImport createImport(CtReference reference);

/**
* @see TypeFactory#createUnresolvedImport(String,boolean)
*/
CtImport createUnresolvedImport(String reference, boolean isStatic);

/**
* @see TypeFactory#createTypeMemberWildcardImportReference(CtTypeReference)
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/spoon/reflect/factory/FactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,11 @@ public CtImport createImport(CtReference reference) {
return Type().createImport(reference);
}

@Override
public CtImport createUnresolvedImport(String reference, boolean isStatic) {
return Type().createUnresolvedImport(reference, isStatic);
}

@Override
public CtTypeMemberWildcardImportReference createTypeMemberWildcardImportReference(CtTypeReference typeReference) {
return Type().createTypeMemberWildcardImportReference(typeReference);
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/spoon/reflect/factory/TypeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.experimental.CtUnresolvedImport;
import spoon.reflect.reference.CtActualTypeContainer;
import spoon.reflect.reference.CtArrayTypeReference;
import spoon.reflect.declaration.CtImport;
Expand Down Expand Up @@ -715,4 +716,11 @@ protected void enter(CtElement e) {
}.scan(importRef);
return ctImport.setReference(importRef);
}

public CtImport createUnresolvedImport(String reference, boolean isStatic) {
CtUnresolvedImport ctUnresolvedImport = (CtUnresolvedImport) factory.Core().createUnresolvedImport();
ctUnresolvedImport.setUnresolvedReference(reference);
ctUnresolvedImport.setStatic(isStatic);
return ctUnresolvedImport;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.experimental.CtUnresolvedImport;
import spoon.reflect.declaration.CtUsedService;
import spoon.reflect.declaration.CtVariable;
import spoon.reflect.declaration.ModifierKind;
Expand Down Expand Up @@ -1008,6 +1009,13 @@ public void visitCtImport(CtImport ctImport) {
printer.writeSeparator(".");
printer.writeIdentifier("*");
break;
case UNRESOLVED:
CtUnresolvedImport ctUnresolvedImport = (CtUnresolvedImport) ctImport;
if (ctUnresolvedImport.isStatic()) {
printer.writeKeyword("static");
printer.writeSpace();
}
printer.writeCodeSnippet(ctUnresolvedImport.getUnresolvedReference());
}
printer.writeSeparator(";");
printer.writeln();
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/spoon/reflect/visitor/ElementPrinterHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package spoon.reflect.visitor;

import spoon.compiler.Environment;
import spoon.experimental.CtUnresolvedImport;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtComment;
import spoon.reflect.code.CtFor;
Expand Down Expand Up @@ -300,6 +301,18 @@ public void writeImports(Collection<CtImport> imports) {
setStaticImports.add(this.removeInnerTypeSeparator(importTypeStr) + ".*");
}
break;

case UNRESOLVED:
CtUnresolvedImport unresolvedImport = (CtUnresolvedImport) ctImport;
importTypeStr = unresolvedImport.getUnresolvedReference();
if (!isJavaLangClasses(importTypeStr)) {
if (unresolvedImport.isStatic()) {
setStaticImports.add(importTypeStr);
} else {
setImports.add(importTypeStr);
}
}
break;
}
}

Expand Down
42 changes: 38 additions & 4 deletions src/main/java/spoon/reflect/visitor/ImportScannerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package spoon.reflect.visitor;

import spoon.experimental.CtUnresolvedImport;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtCatchVariable;
import spoon.reflect.code.CtFieldAccess;
Expand Down Expand Up @@ -321,7 +322,7 @@ public boolean isImported(CtReference ref) {
@Override
public void initWithImports(Iterable<CtImport> importCollection) {
for (CtImport ctImport : importCollection) {
this.usedImport.put(ctImport, Boolean.FALSE);
this.usedImport.put(ctImport, (ctImport instanceof CtUnresolvedImport) ? Boolean.TRUE : Boolean.FALSE);
}
}

Expand Down Expand Up @@ -434,8 +435,12 @@ protected boolean addClassImport(CtTypeReference<?> ref) {
}
}

classImports.put(ref.getSimpleName(), ref);
return true;
if (!isAlreadyInUsedImport(ref)) {
classImports.put(ref.getSimpleName(), ref);
return true;
} else {
return false;
}
}

private boolean setImportUsed(CtImport ctImport) {
Expand Down Expand Up @@ -496,7 +501,6 @@ private boolean isAlreadyInUsedImport(CtReference ref) {
}
break;


case TYPE:
if (isTypeRef) {
CtTypeReference typeReference = (CtTypeReference) ctImport.getReference();
Expand All @@ -516,6 +520,36 @@ private boolean isAlreadyInUsedImport(CtReference ref) {
}
}
break;

case UNRESOLVED:
CtUnresolvedImport unresolvedImport = (CtUnresolvedImport) ctImport;
String importRef = unresolvedImport.getUnresolvedReference();
String importRefPrefix = null;

if (importRef.contains("*")) {
importRefPrefix = importRef.substring(0, importRef.length() - 1);
}

if (isTypeRef && !unresolvedImport.isStatic()) {
return importRef.equals(refQualifiedName)
|| (importRefPrefix != null
&& refQualifiedName.startsWith(importRefPrefix)
&& !refQualifiedName.substring(importRefPrefix.length()).contains(".")
);
}

if ((isExecRef || isFieldRef) && refDeclaringType != null && unresolvedImport.isStatic()) {
if (isExecRef) {
refQualifiedName = refDeclaringType + "." + ref.getSimpleName();
}
return importRef.equals(refQualifiedName)
|| (importRefPrefix != null
&& refQualifiedName.startsWith(importRefPrefix)
&& !refQualifiedName.substring(importRefPrefix.length()).contains(".")
);
}

break;
}
}
return false;
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/spoon/support/DefaultCoreFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.declaration.CtProvidedService;
import spoon.reflect.declaration.CtTypeParameter;
import spoon.experimental.CtUnresolvedImport;
import spoon.reflect.declaration.CtUsedService;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.factory.Factory;
Expand Down Expand Up @@ -729,6 +730,13 @@ public CtImport createImport() {
return e;
}

@Override
public CtImport createUnresolvedImport() {
CtImport e = new CtUnresolvedImport();
e.setFactory(getMainFactory());
return e;
}

@Override
public CtPackageDeclaration createPackageDeclaration() {
CtPackageDeclaration e = new CtPackageDeclarationImpl();
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/spoon/support/compiler/jdt/JDTImportBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,20 @@ void build() {

if (ctPackage != null) {
this.imports.add(createImportWithPosition(ctPackage.getReference(), importRef));
} else {
if (factory.getEnvironment().getNoClasspath()) {
this.imports.add(createUnresolvedImportWithPosition(importName, false, importRef));
}
}

} else {
CtType klass = this.getOrLoadClass(importName);
if (klass != null) {
this.imports.add(createImportWithPosition(klass.getReference(), importRef));
} else {
if (factory.getEnvironment().getNoClasspath()) {
this.imports.add(createUnresolvedImportWithPosition(importName, false, importRef));
}
}
}
} else {
Expand All @@ -91,6 +99,10 @@ void build() {
this.imports.add(createImportWithPosition(methodOrField.getReference(), importRef));
}
}
} else {
if (factory.getEnvironment().getNoClasspath()) {
this.imports.add(createUnresolvedImportWithPosition(importName, true, importRef));
}
}
}
}
Expand All @@ -109,6 +121,16 @@ private CtImport createImportWithPosition(CtReference ref, ImportReference impor
return imprt;
}

private CtImport createUnresolvedImportWithPosition(String ref, boolean isStatic, ImportReference importRef) {
char[] content = sourceUnit.getContents();
CtImport imprt = factory.Type().createUnresolvedImport(ref, isStatic);
//include comment before import
int declStart = importRef.declarationSourceStart;
int commentStart = PositionBuilder.findNextNonWhitespace(false, content, declStart, PositionBuilder.findPrevNonWhitespace(content, 0, declStart - 1) + 1);
imprt.setPosition(factory.Core().createCompoundSourcePosition(spoonUnit, importRef.sourceStart(), importRef.sourceEnd(), commentStart, importRef.declarationEnd, spoonUnit.getLineSeparatorPositions()));
return imprt;
}

private CtType getOrLoadClass(String className) {
CtType klass = this.factory.Type().get(className);

Expand Down
Loading

0 comments on commit d0aebbb

Please sign in to comment.