Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: runtime/observatory/lib/src/debugger/debugger_location.dart

Issue 1150303004: Switch to using SourceLocation universally in service protocol. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: post merge Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of debugger; 5 part of debugger;
6 6
7 class SourceLocation { 7 class DebuggerLocation {
8 SourceLocation.file(this.script, this.line, this.col); 8 DebuggerLocation.file(this.script, this.line, this.col);
9 SourceLocation.func(this.function); 9 DebuggerLocation.func(this.function);
10 SourceLocation.error(this.errorMessage); 10 DebuggerLocation.error(this.errorMessage);
11 11
12 static RegExp sourceLocMatcher = new RegExp(r'^([^\d:][^:]+:)?(\d+)(:\d+)?'); 12 static RegExp sourceLocMatcher = new RegExp(r'^([^\d:][^:]+:)?(\d+)(:\d+)?');
13 static RegExp functionMatcher = new RegExp(r'^([^.]+)([.][^.]+)?'); 13 static RegExp functionMatcher = new RegExp(r'^([^.]+)([.][^.]+)?');
14 14
15 /// Parses a source location description. 15 /// Parses a source location description.
16 /// 16 ///
17 /// Formats: 17 /// Formats:
18 /// '' - current position 18 /// '' - current position
19 /// 13 - line 13, current script 19 /// 13 - line 13, current script
20 /// 13:20 - line 13, col 20, current script 20 /// 13:20 - line 13, col 20, current script
21 /// script.dart:13 - line 13, script.dart 21 /// script.dart:13 - line 13, script.dart
22 /// script.dart:13:20 - line 13, col 20, script.dart 22 /// script.dart:13:20 - line 13, col 20, script.dart
23 /// main - function 23 /// main - function
24 /// FormatException - constructor 24 /// FormatException - constructor
25 /// _SHA1._updateHash - method 25 /// _SHA1._updateHash - method
26 static Future<SourceLocation> parse(Debugger debugger, String locDesc) { 26 static Future<DebuggerLocation> parse(Debugger debugger, String locDesc) {
27 if (locDesc == '') { 27 if (locDesc == '') {
28 // Special case: '' means return current location. 28 // Special case: '' means return current location.
29 return _currentLocation(debugger); 29 return _currentLocation(debugger);
30 } 30 }
31 31
32 // Parse the location description. 32 // Parse the location description.
33 var match = sourceLocMatcher.firstMatch(locDesc); 33 var match = sourceLocMatcher.firstMatch(locDesc);
34 if (match != null) { 34 if (match != null) {
35 return _parseScriptLine(debugger, match); 35 return _parseScriptLine(debugger, match);
36 } 36 }
37 match = functionMatcher.firstMatch(locDesc); 37 match = functionMatcher.firstMatch(locDesc);
38 if (match != null) { 38 if (match != null) {
39 return _parseFunction(debugger, match); 39 return _parseFunction(debugger, match);
40 } 40 }
41 return new Future.value(new SourceLocation.error( 41 return new Future.value(new DebuggerLocation.error(
42 "Invalid source location '${locDesc}'")); 42 "Invalid source location '${locDesc}'"));
43 } 43 }
44 44
45 static Future<SourceLocation> _currentLocation(Debugger debugger) { 45 static Future<DebuggerLocation> _currentLocation(Debugger debugger) {
46 ServiceMap stack = debugger.stack; 46 ServiceMap stack = debugger.stack;
47 if (stack == null || stack['frames'].length == 0) { 47 if (stack == null || stack['frames'].length == 0) {
48 return new Future.value(new SourceLocation.error( 48 return new Future.value(new DebuggerLocation.error(
49 'A script must be provided when the stack is empty')); 49 'A script must be provided when the stack is empty'));
50 } 50 }
51 var frame = stack['frames'][debugger.currentFrame]; 51 var frame = stack['frames'][debugger.currentFrame];
52 Script script = frame['script']; 52 Script script = frame.location.script;
53 return script.load().then((_) { 53 return script.load().then((_) {
54 var line = script.tokenToLine(frame['tokenPos']); 54 var line = script.tokenToLine(frame.location.tokenPos);
55 // TODO(turnidge): Pass in the column here once the protocol supports it. 55 // TODO(turnidge): Pass in the column here once the protocol supports it.
56 return new Future.value(new SourceLocation.file(script, line, null)); 56 return new Future.value(new DebuggerLocation.file(script, line, null));
57 }); 57 });
58 } 58 }
59 59
60 static Future<SourceLocation> _parseScriptLine(Debugger debugger, 60 static Future<DebuggerLocation> _parseScriptLine(Debugger debugger,
61 Match match) { 61 Match match) {
62 var scriptName = match.group(1); 62 var scriptName = match.group(1);
63 if (scriptName != null) { 63 if (scriptName != null) {
64 scriptName = scriptName.substring(0, scriptName.length - 1); 64 scriptName = scriptName.substring(0, scriptName.length - 1);
65 } 65 }
66 var lineStr = match.group(2); 66 var lineStr = match.group(2);
67 assert(lineStr != null); 67 assert(lineStr != null);
68 var colStr = match.group(3); 68 var colStr = match.group(3);
69 if (colStr != null) { 69 if (colStr != null) {
70 colStr = colStr.substring(1); 70 colStr = colStr.substring(1);
71 } 71 }
72 var line = int.parse(lineStr, onError:(_) => -1); 72 var line = int.parse(lineStr, onError:(_) => -1);
73 var col = (colStr != null 73 var col = (colStr != null
74 ? int.parse(colStr, onError:(_) => -1) 74 ? int.parse(colStr, onError:(_) => -1)
75 : null); 75 : null);
76 if (line == -1) { 76 if (line == -1) {
77 return new Future.value(new SourceLocation.error( 77 return new Future.value(new DebuggerLocation.error(
78 "Line '${lineStr}' must be an integer")); 78 "Line '${lineStr}' must be an integer"));
79 } 79 }
80 if (col == -1) { 80 if (col == -1) {
81 return new Future.value(new SourceLocation.error( 81 return new Future.value(new DebuggerLocation.error(
82 "Column '${colStr}' must be an integer")); 82 "Column '${colStr}' must be an integer"));
83 } 83 }
84 84
85 if (scriptName != null) { 85 if (scriptName != null) {
86 // Resolve the script. 86 // Resolve the script.
87 return _lookupScript(debugger.isolate, scriptName).then((scripts) { 87 return _lookupScript(debugger.isolate, scriptName).then((scripts) {
88 if (scripts.length == 0) { 88 if (scripts.length == 0) {
89 return new SourceLocation.error("Script '${scriptName}' not found"); 89 return new DebuggerLocation.error("Script '${scriptName}' not found");
90 } else if (scripts.length == 1) { 90 } else if (scripts.length == 1) {
91 return new SourceLocation.file(scripts[0], line, col); 91 return new DebuggerLocation.file(scripts[0], line, col);
92 } else { 92 } else {
93 // TODO(turnidge): Allow the user to disambiguate. 93 // TODO(turnidge): Allow the user to disambiguate.
94 return new SourceLocation.error("Script '${scriptName}' is ambigous"); 94 return new DebuggerLocation.error("Script '${scriptName}' is ambigous" );
95 } 95 }
96 }); 96 });
97 } else { 97 } else {
98 // No script provided. Default to top of stack for now. 98 // No script provided. Default to top of stack for now.
99 ServiceMap stack = debugger.stack; 99 ServiceMap stack = debugger.stack;
100 if (stack == null || stack['frames'].length == 0) { 100 if (stack == null || stack['frames'].length == 0) {
101 return new Future.value(new SourceLocation.error( 101 return new Future.value(new DebuggerLocation.error(
102 'A script must be provided when the stack is empty')); 102 'A script must be provided when the stack is empty'));
103 } 103 }
104 Script script = stack['frames'][0]['script']; 104 Script script = stack['frames'][0].location.script;
105 return new Future.value(new SourceLocation.file(script, line, col)); 105 return new Future.value(new DebuggerLocation.file(script, line, col));
106 } 106 }
107 } 107 }
108 108
109 static Future<List<Script>> _lookupScript(Isolate isolate, 109 static Future<List<Script>> _lookupScript(Isolate isolate,
110 String name, 110 String name,
111 {bool allowPrefix: false}) { 111 {bool allowPrefix: false}) {
112 var pending = []; 112 var pending = [];
113 for (var lib in isolate.libraries) { 113 for (var lib in isolate.libraries) {
114 if (!lib.loaded) { 114 if (!lib.loaded) {
115 pending.add(lib.load()); 115 pending.add(lib.load());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 assert(cls.loaded); 191 assert(cls.loaded);
192 if (name == function.name) { 192 if (name == function.name) {
193 return function; 193 return function;
194 } 194 }
195 } 195 }
196 return null; 196 return null;
197 } 197 }
198 198
199 // TODO(turnidge): This does not handle named functions which are 199 // TODO(turnidge): This does not handle named functions which are
200 // inside of named functions, e.g. foo.bar.baz. 200 // inside of named functions, e.g. foo.bar.baz.
201 static Future<SourceLocation> _parseFunction(Debugger debugger, 201 static Future<DebuggerLocation> _parseFunction(Debugger debugger,
202 Match match) { 202 Match match) {
203 Isolate isolate = debugger.isolate; 203 Isolate isolate = debugger.isolate;
204 var base = match.group(1); 204 var base = match.group(1);
205 var qualifier = match.group(2); 205 var qualifier = match.group(2);
206 assert(base != null); 206 assert(base != null);
207 207
208 return _lookupClass(isolate, base).then((classes) { 208 return _lookupClass(isolate, base).then((classes) {
209 var functions = []; 209 var functions = [];
210 if (qualifier == null) { 210 if (qualifier == null) {
211 // Unqualified name is either a function or a constructor. 211 // Unqualified name is either a function or a constructor.
(...skipping 19 matching lines...) Expand all
231 } 231 }
232 } else { 232 } else {
233 if (functionName == function.name) { 233 if (functionName == function.name) {
234 functions.add(function); 234 functions.add(function);
235 } 235 }
236 } 236 }
237 } 237 }
238 } 238 }
239 } 239 }
240 if (functions.length == 0) { 240 if (functions.length == 0) {
241 return new SourceLocation.error( 241 return new DebuggerLocation.error(
242 "Function '${match.group(0)}' not found"); 242 "Function '${match.group(0)}' not found");
243 } else if (functions.length == 1) { 243 } else if (functions.length == 1) {
244 return new SourceLocation.func(functions[0]); 244 return new DebuggerLocation.func(functions[0]);
245 } else { 245 } else {
246 // TODO(turnidge): Allow the user to disambiguate. 246 // TODO(turnidge): Allow the user to disambiguate.
247 return new SourceLocation.error( 247 return new DebuggerLocation.error(
248 "Function '${match.group(0)}' is ambigous"); 248 "Function '${match.group(0)}' is ambigous");
249 } 249 }
250 return new SourceLocation.error('foo'); 250 return new DebuggerLocation.error('foo');
251 }); 251 });
252 } 252 }
253 253
254 static RegExp partialSourceLocMatcher = 254 static RegExp partialSourceLocMatcher =
255 new RegExp(r'^([^\d:]?[^:]+[:]?)?(\d+)?([:]\d+)?'); 255 new RegExp(r'^([^\d:]?[^:]+[:]?)?(\d+)?([:]\d+)?');
256 static RegExp partialFunctionMatcher = new RegExp(r'^([^.]*)([.][^.]*)?'); 256 static RegExp partialFunctionMatcher = new RegExp(r'^([^.]*)([.][^.]*)?');
257 257
258 /// Completes a partial source location description. 258 /// Completes a partial source location description.
259 static Future<List<String>> complete(Debugger debugger, String locDesc) { 259 static Future<List<String>> complete(Debugger debugger, String locDesc) {
260 List<Future<List<String>>> pending = []; 260 List<Future<List<String>>> pending = [];
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 return 'invalid source location (${errorMessage})'; 357 return 'invalid source location (${errorMessage})';
358 } 358 }
359 359
360 Script script; 360 Script script;
361 int line; 361 int line;
362 int col; 362 int col;
363 ServiceFunction function; 363 ServiceFunction function;
364 String errorMessage; 364 String errorMessage;
365 bool get valid => (errorMessage == null); 365 bool get valid => (errorMessage == null);
366 } 366 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/debugger.dart ('k') | runtime/observatory/lib/src/debugger/source_location.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698