OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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:front_end/src/fasta/scanner.dart' | 5 import 'package:front_end/src/fasta/scanner.dart' |
6 show BeginGroupToken, StringToken, Token; | 6 show BeginGroupToken, StringToken, Token; |
7 import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN; | 7 import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN; |
8 | 8 |
9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../common_elements.dart' show CommonElements; |
10 import '../common/backend_api.dart'; | 11 import '../common/backend_api.dart'; |
11 import '../common/resolution.dart'; | 12 import '../common/resolution.dart'; |
12 import '../compiler.dart' show Compiler; | 13 import '../compiler.dart' show Compiler; |
13 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
14 import '../elements/elements.dart' | 15 import '../elements/elements.dart' |
15 show | 16 show |
16 ClassElement, | 17 ClassElement, |
17 Element, | 18 Element, |
18 FieldElement, | 19 FieldElement, |
19 LibraryElement, | 20 LibraryElement, |
20 MemberElement, | 21 MemberElement, |
21 MetadataAnnotation, | 22 MetadataAnnotation, |
22 MethodElement; | 23 MethodElement; |
23 import '../elements/entities.dart'; | 24 import '../elements/entities.dart'; |
24 import '../elements/modelx.dart' show FunctionElementX, MetadataAnnotationX; | 25 import '../elements/modelx.dart' show FunctionElementX, MetadataAnnotationX; |
25 import '../elements/resolution_types.dart' show ResolutionDartType; | 26 import '../elements/resolution_types.dart' show ResolutionDartType; |
26 import '../js_backend/backend_helpers.dart'; | |
27 import '../js_backend/js_backend.dart'; | 27 import '../js_backend/js_backend.dart'; |
28 import '../js_backend/native_data.dart'; | 28 import '../js_backend/native_data.dart'; |
29 import '../patch_parser.dart'; | 29 import '../patch_parser.dart'; |
30 import '../tree/tree.dart'; | 30 import '../tree/tree.dart'; |
31 import 'behavior.dart'; | 31 import 'behavior.dart'; |
32 | 32 |
33 /// Interface for computing native members and [NativeBehavior]s in member code | 33 /// Interface for computing native members and [NativeBehavior]s in member code |
34 /// based on the AST. | 34 /// based on the AST. |
35 abstract class NativeDataResolver { | 35 abstract class NativeDataResolver { |
36 /// Returns `true` if [element] is a JsInterop member. | 36 /// Returns `true` if [element] is a JsInterop member. |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 Token token = node.getBeginToken(); | 220 Token token = node.getBeginToken(); |
221 if (identical(token.stringValue, 'native')) return true; | 221 if (identical(token.stringValue, 'native')) return true; |
222 return false; | 222 return false; |
223 }); | 223 }); |
224 } | 224 } |
225 | 225 |
226 /// Returns the JSName annotation string or `null` if no JSName annotation is | 226 /// Returns the JSName annotation string or `null` if no JSName annotation is |
227 /// present. | 227 /// present. |
228 String _findJsNameFromAnnotation(Element element) { | 228 String _findJsNameFromAnnotation(Element element) { |
229 String name = null; | 229 String name = null; |
230 ClassElement annotationClass = _backend.helpers.annotationJSNameClass; | 230 ClassElement annotationClass = |
| 231 _compiler.commonElements.annotationJSNameClass; |
231 for (MetadataAnnotation annotation in element.implementation.metadata) { | 232 for (MetadataAnnotation annotation in element.implementation.metadata) { |
232 annotation.ensureResolved(_compiler.resolution); | 233 annotation.ensureResolved(_compiler.resolution); |
233 ConstantValue value = | 234 ConstantValue value = |
234 _compiler.constants.getConstantValue(annotation.constant); | 235 _compiler.constants.getConstantValue(annotation.constant); |
235 if (!value.isConstructedObject) continue; | 236 if (!value.isConstructedObject) continue; |
236 ConstructedConstantValue constructedObject = value; | 237 ConstructedConstantValue constructedObject = value; |
237 if (constructedObject.type.element != annotationClass) continue; | 238 if (constructedObject.type.element != annotationClass) continue; |
238 | 239 |
239 Iterable<ConstantValue> fields = constructedObject.fields.values; | 240 Iterable<ConstantValue> fields = constructedObject.fields.values; |
240 // TODO(sra): Better validation of the constant. | 241 // TODO(sra): Better validation of the constant. |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 } | 313 } |
313 } | 314 } |
314 return null; | 315 return null; |
315 } | 316 } |
316 | 317 |
317 void validate(Compiler compiler, Element element, | 318 void validate(Compiler compiler, Element element, |
318 MetadataAnnotation annotation, ConstantValue constant) { | 319 MetadataAnnotation annotation, ConstantValue constant) { |
319 ResolutionDartType annotationType = | 320 ResolutionDartType annotationType = |
320 constant.getType(compiler.commonElements); | 321 constant.getType(compiler.commonElements); |
321 if (annotationType.element != | 322 if (annotationType.element != |
322 compiler.backend.helpers.nativeAnnotationClass) { | 323 compiler.commonElements.nativeAnnotationClass) { |
323 DiagnosticReporter reporter = compiler.reporter; | 324 DiagnosticReporter reporter = compiler.reporter; |
324 reporter.internalError(annotation, 'Invalid @Native(...) annotation.'); | 325 reporter.internalError(annotation, 'Invalid @Native(...) annotation.'); |
325 } | 326 } |
326 } | 327 } |
327 } | 328 } |
328 | 329 |
329 void checkJsInteropClassAnnotations(Compiler compiler, LibraryElement library, | 330 void checkJsInteropClassAnnotations(Compiler compiler, LibraryElement library, |
330 NativeBasicDataBuilder nativeBasicDataBuilder) { | 331 NativeBasicDataBuilder nativeBasicDataBuilder) { |
331 bool checkJsInteropAnnotation(Element element) { | 332 bool checkJsInteropAnnotation(Element element) { |
332 return EagerAnnotationHandler.checkAnnotation( | 333 return EagerAnnotationHandler.checkAnnotation( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 annotation.beginToken.next.lexeme == 'JS'; | 367 annotation.beginToken.next.lexeme == 'JS'; |
367 | 368 |
368 bool apply( | 369 bool apply( |
369 Compiler compiler, Element element, MetadataAnnotation annotation) { | 370 Compiler compiler, Element element, MetadataAnnotation annotation) { |
370 return hasJsNameAnnotation(annotation); | 371 return hasJsNameAnnotation(annotation); |
371 } | 372 } |
372 | 373 |
373 @override | 374 @override |
374 void validate(Compiler compiler, Element element, | 375 void validate(Compiler compiler, Element element, |
375 MetadataAnnotation annotation, ConstantValue constant) { | 376 MetadataAnnotation annotation, ConstantValue constant) { |
376 JavaScriptBackend backend = compiler.backend; | |
377 ResolutionDartType type = constant.getType(compiler.commonElements); | 377 ResolutionDartType type = constant.getType(compiler.commonElements); |
378 if (type.element != backend.helpers.jsAnnotationClass) { | 378 if (type.element != compiler.commonElements.jsAnnotationClass) { |
379 compiler.reporter | 379 compiler.reporter |
380 .internalError(annotation, 'Invalid @JS(...) annotation.'); | 380 .internalError(annotation, 'Invalid @JS(...) annotation.'); |
381 } | 381 } |
382 } | 382 } |
383 | 383 |
384 bool get defaultResult => false; | 384 bool get defaultResult => false; |
385 } | 385 } |
386 | 386 |
387 /// Interface for computing all native classes in a set of libraries. | 387 /// Interface for computing all native classes in a set of libraries. |
388 abstract class NativeClassResolver { | 388 abstract class NativeClassResolver { |
389 Iterable<ClassEntity> computeNativeClasses(Iterable<LibraryEntity> libraries); | 389 Iterable<ClassEntity> computeNativeClasses(Iterable<LibraryEntity> libraries); |
390 } | 390 } |
391 | 391 |
392 class NativeClassResolverImpl implements NativeClassResolver { | 392 class NativeClassResolverImpl implements NativeClassResolver { |
393 final DiagnosticReporter _reporter; | 393 final DiagnosticReporter _reporter; |
394 final Resolution _resolution; | 394 final Resolution _resolution; |
395 final BackendHelpers _helpers; | 395 final CommonElements _commonElements; |
396 final NativeBasicData _nativeBasicData; | 396 final NativeBasicData _nativeBasicData; |
397 | 397 |
398 Map<String, ClassElement> _tagOwner = new Map<String, ClassElement>(); | 398 Map<String, ClassElement> _tagOwner = new Map<String, ClassElement>(); |
399 | 399 |
400 NativeClassResolverImpl( | 400 NativeClassResolverImpl(this._resolution, this._reporter, |
401 this._resolution, this._reporter, this._helpers, this._nativeBasicData); | 401 this._commonElements, this._nativeBasicData); |
402 | 402 |
403 Iterable<ClassElement> computeNativeClasses( | 403 Iterable<ClassElement> computeNativeClasses( |
404 Iterable<LibraryElement> libraries) { | 404 Iterable<LibraryElement> libraries) { |
405 Set<ClassElement> nativeClasses = new Set<ClassElement>(); | 405 Set<ClassElement> nativeClasses = new Set<ClassElement>(); |
406 libraries.forEach((l) => _processNativeClassesInLibrary(l, nativeClasses)); | 406 libraries.forEach((l) => _processNativeClassesInLibrary(l, nativeClasses)); |
407 if (_helpers.isolateHelperLibrary != null) { | 407 if (_commonElements.isolateHelperLibrary != null) { |
408 _processNativeClassesInLibrary( | 408 _processNativeClassesInLibrary( |
409 _helpers.isolateHelperLibrary, nativeClasses); | 409 _commonElements.isolateHelperLibrary, nativeClasses); |
410 } | 410 } |
411 _processSubclassesOfNativeClasses(libraries, nativeClasses); | 411 _processSubclassesOfNativeClasses(libraries, nativeClasses); |
412 return nativeClasses; | 412 return nativeClasses; |
413 } | 413 } |
414 | 414 |
415 void _processNativeClassesInLibrary( | 415 void _processNativeClassesInLibrary( |
416 LibraryElement library, Set<ClassElement> nativeClasses) { | 416 LibraryElement library, Set<ClassElement> nativeClasses) { |
417 // Use implementation to ensure the inclusion of injected members. | 417 // Use implementation to ensure the inclusion of injected members. |
418 library.implementation.forEachLocalMember((Element element) { | 418 library.implementation.forEachLocalMember((Element element) { |
419 if (element.isClass) { | 419 if (element.isClass) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 } | 561 } |
562 // Should be at '{', 'with', 'implements', '<' or 'native'. | 562 // Should be at '{', 'with', 'implements', '<' or 'native'. |
563 return id.lexeme; | 563 return id.lexeme; |
564 } | 564 } |
565 | 565 |
566 return _reporter.withCurrentElement(classElement, () { | 566 return _reporter.withCurrentElement(classElement, () { |
567 return scanForExtendsName(classElement.position); | 567 return scanForExtendsName(classElement.position); |
568 }); | 568 }); |
569 } | 569 } |
570 } | 570 } |
OLD | NEW |