void (int offset, Environment env) { Project project = getProject(); Editor editor = FileEditorManager.getInstance(project).openTextEditor(new OpenFileDescriptor(project, getVirtualFile(), offset), true); assert editor != null; FileViewProvider viewProvider = getFile().getViewProvider(); boolean containsErrorElements = MadTestingUtil.containsErrorElements(viewProvider); List<HighlightInfo> errors = highlightErrors(project, editor); boolean hasErrors = !errors.isEmpty() || containsErrorElements; PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, getProject()); assert file != null; List<IntentionAction> intentions = getAvailableIntentions(editor, file); // Do not reuse originally passed offset here, sometimes it's adjusted by Editor PsiElement currentElement = file.findElementAt(editor.getCaretModel().getOffset()); if (!containsErrorElements) { intentions = wrapAndCheck(env, editor, currentElement, hasErrors, intentions); } IntentionAction intention = chooseIntention(env, intentions); if (intention == null) return; if (myPolicy.shouldCheckPreview(intention) && intention.getElementToMakeWritable(file) == file) { checkPreview(intention, editor); } String intentionString = intention.toString(); boolean checkComments = myPolicy.checkComments(intention) && PsiTreeUtil .getParentOfType(file.findElementAt(offset), PsiComment.class, false) == null; Collection<String> comments = checkComments ? extractCommentsReformattedToSingleWhitespace(file) : Collections.emptyList(); boolean mayBreakCode = myPolicy.mayBreakCode(intention, editor, file); Document changedDocument = getDocumentToBeChanged(intention); String textBefore = changedDocument == null ? null : changedDocument.getText(); Long stampBefore = changedDocument == null ? null : changedDocument.getModificationStamp(); Runnable r = () -> CodeInsightTestFixtureImpl.invokeIntention(intention, file, editor); Disposable disposable = Disposer.newDisposable(); try { UiInterceptors.register(new RandomActivityInterceptor(env, disposable)); if (containsErrorElements) { Registry.get("ide.check.structural.psi.text.consistency.in.tests").setValue(false, disposable); Disposer.register(disposable, this::restoreAfterPotentialPsiTextInconsistency); } Pair<PsiFile, Editor> pair = ShowIntentionActionsHandler.chooseFileForAction(file, editor, intention); if (pair != null && pair.second instanceof EditorWindow) { // intentions too often break wildly when invoked inside injection :( // todo remove return when IDEA-187613, IDEA-187427, IDEA-194969 are fixed return; } if (changedDocument != null) { MadTestingUtil.restrictChangesToDocument(changedDocument, r); } else { r.run(); } if (changedDocument != null && PsiDocumentManager.getInstance(project).isDocumentBlockedByPsi(changedDocument)) { throw new AssertionError("Document is left blocked by PSI"); } if (!hasErrors && stampBefore != null && stampBefore.equals(changedDocument.getModificationStamp())) { String message = "No change was performed in the document"; if (intention.startInWriteAction()) { message += ".\nIf it's by design that " + intentionString + " doesn't change source files, " + "it should return false from 'startInWriteAction'"; } throw new AssertionError(message); } PsiTestUtil.checkPsiStructureWithCommit(getFile(), PsiTestUtil::checkStubsMatchText); if (!mayBreakCode && !hasErrors) { checkNoNewErrors(project, editor, intentionString, myPolicy); } if (checkComments) { List<String> fileComments = extractCommentsReformattedToSingleWhitespace(file); for (String comment : comments) { if (!fileComments.contains(comment)) { throw new AssertionError("Lost comment '" + comment + "' during " + intentionString); } } } } catch (Throwable error) { LOG.debug("Error occurred, text before intention invocation:\n" + textBefore); env.logMessage("Error happened, the file's text before invoking printed to the debug log, search for 'text before intention invocation' there"); throw error; } finally { Disposer.dispose(disposable); } }