KT-1426 Implement "Optimize Imports" in plugin - do not remove imports for objects

This commit is contained in:
Nikolay Krasko
2012-03-20 18:47:25 +04:00
parent 5bcef67dfe
commit 2519f4d7f2
5 changed files with 60 additions and 45 deletions
@@ -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
}