mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
create groovy method from usage by groovy ref
This commit is contained in:
+1
@@ -202,6 +202,7 @@ public class CreateFromUsageUtils {
|
||||
PsiDocumentManager manager = PsiDocumentManager.getInstance(method.getProject());
|
||||
manager.doPostponedOperationsAndUnblockDocument(manager.getDocument(containingFile));
|
||||
EditorModificationUtil.insertStringAtCaret(newEditor, lineIndent);
|
||||
EditorModificationUtil.insertStringAtCaret(newEditor, "\n", false, false);
|
||||
}
|
||||
else {
|
||||
//correct position caret for groovy and java methods
|
||||
|
||||
+1
-1
@@ -285,7 +285,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkTypeParam(final PsiMethod method, final PsiTypeParameter typeParameter) {
|
||||
public static boolean checkTypeParam(final PsiMethod method, final PsiTypeParameter typeParameter) {
|
||||
final String typeParameterName = typeParameter.getName();
|
||||
|
||||
final PsiTypeVisitor<Boolean> visitor = new PsiTypeVisitor<Boolean>() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -54,11 +54,15 @@ public class JavaTemplateUtil {
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
|
||||
if (method != null) {
|
||||
PsiTypeParameterList paramList = method.getTypeParameterList();
|
||||
PsiTypeParameter[] params = paramList.getTypeParameters();
|
||||
PsiTypeParameter[] params = paramList != null ? paramList.getTypeParameters() : PsiTypeParameter.EMPTY_ARRAY;
|
||||
for (PsiTypeParameter param : params) {
|
||||
if (param.getName().equals(aClass.getName())) return;
|
||||
}
|
||||
try {
|
||||
if (paramList == null) {
|
||||
final PsiTypeParameterList newList = JVMElementFactories.getFactory(method.getLanguage(), project).createTypeParameterList();
|
||||
paramList = (PsiTypeParameterList)method.addAfter(newList, method.getModifierList());
|
||||
}
|
||||
paramList.add(aClass.copy());
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
|
||||
}
|
||||
|
||||
@@ -1785,13 +1785,15 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
|
||||
if (targetClass == null) return;
|
||||
|
||||
addDynamicAnnotation(annotation, refExpr);
|
||||
if (targetClass instanceof GrMemberOwner && targetClass.isWritable()) {
|
||||
if (targetClass.isWritable()) {
|
||||
if (!(targetClass instanceof GroovyScriptClass)) {
|
||||
annotation.registerFix(new CreateFieldFromUsageFix(refExpr, (GrMemberOwner)targetClass));
|
||||
if (targetClass instanceof GrMemberOwner) {
|
||||
annotation.registerFix(new CreateFieldFromUsageFix(refExpr, (GrMemberOwner)targetClass));
|
||||
}
|
||||
}
|
||||
|
||||
if (refExpr.getParent() instanceof GrCall && refExpr.getParent() instanceof GrExpression) {
|
||||
annotation.registerFix(new CreateMethodFromUsageFix(refExpr, (GrMemberOwner)targetClass));
|
||||
annotation.registerFix(new CreateMethodFromUsageFix(refExpr, targetClass));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -84,7 +85,8 @@ public abstract class CreateClassFix {
|
||||
|
||||
GrMethod method = GroovyPsiElementFactory.getInstance(project).createConstructorFromText(name, paramTypes, paramNames, "{\n}");
|
||||
method = targetClass.addMemberDeclaration(method, null);
|
||||
IntentionUtils.createTemplateForMethod(argTypes, paramTypesExpressions, method, targetClass, new TypeConstraint[0], true);
|
||||
final PsiNameIdentifierOwner context = PsiTreeUtil.getParentOfType(myRefElement, PsiMethod.class, PsiClass.class);
|
||||
IntentionUtils.createTemplateForMethod(argTypes, paramTypesExpressions, method, targetClass, new TypeConstraint[0], true, context);
|
||||
} else {
|
||||
putCursor(project, targetClass.getContainingFile(), targetClass);
|
||||
}
|
||||
|
||||
+34
-31
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -18,9 +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.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,12 +26,8 @@ import org.jetbrains.plugins.groovy.GroovyBundle;
|
||||
import org.jetbrains.plugins.groovy.intentions.base.IntentionUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.editor.template.expressions.ChooseTypeExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
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.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
@@ -45,10 +39,10 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
* @author ven
|
||||
*/
|
||||
public class CreateMethodFromUsageFix implements IntentionAction {
|
||||
private final GrMemberOwner myTargetClass;
|
||||
private final PsiClass myTargetClass;
|
||||
private final GrReferenceExpression myRefExpression;
|
||||
|
||||
public CreateMethodFromUsageFix(GrReferenceExpression refExpression, GrMemberOwner targetClass) {
|
||||
public CreateMethodFromUsageFix(GrReferenceExpression refExpression, PsiClass targetClass) {
|
||||
myRefExpression = refExpression;
|
||||
myTargetClass = targetClass;
|
||||
}
|
||||
@@ -68,27 +62,21 @@ public class CreateMethodFromUsageFix implements IntentionAction {
|
||||
}
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
StringBuilder methodBuffer = new StringBuilder();
|
||||
if (PsiUtil.isInStaticContext(myRefExpression, myTargetClass)) methodBuffer.append("static ");
|
||||
methodBuffer.append("Object ").append(myRefExpression.getReferenceName()).append(" (");
|
||||
final JVMElementFactory factory = JVMElementFactories.getFactory(myTargetClass.getLanguage(), project);
|
||||
PsiMethod method = factory.createMethod(myRefExpression.getReferenceName(), PsiType.VOID);
|
||||
if (PsiUtil.isInStaticContext(myRefExpression, myTargetClass)) {
|
||||
method.getModifierList().setModifierProperty(PsiModifier.STATIC, true);
|
||||
}
|
||||
|
||||
PsiType[] argTypes = PsiUtil.getArgumentTypes(myRefExpression, false);
|
||||
assert argTypes != null;
|
||||
ChooseTypeExpression[] paramTypesExpressions = new ChooseTypeExpression[argTypes.length];
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
PsiType argType = argTypes[i];
|
||||
if (argType == null) argType = TypesUtil.getJavaLangObject(myRefExpression);
|
||||
if (i > 0) methodBuffer.append(", ");
|
||||
methodBuffer.append("Object o").append(i);
|
||||
paramTypesExpressions[i] =
|
||||
new ChooseTypeExpression(new TypeConstraint[]{SupertypeConstraint.create(argType)}, myRefExpression.getManager());
|
||||
}
|
||||
methodBuffer.append(") {\n}");
|
||||
GrMethod method = GroovyPsiElementFactory.getInstance(project).createMethodFromText(methodBuffer.toString());
|
||||
GrMemberOwner owner = myTargetClass;
|
||||
|
||||
ChooseTypeExpression[] paramTypesExpressions = setupParams(method, argTypes, factory);
|
||||
|
||||
TypeConstraint[] constraints = GroovyExpectedTypesProvider.calculateTypeConstraints((GrExpression)myRefExpression.getParent());
|
||||
PsiElement parent = myTargetClass instanceof GrTypeDefinition
|
||||
? ((GrTypeDefinition)myTargetClass).getBody()
|
||||
: ((GroovyScriptClass)myTargetClass).getContainingFile();
|
||||
PsiElement parent = myTargetClass instanceof GroovyScriptClass
|
||||
? ((GroovyScriptClass)myTargetClass).getContainingFile()
|
||||
: myTargetClass;
|
||||
if (PsiTreeUtil.isAncestor(parent, myRefExpression, false)) {
|
||||
PsiElement prevParent = PsiTreeUtil.findPrevParent(parent, myRefExpression);
|
||||
PsiElement sibling = PsiUtil.skipWhitespaces(prevParent.getNextSibling(), true);
|
||||
@@ -98,13 +86,28 @@ public class CreateMethodFromUsageFix implements IntentionAction {
|
||||
else {
|
||||
sibling = prevParent.getNextSibling();
|
||||
}
|
||||
method = owner.addMemberDeclaration(method, sibling);
|
||||
method = (PsiMethod)myTargetClass.addAfter(method, sibling);
|
||||
}
|
||||
else {
|
||||
method = owner.addMemberDeclaration(method, null);
|
||||
method = (PsiMethod)myTargetClass.add(method);
|
||||
}
|
||||
|
||||
IntentionUtils.createTemplateForMethod(argTypes, paramTypesExpressions, method, owner, constraints, false);
|
||||
final PsiElement context = PsiTreeUtil.getParentOfType(myRefExpression, PsiClass.class, PsiMethod.class);
|
||||
IntentionUtils.createTemplateForMethod(argTypes, paramTypesExpressions, method, myTargetClass, constraints, false, context);
|
||||
}
|
||||
|
||||
private ChooseTypeExpression[] setupParams(PsiMethod method, PsiType[] argTypes, JVMElementFactory factory) {
|
||||
final PsiParameterList parameterList = method.getParameterList();
|
||||
|
||||
ChooseTypeExpression[] paramTypesExpressions = new ChooseTypeExpression[argTypes.length];
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
PsiType argType = TypesUtil.unboxPrimitiveTypeWrapper(argTypes[i]);
|
||||
if (argType == 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());
|
||||
}
|
||||
return paramTypesExpressions;
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
|
||||
+66
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -16,15 +16,16 @@
|
||||
package org.jetbrains.plugins.groovy.intentions.base;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.template.Template;
|
||||
import com.intellij.codeInsight.template.TemplateBuilderImpl;
|
||||
import com.intellij.codeInsight.template.TemplateManager;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromUsageFix;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
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.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -33,12 +34,7 @@ import org.jetbrains.plugins.groovy.lang.editor.template.expressions.ChooseTypeE
|
||||
import org.jetbrains.plugins.groovy.lang.editor.template.expressions.ParameterNameExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrMemberOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
|
||||
/**
|
||||
@@ -47,6 +43,8 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
*/
|
||||
public class IntentionUtils {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(IntentionUtils.class);
|
||||
|
||||
public static void replaceExpression(@NotNull String newExpression, @NotNull GrExpression expression) throws IncorrectOperationException {
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(expression.getProject());
|
||||
final GrExpression newCall = factory.createExpressionFromText(newExpression);
|
||||
@@ -62,27 +60,29 @@ public class IntentionUtils {
|
||||
|
||||
public static void createTemplateForMethod(PsiType[] argTypes,
|
||||
ChooseTypeExpression[] paramTypesExpressions,
|
||||
GrMethod method,
|
||||
GrMemberOwner owner,
|
||||
TypeConstraint[] constraints, boolean isConstructor) {
|
||||
PsiMethod method,
|
||||
PsiClass owner,
|
||||
TypeConstraint[] constraints,
|
||||
boolean isConstructor,
|
||||
final PsiElement context) {
|
||||
|
||||
Project project = owner.getProject();
|
||||
GrTypeElement typeElement = method.getReturnTypeElementGroovy();
|
||||
final Project project = owner.getProject();
|
||||
PsiTypeElement typeElement = method.getReturnTypeElement();
|
||||
ChooseTypeExpression expr = new ChooseTypeExpression(constraints, PsiManager.getInstance(project));
|
||||
TemplateBuilderImpl builder = new TemplateBuilderImpl(method);
|
||||
if (!isConstructor) {
|
||||
assert typeElement != null;
|
||||
builder.replaceElement(typeElement, expr);
|
||||
}
|
||||
GrParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
assert parameters.length == argTypes.length;
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
GrParameter parameter = parameters[i];
|
||||
GrTypeElement parameterTypeElement = parameter.getTypeElementGroovy();
|
||||
PsiParameter parameter = parameters[i];
|
||||
PsiTypeElement parameterTypeElement = parameter.getTypeElement();
|
||||
builder.replaceElement(parameterTypeElement, paramTypesExpressions[i]);
|
||||
builder.replaceElement(parameter.getNameIdentifierGroovy(), new ParameterNameExpression());
|
||||
builder.replaceElement(parameter.getNameIdentifier(), new ParameterNameExpression());
|
||||
}
|
||||
GrOpenBlock body = method.getBlock();
|
||||
PsiCodeBlock body = method.getBody();
|
||||
assert body != null;
|
||||
PsiElement lbrace = body.getLBrace();
|
||||
assert lbrace != null;
|
||||
@@ -91,11 +91,53 @@ public class IntentionUtils {
|
||||
method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
|
||||
Template template = builder.buildTemplate();
|
||||
|
||||
Editor newEditor = QuickfixUtil.positionCursor(project, owner.getContainingFile(), method);
|
||||
final PsiFile targetFile = owner.getContainingFile();
|
||||
final Editor newEditor = QuickfixUtil.positionCursor(project, targetFile, method);
|
||||
TextRange range = method.getTextRange();
|
||||
newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
|
||||
|
||||
TemplateManager manager = TemplateManager.getInstance(project);
|
||||
manager.startTemplate(newEditor, template);
|
||||
|
||||
|
||||
TemplateEditingListener templateListener = new TemplateEditingAdapter() {
|
||||
@Override
|
||||
public void templateFinished(Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
|
||||
final int offset = newEditor.getCaretModel().getOffset();
|
||||
PsiMethod method = PsiTreeUtil.findElementOfClassAtOffset(targetFile, offset - 1, PsiMethod.class, false);
|
||||
if (context instanceof PsiMethod) {
|
||||
final PsiTypeParameter[] typeParameters = ((PsiMethod)context).getTypeParameters();
|
||||
if (typeParameters.length > 0) {
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
if (CreateMethodFromUsageFix.checkTypeParam(method, typeParameter)) {
|
||||
final JVMElementFactory factory = JVMElementFactories.getFactory(method.getLanguage(), method.getProject());
|
||||
PsiTypeParameterList list = method.getTypeParameterList();
|
||||
if (list == null) {
|
||||
PsiTypeParameterList newList = factory.createTypeParameterList();
|
||||
list = (PsiTypeParameterList)method.addAfter(newList, method.getModifierList());
|
||||
}
|
||||
list.add(factory.createTypeParameter(typeParameter.getName(), typeParameter.getExtendsList().getReferencedTypes()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (method != null) {
|
||||
try {
|
||||
CreateFromUsageUtils.setupMethodBody(method);
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
|
||||
CreateFromUsageUtils.setupEditor(method, newEditor);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
manager.startTemplate(newEditor, template, templateListener);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -22,6 +22,7 @@ import com.intellij.codeInsight.template.Expression;
|
||||
import com.intellij.codeInsight.template.ExpressionContext;
|
||||
import com.intellij.codeInsight.template.PsiTypeResult;
|
||||
import com.intellij.codeInsight.template.Result;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
@@ -86,7 +87,12 @@ public class ChooseTypeExpression extends Expression {
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments();
|
||||
PsiType type = myTypePointer.getType();
|
||||
if (type != null) {
|
||||
return new PsiTypeResult(type, context.getProject());
|
||||
return new PsiTypeResult(type, context.getProject()) {
|
||||
@Override
|
||||
public void handleRecalc(PsiFile psiFile, Document document, int segmentStart, int segmentEnd) {
|
||||
if (myItems.length <= 1) super.handleRecalc(psiFile, document, segmentStart, segmentEnd);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user