Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2016-10-14 19:08:58 +02:00
146 changed files with 2933 additions and 1076 deletions
@@ -35,7 +35,7 @@ public class IntroduceFieldPostfixTemplate extends PostfixTemplateWithExpression
protected void expandForChooseExpression(@NotNull PsiElement expression, @NotNull Editor editor) {
IntroduceFieldHandler handler =
ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler(expression) : new IntroduceFieldHandler();
handler.invoke(expression.getProject(), new PsiElement[]{expression}, null);
handler.invoke(expression.getProject(), expression, editor);
}
@NotNull
@@ -86,6 +86,11 @@ public class IntroduceVariablePostfixTemplate extends PostfixTemplateWithExpress
}
};
}
@Override
protected boolean isInplaceAvailableInTestMode() {
return true;
}
};
}
}
@@ -25,11 +25,15 @@ import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor;
import com.intellij.refactoring.ui.ConflictsDialog;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.refactoring.util.InlineUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -107,6 +111,19 @@ public class SameParameterValueInspection extends SameParameterValueInspectionBa
}
public static void inlineSameParameterValue(final PsiMethod method, final PsiParameter parameter, final PsiExpression defToInline) {
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
JavaSafeDeleteProcessor.collectMethodConflicts(conflicts, method, parameter);
if (!conflicts.isEmpty()) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
if (!BaseRefactoringProcessor.ConflictsInTestsException.isTestIgnore()) {
throw new BaseRefactoringProcessor.ConflictsInTestsException(conflicts.values());
}
}
else if (!new ConflictsDialog(parameter.getProject(), conflicts).showAndGet()) {
return;
}
}
final Collection<PsiReference> refsToInline = ReferencesSearch.search(parameter).findAll();
ApplicationManager.getApplication().runWriteAction(() -> {
@@ -15,7 +15,6 @@
*/
package com.intellij.psi.stubsHierarchy.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
@@ -25,7 +24,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
import com.intellij.psi.stubs.StubBase;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubTree;
import com.intellij.util.ObjectUtils;
@@ -108,9 +106,7 @@ class AnchorRepository {
private static PsiElement restoreFromStubIndex(PsiFileWithStubSupport fileImpl, int index) {
StubTree tree = fileImpl.getStubTree();
boolean foreign = tree == null;
if (foreign) {
if (tree == null) {
if (fileImpl instanceof PsiFileImpl) {
tree = ((PsiFileImpl)fileImpl).calcStubTree();
}
@@ -123,16 +119,8 @@ class AnchorRepository {
if (index >= list.size()) {
return null;
}
StubElement stub = list.get(index);
if (foreign) {
final PsiElement cachedPsi = ((StubBase)stub).getCachedPsi();
if (cachedPsi != null) return cachedPsi;
final ASTNode ast = fileImpl.findTreeForStub(tree, stub);
return ast != null ? ast.getPsi() : null;
}
return stub.getPsi();
return ((StubElement)list.get(index)).getPsi();
}
}
@@ -27,6 +27,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.extractMethod.ExtractMethodHandler;
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
/**
@@ -64,11 +65,15 @@ public abstract class IntroduceHandlerBase implements RefactoringActionHandler,
else {
editor = null;
}
if (tempExpr instanceof PsiExpression) {
invokeImpl(project, (PsiExpression)tempExpr, editor);
invoke(project, tempExpr, editor);
}
public void invoke(@NotNull Project project, PsiElement element, @Nullable Editor editor) {
if (element instanceof PsiExpression) {
invokeImpl(project, (PsiExpression)element, editor);
}
else if(tempExpr instanceof PsiLocalVariable) {
invokeImpl(project, (PsiLocalVariable)tempExpr, editor);
else if(element instanceof PsiLocalVariable) {
invokeImpl(project, (PsiLocalVariable)element, editor);
}
else {
LOG.error("elements[0] should be PsiExpression or PsiLocalVariable");
@@ -16,10 +16,10 @@
package com.intellij.refactoring;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
@@ -61,7 +61,7 @@ public class OptimizeImportsRefactoringHelper implements RefactoringHelper<Set<P
});
final Set<SmartPsiElementPointer<PsiImportStatementBase>> redundants = new HashSet<>();
final Runnable findRedundantImports = () -> DumbService.getInstance(project).runReadActionInSmartMode(() -> {
final Runnable findRedundantImports = () -> ReadAction.run(() -> {
final JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(project);
final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
@@ -30,10 +30,8 @@ import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase;
import com.intellij.refactoring.changeSignature.JavaChangeInfo;
import com.intellij.refactoring.changeSignature.JavaChangeInfoImpl;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.refactoring.util.InlineUtil;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor;
import com.intellij.refactoring.util.*;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.usageView.UsageViewUtil;
@@ -204,6 +202,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor
@Override
protected boolean preprocessUsages(@NotNull Ref<UsageInfo[]> refUsages) {
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
JavaSafeDeleteProcessor.collectMethodConflicts(conflicts, myMethod, myParameter);
final UsageInfo[] usages = refUsages.get();
final InaccessibleExpressionsDetector detector = new InaccessibleExpressionsDetector(conflicts);
myInitializer.accept(detector);
@@ -84,7 +84,7 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop
protected PsiField createFieldToStartTemplateOn(final String[] names,
final PsiType defaultType) {
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiField>() {
final PsiField field = ApplicationManager.getApplication().runWriteAction(new Computable<PsiField>() {
@Override
public PsiField compute() {
PsiField field = elementFactory.createField(chooseName(names, myParentClass.getLanguage()), defaultType);
@@ -97,10 +97,12 @@ public class InplaceIntroduceFieldPopup extends AbstractInplaceIntroduceFieldPop
if (visibility != null) {
PsiUtil.setModifierProperty(field, visibility, true);
}
myFieldRangeStart = myEditor.getDocument().createRangeMarker(field.getTextRange());
myFieldRangeStart = myEditor.getDocument().createRangeMarker(field.getTextRange());
return field;
}
});
PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myEditor.getDocument());
return field;
}
@Override
@@ -36,6 +36,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.scope.processor.VariablesProcessor;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -55,6 +56,7 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -396,6 +398,15 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer
final PsiVariable variable = ApplicationManager.getApplication().runWriteAction(
IntroduceVariableBase.introduce(myProject, myExpr, myEditor, myChosenAnchor.getElement(), getOccurrences(), mySettings));
PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myEditor.getDocument());
if (isReplaceAllOccurrences()) {
List<RangeMarker> occurrences = new ArrayList<>();
ReferencesSearch.search(variable).forEach(reference -> {
occurrences.add(createMarker(reference.getElement()));
});
setOccurrenceMarkers(occurrences);
}
final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(variable, PsiDeclarationStatement.class);
myPointer = declarationStatement != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(declarationStatement) : null;
myEditor.putUserData(ReassignVariableUtil.DECLARATION_KEY, myPointer);
@@ -411,6 +422,7 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer
finally {
myDeleteSelf = true;
}
PsiDocumentManager.getInstance(myProject).doPostponedOperationsAndUnblockDocument(myEditor.getDocument());
initOccurrencesMarkers();
return variable;
}
@@ -18,6 +18,7 @@ package com.intellij.refactoring.move.moveClassesOrPackages;
import com.intellij.CommonBundle;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.module.Module;
@@ -34,6 +35,7 @@ import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.JavaRefactoringSettings;
import com.intellij.refactoring.MoveDestination;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.move.MoveCallback;
import com.intellij.refactoring.move.MoveHandlerDelegate;
@@ -218,16 +220,28 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate {
PsiPackage aPackage,
boolean searchInComments,
boolean searchForTextOccurences) {
final MoveDestination destination = createDestination(aPackage, targetDirectory);
try {
for (PsiDirectory dir: directories) {
MoveFilesOrDirectoriesUtil.checkIfMoveIntoSelf(dir, targetDirectory);
MoveFilesOrDirectoriesUtil.checkIfMoveIntoSelf(dir, WriteAction.compute(() -> destination.getTargetDirectory(dir)));
}
}
catch (IncorrectOperationException e) {
Messages.showErrorDialog(project, e.getMessage(), RefactoringBundle.message("cannot.move"));
return null;
}
return new MoveDirectoryWithClassesProcessor(project, directories, targetDirectory, searchInComments, searchForTextOccurences, true, callback);
return new MoveDirectoryWithClassesProcessor(project, directories, null, searchInComments, searchForTextOccurences, true, callback) {
@Override
public TargetDirectoryWrapper getTargetDirectory(PsiDirectory dir) {
final PsiDirectory targetDirectory = destination.getTargetDirectory(dir);
return new TargetDirectoryWrapper(targetDirectory);
}
@Override
protected String getTargetName() {
return targetDirectory.getName();
}
};
}
};
dlg.show();
@@ -218,16 +218,7 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends MoveDialogBase {
PsiPackage aPackage,
boolean searchInComments,
boolean searchForTextOccurences) {
final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile());
if (sourceRoot == null) {
Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"),
RefactoringBundle.message("cannot.move"));
return null;
}
final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project);
final MoveDestination destination = myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible()
? factory.createSourceFolderPreservingMoveDestination(aPackage.getQualifiedName())
: factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot);
final MoveDestination destination = createDestination(aPackage, directory);
MoveClassesOrPackagesProcessor processor = createMoveClassesOrPackagesProcessor(myDirectory.getProject(), myElementsToMove, destination,
searchInComments, searchForTextOccurences, myMoveCallback);
@@ -239,6 +230,21 @@ public class MoveClassesOrPackagesToNewDirectoryDialog extends MoveDialogBase {
return null;
}
protected MoveDestination createDestination(PsiPackage aPackage, PsiDirectory directory) {
final Project project = aPackage.getProject();
final VirtualFile sourceRoot = ProjectRootManager.getInstance(project).getFileIndex().getSourceRootForFile(directory.getVirtualFile());
if (sourceRoot == null) {
Messages.showErrorDialog(project, RefactoringBundle.message("destination.directory.does.not.correspond.to.any.package"),
RefactoringBundle.message("cannot.move"));
return null;
}
final JavaRefactoringFactory factory = JavaRefactoringFactory.getInstance(project);
return myPreserveSourceRoot.isSelected() && myPreserveSourceRoot.isVisible()
? factory.createSourceFolderPreservingMoveDestination(aPackage.getQualifiedName())
: factory.createSourceRootMoveDestination(aPackage.getQualifiedName(), sourceRoot);
}
@Override
protected String getMovePropertySuffix() {
return "ClassWithTarget";
@@ -39,7 +39,6 @@ import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NonNls;
@@ -125,7 +124,7 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
qualifyOuterMemberReferences(outerHides);
qualifyStaticImportReferences(staticImportHides);
if (method.findDeepestSuperMethods().length == 0) {
if (!method.isConstructor() && method.findDeepestSuperMethods().length == 0) {
PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, CommonClassNames.JAVA_LANG_OVERRIDE);
if (annotation != null && annotation.isPhysical()) {
annotation.delete();
@@ -296,15 +296,9 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
final PsiElement scope = ((PsiParameter)element).getDeclarationScope();
if (scope instanceof PsiMethod) {
final PsiMethod method = (PsiMethod)scope;
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null) {
final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter)element);
final PsiMethod methodCopy = (PsiMethod)method.copy();
methodCopy.getParameterList().getParameters()[parameterIndex].delete();
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
ConflictsUtil.checkMethodConflicts(containingClass, method, methodCopy, conflicts);
return (Collection<String>)conflicts.values();
}
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
collectMethodConflicts(conflicts, method, (PsiParameter)element);
return (Collection<String>)conflicts.values();
}
}
return null;
@@ -963,7 +957,17 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
return false;
}
public static void collectMethodConflicts(MultiMap<PsiElement, String> conflicts, PsiMethod method, PsiParameter parameter) {
final PsiClass containingClass = method.getContainingClass();
if (containingClass != null) {
final int parameterIndex = method.getParameterList().getParameterIndex(parameter);
final PsiMethod methodCopy = (PsiMethod)method.copy();
methodCopy.getParameterList().getParameters()[parameterIndex].delete();
ConflictsUtil.checkMethodConflicts(containingClass, method, methodCopy, conflicts);
}
}
private static class SafeDeleteFunctionalExpressionUsageInfo extends SafeDeleteReferenceUsageInfo {
public SafeDeleteFunctionalExpressionUsageInfo(@NotNull PsiElement element, PsiElement referencedElement) {
super(element, referencedElement, false);