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

Unified Diff: runtime/observatory/lib/src/elements/script_inset.dart

Issue 1584173003: Use getSourceReport for coverage/callsites in Observatory. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: cleanups Created 4 years, 11 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 side-by-side diff with in-line comments
Download patch
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 47bbff7b4f3d4066834e0250192e0e19594d5546..bc5f25a426da5046d6aa57cfe3b01c4e736b8899 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -6,6 +6,7 @@ library script_inset_element;
import 'dart:async';
import 'dart:html';
+import 'dart:math';
import 'observatory_element.dart';
import 'service_ref.dart';
import 'package:observatory/service.dart';
@@ -244,7 +245,7 @@ class CallSiteAnnotation extends Annotation {
for (var entry in callSite.entries) {
var r = row();
- r.append(cell(serviceRef(entry.receiverContainer)));
+ r.append(cell(serviceRef(entry.receiver)));
r.append(cell(entry.count.toString()));
r.append(cell(serviceRef(entry.target)));
details.append(r);
@@ -374,16 +375,23 @@ class ScriptInsetElement extends ObservatoryElement {
@published bool inDebuggerContext = false;
@published ObservableList variables;
+ @published Element scroller;
+ RefreshButtonElement _refreshButton;
+
int _currentLine;
int _currentCol;
int _startLine;
int _endLine;
+ Map<int, List<ServiceMap>> _rangeMap = {};
+ Set _callSites = new Set<CallSite>();
+
var annotations = [];
var annotationsCursor;
StreamSubscription _scriptChangeSubscription;
Future<StreamSubscription> _debugSubscriptionFuture;
+ StreamSubscription _scrollSubscription;
bool hasLoadedLibraryDeclarations = false;
@@ -402,11 +410,20 @@ class ScriptInsetElement extends ObservatoryElement {
super.attached();
_debugSubscriptionFuture =
app.vm.listenEventStream(VM.kDebugStream, _onDebugEvent);
+ if (scroller != null) {
+ _scrollSubscription = scroller.onScroll.listen(_onScroll);
+ } else {
+ _scrollSubscription = window.onScroll.listen(_onScroll);
+ }
}
void detached() {
cancelFutureSubscription(_debugSubscriptionFuture);
_debugSubscriptionFuture = null;
+ if (_scrollSubscription != null) {
+ _scrollSubscription.cancel();
+ _scrollSubscription = null;
+ }
if (_scriptChangeSubscription != null) {
// Don't leak. If only Dart and Javascript exposed weak references...
_scriptChangeSubscription.cancel();
@@ -415,6 +432,14 @@ class ScriptInsetElement extends ObservatoryElement {
super.detached();
}
+ void _onScroll(event) {
+ var currentTop = _refreshButton.style.top;
+ var newTop = _refreshButtonTop();
+ if (currentTop != newTop) {
+ _refreshButton.style.top = '${newTop}px';
+ }
+ }
+
void _onDebugEvent(event) {
if (script == null) {
return;
@@ -486,11 +511,51 @@ class ScriptInsetElement extends ObservatoryElement {
element.title = "Line did execute";
return element;
}
+ Element hitsCompiled(Element element) {
+ element.classes.add('hitsCompiled');
+ element.title = "Line in compiled function";
+ return element;
+ }
+ Element hitsNotCompiled(Element element) {
+ element.classes.add('hitsNotCompiled');
+ element.title = "Line in uncompiled function";
+ return element;
+ }
Element container;
+ Future _refresh() async {
+ await update();
+ }
+
+ // Build _rangeMap and _callSites from a source report.
+ Future _refreshSourceReport() async {
+ var sourceReport = await script.isolate.getSourceReport(
+ [Isolate.kCallSitesReport], script, startPos, endPos);
+ _rangeMap.clear();
+ _callSites.clear();
+ for (var range in sourceReport['ranges']) {
+ int startLine = script.tokenToLine(range['startPos']);
+ int endLine = script.tokenToLine(range['endPos']);
+ for (var line = startLine; line <= endLine; line++) {
+ var rangeList = _rangeMap[line];
+ if (rangeList == null) {
+ _rangeMap[line] = [range];
+ } else {
+ rangeList.add(range);
+ }
+ }
+ var rangeCallSites = range['callSites'];
+ if (rangeCallSites != null) {
+ for (var callSiteMap in rangeCallSites) {
+ _callSites.add(new CallSite.fromMap(callSiteMap, script));
+ }
+ }
+ }
+ }
+
Task _updateTask;
- void update() {
+ Future update() async {
assert(_updateTask != null);
if (script == null) {
// We may have previously had a script.
@@ -500,13 +565,12 @@ class ScriptInsetElement extends ObservatoryElement {
return;
}
if (!script.loaded) {
- script.load().then((_) => update());
- return;
+ await script.load();
}
-
if (_scriptChangeSubscription == null) {
_scriptChangeSubscription = script.changes.listen((_) => update());
}
+ await _refreshSourceReport();
computeAnnotations();
@@ -803,7 +867,7 @@ class ScriptInsetElement extends ObservatoryElement {
}
void addCallSiteAnnotations() {
- for (var callSite in script.callSites) {
+ for (var callSite in _callSites) {
annotations.add(new CallSiteAnnotation(callSite));
}
}
@@ -828,10 +892,35 @@ class ScriptInsetElement extends ObservatoryElement {
}
}
+ int _refreshButtonTop() {
+ if (_refreshButton == null) {
+ return 5;
+ }
+ const padding = 5;
+ const navbarHeight = 40;
Cutch 2016/01/14 21:37:40 The navbarHeight constant is hardcoded in two plac
+ var rect = getBoundingClientRect();
+ var buttonHeight = _refreshButton.clientHeight;
+ return min(max(0, navbarHeight - rect.top) + padding,
+ rect.height - (buttonHeight + padding));
+ }
+
+ RefreshButtonElement _newRefreshButton() {
+ var button = new Element.tag('refresh-button');
+ button.style.position = 'absolute';
+ button.style.display = 'inline-block';
+ button.style.top = '${_refreshButtonTop()}px';
+ button.style.right = '5px';
+ button.callback = _refresh;
+ return button;
+ }
+
Element linesTable() {
var table = new DivElement();
table.classes.add("sourceTable");
+ _refreshButton = _newRefreshButton();
+ table.append(_refreshButton);
+
if (_startLine == null || _endLine == null) {
return table;
}
@@ -973,17 +1062,48 @@ class ScriptInsetElement extends ObservatoryElement {
var lineNumber = line == null ? "..." : line.line;
var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
e.classes.add('noCopy');
-
if (lineNumber == _currentLine) {
hitsCurrent(e);
- } else if ((line == null) || (line.hits == null)) {
+ return e;
+ }
+ var ranges = _rangeMap[lineNumber];
+ if ((ranges == null) || ranges.isEmpty) {
+ // This line is not code.
hitsUnknown(e);
- } else if (line.hits == 0) {
+ return e;
+ }
+ bool compiled = false;
+ bool hasCallInfo = false;
+ bool executed = false;
+ for (var range in ranges) {
+ if (range['compiled']) {
+ compiled = true;
+ for (var callSite in range['callSites']) {
+ var callLine = line.script.tokenToLine(callSite['tokenPos']);
+ if (lineNumber == callLine) {
+ // The call site is on the current line.
+ hasCallInfo = true;
+ for (var cacheEntry in callSite['cacheEntries']) {
+ if (cacheEntry['count'] > 0) {
+ // If any call site on the line has been executed, we
+ // mark the line as executed.
+ executed = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (executed) {
+ hitsExecuted(e);
+ } else if (hasCallInfo) {
hitsNotExecuted(e);
+ } else if (compiled) {
+ hitsCompiled(e);
} else {
- hitsExecuted(e);
+ hitsNotCompiled(e);
}
-
return e;
}
@@ -1036,6 +1156,26 @@ class ScriptInsetElement extends ObservatoryElement {
}
}
+@CustomTag('refresh-button')
+class RefreshButtonElement extends PolymerElement {
+ RefreshButtonElement.created() : super.created();
+
+ @published var callback = null;
+ bool busy = false;
+
+ Future buttonClick(var event, var b, var c) async {
+ if (busy) {
+ return;
+ }
+ busy = true;
+ if (callback != null) {
+ await callback();
+ }
+ busy = false;
+ }
+}
+
+
@CustomTag('source-inset')
class SourceInsetElement extends PolymerElement {
SourceInsetElement.created() : super.created();
@@ -1045,4 +1185,5 @@ class SourceInsetElement extends PolymerElement {
@published int currentPos;
@published bool inDebuggerContext = false;
@published ObservableList variables;
+ @published Element scroller;
}

Powered by Google App Engine
This is Rietveld 408576698