KT-1426 Implement "Optimize Imports" in plugin - do not remove imports for objects
This commit is contained in:
@@ -145,49 +145,37 @@ public class JetPsiUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FqName getFQName(@NotNull JetClassOrObject jetClass) {
|
||||
if (jetClass.getName() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiElement parent = jetClass.getParent();
|
||||
if (parent instanceof JetFile) {
|
||||
return makeFQName(getFQName((JetFile) parent), jetClass);
|
||||
}
|
||||
while (parent instanceof JetClassBody) {
|
||||
parent = parent.getParent();
|
||||
if (parent instanceof JetObjectDeclaration && parent.getParent() instanceof JetClassObject) {
|
||||
parent = parent.getParent().getParent();
|
||||
public static FqName getFQName(JetNamedDeclaration namedDeclaration) {
|
||||
if (namedDeclaration instanceof JetObjectDeclarationName) {
|
||||
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(namedDeclaration, JetObjectDeclaration.class);
|
||||
if (objectDeclaration == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (parent instanceof JetClassOrObject) {
|
||||
return makeFQName(getFQName(((JetClassOrObject) parent)), jetClass);
|
||||
}
|
||||
return new FqName(jetClass.getName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static FqName getFQName(@NotNull JetNamedFunction jetNamedFunction) {
|
||||
return getFQName(objectDeclaration);
|
||||
}
|
||||
|
||||
String functionName = jetNamedFunction.getName();
|
||||
String functionName = namedDeclaration.getName();
|
||||
if (functionName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
PsiElement qualifiedElement = PsiTreeUtil.getParentOfType(
|
||||
jetNamedFunction,
|
||||
JetFile.class, JetClassOrObject.class, JetNamedFunction.class);
|
||||
PsiElement parent = namedDeclaration.getParent();
|
||||
if (parent instanceof JetClassBody) {
|
||||
// One nesting to JetClassBody doesn't affect to qualified name
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
FqName firstPart = FqName.ROOT;
|
||||
if (qualifiedElement instanceof JetFile) {
|
||||
firstPart = getFQName((JetFile) qualifiedElement);
|
||||
FqName firstPart = null;
|
||||
if (parent instanceof JetFile) {
|
||||
firstPart = getFQName((JetFile) parent);
|
||||
}
|
||||
else if (qualifiedElement instanceof JetClassOrObject) {
|
||||
firstPart = getFQName((JetClassOrObject) qualifiedElement);
|
||||
else if (parent instanceof JetNamedDeclaration) {
|
||||
firstPart = getFQName((JetNamedDeclaration) parent);
|
||||
}
|
||||
else if (qualifiedElement instanceof JetNamedFunction) {
|
||||
firstPart = getFQName((JetNamedFunction) qualifiedElement);
|
||||
|
||||
if (firstPart == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return firstPart.child(functionName);
|
||||
|
||||
@@ -130,7 +130,7 @@ public final class QualifiedNamesUtil {
|
||||
}
|
||||
|
||||
public static boolean isImported(@NotNull ImportPath alreadyImported, @NotNull FqName fqName) {
|
||||
if (alreadyImported.isAllUnder()) {
|
||||
if (alreadyImported.isAllUnder() && !fqName.isRoot()) {
|
||||
return alreadyImported.fqnPart().equals(fqName.parent());
|
||||
}
|
||||
|
||||
|
||||
@@ -83,9 +83,17 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
// Remove imports
|
||||
List<JetImportDirective> imports = jetFile.getImportDirectives();
|
||||
if (!imports.isEmpty()) {
|
||||
jetFile.deleteChildRange(
|
||||
getWithPreviousWhitespaces(imports.get(0)),
|
||||
getWithFollowedWhitespaces(imports.get(imports.size() - 1)));
|
||||
PsiElement firstForDelete = getWithPreviousWhitespaces(imports.get(0));
|
||||
PsiElement lastForDelete = getWithFollowedWhitespaces(imports.get(imports.size() - 1));
|
||||
|
||||
// Should be found before deletion
|
||||
PsiElement elementBeforeImports = firstForDelete.getPrevSibling();
|
||||
|
||||
jetFile.deleteChildRange(firstForDelete, lastForDelete);
|
||||
|
||||
if (elementBeforeImports != null) {
|
||||
jetFile.addAfter(JetPsiFactory.createWhiteSpace(jetFile.getProject(), "\n"), elementBeforeImports);
|
||||
}
|
||||
}
|
||||
|
||||
// Insert back only necessary imports in correct order
|
||||
@@ -120,7 +128,7 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Set<FqName> extractUsedQualifiedNames(JetFile jetFile) {
|
||||
public static Set<FqName> extractUsedQualifiedNames(final JetFile jetFile) {
|
||||
final Set<FqName> usedQualifiedNames = new HashSet<FqName>();
|
||||
jetFile.accept(new JetVisitorVoid() {
|
||||
@Override
|
||||
@@ -131,7 +139,9 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(JetReferenceExpression expression) {
|
||||
if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class) == null) {
|
||||
if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class) == null &&
|
||||
PsiTreeUtil.getParentOfType(expression, JetNamespaceHeader.class) == null) {
|
||||
|
||||
PsiReference reference = expression.getReference();
|
||||
if (reference != null) {
|
||||
List<PsiElement> references = new ArrayList<PsiElement>();
|
||||
@@ -141,7 +151,7 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
}
|
||||
|
||||
if (references.isEmpty() && reference instanceof PsiPolyVariantReference) {
|
||||
for (ResolveResult resolveResult : ((PsiPolyVariantReference) reference).multiResolve(true)) {
|
||||
for (ResolveResult resolveResult : ((PsiPolyVariantReference)reference).multiResolve(true)) {
|
||||
references.add(resolveResult.getElement());
|
||||
}
|
||||
}
|
||||
@@ -153,7 +163,6 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
super.visitReferenceExpression(expression);
|
||||
@@ -166,18 +175,22 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
|
||||
@Nullable
|
||||
public static FqName getElementUsageFQName(PsiElement element) {
|
||||
if (element instanceof JetClassOrObject) {
|
||||
return JetPsiUtil.getFQName((JetClassOrObject) element);
|
||||
if (element instanceof JetFile) {
|
||||
return JetPsiUtil.getFQName((JetFile) element);
|
||||
}
|
||||
if (element instanceof JetNamedFunction) {
|
||||
return JetPsiUtil.getFQName((JetNamedFunction) element);
|
||||
|
||||
if (element instanceof JetNamedDeclaration) {
|
||||
return JetPsiUtil.getFQName((JetNamedDeclaration) element);
|
||||
}
|
||||
|
||||
if (element instanceof PsiClass) {
|
||||
String qualifiedName = ((PsiClass) element).getQualifiedName();
|
||||
if (qualifiedName != null) {
|
||||
return new FqName(qualifiedName);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Still problem with kotlin global properties imported from class files
|
||||
if (element instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) element;
|
||||
|
||||
@@ -201,6 +214,10 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
}
|
||||
}
|
||||
|
||||
if (element instanceof PsiPackage) {
|
||||
return new FqName(((PsiPackage) element).getQualifiedName());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,15 @@ import java.net.HttpRetryException
|
||||
import java.util.ArrayList
|
||||
import kotlin.util.measureTimeMillis
|
||||
import java.util.HashMap
|
||||
import kotlin.test.asserter
|
||||
import kotlin.test.Asserter
|
||||
import kotlin.Assertions
|
||||
|
||||
class Action {
|
||||
fun test() {
|
||||
// val traait : Asserter = asserter
|
||||
val traait : Asserter? = null
|
||||
val objectImport : Assertions? = null
|
||||
measureTimeMillis({ println(HashMap<String, Int>().size()) })
|
||||
val test : ArrayList<Int>? = null
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
import kotlin.test.Asserter
|
||||
import kotlin.util.measureTimeMillis
|
||||
|
||||
class Action {
|
||||
fun test() {
|
||||
// val traait : Asserter = asserter
|
||||
val traait : Asserter? = null
|
||||
val objectImport : Assertions? = null
|
||||
measureTimeMillis({ println(HashMap<String, Int>().size()) })
|
||||
val test : ArrayList<Int>? = null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user