Skip to content

Commit 83d864c

Browse files
authored
Make logic dealing with converting offsets more robust. (#3635)
Only use the converted offsets when the file and the converted offsets disagree. This avoids bugs where we sometimes converted offsets that shouldn't be converted on windows.
1 parent 6b3516c commit 83d864c

File tree

3 files changed

+41
-15
lines changed

3 files changed

+41
-15
lines changed

src/io/flutter/editor/OutlineLocation.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public OutlineLocation(
6161
int column,
6262
int indent,
6363
VirtualFile file,
64-
DartAnalysisServerService analysisService
64+
WidgetIndentsHighlightingPass pass
6565
) {
6666
this.line = line;
6767
this.column = column;
@@ -76,8 +76,8 @@ public OutlineLocation(
7676
assert (column >= indent);
7777
assert (line >= 0);
7878
this.indent = indent;
79-
this.offset = analysisService.getConvertedOffset(file, node.getOffset());
80-
this.endOffset = analysisService.getConvertedOffset(file, node.getOffset() + node.getLength());
79+
this.offset = pass.getConvertedOffset(node);
80+
this.endOffset = pass.getConvertedOffset(node.getOffset() + node.getLength());
8181
}
8282

8383
public void dispose() {

src/io/flutter/editor/WidgetIndentsHighlightingPass.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,14 @@ public void paint(@NotNull Editor editor, @NotNull RangeHighlighter highlighter,
425425
private final Document myDocument;
426426
private final Project myProject;
427427
private final VirtualFile myFile;
428+
private final boolean convertOffsets;
428429

429-
WidgetIndentsHighlightingPass(@NotNull Project project, @NotNull EditorEx editor) {
430+
WidgetIndentsHighlightingPass(@NotNull Project project, @NotNull EditorEx editor, boolean convertOffsets) {
430431
this.myDocument = editor.getDocument();
431432
this.myEditor = editor;
432433
this.myProject = project;
433434
this.myFile = editor.getVirtualFile();
435+
this.convertOffsets = convertOffsets;
434436
}
435437

436438
private static void drawVerticalLineHelper(
@@ -524,8 +526,8 @@ public static void cleanupHighlighters(Editor editor) {
524526
setIndentsPassData(editor, null);
525527
}
526528

527-
public static void run(@NotNull Project project, @NotNull EditorEx editor, @NotNull FlutterOutline outline) {
528-
final WidgetIndentsHighlightingPass widgetIndentsHighlightingPass = new WidgetIndentsHighlightingPass(project, editor);
529+
public static void run(@NotNull Project project, @NotNull EditorEx editor, @NotNull FlutterOutline outline, boolean convertOffsets) {
530+
final WidgetIndentsHighlightingPass widgetIndentsHighlightingPass = new WidgetIndentsHighlightingPass(project, editor, convertOffsets);
529531
widgetIndentsHighlightingPass.setOutline(outline);
530532
}
531533

@@ -671,10 +673,28 @@ DartAnalysisServerService getAnalysisService() {
671673
return DartAnalysisServerService.getInstance(myProject);
672674
}
673675

676+
/**
677+
* All calls to convert offsets for indent highlighting must go through this
678+
* method.
679+
*
680+
* Sometimes we need to use the raw offsets and sometimes we need
681+
* to use the converted offsets depending on whether the FlutterOutline
682+
* matches the current document or the expectations given by the
683+
* @param node
684+
* @return
685+
*/
686+
int getConvertedOffset(FlutterOutline node) {
687+
return getConvertedOffset(node.getOffset());
688+
}
689+
690+
int getConvertedOffset(int offset) {
691+
return convertOffsets ? getAnalysisService().getConvertedOffset(myFile, offset) : offset;
692+
}
693+
674694
private OutlineLocation computeLocation(FlutterOutline node) {
675695
assert (myDocument != null);
676696
final int documentLength = myDocument.getTextLength();
677-
final int rawOffset = getAnalysisService().getConvertedOffset(myFile, node.getOffset());
697+
final int rawOffset = getConvertedOffset(node);
678698
final int nodeOffset = min(rawOffset, documentLength);
679699
final int line = myDocument.getLineNumber(nodeOffset);
680700
final int lineStartOffset = myDocument.getLineStartOffset(line);
@@ -692,7 +712,7 @@ private OutlineLocation computeLocation(FlutterOutline node) {
692712
}
693713
}
694714

695-
return new OutlineLocation(node, line, column, indent, myFile, getAnalysisService());
715+
return new OutlineLocation(node, line, column, indent, myFile, this);
696716
}
697717

698718
private void buildWidgetDescriptors(

src/io/flutter/editor/WidgetIndentsHighlightingPassFactory.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@
2121
import com.intellij.openapi.editor.ex.DocumentEx;
2222
import com.intellij.openapi.editor.ex.EditorEx;
2323
import com.intellij.openapi.fileEditor.*;
24-
import com.intellij.openapi.fileEditor.impl.FileOffsetsManager;
2524
import com.intellij.openapi.progress.ProgressIndicator;
2625
import com.intellij.openapi.project.Project;
2726
import com.intellij.openapi.util.io.FileUtil;
2827
import com.intellij.openapi.vfs.VirtualFile;
2928
import com.intellij.psi.PsiFile;
29+
import com.jetbrains.lang.dart.analyzer.DartAnalysisServerService;
3030
import io.flutter.FlutterUtils;
3131
import io.flutter.dart.FlutterDartAnalysisServer;
3232
import io.flutter.dart.FlutterOutlineListener;
@@ -230,7 +230,6 @@ private void syncSettings(FlutterSettings settings) {
230230
isShowBuildMethodGuides = settings.isShowBuildMethodGuides();
231231
updateActiveEditors();
232232
}
233-
234233
isShowMultipleChildrenGuides = settings.isShowMultipleChildrenGuides() && isShowBuildMethodGuides;
235234
}
236235

@@ -290,7 +289,7 @@ public TextEditorHighlightingPass createHighlightingPass(@NotNull PsiFile file,
290289
}
291290

292291
void runWidgetIndentsPass(EditorEx editor, @NotNull FlutterOutline outline) {
293-
if (editor.isDisposed()) {
292+
if (editor.isDisposed() || project.isDisposed()) {
294293
// The editor might have been disposed before we got a new FlutterOutline.
295294
// It is safe to ignore it as it isn't relevant.
296295
return;
@@ -302,18 +301,25 @@ void runWidgetIndentsPass(EditorEx editor, @NotNull FlutterOutline outline) {
302301
}
303302
// If the editor and the outline have different lengths then
304303
// the outline is out of date and cannot safely be displayed.
305-
final FileOffsetsManager offsetManager = FileOffsetsManager.getInstance();
306304
final DocumentEx document = editor.getDocument();
307-
if (document.getTextLength() != offsetManager.getConvertedOffset(file, outline.getLength())) {
305+
final int documentLength = document.getTextLength();
306+
final int outlineLength = outline.getLength();
307+
// TODO(jacobr): determine why we sometimes have to check against both the
308+
// raw outlineLength and the converted outline length for things to work
309+
// correctly on windows.
310+
if (documentLength != outlineLength &&
311+
documentLength != DartAnalysisServerService.getInstance(project).getConvertedOffset(file, outlineLength)) {
308312
// Outline is out of date. That is ok. Ignore it for now.
309313
// An up to date outline will probably arive shortly. Showing an
310314
// outline from data inconsistent with the current
311315
// content will show annoying flicker. It is better to
312316
// instead
313317
return;
314318
}
315-
316-
WidgetIndentsHighlightingPass.run(project, editor, outline);
319+
// We only need to convert offsets when the document and outline disagree
320+
// on the document length.
321+
final boolean convertOffsets = documentLength != outlineLength;
322+
WidgetIndentsHighlightingPass.run(project, editor, outline, convertOffsets);
317323
}
318324

319325
@Override

0 commit comments

Comments
 (0)