Store alias name with import path
This commit is contained in:
@@ -26,6 +26,7 @@ import com.intellij.util.LocalTimeCounter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.ImportPath;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetFileType;
|
||||
@@ -179,11 +180,6 @@ public class JetPsiFactory {
|
||||
|
||||
@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");
|
||||
}
|
||||
@@ -191,12 +187,9 @@ public class JetPsiFactory {
|
||||
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);
|
||||
Name alias = importPath.getAlias();
|
||||
if (alias != null) {
|
||||
importDirectiveBuilder.append(" as ").append(alias.getName());
|
||||
}
|
||||
|
||||
JetFile namespace = createFile(project, importDirectiveBuilder.toString());
|
||||
|
||||
@@ -258,17 +258,22 @@ public class JetPsiUtil {
|
||||
@Nullable
|
||||
@IfNotParsed
|
||||
public static ImportPath getImportPath(JetImportDirective importDirective) {
|
||||
if (PsiTreeUtil.hasErrorElements(importDirective)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final JetExpression importedReference = importDirective.getImportedReference();
|
||||
if (importedReference == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (PsiTreeUtil.hasErrorElements(importedReference)) {
|
||||
return null;
|
||||
Name alias = null;
|
||||
String aliasName = importDirective.getAliasName();
|
||||
if (aliasName != null) {
|
||||
alias = Name.identifier(aliasName);
|
||||
}
|
||||
|
||||
final String text = importedReference.getText();
|
||||
return new ImportPath(text.replaceAll(" ", "") + (importDirective.isAllUnder() ? ".*" : ""));
|
||||
return new ImportPath(new FqName(importedReference.getText().replaceAll(" ", "")), importDirective.isAllUnder(), alias);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -17,15 +17,23 @@
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public final class ImportPath {
|
||||
private final @NotNull FqName fqName;
|
||||
private final @Nullable Name alias;
|
||||
private final boolean isAllUnder;
|
||||
|
||||
public ImportPath(@NotNull FqName fqName, boolean isAllUnder) {
|
||||
this(fqName, isAllUnder, null);
|
||||
}
|
||||
|
||||
public ImportPath(@NotNull FqName fqName, boolean isAllUnder, @Nullable Name alias) {
|
||||
this.fqName = fqName;
|
||||
this.isAllUnder = isAllUnder;
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
public ImportPath(@NotNull String pathStr) {
|
||||
@@ -37,6 +45,8 @@ public final class ImportPath {
|
||||
this.isAllUnder = false;
|
||||
this.fqName = new FqName(pathStr);
|
||||
}
|
||||
|
||||
alias = null;
|
||||
}
|
||||
|
||||
public String getPathStr() {
|
||||
@@ -45,7 +55,7 @@ public final class ImportPath {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getPathStr();
|
||||
return getPathStr() + (alias != null ? " as " + alias.getName() : "");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -53,21 +63,47 @@ public final class ImportPath {
|
||||
return fqName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Name getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public boolean hasAlias() {
|
||||
return alias != null;
|
||||
}
|
||||
|
||||
public boolean isAllUnder() {
|
||||
return isAllUnder;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Name getImportedName() {
|
||||
if (!isAllUnder()) {
|
||||
return alias != null ? alias : fqName.shortName();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
ImportPath path = (ImportPath) o;
|
||||
|
||||
if (isAllUnder != path.isAllUnder) return false;
|
||||
if (alias != null ? !alias.equals(path.alias) : path.alias != null) return false;
|
||||
if (!fqName.equals(path.fqName)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@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);
|
||||
int result = fqName.hashCode();
|
||||
result = 31 * result + (alias != null ? alias.hashCode() : 0);
|
||||
result = 31 * result + (isAllUnder ? 1 : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,10 @@ public final class QualifiedNamesUtil {
|
||||
}
|
||||
|
||||
public static boolean isImported(@NotNull ImportPath alreadyImported, @NotNull FqName fqName) {
|
||||
if (alreadyImported.hasAlias()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (alreadyImported.isAllUnder() && !fqName.isRoot()) {
|
||||
return alreadyImported.fqnPart().equals(fqName.parent());
|
||||
}
|
||||
@@ -132,7 +136,7 @@ public final class QualifiedNamesUtil {
|
||||
}
|
||||
|
||||
public static boolean isImported(@NotNull ImportPath alreadyImported, @NotNull ImportPath newImport) {
|
||||
if (newImport.isAllUnder()) {
|
||||
if (newImport.isAllUnder() || newImport.hasAlias()) {
|
||||
return alreadyImported.equals(newImport);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class JetExplicitlyImportedWeigher extends LookupElementWeigher {
|
||||
// Invalid name can be met for class object descriptor: Test.MyTest.A.<no name provided>.testOther
|
||||
if (FqName.isValid(fqName.toString())) {
|
||||
ImportPath importPath = new ImportPath(fqName.toString());
|
||||
if (ImportInsertHelper.doNeedImport(importPath, null, file)) {
|
||||
if (ImportInsertHelper.doNeedImport(importPath, file)) {
|
||||
return MyResult.notImported;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -101,8 +101,8 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isUseful(importPath, anImport.getAliasName(), usedQualifiedNames)) {
|
||||
ImportInsertHelper.addImportDirective(importPath, anImport.getAliasName(), jetFile);
|
||||
if (isUseful(importPath, usedQualifiedNames)) {
|
||||
ImportInsertHelper.addImportDirective(importPath, jetFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -111,8 +111,8 @@ public class JetImportOptimizer implements ImportOptimizer {
|
||||
};
|
||||
}
|
||||
|
||||
public static boolean isUseful(ImportPath importPath, @Nullable String aliasName, Collection<FqName> usedNames) {
|
||||
if (aliasName != null) {
|
||||
public static boolean isUseful(ImportPath importPath, Collection<FqName> usedNames) {
|
||||
if (importPath.hasAlias()) {
|
||||
// TODO: Add better analysis for aliases
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class ImportClassAndFunFix extends JetHintAction<JetSimpleNameExpression>
|
||||
@Override
|
||||
public boolean apply(@Nullable FqName fqName) {
|
||||
assert fqName != null;
|
||||
return ImportInsertHelper.doNeedImport(new ImportPath(fqName, false), null, (JetFile) file);
|
||||
return ImportInsertHelper.doNeedImport(new ImportPath(fqName, false), (JetFile) file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class ImportInsertHelper {
|
||||
* @param file File where directive should be added.
|
||||
*/
|
||||
public static void addImportDirective(@NotNull FqName importFqn, @NotNull JetFile file) {
|
||||
addImportDirective(new ImportPath(importFqn, false), null, file);
|
||||
addImportDirective(new ImportPath(importFqn, false), file);
|
||||
}
|
||||
|
||||
public static void addImportDirectiveOrChangeToFqName(@NotNull FqName importFqn, @NotNull JetFile file, int refOffset, @NotNull PsiElement targetElement) {
|
||||
@@ -109,15 +109,15 @@ public class ImportInsertHelper {
|
||||
return;
|
||||
}
|
||||
}
|
||||
addImportDirective(new ImportPath(importFqn, false), null, file);
|
||||
addImportDirective(new ImportPath(importFqn, false), file);
|
||||
}
|
||||
|
||||
public static void addImportDirective(@NotNull ImportPath importPath, @Nullable String aliasName, @NotNull JetFile file) {
|
||||
if (!doNeedImport(importPath, aliasName, file)) {
|
||||
public static void addImportDirective(@NotNull ImportPath importPath, @NotNull JetFile file) {
|
||||
if (!doNeedImport(importPath, file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
JetImportDirective newDirective = JetPsiFactory.createImportDirective(file.getProject(), importPath, aliasName);
|
||||
JetImportDirective newDirective = JetPsiFactory.createImportDirective(file.getProject(), importPath);
|
||||
List<JetImportDirective> importDirectives = file.getImportDirectives();
|
||||
|
||||
if (!importDirectives.isEmpty()) {
|
||||
@@ -125,34 +125,36 @@ public class ImportInsertHelper {
|
||||
lastDirective.getParent().addAfter(newDirective, lastDirective);
|
||||
}
|
||||
else {
|
||||
file.getNamespaceHeader().getParent().addAfter(newDirective, file.getNamespaceHeader());
|
||||
JetNamespaceHeader header = file.getNamespaceHeader();
|
||||
if (header == null) {
|
||||
throw new IllegalStateException("Scripts are not supported: " + file.getName());
|
||||
}
|
||||
|
||||
header.getParent().addAfter(newDirective, file.getNamespaceHeader());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that import is useless.
|
||||
*/
|
||||
private static boolean isImportedByDefault(@NotNull ImportPath importPath, @Nullable String aliasName, @NotNull FqName filePackageFqn) {
|
||||
private static boolean isImportedByDefault(@NotNull ImportPath importPath, @NotNull FqName filePackageFqn) {
|
||||
if (importPath.fqnPart().isRoot()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aliasName != null) {
|
||||
return false;
|
||||
}
|
||||
if (!importPath.isAllUnder() && !importPath.hasAlias()) {
|
||||
// Single element import without .* and alias is useless
|
||||
if (QualifiedNamesUtil.isOneSegmentFQN(importPath.fqnPart())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Single element import without .* and alias is useless
|
||||
if (!importPath.isAllUnder() && QualifiedNamesUtil.isOneSegmentFQN(importPath.fqnPart())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// There's no need to import a declaration from the package of current file
|
||||
if (!importPath.isAllUnder() && filePackageFqn.equals(importPath.fqnPart().parent())) {
|
||||
return true;
|
||||
// There's no need to import a declaration from the package of current file
|
||||
if (filePackageFqn.equals(importPath.fqnPart().parent())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isImportedWithKotlinDefault(importPath)) return true;
|
||||
|
||||
if (isImportedWithJavaDefault(importPath)) return true;
|
||||
|
||||
return false;
|
||||
@@ -176,13 +178,13 @@ public class ImportInsertHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean doNeedImport(@NotNull ImportPath importPath, @Nullable String aliasName, @NotNull JetFile file) {
|
||||
if (QualifiedNamesUtil.getFirstSegment(importPath.fqnPart().getFqName()).equals(JavaDescriptorResolver.JAVA_ROOT.getName())) {
|
||||
public static boolean doNeedImport(@NotNull ImportPath importPath, @NotNull JetFile file) {
|
||||
if (importPath.fqnPart().firstSegmentIs(JavaDescriptorResolver.JAVA_ROOT)) {
|
||||
FqName withoutJavaRoot = QualifiedNamesUtil.withoutFirstSegment(importPath.fqnPart());
|
||||
importPath = new ImportPath(withoutJavaRoot, importPath.isAllUnder());
|
||||
importPath = new ImportPath(withoutJavaRoot, importPath.isAllUnder(), importPath.getAlias());
|
||||
}
|
||||
|
||||
if (isImportedByDefault(importPath, null, JetPsiUtil.getFQName(file))) {
|
||||
if (isImportedByDefault(importPath, JetPsiUtil.getFQName(file))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -192,10 +194,8 @@ public class ImportInsertHelper {
|
||||
// Check if import is already present
|
||||
for (JetImportDirective directive : importDirectives) {
|
||||
ImportPath existentImportPath = JetPsiUtil.getImportPath(directive);
|
||||
if (directive.getAliasName() == null && aliasName == null) {
|
||||
if (existentImportPath != null && QualifiedNamesUtil.isImported(existentImportPath, importPath)) {
|
||||
return false;
|
||||
}
|
||||
if (existentImportPath != null && QualifiedNamesUtil.isImported(existentImportPath, importPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user