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

Side by Side Diff: pkg/compiler/lib/src/inferrer/type_graph_dump.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 library dart2js.inferrer.type_graph_dump; 4 library dart2js.inferrer.type_graph_dump;
5 5
6 import 'dart:async'; 6 import 'dart:async';
7 import 'type_graph_nodes.dart'; 7 import 'type_graph_nodes.dart';
8 import 'type_graph_inferrer.dart'; 8 import 'type_graph_inferrer.dart';
9 import '../elements/elements.dart'; 9 import '../elements/elements.dart';
10 import '../types/types.dart'; 10 import '../types/types.dart';
(...skipping 11 matching lines...) Expand all
22 /// dot -Tpng -O typegraph/main.dot 22 /// dot -Tpng -O typegraph/main.dot
23 /// open typegraph/main.dot.png 23 /// open typegraph/main.dot.png
24 /// 24 ///
25 /// dot -Tpng -O typegraph/dart._internal.Sort._dualPivotQuicksort.dot 25 /// dot -Tpng -O typegraph/dart._internal.Sort._dualPivotQuicksort.dot
26 /// open typegraph/dart._internal.Sort._dualPivotQuicksort.dot.png 26 /// open typegraph/dart._internal.Sort._dualPivotQuicksort.dot.png
27 /// 27 ///
28 class TypeGraphDump { 28 class TypeGraphDump {
29 static const String outputDir = 'typegraph'; 29 static const String outputDir = 'typegraph';
30 30
31 final TypeGraphInferrerEngine inferrer; 31 final TypeGraphInferrerEngine inferrer;
32 final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeAnalysis 32 final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeAnalysis =
33 = <TypeInformation, Set<TypeInformation>>{}; 33 <TypeInformation, Set<TypeInformation>>{};
34 final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeTracing 34 final Map<TypeInformation, Set<TypeInformation>> assignmentsBeforeTracing =
35 = <TypeInformation, Set<TypeInformation>>{}; 35 <TypeInformation, Set<TypeInformation>>{};
36 final Set<String> usedFilenames = new Set<String>(); 36 final Set<String> usedFilenames = new Set<String>();
37 37
38 TypeGraphDump(this.inferrer); 38 TypeGraphDump(this.inferrer);
39 39
40 /// Take a copy of the assignment set for each node, since that may change 40 /// Take a copy of the assignment set for each node, since that may change
41 /// during the analysis. 41 /// during the analysis.
42 void beforeAnalysis() { 42 void beforeAnalysis() {
43 for (TypeInformation node in inferrer.types.allTypes) { 43 for (TypeInformation node in inferrer.types.allTypes) {
44 Set<TypeInformation> copy = node.assignments.toSet(); 44 Set<TypeInformation> copy = node.assignments.toSet();
45 if (!copy.isEmpty) { 45 if (!copy.isEmpty) {
(...skipping 12 matching lines...) Expand all
58 } 58 }
59 } 59 }
60 60
61 /// Dumps the entire graph. 61 /// Dumps the entire graph.
62 void afterAnalysis() { 62 void afterAnalysis() {
63 // Group all the type nodes by their context member. 63 // Group all the type nodes by their context member.
64 Map<Element, List<TypeInformation>> nodes = 64 Map<Element, List<TypeInformation>> nodes =
65 <Element, List<TypeInformation>>{}; 65 <Element, List<TypeInformation>>{};
66 for (TypeInformation node in inferrer.types.allTypes) { 66 for (TypeInformation node in inferrer.types.allTypes) {
67 if (node.contextMember != null) { 67 if (node.contextMember != null) {
68 nodes.putIfAbsent(node.contextMember, () => <TypeInformation>[]) 68 nodes
69 .add(node); 69 .putIfAbsent(node.contextMember, () => <TypeInformation>[])
70 .add(node);
70 } 71 }
71 } 72 }
72 // Print every group separately. 73 // Print every group separately.
73 for (Element element in nodes.keys) { 74 for (Element element in nodes.keys) {
74 EventSink<String> output; 75 EventSink<String> output;
75 try { 76 try {
76 String name = filenameFromElement(element); 77 String name = filenameFromElement(element);
77 output = inferrer.compiler.outputProvider('$outputDir/$name', 'dot'); 78 output = inferrer.compiler.outputProvider('$outputDir/$name', 'dot');
78 _GraphGenerator visitor = new _GraphGenerator(this, element, output); 79 _GraphGenerator visitor = new _GraphGenerator(this, element, output);
79 for (TypeInformation node in nodes[element]) { 80 for (TypeInformation node in nodes[element]) {
(...skipping 13 matching lines...) Expand all
93 /// graph for [element]. 94 /// graph for [element].
94 /// 95 ///
95 /// Will never return the a given filename more than once, even if called with 96 /// Will never return the a given filename more than once, even if called with
96 /// the same element. 97 /// the same element.
97 String filenameFromElement(Element element) { 98 String filenameFromElement(Element element) {
98 // The toString method of elements include characters that are unsuitable 99 // The toString method of elements include characters that are unsuitable
99 // for URIs and file systems. 100 // for URIs and file systems.
100 List<String> parts = <String>[]; 101 List<String> parts = <String>[];
101 parts.add(element.library?.libraryName); 102 parts.add(element.library?.libraryName);
102 parts.add(element.enclosingClass?.name); 103 parts.add(element.enclosingClass?.name);
103 Element namedElement = element is LocalElement 104 Element namedElement =
104 ? element.executableContext 105 element is LocalElement ? element.executableContext : element;
105 : element;
106 if (namedElement.isGetter) { 106 if (namedElement.isGetter) {
107 parts.add('get-${namedElement.name}'); 107 parts.add('get-${namedElement.name}');
108 } else if (namedElement.isSetter) { 108 } else if (namedElement.isSetter) {
109 parts.add('set-${namedElement.name}'); 109 parts.add('set-${namedElement.name}');
110 } else if (namedElement.isConstructor) { 110 } else if (namedElement.isConstructor) {
111 if (namedElement.name.isEmpty) { 111 if (namedElement.name.isEmpty) {
112 parts.add('-constructor'); 112 parts.add('-constructor');
113 } else { 113 } else {
114 parts.add(namedElement.name); 114 parts.add(namedElement.name);
115 } 115 }
116 } else if (namedElement.isOperator) { 116 } else if (namedElement.isOperator) {
117 parts.add(Elements.operatorNameToIdentifier(namedElement.name) 117 parts.add(Elements
118 .operatorNameToIdentifier(namedElement.name)
118 .replaceAll(r'$', '-')); 119 .replaceAll(r'$', '-'));
119 } else { 120 } else {
120 parts.add(namedElement.name); 121 parts.add(namedElement.name);
121 } 122 }
122 if (namedElement != element) { 123 if (namedElement != element) {
123 if (element.name.isEmpty) { 124 if (element.name.isEmpty) {
124 parts.add('anon${element.sourcePosition.begin}'); 125 parts.add('anon${element.sourcePosition.begin}');
125 } else { 126 } else {
126 parts.add(element.name); 127 parts.add(element.name);
127 } 128 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 199
199 /// Escapes characters in [text] so it can be used as part of a label. 200 /// Escapes characters in [text] so it can be used as part of a label.
200 String escapeLabel(String text) { 201 String escapeLabel(String text) {
201 return text.replaceAllMapped(escapeRegexp, (m) => '\\${m.group(0)}'); 202 return text.replaceAllMapped(escapeRegexp, (m) => '\\${m.group(0)}');
202 } 203 }
203 204
204 /// Creates an edge from [src] to [dst]. 205 /// Creates an edge from [src] to [dst].
205 /// 206 ///
206 /// If [dst] is a record type node, [port] may refer to one of the fields 207 /// If [dst] is a record type node, [port] may refer to one of the fields
207 /// defined in that record (e.g. `obj`, `arg0`, `arg1`, etc) 208 /// defined in that record (e.g. `obj`, `arg0`, `arg1`, etc)
208 void addEdge(TypeInformation src, 209 void addEdge(TypeInformation src, TypeInformation dst,
209 TypeInformation dst, 210 {String port, String color: 'black'}) {
210 {String port,
211 String color: 'black'}) {
212 if (isExternal(src) && isExternal(dst)) { 211 if (isExternal(src) && isExternal(dst)) {
213 return; // Do not add edges between external nodes. 212 return; // Do not add edges between external nodes.
214 } 213 }
215 String dstText = getNode(dst); 214 String dstText = getNode(dst);
216 if (port != null) { 215 if (port != null) {
217 dstText += ':$port'; 216 dstText += ':$port';
218 } 217 }
219 if (src is ConcreteTypeInformation) { 218 if (src is ConcreteTypeInformation) {
220 // Concrete types can have a huge number of uses which will flood the 219 // Concrete types can have a huge number of uses which will flood the
221 // graph with very long hard-to-follow edges. Copy the concrete nodes 220 // graph with very long hard-to-follow edges. Copy the concrete nodes
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 if (node.contextMember != null && node.contextMember != element) { 262 if (node.contextMember != null && node.contextMember != element) {
264 return '$text\n(from ${node.contextMember})'; 263 return '$text\n(from ${node.contextMember})';
265 } 264 }
266 return text; 265 return text;
267 } 266 }
268 267
269 /// Creates a node for [node] displaying the given [text] in its box. 268 /// Creates a node for [node] displaying the given [text] in its box.
270 /// 269 ///
271 /// [inputs] specify named inputs to the node. If omitted, edges will be 270 /// [inputs] specify named inputs to the node. If omitted, edges will be
272 /// based on [node.assignments]. 271 /// based on [node.assignments].
273 void addNode(TypeInformation node, 272 void addNode(TypeInformation node, String text,
274 String text, 273 {String color: defaultNodeColor, Map<String, TypeInformation> inputs}) {
275 {String color: defaultNodeColor,
276 Map<String, TypeInformation> inputs}) {
277 seen.add(node); 274 seen.add(node);
278 String style = getStyleForNode(node, color); 275 String style = getStyleForNode(node, color);
279 text = appendDetails(node, text); 276 text = appendDetails(node, text);
280 text = escapeLabel(text); 277 text = escapeLabel(text);
281 String id = getNode(node); 278 String id = getNode(node);
282 String returnType = escapeLabel(formatType(node.type)); 279 String returnType = escapeLabel(formatType(node.type));
283 if (inputs != null) { 280 if (inputs != null) {
284 Iterable<String> keys = inputs.keys.where((key) => inputs[key] != null); 281 Iterable<String> keys = inputs.keys.where((key) => inputs[key] != null);
285 String header = keys.map((key) => '<a$key> $key').join('|'); 282 String header = keys.map((key) => '<a$key> $key').join('|');
286 String label = '{{$header}|$text|<returnType> $returnType}'; 283 String label = '{{$header}|$text|<returnType> $returnType}';
287 append('$id [shape=record,label="$label",$style]'); 284 append('$id [shape=record,label="$label",$style]');
288 for (String key in keys) { 285 for (String key in keys) {
289 addEdge(inputs[key], node, port: 'a$key'); 286 addEdge(inputs[key], node, port: 'a$key');
290 } 287 }
291 } else { 288 } else {
292 String label = '{$text|<returnType> $returnType}'; 289 String label = '{$text|<returnType> $returnType}';
293 append('$id [shape=record,label="$label",$style]'); 290 append('$id [shape=record,label="$label",$style]');
294 // Add assignment edges. Color the edges based on whether they were 291 // Add assignment edges. Color the edges based on whether they were
295 // added, removed, temporary, or unchanged. 292 // added, removed, temporary, or unchanged.
296 var originalSet = global.assignmentsBeforeAnalysis[node] ?? const []; 293 var originalSet = global.assignmentsBeforeAnalysis[node] ?? const [];
297 var tracerSet = global.assignmentsBeforeTracing[node] ?? const []; 294 var tracerSet = global.assignmentsBeforeTracing[node] ?? const [];
298 var currentSet = node.assignments.toSet(); 295 var currentSet = node.assignments.toSet();
299 for (TypeInformation assignment in currentSet) { 296 for (TypeInformation assignment in currentSet) {
300 String color = originalSet.contains(assignment) 297 String color =
301 ? unchangedEdge 298 originalSet.contains(assignment) ? unchangedEdge : addedEdge;
302 : addedEdge;
303 addEdge(assignment, node, color: color); 299 addEdge(assignment, node, color: color);
304 } 300 }
305 for (TypeInformation assignment in originalSet) { 301 for (TypeInformation assignment in originalSet) {
306 if (!currentSet.contains(assignment)) { 302 if (!currentSet.contains(assignment)) {
307 addEdge(assignment, node, color: removedEdge); 303 addEdge(assignment, node, color: removedEdge);
308 } 304 }
309 } 305 }
310 for (TypeInformation assignment in tracerSet) { 306 for (TypeInformation assignment in tracerSet) {
311 if (!currentSet.contains(assignment) && 307 if (!currentSet.contains(assignment) &&
312 !originalSet.contains(assignment)) { 308 !originalSet.contains(assignment)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 340
345 void visitMapTypeInformation(MapTypeInformation info) { 341 void visitMapTypeInformation(MapTypeInformation info) {
346 addNode(info, 'Map'); 342 addNode(info, 'Map');
347 } 343 }
348 344
349 void visitConcreteTypeInformation(ConcreteTypeInformation info) { 345 void visitConcreteTypeInformation(ConcreteTypeInformation info) {
350 addNode(info, 'Concrete'); 346 addNode(info, 'Concrete');
351 } 347 }
352 348
353 void visitStringLiteralTypeInformation(StringLiteralTypeInformation info) { 349 void visitStringLiteralTypeInformation(StringLiteralTypeInformation info) {
354 String text = shorten(info.value.slowToString()).replaceAll('\n','\\n'); 350 String text = shorten(info.value.slowToString()).replaceAll('\n', '\\n');
355 addNode(info, 'StringLiteral\n"$text"'); 351 addNode(info, 'StringLiteral\n"$text"');
356 } 352 }
357 353
358 void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) { 354 void visitBoolLiteralTypeInformation(BoolLiteralTypeInformation info) {
359 addNode(info, 'BoolLiteral\n${info.value}'); 355 addNode(info, 'BoolLiteral\n${info.value}');
360 } 356 }
361 357
362 void handleCall(CallSiteTypeInformation info, String text, Map inputs) { 358 void handleCall(CallSiteTypeInformation info, String text, Map inputs) {
363 String sourceCode = shorten('${info.call}'); 359 String sourceCode = shorten('${info.call}');
364 text = '$text\n$sourceCode'; 360 text = '$text\n$sourceCode';
365 if (info.arguments != null) { 361 if (info.arguments != null) {
366 for (int i = 0; i < info.arguments.positional.length; ++i) { 362 for (int i = 0; i < info.arguments.positional.length; ++i) {
367 inputs['arg$i'] = info.arguments.positional[i]; 363 inputs['arg$i'] = info.arguments.positional[i];
368 } 364 }
369 for (String argName in info.arguments.named.keys) { 365 for (String argName in info.arguments.named.keys) {
370 inputs[argName] = info.arguments.named[argName]; 366 inputs[argName] = info.arguments.named[argName];
371 } 367 }
372 } 368 }
373 addNode(info, text, color: callColor, inputs: inputs); 369 addNode(info, text, color: callColor, inputs: inputs);
374 } 370 }
375 371
376 void visitClosureCallSiteTypeInformation(ClosureCallSiteTypeInformation info) { 372 void visitClosureCallSiteTypeInformation(
373 ClosureCallSiteTypeInformation info) {
377 handleCall(info, 'ClosureCallSite', {}); 374 handleCall(info, 'ClosureCallSite', {});
378 } 375 }
379 376
380 void visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) { 377 void visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
381 handleCall(info, 'StaticCallSite', {}); 378 handleCall(info, 'StaticCallSite', {});
382 } 379 }
383 380
384 void visitDynamicCallSiteTypeInformation(DynamicCallSiteTypeInformation info) { 381 void visitDynamicCallSiteTypeInformation(
385 handleCall(info, 'DynamicCallSite', { 382 DynamicCallSiteTypeInformation info) {
386 'obj': info.receiver 383 handleCall(info, 'DynamicCallSite', {'obj': info.receiver});
387 });
388 } 384 }
389 385
390 void visitMemberTypeInformation(MemberTypeInformation info) { 386 void visitMemberTypeInformation(MemberTypeInformation info) {
391 addNode(info, 'Member\n${info.element}'); 387 addNode(info, 'Member\n${info.element}');
392 } 388 }
393 389
394 void visitParameterTypeInformation(ParameterTypeInformation info) { 390 void visitParameterTypeInformation(ParameterTypeInformation info) {
395 addNode(info, 'Parameter ${info.element?.name ?? ''}'); 391 addNode(info, 'Parameter ${info.element?.name ?? ''}');
396 } 392 }
397 393
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 String value = formatType(type.valueType); 432 String value = formatType(type.valueType);
437 return '$container<$key,$value>'; 433 return '$container<$key,$value>';
438 } 434 }
439 if (type is ValueTypeMask) { 435 if (type is ValueTypeMask) {
440 String baseType = formatType(type.forwardTo); 436 String baseType = formatType(type.forwardTo);
441 String value = type.value.toStructuredString(); 437 String value = type.value.toStructuredString();
442 return '$baseType=$value'; 438 return '$baseType=$value';
443 } 439 }
444 return '$type'; // Fall back on toString if not supported here. 440 return '$type'; // Fall back on toString if not supported here.
445 } 441 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart ('k') | pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698