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

Unified Diff: pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart

Issue 16964008: Code coverage, something is working now. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixes for Phil review comments Created 7 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 side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart
diff --git a/pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart b/pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart
new file mode 100644
index 0000000000000000000000000000000000000000..5507c9be258ac52c1ab71ff4f9e6650830cef425
--- /dev/null
+++ b/pkg/analyzer_experimental/lib/src/services/runtime/coverage/models.dart
@@ -0,0 +1,167 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// A library with code coverage models.
+library runtime.coverage.model;
+
+import 'dart:collection' show SplayTreeMap;
+
+import 'package:analyzer_experimental/src/generated/source.dart' show Source, SourceRange;
+import 'package:analyzer_experimental/src/generated/ast.dart' show ASTNode;
+
+import 'utils.dart';
+
+
+/// Contains information about the application.
+class AppInfo {
+ final List<NodeInfo> nodeStack = new List<NodeInfo>();
Bob Nystrom 2013/06/17 21:30:12 final nodeStack = <NodeInfo>[]; Ditto for other f
scheglov 2013/06/17 22:30:57 For all fields or for final fields with initialize
Bob Nystrom 2013/06/17 22:44:41 Just ones with initializers. If they aren't initia
+ final List<UnitInfo> units = new List<UnitInfo>();
+ final Map<String, UnitInfo> pathToFile = new Map<String, UnitInfo>();
+ NodeInfo currentNode = null;
+ int nextId = 0;
+
+ void enterUnit(String path, String content) {
+ var unit = new UnitInfo(this, path, content);
+ units.add(unit);
+ currentNode = unit;
+ }
+
+ void enter(String kind, String name) {
+ nodeStack.add(currentNode);
+ currentNode = new NodeInfo(this, currentNode, kind, name);
+ }
+
+ void leave() {
+ currentNode = nodeStack.removeLast();
+ }
+
+ int addNode(ASTNode node) {
+ return currentNode.addNode(node);
+ }
+
+ void print(StringSink sink, Set<int> executedIds) {
Bob Nystrom 2013/06/17 21:30:12 Calling a method "print" is probably asking for tr
scheglov 2013/06/17 22:30:57 Ah... yes. Renamed to 'write'.
+ sink.writeln('{');
+ units.asMap().forEach((int i, UnitInfo unit) {
+ if (i != 0) sink.writeln(',');
+ unit.print(sink, executedIds, ' ');
+ });
+ sink.writeln();
+ sink.writeln('}');
+ }
+}
+
+/// Information about some node - unit, class, method, function.
+class NodeInfo {
+ final AppInfo appInfo;
+ final NodeInfo parent;
+ final String kind;
+ final String name;
+ final Map<int, SourceRange> idToRange = new SplayTreeMap<int, SourceRange>();
+ final List<NodeInfo> children = <NodeInfo> [];
Bob Nystrom 2013/06/17 21:30:12 No space between > and [
scheglov 2013/06/17 22:30:57 Done.
+
+ NodeInfo(this.appInfo, this.parent, this.kind, this.name) {
+ if (parent != null) {
+ parent.children.add(this);
+ }
+ }
+
+ int addNode(ASTNode node) {
+ var id = appInfo.nextId++;
+ var range = new SourceRange(node.offset, node.length);
+ idToRange[id] = range;
+ return id;
+ }
+
+ void print(StringSink sink, Set<int> executedIds, String prefix) {
+ sink.writeln('$prefix"$name": {');
+ // Kind.
+ sink.writeln('$prefix "kind": "$kind",');
+ // Print children.
+ if (children.isNotEmpty) {
Bob Nystrom 2013/06/17 21:30:12 Today I learned Iterable has isNotEmpty! :)
+ sink.writeln('$prefix "children": {');
+ children.asMap().forEach((int i, NodeInfo child) {
scheglov 2013/06/17 22:30:57 Is it recommended to have type annotations for clo
Bob Nystrom 2013/06/17 22:44:41 The style guide says: "AVOID annotating types on f
scheglov 2013/06/18 06:11:04 Done.
+ if (i != 0) sink.writeln(',');
+ children[i].print(sink, executedIds, '$prefix ');
+ });
Bob Nystrom 2013/06/17 21:30:12 Clever! You could also try: children.fold(null, (
scheglov 2013/06/17 22:30:57 More lines of code - I have to add "return" :-(
+ sink.writeln();
+ sink.writeln('$prefix }');
+ }
+ // Print source and line ranges.
+ if (children.isEmpty) {
+ sink.write('${prefix} "ranges": [');
+ var rangePrinter = new RangePrinter(unit, sink, executedIds);
+ idToRange.forEach(rangePrinter.handle);
Bob Nystrom 2013/06/17 21:30:12 Nice.
+ rangePrinter.printRange();
+ sink.writeln(']');
+ }
+ // Close this node.
+ sink.write('$prefix}');
+ }
+
+ UnitInfo get unit => parent.unit;
+}
+
+/// Helper for printing merged source/line intervals.
+class RangePrinter {
+ final UnitInfo unit;
+ final StringSink sink;
+ final Set<int> executedIds;
+
+ bool first = true;
+ int startId = -1;
+ int startOffset = -1;
+ int endId = -1;
+ int endOffset = -1;
+
+ RangePrinter(this.unit, this.sink, this.executedIds);
+
+ handle(int id, SourceRange range) {
+ if (executedIds.contains(id)) {
+ printRange();
+ } else {
+ if (endId == id - 1) {
+ endId = id;
+ endOffset = range.end;
+ } else {
+ startId = id;
+ endId = id;
+ startOffset = range.offset;
+ endOffset = range.end;
+ }
+ }
+ }
+
+ void printRange() {
+ if (endId == -1) return;
+ printSeparator();
+ var startLine = unit.getLine(startOffset);
+ var endLine = unit.getLine(endOffset);
+ sink.write('$startOffset,$endOffset,$startLine,$endLine');
+ startId = startOffset = startLine = -1;
+ endId = endOffset = endLine = -1;
+ }
+
+ void printSeparator() {
+ if (first) {
+ first = false;
+ } else {
+ sink.write(', ');
+ }
+ }
+}
+
+/// Containts information about the single unit of the application.
Bob Nystrom 2013/06/17 21:30:12 Containts -> Contains.
scheglov 2013/06/17 22:30:57 Done.
+class UnitInfo extends NodeInfo {
+ List<int> lineOffsets;
+
+ UnitInfo(AppInfo appInfo, String path, String content) : super(appInfo, null, 'unit', path) {
Bob Nystrom 2013/06/17 21:30:12 Move ": super..." to the next line.
scheglov 2013/06/17 22:30:57 Done.
+ lineOffsets = getLineOffsets(content);
+ }
+
+ UnitInfo get unit => this;
+
+ int getLine(int offset) {
+ return binarySearch(lineOffsets, (x) => x >= offset);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698