mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Explicitly release range markers created by PostprocessReformattingAspect - fails in case of great document changes number within the same transaction
This commit is contained in:
+62
-28
@@ -18,6 +18,7 @@ package com.intellij.psi.impl.source;
|
||||
import com.intellij.formatting.FormatTextRanges;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationAdapter;
|
||||
import com.intellij.openapi.application.ApplicationListener;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -46,6 +47,7 @@ import com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade;
|
||||
import com.intellij.psi.impl.source.codeStyle.IndentHelperImpl;
|
||||
import com.intellij.psi.impl.source.tree.*;
|
||||
import com.intellij.util.LocalTimeCounter;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
@@ -295,33 +297,44 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
final VirtualFile virtualFile = key.getVirtualFile();
|
||||
if (!virtualFile.isValid()) return;
|
||||
|
||||
final TreeSet<PostprocessFormattingTask> postprocessTasks = new TreeSet<PostprocessFormattingTask>();
|
||||
// process all roots in viewProvider to find marked for reformat before elements and create appropriate range markers
|
||||
handleReformatMarkers(key, postprocessTasks);
|
||||
final TreeSet<PostprocessFormattingTask> postProcessTasks = new TreeSet<PostprocessFormattingTask>();
|
||||
Collection<Disposable> toDispose = ContainerUtilRt.newArrayList();
|
||||
try {
|
||||
// process all roots in viewProvider to find marked for reformat before elements and create appropriate range markers
|
||||
handleReformatMarkers(key, postProcessTasks);
|
||||
toDispose.addAll(postProcessTasks);
|
||||
|
||||
// then we create ranges by changed nodes. One per node. There ranges can intersect. Ranges are sorted by end offset.
|
||||
if (astNodes != null) createActionsMap(astNodes, key, postprocessTasks);
|
||||
// then we create ranges by changed nodes. One per node. There ranges can intersect. Ranges are sorted by end offset.
|
||||
if (astNodes != null) createActionsMap(astNodes, key, postProcessTasks);
|
||||
|
||||
if ("true".equals(System.getProperty("check.psi.is.valid")) && ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
checkPsiIsCorrect(key);
|
||||
if ("true".equals(System.getProperty("check.psi.is.valid")) && ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
checkPsiIsCorrect(key);
|
||||
}
|
||||
|
||||
while (!postProcessTasks.isEmpty()) {
|
||||
// now we have to normalize actions so that they not intersect and ordered in most appropriate way
|
||||
// (free reformatting -> reindent -> formatting under reindent)
|
||||
final List<PostponedAction> normalizedActions = normalizeAndReorderPostponedActions(postProcessTasks, document);
|
||||
toDispose.addAll(normalizedActions);
|
||||
|
||||
// only in following loop real changes in document are made
|
||||
for (final PostponedAction normalizedAction : normalizedActions) {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myPsiManager.getProject());
|
||||
boolean old = settings.ENABLE_JAVADOC_FORMATTING;
|
||||
settings.ENABLE_JAVADOC_FORMATTING = false;
|
||||
try {
|
||||
normalizedAction.execute(key);
|
||||
}
|
||||
finally {
|
||||
settings.ENABLE_JAVADOC_FORMATTING = old;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!postprocessTasks.isEmpty()) {
|
||||
// now we have to normalize actions so that they not intersect and ordered in most appropriate way
|
||||
// (free reformatting -> reindent -> formatting under reindent)
|
||||
final List<PostponedAction> normalizedActions = normalizeAndReorderPostponedActions(postprocessTasks, document);
|
||||
|
||||
// only in following loop real changes in document are made
|
||||
for (final PostponedAction normalizedAction : normalizedActions) {
|
||||
CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(myPsiManager.getProject());
|
||||
boolean old = settings.ENABLE_JAVADOC_FORMATTING;
|
||||
settings.ENABLE_JAVADOC_FORMATTING = false;
|
||||
try {
|
||||
normalizedAction.execute(key);
|
||||
}
|
||||
finally {
|
||||
settings.ENABLE_JAVADOC_FORMATTING = old;
|
||||
}
|
||||
finally {
|
||||
for (Disposable disposable : toDispose) {
|
||||
//noinspection SSBasedInspection
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -599,10 +612,10 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
return codeFormatter;
|
||||
}
|
||||
|
||||
private abstract static class PostprocessFormattingTask implements Comparable<PostprocessFormattingTask>, Segment {
|
||||
private final RangeMarker myRange;
|
||||
private abstract static class PostprocessFormattingTask implements Comparable<PostprocessFormattingTask>, Segment, Disposable {
|
||||
@NotNull private final RangeMarker myRange;
|
||||
|
||||
public PostprocessFormattingTask(RangeMarker rangeMarker) {
|
||||
public PostprocessFormattingTask(@NotNull RangeMarker rangeMarker) {
|
||||
myRange = rangeMarker;
|
||||
}
|
||||
|
||||
@@ -621,6 +634,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
return diff;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RangeMarker getRange() {
|
||||
return myRange;
|
||||
}
|
||||
@@ -634,6 +648,12 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
public int getEndOffset() {
|
||||
return myRange.getEndOffset();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
if (myRange.isValid()) {
|
||||
myRange.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReformatTask extends PostprocessFormattingTask {
|
||||
@@ -661,7 +681,7 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
}
|
||||
}
|
||||
|
||||
private interface PostponedAction {
|
||||
private interface PostponedAction extends Disposable {
|
||||
void execute(FileViewProvider viewProvider);
|
||||
}
|
||||
|
||||
@@ -677,6 +697,10 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
final CodeFormatterFacade codeFormatter = getFormatterFacade(viewProvider);
|
||||
codeFormatter.processText(viewProvider.getPsi(viewProvider.getBaseLanguage()), myRanges.ensureNonEmpty(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReindentRangesAction implements PostponedAction {
|
||||
@@ -700,6 +724,16 @@ public class PostprocessReformattingAspect implements PomModelAspect {
|
||||
if (indentAdjustment != 0) adjustIndentationInRange(psiFile, document, whitespaces, indentAdjustment);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (Pair<Integer, RangeMarker> pair : myRangesToReindent) {
|
||||
RangeMarker marker = pair.second;
|
||||
if (marker.isValid()) {
|
||||
marker.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
Reference in New Issue
Block a user