mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
IDEA-118279 create constructor params: apply cleanup
This commit is contained in:
@@ -25,6 +25,7 @@ import com.intellij.codeInsight.generation.PsiMethodMember;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.AssignFieldFromParameterAction;
|
||||
import com.intellij.codeInsight.intention.impl.FieldFromParameterUtils;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionContextBase;
|
||||
import com.intellij.ide.util.MemberChooser;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -123,6 +124,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
}
|
||||
}
|
||||
});
|
||||
final List<PsiElement> cleanupElements = new ArrayList<PsiElement>();
|
||||
final ArrayList<PsiMethod> constrs = filterConstructorsIfFieldAlreadyAssigned(constructors, getField());
|
||||
if (constrs.size() > 1) {
|
||||
final PsiMethodMember[] members = new PsiMethodMember[constrs.size()];
|
||||
@@ -142,7 +144,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
}
|
||||
|
||||
for (PsiMethodMember member : elements) {
|
||||
if (!addParameterToConstructor(project, file, editor, member.getElement(), new PsiField[] {getField()})) break;
|
||||
if (!addParameterToConstructor(project, file, editor, member.getElement(), new PsiField[] {getField()}, cleanupElements)) break;
|
||||
}
|
||||
|
||||
} else if (!constrs.isEmpty()) {
|
||||
@@ -177,12 +179,13 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
|
||||
addParameterToConstructor(project, file, editor, constructor, constrs.size() == constructors.length
|
||||
? fields.toArray(new PsiField[fields.size()])
|
||||
: new PsiField[]{getField()});
|
||||
: new PsiField[]{getField()}, cleanupElements);
|
||||
}
|
||||
finally {
|
||||
fieldsToFix.clear();
|
||||
}
|
||||
}
|
||||
GlobalInspectionContextBase.cleanupElements(project, null, cleanupElements.toArray(new PsiElement[cleanupElements.size()]));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -231,7 +234,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
final PsiFile file,
|
||||
final Editor editor,
|
||||
final PsiMethod constructor,
|
||||
final PsiField[] fields) throws IncorrectOperationException {
|
||||
final PsiField[] fields, final List<PsiElement> cleanupElements) throws IncorrectOperationException {
|
||||
final PsiParameterList parameterList = constructor.getParameterList();
|
||||
final PsiParameter[] parameters = parameterList.getParameters();
|
||||
ParameterInfoImpl[] newParamInfos = new ParameterInfoImpl[parameters.length + fields.length];
|
||||
@@ -267,7 +270,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return doCreate(project, editor, parameters, constructorPointer, resultParams, usedFields);
|
||||
return doCreate(project, editor, parameters, constructorPointer, resultParams, usedFields, cleanupElements);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -309,7 +312,7 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
}
|
||||
|
||||
private static boolean doCreate(Project project, Editor editor, PsiParameter[] parameters, SmartPsiElementPointer constructorPointer,
|
||||
ParameterInfoImpl[] parameterInfos, HashMap<PsiField, String> fields) {
|
||||
ParameterInfoImpl[] parameterInfos, HashMap<PsiField, String> fields, List<PsiElement> cleanupElements) {
|
||||
PsiMethod constructor = (PsiMethod)constructorPointer.getElement();
|
||||
assert constructor != null;
|
||||
PsiParameter[] newParameters = constructor.getParameterList().getParameters();
|
||||
@@ -324,7 +327,11 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
|
||||
continue;
|
||||
}
|
||||
notNull(project, field, parameter);
|
||||
AssignFieldFromParameterAction.addFieldAssignmentStatement(project, field, parameter, editor);
|
||||
cleanupElements.add(parameter);
|
||||
final PsiElement assignmentStatement = AssignFieldFromParameterAction.addFieldAssignmentStatement(project, field, parameter, editor);
|
||||
if (assignmentStatement != null) {
|
||||
cleanupElements.add(assignmentStatement);
|
||||
}
|
||||
created = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +136,7 @@ public abstract class GenerateMembersHandlerBase implements CodeInsightActionHan
|
||||
}
|
||||
}
|
||||
|
||||
AnalysisScope scope = new AnalysisScope(new LocalSearchScope(elements.toArray(new PsiElement[elements.size()])), project);
|
||||
GlobalInspectionContextBase.codeCleanup(project, scope, null);
|
||||
GlobalInspectionContextBase.cleanupElements(project, null, elements.toArray(new PsiElement[elements.size()]));
|
||||
}
|
||||
|
||||
final ArrayList<TemplateGenerationInfo> templates = new ArrayList<TemplateGenerationInfo>();
|
||||
|
||||
@@ -99,19 +99,19 @@ public class AssignFieldFromParameterAction extends BaseIntentionAction {
|
||||
return field;
|
||||
}
|
||||
|
||||
public static void addFieldAssignmentStatement(@NotNull Project project,
|
||||
@NotNull PsiField field,
|
||||
@NotNull PsiParameter parameter,
|
||||
@NotNull Editor editor) throws IncorrectOperationException {
|
||||
public static PsiElement addFieldAssignmentStatement(@NotNull Project project,
|
||||
@NotNull PsiField field,
|
||||
@NotNull PsiParameter parameter,
|
||||
@NotNull Editor editor) throws IncorrectOperationException {
|
||||
final PsiMethod method = (PsiMethod)parameter.getDeclarationScope();
|
||||
final PsiCodeBlock methodBody = method.getBody();
|
||||
if (methodBody == null) return;
|
||||
if (methodBody == null) return null;
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
final String fieldName = field.getName();
|
||||
final String parameterName = parameter.getName();
|
||||
final boolean isMethodStatic = method.hasModifierProperty(PsiModifier.STATIC);
|
||||
final PsiClass targetClass = method.getContainingClass();
|
||||
if (targetClass == null) return;
|
||||
if (targetClass == null) return null;
|
||||
|
||||
String stmtText = fieldName + " = " + parameterName + ";";
|
||||
if (Comparing.strEqual(fieldName, parameterName) || JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(fieldName, methodBody) != field) {
|
||||
@@ -131,5 +131,6 @@ public class AssignFieldFromParameterAction extends BaseIntentionAction {
|
||||
}
|
||||
editor.getCaretModel().moveToOffset(inserted.getTextRange().getEndOffset());
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
|
||||
return inserted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ class A {
|
||||
private final int _field;
|
||||
private final int field;
|
||||
A(int field, int field1) {
|
||||
_field = field;
|
||||
this._field = field;
|
||||
this.field = field1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionTool;
|
||||
import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
|
||||
import com.siyeh.ig.style.MissortedModifiersInspection;
|
||||
import com.siyeh.ig.style.UnqualifiedFieldAccessInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -11,7 +13,7 @@ public class CreateConstructorParameterFromFieldTest extends LightQuickFixParame
|
||||
@NotNull
|
||||
@Override
|
||||
protected LocalInspectionTool[] configureLocalInspectionTools() {
|
||||
return new LocalInspectionTool[]{ new UnusedSymbolLocalInspection()};
|
||||
return new LocalInspectionTool[]{ new UnusedSymbolLocalInspection(), new MissortedModifiersInspection(), new UnqualifiedFieldAccessInspection()};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class CleanupIntention implements IntentionAction, LowPriorityAc
|
||||
final AnalysisScope scope = getScope(project, file);
|
||||
if (scope != null) {
|
||||
final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
globalContext.codeCleanup(project, scope, profile, getText(), null);
|
||||
globalContext.codeCleanup(project, scope, profile, getText(), null, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.scope.packageSet.NamedScope;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -409,13 +410,19 @@ public class GlobalInspectionContextBase extends UserDataHolderBase implements G
|
||||
public void codeCleanup(final Project project,
|
||||
final AnalysisScope scope,
|
||||
final InspectionProfile profile,
|
||||
final String commandName, Runnable postRunnable) {}
|
||||
final String commandName, Runnable postRunnable,
|
||||
final boolean modal) {}
|
||||
|
||||
public static void codeCleanup(Project project, AnalysisScope scope, Runnable runnable) {
|
||||
GlobalInspectionContextBase globalContext =
|
||||
(GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
|
||||
GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
|
||||
final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
globalContext.codeCleanup(project, scope, profile, null, runnable);
|
||||
globalContext.codeCleanup(project, scope, profile, null, runnable, false);
|
||||
}
|
||||
|
||||
public static void cleanupElements(Project project, Runnable runnable, PsiElement... scope) {
|
||||
GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)InspectionManager.getInstance(project).createNewGlobalContext(false);
|
||||
final InspectionProfile profile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
globalContext.codeCleanup(project, new AnalysisScope(new LocalSearchScope(scope), project), profile, null, runnable, true);
|
||||
}
|
||||
|
||||
public void close(boolean noSuspisiousCodeFound) {
|
||||
|
||||
@@ -37,7 +37,7 @@ public class CodeCleanupAction extends CodeInspectionAction {
|
||||
final InspectionProfile profile = myExternalProfile != null ? myExternalProfile : InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
|
||||
final InspectionManager managerEx = InspectionManager.getInstance(project);
|
||||
final GlobalInspectionContextBase globalContext = (GlobalInspectionContextBase)managerEx.createNewGlobalContext(false);
|
||||
globalContext.codeCleanup(project, scope, profile, getTemplatePresentation().getText(), null);
|
||||
globalContext.codeCleanup(project, scope, profile, getTemplatePresentation().getText(), null, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,6 +48,7 @@ import com.intellij.openapi.project.ProjectUtilCore;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -55,6 +56,7 @@ import com.intellij.openapi.wm.ToolWindowId;
|
||||
import com.intellij.openapi.wm.ToolWindowManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.ui.content.*;
|
||||
import com.intellij.util.Processor;
|
||||
@@ -612,75 +614,106 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
|
||||
final AnalysisScope scope,
|
||||
final InspectionProfile profile,
|
||||
final String commandName,
|
||||
final Runnable postRunnable) {
|
||||
final Runnable postRunnable,
|
||||
final boolean modal) {
|
||||
Task task;
|
||||
if (modal) {
|
||||
task = new Task.Modal(project, "Inspect code...", true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
cleanup(scope, profile, project, postRunnable, commandName);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
task = new Task.Backgroundable(project, "Inspect code...", true) {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
cleanup(scope, profile, project, postRunnable, commandName);
|
||||
}
|
||||
};
|
||||
}
|
||||
ProgressManager.getInstance().run(task);
|
||||
}
|
||||
|
||||
private void cleanup(final AnalysisScope scope,
|
||||
final InspectionProfile profile,
|
||||
final Project project,
|
||||
final Runnable postRunnable,
|
||||
final String commandName) {
|
||||
final List<LocalInspectionToolWrapper> lTools = new ArrayList<LocalInspectionToolWrapper>();
|
||||
|
||||
final LinkedHashMap<PsiFile, List<HighlightInfo>> results = new LinkedHashMap<PsiFile, List<HighlightInfo>>();
|
||||
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Inspect code...", true) {
|
||||
|
||||
final SearchScope searchScope = scope.toSearchScope();
|
||||
scope.accept(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
scope.accept(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void visitFile(PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null || virtualFile.getFileType().isBinary()) return;
|
||||
for (final Tools tools : profile.getAllEnabledInspectionTools(project)) {
|
||||
if (tools.getTool().getTool() instanceof CleanupLocalInspectionTool) {
|
||||
final InspectionToolWrapper tool = tools.getEnabledTool(file);
|
||||
if (tool instanceof LocalInspectionToolWrapper) {
|
||||
lTools.add((LocalInspectionToolWrapper)tool);
|
||||
tool.initialize(GlobalInspectionContextImpl.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lTools.isEmpty()) {
|
||||
final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(project).getDocument(file), 0,
|
||||
file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true,
|
||||
HighlightInfoProcessor.getEmpty());
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
pass.doInspectInBatch(GlobalInspectionContextImpl.this, (InspectionManagerEx)InspectionManager.getInstance(project), lTools);
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
results.put(file, pass.getInfos());
|
||||
public void visitFile(PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null || virtualFile.getFileType().isBinary()) return;
|
||||
for (final Tools tools : profile.getAllEnabledInspectionTools(project)) {
|
||||
if (tools.getTool().getTool() instanceof CleanupLocalInspectionTool) {
|
||||
final InspectionToolWrapper tool = tools.getEnabledTool(file);
|
||||
if (tool instanceof LocalInspectionToolWrapper) {
|
||||
lTools.add((LocalInspectionToolWrapper)tool);
|
||||
tool.initialize(GlobalInspectionContextImpl.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!FileModificationService.getInstance().preparePsiElementsForWrite(results.keySet())) return;
|
||||
|
||||
final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, "Code Cleanup", true);
|
||||
progressTask.setMinIterationTime(200);
|
||||
progressTask.setTask(new SequentialCleanupTask(project, results, progressTask));
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(progressTask);
|
||||
}
|
||||
});
|
||||
if (postRunnable != null) {
|
||||
ApplicationManager.getApplication().invokeLater(postRunnable);
|
||||
}
|
||||
if (!lTools.isEmpty()) {
|
||||
final LocalInspectionsPass pass = new LocalInspectionsPass(file, PsiDocumentManager.getInstance(project).getDocument(file), 0,
|
||||
file.getTextLength(), LocalInspectionsPass.EMPTY_PRIORITY_RANGE, true,
|
||||
HighlightInfoProcessor.getEmpty());
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
pass.doInspectInBatch(GlobalInspectionContextImpl.this, (InspectionManagerEx)InspectionManager.getInstance(project), lTools);
|
||||
}
|
||||
};
|
||||
ApplicationManager.getApplication().runReadAction(runnable);
|
||||
final List<HighlightInfo> infos = pass.getInfos();
|
||||
if (searchScope instanceof LocalSearchScope) {
|
||||
for (Iterator<HighlightInfo> iterator = infos.iterator(); iterator.hasNext(); ) {
|
||||
final HighlightInfo info = iterator.next();
|
||||
final TextRange infoRange = new TextRange(info.getStartOffset(), info.getEndOffset());
|
||||
if (!((LocalSearchScope)searchScope).containsRange(file, infoRange)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}, commandName, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
ApplicationManager.getApplication().invokeLater(runnable);
|
||||
results.put(file, infos);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!FileModificationService.getInstance().preparePsiElementsForWrite(results.keySet())) return;
|
||||
|
||||
final SequentialModalProgressTask progressTask = new SequentialModalProgressTask(project, "Code Cleanup", true);
|
||||
progressTask.setMinIterationTime(200);
|
||||
progressTask.setTask(new SequentialCleanupTask(project, results, progressTask));
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ProgressManager.getInstance().run(progressTask);
|
||||
}
|
||||
});
|
||||
if (postRunnable != null) {
|
||||
ApplicationManager.getApplication().invokeLater(postRunnable);
|
||||
}
|
||||
}
|
||||
}, commandName, null);
|
||||
}
|
||||
};
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
ApplicationManager.getApplication().invokeLater(runnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user