mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-22 14:31:25 +07:00
change signature: propagate parameters change to lambda expressions (IDEA-150138)
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.refactoring.changeSignature;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
|
||||
class FunctionalInterfaceChangedUsageInfo extends UsageInfo {
|
||||
|
||||
private final PsiMethod myMethod;
|
||||
|
||||
public FunctionalInterfaceChangedUsageInfo(PsiElement element, PsiMethod method) {
|
||||
super(element);
|
||||
myMethod = method;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return "Functional expression will be corrupted";
|
||||
}
|
||||
|
||||
public PsiMethod getMethod() {
|
||||
return myMethod;
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,15 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (usage instanceof FunctionalInterfaceChangedUsageInfo) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(usage.getProject());
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element instanceof PsiLambdaExpression) {
|
||||
processMethodParams((JavaChangeInfo)changeInfo, ((FunctionalInterfaceChangedUsageInfo)usage).getMethod(),
|
||||
elementFactory, PsiSubstitutor.EMPTY, ((PsiLambdaExpression)element).getParameterList(), ((PsiLambdaExpression)element).getBody());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
@@ -728,10 +737,24 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
|
||||
PsiParameterList list = method.getParameterList();
|
||||
int newParamsLength = processMethodParams(changeInfo, baseMethod, factory, substitutor, list, method.getBody());
|
||||
fixJavadocsForChangedMethod(method, changeInfo, newParamsLength);
|
||||
if (changeInfo.isExceptionSetOrOrderChanged()) {
|
||||
final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
|
||||
fixPrimaryThrowsLists(method, newExceptions);
|
||||
}
|
||||
}
|
||||
|
||||
private static int processMethodParams(JavaChangeInfo changeInfo,
|
||||
PsiMethod baseMethod,
|
||||
PsiElementFactory factory,
|
||||
PsiSubstitutor substitutor,
|
||||
PsiParameterList list,
|
||||
PsiElement methodBody) {
|
||||
PsiParameter[] parameters = list.getParameters();
|
||||
|
||||
final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters();
|
||||
final int delta = baseMethod != null ? baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount() : 0;
|
||||
final int delta = baseMethod != null ? baseMethod.getParameterList().getParametersCount() - list.getParametersCount() : 0;
|
||||
PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)];
|
||||
final String[] oldParameterNames = changeInfo.getOldParameterNames();
|
||||
final String[] oldParameterTypes = changeInfo.getOldParameterTypes();
|
||||
@@ -748,12 +771,15 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
parameter.getNameIdentifier().replace(newIdentifier);
|
||||
}
|
||||
|
||||
String oldType = oldParameterTypes[index];
|
||||
if (!oldType.equals(info.getTypeText())) {
|
||||
parameter.normalizeDeclaration();
|
||||
PsiType newType = substitutor.substitute(info.createType(changeInfo.getMethod().getParameterList(), method.getManager()));
|
||||
|
||||
parameter.getTypeElement().replace(factory.createTypeElement(newType));
|
||||
final PsiTypeElement typeElement = parameter.getTypeElement();
|
||||
if (typeElement != null) {
|
||||
String oldType = oldParameterTypes[index];
|
||||
if (!oldType.equals(info.getTypeText())) {
|
||||
parameter.normalizeDeclaration();
|
||||
PsiType newType =
|
||||
substitutor.substitute(info.createType(changeInfo.getMethod().getParameterList(), changeInfo.getMethod().getManager()));
|
||||
typeElement.replace(factory.createTypeElement(newType));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -762,12 +788,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
|
||||
|
||||
resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm());
|
||||
fixJavadocsForChangedMethod(method, changeInfo, newParms.length);
|
||||
if (changeInfo.isExceptionSetOrOrderChanged()) {
|
||||
final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo);
|
||||
fixPrimaryThrowsLists(method, newExceptions);
|
||||
}
|
||||
resolveParameterVsFieldsConflicts(newParms, list, changeInfo.toRemoveParm(), methodBody);
|
||||
return newParms.length;
|
||||
}
|
||||
|
||||
private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo) throws IncorrectOperationException {
|
||||
@@ -804,7 +826,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]);
|
||||
boolean[] toRemoveParm = new boolean[arrayed.length];
|
||||
Arrays.fill(toRemoveParm, false);
|
||||
resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm);
|
||||
resolveParameterVsFieldsConflicts(arrayed, caller.getParameterList(), toRemoveParm, caller.getBody());
|
||||
}
|
||||
|
||||
if (toInsertThrows) {
|
||||
@@ -883,12 +905,12 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
|
||||
private static void resolveParameterVsFieldsConflicts(final PsiParameter[] newParms,
|
||||
final PsiMethod method,
|
||||
final PsiParameterList list,
|
||||
boolean[] toRemoveParm) throws IncorrectOperationException {
|
||||
boolean[] toRemoveParm,
|
||||
final PsiElement methodBody) throws IncorrectOperationException {
|
||||
List<FieldConflictsResolver> conflictResolvers = new ArrayList<FieldConflictsResolver>();
|
||||
for (PsiParameter parameter : newParms) {
|
||||
conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody()));
|
||||
conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), methodBody));
|
||||
}
|
||||
ChangeSignatureUtil.synchronizeList(list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm);
|
||||
JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list);
|
||||
@@ -957,7 +979,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
|
||||
}
|
||||
|
||||
checkContract(conflictDescriptions, method);
|
||||
} else if (element instanceof PsiMethodReferenceExpression) {
|
||||
}
|
||||
else if (element instanceof PsiMethodReferenceExpression) {
|
||||
conflictDescriptions.putValue(element, "Changed method is used in method reference");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,16 +329,4 @@ class JavaChangeSignatureUsageSearcher {
|
||||
RefactoringUIUtil.getDescription(myMethod, true));
|
||||
}
|
||||
}
|
||||
|
||||
private static class FunctionalInterfaceChangedUsageInfo extends UnresolvableCollisionUsageInfo {
|
||||
|
||||
public FunctionalInterfaceChangedUsageInfo(PsiElement element, PsiElement referencedElement) {
|
||||
super(element, referencedElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Functional expression will be corrupted";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,12 +31,16 @@ import java.util.List;
|
||||
*/
|
||||
public class FieldConflictsResolver {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.FieldConflictsResolver");
|
||||
private final PsiCodeBlock myScope;
|
||||
private final PsiElement myScope;
|
||||
private final PsiField myField;
|
||||
private final List<PsiReferenceExpression> myReferenceExpressions;
|
||||
private PsiClass myQualifyingClass;
|
||||
|
||||
public FieldConflictsResolver(String name, PsiCodeBlock scope) {
|
||||
this(name, (PsiElement)scope);
|
||||
}
|
||||
|
||||
public FieldConflictsResolver(String name, PsiElement scope) {
|
||||
myScope = scope;
|
||||
if (myScope == null) {
|
||||
myField = null;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
interface SAM {
|
||||
void foo(boolean b);
|
||||
}
|
||||
|
||||
class Test {
|
||||
{
|
||||
bar((boolean b) -> {});
|
||||
}
|
||||
|
||||
void bar(SAM sam){}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
interface SAM {
|
||||
void foo(boolean b);
|
||||
}
|
||||
|
||||
class Test {
|
||||
{
|
||||
SAM sam = (boolean b) -> {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
interface I {
|
||||
void m<caret>(int a, int b);
|
||||
}
|
||||
|
||||
class Test {
|
||||
{
|
||||
I i = (a, b) -> {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
interface I {
|
||||
void m(int b, boolean a);
|
||||
}
|
||||
|
||||
class Test {
|
||||
{
|
||||
I i = (b, a) -> {};
|
||||
}
|
||||
}
|
||||
@@ -15,23 +15,19 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.ChangeSignatureBaseTest;
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
|
||||
import com.intellij.refactoring.changeSignature.ThrownExceptionInfo;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
|
||||
public class ChangeSignatureTouchLambdaTest extends ChangeSignatureBaseTest {
|
||||
|
||||
public void testVariableDeclaration() {
|
||||
doTestConflict();
|
||||
doTest(null, null, null, new ParameterInfoImpl[] {new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, new ThrownExceptionInfo[0], false);
|
||||
}
|
||||
|
||||
public void testMethodArgument() throws Exception {
|
||||
doTestConflict();
|
||||
doTest(null, null, null, new ParameterInfoImpl[] {new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, new ThrownExceptionInfo[0], false);
|
||||
}
|
||||
|
||||
public void testDefaultMethodTouched() throws Exception {
|
||||
@@ -42,14 +38,6 @@ public class ChangeSignatureTouchLambdaTest extends ChangeSignatureBaseTest {
|
||||
doTest(null, null, null, new ParameterInfoImpl[] {new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN, "false")}, new ThrownExceptionInfo[0], true);
|
||||
}
|
||||
|
||||
private void doTestConflict() {
|
||||
try {
|
||||
doTest(null, null, null, new ParameterInfoImpl[] {new ParameterInfoImpl(-1, "b", PsiType.BOOLEAN)}, new ThrownExceptionInfo[0], false);
|
||||
fail("Conflict expected");
|
||||
}
|
||||
catch (BaseRefactoringProcessor.ConflictsInTestsException ignored) { }
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRelativePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/lambda/changeSignature/";
|
||||
|
||||
@@ -333,6 +333,13 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest {
|
||||
}, false);
|
||||
}
|
||||
|
||||
public void testReorderParamsOfFunctionalInterface() {
|
||||
doTest(null, null, null, method -> new ParameterInfoImpl[]{
|
||||
new ParameterInfoImpl(1, "b", PsiType.INT),
|
||||
new ParameterInfoImpl(0, "a", PsiType.BOOLEAN)
|
||||
}, false);
|
||||
}
|
||||
|
||||
public void testMethodParametersAlignmentAfterMethodNameChange() {
|
||||
getJavaSettings().ALIGN_MULTILINE_PARAMETERS = true;
|
||||
getJavaSettings().ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true;
|
||||
|
||||
Reference in New Issue
Block a user