| 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_elements.dart' show CommonElements; |
| 11 import '../common/backend_api.dart'; | 11 import '../common/backend_api.dart'; |
| 12 import '../common/resolution.dart'; | 12 import '../common/resolution.dart'; |
| 13 import '../compiler.dart' show Compiler; | 13 import '../compiler.dart' show Compiler; |
| 14 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
| 15 import '../elements/elements.dart' | 15 import '../elements/elements.dart' |
| 16 show | 16 show |
| 17 ClassElement, | 17 ClassElement, |
| 18 Element, | 18 Element, |
| 19 FieldElement, | 19 FieldElement, |
| 20 LibraryElement, | 20 LibraryElement, |
| 21 MemberElement, | 21 MemberElement, |
| 22 MetadataAnnotation, | 22 MetadataAnnotation, |
| 23 MethodElement; | 23 MethodElement; |
| 24 import '../elements/entities.dart'; | 24 import '../elements/entities.dart'; |
| 25 import '../elements/modelx.dart' show FunctionElementX, MetadataAnnotationX; | 25 import '../elements/modelx.dart' show FunctionElementX, MetadataAnnotationX; |
| 26 import '../elements/resolution_types.dart' show ResolutionDartType; | 26 import '../elements/resolution_types.dart' show ResolutionDartType; |
| 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 '../kernel/world_builder.dart' show KernelAnnotationProcessor; | |
| 30 import '../patch_parser.dart'; | 29 import '../patch_parser.dart'; |
| 31 import '../tree/tree.dart'; | 30 import '../tree/tree.dart'; |
| 32 import 'behavior.dart'; | 31 import 'behavior.dart'; |
| 33 | 32 |
| 34 /// Class that performs the mechanics to investigate annotations in the code. | |
| 35 abstract class AnnotationProcessor { | |
| 36 factory AnnotationProcessor(Compiler compiler) => | |
| 37 compiler.options.loadFromDill | |
| 38 // TODO(johnniwinther): Pass the [KernelWorldBuilder] to | |
| 39 // [KernelAnnotationProcessor]. | |
| 40 ? new KernelAnnotationProcessor(null) | |
| 41 : new _ElementAnnotationProcessor(compiler); | |
| 42 | |
| 43 void extractNativeAnnotations( | |
| 44 LibraryEntity library, NativeBasicDataBuilder nativeBasicDataBuilder); | |
| 45 | |
| 46 void extractJsInteropAnnotations( | |
| 47 LibraryEntity library, NativeBasicDataBuilder nativeBasicDataBuilder); | |
| 48 } | |
| 49 | |
| 50 /// Original logic for annotation processing, which involves in some cases | |
| 51 /// triggering pre-parsing and validation of the annotations. | |
| 52 class _ElementAnnotationProcessor implements AnnotationProcessor { | |
| 53 Compiler _compiler; | |
| 54 | |
| 55 _ElementAnnotationProcessor(this._compiler); | |
| 56 | |
| 57 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its | |
| 58 /// native name from the annotation. | |
| 59 void extractNativeAnnotations( | |
| 60 LibraryElement library, NativeBasicDataBuilder nativeBasicDataBuilder) { | |
| 61 library.forEachLocalMember((Element element) { | |
| 62 if (element.isClass) { | |
| 63 EagerAnnotationHandler.checkAnnotation(_compiler, element, | |
| 64 new NativeAnnotationHandler(nativeBasicDataBuilder)); | |
| 65 } | |
| 66 }); | |
| 67 } | |
| 68 | |
| 69 void extractJsInteropAnnotations( | |
| 70 LibraryElement library, NativeBasicDataBuilder nativeBasicDataBuilder) { | |
| 71 bool checkJsInteropAnnotation(Element element) { | |
| 72 return EagerAnnotationHandler.checkAnnotation( | |
| 73 _compiler, element, const JsInteropAnnotationHandler()); | |
| 74 } | |
| 75 | |
| 76 if (checkJsInteropAnnotation(library)) { | |
| 77 nativeBasicDataBuilder.markAsJsInteropLibrary(library); | |
| 78 } | |
| 79 library.forEachLocalMember((Element element) { | |
| 80 if (element.isClass) { | |
| 81 ClassElement cls = element; | |
| 82 if (checkJsInteropAnnotation(element)) { | |
| 83 nativeBasicDataBuilder.markAsJsInteropClass(cls); | |
| 84 } | |
| 85 } | |
| 86 }); | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 /// Interface for computing native members and [NativeBehavior]s in member code | 33 /// Interface for computing native members and [NativeBehavior]s in member code |
| 91 /// based on the AST. | 34 /// based on the AST. |
| 92 abstract class NativeDataResolver { | 35 abstract class NativeDataResolver { |
| 93 /// Returns `true` if [element] is a JsInterop member. | 36 /// Returns `true` if [element] is a JsInterop member. |
| 94 bool isJsInteropMember(MemberElement element); | 37 bool isJsInteropMember(MemberElement element); |
| 95 | 38 |
| 96 /// Computes whether [element] is native or JsInterop and, if so, registers | 39 /// Computes whether [element] is native or JsInterop and, if so, registers |
| 97 /// its [NativeBehavior]s to [registry]. | 40 /// its [NativeBehavior]s to [registry]. |
| 98 void resolveNativeMember(MemberElement element, NativeRegistry registry); | 41 void resolveNativeMember(MemberElement element, NativeRegistry registry); |
| 99 | 42 |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 node, _reporter, _compiler.commonElements, resolver); | 256 node, _reporter, _compiler.commonElements, resolver); |
| 314 } | 257 } |
| 315 | 258 |
| 316 @override | 259 @override |
| 317 NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) { | 260 NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) { |
| 318 return NativeBehavior.ofJsBuiltinCallSend( | 261 return NativeBehavior.ofJsBuiltinCallSend( |
| 319 node, _reporter, _compiler.commonElements, resolver); | 262 node, _reporter, _compiler.commonElements, resolver); |
| 320 } | 263 } |
| 321 } | 264 } |
| 322 | 265 |
| 323 /// Check whether [cls] has a `@Native(...)` annotation, and if so, set its | |
| 324 /// native name from the annotation. | |
| 325 checkNativeAnnotation(Compiler compiler, ClassElement cls, | |
| 326 NativeBasicDataBuilder nativeBasicDataBuilder) { | |
| 327 EagerAnnotationHandler.checkAnnotation( | |
| 328 compiler, cls, new NativeAnnotationHandler(nativeBasicDataBuilder)); | |
| 329 } | |
| 330 | |
| 331 /// Annotation handler for pre-resolution detection of `@Native(...)` | 266 /// Annotation handler for pre-resolution detection of `@Native(...)` |
| 332 /// annotations. | 267 /// annotations. |
| 333 class NativeAnnotationHandler extends EagerAnnotationHandler<String> { | 268 class NativeAnnotationHandler extends EagerAnnotationHandler<String> { |
| 334 final NativeBasicDataBuilder _nativeBasicDataBuilder; | 269 final NativeBasicDataBuilder _nativeBasicDataBuilder; |
| 335 | 270 |
| 336 NativeAnnotationHandler(this._nativeBasicDataBuilder); | 271 NativeAnnotationHandler(this._nativeBasicDataBuilder); |
| 337 | 272 |
| 338 String getNativeAnnotation(MetadataAnnotationX annotation) { | 273 String getNativeAnnotation(MetadataAnnotationX annotation) { |
| 339 if (annotation.beginToken != null && | 274 if (annotation.beginToken != null && |
| 340 annotation.beginToken.next.lexeme == 'Native') { | 275 annotation.beginToken.next.lexeme == 'Native') { |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 | 540 |
| 606 Iterable<ConstantValue> fields = constructedObject.fields.values; | 541 Iterable<ConstantValue> fields = constructedObject.fields.values; |
| 607 // TODO(sra): Better validation of the constant. | 542 // TODO(sra): Better validation of the constant. |
| 608 if (fields.length != 1 || fields.single is! StringConstantValue) { | 543 if (fields.length != 1 || fields.single is! StringConstantValue) { |
| 609 throw new SpannableAssertionFailure( | 544 throw new SpannableAssertionFailure( |
| 610 spannable, 'Annotations needs one string: ${value.toStructuredText()}'); | 545 spannable, 'Annotations needs one string: ${value.toStructuredText()}'); |
| 611 } | 546 } |
| 612 StringConstantValue specStringConstant = fields.single; | 547 StringConstantValue specStringConstant = fields.single; |
| 613 return specStringConstant.toDartString().slowToString(); | 548 return specStringConstant.toDartString().slowToString(); |
| 614 } | 549 } |
| OLD | NEW |