integration with java

This commit is contained in:
Maxim Medvedev
2010-05-29 13:40:10 +04:00
parent 5db1013634
commit 01f41c1678
39 changed files with 365 additions and 139 deletions
@@ -206,9 +206,8 @@ public class ChangeSignatureProcessor extends BaseRefactoringProcessor {
protected boolean isProcessCovariantOverriders() {
return Messages
.showYesNoDialog(myProject, RefactoringBundle.message("do.you.want.to.process.overriding.methods.with.covariant.return.type"),
JavaChangeSignatureHandler.REFACTORING_NAME, Messages.getQuestionIcon())
== DialogWrapper.OK_EXIT_CODE;
.showYesNoDialog(myProject, RefactoringBundle.message("do.you.want.to.process.overriding.methods.with.covariant.return.type"),
JavaChangeSignatureHandler.REFACTORING_NAME, Messages.getQuestionIcon()) == DialogWrapper.OK_EXIT_CODE;
}
protected void performRefactoring(UsageInfo[] usages) {
@@ -403,14 +403,13 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
newArgsLength = newParms.length;
}
final PsiExpression[] newArgs = new PsiExpression[newArgsLength];
final JavaParameterInfo[] newParameters = changeInfo.getNewParameters();
for (int i = 0; i < newNonVarargCount; i++) {
newArgs[i] = createActualArgument(changeInfo, list, newParms[i], toInsertDefaultValue, args);
}
if (changeInfo.isArrayToVarargs()) {
if (newVarargInitializers == null) {
newArgs[newNonVarargCount] =
createActualArgument(changeInfo, list, newParameters[newNonVarargCount], toInsertDefaultValue, args);
createActualArgument(changeInfo, list, newParms[newNonVarargCount], toInsertDefaultValue, args);
}
else {
System.arraycopy(newVarargInitializers, 0, newArgs, newNonVarargCount, newVarargInitializers.length);
@@ -72,7 +72,7 @@ public class DMethodElement extends DItemElement {
final String[] argumentsTypes = QuickfixUtil.getArgumentsTypes(myPairs);
final GrMethod method = GroovyPsiElementFactory.getInstance(manager.getProject())
.createMethodFromText(staticModifier, getName(), type, argumentsTypes);
.createMethodFromText(staticModifier, getName(), type, argumentsTypes, null);
myImplicitMethod = new GrDynamicImplicitMethod(manager, method, containingClassName) {
@Override
@@ -144,15 +144,27 @@ public abstract class GroovyPsiElementFactory {
public abstract PsiElement createDotToken(String newDot);
public abstract GrMethod createMethodFromText(String methodText);
public abstract GrMethod createMethodFromText(String methodText, PsiElement context);
public GrMethod createMethodFromText(String methodText) {
return createMethodFromText(methodText, null);
}
public abstract GrAnnotation createAnnotationFromText(String annoText);
public abstract GroovyFile createGroovyFile(String text, boolean isPhisical, PsiElement context);
public abstract GrMethod createMethodFromText(String modifier, String name, String type, String[] paramTypes);
public abstract GrMethod createMethodFromText(String modifier, String name, String type, String[] paramTypes, PsiElement context);
public abstract GrMethod createConstructorFromText(@NotNull String constructorName, String[] paramTypes, String[] paramNames, String body);
public abstract GrMethod createConstructorFromText(@NotNull String constructorName,
String[] paramTypes,
String[] paramNames,
String body,
PsiElement context);
public GrMethod createConstructorFromText(@NotNull String constructorName, String[] paramTypes, String[] paramNames, String body) {
return createConstructorFromText(constructorName, paramTypes, paramNames, body, null);
}
public abstract GrLabel createLabel(@NotNull String name);
@@ -163,4 +175,6 @@ public abstract class GroovyPsiElementFactory {
public abstract PsiReferenceList createThrownList(PsiClassType[] exceptionTypes);
public abstract GrCatchClause createCatchClause(PsiClassType type, String parameterName);
public abstract GrArgumentList createArgumentList();
}
@@ -355,10 +355,15 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
return createReferenceExpressionFromText("a" + newDot + "b").getDotToken();
}
public GrConstructorImpl createConstructorFromText(@NotNull String constructorName, @Nullable String[] paramTypes, String[] paramNames, String body) {
final GrMethod method = createMethodFromText(null, constructorName, null, paramTypes, paramNames, body);
public GrConstructorImpl createConstructorFromText(@NotNull String constructorName,
@Nullable String[] paramTypes,
String[] paramNames,
String body,
PsiElement context) {
final GrMethod method = createMethodFromText(null, constructorName, null, paramTypes, paramNames, body, context);
GroovyFileBase file = createDummyFile("class " + constructorName + "{" + method.getText() + "}");
GroovyFileImpl file = createDummyFile("class " + constructorName + "{" + method.getText() + "}");
file.setContext(context);
GrTopLevelDefintion defintion = file.getTopLevelDefinitions()[0];
assert defintion != null && defintion instanceof GrClassDefinition;
final PsiMethod constructor = ((GrClassDefinition) defintion).getMethods()[0];
@@ -374,8 +379,11 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
return ((GrLabeledStatement)definition).getLabel();
}
public GrMethod createMethodFromText(@NotNull String methodText) {
GroovyFileBase file = createDummyFile(methodText);
public GrMethod createMethodFromText(@NotNull String methodText, PsiElement context) {
GroovyFileImpl file = createDummyFile(methodText);
if (context != null) {
file.setContext(context);
}
try {
GrTopLevelDefintion defintion = file.getTopLevelDefinitions()[0];
assert defintion != null && defintion instanceof GrMethod;
@@ -388,7 +396,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
@Override
public GrAnnotation createAnnotationFromText(String annoText) {
return createMethodFromText(annoText + " void foo() {}").getModifierList().getAnnotations()[0];
return createMethodFromText(annoText + " void foo() {}", null).getModifierList().getAnnotations()[0];
}
public PsiFile createGroovyFile(String idText) {
@@ -500,7 +508,13 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
}
private GrMethod createMethodFromText(String modifier, String name, String type, @Nullable String[] paramTypes, @NotNull String[] paramNames, String body) {
private GrMethod createMethodFromText(String modifier,
String name,
String type,
@Nullable String[] paramTypes,
@NotNull String[] paramNames,
String body,
PsiElement context) {
StringBuilder builder = new StringBuilder();
if (modifier != null){
@@ -537,10 +551,10 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
builder.append("}");
}
return createMethodFromText(builder.toString());
return createMethodFromText(builder.toString(), context);
}
public GrMethod createMethodFromText(String modifier, String name, @Nullable String type, String[] paramTypes) {
public GrMethod createMethodFromText(String modifier, String name, @Nullable String type, String[] paramTypes, PsiElement context) {
PsiType psiType;
List<PsiType> res = new ArrayList<PsiType>();
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject);
@@ -556,7 +570,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
}
return createMethodFromText(modifier, name, type, paramTypes,
QuickfixUtil.getMethodArgumentsNames(myProject, res.toArray(new PsiType[res.size()])), null);
QuickfixUtil.getMethodArgumentsNames(myProject, res.toArray(new PsiType[res.size()])), null, context);
}
public GrDocComment createDocCommentFromText(String text) {
@@ -575,14 +589,14 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
@Override
public PsiReferenceList createThrownList(PsiClassType[] exceptionTypes) {
if (exceptionTypes.length == 0) {
return createMethodFromText("def foo(){}").getThrowsList();
return createMethodFromText("def foo(){}", null).getThrowsList();
}
String[] types = new String[exceptionTypes.length];
for (int i = 0; i < types.length; i++) {
types[i] = exceptionTypes[i].getCanonicalText();
}
final String end = StringUtil.join(types, ",");
return createMethodFromText("def foo() throws " + end + "{}").getThrowsList();
return createMethodFromText("def foo() throws " + end + "{}", null).getThrowsList();
}
@Override
@@ -598,4 +612,9 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
final GrTryCatchStatement statement = (GrTryCatchStatement)createStatementFromText(buffer.toString());
return statement.getCatchClauses()[0];
}
@Override
public GrArgumentList createArgumentList() {
return ((GrCall)createExpressionFromText("foo()")).getArgumentList();
}
}
@@ -34,7 +34,10 @@ import com.intellij.usageView.UsageViewUtil;
import com.intellij.util.containers.HashSet;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTagValueToken;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
@@ -146,7 +149,10 @@ class GrChageSignatureUsageSearcher {
}
}
};
GrUnresolvableLocalCollisionDetector.visitLocalsCollisions(method, newName, method.getBlock(), variableVisitor);
final GrOpenBlock block = method.getBlock();
if (block != null) {
GrUnresolvableLocalCollisionDetector.visitLocalsCollisions(method, newName, block, variableVisitor);
}
}
}
}
@@ -204,10 +210,22 @@ class GrChageSignatureUsageSearcher {
//todo check for applicability of arguments to method
if (PsiUtil.isMethodUsage(element)) {
GrClosureSignature signature = GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY);
GrClosureSignatureUtil.ArgInfo[] map = GrClosureSignatureUtil
.mapParametersToArguments(signature, PsiUtil.getArgumentsList(element), method.getManager(), method.getResolveScope());
result.add(
new GrMethodCallUsageInfo(element, GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY), isToModifyArgs, isToCatchExceptions, map));
final GrArgumentList argList = PsiUtil.getArgumentsList(element);
//enum constant may not have argList
if (argList == null) {
if (element instanceof GrEnumConstant) {
result.add(
new GrMethodCallUsageInfo(element, GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY), isToModifyArgs,
isToCatchExceptions, new GrClosureSignatureUtil.ArgInfo[0]));
}
}
else {
GrClosureSignatureUtil.ArgInfo[] map =
GrClosureSignatureUtil.mapParametersToArguments(signature, argList, method.getManager(), method.getResolveScope());
result.add(
new GrMethodCallUsageInfo(element, GrClosureSignatureUtil.createSignature(method, PsiSubstitutor.EMPTY), isToModifyArgs,
isToCatchExceptions, map));
}
}
else if (element instanceof GrDocTagValueToken) {
result.add(new UsageInfo(ref.getElement()));
@@ -139,10 +139,10 @@ class GrChangeSignatureConflictSearcher {
final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType();
String newMethodName = myChangeInfo.getNewName();
if (returnType != null) {
prototype = factory.createMethodFromText("", newMethodName, returnType.getTypeText(), ArrayUtil.EMPTY_STRING_ARRAY);
prototype = factory.createMethodFromText("", newMethodName, returnType.getTypeText(), ArrayUtil.EMPTY_STRING_ARRAY, method);
}
else {
prototype = factory.createConstructorFromText(newMethodName, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}");
prototype = factory.createConstructorFromText(newMethodName, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", method);
}
JavaParameterInfo[] parameters = myChangeInfo.getNewParameters();
@@ -116,7 +116,7 @@
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</component>
<grid id="1d25b" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="1d25b" binding="myDelegatePanel" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -72,6 +72,7 @@ public class GrChangeSignatureDialog extends RefactoringDialog {
@SuppressWarnings({"UnusedDeclaration"}) private JPanel myParameterButtonPanel;
private JBTable myExceptionsTable;
@SuppressWarnings({"UnusedDeclaration"}) private JPanel myExceptionsButtonPanel;
private JPanel myDelegatePanel;
private GrParameterTableModel myParameterModel;
private GrMethod myMethod;
private PsiTypeCodeFragment myReturnTypeCodeFragment;
@@ -96,6 +97,11 @@ public class GrChangeSignatureDialog extends RefactoringDialog {
protected void init() {
super.init();
final PsiClass psiClass = myMethod.getContainingClass();
if (psiClass == null) return;
if (psiClass.isInterface()) {
myDelegatePanel.setVisible(false);
}
}
private void stopEditing() {
@@ -21,7 +21,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.*;
import com.intellij.refactoring.changeSignature.*;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.refactoring.util.RefactoringUtil;
@@ -37,8 +37,10 @@ import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.GroovyFileType;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
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.GrCatchClause;
@@ -50,12 +52,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArg
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrConstructor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
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.impl.statements.expressions.TypesUtil;
@@ -110,10 +112,28 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
newMethod = (GrMethod)psiClass.addAfter(newMethod, method);
StringBuffer buffer = new StringBuffer();
buffer.append("\n");
if (!PsiType.VOID.equals(method.getReturnType())) {
buffer.append("return ");
if (method.isConstructor()) {
buffer.append("this");
}
buffer.append(method.getName()).append("(");
else {
if (!PsiType.VOID.equals(method.getReturnType())) {
buffer.append("return ");
}
buffer.append(method.getName());
}
generateParametersForDelegateCall(grInfo, method, buffer);
final GrCodeBlock codeBlock = GroovyPsiElementFactory.getInstance(method.getProject()).createMethodBodyFromText(buffer.toString());
newMethod.setBlock(codeBlock);
newMethod.getModifierList().setModifierProperty(GrModifier.ABSTRACT, false);
CodeStyleManager.getInstance(method.getProject()).reformat(newMethod);
return processPrimaryMethodInner(grInfo, method, null);
}
private static void generateParametersForDelegateCall(GrChangeInfoImpl grInfo, GrMethod method, StringBuffer buffer) {
buffer.append("(");
final GrParameter[] oldParameters = method.getParameterList().getParameters();
final JavaParameterInfo[] parameters = grInfo.getNewParameters();
@@ -131,11 +151,6 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
}
buffer.append(StringUtil.join(params, ","));
buffer.append(");");
final GrCodeBlock codeBlock = GroovyPsiElementFactory.getInstance(method.getProject()).createMethodBodyFromText(buffer.toString());
newMethod.setBlock(codeBlock);
CodeStyleManager.getInstance(method.getProject()).reformat(newMethod);
return processPrimaryMethodInner(grInfo, method, null);
}
private static boolean processPrimaryMethodInner(JavaChangeInfo changeInfo, GrMethod method, PsiMethod baseMethod) {
@@ -151,6 +166,9 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
method.getModifierList().setModifierProperty(changeInfo.getNewVisibility(), true);
}
PsiSubstitutor substitutor = baseMethod != null ? calculateSubstitutor(method, baseMethod) : PsiSubstitutor.EMPTY;
final PsiMethod context = changeInfo.getMethod();
if (changeInfo.isReturnTypeChanged()) {
CanonicalTypes.Type newReturnType = changeInfo.getNewReturnType();
GrTypeElement element = method.getReturnTypeElementGroovy();
@@ -164,8 +182,11 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
}
}
else {
PsiType type = newReturnType.getType(method.getParameterList(), method.getManager());
method.setReturnType(type);
PsiType type = newReturnType.getType(context, method.getManager());
final PsiType oldReturnType = method.getReturnType();
if (!TypesUtil.isAssignable(type, oldReturnType, context.getManager(), context.getResolveScope())) { //todo ask for replace covariant type
method.setReturnType(substitutor.substitute(type));
}
}
}
@@ -179,39 +200,24 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(method.getProject());
GrParameter anchor = null;
for (JavaParameterInfo newParameter : newParameters) {
/*
int index = newParameter.getOldIndex();
if (index < 0) {
*/
String typeText;
PsiType type;
if (newParameter instanceof GrParameterInfo && ((GrParameterInfo)newParameter).hasNoType()) {
typeText = null;
type = null;
}
else {
typeText = newParameter.getTypeText();
type = substitutor.substitute(newParameter.createType(context, method.getManager()));
}
GrParameter grParameter =
factory.createParameter(newParameter.getName(), typeText, getInitializer(newParameter), parameterList);
GrParameter grParameter = factory
.createParameter(newParameter.getName(), type == null ? null : type.getCanonicalText(), getInitializer(newParameter),
parameterList);
anchor = (GrParameter)parameterList.addAfter(grParameter, anchor);
/* }
else {
GrParameter grParameter = oldParameters[index];
if (grParameter != getNextOfType(parameterList, anchor, GrParameter.class)) {
anchor = (GrParameter)parameterList.addAfter(grParameter, anchor);
}
else {
anchor = grParameter;
toRemove.remove(grParameter);
}
if (anchor.getName() != newParameter.getName()) {
anchor.setName(newParameter.getName());
}
}*/
}
for (GrParameter oldParameter : toRemove) {
oldParameter.delete();
}
PsiUtil.shortenReferences(parameterList);
CodeStyleManager.getInstance(parameterList.getProject()).reformat(parameterList);
if (changeInfo.isExceptionSetOrOrderChanged()) {
@@ -230,6 +236,31 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
return true;
}
private static PsiSubstitutor calculateSubstitutor(PsiMethod derivedMethod, PsiMethod baseMethod) {
PsiSubstitutor substitutor;
if (derivedMethod.getManager().areElementsEquivalent(derivedMethod, baseMethod)) {
substitutor = PsiSubstitutor.EMPTY;
}
else {
final PsiClass baseClass = baseMethod.getContainingClass();
final PsiClass derivedClass = derivedMethod.getContainingClass();
if (baseClass != null && derivedClass != null && InheritanceUtil.isInheritorOrSelf(derivedClass, baseClass, true)) {
final PsiSubstitutor superClassSubstitutor =
TypeConversionUtil.getSuperClassSubstitutor(baseClass, derivedClass, PsiSubstitutor.EMPTY);
final MethodSignature superMethodSignature = baseMethod.getSignature(superClassSubstitutor);
final MethodSignature methodSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY);
final PsiSubstitutor superMethodSubstitutor =
MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, superMethodSignature);
substitutor = superMethodSubstitutor != null ? superMethodSubstitutor : superClassSubstitutor;
}
else {
substitutor = PsiSubstitutor.EMPTY;
}
}
return substitutor;
}
@Nullable
private static <Type extends PsiElement, List extends PsiElement> Type getNextOfType(List parameterList,
PsiElement current,
@@ -293,7 +324,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
String name = psiClass.getName();
GrConstructor constructor = ((GrConstructor)GroovyPsiElementFactory.getInstance(psiClass.getProject())
.createConstructorFromText(name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}"));
.createConstructorFromText(name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", null));
GrModifierList list = constructor.getModifierList();
if (psiClass.hasModifierProperty(GrModifier.PRIVATE)) list.setModifierProperty(GrModifier.PRIVATE, true);
@@ -337,8 +368,17 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
}
if (toChangeArguments) {
JavaParameterInfo[] parameters = changeInfo.getNewParameters();
GrArgumentList argumentList = ((GrCall)element.getParent()).getArgumentList();
if (argumentList == null) return;
GrArgumentList argumentList = PsiUtil.getArgumentsList(element);
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject());
if (argumentList == null) {
if (element instanceof GrEnumConstant) {
argumentList = factory.createArgumentList();
argumentList = (GrArgumentList)element.add(argumentList);
}
else {
return;
}
}
Set<PsiElement> argsToDelete = new HashSet<PsiElement>(map.length * 2);
for (GrClosureSignatureUtil.ArgInfo argInfo : map) {
argsToDelete.addAll(argInfo.args);
@@ -355,7 +395,6 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
arg.delete();
}
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject());
boolean skipOptionals = false;
PsiElement anchor = null; //PsiTreeUtil.getChildOfAnyType(argumentList, GrExpression.class, GrNamedArgument.class);
@@ -384,14 +423,29 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
else { //arguments for simple parameters
if (arguments.size() == 1) { //arg exists
PsiElement arg = arguments.iterator().next();
if (i == parameters.length - 1 && parameter.isVarargType()) {
if (arg instanceof GrSafeCastExpression) {
PsiElement expr = ((GrSafeCastExpression)arg).getOperand();
if (expr instanceof GrListOrMap && !((GrListOrMap)expr).isMap()) {
final PsiElement copy = expr.copy();
PsiElement[] newVarargs = ((GrListOrMap)copy).getInitializers();
for (PsiElement vararg : newVarargs) {
anchor = argumentList.addAfter(vararg, anchor);
}
arg.delete();
continue;
}
}
}
PsiElement curArg = getNextOfType(argumentList, anchor, GrExpression.class);
if (curArg == arg) {
anchor = arg;
}
else {
final PsiElement copy = arg.copy();
arg.delete();
anchor = argumentList.addAfter(copy, anchor);
arg.delete();
}
}
else { //arg is skipped. Parameter is optional
@@ -425,15 +479,18 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
private static void fixExceptions(PsiElement element, PsiClassType[] exceptions) {
if (exceptions.length == 0) return;
final GroovyPsiElement context =
PsiTreeUtil.getParentOfType(element, GrTryCatchStatement.class, GrClosableBlock.class, GrMethod.class);
PsiTreeUtil.getParentOfType(element, GrTryCatchStatement.class, GrClosableBlock.class, GrMethod.class, GroovyFile.class);
if (context instanceof GrClosableBlock) {
element = generateTryCatch(element, exceptions);
}
else if (context instanceof GrMethod) {
final PsiClassType[] referencedTypes = ((GrMethod)context).getThrowsList().getReferencedTypes();
final List<PsiClassType> psiClassTypes = filterOutExceptions(exceptions, context, referencedTypes);
final PsiClassType[] handledExceptions = ((GrMethod)context).getThrowsList().getReferencedTypes();
final List<PsiClassType> psiClassTypes = filterOutExceptions(exceptions, context, handledExceptions);
element = generateTryCatch(element, psiClassTypes.toArray(new PsiClassType[psiClassTypes.size()]));
}
else if (context instanceof GroovyFile) {
element = generateTryCatch(element, exceptions);
}
else if (context instanceof GrTryCatchStatement) {
final GrCatchClause[] catchClauses = ((GrTryCatchStatement)context).getCatchClauses();
List<PsiClassType> referencedTypes = ContainerUtil.map(catchClauses, new Function<GrCatchClause, PsiClassType>() {
@@ -493,6 +550,8 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
for (PsiClassType type : exceptions) {
final String[] names = GroovyNameSuggestionUtil.suggestVariableNameByType(type, nameValidator);
final GrCatchClause catchClause = factory.createCatchClause(type, names[0]);
final GrStatement printStackTrace = factory.createStatementFromText(names[0] + ".printStackTrace()");
catchClause.getBody().addStatementBefore(printStackTrace, null);
anchor = tryCatch.addCatchClause(catchClause, anchor);
PsiUtil.shortenReferences(anchor);
}
@@ -501,10 +560,11 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
private static List<PsiClassType> filterOutExceptions(PsiClassType[] exceptions,
final GroovyPsiElement context,
final PsiClassType[] referencedTypes) {
final PsiClassType[] handledExceptions) {
return ContainerUtil.findAll(exceptions, new Condition<PsiClassType>() {
public boolean value(PsiClassType o) {
for (PsiClassType type : referencedTypes) {
if (!InheritanceUtil.isInheritor(o, CommonClassNames.JAVA_LANG_EXCEPTION)) return false;
for (PsiClassType type : handledExceptions) {
if (TypesUtil.isAssignable(type, o, context.getManager(), context.getResolveScope(), false)) return false;
}
return true;
@@ -11,8 +11,6 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.plugins.groovy.util.TestUtils;
import java.io.File;
/**
* @author Maxim.Medvedev
*/
@@ -125,7 +123,7 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
}
*/
//todo?
/*//todo?
public void testUseAnyVariable() throws Exception {
doTest(null, null, null, new GenParams() {
public ParameterInfoImpl[] genParams(PsiMethod method) throws IncorrectOperationException {
@@ -135,20 +133,21 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
};
}
}, false);
}
}*/
/*
public void testRemoveVarargParameter() throws Exception {
doTest(null, null, null, new ParameterInfoImpl[]{new ParameterInfoImpl(0)}, new ThrownExceptionInfo[0], false);
}
*/
public void testEnumConstructor() throws Exception {
doTest(null, new ParameterInfoImpl[] {
new ParameterInfoImpl(-1, "i", PsiType.INT, "10")
}, false);
}
*/
public void testVarargs1() throws Exception {
doTest(null, new ParameterInfoImpl[] {
new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN, "true"),
@@ -166,6 +165,7 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
false);
}
/*
public void testAlreadyHandled() throws Exception {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
new GenExceptions() {
@@ -176,8 +176,9 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
}
},
false);
}
}*/
/*
public void testAddRuntimeException() throws Exception {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
new GenExceptions() {
@@ -189,6 +190,7 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
},
false);
}
*/
public void testAddException() throws Exception {
doTest(null, null, null, new SimpleParameterGen(new ParameterInfoImpl[0]),
@@ -202,6 +204,7 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
false);
}
/*
//todo
public void testReorderWithVarargs() throws Exception { // IDEADEV-26977
final PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
@@ -210,10 +213,7 @@ public class ChangeSignatureForJavaTest extends LightCodeInsightFixtureTestCase
new ParameterInfoImpl(0, "s", factory.createTypeFromText("java.lang.String...", myFixture.getFile()))
}, false);
}
public void testIntroduceParameterWithDefaultValueInHierarchy() throws Exception {
doTest(null, new ParameterInfoImpl[]{new ParameterInfoImpl(-1, "i", PsiType.INT, "0")}, false);
}
*/
private void doTest(String newReturnType, ParameterInfoImpl[] parameterInfos, final boolean generateDelegate) throws Exception {
doTest(null, null, newReturnType, parameterInfos, new ThrownExceptionInfo[0], generateDelegate);
@@ -183,18 +183,28 @@ public class ChangeSignatureTest extends ChangeSignatureTestCase {
);
}
public void testGenerateDelegateForConstructor() {
//todo
public void testGenerateDelegateForConstructor() throws Exception {
doTest("public", "Foo", null, new SimpleInfo[]{new SimpleInfo(0), new SimpleInfo("a", -1, "5", null, PsiType.INT)},
new ThrownExceptionInfo[0], true);
}
public void testGenerateDelegateForAbstract() {
//todo
public void testGenerateDelegateForAbstract() throws Exception {
doTest("public", "foo", null, new SimpleInfo[]{new SimpleInfo(0), new SimpleInfo("a", -1, "5", null, PsiType.INT)},
new ThrownExceptionInfo[0], true);
}
public void testTypeParameters() throws Exception {
doTest(new SimpleInfo[]{new SimpleInfo("list", -1, "null", null, createType("java.util.List<T>")), new SimpleInfo(0)});
}
public void testEnumConstructor() throws Exception {
doTest(new SimpleInfo[]{new SimpleInfo("a", -1, "2", null, PsiType.INT)});
}
public void testMoveArrayToTheEnd() throws Exception {
doTest(new SimpleInfo[] {new SimpleInfo(1), new SimpleInfo(0)});
}
private PsiType createType(String typeText) {
return JavaPsiFacade.getElementFactory(getProject()).createTypeByFQClassName(typeText, GlobalSearchScope.allScope(getProject()));
}
@@ -6,6 +6,7 @@ def bar() {
try{
foo("")
}catch(IOException e){
e.printStackTrace()
}
}
@@ -4,5 +4,6 @@ new Object().each {
try{
foo("")
}catch(IOException e){
e.printStackTrace()
}
}
@@ -0,0 +1,9 @@
abstract class X {
abstract def foo<caret>(String s)
}
class Y extends X {
def foo(String s) {
}
}
@@ -0,0 +1,13 @@
abstract class X {
abstract def foo(String s, int a)
def foo(String s) {
return foo(s, 5);
}
}
class Y extends X {
def foo(String s, int a) {
}
}
@@ -0,0 +1,11 @@
class Foo {
def F<caret>oo(String s) {
}
def Foo() {
this("a")
print new Foo("b");
}
}
@@ -0,0 +1,15 @@
class Foo {
def Foo(String s, int a) {
}
def Foo(String s) {
this(s, 5);
}
def Foo() {
this("a")
print new Foo("b");
}
}
@@ -0,0 +1,3 @@
def fo<caret>o(String[] ss, int i) {}
foo(["1", "2"] as String[], 1);
@@ -0,0 +1,3 @@
def foo(int i, String[] ss) {}
foo(1, "1", "2");
@@ -0,0 +1,7 @@
class X<T> {
def f<caret>oo(T t) {}
}
class Y extends X<String> {
def foo(String t){}
}
@@ -0,0 +1,7 @@
class X<T> {
def foo(List<T> list, T t) {}
}
class Y extends X<String> {
def foo(List<String> list, String t){}
}
@@ -1,6 +1,6 @@
def test=new Test()
try{
test.foo();
} catch (Exception e) {
test.foo()
}catch(Exception e){
e.printStackTrace()
}
@@ -0,0 +1,7 @@
class B1 extends A {
Q method() { }
}
class C1 extends A {
Z method() { }
}
@@ -0,0 +1,7 @@
class B1 extends A {
Q method() { }
}
class C1 extends A {
Runnable method() { }
}
@@ -1,7 +0,0 @@
enum En {
A {},
B {},
C;
<caret>En() { }
}
@@ -1,7 +0,0 @@
enum En {
A(10) {},
B(10) {},
C(10);
En(int i) { }
}
@@ -0,0 +1,5 @@
class CString1 extends C<String> {
void put(Object o) {
System.out.println(o+"Text");
}
}
@@ -0,0 +1,5 @@
class CString1 extends C<String> {
void put(String t) {
System.out.println(t+"Text");
}
}
@@ -1,9 +0,0 @@
class Foo {
void f<caret>oo(){}
class A extends Foo {
void foo(){
super.foo();
}
}
}
@@ -1,9 +0,0 @@
class Foo {
void foo(int i){}
class A extends Foo {
void foo(int i){
super.foo(i);
}
}
}
@@ -0,0 +1,20 @@
class Derived1 extends Test {
void foo() throws MyException,
MyException1 {
}
void bar () {
try {
foo();
}
catch (MyException e) {}
catch (MyException1 myException1) {}
}
}
try {
new Test().foo();
}
catch (MyException e) {}
catch (MyException1 myException1) {}
@@ -0,0 +1,19 @@
class Derived1 extends Test {
void foo() throws MyException1, MyException {
}
void bar () {
try {
Test.foo();
}
catch (MyException e) {}
catch (MyException1 myException1) {}
}
}
try {
new Test().foo();
}
catch (MyException e) {}
catch (MyException1 myException1) {}
@@ -1,7 +0,0 @@
class Test {
void <caret>foo(String[] s, int a) {}
{
foo(new String[]{"a", "bbb"}, 1);
}
}
@@ -1,7 +0,0 @@
class Test {
void foo(int a, String... s) {}
{
foo(1, "a", "bbb");
}
}
@@ -0,0 +1,4 @@
class C2 extends C<String> {
protected <V> V method(){
}
}
@@ -0,0 +1,4 @@
class C2 extends C<String> {
protected <V> V method(String t, V u, C<V> cu){
}
}
@@ -0,0 +1,3 @@
new C().method()
new C().method(1)
new C().method(1, 2)
@@ -0,0 +1,3 @@
new C().method(true)
new C().method(true, 1)
new C().method(true, 1, 2)