OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 library dart2js.resolution_strategy; | 5 library dart2js.resolution_strategy; |
6 | 6 |
| 7 import 'package:front_end/src/fasta/scanner.dart' show Token; |
| 8 |
7 import '../common.dart'; | 9 import '../common.dart'; |
8 import '../common_elements.dart'; | 10 import '../common_elements.dart'; |
9 import '../common/backend_api.dart'; | 11 import '../common/backend_api.dart'; |
10 import '../common/names.dart'; | 12 import '../common/names.dart'; |
11 import '../common/resolution.dart'; | 13 import '../common/resolution.dart'; |
12 import '../common/tasks.dart'; | 14 import '../common/tasks.dart'; |
13 import '../compiler.dart'; | 15 import '../compiler.dart'; |
14 import '../constants/values.dart'; | 16 import '../constants/values.dart'; |
15 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
16 import '../elements/entities.dart'; | 18 import '../elements/entities.dart'; |
17 import '../elements/modelx.dart'; | 19 import '../elements/modelx.dart'; |
18 import '../elements/resolution_types.dart'; | 20 import '../elements/resolution_types.dart'; |
19 import '../environment.dart'; | 21 import '../environment.dart'; |
20 import '../enqueue.dart'; | 22 import '../enqueue.dart'; |
21 import '../frontend_strategy.dart'; | 23 import '../frontend_strategy.dart'; |
22 import '../js_backend/backend.dart'; | 24 import '../js_backend/backend.dart'; |
23 import '../js_backend/backend_usage.dart'; | 25 import '../js_backend/backend_usage.dart'; |
24 import '../js_backend/custom_elements_analysis.dart'; | 26 import '../js_backend/custom_elements_analysis.dart'; |
25 import '../js_backend/mirrors_analysis.dart'; | 27 import '../js_backend/mirrors_analysis.dart'; |
26 import '../js_backend/mirrors_data.dart'; | 28 import '../js_backend/mirrors_data.dart'; |
27 import '../js_backend/native_data.dart'; | 29 import '../js_backend/native_data.dart'; |
28 import '../js_backend/no_such_method_registry.dart'; | 30 import '../js_backend/no_such_method_registry.dart'; |
29 import '../library_loader.dart'; | 31 import '../library_loader.dart'; |
30 import '../native/resolver.dart'; | 32 import '../native/resolver.dart'; |
| 33 import '../tree/tree.dart' show Node; |
31 import '../serialization/task.dart'; | 34 import '../serialization/task.dart'; |
32 import '../patch_parser.dart'; | 35 import '../patch_parser.dart'; |
33 import '../resolved_uri_translator.dart'; | 36 import '../resolved_uri_translator.dart'; |
34 import '../universe/call_structure.dart'; | 37 import '../universe/call_structure.dart'; |
35 import '../universe/use.dart'; | 38 import '../universe/use.dart'; |
36 import '../universe/world_builder.dart'; | 39 import '../universe/world_builder.dart'; |
37 import '../universe/world_impact.dart'; | 40 import '../universe/world_impact.dart'; |
38 import 'no_such_method_resolver.dart'; | 41 import 'no_such_method_resolver.dart'; |
39 | 42 |
40 /// [FrontendStrategy] that loads '.dart' files and creates a resolved element | 43 /// [FrontendStrategy] that loads '.dart' files and creates a resolved element |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 _compiler.reporter.reportWarningMessage(errorElement, | 192 _compiler.reporter.reportWarningMessage(errorElement, |
190 errorElement.messageKind, errorElement.messageArguments); | 193 errorElement.messageKind, errorElement.messageArguments); |
191 } | 194 } |
192 MethodElement mainMethod; | 195 MethodElement mainMethod; |
193 if (mainFunction != null && !mainFunction.isMalformed) { | 196 if (mainFunction != null && !mainFunction.isMalformed) { |
194 mainFunction.computeType(_compiler.resolution); | 197 mainFunction.computeType(_compiler.resolution); |
195 mainMethod = mainFunction; | 198 mainMethod = mainFunction; |
196 } | 199 } |
197 return mainMethod; | 200 return mainMethod; |
198 } | 201 } |
| 202 |
| 203 SourceSpan spanFromToken(Element currentElement, Token token) => |
| 204 _spanFromTokens(currentElement, token, token); |
| 205 |
| 206 SourceSpan _spanFromTokens(Element currentElement, Token begin, Token end, |
| 207 [Uri uri]) { |
| 208 if (begin == null || end == null) { |
| 209 // TODO(ahe): We can almost always do better. Often it is only |
| 210 // end that is null. Otherwise, we probably know the current |
| 211 // URI. |
| 212 throw 'Cannot find tokens to produce error message.'; |
| 213 } |
| 214 if (uri == null && currentElement != null) { |
| 215 if (currentElement is! Element) { |
| 216 throw 'Can only find tokens from an Element.'; |
| 217 } |
| 218 Element element = currentElement; |
| 219 uri = element.compilationUnit.script.resourceUri; |
| 220 assert(invariant(currentElement, () { |
| 221 bool sameToken(Token token, Token sought) { |
| 222 if (token == sought) return true; |
| 223 if (token.stringValue == '>>') { |
| 224 // `>>` is converted to `>` in the parser when needed. |
| 225 return sought.stringValue == '>' && |
| 226 token.charOffset <= sought.charOffset && |
| 227 sought.charOffset < token.charEnd; |
| 228 } |
| 229 return false; |
| 230 } |
| 231 |
| 232 /// Check that [begin] and [end] can be found between [from] and [to]. |
| 233 validateToken(Token from, Token to) { |
| 234 if (from == null || to == null) return true; |
| 235 bool foundBegin = false; |
| 236 bool foundEnd = false; |
| 237 Token token = from; |
| 238 while (true) { |
| 239 if (sameToken(token, begin)) { |
| 240 foundBegin = true; |
| 241 } |
| 242 if (sameToken(token, end)) { |
| 243 foundEnd = true; |
| 244 } |
| 245 if (foundBegin && foundEnd) { |
| 246 return true; |
| 247 } |
| 248 if (token == to || token == token.next || token.next == null) { |
| 249 break; |
| 250 } |
| 251 token = token.next; |
| 252 } |
| 253 |
| 254 // Create a good message for when the tokens were not found. |
| 255 StringBuffer sb = new StringBuffer(); |
| 256 sb.write('Invalid current element: $element. '); |
| 257 sb.write('Looking for '); |
| 258 sb.write('[${begin} (${begin.hashCode}),'); |
| 259 sb.write('${end} (${end.hashCode})] in'); |
| 260 |
| 261 token = from; |
| 262 while (true) { |
| 263 sb.write('\n ${token} (${token.hashCode})'); |
| 264 if (token == to || token == token.next || token.next == null) { |
| 265 break; |
| 266 } |
| 267 token = token.next; |
| 268 } |
| 269 return sb.toString(); |
| 270 } |
| 271 |
| 272 if (element.enclosingClass != null && |
| 273 element.enclosingClass.isEnumClass) { |
| 274 // Enums ASTs are synthesized (and give messed up messages). |
| 275 return true; |
| 276 } |
| 277 |
| 278 if (element is AstElement) { |
| 279 AstElement astElement = element; |
| 280 if (astElement.hasNode) { |
| 281 Token from = astElement.node.getBeginToken(); |
| 282 Token to = astElement.node.getEndToken(); |
| 283 if (astElement.metadata.isNotEmpty) { |
| 284 if (!astElement.metadata.first.hasNode) { |
| 285 // We might try to report an error while parsing the metadata |
| 286 // itself. |
| 287 return true; |
| 288 } |
| 289 from = astElement.metadata.first.node.getBeginToken(); |
| 290 } |
| 291 return validateToken(from, to); |
| 292 } |
| 293 } |
| 294 return true; |
| 295 }, message: "Invalid current element: $element [$begin,$end].")); |
| 296 } |
| 297 return new SourceSpan.fromTokens(uri, begin, end); |
| 298 } |
| 299 |
| 300 SourceSpan _spanFromNode(Element currentElement, Node node) { |
| 301 return _spanFromTokens( |
| 302 currentElement, node.getBeginToken(), node.getPrefixEndToken()); |
| 303 } |
| 304 |
| 305 SourceSpan _spanFromElement(Element currentElement, Element element) { |
| 306 if (element != null && element.sourcePosition != null) { |
| 307 return element.sourcePosition; |
| 308 } |
| 309 while (element != null && element.isSynthesized) { |
| 310 element = element.enclosingElement; |
| 311 } |
| 312 if (element != null && |
| 313 element.sourcePosition == null && |
| 314 !element.isLibrary && |
| 315 !element.isCompilationUnit) { |
| 316 // Sometimes, the backend fakes up elements that have no |
| 317 // position. So we use the enclosing element instead. It is |
| 318 // not a good error location, but cancel really is "internal |
| 319 // error" or "not implemented yet", so the vicinity is good |
| 320 // enough for now. |
| 321 element = element.enclosingElement; |
| 322 // TODO(ahe): I plan to overhaul this infrastructure anyways. |
| 323 } |
| 324 if (element == null) { |
| 325 element = currentElement; |
| 326 } |
| 327 if (element == null) { |
| 328 return null; |
| 329 } |
| 330 |
| 331 if (element.sourcePosition != null) { |
| 332 return element.sourcePosition; |
| 333 } |
| 334 Token position = element.position; |
| 335 Uri uri = element.compilationUnit.script.resourceUri; |
| 336 return (position == null) |
| 337 ? new SourceSpan(uri, 0, 0) |
| 338 : _spanFromTokens(currentElement, position, position, uri); |
| 339 } |
| 340 |
| 341 SourceSpan spanFromSpannable(Spannable node, Entity currentElement) { |
| 342 if (node is Node) { |
| 343 return _spanFromNode(currentElement, node); |
| 344 } else if (node is Element) { |
| 345 return _spanFromElement(currentElement, node); |
| 346 } else if (node is MetadataAnnotation) { |
| 347 return node.sourcePosition; |
| 348 } |
| 349 return null; |
| 350 } |
199 } | 351 } |
200 | 352 |
201 /// An element environment base on a [Compiler]. | 353 /// An element environment base on a [Compiler]. |
202 class _CompilerElementEnvironment implements ElementEnvironment { | 354 class _CompilerElementEnvironment implements ElementEnvironment { |
203 final Compiler _compiler; | 355 final Compiler _compiler; |
204 | 356 |
205 _CompilerElementEnvironment(this._compiler); | 357 _CompilerElementEnvironment(this._compiler); |
206 | 358 |
207 LibraryProvider get _libraryProvider => _compiler.libraryLoader; | 359 LibraryProvider get _libraryProvider => _compiler.libraryLoader; |
208 Resolution get _resolution => _compiler.resolution; | 360 Resolution get _resolution => _compiler.resolution; |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 } | 780 } |
629 } | 781 } |
630 }); | 782 }); |
631 }); | 783 }); |
632 } | 784 } |
633 | 785 |
634 _compiler.libraryLoader.libraries | 786 _compiler.libraryLoader.libraries |
635 .forEach(processJsInteropAnnotationsInLibrary); | 787 .forEach(processJsInteropAnnotationsInLibrary); |
636 } | 788 } |
637 } | 789 } |
OLD | NEW |