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

Side by Side Diff: runtime/observatory/lib/src/elements/script_inset.dart

Issue 1305413004: Add source annotations for breakpoints. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: code review Created 5 years, 3 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
« no previous file with comments | « no previous file | runtime/observatory/lib/src/elements/script_inset.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 library script_inset_element; 5 library script_inset_element;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:html'; 8 import 'dart:html';
9 import 'observatory_element.dart'; 9 import 'observatory_element.dart';
10 import 'service_ref.dart'; 10 import 'service_ref.dart';
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 a.text = content.text; 50 a.text = content.text;
51 content.text = ''; 51 content.text = '';
52 content.append(a); 52 content.append(a);
53 } 53 }
54 54
55 55
56 abstract class Annotation implements Comparable<Annotation> { 56 abstract class Annotation implements Comparable<Annotation> {
57 int line; 57 int line;
58 int columnStart; 58 int columnStart;
59 int columnStop; 59 int columnStop;
60 int get priority;
60 61
61 void applyStyleTo(element); 62 void applyStyleTo(element);
62 63
63 int compareTo(Annotation other) { 64 int compareTo(Annotation other) {
64 if (line == other.line) { 65 if (line == other.line) {
66 if (columnStart == other.columnStart) {
67 return priority.compareTo(other.priority);
68 }
65 return columnStart.compareTo(other.columnStart); 69 return columnStart.compareTo(other.columnStart);
66 } 70 }
67 return line.compareTo(other.line); 71 return line.compareTo(other.line);
68 } 72 }
69 73
70 Element table() { 74 Element table() {
71 var e = new DivElement(); 75 var e = new DivElement();
72 e.style.display = "table"; 76 e.style.display = "table";
73 e.style.color = "#333"; 77 e.style.color = "#333";
74 e.style.font = "400 14px 'Montserrat', sans-serif"; 78 e.style.font = "400 14px 'Montserrat', sans-serif";
(...skipping 18 matching lines...) Expand all
93 } 97 }
94 98
95 Element serviceRef(object) { 99 Element serviceRef(object) {
96 AnyServiceRefElement e = new Element.tag("any-service-ref"); 100 AnyServiceRefElement e = new Element.tag("any-service-ref");
97 e.ref = object; 101 e.ref = object;
98 return e; 102 return e;
99 } 103 }
100 } 104 }
101 105
102 class CurrentExecutionAnnotation extends Annotation { 106 class CurrentExecutionAnnotation extends Annotation {
107 int priority = 0; // highest priority.
108
103 void applyStyleTo(element) { 109 void applyStyleTo(element) {
104 if (element == null) { 110 if (element == null) {
105 return; // TODO(rmacnak): Handling overlapping annotations. 111 return; // TODO(rmacnak): Handling overlapping annotations.
106 } 112 }
107 element.classes.add("currentCol"); 113 element.classes.add("currentCol");
108 element.title = "Current execution"; 114 element.title = "Current execution";
109 } 115 }
110 } 116 }
111 117
118 class BreakpointAnnotation extends Annotation {
119 Breakpoint bpt;
120 int priority = 1;
121
122 BreakpointAnnotation(this.bpt) {
123 var script = bpt.location.script;
124 var pos = bpt.location.tokenPos;
125 line = script.tokenToLine(pos);
126 columnStart = script.tokenToCol(pos) - 1; // tokenToCol is 1-origin.
127 var length = script.guessTokenLength(line, columnStart);
128 if (length == null) {
129 length = 1;
130 }
131 columnStop = columnStart + length;
132 }
133
134 void applyStyleTo(element) {
135 if (element == null) {
136 return; // TODO(rmacnak): Handling overlapping annotations.
137 }
138 var script = bpt.location.script;
139 var pos = bpt.location.tokenPos;
140 int line = script.tokenToLine(pos);
141 int column = script.tokenToCol(pos);
142 element.classes.add("breakAnnotation");
143 element.title = "Breakpoint ${bpt.number} at ${line}:${column}";
144 }
145 }
146
112 class LibraryAnnotation extends Annotation { 147 class LibraryAnnotation extends Annotation {
113 Library target; 148 Library target;
114 String url; 149 String url;
150 int priority = 2;
151
115 LibraryAnnotation(this.target, this.url); 152 LibraryAnnotation(this.target, this.url);
116 153
117 void applyStyleTo(element) { 154 void applyStyleTo(element) {
118 if (element == null) { 155 if (element == null) {
119 return; // TODO(rmacnak): Handling overlapping annotations. 156 return; // TODO(rmacnak): Handling overlapping annotations.
120 } 157 }
121 element.title = "library ${target.uri}"; 158 element.title = "library ${target.uri}";
122 addLink(element, url); 159 addLink(element, url);
123 } 160 }
124 } 161 }
125 162
126 class PartAnnotation extends Annotation { 163 class PartAnnotation extends Annotation {
127 Script part; 164 Script part;
128 String url; 165 String url;
166 int priority = 2;
167
129 PartAnnotation(this.part, this.url); 168 PartAnnotation(this.part, this.url);
130 169
131 void applyStyleTo(element) { 170 void applyStyleTo(element) {
132 if (element == null) { 171 if (element == null) {
133 return; // TODO(rmacnak): Handling overlapping annotations. 172 return; // TODO(rmacnak): Handling overlapping annotations.
134 } 173 }
135 element.title = "script ${part.uri}"; 174 element.title = "script ${part.uri}";
136 addLink(element, url); 175 addLink(element, url);
137 } 176 }
138 } 177 }
139 178
140 class LocalVariableAnnotation extends Annotation { 179 class LocalVariableAnnotation extends Annotation {
141 final value; 180 final value;
181 int priority = 2;
142 182
143 LocalVariableAnnotation(LocalVarLocation location, this.value) { 183 LocalVariableAnnotation(LocalVarLocation location, this.value) {
144 line = location.line; 184 line = location.line;
145 columnStart = location.column; 185 columnStart = location.column;
146 columnStop = location.endColumn; 186 columnStop = location.endColumn;
147 } 187 }
148 188
149 void applyStyleTo(element) { 189 void applyStyleTo(element) {
150 if (element == null) { 190 if (element == null) {
151 return; // TODO(rmacnak): Handling overlapping annotations. 191 return; // TODO(rmacnak): Handling overlapping annotations.
152 } 192 }
153 element.style.fontWeight = "bold"; 193 element.style.fontWeight = "bold";
154 element.title = "${value.shortName}"; 194 element.title = "${value.shortName}";
155 } 195 }
156 } 196 }
157 197
158 class CallSiteAnnotation extends Annotation { 198 class CallSiteAnnotation extends Annotation {
159 CallSite callSite; 199 CallSite callSite;
200 int priority = 2;
160 201
161 CallSiteAnnotation(this.callSite) { 202 CallSiteAnnotation(this.callSite) {
162 line = callSite.line; 203 line = callSite.line;
163 columnStart = callSite.column - 1; // Call site is 1-origin. 204 columnStart = callSite.column - 1; // Call site is 1-origin.
164 var tokenLength = callSite.script.guessTokenLength(line, columnStart); 205 var tokenLength = callSite.script.guessTokenLength(line, columnStart);
165 if (tokenLength == null) { 206 if (tokenLength == null) {
166 tokenLength = callSite.name.length; // Approximate. 207 tokenLength = callSite.name.length; // Approximate.
167 if (callSite.name.startsWith("get:") || 208 if (callSite.name.startsWith("get:") ||
168 callSite.name.startsWith("set:")) tokenLength -= 4; 209 callSite.name.startsWith("set:")) tokenLength -= 4;
169 } 210 }
(...skipping 26 matching lines...) Expand all
196 details.append(r); 237 details.append(r);
197 } 238 }
198 } 239 }
199 return details; 240 return details;
200 }); 241 });
201 } 242 }
202 } 243 }
203 244
204 abstract class DeclarationAnnotation extends Annotation { 245 abstract class DeclarationAnnotation extends Annotation {
205 String url; 246 String url;
247 int priority = 2;
248
206 DeclarationAnnotation(decl, this.url) { 249 DeclarationAnnotation(decl, this.url) {
207 assert(decl.loaded); 250 assert(decl.loaded);
208 SourceLocation location = decl.location; 251 SourceLocation location = decl.location;
209 if (location == null) { 252 if (location == null) {
210 line = 0; 253 line = 0;
211 columnStart = 0; 254 columnStart = 0;
212 columnStop = 0; 255 columnStop = 0;
213 return; 256 return;
214 } 257 }
215 258
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 @published ObservableList variables; 362 @published ObservableList variables;
320 363
321 int _currentLine; 364 int _currentLine;
322 int _currentCol; 365 int _currentCol;
323 int _startLine; 366 int _startLine;
324 int _endLine; 367 int _endLine;
325 368
326 var annotations = []; 369 var annotations = [];
327 var annotationsCursor; 370 var annotationsCursor;
328 371
329 StreamSubscription scriptChangeSubscription; 372 StreamSubscription _scriptChangeSubscription;
373 Future<StreamSubscription> _debugSubscriptionFuture;
330 374
331 bool hasLoadedLibraryDeclarations = false; 375 bool hasLoadedLibraryDeclarations = false;
332 376
333 String makeLineId(int line) { 377 String makeLineId(int line) {
334 return 'line-$line'; 378 return 'line-$line';
335 } 379 }
336 380
337 void _scrollToCurrentPos() { 381 void _scrollToCurrentPos() {
338 var line = shadowRoot.getElementById(makeLineId(_currentLine)); 382 var line = shadowRoot.getElementById(makeLineId(_currentLine));
339 if (line != null) { 383 if (line != null) {
340 line.scrollIntoView(); 384 line.scrollIntoView();
341 } 385 }
342 } 386 }
343 387
388 void attached() {
389 super.attached();
390 _debugSubscriptionFuture =
391 app.vm.listenEventStream(VM.kDebugStream, _onDebugEvent);
392 }
393
344 void detached() { 394 void detached() {
345 if (scriptChangeSubscription != null) { 395 cancelFutureSubscription(_debugSubscriptionFuture);
396 _debugSubscriptionFuture = null;
397 if (_scriptChangeSubscription != null) {
346 // Don't leak. If only Dart and Javascript exposed weak references... 398 // Don't leak. If only Dart and Javascript exposed weak references...
347 scriptChangeSubscription.cancel(); 399 _scriptChangeSubscription.cancel();
348 scriptChangeSubscription = null; 400 _scriptChangeSubscription = null;
349 } 401 }
350 super.detached(); 402 super.detached();
351 } 403 }
352 404
405 void _onDebugEvent(event) {
406 if (script == null) {
407 return;
408 }
409 switch (event.kind) {
410 case ServiceEvent.kBreakpointAdded:
411 case ServiceEvent.kBreakpointResolved:
412 case ServiceEvent.kBreakpointRemoved:
413 var loc = event.breakpoint.location;
414 if (loc.script == script) {
415 int line = script.tokenToLine(loc.tokenPos);
416 if ((line >= _startLine) && (line <= _endLine)) {
417 _updateTask.queue();
418 }
419 }
420 break;
421 default:
422 // Ignore.
423 break;
424 }
425 }
426
353 void currentPosChanged(oldValue) { 427 void currentPosChanged(oldValue) {
354 _updateTask.queue(); 428 _updateTask.queue();
355 _scrollToCurrentPos(); 429 _scrollToCurrentPos();
356 } 430 }
357 431
358 void startPosChanged(oldValue) { 432 void startPosChanged(oldValue) {
359 _updateTask.queue(); 433 _updateTask.queue();
360 } 434 }
361 435
362 void endPosChanged(oldValue) { 436 void endPosChanged(oldValue) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 if (container != null) { 474 if (container != null) {
401 container.children.clear(); 475 container.children.clear();
402 } 476 }
403 return; 477 return;
404 } 478 }
405 if (!script.loaded) { 479 if (!script.loaded) {
406 script.load().then((_) => update()); 480 script.load().then((_) => update());
407 return; 481 return;
408 } 482 }
409 483
410 if (scriptChangeSubscription == null) { 484 if (_scriptChangeSubscription == null) {
411 scriptChangeSubscription = script.changes.listen((_) => update()); 485 _scriptChangeSubscription = script.changes.listen((_) => update());
412 } 486 }
413 487
414 computeAnnotations(); 488 computeAnnotations();
415 489
416 var table = linesTable(); 490 var table = linesTable();
417 var firstBuild = false; 491 var firstBuild = false;
418 if (container == null) { 492 if (container == null) {
419 // Indirect to avoid deleting the style element. 493 // Indirect to avoid deleting the style element.
420 container = new DivElement(); 494 container = new DivElement();
421 shadowRoot.append(container); 495 shadowRoot.append(container);
(...skipping 21 matching lines...) Expand all
443 _currentCol--; // make this 0-based. 517 _currentCol--; // make this 0-based.
444 } 518 }
445 519
446 _endLine = (endPos != null 520 _endLine = (endPos != null
447 ? script.tokenToLine(endPos) 521 ? script.tokenToLine(endPos)
448 : script.lines.length + script.lineOffset); 522 : script.lines.length + script.lineOffset);
449 523
450 annotations.clear(); 524 annotations.clear();
451 525
452 addCurrentExecutionAnnotation(); 526 addCurrentExecutionAnnotation();
527 addBreakpointAnnotations();
453 528
454 if (!inDebuggerContext && script.library != null) { 529 if (!inDebuggerContext && script.library != null) {
455 if (hasLoadedLibraryDeclarations) { 530 if (hasLoadedLibraryDeclarations) {
456 addLibraryAnnotations(); 531 addLibraryAnnotations();
457 addDependencyAnnotations(); 532 addDependencyAnnotations();
458 addPartAnnotations(); 533 addPartAnnotations();
459 addClassAnnotations(); 534 addClassAnnotations();
460 addFieldAnnotations(); 535 addFieldAnnotations();
461 addFunctionAnnotations(); 536 addFunctionAnnotations();
462 addCallSiteAnnotations(); 537 addCallSiteAnnotations();
(...skipping 17 matching lines...) Expand all
480 a.columnStart = _currentCol; 555 a.columnStart = _currentCol;
481 var length = script.guessTokenLength(_currentLine, _currentCol); 556 var length = script.guessTokenLength(_currentLine, _currentCol);
482 if (length == null) { 557 if (length == null) {
483 length = 1; 558 length = 1;
484 } 559 }
485 a.columnStop = _currentCol + length; 560 a.columnStop = _currentCol + length;
486 annotations.add(a); 561 annotations.add(a);
487 } 562 }
488 } 563 }
489 564
565 void addBreakpointAnnotations() {
566 for (var line = _startLine; line <= _endLine; line++) {
567 var bpts = script.getLine(line).breakpoints;
568 if (bpts != null) {
569 for (var bpt in bpts) {
570 if (bpt.location != null) {
571 annotations.add(new BreakpointAnnotation(bpt));
572 }
573 }
574 }
575 }
576 }
577
490 Future loadDeclarationsOfLibrary(Library lib) { 578 Future loadDeclarationsOfLibrary(Library lib) {
491 return lib.load().then((lib) { 579 return lib.load().then((lib) {
492 var loads = []; 580 var loads = [];
493 for (var func in lib.functions) { 581 for (var func in lib.functions) {
494 loads.add(func.load()); 582 loads.add(func.load());
495 } 583 }
496 for (var field in lib.variables) { 584 for (var field in lib.variables) {
497 loads.add(field.load()); 585 loads.add(field.load());
498 } 586 }
499 for (var cls in lib.classes) { 587 for (var cls in lib.classes) {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 class SourceInsetElement extends PolymerElement { 994 class SourceInsetElement extends PolymerElement {
907 SourceInsetElement.created() : super.created(); 995 SourceInsetElement.created() : super.created();
908 996
909 @published SourceLocation location; 997 @published SourceLocation location;
910 @published String height = null; 998 @published String height = null;
911 @published int currentPos; 999 @published int currentPos;
912 @published bool inDebuggerContext = false; 1000 @published bool inDebuggerContext = false;
913 @published ObservableList variables; 1001 @published ObservableList variables;
914 } 1002 }
915 1003
OLDNEW
« no previous file with comments | « no previous file | runtime/observatory/lib/src/elements/script_inset.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698