Added auto-importing in JetChangePropertyActions.addTypeAnnotation(). It is used in "specify type explicitly" intention and "introduce variable" refactoring. Corrected auto-importing for cases of nested classes (e.g. Map.Entry).

This commit is contained in:
Evgeny Gerashchenko
2012-04-21 02:39:23 +04:00
parent 32605248c5
commit 82b4304f0e
8 changed files with 68 additions and 24 deletions
@@ -529,6 +529,23 @@ public class TypeUtils {
return null;
}
private static void addAllClassDescriptors(@NotNull JetType type, @NotNull Set<ClassDescriptor> set) {
ClassDescriptor cd = getClassDescriptor(type);
if (cd != null) {
set.add(cd);
}
for (TypeProjection projection : type.getArguments()) {
addAllClassDescriptors(projection.getType(), set);
}
}
@NotNull
public static List<ClassDescriptor> getAllClassDescriptors(@NotNull JetType type) {
Set<ClassDescriptor> classDescriptors = new HashSet<ClassDescriptor>();
addAllClassDescriptors(type, classDescriptors);
return new ArrayList<ClassDescriptor>(classDescriptors);
}
public static boolean hasUnsubstitutedTypeParameters(JetType type) {
if (type.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
return true;
@@ -30,10 +30,7 @@ import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.*;
/**
* @author abreslav
@@ -122,6 +119,15 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
}
}
private static List<String> getOuterClassesNames(ClassDescriptor cd) {
ArrayList<String> result = new ArrayList<String>();
while (cd.getContainingDeclaration() instanceof ClassifierDescriptor) {
result.add(cd.getName());
cd = (ClassDescriptor)cd.getContainingDeclaration();
}
return result;
}
private String renderDefaultType(JetType type, boolean shortNamesOnly) {
StringBuilder sb = new StringBuilder();
ClassifierDescriptor cd = type.getConstructor().getDeclarationDescriptor();
@@ -132,7 +138,18 @@ public class DescriptorRenderer implements Renderer<DeclarationDescriptor> {
typeNameObject = type.getConstructor();
}
else {
typeNameObject = shortNamesOnly ? cd.getName() : DescriptorUtils.getFQName(cd);
if (shortNamesOnly) {
// for nested classes qualified name should be used
typeNameObject = cd.getName();
DeclarationDescriptor parent = cd.getContainingDeclaration();
while (parent instanceof ClassDescriptor) {
typeNameObject = parent.getName() + "." + typeNameObject;
parent = parent.getContainingDeclaration();
}
}
else {
typeNameObject = DescriptorUtils.getFQName(cd);
}
}
sb.append(typeNameObject);
@@ -37,12 +37,6 @@ import java.util.LinkedList;
* @author svtk
*/
public class JetPluginUtil {
@NotNull
public static FqName computeTypeFullName(@NotNull JetType type) {
ClassDescriptor clazz = (ClassDescriptor) type.getConstructor().getDeclarationDescriptor();
return DescriptorUtils.getFQName(clazz).toSafe();
}
@NotNull
private static LinkedList<String> computeTypeFullNameList(JetType type) {
if (type instanceof DeferredType) {
@@ -131,7 +131,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
}
bodyBuilder.append(descriptor.getName()).append(" : ").append(DescriptorRenderer.COMPACT.renderTypeWithShortNames(
descriptor.getType()));
ImportInsertHelper.addImportDirectiveIfNeeded(descriptor.getType(), file);
ImportInsertHelper.addImportDirectivesIfNeeded(descriptor.getType(), file);
String initializer = defaultInitializer(descriptor.getType(), JetStandardLibrary.getInstance());
if (initializer != null) {
bodyBuilder.append(" = ").append(initializer);
@@ -168,7 +168,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
bodyBuilder.append(" : ");
bodyBuilder.append(DescriptorRenderer.COMPACT.renderTypeWithShortNames(parameterDescriptor.getType()));
ImportInsertHelper.addImportDirectiveIfNeeded(parameterDescriptor.getType(), file);
ImportInsertHelper.addImportDirectivesIfNeeded(parameterDescriptor.getType(), file);
if (!isAbstractFun) {
delegationBuilder.append(parameterDescriptor.getName());
@@ -184,7 +184,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
boolean returnsNotUnit = returnType != null && !stdlib.getTuple0Type().equals(returnType);
if (returnsNotUnit) {
bodyBuilder.append(" : ").append(DescriptorRenderer.COMPACT.renderTypeWithShortNames(returnType));
ImportInsertHelper.addImportDirectiveIfNeeded(returnType, file);
ImportInsertHelper.addImportDirectivesIfNeeded(returnType, file);
}
bodyBuilder.append("{").append(returnsNotUnit && !isAbstractFun ? "return " : "").append(delegationBuilder.toString()).append("}");
@@ -68,7 +68,7 @@ public class AddReturnTypeFix extends JetIntentionAction<JetNamedDeclaration> {
assert element instanceof JetFunction;
newElement = addFunctionType(project, (JetFunction) element, type);
}
ImportInsertHelper.addImportDirectiveIfNeeded(type, (JetFile) file);
ImportInsertHelper.addImportDirectivesIfNeeded(type, (JetFile)file);
element.replace(newElement);
}
@@ -17,22 +17,21 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.psi.PsiElement;
import com.intellij.usages.impl.rules.NonCodeUsageGroupingRule;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.DefaultModuleConfiguration;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.ImportPath;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.java.JavaBridgeConfiguration;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.plugin.JetPluginUtil;
import org.jetbrains.jet.util.QualifiedNamesUtil;
@@ -53,7 +52,7 @@ public class ImportInsertHelper {
* @param type type to import
* @param file file where import directive should be added
*/
public static void addImportDirectiveIfNeeded(@NotNull JetType type, @NotNull JetFile file) {
public static void addImportDirectivesIfNeeded(@NotNull JetType type, @NotNull JetFile file) {
if (JetPluginUtil.checkTypeIsStandard(type, file.getProject()) || ErrorUtils.isErrorType(type)) {
return;
}
@@ -62,7 +61,9 @@ public class ImportInsertHelper {
if (element != null && element.getContainingFile() == file) { //declaration is in the same file, so no import is needed
return;
}
addImportDirective(JetPluginUtil.computeTypeFullName(type), file);
for (ClassDescriptor clazz : TypeUtils.getAllClassDescriptors(type)) {
addImportDirective(DescriptorUtils.getFQName(getTopLevelClass(clazz)).toSafe(), file);
}
}
/**
@@ -155,4 +156,15 @@ public class ImportInsertHelper {
return true;
}
private static ClassDescriptor getTopLevelClass(ClassDescriptor classDescriptor) {
while (true) {
DeclarationDescriptor parent = classDescriptor.getContainingDeclaration();
if (parent instanceof ClassDescriptor) {
classDescriptor = (ClassDescriptor) parent;
} else {
return classDescriptor;
}
}
}
}
@@ -119,7 +119,7 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction<JetProperty>
}
}
if (needImport) {
ImportInsertHelper.addImportDirectiveIfNeeded(type, (JetFile) file);
ImportInsertHelper.addImportDirectivesIfNeeded(type, (JetFile)file);
}
element.replace(newElement);
}
@@ -5,10 +5,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetTypeReference;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.quickfix.ImportInsertHelper;
import org.jetbrains.jet.resolve.DescriptorRenderer;
/**
* User: Alefas
@@ -35,13 +38,14 @@ public class JetChangePropertyActions {
if (anchor == null) return;
anchor = anchor.getNextSibling();
if (anchor == null || !(anchor instanceof PsiWhiteSpace)) return;
JetTypeReference typeReference = JetPsiFactory.createType(project, exprType.toString());
JetTypeReference typeReference = JetPsiFactory.createType(project, DescriptorRenderer.TEXT.renderTypeWithShortNames(exprType));
ASTNode colon = JetPsiFactory.createColonNode(project);
ASTNode anchorNode = anchor.getNode().getTreeNext();
property.getNode().addChild(colon, anchorNode);
property.getNode().addChild(JetPsiFactory.createWhiteSpace(project).getNode(), anchorNode);
property.getNode().addChild(typeReference.getNode(), anchorNode);
property.getNode().addChild(JetPsiFactory.createWhiteSpace(project).getNode(), anchorNode);
ImportInsertHelper.addImportDirectivesIfNeeded(exprType, (JetFile)property.getContainingFile());
anchor.delete();
}