KT-1426 Implement "Optimize Imports" in plugin - untested draft version
This commit is contained in:
+4
-3
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -36,7 +37,7 @@ import java.util.Collections;
|
||||
*/
|
||||
public class JavaBridgeConfiguration implements ModuleConfiguration {
|
||||
|
||||
public static final String[] DEFAULT_JAVA_IMPORTS = new String[] { "java.lang.*" };
|
||||
public static final ImportPath[] DEFAULT_JAVA_IMPORTS = new ImportPath[] { new ImportPath("java.lang.*") };
|
||||
|
||||
public static ModuleConfiguration createJavaBridgeConfiguration(@NotNull Project project, @NotNull BindingTrace trace, ModuleConfiguration delegateConfiguration) {
|
||||
return new JavaBridgeConfiguration(project, trace, delegateConfiguration);
|
||||
@@ -54,8 +55,8 @@ public class JavaBridgeConfiguration implements ModuleConfiguration {
|
||||
|
||||
@Override
|
||||
public void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection<JetImportDirective> directives) {
|
||||
for (String importFQN : DEFAULT_JAVA_IMPORTS) {
|
||||
directives.add(JetPsiFactory.createImportDirective(project, importFQN));
|
||||
for (ImportPath importPath : DEFAULT_JAVA_IMPORTS) {
|
||||
directives.add(JetPsiFactory.createImportDirective(project, importPath));
|
||||
}
|
||||
delegateConfiguration.addDefaultImports(rootScope, directives);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetImportDirective;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.resolve.BindingTrace;
|
||||
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -30,7 +31,8 @@ import java.util.Collection;
|
||||
* @author svtk
|
||||
*/
|
||||
public class DefaultModuleConfiguration implements ModuleConfiguration {
|
||||
public static final String[] DEFAULT_JET_IMPORTS = new String[] { "kotlin.*", "kotlin.io.*" };
|
||||
public static final ImportPath[] DEFAULT_JET_IMPORTS = new ImportPath[] {
|
||||
new ImportPath("kotlin.*"), new ImportPath("kotlin.io.*") };
|
||||
|
||||
private Project project;
|
||||
|
||||
@@ -44,7 +46,7 @@ public class DefaultModuleConfiguration implements ModuleConfiguration {
|
||||
|
||||
@Override
|
||||
public void addDefaultImports(@NotNull WritableScope rootScope, @NotNull Collection<JetImportDirective> directives) {
|
||||
for (String defaultJetImport : DEFAULT_JET_IMPORTS) {
|
||||
for (ImportPath defaultJetImport : DEFAULT_JET_IMPORTS) {
|
||||
directives.add(JetPsiFactory.createImportDirective(project, defaultJetImport));
|
||||
}
|
||||
}
|
||||
@@ -52,5 +54,4 @@ public class DefaultModuleConfiguration implements ModuleConfiguration {
|
||||
@Override
|
||||
public void extendNamespaceScope(@NotNull BindingTrace trace, @NotNull NamespaceDescriptor namespaceDescriptor, @NotNull WritableScope namespaceMemberScope) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
@@ -140,21 +140,35 @@ public class JetPsiFactory {
|
||||
return function.getValueParameters().get(0);
|
||||
}
|
||||
|
||||
// public static JetNamespace createNamespace(Project project, String text) {
|
||||
// JetFile file = createFile(project, text);
|
||||
// return file.getRootNamespace();
|
||||
// }
|
||||
|
||||
public static JetImportDirective createImportDirective(Project project, @NotNull String classPath) {
|
||||
if (classPath.isEmpty()) {
|
||||
throw new IllegalArgumentException("import path must not be empty");
|
||||
}
|
||||
JetFile namespace = createFile(project, "import " + classPath);
|
||||
return namespace.getImportDirectives().iterator().next();
|
||||
@NotNull
|
||||
public static JetImportDirective createImportDirective(Project project, @NotNull String path) {
|
||||
return createImportDirective(project, new ImportPath(path));
|
||||
}
|
||||
|
||||
public static JetImportDirective createImportDirective(Project project, @NotNull FqName fqName) {
|
||||
return createImportDirective(project, fqName.getFqName());
|
||||
@NotNull
|
||||
public static JetImportDirective createImportDirective(Project project, @NotNull ImportPath importPath) {
|
||||
return createImportDirective(project, importPath, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetImportDirective createImportDirective(Project project, @NotNull ImportPath importPath, @Nullable String aliasName) {
|
||||
if (importPath.fqnPart().isRoot()) {
|
||||
throw new IllegalArgumentException("import path must not be empty");
|
||||
}
|
||||
|
||||
StringBuilder importDirectiveBuilder = new StringBuilder("import ");
|
||||
importDirectiveBuilder.append(importPath.getPathStr());
|
||||
|
||||
if (aliasName != null) {
|
||||
if (aliasName.isEmpty()) {
|
||||
throw new IllegalArgumentException("Alias must not be empty");
|
||||
}
|
||||
|
||||
importDirectiveBuilder.append(" as ").append(aliasName);
|
||||
}
|
||||
|
||||
JetFile namespace = createFile(project, importDirectiveBuilder.toString());
|
||||
return namespace.getImportDirectives().iterator().next();
|
||||
}
|
||||
|
||||
public static PsiElement createPrimaryConstructor(Project project) {
|
||||
|
||||
@@ -23,8 +23,8 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.util.QualifiedNamesUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@@ -194,14 +194,14 @@ public class JetPsiUtil {
|
||||
}
|
||||
|
||||
@Nullable @JetElement.IfNotParsed
|
||||
public static String getImportPath(JetImportDirective importDirective) {
|
||||
public static ImportPath getImportPath(JetImportDirective importDirective) {
|
||||
final JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String text = importedReference.getText();
|
||||
return text.replaceAll(" ", "") + (importDirective.isAllUnder() ? ".*" : "");
|
||||
return new ImportPath(text.replaceAll(" ", "") + (importDirective.isAllUnder() ? ".*" : ""));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public final class ImportPath {
|
||||
final @NotNull FqName fqName;
|
||||
final boolean isAllUnder;
|
||||
|
||||
public ImportPath(@NotNull FqName fqName, boolean isAllUnder) {
|
||||
this.fqName = fqName;
|
||||
this.isAllUnder = isAllUnder;
|
||||
}
|
||||
|
||||
public ImportPath(@NotNull String pathStr) {
|
||||
if (pathStr.endsWith(".*")) {
|
||||
this.isAllUnder = true;
|
||||
this.fqName = new FqName(pathStr.substring(0, pathStr.length() - 2));
|
||||
}
|
||||
else {
|
||||
this.isAllUnder = false;
|
||||
this.fqName = new FqName(pathStr);
|
||||
}
|
||||
}
|
||||
|
||||
public String getPathStr() {
|
||||
return fqName.getFqName() + (isAllUnder ? ".*" : "");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FqName fqnPart() {
|
||||
return fqName;
|
||||
}
|
||||
|
||||
public boolean isAllUnder() {
|
||||
return isAllUnder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 31 * fqName.hashCode() + (isAllUnder ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof ImportPath)) return false;
|
||||
|
||||
ImportPath other = (ImportPath) obj;
|
||||
return fqName.equals(other.fqName) && (isAllUnder == other.isAllUnder);
|
||||
}
|
||||
}
|
||||
@@ -19,14 +19,18 @@ package org.jetbrains.jet.util;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||
|
||||
/**
|
||||
* Common methods for working with qualified names strings.
|
||||
* Common methods for working with qualified names.
|
||||
*
|
||||
* @author Nikolay Krasko
|
||||
*/
|
||||
public final class QualifiedNamesUtil {
|
||||
|
||||
private QualifiedNamesUtil() {
|
||||
}
|
||||
|
||||
public static boolean isSubpackageOf(@NotNull final FqName subpackageName, @NotNull FqName packageName) {
|
||||
return subpackageName.equals(packageName) ||
|
||||
(subpackageName.getFqName().startsWith(packageName.getFqName()) && subpackageName.getFqName().charAt(packageName.getFqName().length()) == '.');
|
||||
@@ -45,6 +49,10 @@ public final class QualifiedNamesUtil {
|
||||
return fqn.indexOf('.') < 0;
|
||||
}
|
||||
|
||||
public static boolean isOneSegmentFQN(@NotNull FqName fqn) {
|
||||
return isOneSegmentFQN(fqn.getFqName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String fqnToShortName(@NotNull FqName fqn) {
|
||||
return getLastSegment(fqn);
|
||||
@@ -62,18 +70,18 @@ public final class QualifiedNamesUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String withoutLastSegment(@NotNull String fqn) {
|
||||
final int lastDotIndex = fqn.lastIndexOf('.');
|
||||
if (lastDotIndex > 0) {
|
||||
return fqn.substring(0, lastDotIndex);
|
||||
}
|
||||
|
||||
return "";
|
||||
public static FqName withoutLastSegment(@NotNull FqName fqName) {
|
||||
return fqName.parent();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static FqName withoutLastSegment(@NotNull FqName fqName) {
|
||||
return fqName.parent();
|
||||
public static FqName withoutFirstSegment(@NotNull FqName fqName) {
|
||||
if (fqName.isRoot() || fqName.parent().isRoot()) {
|
||||
return FqName.ROOT;
|
||||
}
|
||||
|
||||
String fqNameStr = fqName.getFqName();
|
||||
return new FqName(fqNameStr.substring(fqNameStr.indexOf('.'), fqNameStr.length()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -121,18 +129,19 @@ public final class QualifiedNamesUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that given fqn could be imported with import.
|
||||
*
|
||||
* @param importPath path from the import. Could contain .* part
|
||||
* @param fqn or another import directive
|
||||
*/
|
||||
public static boolean isImported(@NotNull String importPath, @NotNull String fqn) {
|
||||
if (importPath.endsWith("*")) {
|
||||
// TODO: import path is not valid FQN
|
||||
return withoutLastSegment(importPath).equals(withoutLastSegment(fqn));
|
||||
public static boolean isImported(@NotNull ImportPath alreadyImported, @NotNull FqName fqName) {
|
||||
if (alreadyImported.isAllUnder()) {
|
||||
return alreadyImported.fqnPart().equals(fqName.parent());
|
||||
}
|
||||
|
||||
return importPath.equals(fqn);
|
||||
return alreadyImported.fqnPart().equals(fqName);
|
||||
}
|
||||
|
||||
public static boolean isImported(@NotNull ImportPath alreadyImported, @NotNull ImportPath newImport) {
|
||||
if (newImport.isAllUnder()) {
|
||||
return alreadyImported.equals(newImport);
|
||||
}
|
||||
|
||||
return isImported(alreadyImported, newImport.fqnPart());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user