5
5
*/
6
6
package io .flutter .devtools ;
7
7
8
+ import com .intellij .openapi .application .Application ;
8
9
import com .intellij .openapi .editor .colors .EditorColorsManager ;
10
+ import com .intellij .openapi .vfs .VirtualFile ;
9
11
import com .intellij .ui .ColorUtil ;
10
12
import com .intellij .ui .JBColor ;
11
13
import com .intellij .util .ui .UIUtil ;
14
+ import org .dartlang .vm .service .VmService ;
15
+ import org .dartlang .vm .service .VmServiceListener ;
12
16
import org .jetbrains .annotations .NotNull ;
13
17
18
+ import org .dartlang .vm .service .element .Event ;
19
+
20
+ import com .google .gson .JsonObject ;
21
+ import com .intellij .openapi .application .ApplicationManager ;
22
+ import com .intellij .openapi .vfs .LocalFileSystem ;
23
+ import com .intellij .xdebugger .impl .XSourcePositionImpl ;
24
+ import io .flutter .run .daemon .FlutterApp ;
25
+ import io .flutter .utils .JsonUtils ;
26
+ import org .dartlang .vm .service .element .*;
27
+ import org .jetbrains .annotations .Nullable ;
28
+
29
+ import java .net .MalformedURLException ;
30
+ import java .net .URI ;
31
+ import java .net .URISyntaxException ;
32
+ import java .util .*;
33
+
14
34
public class DevToolsUtils {
15
35
public static String findWidgetId (String url ) {
16
36
final String searchFor = "inspectorRef=" ;
@@ -23,6 +43,75 @@ public static String findWidgetId(String url) {
23
43
return null ;
24
44
}
25
45
46
+ /**
47
+ * Register a VM listener that listens for devtools "ToolEvent"s.
48
+ * @param app the associated app
49
+ */
50
+ public static void registerDevToolsVmServiceListener (@ NotNull FlutterApp app ) {
51
+ // This functionality lived originally in the `FlutterInspectorService` introduced in:
52
+ // https://github.com/flutter/flutter-intellij/pull/6881
53
+ //
54
+ // It was mistakenly removed in: https://github.com/flutter/flutter-intellij/pull/7867
55
+ //
56
+ // TODO(pq): some follow-ups:
57
+ // * consider a better long-term home for this utility
58
+ // * do we need to de-register?
59
+
60
+ VmService vmService = app .getVmService ();
61
+ if (vmService == null ) return ;
62
+
63
+ vmService .addVmServiceListener (new VmServiceListener () {
64
+ @ Override
65
+ public void connectionOpened () { }
66
+
67
+ @ Override
68
+ public void received (String streamId , Event event ) {
69
+ if (streamId != null ) {
70
+ onVmServiceReceived (app , streamId , event );
71
+ }
72
+ }
73
+
74
+ @ Override
75
+ public void connectionClosed () { }
76
+ });
77
+ }
78
+
79
+ private static void onVmServiceReceived (@ NotNull FlutterApp app , @ NotNull String streamId , @ Nullable Event event ) {
80
+ Application application = ApplicationManager .getApplication ();
81
+ if (application == null ) return ;
82
+
83
+ if (streamId .equals ("ToolEvent" )) {
84
+ Optional <Event > eventOrNull = Optional .ofNullable (event );
85
+ if ("navigate" .equals (eventOrNull .map (Event ::getExtensionKind ).orElse (null ))) {
86
+ JsonObject json = eventOrNull .map (Event ::getExtensionData ).map (ExtensionData ::getJson ).orElse (null );
87
+ if (json == null ) return ;
88
+
89
+ String fileUri = JsonUtils .getStringMember (json , "fileUri" );
90
+ if (fileUri == null ) return ;
91
+
92
+ String path = null ;
93
+ try {
94
+ path = new URI (fileUri ).toURL ().getFile ();
95
+ }
96
+ catch (MalformedURLException | URISyntaxException e ) {
97
+ // A null path will cause an early return.
98
+ }
99
+ if (path == null ) return ;
100
+
101
+ VirtualFile file = LocalFileSystem .getInstance ().findFileByPath (path );
102
+ int line = JsonUtils .getIntMember (json , "line" );
103
+ int column = JsonUtils .getIntMember (json , "column" );
104
+
105
+ application .invokeLater (() -> {
106
+ if (file != null && line >= 0 && column >= 0 ) {
107
+ XSourcePositionImpl position = XSourcePositionImpl .create (file , line - 1 , column - 1 );
108
+ position .createNavigatable (app .getProject ()).navigate (false );
109
+ }
110
+ });
111
+ }
112
+ }
113
+ }
114
+
26
115
public String getColorHexCode () {
27
116
return ColorUtil .toHex (UIUtil .getEditorPaneBackground ());
28
117
}
@@ -37,6 +126,6 @@ public Boolean getIsBackgroundBright() {
37
126
// Return the default normal font size if editor manager is not found.
38
127
return UIUtil .getFontSize (UIUtil .FontSize .NORMAL );
39
128
}
40
- return (float ) manager .getGlobalScheme ().getEditorFontSize ();
129
+ return (float )manager .getGlobalScheme ().getEditorFontSize ();
41
130
}
42
131
}
0 commit comments