mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+1
-1
@@ -106,7 +106,7 @@ class AddModuleDependencyFix extends AddOrderEntryFix {
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return !project.isDisposed() && !myCurrentModule.isDisposed() && myModules.stream().noneMatch(Module::isDisposed);
|
||||
return !project.isDisposed() && !myCurrentModule.isDisposed() && !myModules.isEmpty() && myModules.stream().noneMatch(Module::isDisposed);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -56,6 +56,7 @@ abstract class MigrateToStreamFix implements LocalQuickFix {
|
||||
if (!FileModificationService.getInstance().preparePsiElementForWrite(loopStatement)) return;
|
||||
PsiElement result = migrate(project, loopStatement, body, tb);
|
||||
if(result != null) {
|
||||
source.cleanUpSource();
|
||||
simplifyAndFormat(project, result);
|
||||
}
|
||||
}
|
||||
|
||||
+179
-22
@@ -390,23 +390,14 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
return consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, variable.getType()) : null;
|
||||
}
|
||||
|
||||
static boolean isVariableSuitableForStream(PsiVariable variable, PsiStatement statement) {
|
||||
PsiElement declaration = variable.getParent();
|
||||
// For-loop initializer is not effectively final, but suitable for stream conversion
|
||||
if(declaration instanceof PsiDeclarationStatement) {
|
||||
PsiElement grandParent = declaration.getParent();
|
||||
if (grandParent instanceof PsiForStatement) {
|
||||
PsiForStatement forStatement = (PsiForStatement)grandParent;
|
||||
if (forStatement.getInitialization() == declaration) {
|
||||
PsiStatement body = forStatement.getBody();
|
||||
if(body != null && PsiTreeUtil.isAncestor(statement, body, false)) {
|
||||
return ReferencesSearch.search(variable, new LocalSearchScope(body)).forEach(ref -> {
|
||||
PsiElement element = ref.getElement();
|
||||
return !(element instanceof PsiExpression) || !PsiUtil.isAccessedForWriting((PsiExpression)element);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
static boolean isVariableSuitableForStream(PsiVariable variable, PsiStatement statement, TerminalBlock tb) {
|
||||
if(ReferencesSearch.search(variable, variable.getUseScope()).forEach(ref -> {
|
||||
PsiElement element = ref.getElement();
|
||||
return !(element instanceof PsiExpression) ||
|
||||
!PsiUtil.isAccessedForWriting((PsiExpression)element) ||
|
||||
tb.operations().anyMatch(op -> op.isWriteAllowed(variable, (PsiExpression)element));
|
||||
})) {
|
||||
return true;
|
||||
}
|
||||
return HighlightControlFlowUtil.isEffectivelyFinal(variable, statement, null);
|
||||
}
|
||||
@@ -429,6 +420,58 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether variable can be referenced between start and loop entry. Back-edges are also considered, so the actual place
|
||||
* where it referenced might be outside of (start, loop entry) interval.
|
||||
*
|
||||
* @param flow ControlFlow to analyze
|
||||
* @param start start point
|
||||
* @param loop loop to check
|
||||
* @param variable variable to analyze
|
||||
* @return true if variable can be referenced between start and stop points
|
||||
*/
|
||||
private static boolean isVariableReferencedBeforeLoopEntry(final ControlFlow flow,
|
||||
final int start,
|
||||
final PsiLoopStatement loop,
|
||||
final PsiVariable variable) {
|
||||
final int loopStart = flow.getStartOffset(loop);
|
||||
final int loopEnd = flow.getEndOffset(loop);
|
||||
if(start == loopStart) return false;
|
||||
|
||||
List<ControlFlowUtil.ControlFlowEdge> edges = ControlFlowUtil.getEdges(flow, start);
|
||||
// DFS visits instructions mainly in backward direction while here visiting in forward direction
|
||||
// greatly reduces number of iterations.
|
||||
Collections.reverse(edges);
|
||||
|
||||
BitSet referenced = new BitSet();
|
||||
boolean changed = true;
|
||||
while(changed) {
|
||||
changed = false;
|
||||
for(ControlFlowUtil.ControlFlowEdge edge: edges) {
|
||||
int from = edge.myFrom;
|
||||
int to = edge.myTo;
|
||||
if(referenced.get(from)) {
|
||||
// jump to the loop start from within the loop is not considered as loop entry
|
||||
if(to == loopStart && (from < loopStart || from >= loopEnd)) {
|
||||
return true;
|
||||
}
|
||||
if(!referenced.get(to)) {
|
||||
referenced.set(to);
|
||||
changed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(ControlFlowUtil.isVariableAccess(flow, from, variable)) {
|
||||
referenced.set(from);
|
||||
referenced.set(to);
|
||||
if(to == loopStart) return true;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum InitializerUsageStatus {
|
||||
// Variable is declared just before the wanted place
|
||||
DECLARED_JUST_BEFORE,
|
||||
@@ -440,7 +483,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
UNKNOWN
|
||||
}
|
||||
|
||||
static InitializerUsageStatus getInitializerUsageStatus(PsiVariable var, PsiStatement nextStatement) {
|
||||
static InitializerUsageStatus getInitializerUsageStatus(PsiVariable var, PsiLoopStatement nextStatement) {
|
||||
if(!(var instanceof PsiLocalVariable) || var.getInitializer() == null) return UNKNOWN;
|
||||
if(isDeclarationJustBefore(var, nextStatement)) return DECLARED_JUST_BEFORE;
|
||||
// Check that variable is declared in the same method or the same lambda expression
|
||||
@@ -458,7 +501,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
int start = controlFlow.getEndOffset(var.getInitializer())+1;
|
||||
int stop = controlFlow.getStartOffset(nextStatement);
|
||||
if(ControlFlowUtil.isVariableReferencedBetween(controlFlow, start, stop, var)) return UNKNOWN;
|
||||
if(isVariableReferencedBeforeLoopEntry(controlFlow, start, nextStatement, var)) return UNKNOWN;
|
||||
if (!ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var)) return AT_WANTED_PLACE_ONLY;
|
||||
return var.hasModifierProperty(PsiModifier.FINAL) ? UNKNOWN : AT_WANTED_PLACE;
|
||||
}
|
||||
@@ -494,6 +537,12 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
processLoop(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhileStatement(PsiWhileStatement statement) {
|
||||
super.visitWhileStatement(statement);
|
||||
processLoop(statement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitForStatement(PsiForStatement statement) {
|
||||
super.visitForStatement(statement);
|
||||
@@ -524,7 +573,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
int startOffset = controlFlow.getStartOffset(body);
|
||||
int endOffset = controlFlow.getEndOffset(body);
|
||||
final List<PsiVariable> nonFinalVariables = StreamEx.of(ControlFlowUtil.getUsedVariables(controlFlow, startOffset, endOffset))
|
||||
.remove(variable -> isVariableSuitableForStream(variable, statement)).toList();
|
||||
.remove(variable -> isVariableSuitableForStream(variable, statement, tb)).toList();
|
||||
|
||||
if (exitPoints.isEmpty()) {
|
||||
if(getIncrementedVariable(tb, nonFinalVariables) != null) {
|
||||
@@ -679,6 +728,12 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
PsiStatement initialization = ((PsiForStatement)statement).getInitialization();
|
||||
LOG.assertTrue(initialization != null);
|
||||
return initialization.getTextRange();
|
||||
} else if(statement instanceof PsiWhileStatement) {
|
||||
PsiJavaToken rParenth = ((PsiWhileStatement)statement).getRParenth();
|
||||
if (wholeStatement && rParenth != null) {
|
||||
return new TextRange(statement.getTextOffset(), rParenth.getTextOffset() + 1);
|
||||
}
|
||||
return statement.getFirstChild().getTextRange();
|
||||
} else {
|
||||
throw new IllegalStateException("Unexpected statement type: "+statement);
|
||||
}
|
||||
@@ -830,6 +885,10 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
|
||||
abstract String createReplacement();
|
||||
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static class FilterOp extends Operation {
|
||||
@@ -921,6 +980,11 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
PsiExpression expression = myType == null ? myExpression : RefactoringUtil.convertInitializerToNormalExpression(myExpression, myType);
|
||||
return "." + operationName + "(" + LambdaUtil.createLambda(myVariable, expression) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
return variable == myVariable && reference.getParent() == myExpression.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
static class FlatMapOp extends Operation {
|
||||
@@ -954,6 +1018,11 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
return mySource.createReplacement();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
return mySource.isWriteAllowed(variable, reference);
|
||||
}
|
||||
|
||||
boolean breaksMe(PsiBreakStatement statement) {
|
||||
return statement.findExitedStatement() == myLoop;
|
||||
}
|
||||
@@ -964,6 +1033,9 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
super(null, expression, variable);
|
||||
}
|
||||
|
||||
void cleanUpSource() {
|
||||
}
|
||||
|
||||
@Contract("null -> null")
|
||||
static StreamSource tryCreate(PsiLoopStatement statement) {
|
||||
if(statement instanceof PsiForStatement) {
|
||||
@@ -973,10 +1045,74 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
ArrayStream source = ArrayStream.from((PsiForeachStatement)statement);
|
||||
return source == null ? CollectionStream.from((PsiForeachStatement)statement) : source;
|
||||
}
|
||||
if(statement instanceof PsiWhileStatement) {
|
||||
return BufferedReaderLines.from((PsiWhileStatement)statement);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class BufferedReaderLines extends StreamSource {
|
||||
private BufferedReaderLines(PsiVariable variable, PsiExpression expression) {
|
||||
super(variable, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
String createReplacement() {
|
||||
return myExpression.getText()+".lines()";
|
||||
}
|
||||
|
||||
@Override
|
||||
void cleanUpSource() {
|
||||
myVariable.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
return myVariable == variable && reference.getParent() == PsiTreeUtil.getParentOfType(myExpression, PsiAssignmentExpression.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BufferedReaderLines from(PsiWhileStatement whileLoop) {
|
||||
// while ((line = br.readLine()) != null)
|
||||
PsiExpression condition = PsiUtil.skipParenthesizedExprDown(whileLoop.getCondition());
|
||||
if(!(condition instanceof PsiBinaryExpression)) return null;
|
||||
PsiBinaryExpression binOp = (PsiBinaryExpression)condition;
|
||||
if(!JavaTokenType.NE.equals(binOp.getOperationTokenType())) return null;
|
||||
PsiExpression operand = null;
|
||||
if(ExpressionUtils.isNullLiteral(binOp.getROperand())) {
|
||||
operand = binOp.getLOperand();
|
||||
} else if(ExpressionUtils.isNullLiteral(binOp.getLOperand())) {
|
||||
operand = binOp.getROperand();
|
||||
}
|
||||
if(operand == null) return null;
|
||||
PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(PsiUtil.skipParenthesizedExprDown(operand));
|
||||
if(assignment == null) return null;
|
||||
PsiExpression lValue = assignment.getLExpression();
|
||||
if(!(lValue instanceof PsiReferenceExpression)) return null;
|
||||
PsiElement element = ((PsiReferenceExpression)lValue).resolve();
|
||||
if(!(element instanceof PsiLocalVariable)) return null;
|
||||
PsiLocalVariable var = (PsiLocalVariable)element;
|
||||
if(!ReferencesSearch.search(var, var.getUseScope()).forEach(ref -> {
|
||||
return PsiTreeUtil.isAncestor(whileLoop, ref.getElement(), true);
|
||||
})) {
|
||||
return null;
|
||||
}
|
||||
PsiExpression rValue = PsiUtil.skipParenthesizedExprDown(assignment.getRExpression());
|
||||
if(!(rValue instanceof PsiMethodCallExpression)) return null;
|
||||
PsiMethodCallExpression call = (PsiMethodCallExpression)rValue;
|
||||
if(call.getArgumentList().getExpressions().length != 0) return null;
|
||||
if(!"readLine".equals(call.getMethodExpression().getReferenceName())) return null;
|
||||
PsiExpression readerExpression = call.getMethodExpression().getQualifierExpression();
|
||||
if(readerExpression == null) return null;
|
||||
PsiMethod method = call.resolveMethod();
|
||||
if(method == null) return null;
|
||||
PsiClass aClass = method.getContainingClass();
|
||||
if(aClass == null || !"java.io.BufferedReader".equals(aClass.getQualifiedName())) return null;
|
||||
return new BufferedReaderLines(var, readerExpression);
|
||||
}
|
||||
}
|
||||
|
||||
static class ArrayStream extends StreamSource {
|
||||
private ArrayStream(PsiVariable variable, PsiExpression expression) {
|
||||
super(variable, expression);
|
||||
@@ -1063,6 +1199,17 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
return className+"."+methodName+"("+myExpression.getText()+", "+myBound.getText()+")";
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isWriteAllowed(PsiVariable variable, PsiExpression reference) {
|
||||
if(variable == myVariable) {
|
||||
PsiForStatement forStatement = PsiTreeUtil.getParentOfType(variable, PsiForStatement.class);
|
||||
if(forStatement != null) {
|
||||
return PsiTreeUtil.isAncestor(forStatement.getUpdate(), reference, false);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CountingLoop from(PsiForStatement forStatement) {
|
||||
// check that initialization is for(int/long i = <initial_value>;...;...)
|
||||
@@ -1224,7 +1371,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
if(source == null || body == null) return null;
|
||||
// flatMap from primitive to primitive is supported only if primitive types match
|
||||
// otherwise it would be necessary to create bogus step like
|
||||
// .mapToObj(var -> blahblah.stream()).flatMap(Function.identity())
|
||||
// .mapToObj(var -> collection.stream()).flatMap(Function.identity())
|
||||
if(myVariable.getType() instanceof PsiPrimitiveType && !myVariable.getType().equals(source.getVariable().getType())) return null;
|
||||
FlatMapOp op = new FlatMapOp(myPreviousOp, source, myVariable, loopStatement);
|
||||
TerminalBlock withFlatMap = new TerminalBlock(op, source.getVariable(), body);
|
||||
@@ -1268,6 +1415,16 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
}
|
||||
}
|
||||
PsiAssignmentExpression assignment = ExpressionUtils.getAssignment(first);
|
||||
if(assignment != null) {
|
||||
PsiExpression lValue = assignment.getLExpression();
|
||||
PsiExpression rValue = assignment.getRExpression();
|
||||
if(rValue != null && lValue instanceof PsiReferenceExpression && ((PsiReferenceExpression)lValue).isReferenceTo(myVariable)) {
|
||||
PsiStatement[] leftOver = Arrays.copyOfRange(myStatements, 1, myStatements.length);
|
||||
MapOp op = new MapOp(myPreviousOp, rValue, myVariable, myVariable.getType());
|
||||
return new TerminalBlock(op, myVariable, leftOver);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1300,7 +1457,7 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private StreamEx<Operation> operations() {
|
||||
StreamEx<Operation> operations() {
|
||||
return StreamEx.iterate(myPreviousOp, Objects::nonNull, Operation::getPreviousOp);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -45,7 +45,9 @@ import com.intellij.refactoring.listeners.RefactoringEventData;
|
||||
import com.intellij.refactoring.listeners.RefactoringEventListener;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.InlineUtil;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -96,7 +98,7 @@ public class InlineLocalHandler extends JavaInlineActionHandler {
|
||||
final PsiElement element = psiReference.getElement();
|
||||
PsiElement innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, PsiLambdaExpression.class);
|
||||
while (innerClass != containingClass && innerClass != null) {
|
||||
final PsiClass parentPsiClass = PsiTreeUtil.getParentOfType(innerClass, PsiClass.class, true);
|
||||
final PsiElement parentPsiClass = PsiTreeUtil.getParentOfType(innerClass.getParent(), PsiClass.class, PsiLambdaExpression.class);
|
||||
if (parentPsiClass == containingClass) {
|
||||
if (innerClass instanceof PsiLambdaExpression) {
|
||||
if (PsiTreeUtil.isAncestor(innerClass, local, false)) {
|
||||
|
||||
@@ -470,7 +470,6 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
GenericInlineHandler.inlineReference(usage, myMethod, myInliners);
|
||||
}
|
||||
}
|
||||
myMethod.delete();
|
||||
}
|
||||
else {
|
||||
List<PsiReferenceExpression> refExprList = new ArrayList<>();
|
||||
@@ -513,8 +512,8 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
psiElement.delete();
|
||||
}
|
||||
}
|
||||
if (myMethod.isWritable()) myMethod.delete();
|
||||
}
|
||||
if (myMethod.isWritable()) myMethod.delete();
|
||||
}
|
||||
removeAddedBracesWhenPossible();
|
||||
}
|
||||
@@ -544,8 +543,9 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
public static void inlineConstructorCall(PsiCall constructorCall) {
|
||||
final PsiMethod oldConstructor = constructorCall.resolveMethod();
|
||||
PsiMethod oldConstructor = constructorCall.resolveMethod();
|
||||
LOG.assertTrue(oldConstructor != null);
|
||||
oldConstructor = (PsiMethod)oldConstructor.getNavigationElement();
|
||||
PsiExpression[] instanceCreationArguments = constructorCall.getArgumentList().getExpressions();
|
||||
if (oldConstructor.isVarArgs()) { //wrap with explicit array
|
||||
final PsiParameter[] parameters = oldConstructor.getParameterList().getParameters();
|
||||
|
||||
+6
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -81,6 +81,11 @@ public class InlineToAnonymousClassDialog extends InlineOptionsWithSearchSetting
|
||||
protected void saveSearchInCommentsAndStrings(boolean searchInComments) {
|
||||
JavaRefactoringSettings.getInstance().INLINE_CLASS_SEARCH_IN_COMMENTS = searchInComments;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean allowInlineAll() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSearchInTextOccurrences(boolean searchInTextOccurrences) {
|
||||
|
||||
+12
-10
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PlatformPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
@@ -115,7 +116,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
|
||||
final Ref<String> errorMessage = new Ref<>();
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> ApplicationManager.getApplication().runReadAction(() -> errorMessage.set(getCannotInlineMessage(psiClass))), "Check if inline is possible...", true, project)) return;
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> ApplicationManager.getApplication().runReadAction(() -> errorMessage.set(getCannotInlineMessage((PsiClass)psiClass.getNavigationElement()))), "Check if inline is possible...", true, project)) return;
|
||||
if (errorMessage.get() != null) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, errorMessage.get(), RefactoringBundle.message("inline.to.anonymous.refactoring"), null);
|
||||
return;
|
||||
@@ -201,7 +202,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
if (psiClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
return RefactoringBundle.message("inline.to.anonymous.no.abstract");
|
||||
}
|
||||
if (!psiClass.getManager().isInProject(psiClass)) {
|
||||
if (psiClass instanceof PsiCompiledElement) {
|
||||
return "Library classes cannot be inlined";
|
||||
}
|
||||
|
||||
@@ -230,6 +231,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(psiClass.getProject());
|
||||
final PsiMethod[] methods = psiClass.getMethods();
|
||||
for(PsiMethod method: methods) {
|
||||
if (method.isConstructor()) {
|
||||
@@ -238,7 +240,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
}
|
||||
}
|
||||
else if (method.findSuperMethods().length == 0) {
|
||||
if (!ReferencesSearch.search(method).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
if (!ReferencesSearch.search(method, searchScope).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
return "Class cannot be inlined because there are usages of its methods not inherited from its superclass or interface";
|
||||
}
|
||||
}
|
||||
@@ -253,7 +255,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
if (classModifiers.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return "Class cannot be inlined because it has static inner classes";
|
||||
}
|
||||
if (!ReferencesSearch.search(innerClass).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
if (!ReferencesSearch.search(innerClass, searchScope).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
return "Class cannot be inlined because it has usages of its inner classes";
|
||||
}
|
||||
}
|
||||
@@ -274,7 +276,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
return "Class cannot be inlined because it has static fields with non-constant initializers";
|
||||
}
|
||||
}
|
||||
if (!ReferencesSearch.search(field).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
if (!ReferencesSearch.search(field, searchScope).forEach(new AllowedUsagesProcessor(psiClass))) {
|
||||
return "Class cannot be inlined because it has usages of fields not inherited from its superclass";
|
||||
}
|
||||
}
|
||||
@@ -305,7 +307,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
@Nullable
|
||||
private static String getCannotInlineDueToUsagesMessage(final PsiClass aClass) {
|
||||
boolean hasUsages = false;
|
||||
for(PsiReference reference : ReferencesSearch.search(aClass)) {
|
||||
for(PsiReference reference : ReferencesSearch.search(aClass, GlobalSearchScope.projectScope(aClass.getProject()))) {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element == null) continue;
|
||||
if (!PsiTreeUtil.isAncestor(aClass, element, false)) {
|
||||
@@ -359,10 +361,10 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
|
||||
@Override
|
||||
public boolean process(final PsiReference psiReference) {
|
||||
if (PsiTreeUtil.isAncestor(myPsiElement, psiReference.getElement(), false)) {
|
||||
PsiElement element = psiReference.getElement();
|
||||
if (element != null && PsiTreeUtil.isAncestor(myPsiElement, element.getNavigationElement(), false)) {
|
||||
return true;
|
||||
}
|
||||
PsiElement element = psiReference.getElement();
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
PsiExpression qualifier = ((PsiReferenceExpression)element).getQualifierExpression();
|
||||
while (qualifier instanceof PsiParenthesizedExpression) {
|
||||
@@ -371,7 +373,7 @@ public class InlineToAnonymousClassHandler extends JavaInlineActionHandler {
|
||||
if (qualifier instanceof PsiNewExpression) {
|
||||
PsiNewExpression newExpr = (PsiNewExpression) qualifier;
|
||||
PsiJavaCodeReferenceElement classRef = newExpr.getClassReference();
|
||||
if (classRef != null && myPsiElement.equals(classRef.resolve())) {
|
||||
if (classRef != null && myPsiElement.isEquivalentTo(classRef.resolve())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+21
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -76,7 +76,8 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
return new UsageInfo[] { new UsageInfo(myCallToInline) };
|
||||
}
|
||||
Set<UsageInfo> usages = new HashSet<>();
|
||||
for (PsiReference reference : ReferencesSearch.search(myClass)) {
|
||||
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(myProject);
|
||||
for (PsiReference reference : ReferencesSearch.search(myClass, searchScope)) {
|
||||
usages.add(new UsageInfo(reference.getElement()));
|
||||
}
|
||||
|
||||
@@ -89,9 +90,8 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
if (mySearchInNonJavaFiles) {
|
||||
GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myClass.getProject());
|
||||
TextOccurrencesUtil.addTextOccurences(myClass, qName, projectScope, nonCodeUsages,
|
||||
new NonCodeUsageInfoFactory(myClass, qName));
|
||||
TextOccurrencesUtil.addTextOccurences(myClass, qName, searchScope, nonCodeUsages,
|
||||
new NonCodeUsageInfoFactory(myClass, qName));
|
||||
}
|
||||
usages.addAll(nonCodeUsages);
|
||||
}
|
||||
@@ -99,6 +99,15 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
return usages.toArray(new UsageInfo[usages.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Collection<? extends PsiElement> getElementsToWrite(@NotNull UsageViewDescriptor descriptor) {
|
||||
if (!myInlineThisOnly && !myClass.isWritable()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return super.getElementsToWrite(descriptor);
|
||||
}
|
||||
|
||||
protected void refreshElements(@NotNull PsiElement[] elements) {
|
||||
assert elements.length == 1;
|
||||
myClass = (PsiClass) elements [0];
|
||||
@@ -156,7 +165,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
@Override
|
||||
public void visitParameter(PsiParameter parameter) {
|
||||
super.visitParameter(parameter);
|
||||
if (PsiUtil.resolveClassInType(parameter.getType()) != myClass) return;
|
||||
if (!myClass.isEquivalentTo(PsiUtil.resolveClassInType(parameter.getType()))) return;
|
||||
|
||||
for (PsiReference psiReference : ReferencesSearch.search(parameter)) {
|
||||
final PsiElement refElement = psiReference.getElement();
|
||||
@@ -180,7 +189,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
super.visitNewExpression(expression);
|
||||
if (PsiUtil.resolveClassInType(expression.getType()) != myClass) return;
|
||||
if (!myClass.isEquivalentTo(PsiUtil.resolveClassInType(expression.getType()))) return;
|
||||
result.putValue(expression, "Class cannot be inlined because a call to its constructor inside body");
|
||||
}
|
||||
|
||||
@@ -189,7 +198,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
super.visitMethodCallExpression(expression);
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
|
||||
if (qualifierExpression != null && PsiUtil.resolveClassInType(qualifierExpression.getType()) != myClass) return;
|
||||
if (qualifierExpression != null && !myClass.isEquivalentTo(PsiUtil.resolveClassInType(qualifierExpression.getType()))) return;
|
||||
final PsiElement resolved = methodExpression.resolve();
|
||||
if (resolved instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)resolved;
|
||||
@@ -244,7 +253,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
if (!myInlineThisOnly) {
|
||||
if (!myInlineThisOnly && myClass.getOriginalElement().isWritable()) {
|
||||
try {
|
||||
myClass.delete();
|
||||
}
|
||||
@@ -262,7 +271,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
else {
|
||||
PsiClass target = superType.resolve();
|
||||
assert target != null : superType;
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
|
||||
PsiJavaCodeReferenceElement element = factory.createClassReferenceElement(target);
|
||||
PsiJavaCodeReferenceElement reference = psiNewExpression.getClassReference();
|
||||
assert reference != null : psiNewExpression;
|
||||
@@ -275,11 +284,11 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
|
||||
private void replaceWithSuperType(final PsiTypeElement typeElement, final PsiClassType superType) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
|
||||
PsiClassType psiType = (PsiClassType) typeElement.getType();
|
||||
PsiClassType.ClassResolveResult classResolveResult = psiType.resolveGenerics();
|
||||
PsiType substType = classResolveResult.getSubstitutor().substitute(superType);
|
||||
assert classResolveResult.getElement() == myClass;
|
||||
assert myClass.isEquivalentTo(classResolveResult.getElement());
|
||||
try {
|
||||
PsiElement replaced = typeElement.replace(factory.createTypeElement(substType));
|
||||
JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced);
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -82,7 +82,8 @@ class InlineToAnonymousConstructorProcessor {
|
||||
checkInlineChainingConstructor();
|
||||
JavaResolveResult classResolveResult = myNewExpression.getClassReference().advancedResolve(false);
|
||||
JavaResolveResult methodResolveResult = myNewExpression.resolveMethodGenerics();
|
||||
myConstructor = (PsiMethod) methodResolveResult.getElement();
|
||||
final PsiElement element = methodResolveResult.getElement();
|
||||
myConstructor = element != null ? (PsiMethod) element.getNavigationElement() : null;
|
||||
myConstructorArguments = myNewExpression.getArgumentList();
|
||||
|
||||
PsiSubstitutor classResolveSubstitutor = classResolveResult.getSubstitutor();
|
||||
|
||||
+11
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -54,8 +54,6 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspCodeBlock;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||
import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
|
||||
import com.intellij.psi.scope.processor.VariablesProcessor;
|
||||
import com.intellij.psi.scope.util.PsiScopesUtil;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.*;
|
||||
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
|
||||
@@ -755,14 +753,16 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
|
||||
boolean skipForStatement = true;
|
||||
final PsiForStatement forStatement = PsiTreeUtil.getParentOfType(expr, PsiForStatement.class);
|
||||
if (forStatement != null) {
|
||||
final VariablesProcessor variablesProcessor = new VariablesProcessor(false) {
|
||||
@Override
|
||||
protected boolean check(PsiVariable var, ResolveState state) {
|
||||
return PsiTreeUtil.isAncestor(forStatement.getInitialization(), var, true);
|
||||
}
|
||||
};
|
||||
PsiScopesUtil.treeWalkUp(variablesProcessor, expr, null);
|
||||
skipForStatement = variablesProcessor.size() == 0;
|
||||
Set<PsiVariable> vars = new HashSet<>();
|
||||
SyntaxTraverser.psiTraverser().withRoot(expr)
|
||||
.filter(element -> element instanceof PsiReferenceExpression)
|
||||
.forEach(element -> {
|
||||
final PsiElement resolve = ((PsiReferenceExpression)element).resolve();
|
||||
if (resolve instanceof PsiVariable) {
|
||||
vars.add((PsiVariable)resolve);
|
||||
}
|
||||
});
|
||||
skipForStatement = vars.stream().noneMatch(variable -> PsiTreeUtil.isAncestor(forStatement.getInitialization(), variable, true));
|
||||
}
|
||||
|
||||
PsiElement containerParent = tempContainer;
|
||||
|
||||
+17
-20
@@ -19,7 +19,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverridenUsageInfo;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverriddenUsageInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -34,7 +34,7 @@ class MigrateGetterNameSetting {
|
||||
|
||||
private final AtomicReference<Boolean> myGlobalValue = new AtomicReference<>();
|
||||
|
||||
void askUserIfNeed(final OverridenUsageInfo info, final String newMethodName, final PsiType migrationReturnType) {
|
||||
void askUserIfNeed(final OverriddenUsageInfo info, final String newMethodName, final PsiType migrationReturnType) {
|
||||
final Boolean globalValue = myGlobalValue.get();
|
||||
if (globalValue == null) {
|
||||
final String currentName = ((PsiMethod)info.getElement()).getName();
|
||||
@@ -42,26 +42,23 @@ class MigrateGetterNameSetting {
|
||||
currentName,
|
||||
newMethodName,
|
||||
migrationReturnType.getCanonicalText());
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Boolean globalValue = myGlobalValue.get();
|
||||
if (globalValue == null) {
|
||||
final int code = showChooserDialog(messageText);
|
||||
if (code == 0) {
|
||||
myGlobalValue.set(true);
|
||||
info.setMigrateMethodName(newMethodName);
|
||||
}
|
||||
else if (code == 1) {
|
||||
info.setMigrateMethodName(newMethodName);
|
||||
}
|
||||
else if (code == 2) {
|
||||
myGlobalValue.set(false);
|
||||
}
|
||||
}
|
||||
else if (globalValue.equals(Boolean.TRUE)) {
|
||||
UIUtil.invokeAndWaitIfNeeded((Runnable)() -> {
|
||||
final Boolean globalValue1 = myGlobalValue.get();
|
||||
if (globalValue1 == null) {
|
||||
final int code = showChooserDialog(messageText);
|
||||
if (code == 0) {
|
||||
myGlobalValue.set(true);
|
||||
info.setMigrateMethodName(newMethodName);
|
||||
}
|
||||
else if (code == 1) {
|
||||
info.setMigrateMethodName(newMethodName);
|
||||
}
|
||||
else if (code == 2) {
|
||||
myGlobalValue.set(false);
|
||||
}
|
||||
}
|
||||
else if (globalValue1.equals(Boolean.TRUE)) {
|
||||
info.setMigrateMethodName(newMethodName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
-9
@@ -46,15 +46,6 @@ public class TypeConversionDescriptorBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return substitutor of converted method parameters
|
||||
* or null if expression is not method call expression
|
||||
*/
|
||||
@Nullable
|
||||
public PsiSubstitutor getConvertedMethodParameters() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
return expression;
|
||||
}
|
||||
|
||||
@@ -348,14 +348,14 @@ public class TypeEvaluator {
|
||||
}
|
||||
|
||||
public String getReport() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
final StringBuilder buffer = new StringBuilder();
|
||||
|
||||
final String[] t = new String[myTypeMap.size()];
|
||||
int k = 0;
|
||||
|
||||
for (final TypeMigrationUsageInfo info : myTypeMap.keySet()) {
|
||||
final LinkedList<PsiType> types = myTypeMap.get(info);
|
||||
final StringBuffer b = new StringBuffer();
|
||||
final StringBuilder b = new StringBuilder();
|
||||
|
||||
if (types != null) {
|
||||
b.append(info.getElement()).append(" : ");
|
||||
|
||||
+11
-12
@@ -38,7 +38,7 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.rename.RenameProcessor;
|
||||
import com.intellij.refactoring.typeCook.deductive.PsiExtendedTypeVisitor;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverridenUsageInfo;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverriddenUsageInfo;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.OverriderUsageInfo;
|
||||
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
@@ -88,7 +88,7 @@ public class TypeMigrationLabeler {
|
||||
private final Set<TypeMigrationUsageInfo> myProcessedRoots = new HashSet<>();
|
||||
|
||||
public TypeMigrationLabeler(final TypeMigrationRules rules, PsiType rootType) {
|
||||
this(rules, Functions.<PsiElement, PsiType>constant(rootType));
|
||||
this(rules, Functions.constant(rootType));
|
||||
}
|
||||
|
||||
public TypeMigrationLabeler(final TypeMigrationRules rules, Function<PsiElement, PsiType> migrationRootTypeFunction) {
|
||||
@@ -339,8 +339,8 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
else {
|
||||
TypeMigrationReplacementUtil.migrateMemberOrVariableType(element, project, getTypeEvaluator().getType(usageInfo));
|
||||
if (usageInfo instanceof OverridenUsageInfo) {
|
||||
final String migrationName = ((OverridenUsageInfo)usageInfo).getMigrateMethodName();
|
||||
if (usageInfo instanceof OverriddenUsageInfo) {
|
||||
final String migrationName = ((OverriddenUsageInfo)usageInfo).getMigrateMethodName();
|
||||
if (migrationName != null) {
|
||||
ApplicationManager.getApplication().invokeLater(() -> new RenameProcessor(project, element, migrationName, false, false).run());
|
||||
}
|
||||
@@ -662,12 +662,12 @@ public class TypeMigrationLabeler {
|
||||
for (int i = -1; i < methods.length; i++) {
|
||||
final TypeMigrationUsageInfo m;
|
||||
if (i < 0) {
|
||||
final OverridenUsageInfo overridenUsageInfo = new OverridenUsageInfo(method);
|
||||
m = overridenUsageInfo;
|
||||
final OverriddenUsageInfo overriddenUsageInfo = new OverriddenUsageInfo(method);
|
||||
m = overriddenUsageInfo;
|
||||
final String newMethodName = isMethodNameCanBeChanged(method);
|
||||
if (newMethodName != null) {
|
||||
final MigrateGetterNameSetting migrateGetterNameSetting = myRules.getConversionSettings(MigrateGetterNameSetting.class);
|
||||
migrateGetterNameSetting.askUserIfNeed(overridenUsageInfo, newMethodName, myTypeEvaluator.getType(myCurrentRoot));
|
||||
migrateGetterNameSetting.askUserIfNeed(overriddenUsageInfo, newMethodName, myTypeEvaluator.getType(myCurrentRoot));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -687,13 +687,13 @@ public class TypeMigrationLabeler {
|
||||
final PsiMethod[] methods = OverridingMethodsSearch.search(method).toArray(PsiMethod.EMPTY_ARRAY);
|
||||
|
||||
final OverriderUsageInfo[] overriders = new OverriderUsageInfo[methods.length];
|
||||
final OverridenUsageInfo overridenUsageInfo = new OverridenUsageInfo(method.getParameterList().getParameters()[index]);
|
||||
final OverriddenUsageInfo overriddenUsageInfo = new OverriddenUsageInfo(method.getParameterList().getParameters()[index]);
|
||||
for (int i = -1; i < methods.length; i++) {
|
||||
final PsiMethod m = i < 0 ? method : methods[i];
|
||||
final PsiParameter p = m.getParameterList().getParameters()[index];
|
||||
final TypeMigrationUsageInfo paramUsageInfo;
|
||||
if (i < 0) {
|
||||
paramUsageInfo = overridenUsageInfo;
|
||||
paramUsageInfo = overriddenUsageInfo;
|
||||
}
|
||||
else {
|
||||
overriders[i] = new OverriderUsageInfo(p, method);
|
||||
@@ -924,7 +924,7 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(validReferences, (o1, o2) -> o1.getElement().getTextOffset() - o2.getElement().getTextOffset());
|
||||
Collections.sort(validReferences, Comparator.comparingInt(o -> o.getElement().getTextOffset()));
|
||||
|
||||
return validReferences.toArray(new PsiReference[validReferences.size()]);
|
||||
}
|
||||
@@ -1040,8 +1040,7 @@ public class TypeMigrationLabeler {
|
||||
}
|
||||
|
||||
private void iterate() {
|
||||
final LinkedList<Pair<TypeMigrationUsageInfo, PsiType>> roots =
|
||||
(LinkedList<Pair<TypeMigrationUsageInfo, PsiType>>)myMigrationRoots.clone();
|
||||
final List<Pair<TypeMigrationUsageInfo, PsiType>> roots = new ArrayList<>(myMigrationRoots);
|
||||
|
||||
myMigrationRoots = new LinkedList<>();
|
||||
|
||||
|
||||
+2
-3
@@ -45,11 +45,10 @@ import java.util.*;
|
||||
import static com.intellij.util.ObjectUtils.assertNotNull;
|
||||
|
||||
public class TypeMigrationProcessor extends BaseRefactoringProcessor {
|
||||
private final static Logger LOG = Logger.getInstance(TypeMigrationProcessor.class);
|
||||
private final static int MAX_ROOT_IN_PREVIEW_PRESENTATION = 3;
|
||||
|
||||
private PsiElement[] myRoot;
|
||||
private Function<PsiElement, PsiType> myRootTypes;
|
||||
private final Function<PsiElement, PsiType> myRootTypes;
|
||||
private final TypeMigrationRules myRules;
|
||||
private TypeMigrationLabeler myLabeler;
|
||||
|
||||
@@ -74,7 +73,7 @@ public class TypeMigrationProcessor extends BaseRefactoringProcessor {
|
||||
final PsiElement root,
|
||||
final PsiType migrationType,
|
||||
final boolean optimizeImports) {
|
||||
runHighlightingTypeMigration(project, editor, rules, new PsiElement[] {root}, Functions.<PsiElement, PsiType>constant(migrationType), optimizeImports);
|
||||
runHighlightingTypeMigration(project, editor, rules, new PsiElement[] {root}, Functions.constant(migrationType), optimizeImports);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -202,7 +202,7 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
|
||||
final PsiType valueType = myTypeEvaluator.evaluateType(value);
|
||||
if (returnType != null && valueType != null) {
|
||||
if (!myLabeler.addMigrationRoot(method, valueType, myStatement, TypeConversionUtil.isAssignable(returnType, valueType) && !isGetter(value, method), true, true)
|
||||
&& TypeMigrationLabeler.typeContainsTypeParameters(returnType, Collections.<PsiTypeParameter>emptySet())) {
|
||||
&& TypeMigrationLabeler.typeContainsTypeParameters(returnType, Collections.emptySet())) {
|
||||
value.accept(this);
|
||||
}
|
||||
}
|
||||
@@ -638,7 +638,7 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
|
||||
PsiType type = myTypeEvaluator.evaluateType(expr);
|
||||
type = type instanceof PsiEllipsisType ? ((PsiEllipsisType)type).toArrayType() : type;
|
||||
myType = GenericsUtil.getVariableTypeByExpressionType(type);
|
||||
myChanged = (myOriginType == null || myType == null) ? false : !myType.equals(myOriginType);
|
||||
myChanged = !(myOriginType == null || myType == null) && !myType.equals(myOriginType);
|
||||
}
|
||||
|
||||
public TypeView(PsiVariable var, PsiSubstitutor varSubstitutor, PsiSubstitutor evalSubstitutor) {
|
||||
@@ -649,7 +649,7 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
|
||||
if (evalSubstitutor != null) realMap.putAll(evalSubstitutor.getSubstitutionMap());
|
||||
|
||||
myType = PsiSubstitutorImpl.createSubstitutor(realMap).substitute(myTypeEvaluator.getType(var));
|
||||
myChanged = (myOriginType == null || myType == null) ? false : !myType.equals(myOriginType);
|
||||
myChanged = !(myOriginType == null || myType == null) && !myType.equals(myOriginType);
|
||||
}
|
||||
|
||||
public PsiType getType() {
|
||||
|
||||
-6
@@ -34,12 +34,6 @@ public class ChangeTypeSignatureAction extends BaseRefactoringAction {
|
||||
}
|
||||
|
||||
public boolean isEnabledOnElements(@NotNull PsiElement[] elements) {
|
||||
Project currProject = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext());
|
||||
|
||||
if (currProject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elements.length > 1) return false;
|
||||
|
||||
for (PsiElement element : elements) {
|
||||
|
||||
+2
-2
@@ -65,7 +65,7 @@ public class RootTypeConversionRule extends TypeConversionRule {
|
||||
if (Comparing.equal(functionalInterfaceType, to) && method.isEquivalentTo(LambdaUtil.getFunctionalInterfaceMethod(from))) {
|
||||
return new TypeConversionDescriptorBase() {
|
||||
@Override
|
||||
public PsiExpression replace(PsiExpression expression, TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)expression;
|
||||
final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression();
|
||||
if (qualifierExpression != null) {
|
||||
@@ -147,7 +147,7 @@ public class RootTypeConversionRule extends TypeConversionRule {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression replace(PsiExpression expression, TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
|
||||
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
|
||||
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject());
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class FailedConversionsDialog extends DialogWrapper {
|
||||
panel.add(new JLabel(RefactoringBundle.message("the.following.problems.were.found")), BorderLayout.NORTH);
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
@NonNls StringBuffer buf = new StringBuffer();
|
||||
@NonNls StringBuilder buf = new StringBuilder();
|
||||
for (String description : myConflictDescriptions) {
|
||||
buf.append(description);
|
||||
buf.append("<br><br>");
|
||||
|
||||
@@ -121,8 +121,4 @@ public class MigrationNode extends AbstractTreeNode<TypeMigrationUsageInfo> impl
|
||||
public MigrationNode getDuplicate() {
|
||||
return myDuplicatedNode;
|
||||
}
|
||||
|
||||
public boolean hasDuplicate() {
|
||||
return myDuplicatedNode != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,15 +187,14 @@ public class MigrationPanel extends JPanel implements Disposable {
|
||||
if (userObject instanceof MigrationRootNode) {
|
||||
ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
|
||||
final HashSet<VirtualFile> files = new HashSet<>();
|
||||
final TypeMigrationUsageInfo[] usages = ApplicationManager.getApplication().runReadAction(new Computable<TypeMigrationUsageInfo[]>() {
|
||||
@Override
|
||||
public TypeMigrationUsageInfo[] compute() {
|
||||
final TypeMigrationUsageInfo[] usages = ApplicationManager.getApplication().runReadAction(
|
||||
(Computable<TypeMigrationUsageInfo[]>)() -> {
|
||||
final Collection<? extends AbstractTreeNode> children = ((MigrationRootNode)userObject).getChildren();
|
||||
for (AbstractTreeNode child : children) {
|
||||
expandTree((MigrationNode)child);
|
||||
}
|
||||
final TypeMigrationUsageInfo[] usages = myLabeler.getMigratedUsages();
|
||||
for (TypeMigrationUsageInfo usage : usages) {
|
||||
final TypeMigrationUsageInfo[] usages1 = myLabeler.getMigratedUsages();
|
||||
for (TypeMigrationUsageInfo usage : usages1) {
|
||||
if (!usage.isExcluded()) {
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element != null) {
|
||||
@@ -203,9 +202,8 @@ public class MigrationPanel extends JPanel implements Disposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return usages;
|
||||
}
|
||||
});
|
||||
return usages1;
|
||||
});
|
||||
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(() -> {
|
||||
@@ -306,7 +304,7 @@ public class MigrationPanel extends JPanel implements Disposable {
|
||||
}
|
||||
|
||||
public Object getData(@NonNls final String dataId) {
|
||||
if (DataConstants.PSI_ELEMENT.equals(dataId)) {
|
||||
if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
|
||||
final DefaultMutableTreeNode[] selectedNodes = getSelectedNodes(DefaultMutableTreeNode.class, null);
|
||||
return selectedNodes.length == 1 && selectedNodes[0].getUserObject() instanceof MigrationNode
|
||||
? ((MigrationNode)selectedNodes[0].getUserObject()).getInfo().getElement() : null;
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.*;
|
||||
public class MigrationRootNode extends AbstractTreeNode<TypeMigrationLabeler> implements DuplicateNodeRenderer.DuplicatableNode {
|
||||
private final TypeMigrationLabeler myLabeler;
|
||||
private List<MigrationNode> myCachedChildren;
|
||||
private final PsiElement myRoots[];
|
||||
private final PsiElement[] myRoots;
|
||||
private final boolean myPreviewUsages;
|
||||
|
||||
protected MigrationRootNode(Project project,
|
||||
|
||||
+2
-2
@@ -22,10 +22,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author anna
|
||||
* Date: 27-Mar-2008
|
||||
*/
|
||||
public class OverridenUsageInfo extends TypeMigrationUsageInfo {
|
||||
public class OverriddenUsageInfo extends TypeMigrationUsageInfo {
|
||||
private volatile String myMigrateMethodName;
|
||||
|
||||
public OverridenUsageInfo(@NotNull PsiElement element) {
|
||||
public OverriddenUsageInfo(@NotNull PsiElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user