diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java index 751812c41647..7cdd4e046204 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageFix.java @@ -25,7 +25,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; -import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; @@ -81,22 +80,8 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix { PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true); } - if (enclosingContext != null && - enclosingContext.getParent() == parentClass && - targetClass == parentClass && - enclosingContext instanceof PsiField) { - field = (PsiField)targetClass.addBefore(field, enclosingContext); - } - else if (enclosingContext != null && - enclosingContext.getParent() == parentClass && - targetClass == parentClass && - enclosingContext instanceof PsiClassInitializer) { - field = (PsiField)targetClass.addBefore(field, enclosingContext); - targetClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), enclosingContext); - } - else { - field = (PsiField)targetClass.add(field); - } + + field = CreateFieldFromUsageHelper.insertField(targetClass, field, myReferenceExpression); setupVisibility(parentClass, targetClass, field.getModifierList()); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java index 5d94ce9d8e14..0a656f7f7dce 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFieldFromUsageHelper.java @@ -41,6 +41,14 @@ public abstract class CreateFieldFromUsageHelper { CreateFromUsageBaseFix.getTargetSubstitutor(context)); } + public static PsiField insertField(PsiClass targetClass, PsiField field, PsiElement place) { + CreateFieldFromUsageHelper helper = EP_NAME.forLanguage(field.getLanguage()); + if (helper == null) return null; + return helper.insertFieldImpl(targetClass, field, place); + } + + public abstract PsiField insertFieldImpl(PsiClass targetClass, PsiField field, PsiElement place); + public abstract Template setupTemplateImpl(PsiField field, Object expectedTypes, PsiClass targetClass, diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java index 2c4170112a51..06d038b2cef5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java @@ -22,6 +22,8 @@ import com.intellij.codeInsight.template.TemplateBuilderImpl; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; +import com.intellij.psi.util.PsiTreeUtil; /** * @author Max Medvedev @@ -60,4 +62,34 @@ public class JavaCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper { if (((ExpectedTypeInfo[])expectedTypes).length > 1) template.setToShortenLongNames(false); return template; } + + public PsiField insertFieldImpl(PsiClass targetClass, PsiField field, PsiElement place) { + PsiMember enclosingContext = null; + PsiClass parentClass; + do { + enclosingContext = PsiTreeUtil.getParentOfType(enclosingContext == null ? place : enclosingContext, PsiMethod.class, PsiField.class, PsiClassInitializer.class); + parentClass = enclosingContext == null ? null : enclosingContext.getContainingClass(); + } + while (parentClass instanceof PsiAnonymousClass); + + if (enclosingContext != null && + enclosingContext.getParent() == parentClass && + targetClass == parentClass && + enclosingContext instanceof PsiField) { + field = (PsiField)targetClass.addBefore(field, enclosingContext); + } + else if (enclosingContext != null && + enclosingContext.getParent() == parentClass && + targetClass == parentClass && + enclosingContext instanceof PsiClassInitializer) { + field = (PsiField)targetClass.addBefore(field, enclosingContext); + targetClass.addBefore(CodeEditUtil.createLineFeed(field.getManager()), enclosingContext); + } + else { + field = (PsiField)targetClass.add(field); + } + + return field; + } + } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 27d16d256992..4838d4f39d28 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -1778,9 +1778,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } if (targetClass.isWritable()) { if (!(targetClass instanceof GroovyScriptClass)) { - if (targetClass instanceof GrMemberOwner) { - annotation.registerFix(new CreateFieldFromUsageFix(refExpr, (GrMemberOwner)targetClass)); - } + annotation.registerFix(new CreateFieldFromUsageFix(refExpr, targetClass)); } if (refExpr.getParent() instanceof GrCall && refExpr.getParent() instanceof GrExpression) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java index ab5d0e57085d..a0c86a6b4503 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFix.java @@ -15,36 +15,27 @@ */ package org.jetbrains.plugins.groovy.annotator.intentions; -import com.intellij.codeInsight.CodeInsightUtilBase; +import com.intellij.codeInsight.daemon.impl.quickfix.CreateFieldFromUsageHelper; import com.intellij.codeInsight.template.Template; -import com.intellij.codeInsight.template.TemplateBuilderImpl; import com.intellij.codeInsight.template.TemplateManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiManager; -import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; -import org.jetbrains.plugins.groovy.lang.editor.template.expressions.ChooseTypeExpression; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrMemberOwner; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; /** * @author Maxim.Medvedev */ public class CreateFieldFix { - private final GrMemberOwner myTargetClass; + private final PsiClass myTargetClass; - protected GrMemberOwner getTargetClass() { + protected PsiClass getTargetClass() { return myTargetClass; } - protected CreateFieldFix(GrMemberOwner targetClass) { + protected CreateFieldFix(PsiClass targetClass) { myTargetClass = targetClass; } @@ -52,28 +43,17 @@ public class CreateFieldFix { return myTargetClass.isValid(); } - protected void doFix(Project project, String[] modifiers, String fieldName, TypeConstraint[] typeConstraints) throws IncorrectOperationException { - PsiClassType type = JavaPsiFacade.getElementFactory(project).createTypeByFQClassName("Object", GlobalSearchScope.allScope(project)); - GrVariableDeclaration fieldDecl = - GroovyPsiElementFactory.getInstance(project).createFieldDeclaration(modifiers, fieldName, null, type); - fieldDecl = (GrVariableDeclaration)myTargetClass.add(fieldDecl); - GrTypeElement typeElement = fieldDecl.getTypeElementGroovy(); - assert typeElement != null; - - ChooseTypeExpression expr = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project)); - TemplateBuilderImpl builder = new TemplateBuilderImpl(fieldDecl); - builder.replaceElement(typeElement, expr); - fieldDecl = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(fieldDecl); - if (fieldDecl == null) { - return; + protected void doFix(Project project, String[] modifiers, String fieldName, TypeConstraint[] typeConstraints, PsiElement context) throws IncorrectOperationException { + PsiField field = JVMElementFactories.getFactory(myTargetClass.getLanguage(), project).createField(fieldName, PsiType.INT); + for (String modifier : modifiers) { + PsiUtil.setModifierProperty(field, modifier, true); } - Template template = builder.buildTemplate(); + field = CreateFieldFromUsageHelper.insertField(myTargetClass, field, context); - Editor newEditor = QuickfixUtil.positionCursor(project, myTargetClass.getContainingFile(), fieldDecl); - TextRange range = fieldDecl.getTextRange(); - newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset()); + Editor newEditor = QuickfixUtil.positionCursor(project, myTargetClass.getContainingFile(), field); + Template template = CreateFieldFromUsageHelper.setupTemplate(field, typeConstraints, myTargetClass, newEditor, context, false); TemplateManager manager = TemplateManager.getInstance(project); manager.startTemplate(newEditor, template); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromConstructorLabelFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromConstructorLabelFix.java index 31c23c53905e..a750a097c74b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromConstructorLabelFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromConstructorLabelFix.java @@ -72,6 +72,6 @@ public class CreateFieldFromConstructorLabelFix extends GroovyFix { @Override protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException { - myFix.doFix(project, ArrayUtil.EMPTY_STRING_ARRAY, getFieldName(), calculateTypeConstrains()); + myFix.doFix(project, ArrayUtil.EMPTY_STRING_ARRAY, getFieldName(), calculateTypeConstrains(), myNamedArgument); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java index 4f84cd786747..18fd9c69258a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/CreateFieldFromUsageFix.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.annotator.intentions; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiModifier; import com.intellij.util.ArrayUtil; @@ -26,7 +27,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrMemberOwner; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -38,7 +38,7 @@ public class CreateFieldFromUsageFix implements IntentionAction { private final CreateFieldFix myFix; private final GrReferenceExpression myRefExpression; - public CreateFieldFromUsageFix(GrReferenceExpression refExpression, GrMemberOwner targetClass) { + public CreateFieldFromUsageFix(GrReferenceExpression refExpression, PsiClass targetClass) { myFix = new CreateFieldFix(targetClass); myRefExpression = refExpression; } @@ -75,7 +75,7 @@ public class CreateFieldFromUsageFix implements IntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - myFix.doFix(project, generateModifiers(), getFieldName(), calculateTypeConstrains()); + myFix.doFix(project, generateModifiers(), getFieldName(), calculateTypeConstrains(), myRefExpression); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java index d3383ab310d1..61a519270988 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GroovyCreateFieldFromUsageHelper.java @@ -80,4 +80,9 @@ public class GroovyCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper } return template; } + + @Override + public PsiField insertFieldImpl(PsiClass targetClass, PsiField field, PsiElement place) { + return (PsiField)targetClass.add(field); + } }