Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.intellij.java.impl.refactoring.inline;

import com.intellij.java.analysis.impl.codeInspection.SideEffectChecker;
import com.intellij.java.impl.psi.impl.source.resolve.reference.impl.JavaLangClassMemberReference;
import com.intellij.java.impl.refactoring.introduceParameter.Util;
import com.intellij.java.impl.refactoring.rename.RenameJavaVariableProcessor;
import com.intellij.java.impl.refactoring.util.ConflictsUtil;
Expand Down Expand Up @@ -66,6 +68,7 @@
import consulo.usage.NonCodeUsageInfo;
import consulo.usage.UsageInfo;
import consulo.usage.UsageViewDescriptor;
import consulo.util.collection.ContainerUtil;
import consulo.util.collection.MultiMap;
import consulo.util.dataholder.Key;
import consulo.util.lang.StringUtil;
Expand Down Expand Up @@ -211,29 +214,34 @@ protected boolean preprocessUsages(@Nonnull SimpleReference<UsageInfo[]> refUsag
}
}
UsageInfo[] usagesIn = refUsages.get();
MultiMap<PsiElement, String> conflicts = new MultiMap<>();
MultiMap<PsiElement, LocalizeValue> conflicts = new MultiMap<>();

if (!myInlineThisOnly) {
PsiMethod[] superMethods = myMethod.findSuperMethods();
for (PsiMethod method : superMethods) {
String className = Objects.requireNonNull(method.getContainingClass()).getQualifiedName();
LocalizeValue message = method.isAbstract()
? RefactoringLocalize.inlinedMethodImplementsMethodFrom0(method.getContainingClass().getQualifiedName())
: RefactoringLocalize.inlinedMethodOverridesMethodFrom0(method.getContainingClass().getQualifiedName());
conflicts.putValue(method, message.get());
? RefactoringLocalize.inlinedMethodImplementsMethodFrom0(className)
: RefactoringLocalize.inlinedMethodOverridesMethodFrom0(className);
conflicts.putValue(method, message);
}

for (UsageInfo info : usagesIn) {
PsiElement element = info.getElement();
if (element instanceof PsiDocMethodOrFieldRef && !PsiTreeUtil.isAncestor(myMethod, element, false)) {
conflicts.putValue(element, JavaRefactoringLocalize.inlineMethodUsedInJavadoc().get());
if (element instanceof PsiDocMethodOrFieldRef memberRef && !PsiTreeUtil.isAncestor(myMethod, memberRef, false)) {
conflicts.putValue(memberRef, JavaRefactoringLocalize.inlineMethodUsedInJavadoc());
}
if (element instanceof PsiMethodReferenceExpression) {
conflicts.putValue(element, "Inlined method is used in method reference");
if (element instanceof PsiLiteralExpression literal
&& ContainerUtil.or(literal.getReferences(), JavaLangClassMemberReference.class::isInstance)) {
conflicts.putValue(literal, JavaRefactoringLocalize.inlineMethodUsedInReflection());
}
if (element instanceof PsiMethodReferenceExpression methodRef) {
processSideEffectsInMethodReferenceQualifier(conflicts, methodRef);
}

LocalizeValue errorMessage = checkCalledInSuperOrThisExpr(myMethod.getBody(), element);
if (errorMessage != LocalizeValue.empty()) {
conflicts.putValue(element, errorMessage.get());
conflicts.putValue(element, errorMessage);
}
}
}
Expand All @@ -248,7 +256,7 @@ protected boolean preprocessUsages(@Nonnull SimpleReference<UsageInfo[]> refUsag
@Nonnull
@Override
@RequiredReadAction
public MultiMap<PsiElement, String> getConflicts(@Nonnull PsiReference reference, @Nonnull PsiElement referenced) {
public MultiMap<PsiElement, LocalizeValue> getConflicts(@Nonnull PsiReference reference, @Nonnull PsiElement referenced) {
return MultiMap.empty();
}

Expand Down Expand Up @@ -281,7 +289,7 @@ public void inlineUsage(@Nonnull UsageInfo usage, @Nonnull PsiElement referenced
if (reference != null) {
InlineUtil.TailCallType type = InlineUtil.getTailCallType(reference);
if (type == InlineUtil.TailCallType.Simple) {
conflicts.putValue(statement, "Inlined result would contain parse errors");
conflicts.putValue(statement, LocalizeValue.localizeTODO("Inlined result would contain parse errors"));
break;
}
}
Expand All @@ -296,6 +304,20 @@ public void inlineUsage(@Nonnull UsageInfo usage, @Nonnull PsiElement referenced
return showConflicts(conflicts, usagesIn);
}

private static void processSideEffectsInMethodReferenceQualifier(
@Nonnull MultiMap<PsiElement, LocalizeValue> conflicts,
@Nonnull PsiMethodReferenceExpression methodRef
) {
PsiExpression qualifierExpression = methodRef.getQualifierExpression();
if (qualifierExpression != null) {
List<PsiElement> sideEffects = new ArrayList<>();
SideEffectChecker.checkSideEffects(qualifierExpression, sideEffects);
if (!sideEffects.isEmpty()) {
conflicts.putValue(methodRef, JavaRefactoringLocalize.inlineMethodQualifierUsageSideEffect());
}
}
}

@RequiredReadAction
private static List<PsiReference> convertUsagesToRefs(UsageInfo[] usagesIn) {
List<PsiReference> refs = new ArrayList<>();
Expand All @@ -312,8 +334,7 @@ private boolean checkReadOnly() {
return myMethod.isWritable() || myMethod instanceof PsiCompiledElement;
}

private void addInaccessibleSuperCallsConflicts(final UsageInfo[] usagesIn, final MultiMap<PsiElement, String> conflicts) {

private void addInaccessibleSuperCallsConflicts(final UsageInfo[] usagesIn, final MultiMap<PsiElement, LocalizeValue> conflicts) {
myMethod.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitClass(@Nonnull PsiClass aClass) {
Expand Down Expand Up @@ -347,8 +368,14 @@ public void visitSuperExpression(@Nonnull PsiSuperExpression expression) {
LOG.assertTrue(methodCallExpression != null);
conflicts.putValue(
expression,
"Inlined method calls " + methodCallExpression.getText() + " which won't be accessed in " +
StringUtil.join(targetContainingClasses, psiClass -> RefactoringUIUtil.getDescription(psiClass, false), ",")
LocalizeValue.localizeTODO(
"Inlined method calls " + methodCallExpression.getText() + " which won't be accessed in " +
StringUtil.join(
targetContainingClasses,
psiClass -> RefactoringUIUtil.getDescription(psiClass, false),
","
)
)
);
}
}
Expand All @@ -361,7 +388,7 @@ public static void addInaccessibleMemberConflicts(
PsiElement element,
UsageInfo[] usages,
ReferencedElementsCollector collector,
MultiMap<PsiElement, String> conflicts
MultiMap<PsiElement, LocalizeValue> conflicts
) {
element.accept(collector);
Map<PsiMember, Set<PsiMember>> containersToReferenced = getInaccessible(collector.myReferencedMembers, usages, element);
Expand All @@ -376,22 +403,18 @@ public static void addInaccessibleMemberConflicts(
referencedDescription,
containerDescription
);
conflicts.putValue(container, CommonRefactoringUtil.capitalize(message.get()));
conflicts.putValue(container, message.capitalize());
}
}
}

/**
* Given a set of referencedElements, returns a map from containers (in a sense of ConflictsUtil.getContainer)
* to subsets of referencedElements that are not accessible from that container
*
* @param referencedElements
* @param usages
* @param elementToInline
*/
@RequiredReadAction
private static Map<PsiMember, Set<PsiMember>> getInaccessible(
HashSet<PsiMember> referencedElements,
Set<PsiMember> referencedElements,
UsageInfo[] usages,
PsiElement elementToInline
) {
Expand Down Expand Up @@ -584,7 +607,7 @@ private static void replaceParameterReferences(
boolean isParameterReference = false;
if (element instanceof PsiReferenceExpression expression
&& expression.resolve() instanceof PsiParameter parameter
&& element.getManager().areElementsEquivalent(parameter.getDeclarationScope(), oldConstructor)) {
&& expression.getManager().areElementsEquivalent(parameter.getDeclarationScope(), oldConstructor)) {
isParameterReference = true;
PsiElement declarationScope = parameter.getDeclarationScope();
PsiParameter[] declarationParameters = ((PsiMethod) declarationScope).getParameterList().getParameters();
Expand Down Expand Up @@ -823,7 +846,7 @@ private BlockData prepareBlock(
if (paramType instanceof PsiEllipsisType ellipsisType) {
paramType = callSubstitutor.substitute(ellipsisType.toArrayType());
if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
defaultValue = "new " + ((PsiArrayType) paramType).getComponentType().getCanonicalText() + "[]{}";
defaultValue = "new " + ellipsisType.getComponentType().getCanonicalText() + "[]{}";
}
else {
defaultValue = PsiTypesUtil.getDefaultValueOfType(paramType);
Expand Down Expand Up @@ -1468,8 +1491,7 @@ private void inlineEnumConstantParameter(
@Override
public void visitReturnStatement(@Nonnull PsiReturnStatement statement) {
super.visitReturnStatement(statement);
PsiExpression expr = statement.getReturnValue();
if (expr instanceof PsiMethodCallExpression methodCall) {
if (statement.getReturnValue() instanceof PsiMethodCallExpression methodCall) {
refsVector.add(methodCall.getMethodExpression());
}
}
Expand All @@ -1494,11 +1516,7 @@ private static PsiExpression getSimpleReturnedExpression(PsiMethod method) {
if (psiStatements.length != 1) {
return null;
}
PsiStatement statement = psiStatements[0];
if (!(statement instanceof PsiReturnStatement)) {
return null;
}
return ((PsiReturnStatement) statement).getReturnValue();
return psiStatements[0] instanceof PsiReturnStatement returnStmt ? returnStmt.getReturnValue() : null;
}

private static void addMarkedElements(final List<PsiReferenceExpression> array, PsiElement scope) {
Expand Down
Loading