| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |