use of com.intellij.util.containers.MultiMap in project intellij-community by JetBrains.
the class PsiSearchHelperImpl method collectFiles.
private void collectFiles(@NotNull MultiMap<Set<IdIndexEntry>, RequestWithProcessor> singles, @NotNull ProgressIndicator progress, @NotNull final MultiMap<VirtualFile, RequestWithProcessor> intersectionResult, @NotNull final MultiMap<VirtualFile, RequestWithProcessor> restResult) {
for (Map.Entry<Set<IdIndexEntry>, Collection<RequestWithProcessor>> entry : singles.entrySet()) {
final Set<IdIndexEntry> keys = entry.getKey();
if (keys.isEmpty()) {
continue;
}
final Collection<RequestWithProcessor> processors = entry.getValue();
final GlobalSearchScope commonScope = uniteScopes(processors);
final Set<VirtualFile> intersectionWithContainerNameFiles = intersectionWithContainerNameFiles(commonScope, processors, keys);
List<VirtualFile> result = new ArrayList<>();
Processor<VirtualFile> processor = Processors.cancelableCollectProcessor(result);
processFilesContainingAllKeys(myManager.getProject(), commonScope, null, keys, processor);
for (final VirtualFile file : result) {
progress.checkCanceled();
for (final IdIndexEntry indexEntry : keys) {
DumbService.getInstance(myManager.getProject()).runReadActionInSmartMode(() -> FileBasedIndex.getInstance().processValues(IdIndex.NAME, indexEntry, file, (file1, value) -> {
int mask = value.intValue();
for (RequestWithProcessor single : processors) {
final PsiSearchRequest request = single.request;
if ((mask & request.searchContext) != 0 && request.searchScope.contains(file1)) {
MultiMap<VirtualFile, RequestWithProcessor> result1 = intersectionWithContainerNameFiles == null || !intersectionWithContainerNameFiles.contains(file1) ? restResult : intersectionResult;
result1.putValue(file1, single);
}
}
return true;
}, commonScope));
}
}
}
}
use of com.intellij.util.containers.MultiMap in project intellij-community by JetBrains.
the class IntroduceVariableBase method invokeImpl.
protected boolean invokeImpl(final Project project, final PsiExpression expr, final Editor editor) {
if (expr != null) {
final String errorMessage = getErrorMessage(expr);
if (errorMessage != null) {
showErrorMessage(project, editor, RefactoringBundle.getCannotRefactorMessage(errorMessage));
return false;
}
}
if (expr != null && expr.getParent() instanceof PsiExpressionStatement) {
FeatureUsageTracker.getInstance().triggerFeatureUsed("refactoring.introduceVariable.incompleteStatement");
}
if (LOG.isDebugEnabled()) {
LOG.debug("expression:" + expr);
}
if (expr == null || !expr.isPhysical()) {
if (ReassignVariableUtil.reassign(editor))
return false;
if (expr == null) {
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("selected.block.should.represent.an.expression"));
showErrorMessage(project, editor, message);
return false;
}
}
final PsiType originalType = RefactoringUtil.getTypeByExpressionWithExpectedType(expr);
if (originalType == null || LambdaUtil.notInferredType(originalType)) {
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("unknown.expression.type"));
showErrorMessage(project, editor, message);
return false;
}
if (PsiType.VOID.equals(originalType)) {
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("selected.expression.has.void.type"));
showErrorMessage(project, editor, message);
return false;
}
final PsiElement physicalElement = expr.getUserData(ElementToWorkOn.PARENT);
final PsiElement anchorStatement = RefactoringUtil.getParentStatement(physicalElement != null ? physicalElement : expr, false);
if (anchorStatement == null) {
return parentStatementNotFound(project, editor);
}
if (checkAnchorBeforeThisOrSuper(project, editor, anchorStatement, REFACTORING_NAME, HelpID.INTRODUCE_VARIABLE))
return false;
final PsiElement tempContainer = anchorStatement.getParent();
if (!(tempContainer instanceof PsiCodeBlock) && !RefactoringUtil.isLoopOrIf(tempContainer) && !(tempContainer instanceof PsiLambdaExpression) && (tempContainer.getParent() instanceof PsiLambdaExpression)) {
String message = RefactoringBundle.message("refactoring.is.not.supported.in.the.current.context", REFACTORING_NAME);
showErrorMessage(project, editor, message);
return false;
}
if (!NotInSuperCallOccurrenceFilter.INSTANCE.isOK(expr)) {
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("cannot.introduce.variable.in.super.constructor.call"));
showErrorMessage(project, editor, message);
return false;
}
final PsiFile file = anchorStatement.getContainingFile();
LOG.assertTrue(file != null, "expr.getContainingFile() == null");
final PsiElement nameSuggestionContext = editor == null ? null : file.findElementAt(editor.getCaretModel().getOffset());
final RefactoringSupportProvider supportProvider = LanguageRefactoringSupport.INSTANCE.forLanguage(expr.getLanguage());
final boolean isInplaceAvailableOnDataContext = supportProvider != null && editor.getSettings().isVariableInplaceRenameEnabled() && supportProvider.isInplaceIntroduceAvailable(expr, nameSuggestionContext) && (!ApplicationManager.getApplication().isUnitTestMode() || isInplaceAvailableInTestMode()) && !isInJspHolderMethod(expr);
if (isInplaceAvailableOnDataContext) {
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
checkInLoopCondition(expr, conflicts);
if (!conflicts.isEmpty()) {
showErrorMessage(project, editor, StringUtil.join(conflicts.values(), "<br>"));
return false;
}
}
final ExpressionOccurrenceManager occurrenceManager = createOccurrenceManager(expr, tempContainer);
final PsiExpression[] occurrences = occurrenceManager.getOccurrences();
final PsiElement anchorStatementIfAll = occurrenceManager.getAnchorStatementForAll();
OccurrencesInfo occurrencesInfo = new OccurrencesInfo(occurrences);
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file))
return false;
final LinkedHashMap<JavaReplaceChoice, List<PsiExpression>> occurrencesMap = occurrencesInfo.buildOccurrencesMap(expr);
final boolean inFinalContext = occurrenceManager.isInFinalContext();
final InputValidator validator = new InputValidator(this, project, anchorStatementIfAll, anchorStatement, occurrenceManager);
final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, originalType, expr, occurrences);
final boolean[] wasSucceed = new boolean[] { true };
final Pass<JavaReplaceChoice> callback = new Pass<JavaReplaceChoice>() {
@Override
public void pass(final JavaReplaceChoice choice) {
boolean hasWriteAccess = occurrencesInfo.myHasWriteAccess;
List<PsiExpression> nonWrite = occurrencesInfo.myNonWrite;
if (choice != null) {
final boolean noWriteChoice = choice == JavaReplaceChoice.NO_WRITE;
final boolean allChoice = choice.isAll();
final boolean replaceAll = allChoice || noWriteChoice;
typeSelectorManager.setAllOccurrences(replaceAll);
final PsiElement chosenAnchor = chooseAnchor(replaceAll, noWriteChoice, nonWrite, anchorStatementIfAll, anchorStatement);
final IntroduceVariableSettings settings = getSettings(project, editor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, chosenAnchor, choice);
final boolean cantChangeFinalModifier = (hasWriteAccess || inFinalContext) && allChoice;
PsiExpression[] allOccurrences = Arrays.stream(occurrences).filter(occurrence -> !(expr.equals(occurrence) && expr.getParent() instanceof PsiExpressionStatement)).filter(occurrence -> allChoice || (noWriteChoice && !PsiUtil.isAccessedForWriting(occurrence)) || expr.equals(occurrence)).toArray(PsiExpression[]::new);
if (choice.isChain()) {
myInplaceIntroducer = new ChainCallInplaceIntroducer(project, settings, chosenAnchor, editor, expr, allOccurrences, typeSelectorManager, REFACTORING_NAME);
} else {
myInplaceIntroducer = new JavaVariableInplaceIntroducer(project, settings, chosenAnchor, editor, expr, cantChangeFinalModifier, allOccurrences, typeSelectorManager, REFACTORING_NAME);
}
if (myInplaceIntroducer.startInplaceIntroduceTemplate()) {
return;
}
}
CommandProcessor.getInstance().executeCommand(project, () -> {
if (!anchorStatement.isValid()) {
return;
}
final Editor topLevelEditor;
if (!InjectedLanguageManager.getInstance(project).isInjectedFragment(anchorStatement.getContainingFile())) {
topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
} else {
topLevelEditor = editor;
}
PsiVariable variable = null;
try {
final IntroduceVariableSettings settings = getSettings(project, topLevelEditor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, anchorStatement, choice);
if (!settings.isOK()) {
wasSucceed[0] = false;
return;
}
final RefactoringEventData beforeData = new RefactoringEventData();
beforeData.addElement(expr);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringStarted(REFACTORING_ID, beforeData);
final PsiElement chosenAnchor = chooseAnchor(settings.isReplaceAllOccurrences(), hasWriteAccess, nonWrite, anchorStatementIfAll, anchorStatement);
variable = introduce(project, expr, topLevelEditor, chosenAnchor, occurrences, settings);
} finally {
final RefactoringEventData afterData = new RefactoringEventData();
afterData.addElement(variable);
project.getMessageBus().syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC).refactoringDone(REFACTORING_ID, afterData);
}
}, REFACTORING_NAME, null);
}
};
if (!isInplaceAvailableOnDataContext) {
callback.pass(null);
} else {
JavaReplaceChoice choice = getOccurrencesChoice();
if (choice != null) {
callback.pass(choice);
} else {
String title = occurrencesInfo.myChainMethodName != null && occurrences.length == 1 ? "Lambda chain detected" : OccurrencesChooser.DEFAULT_CHOOSER_TITLE;
OccurrencesChooser.<PsiExpression>simpleChooser(editor).showChooser(callback, occurrencesMap, title);
}
}
return wasSucceed[0];
}
use of com.intellij.util.containers.MultiMap in project intellij-community by JetBrains.
the class MoveClassesOrPackagesImpl method doRearrangePackage.
public static void doRearrangePackage(final Project project, final PsiDirectory[] directories) {
if (!CommonRefactoringUtil.checkReadOnlyStatusRecursively(project, Arrays.asList(directories), true)) {
return;
}
List<PsiDirectory> sourceRootDirectories = buildRearrangeTargetsList(project, directories);
DirectoryChooser chooser = new DirectoryChooser(project);
chooser.setTitle(RefactoringBundle.message("select.source.root.chooser.title"));
chooser.fillList(sourceRootDirectories.toArray(new PsiDirectory[sourceRootDirectories.size()]), null, project, "");
if (!chooser.showAndGet()) {
return;
}
final PsiDirectory selectedTarget = chooser.getSelectedDirectory();
if (selectedTarget == null)
return;
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
final Runnable analyzeConflicts = () -> ApplicationManager.getApplication().runReadAction(() -> RefactoringConflictsUtil.analyzeModuleConflicts(project, Arrays.asList(directories), UsageInfo.EMPTY_ARRAY, selectedTarget, conflicts));
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(analyzeConflicts, "Analyze Module Conflicts...", true, project)) {
return;
}
if (!conflicts.isEmpty()) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
throw new BaseRefactoringProcessor.ConflictsInTestsException(conflicts.values());
} else {
final ConflictsDialog conflictsDialog = new ConflictsDialog(project, conflicts);
if (!conflictsDialog.showAndGet()) {
return;
}
}
}
final Ref<IncorrectOperationException> ex = Ref.create(null);
final String commandDescription = RefactoringBundle.message("moving.directories.command");
Runnable runnable = () -> ApplicationManager.getApplication().runWriteAction(() -> {
LocalHistoryAction a = LocalHistory.getInstance().startAction(commandDescription);
try {
rearrangeDirectoriesToTarget(directories, selectedTarget);
} catch (IncorrectOperationException e) {
ex.set(e);
} finally {
a.finish();
}
});
CommandProcessor.getInstance().executeCommand(project, runnable, commandDescription, null);
if (ex.get() != null) {
RefactoringUIUtil.processIncorrectOperation(project, ex.get());
}
}
use of com.intellij.util.containers.MultiMap in project intellij-community by JetBrains.
the class MakeMethodOrClassStaticProcessor method getConflictDescriptions.
protected MultiMap<PsiElement, String> getConflictDescriptions(UsageInfo[] usages) {
MultiMap<PsiElement, String> conflicts = new MultiMap<>();
HashSet<PsiElement> processed = new HashSet<>();
String typeString = StringUtil.capitalize(UsageViewUtil.getType(myMember));
for (UsageInfo usageInfo : usages) {
if (usageInfo instanceof InternalUsageInfo && !(usageInfo instanceof SelfUsageInfo)) {
PsiElement referencedElement = ((InternalUsageInfo) usageInfo).getReferencedElement();
if (!mySettings.isMakeClassParameter()) {
if (referencedElement instanceof PsiModifierListOwner) {
if (((PsiModifierListOwner) referencedElement).hasModifierProperty(PsiModifier.STATIC)) {
continue;
}
}
if (processed.contains(referencedElement))
continue;
processed.add(referencedElement);
if (referencedElement instanceof PsiField) {
PsiField field = (PsiField) referencedElement;
if (mySettings.getNameForField(field) == null) {
String message = RefactoringBundle.message("0.uses.non.static.1.which.is.not.passed.as.a.parameter", typeString, RefactoringUIUtil.getDescription(field, true));
conflicts.putValue(field, message);
}
} else {
String message = RefactoringBundle.message("0.uses.1.which.needs.class.instance", typeString, RefactoringUIUtil.getDescription(referencedElement, true));
conflicts.putValue(referencedElement, message);
}
}
}
if (usageInfo instanceof OverridingMethodUsageInfo) {
LOG.assertTrue(myMember instanceof PsiMethod);
final PsiMethod overridingMethod = ((PsiMethod) usageInfo.getElement());
String message = RefactoringBundle.message("method.0.is.overridden.by.1", RefactoringUIUtil.getDescription(myMember, false), RefactoringUIUtil.getDescription(overridingMethod, true));
conflicts.putValue(overridingMethod, message);
} else {
PsiElement element = usageInfo.getElement();
PsiElement container = ConflictsUtil.getContainer(element);
if (processed.contains(container))
continue;
processed.add(container);
List<Settings.FieldParameter> fieldParameters = mySettings.getParameterOrderList();
ArrayList<PsiField> inaccessible = new ArrayList<>();
for (final Settings.FieldParameter fieldParameter : fieldParameters) {
if (!PsiUtil.isAccessible(fieldParameter.field, element, null)) {
inaccessible.add(fieldParameter.field);
}
}
if (inaccessible.isEmpty())
continue;
createInaccessibleFieldsConflictDescription(inaccessible, container, conflicts);
}
}
return conflicts;
}
use of com.intellij.util.containers.MultiMap in project intellij-community by JetBrains.
the class GrIntroduceValidatorEngine method isOKImpl.
private MultiMap<PsiElement, String> isOKImpl(String varName, boolean replaceAllOccurrences) {
PsiElement firstOccurrence = getFirstOccurrence(replaceAllOccurrences);
final MultiMap<PsiElement, String> conflicts = new MultiMap<>();
assert varName != null;
final int offset = firstOccurrence.getTextRange().getStartOffset();
validateOccurrencesDown(myContext.getScope(), conflicts, varName, offset);
if (!(myContext.getScope() instanceof GroovyFileBase)) {
validateVariableOccurrencesUp(myContext.getScope(), conflicts, varName, offset);
}
if (replaceAllOccurrences) {
for (PsiElement element : myContext.getOccurrences()) {
if (element == firstOccurrence)
continue;
validateVariableOccurrencesUp(element, conflicts, varName, element.getTextRange().getStartOffset());
}
}
return conflicts;
}
Aggregations