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

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

Issue 1196433002: Create and test source mapping for invocations. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Handle the new Name class in the JS Printer. Created 5 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Source information system that maps spans of Dart AST nodes to spans of
6 /// JavaScript nodes.
7
8 library dart2js.source_information.start_end;
9
10 import '../dart2jslib.dart' show
11 MessageKind,
12 SourceSpan;
13 import '../elements/elements.dart' show
14 AstElement,
15 LocalElement;
16 import '../js/js.dart' as js;
17 import '../js/js_source_mapping.dart';
18 import '../scanner/scannerlib.dart' show Token;
19 import '../tree/tree.dart' show Node, Send;
20
21 import 'source_file.dart';
22 import 'source_information.dart';
23
24 /// Source information that contains start source position and optionally an
25 /// end source position.
26 class StartEndSourceInformation extends SourceInformation {
27 @override
28 final SourceLocation startPosition;
29
30 @override
31 final SourceLocation endPosition;
32
33 StartEndSourceInformation(this.startPosition, [this.endPosition]);
34
35 @override
36 List<SourceLocation> get sourceLocations {
37 if (endPosition == null) {
38 return <SourceLocation>[startPosition];
39 } else {
40 return <SourceLocation>[startPosition, endPosition];
41 }
42 }
43
44 @override
45 SourceSpan get sourceSpan {
46 Uri uri = startPosition.sourceUri;
47 int begin = startPosition.offset;
48 int end = endPosition == null ? begin : endPosition.offset;
49 return new SourceSpan(uri, begin, end);
50 }
51
52 int get hashCode {
53 return 0x7FFFFFFF &
54 (startPosition.hashCode * 17 + endPosition.hashCode * 19);
55 }
56
57 bool operator ==(other) {
58 if (identical(this, other)) return true;
59 if (other is! StartEndSourceInformation) return false;
60 return startPosition == other.startPosition &&
61 endPosition == other.endPosition;
62 }
63
64 // TODO(johnniwinther): Inline this in
65 // [StartEndSourceInformationBuilder.buildDeclaration].
66 static StartEndSourceInformation _computeSourceInformation(
67 AstElement element) {
68
69 AstElement implementation = element.implementation;
70 SourceFile sourceFile = implementation.compilationUnit.script.file;
71 String name = computeElementNameForSourceMaps(element);
72 Node node = implementation.node;
73 Token beginToken;
74 Token endToken;
75 if (node == null) {
76 // Synthesized node. Use the enclosing element for the location.
77 beginToken = endToken = element.position;
78 } else {
79 beginToken = node.getBeginToken();
80 endToken = node.getEndToken();
81 }
82 // TODO(johnniwinther): find the right sourceFile here and remove offset
83 // checks below.
84 SourceLocation sourcePosition, endSourcePosition;
85 if (beginToken.charOffset < sourceFile.length) {
86 sourcePosition =
87 new OffsetSourceLocation(sourceFile, beginToken.charOffset, name);
88 }
89 if (endToken.charOffset < sourceFile.length) {
90 endSourcePosition =
91 new OffsetSourceLocation(sourceFile, endToken.charOffset, name);
92 }
93 return new StartEndSourceInformation(sourcePosition, endSourcePosition);
94 }
95
96 /// Create a textual representation of the source information using [uriText]
97 /// as the Uri representation.
98 String _computeText(String uriText) {
99 StringBuffer sb = new StringBuffer();
100 sb.write('$uriText:');
101 // Use 1-based line/startPosition info to match usual dart tool output.
102 sb.write('[${startPosition.line + 1},${startPosition.column + 1}]');
103 if (endPosition != null) {
104 sb.write('-[${endPosition.line + 1},${endPosition.column + 1}]');
105 }
106 return sb.toString();
107 }
108
109 String get shortText {
110 return _computeText(startPosition.sourceUri.pathSegments.last);
111 }
112
113 String toString() {
114 return _computeText('${startPosition.sourceUri}');
115 }
116 }
117
118 class StartEndSourceInformationStrategy
119 implements JavaScriptSourceInformationStrategy {
120 const StartEndSourceInformationStrategy();
121
122 @override
123 SourceInformationBuilder createBuilderForContext(AstElement element) {
124 return new StartEndSourceInformationBuilder(element);
125 }
126
127 @override
128 SourceInformationProcessor createProcessor(SourceMapper sourceMapper) {
129 return new StartEndSourceInformationProcessor(sourceMapper);
130 }
131 }
132
133 class StartEndSourceInformationProcessor extends SourceInformationProcessor {
134 final SourceMapper sourceMapper;
135
136 /// Used to track whether a terminating source location marker has been
137 /// registered for the top-most node with source information.
138 bool hasRegisteredRoot = false;
139
140 StartEndSourceInformationProcessor(this.sourceMapper);
141
142 @override
143 void onPositions(js.Node node,
144 int startPosition,
145 int endPosition,
146 int closingPosition) {
147 if (node.sourceInformation != null) {
148 StartEndSourceInformation sourceInformation = node.sourceInformation;
149 sourceMapper.register(
150 node, startPosition, sourceInformation.startPosition);
151 if (sourceInformation.endPosition != null) {
152 sourceMapper.register(node, endPosition, sourceInformation.endPosition);
153 }
154 if (!hasRegisteredRoot) {
155 sourceMapper.register(node, endPosition, null);
156 hasRegisteredRoot = true;
157 }
158 }
159 }
160 }
161
162 /// [SourceInformationBuilder] that generates [PositionSourceInformation].
163 class StartEndSourceInformationBuilder extends SourceInformationBuilder {
164 final SourceFile sourceFile;
165 final String name;
166
167 StartEndSourceInformationBuilder(AstElement element)
168 : sourceFile = element.compilationUnit.script.file,
169 name = computeElementNameForSourceMaps(element);
170
171 SourceInformation buildDeclaration(AstElement element) {
172 return StartEndSourceInformation._computeSourceInformation(element);
173 }
174
175 SourceLocation sourceFileLocationForToken(Token token) {
176 SourceLocation location =
177 new OffsetSourceLocation(sourceFile, token.charOffset, name);
178 checkValidSourceFileLocation(location, sourceFile, token.charOffset);
179 return location;
180 }
181
182 void checkValidSourceFileLocation(
183 SourceLocation location, SourceFile sourceFile, int offset) {
184 if (!location.isValid) {
185 throw MessageKind.INVALID_SOURCE_FILE_LOCATION.message(
186 {'offset': offset,
187 'fileName': sourceFile.filename,
188 'length': sourceFile.length});
189 }
190 }
191
192 @override
193 SourceInformation buildLoop(Node node) {
194 return new StartEndSourceInformation(
195 sourceFileLocationForToken(node.getBeginToken()),
196 sourceFileLocationForToken(node.getEndToken()));
197 }
198
199 @override
200 SourceInformation buildGeneric(Node node) {
201 return new StartEndSourceInformation(
202 sourceFileLocationForToken(node.getBeginToken()));
203 }
204
205 @override
206 SourceInformation buildReturn(Node node) {
207 return buildGeneric(node);
208 }
209
210 @override
211 SourceInformation buildGet(Node node) => buildGeneric(node);
212
213 @override
214 SourceInformation buildAssignment(Node node) => buildGeneric(node);
215
216 @override
217 SourceInformation buildCall(Node receiver, Node call) {
218 return buildGeneric(receiver);
219 }
220
221 @override
222 SourceInformation buildIf(Node node) => buildGeneric(node);
223
224 @override
225 SourceInformationBuilder forContext(
226 AstElement element, {SourceInformation sourceInformation}) {
227 return new StartEndSourceInformationBuilder(element);
228 }
229 }
230
231
232
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698