| Index: runtime/observatory/lib/src/elements/script_inset.dart
|
| diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
|
| index a7223c8c93d5c6a9b545fcb994d461f6e88af6f2..8a9546740a599840b78565617ff376ce22b50198 100644
|
| --- a/runtime/observatory/lib/src/elements/script_inset.dart
|
| +++ b/runtime/observatory/lib/src/elements/script_inset.dart
|
| @@ -57,11 +57,15 @@ abstract class Annotation implements Comparable<Annotation> {
|
| int line;
|
| int columnStart;
|
| int columnStop;
|
| + int get priority;
|
|
|
| void applyStyleTo(element);
|
|
|
| int compareTo(Annotation other) {
|
| if (line == other.line) {
|
| + if (columnStart == other.columnStart) {
|
| + return priority.compareTo(other.priority);
|
| + }
|
| return columnStart.compareTo(other.columnStart);
|
| }
|
| return line.compareTo(other.line);
|
| @@ -100,6 +104,8 @@ abstract class Annotation implements Comparable<Annotation> {
|
| }
|
|
|
| class CurrentExecutionAnnotation extends Annotation {
|
| + int priority = 0; // highest priority.
|
| +
|
| void applyStyleTo(element) {
|
| if (element == null) {
|
| return; // TODO(rmacnak): Handling overlapping annotations.
|
| @@ -109,9 +115,40 @@ class CurrentExecutionAnnotation extends Annotation {
|
| }
|
| }
|
|
|
| +class BreakpointAnnotation extends Annotation {
|
| + Breakpoint bpt;
|
| + int priority = 1;
|
| +
|
| + BreakpointAnnotation(this.bpt) {
|
| + var script = bpt.location.script;
|
| + var pos = bpt.location.tokenPos;
|
| + line = script.tokenToLine(pos);
|
| + columnStart = script.tokenToCol(pos) - 1; // tokenToCol is 1-origin.
|
| + var length = script.guessTokenLength(line, columnStart);
|
| + if (length == null) {
|
| + length = 1;
|
| + }
|
| + columnStop = columnStart + length;
|
| + }
|
| +
|
| + void applyStyleTo(element) {
|
| + if (element == null) {
|
| + return; // TODO(rmacnak): Handling overlapping annotations.
|
| + }
|
| + var script = bpt.location.script;
|
| + var pos = bpt.location.tokenPos;
|
| + int line = script.tokenToLine(pos);
|
| + int column = script.tokenToCol(pos);
|
| + element.classes.add("breakAnnotation");
|
| + element.title = "Breakpoint ${bpt.number} at ${line}:${column}";
|
| + }
|
| +}
|
| +
|
| class LibraryAnnotation extends Annotation {
|
| Library target;
|
| String url;
|
| + int priority = 2;
|
| +
|
| LibraryAnnotation(this.target, this.url);
|
|
|
| void applyStyleTo(element) {
|
| @@ -126,6 +163,8 @@ class LibraryAnnotation extends Annotation {
|
| class PartAnnotation extends Annotation {
|
| Script part;
|
| String url;
|
| + int priority = 2;
|
| +
|
| PartAnnotation(this.part, this.url);
|
|
|
| void applyStyleTo(element) {
|
| @@ -139,6 +178,7 @@ class PartAnnotation extends Annotation {
|
|
|
| class LocalVariableAnnotation extends Annotation {
|
| final value;
|
| + int priority = 2;
|
|
|
| LocalVariableAnnotation(LocalVarLocation location, this.value) {
|
| line = location.line;
|
| @@ -157,6 +197,7 @@ class LocalVariableAnnotation extends Annotation {
|
|
|
| class CallSiteAnnotation extends Annotation {
|
| CallSite callSite;
|
| + int priority = 2;
|
|
|
| CallSiteAnnotation(this.callSite) {
|
| line = callSite.line;
|
| @@ -203,6 +244,8 @@ class CallSiteAnnotation extends Annotation {
|
|
|
| abstract class DeclarationAnnotation extends Annotation {
|
| String url;
|
| + int priority = 2;
|
| +
|
| DeclarationAnnotation(decl, this.url) {
|
| assert(decl.loaded);
|
| SourceLocation location = decl.location;
|
| @@ -326,7 +369,8 @@ class ScriptInsetElement extends ObservatoryElement {
|
| var annotations = [];
|
| var annotationsCursor;
|
|
|
| - StreamSubscription scriptChangeSubscription;
|
| + StreamSubscription _scriptChangeSubscription;
|
| + Future<StreamSubscription> _debugSubscriptionFuture;
|
|
|
| bool hasLoadedLibraryDeclarations = false;
|
|
|
| @@ -341,15 +385,45 @@ class ScriptInsetElement extends ObservatoryElement {
|
| }
|
| }
|
|
|
| + void attached() {
|
| + super.attached();
|
| + _debugSubscriptionFuture =
|
| + app.vm.listenEventStream(VM.kDebugStream, _onDebugEvent);
|
| + }
|
| +
|
| void detached() {
|
| - if (scriptChangeSubscription != null) {
|
| + cancelFutureSubscription(_debugSubscriptionFuture);
|
| + _debugSubscriptionFuture = null;
|
| + if (_scriptChangeSubscription != null) {
|
| // Don't leak. If only Dart and Javascript exposed weak references...
|
| - scriptChangeSubscription.cancel();
|
| - scriptChangeSubscription = null;
|
| + _scriptChangeSubscription.cancel();
|
| + _scriptChangeSubscription = null;
|
| }
|
| super.detached();
|
| }
|
|
|
| + void _onDebugEvent(event) {
|
| + if (script == null) {
|
| + return;
|
| + }
|
| + switch (event.kind) {
|
| + case ServiceEvent.kBreakpointAdded:
|
| + case ServiceEvent.kBreakpointResolved:
|
| + case ServiceEvent.kBreakpointRemoved:
|
| + var loc = event.breakpoint.location;
|
| + if (loc.script == script) {
|
| + int line = script.tokenToLine(loc.tokenPos);
|
| + if ((line >= _startLine) && (line <= _endLine)) {
|
| + _updateTask.queue();
|
| + }
|
| + }
|
| + break;
|
| + default:
|
| + // Ignore.
|
| + break;
|
| + }
|
| + }
|
| +
|
| void currentPosChanged(oldValue) {
|
| _updateTask.queue();
|
| _scrollToCurrentPos();
|
| @@ -407,8 +481,8 @@ class ScriptInsetElement extends ObservatoryElement {
|
| return;
|
| }
|
|
|
| - if (scriptChangeSubscription == null) {
|
| - scriptChangeSubscription = script.changes.listen((_) => update());
|
| + if (_scriptChangeSubscription == null) {
|
| + _scriptChangeSubscription = script.changes.listen((_) => update());
|
| }
|
|
|
| computeAnnotations();
|
| @@ -450,6 +524,7 @@ class ScriptInsetElement extends ObservatoryElement {
|
| annotations.clear();
|
|
|
| addCurrentExecutionAnnotation();
|
| + addBreakpointAnnotations();
|
|
|
| if (!inDebuggerContext && script.library != null) {
|
| if (hasLoadedLibraryDeclarations) {
|
| @@ -487,6 +562,19 @@ class ScriptInsetElement extends ObservatoryElement {
|
| }
|
| }
|
|
|
| + void addBreakpointAnnotations() {
|
| + for (var line = _startLine; line <= _endLine; line++) {
|
| + var bpts = script.getLine(line).breakpoints;
|
| + if (bpts != null) {
|
| + for (var bpt in bpts) {
|
| + if (bpt.location != null) {
|
| + annotations.add(new BreakpointAnnotation(bpt));
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| Future loadDeclarationsOfLibrary(Library lib) {
|
| return lib.load().then((lib) {
|
| var loads = [];
|
|
|