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

Side by Side Diff: pkg/compiler/lib/src/io/position_information.dart

Issue 1678043003: Add Dart code to diff_view (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Cleanup Created 4 years, 10 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// Source information system mapping that attempts a semantic mapping between 5 /// Source information system mapping that attempts a semantic mapping between
6 /// offsets of JavaScript code points to offsets of Dart code points. 6 /// offsets of JavaScript code points to offsets of Dart code points.
7 7
8 library dart2js.source_information.position; 8 library dart2js.source_information.position;
9 9
10 import '../common.dart'; 10 import '../common.dart';
11 import '../elements/elements.dart' show 11 import '../elements/elements.dart' show
12 AstElement, 12 AstElement,
13 FieldElement,
13 LocalElement; 14 LocalElement;
14 import '../js/js.dart' as js; 15 import '../js/js.dart' as js;
15 import '../js/js_source_mapping.dart'; 16 import '../js/js_source_mapping.dart';
16 import '../js/js_debug.dart'; 17 import '../js/js_debug.dart';
17 import '../tree/tree.dart' show 18 import '../tree/tree.dart' show
19 FunctionExpression,
18 Node, 20 Node,
19 Send; 21 Send;
20 22
21 import 'code_output.dart' show 23 import 'code_output.dart' show
22 CodeBuffer; 24 CodeBuffer;
23 import 'source_file.dart'; 25 import 'source_file.dart';
24 import 'source_information.dart'; 26 import 'source_information.dart';
25 27
26 /// [SourceInformation] that consists of an offset position into the source 28 /// [SourceInformation] that consists of an offset position into the source
27 /// code. 29 /// code.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 List<SourceLocation> get sourceLocations => const <SourceLocation>[]; 142 List<SourceLocation> get sourceLocations => const <SourceLocation>[];
141 143
142 @override 144 @override
143 SourceSpan get sourceSpan => new SourceSpan(null, null, null); 145 SourceSpan get sourceSpan => new SourceSpan(null, null, null);
144 } 146 }
145 147
146 /// [SourceInformationBuilder] that generates [PositionSourceInformation]. 148 /// [SourceInformationBuilder] that generates [PositionSourceInformation].
147 class PositionSourceInformationBuilder implements SourceInformationBuilder { 149 class PositionSourceInformationBuilder implements SourceInformationBuilder {
148 final SourceFile sourceFile; 150 final SourceFile sourceFile;
149 final String name; 151 final String name;
152 final AstElement element;
150 153
151 PositionSourceInformationBuilder(AstElement element) 154 PositionSourceInformationBuilder(AstElement element)
152 : sourceFile = element.implementation.compilationUnit.script.file, 155 : this.element = element,
156 sourceFile = element.implementation.compilationUnit.script.file,
153 name = computeElementNameForSourceMaps(element); 157 name = computeElementNameForSourceMaps(element);
154 158
155 SourceInformation buildDeclaration(AstElement element) { 159 SourceInformation buildDeclaration(AstElement element) {
156 if (element.isSynthesized) { 160 if (element.isSynthesized) {
157 return new PositionSourceInformation( 161 return new PositionSourceInformation(
158 new OffsetSourceLocation( 162 new OffsetSourceLocation(
159 sourceFile, element.position.charOffset, name)); 163 sourceFile, element.position.charOffset, name));
160 } else { 164 } else {
161 return new PositionSourceInformation( 165 return new PositionSourceInformation(
162 null, 166 null,
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 @override 238 @override
235 SourceInformation buildIf(Node node) => buildBegin(node); 239 SourceInformation buildIf(Node node) => buildBegin(node);
236 240
237 @override 241 @override
238 SourceInformation buildThrow(Node node) => buildBegin(node); 242 SourceInformation buildThrow(Node node) => buildBegin(node);
239 243
240 @override 244 @override
241 SourceInformation buildAssignment(Node node) => buildBegin(node); 245 SourceInformation buildAssignment(Node node) => buildBegin(node);
242 246
243 @override 247 @override
248 SourceInformation buildVariableDeclaration() {
249 if (element.hasNode) {
250 Node node = element.node;
251 FunctionExpression functionExpression = node.asFunctionExpression();
252 if (functionExpression != null) {
Siggi Cherem (dart-lang) 2016/02/08 22:31:53 nit: I'd remove the call to `asFunctionExpression`
Johnni Winther 2016/02/10 09:19:27 Done for FunctionExpression. Type promotion is not
253 return buildBegin(functionExpression.body);
254 } else {
255 if (element.isField) {
256 FieldElement field = element;
257 if (field.initializer != null) {
258 return buildBegin(field.initializer);
259 }
260 }
261 // TODO(johnniwinther): Are there other cases?
262 }
263 }
264 return null;
265 }
266
267 @override
244 SourceInformationBuilder forContext(AstElement element) { 268 SourceInformationBuilder forContext(AstElement element) {
245 return new PositionSourceInformationBuilder(element); 269 return new PositionSourceInformationBuilder(element);
246 } 270 }
247 } 271 }
248 272
249 /// The start, end and closing offsets for a [js.Node]. 273 /// The start, end and closing offsets for a [js.Node].
250 class CodePosition { 274 class CodePosition {
251 final int startPosition; 275 final int startPosition;
252 final int endPosition; 276 final int endPosition;
253 final int closingPosition; 277 final int closingPosition;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 @override 426 @override
403 void onPositions(js.Node node, 427 void onPositions(js.Node node,
404 int startPosition, 428 int startPosition,
405 int endPosition, 429 int endPosition,
406 int closingPosition) { 430 int closingPosition) {
407 codePositionRecorder.registerPositions( 431 codePositionRecorder.registerPositions(
408 node, startPosition, endPosition, closingPosition); 432 node, startPosition, endPosition, closingPosition);
409 } 433 }
410 } 434 }
411 435
436 /// Visitor that computes [SourceInformation] for a [js.Node] using information
437 /// attached to the node itself or alternatively from child nodes.
438 class NodeSourceInformation extends js.BaseVisitor<SourceInformation> {
439 const NodeSourceInformation();
440
441 SourceInformation visit(js.Node node) => node?.accept(this);
442
443 @override
444 SourceInformation visitNode(js.Node node) => node.sourceInformation;
445
446 @override
447 SourceInformation visitExpressionStatement(js.ExpressionStatement node) {
448 if (node.sourceInformation != null) {
449 return node.sourceInformation;
450 }
451 return visit(node.expression);
452 }
453
454 @override
455 SourceInformation visitVariableDeclarationList(
456 js.VariableDeclarationList node) {
457 if (node.sourceInformation != null) {
458 return node.sourceInformation;
459 }
460 for (js.Node declaration in node.declarations) {
461 SourceInformation sourceInformation = visit(declaration);
462 if (sourceInformation != null) {
463 return sourceInformation;
464 }
465 }
466 return null;
467 }
468
469 @override
470 SourceInformation visitVariableInitialization(
471 js.VariableInitialization node) {
472 if (node.sourceInformation != null) {
473 return node.sourceInformation;
474 }
475 return visit(node.value);
476 }
477
478 @override
479 SourceInformation visitAssignment(js.Assignment node) {
480 if (node.sourceInformation != null) {
481 return node.sourceInformation;
482 }
483 return visit(node.value);
484 }
485
486 }
487
488 /// Mixin that add support for computing [SourceInformation] for a [js.Node].
489 class NodeToSourceInformationMixin {
490 SourceInformation computeSourceInformation(js.Node node) {
491 return const NodeSourceInformation().visit(node);
492 }
493 }
494
412 /// [TraceListener] that register [SourceLocation]s with a [SourceMapper]. 495 /// [TraceListener] that register [SourceLocation]s with a [SourceMapper].
413 class PositionTraceListener extends TraceListener { 496 class PositionTraceListener extends TraceListener with
497 NodeToSourceInformationMixin {
414 final SourceMapper sourceMapper; 498 final SourceMapper sourceMapper;
415 499
416 PositionTraceListener(this.sourceMapper); 500 PositionTraceListener(this.sourceMapper);
417 501
418 @override 502 @override
419 void onStep(js.Node node, Offset offset, StepKind kind) { 503 void onStep(js.Node node, Offset offset, StepKind kind) {
420 SourceInformation sourceInformation = node.sourceInformation; 504 SourceInformation sourceInformation = computeSourceInformation(node);
421 if (sourceInformation == null) return; 505 if (sourceInformation == null) return;
422 506
423 SourcePositionKind sourcePositionKind = SourcePositionKind.START; 507 SourcePositionKind sourcePositionKind = SourcePositionKind.START;
424 switch (kind) { 508 switch (kind) {
425 case StepKind.FUN: 509 case StepKind.FUN:
426 sourcePositionKind = SourcePositionKind.INNER; 510 sourcePositionKind = SourcePositionKind.INNER;
427 break; 511 break;
428 case StepKind.CALL: 512 case StepKind.CALL:
429 CallPosition callPosition = 513 CallPosition callPosition =
430 CallPosition.getSemanticPositionForCall(node); 514 CallPosition.getSemanticPositionForCall(node);
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 int codeOffset, 829 int codeOffset,
746 StepKind kind) { 830 StepKind kind) {
747 var oldSteps = steps; 831 var oldSteps = steps;
748 steps = []; 832 steps = [];
749 offsetPosition = codeOffset; 833 offsetPosition = codeOffset;
750 visit(child); 834 visit(child);
751 if (steps.isEmpty) { 835 if (steps.isEmpty) {
752 notifyStep(parent, 836 notifyStep(parent,
753 getOffsetForNode(parent, offsetPosition), 837 getOffsetForNode(parent, offsetPosition),
754 kind); 838 kind);
839 // The [offsetPosition] should only be used by the first subexpression.
840 offsetPosition = null;
755 } 841 }
756 steps = oldSteps; 842 steps = oldSteps;
757 } 843 }
758 844
759 @override 845 @override
760 visitExpressionStatement(js.ExpressionStatement node) { 846 visitExpressionStatement(js.ExpressionStatement node) {
761 statementOffset = getSyntaxOffset(node); 847 statementOffset = getSyntaxOffset(node);
762 visitSubexpression( 848 visitSubexpression(
763 node, node.expression, statementOffset, 849 node, node.expression, statementOffset,
764 StepKind.EXPRESSION_STATEMENT); 850 StepKind.EXPRESSION_STATEMENT);
(...skipping 10 matching lines...) Expand all
775 int oldPosition = offsetPosition; 861 int oldPosition = offsetPosition;
776 offsetPosition = null; 862 offsetPosition = null;
777 visitList(node.arguments); 863 visitList(node.arguments);
778 offsetPosition = oldPosition; 864 offsetPosition = oldPosition;
779 CallPosition callPosition = 865 CallPosition callPosition =
780 CallPosition.getSemanticPositionForCall(node); 866 CallPosition.getSemanticPositionForCall(node);
781 js.Node positionNode = callPosition.node; 867 js.Node positionNode = callPosition.node;
782 int callOffset = getSyntaxOffset( 868 int callOffset = getSyntaxOffset(
783 positionNode, kind: callPosition.codePositionKind); 869 positionNode, kind: callPosition.codePositionKind);
784 if (offsetPosition == null) { 870 if (offsetPosition == null) {
871 // Use the call offset if this is not the first subexpression.
785 offsetPosition = callOffset; 872 offsetPosition = callOffset;
786 } 873 }
787 Offset offset = getOffsetForNode(positionNode, offsetPosition); 874 Offset offset = getOffsetForNode(positionNode, offsetPosition);
788 notifyStep(node, offset, StepKind.CALL); 875 notifyStep(node, offset, StepKind.CALL);
789 steps.add(node); 876 steps.add(node);
790 offsetPosition = null; 877 offsetPosition = null;
791 } 878 }
792 879
793 @override 880 @override
794 visitNew(js.New node) { 881 visitNew(js.New node) {
795 visit(node.target); 882 visit(node.target);
796 visitList(node.arguments); 883 visitList(node.arguments);
884 if (offsetPosition == null) {
885 // Use the syntax offset if this is not the first subexpression.
886 offsetPosition = getSyntaxOffset(node);
887 }
797 notifyStep( 888 notifyStep(
798 node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.NEW); 889 node, getOffsetForNode(node, offsetPosition), StepKind.NEW);
799 steps.add(node); 890 steps.add(node);
800 offsetPosition = null; 891 offsetPosition = null;
801 } 892 }
802 893
803 @override 894 @override
804 visitAccess(js.PropertyAccess node) { 895 visitAccess(js.PropertyAccess node) {
805 visit(node.receiver); 896 visit(node.receiver);
806 visit(node.selector); 897 visit(node.selector);
807 } 898 }
808 899
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 StepKind.FOR_UPDATE); 969 StepKind.FOR_UPDATE);
879 } 970 }
880 971
881 notifyPopBranch(); 972 notifyPopBranch();
882 } 973 }
883 974
884 @override 975 @override
885 visitWhile(js.While node) { 976 visitWhile(js.While node) {
886 statementOffset = getSyntaxOffset(node); 977 statementOffset = getSyntaxOffset(node);
887 if (node.condition != null) { 978 if (node.condition != null) {
888 visitSubexpression(node, node.condition, getSyntaxOffset(node.condition), 979 visitSubexpression(node, node.condition, getSyntaxOffset(node),
889 StepKind.WHILE_CONDITION); 980 StepKind.WHILE_CONDITION);
890 } 981 }
891 statementOffset = null; 982 statementOffset = null;
892 leftToRightOffset = null; 983 leftToRightOffset = null;
893 984
894 visit(node.body, BranchKind.LOOP); 985 visit(node.body, BranchKind.LOOP);
895 } 986 }
896 987
897 @override 988 @override
898 visitDo(js.Do node) { 989 visitDo(js.Do node) {
(...skipping 22 matching lines...) Expand all
921 visit(node.value); 1012 visit(node.value);
922 notifyStep( 1013 notifyStep(
923 node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.RETURN); 1014 node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.RETURN);
924 statementOffset = null; 1015 statementOffset = null;
925 leftToRightOffset = null; 1016 leftToRightOffset = null;
926 } 1017 }
927 1018
928 @override 1019 @override
929 visitThrow(js.Throw node) { 1020 visitThrow(js.Throw node) {
930 statementOffset = getSyntaxOffset(node); 1021 statementOffset = getSyntaxOffset(node);
1022 // Do not use [offsetPosition] for the subexpression.
1023 offsetPosition = null;
931 visit(node.expression); 1024 visit(node.expression);
932 notifyStep( 1025 notifyStep(
933 node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.THROW); 1026 node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.THROW);
934 statementOffset = null; 1027 statementOffset = null;
935 leftToRightOffset = null; 1028 leftToRightOffset = null;
936 } 1029 }
937 1030
938 @override 1031 @override
939 visitContinue(js.Continue node) { 1032 visitContinue(js.Continue node) {
940 statementOffset = getSyntaxOffset(node); 1033 statementOffset = getSyntaxOffset(node);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 } 1185 }
1093 } 1186 }
1094 _nodesWithoutInfo.clear(); 1187 _nodesWithoutInfo.clear();
1095 } 1188 }
1096 1189
1097 String getCoverageReport() { 1190 String getCoverageReport() {
1098 collapse(); 1191 collapse();
1099 StringBuffer sb = new StringBuffer(); 1192 StringBuffer sb = new StringBuffer();
1100 int total = _nodesWithInfoCount + _nodesWithoutInfoCount; 1193 int total = _nodesWithInfoCount + _nodesWithoutInfoCount;
1101 if (total > 0) { 1194 if (total > 0) {
1102 sb.write(_nodesWithoutInfoCount); 1195 sb.write(_nodesWithInfoCount);
1103 sb.write('/'); 1196 sb.write('/');
1104 sb.write(total); 1197 sb.write(total);
1105 sb.write(' ('); 1198 sb.write(' (');
1106 sb.write((100.0 * _nodesWithInfoCount / total).toStringAsFixed(2)); 1199 sb.write((100.0 * _nodesWithInfoCount / total).toStringAsFixed(2));
1107 sb.write('%) nodes with info.'); 1200 sb.write('%) nodes with info.');
1108 } else { 1201 } else {
1109 sb.write('No nodes.'); 1202 sb.write('No nodes.');
1110 } 1203 }
1111 if (_nodesWithoutOffsetCount > 0) { 1204 if (_nodesWithoutOffsetCount > 0) {
1112 sb.write(' '); 1205 sb.write(' ');
1113 sb.write(_nodesWithoutOffsetCount); 1206 sb.write(_nodesWithoutOffsetCount);
1114 sb.write(' node'); 1207 sb.write(' node');
1115 if (_nodesWithoutOffsetCount > 1) { 1208 if (_nodesWithoutOffsetCount > 1) {
1116 sb.write('s'); 1209 sb.write('s');
1117 } 1210 }
1118 sb.write(' without offset.'); 1211 sb.write(' without offset.');
1119 } 1212 }
1120 if (_nodesWithoutInfoCount > 0) { 1213 if (_nodesWithoutInfoCount > 0) {
1121 sb.write('\nNodes without info ('); 1214 sb.write('\nNodes without info (');
1122 sb.write(_nodesWithoutInfoCount); 1215 sb.write(_nodesWithoutInfoCount);
1123 sb.write(') by runtime type:'); 1216 sb.write(') by runtime type:');
1124 _nodesWithoutInfoCountByType.forEach((Type type, int count) { 1217 List<Type> types = _nodesWithoutInfoCountByType.keys.toList();
1218 types.sort((a, b) {
1219 return -_nodesWithoutInfoCountByType[a].compareTo(
1220 _nodesWithoutInfoCountByType[b]);
1221 });
1222
1223 types.forEach((Type type) {
1224 int count = _nodesWithoutInfoCountByType[type];
1125 sb.write('\n '); 1225 sb.write('\n ');
1126 sb.write(count); 1226 sb.write(count);
1127 sb.write(' '); 1227 sb.write(' ');
1128 sb.write(type); 1228 sb.write(type);
1129 sb.write(' node'); 1229 sb.write(' node');
1130 if (count > 1) { 1230 if (count > 1) {
1131 sb.write('s'); 1231 sb.write('s');
1132 } 1232 }
1133 }); 1233 });
1134 sb.write('\n'); 1234 sb.write('\n');
1135 } 1235 }
1136 return sb.toString(); 1236 return sb.toString();
1137 } 1237 }
1138 1238
1139 String toString() => getCoverageReport(); 1239 String toString() => getCoverageReport();
1140 } 1240 }
1141 1241
1142 /// [TraceListener] that registers [onStep] callbacks with [coverage]. 1242 /// [TraceListener] that registers [onStep] callbacks with [coverage].
1143 class CoverageListener extends TraceListener { 1243 class CoverageListener extends TraceListener with NodeToSourceInformationMixin {
1144 final Coverage coverage; 1244 final Coverage coverage;
1145 1245
1146 CoverageListener(this.coverage); 1246 CoverageListener(this.coverage);
1147 1247
1148 @override 1248 @override
1149 void onStep(js.Node node, Offset offset, StepKind kind) { 1249 void onStep(js.Node node, Offset offset, StepKind kind) {
1150 SourceInformation sourceInformation = node.sourceInformation; 1250 SourceInformation sourceInformation = computeSourceInformation(node);
1151 if (sourceInformation != null) { 1251 if (sourceInformation != null) {
1152 coverage.registerNodeWithInfo(node); 1252 coverage.registerNodeWithInfo(node);
1153 } else { 1253 } else {
1154 coverage.registerNodeWithoutInfo(node); 1254 coverage.registerNodeWithoutInfo(node);
1155 } 1255 }
1156 } 1256 }
1157 1257
1158 @override 1258 @override
1159 void onEnd(js.Node node) { 1259 void onEnd(js.Node node) {
1160 coverage.collapse(); 1260 coverage.collapse();
1161 } 1261 }
1162 } 1262 }
1163 1263
1164 /// [CodePositionMap] that registers calls with [Coverage]. 1264 /// [CodePositionMap] that registers calls with [Coverage].
1165 class CodePositionCoverage implements CodePositionMap { 1265 class CodePositionCoverage implements CodePositionMap {
1166 final CodePositionMap codePositions; 1266 final CodePositionMap codePositions;
1167 final Coverage coverage; 1267 final Coverage coverage;
1168 1268
1169 CodePositionCoverage(this.codePositions, this.coverage); 1269 CodePositionCoverage(this.codePositions, this.coverage);
1170 1270
1171 @override 1271 @override
1172 CodePosition operator [](js.Node node) { 1272 CodePosition operator [](js.Node node) {
1173 CodePosition codePosition = codePositions[node]; 1273 CodePosition codePosition = codePositions[node];
1174 if (codePosition == null) { 1274 if (codePosition == null) {
1175 coverage.registerNodesWithoutOffset(node); 1275 coverage.registerNodesWithoutOffset(node);
1176 } 1276 }
1177 return codePosition; 1277 return codePosition;
1178 } 1278 }
1179 } 1279 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/io/source_information.dart » ('j') | tests/compiler/dart2js/sourcemaps/diff_view.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698