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

Side by Side Diff: pkg/dev_compiler/lib/src/compiler/source_map_printer.dart

Issue 2977943002: fix #30138, synethic nodes causing crash generating source maps (Closed)
Patch Set: fix Created 3 years, 5 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 import 'package:analyzer/dart/ast/ast.dart'; 5 import 'package:analyzer/dart/ast/ast.dart';
6 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 6 import 'package:analyzer/src/generated/source.dart' show LineInfo;
7 import 'package:source_maps/source_maps.dart' hide Printer; 7 import 'package:source_maps/source_maps.dart' hide Printer;
8 import 'package:source_span/source_span.dart' show SourceLocation; 8 import 'package:source_span/source_span.dart' show SourceLocation;
9 9
10 import '../js_ast/js_ast.dart' as JS; 10 import '../js_ast/js_ast.dart' as JS;
11 11
12 class SourceMapPrintingContext extends JS.SimpleJavaScriptPrintingContext { 12 class SourceMapPrintingContext extends JS.SimpleJavaScriptPrintingContext {
13 /// Current line in the buffer; 13 /// Current line in the buffer;
14 int _line = 0; 14 int _line = 0;
15 15
16 /// Current column in the buffer. 16 /// Current column in the buffer.
17 int _column = 0; 17 int _column = 0;
18 18
19 /// The source_maps builder we write JavaScript code to. 19 /// The source_maps builder we write JavaScript code to.
20 final sourceMap = new SourceMapBuilder(); 20 final sourceMap = new SourceMapBuilder();
21 21
22 /// The cache of URIs for paths. 22 Uri _sourceUri;
23 final _sourceUrlCache = <String, Object>{}; 23 LineInfo _lineInfo;
24 24 AstNode _topLevelNode;
25 CompilationUnit unit;
26 String sourcePath;
27 AstNode _currentTopLevelDeclaration;
28 25
29 @override 26 @override
30 void emit(String code) { 27 void emit(String code) {
31 var chars = code.runes.toList(); 28 var chars = code.runes.toList();
32 var length = chars.length; 29 var length = chars.length;
33 for (int i = 0; i < length; i++) { 30 for (int i = 0; i < length; i++) {
34 var c = chars[i]; 31 var c = chars[i];
35 if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) { 32 if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) {
36 // Return not followed by line-feed is treated as a new line. 33 // Return not followed by line-feed is treated as a new line.
37 _line++; 34 _line++;
38 _column = 0; 35 _column = 0;
39 } else { 36 } else {
40 _column++; 37 _column++;
41 } 38 }
42 } 39 }
43 super.emit(code); 40 super.emit(code);
44 } 41 }
45 42
46 void enterNode(JS.Node jsNode) { 43 void enterNode(JS.Node jsNode) {
47 AstNode node = jsNode.sourceInformation; 44 AstNode node = jsNode.sourceInformation;
48 if (node == null || node.offset == -1 || node.isSynthetic) return; 45 if (node == null || node.offset == -1 || node.isSynthetic) return;
49 if (unit == null) { 46 if (_topLevelNode == null) {
50 // This is a top-level declaration. Note: consecutive top-level 47 // This is a top-level declaration. Note: consecutive top-level
51 // declarations may come from different compilation units due to 48 // declarations may come from different compilation units due to
52 // parts. 49 // parts.
53 _currentTopLevelDeclaration = node; 50 var unit =
54 unit = node.getAncestor((n) => n is CompilationUnit); 51 node.getAncestor((n) => n is CompilationUnit) as CompilationUnit;
55 var source = resolutionMap.elementDeclaredByCompilationUnit(unit).source; 52 // This happens for synthetic nodes created by AstFactory.
56 // Use the uri for dart: uris instead of the path of the source file 53 // We don't need to mark positions for them because we'll have a position
57 // on disk as that results in much cleaner stack traces. 54 // for the next thing down.
58 // Example: 55 if (unit == null) return;
Jennifer Messerly 2017/07/14 07:51:35 this is the actual 1-line fix :)
59 // source.uri = dart:core/object.dart 56
60 // source.fullName = gen/patched_sdk/lib/core/object.dart 57 _topLevelNode = node;
61 sourcePath = 58 var source = unit.element.source;
62 source.isInSystemLibrary ? source.uri.toString() : source.fullName; 59 _lineInfo = unit.lineInfo;
60 _sourceUri = source.uri;
61 // TODO(jmesserly): this is for backwards compat, but it seems cleaner
62 // to preserve the package URI, as long as devtools can open the
63 // corresponding file.
64 if (_sourceUri.scheme == 'package') {
Jennifer Messerly 2017/07/14 07:51:35 refactored this to figure out what was going on. W
65 _sourceUri = Uri.parse(source.fullName);
66 }
63 } 67 }
64 // Skip MethodDeclarations - in the case of a one line function it finds the 68
65 // declaration rather than the body and confuses devtools.
66 if (node is MethodDeclaration) return;
Jennifer Messerly 2017/07/14 07:51:35 this was fixed in CodeGenerator
67 _mark(node.offset, _getIdentifier(node)); 69 _mark(node.offset, _getIdentifier(node));
68 } 70 }
69 71
70 void exitNode(JS.Node jsNode) { 72 void exitNode(JS.Node jsNode) {
71 AstNode node = jsNode.sourceInformation; 73 AstNode node = jsNode.sourceInformation;
72 if (unit == null || node == null || node.offset == -1 || node.isSynthetic) { 74 if (_topLevelNode == null ||
75 node == null ||
76 node.offset == -1 ||
77 node.isSynthetic) {
73 return; 78 return;
74 } 79 }
75 80
76 // TODO(jmesserly): in many cases marking the end will be unnecessary. 81 // TODO(jmesserly): in most cases marking the end will be unnecessary.
77 // Skip MethodDeclarations - in the case of a one line function it finds the 82 _mark(node.end);
78 // declaration rather than the body and confuses devtools.
79 if (node is! MethodDeclaration) {
80 _mark(node.end);
81 }
82 83
83 if (identical(node, _currentTopLevelDeclaration)) { 84 if (identical(node, _topLevelNode)) {
84 unit = null; 85 _sourceUri = null;
85 sourcePath = null; 86 _lineInfo = null;
86 _currentTopLevelDeclaration == null; 87 _topLevelNode = null;
87 } 88 }
88 } 89 }
89 90
90 // TODO(jmesserly): prefix identifiers too, if they map to a named element. 91 // TODO(jmesserly): prefix identifiers too, if they map to a named element.
91 String _getIdentifier(AstNode node) => 92 String _getIdentifier(AstNode node) =>
92 node is SimpleIdentifier ? node.name : null; 93 node is SimpleIdentifier ? node.name : null;
93 94
94 void _mark(int offset, [String identifier]) { 95 void _mark(int offset, [String identifier]) {
95 var loc = unit.lineInfo.getLocation(offset); 96 var loc = _lineInfo.getLocation(offset);
96 // Chrome Devtools wants a mapping for the beginning of 97 // Chrome Devtools wants a mapping for the beginning of
97 // a line, so bump locations at the end of a line to the beginning of 98 // a line, so bump locations at the end of a line to the beginning of
98 // the next line. 99 // the next line.
99 var next = unit.lineInfo.getLocation(offset + 1); 100 var next = _lineInfo.getLocation(offset + 1);
100 if (next.lineNumber == loc.lineNumber + 1) { 101 if (next.lineNumber == loc.lineNumber + 1) {
101 loc = next; 102 loc = next;
102 } 103 }
103 var sourceUrl = _sourceUrlCache.putIfAbsent(
104 sourcePath,
105 () =>
106 sourcePath.startsWith('dart:') || sourcePath.startsWith('package:')
107 ? sourcePath
108 : new Uri.file(sourcePath));
109 sourceMap.addLocation( 104 sourceMap.addLocation(
110 new SourceLocation(offset, 105 new SourceLocation(offset,
111 sourceUrl: sourceUrl, 106 sourceUrl: _sourceUri,
112 line: loc.lineNumber - 1, 107 line: loc.lineNumber - 1,
113 column: loc.columnNumber - 1), 108 column: loc.columnNumber - 1),
114 new SourceLocation(buffer.length, line: _line, column: _column), 109 new SourceLocation(buffer.length, line: _line, column: _column),
115 identifier); 110 identifier);
116 } 111 }
117 } 112 }
118 113
119 const int _LF = 10; 114 const int _LF = 10;
120 const int _CR = 13; 115 const int _CR = 13;
OLDNEW
« no previous file with comments | « pkg/dev_compiler/lib/src/compiler/code_generator.dart ('k') | tests/language_strong/nullaware_opt_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698