void (@NotNull PsiFile psiFile, @NotNull CharSequence newFileText, @NotNull String answersFilePath, boolean checkInitialTreeForErrors, boolean checkFinalTreeForErrors) { if (checkInitialTreeForErrors) { assertNoPsiErrorElements(psiFile); } var project = psiFile.getProject(); var psiDocumentManager = PsiDocumentManager.getInstance(project); var fileDocument = psiDocumentManager.getDocument(psiFile); TestCase.assertNotNull(fileDocument); psiDocumentManager.commitDocument(fileDocument); var originalText = fileDocument.getCharsSequence(); StringBuilder result = new StringBuilder("Original text:") .append(NL_SEPARATOR_NL) .append(originalText) .append(NL_SEPARATOR_NL); var allFiles = psiFile.getViewProvider().getAllFiles(); ContainerUtil.sort(allFiles, Comparator.comparing(it -> it.getLanguage().getID())); for (PsiFile subTree : allFiles) { UsefulTestCase.assertInstanceOf(subTree, PsiFileImpl.class); var subTreeFile = (PsiFileImpl)subTree; TextRange changedRange = ChangedPsiRangeUtil.getChangedPsiRange(subTreeFile, Objects.requireNonNull(subTreeFile.getTreeElement()), newFileText); TestCase.assertNotNull("No changes found", changedRange); Couple<ASTNode> reparseableRoots = BlockSupportImpl.findReparseableRoots(subTreeFile, subTree.getNode(), changedRange, newFileText); result.append("Subtree: ").append(subTree.getLanguage()).append(NL_SEPARATOR_NL); serializeReparseableRoots(reparseableRoots, result, newFileText); result.append(NL_SEPARATOR_NL); } WriteAction.run(() -> fileDocument.setText(newFileText)); psiDocumentManager.commitDocument(fileDocument); var psiBeforeCommit = psiFileToString(psiFile); WriteCommandAction.runWriteCommandAction(project, () -> { fileDocument.setText(""); psiDocumentManager.commitDocument(fileDocument); fileDocument.setText(newFileText); psiDocumentManager.commitDocument(fileDocument); }); TestCase.assertEquals("Reparsing error", psiFileToString(psiFile), psiBeforeCommit); if (checkFinalTreeForErrors) { assertNoPsiErrorElementsInAllSubTrees(psiFile); } UsefulTestCase.assertSameLinesWithFile(answersFilePath, result.toString(), false); }