create Groovy field from usage in java code

This commit is contained in:
Maxim.Medvedev
2012-06-21 15:14:08 +04:00
parent 6849c009ea
commit 1708932dcf
16 changed files with 411 additions and 41 deletions
@@ -15,17 +15,14 @@
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.codeInsight.template.TemplateEditingAdapter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
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.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
@@ -60,7 +57,8 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
@Override
protected void invokeImpl(final PsiClass targetClass) {
final Project project = myReferenceExpression.getProject();
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
JVMElementFactory factory = JVMElementFactories.getFactory(targetClass.getLanguage(), project);
if (factory == null) factory = JavaPsiFacade.getElementFactory(project);
PsiMember enclosingContext = null;
PsiClass parentClass;
@@ -76,21 +74,23 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
ExpectedTypeInfo[] expectedTypes = CreateFromUsageUtils.guessExpectedTypes(myReferenceExpression, false);
String fieldName = myReferenceExpression.getReferenceName();
PsiField field;
if (!createConstantField()) {
field = factory.createField(fieldName, PsiType.INT);
assert fieldName != null;
PsiField field = factory.createField(fieldName, PsiType.INT);
if (createConstantField()) {
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true);
}
else {
PsiClass aClass = factory.createClassFromText("int i = 0;", null);
field = aClass.getFields()[0];
field.setName(fieldName);
}
if (enclosingContext != null && enclosingContext.getParent() == parentClass && targetClass == parentClass
&& enclosingContext instanceof PsiField) {
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) {
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);
}
@@ -113,24 +113,9 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
PsiUtil.setModifierProperty(field, PsiModifier.FINAL, true);
}
TemplateBuilderImpl builder = new TemplateBuilderImpl(field);
PsiElement context = PsiTreeUtil.getParentOfType(myReferenceExpression, PsiClass.class, PsiMethod.class);
new GuessTypeParameters(factory)
.setupTypeElement(field.getTypeElement(), expectedTypes, getTargetSubstitutor(myReferenceExpression),
builder, context, targetClass);
if (createConstantField()) {
builder.replaceElement(field.getInitializer(), new EmptyExpression());
}
builder.setEndVariableAfter(field.getNameIdentifier());
field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
Template template = builder.buildTemplate();
final Editor newEditor = positionCursor(project, targetFile, field);
TextRange range = field.getTextRange();
newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
if (expectedTypes.length > 1) template.setToShortenLongNames(false);
Template template =
CreateFieldFromUsageHelper.setupTemplate(field, expectedTypes, targetClass, newEditor, myReferenceExpression, createConstantField());
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
@Override
@@ -155,11 +140,11 @@ public class CreateFieldFromUsageFix extends CreateVarFromUsageFix {
return false;
}
final PsiElement element = PsiTreeUtil.getParentOfType(ref, PsiClassInitializer.class, PsiMethod.class);
if (element instanceof PsiClassInitializer){
if (element instanceof PsiClassInitializer) {
return true;
}
if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()){
if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
return true;
}
@@ -0,0 +1,50 @@
/*
* Copyright 2000-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 com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.template.Template;
import com.intellij.lang.LanguageExtension;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiSubstitutor;
/**
* @author Max Medvedev
*/
public abstract class CreateFieldFromUsageHelper {
private static final LanguageExtension<CreateFieldFromUsageHelper> EP_NAME =
new LanguageExtension<CreateFieldFromUsageHelper>("com.intellij.codeInsight.createFieldFromUsageHelper");
public static Template setupTemplate(PsiField field,
Object expectedTypes,
PsiClass targetClass,
Editor editor,
PsiElement context, boolean createConstantField) {
CreateFieldFromUsageHelper helper = EP_NAME.forLanguage(field.getLanguage());
if (helper == null) return null;
return helper.setupTemplateImpl(field, expectedTypes, targetClass, editor, context, createConstantField,
CreateFromUsageBaseFix.getTargetSubstitutor(context));
}
public abstract Template setupTemplateImpl(PsiField field,
Object expectedTypes,
PsiClass targetClass,
Editor editor,
PsiElement context,
boolean createConstantField, PsiSubstitutor substitutor);
}
@@ -37,10 +37,10 @@ import java.util.Map;
* @author ven
*/
public class GuessTypeParameters {
private final PsiElementFactory myFactory;
private final JVMElementFactory myFactory;
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.GuessTypeParameters");
public GuessTypeParameters(PsiElementFactory factory) {
public GuessTypeParameters(JVMElementFactory factory) {
myFactory = factory;
}
@@ -145,6 +145,7 @@ public class GuessTypeParameters {
return substitutor;
}
@Nullable
private static PsiClassType getComponentType (PsiType type) {
type = type.getDeepComponentType();
if (type instanceof PsiClassType) return (PsiClassType)type;
@@ -0,0 +1,63 @@
/*
* Copyright 2000-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 com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.CodeInsightUtilBase;
import com.intellij.codeInsight.ExpectedTypeInfo;
import com.intellij.codeInsight.template.Template;
import com.intellij.codeInsight.template.TemplateBuilderImpl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
/**
* @author Max Medvedev
*/
public class JavaCreateFieldFromUsageHelper extends CreateFieldFromUsageHelper {
@Override
public Template setupTemplateImpl(PsiField field,
Object expectedTypes,
PsiClass targetClass,
Editor editor,
PsiElement context,
boolean createConstantField,
PsiSubstitutor substitutor) {
PsiElementFactory factory = JavaPsiFacade.getElementFactory(field.getProject());
TemplateBuilderImpl builder = new TemplateBuilderImpl(field.getParent());
if (!(expectedTypes instanceof ExpectedTypeInfo[])) {
expectedTypes = ExpectedTypeInfo.EMPTY_ARRAY;
}
new GuessTypeParameters(factory).setupTypeElement(field.getTypeElement(), (ExpectedTypeInfo[])expectedTypes, substitutor, builder,
context, targetClass);
if (createConstantField) {
field.setInitializer(factory.createExpressionFromText("0", null));
builder.replaceElement(field.getInitializer(), new EmptyExpression());
}
PsiIdentifier identifier = field.getNameIdentifier();
builder.setEndVariableAfter(identifier);
field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
Template template = builder.buildTemplate();
TextRange range = field.getTextRange();
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
if (((ExpectedTypeInfo[])expectedTypes).length > 1) template.setToShortenLongNames(false);
return template;
}
}