| 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 |