ChooseTypeExpression should insert imports for completed types

This commit is contained in:
Max Medvedev
2012-09-10 11:47:36 +04:00
parent b790132830
commit f7998eb902
9 changed files with 51 additions and 28 deletions
@@ -118,7 +118,8 @@ public abstract class CreateClassFix {
if (argType == null) argType = TypesUtil.getJavaLangObject(refElement);
paramTypes[i] = "Object";
paramNames[i] = "o" + i;
paramTypesExpressions[i] = new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, refElement.getManager());
TypeConstraint[] constraints = {SupertypeConstraint.create(argType)};
paramTypesExpressions[i] = new ChooseTypeExpression(constraints, refElement.getManager(), targetClass.getResolveScope());
}
GrMethod method = GroovyPsiElementFactory.getInstance(project).createConstructorFromText(name, paramTypes, paramNames, "{\n}");
@@ -96,7 +96,7 @@ public class CreateLocalVariableFromUsageFix implements IntentionAction {
}
GrTypeElement typeElement = decl.getTypeElementGroovy();
assert typeElement != null;
ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project));
ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project), typeElement.getResolveScope());
TemplateBuilderImpl builder = new TemplateBuilderImpl(decl);
builder.replaceElement(typeElement, expr);
decl = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(decl);
@@ -107,8 +107,9 @@ public class CreateMethodFromUsageFix implements IntentionAction {
if (argType == null || argType == PsiType.NULL) argType = TypesUtil.getJavaLangObject(myRefExpression);
final PsiParameter p = factory.createParameter("o", argType);
parameterList.add(p);
paramTypesExpressions[i] =
new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, myRefExpression.getManager(), method.getLanguage() == GroovyFileType.GROOVY_LANGUAGE);
TypeConstraint[] constraints = {SupertypeConstraint.create(argType)};
boolean isGroovy = method.getLanguage() == GroovyFileType.GROOVY_LANGUAGE;
paramTypesExpressions[i] = new ChooseTypeExpression(constraints, myRefExpression.getManager(), isGroovy, method.getResolveScope());
}
return paramTypesExpressions;
}
@@ -57,7 +57,8 @@ public class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper
if (expectedTypes instanceof TypeConstraint[]) {
GrTypeElement typeElement = fieldDecl.getTypeElementGroovy();
assert typeElement != null;
ChooseTypeExpression expr = new ChooseTypeExpression((TypeConstraint[])expectedTypes, PsiManager.getInstance(project));
ChooseTypeExpression expr = new ChooseTypeExpression((TypeConstraint[])expectedTypes, PsiManager.getInstance(project),
typeElement.getResolveScope());
builder.replaceElement(typeElement, expr);
}
else if (expectedTypes instanceof ExpectedTypeInfo[]) {
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@@ -69,7 +70,8 @@ public class IntentionUtils {
final Project project = owner.getProject();
PsiTypeElement typeElement = method.getReturnTypeElement();
ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project), method.getLanguage()== GroovyFileType.GROOVY_LANGUAGE);
ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project), method.getLanguage()== GroovyFileType.GROOVY_LANGUAGE,
context.getResolveScope());
TemplateBuilderImpl builder = new TemplateBuilderImpl(method);
if (!isConstructor) {
assert typeElement != null;
@@ -34,8 +34,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
@@ -45,11 +43,7 @@ import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression;
import java.util.ArrayList;
/**
* Created with IntelliJ IDEA.
* User: maxmedvedev
* Date: 9/8/12
* Time: 9:55
* To change this template use File | Settings | File Templates.
* @author Max Medvedev
*/
public class GrSetStrongTypeIntention extends Intention {
@@ -72,15 +66,19 @@ public class GrSetStrongTypeIntention extends Intention {
PsiManager manager = element.getManager();
GrModifierList modifierList = ((GrVariableDeclaration)element).getModifierList();
PsiElement replaceElement;
if (modifierList.hasModifierProperty(GrModifier.DEF) && modifierList.getModifiers().length == 1) {
PsiElement def = PsiUtil.findModifierInList(modifierList, GrModifier.DEF);
builder.replaceElement(def, new ChooseTypeExpression(types.toArray(new TypeConstraint[types.size()]), manager));
replaceElement = PsiUtil.findModifierInList(modifierList, GrModifier.DEF);
}
else {
((GrVariableDeclaration)element).setType(TypesUtil.createType("Abc", element));
GrTypeElement typeElement = ((GrVariableDeclaration)element).getTypeElementGroovy();
builder.replaceElement(typeElement, new ChooseTypeExpression(types.toArray(new TypeConstraint[types.size()]), manager));
replaceElement = ((GrVariableDeclaration)element).getTypeElementGroovy();
}
assert replaceElement != null;
TypeConstraint[] constraints = types.toArray(new TypeConstraint[types.size()]);
ChooseTypeExpression chooseTypeExpression = new ChooseTypeExpression(constraints, manager, replaceElement.getResolveScope());
builder.replaceElement(replaceElement, chooseTypeExpression);
final PsiElement afterPostprocess = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element);
@@ -84,11 +84,12 @@ public class ClosureTemplateBuilder {
if (typeElement != null) {
final TypeConstraint[] typeConstraints = {SupertypeConstraint.create(typeElement.getType())};
final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project));
final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project), nameIdentifier.getResolveScope());
builder.replaceElement(typeElement, expression);
}
else {
final ChooseTypeExpression expression = new ChooseTypeExpression(TypeConstraint.EMPTY_ARRAY, PsiManager.getInstance(project));
final ChooseTypeExpression expression =
new ChooseTypeExpression(TypeConstraint.EMPTY_ARRAY, PsiManager.getInstance(project), nameIdentifier.getResolveScope());
builder.replaceElement(p.getModifierList(), expression);
}
@@ -48,7 +48,7 @@ public abstract class GrMethodCallImpl extends GrCallExpressionImpl implements G
}
for (GrCallExpressionTypeCalculator typeCalculator : GrCallExpressionTypeCalculator.EP_NAME.getExtensions()) {
PsiType res = typeCalculator.calculateReturnType(callExpression, resolveResults);
PsiType res = typeCalculator.calculateReturnType(callExpression, resolveResults);
if (res != null) {
return res;
}
@@ -15,14 +15,18 @@
*/
package org.jetbrains.plugins.groovy.template.expressions;
import com.intellij.codeInsight.completion.InsertHandler;
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.template.*;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTypesUtil;
import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionUtil;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint;
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint;
@@ -40,13 +44,13 @@ public class ChooseTypeExpression extends Expression {
private final LookupElement[] myItems;
private final PsiManager myManager;
public ChooseTypeExpression(TypeConstraint[] constraints, PsiManager manager) {
this(constraints, manager, true);
public ChooseTypeExpression(TypeConstraint[] constraints, PsiManager manager, GlobalSearchScope resolveScope) {
this(constraints, manager, true, resolveScope);
}
public ChooseTypeExpression(TypeConstraint[] constraints, PsiManager manager, boolean forGroovy) {
public ChooseTypeExpression(TypeConstraint[] constraints, PsiManager manager, boolean forGroovy, GlobalSearchScope resolveScope) {
myManager = manager;
myTypePointer = SmartTypePointerManager.getInstance(manager.getProject()).createSmartTypePointer(chooseType(constraints));
myTypePointer = SmartTypePointerManager.getInstance(manager.getProject()).createSmartTypePointer(chooseType(constraints, resolveScope));
myItems = createItems(constraints, forGroovy);
}
@@ -58,7 +62,12 @@ public class ChooseTypeExpression extends Expression {
}
for (TypeConstraint constraint : constraints) {
if (constraint instanceof SubtypeConstraint) {
result.add(PsiTypeLookupItem.createLookupItem(constraint.getDefaultType(), null));
PsiType type = constraint.getDefaultType();
PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(type, null);
setupLookup(item);
result.add(item);
}
else if (constraint instanceof SupertypeConstraint) {
processSuperTypes(constraint.getType(), result);
@@ -72,6 +81,14 @@ public class ChooseTypeExpression extends Expression {
return result.toArray(new LookupElement[result.size()]);
}
private static void setupLookup(PsiTypeLookupItem item) {
item.setInsertHandler(new InsertHandler<LookupItem>() {
public void handleInsert(InsertionContext context, LookupItem item) {
GroovyCompletionUtil.addImportForItem(context.getFile(), context.getStartOffset(), item);
}
});
}
private static void processSuperTypes(PsiType type, Set<LookupElement> result) {
String text = type.getCanonicalText();
String unboxed = PsiTypesUtil.unboxIfPossible(text);
@@ -79,7 +96,9 @@ public class ChooseTypeExpression extends Expression {
result.add(LookupElementBuilder.create(unboxed).bold());
}
else {
result.add(PsiTypeLookupItem.createLookupItem(type, null));
PsiTypeLookupItem item = PsiTypeLookupItem.createLookupItem(type, null);
setupLookup(item);
result.add(item);
}
PsiType[] superTypes = type.getSuperTypes();
for (PsiType superType : superTypes) {
@@ -87,9 +106,9 @@ public class ChooseTypeExpression extends Expression {
}
}
private PsiType chooseType(TypeConstraint[] constraints) {
private PsiType chooseType(TypeConstraint[] constraints, GlobalSearchScope scope) {
if (constraints.length > 0) return constraints[0].getDefaultType();
return PsiType.getJavaLangObject(myManager, GlobalSearchScope.allScope(myManager.getProject()));
return PsiType.getJavaLangObject(myManager, scope);
}
public Result calculateResult(ExpressionContext context) {