| 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' show StringToken, Token; | 5 import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token; |
| 6 import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN; | 6 import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN; |
| 7 import 'package:front_end/src/scanner/token.dart' show BeginToken; | 7 import 'package:front_end/src/scanner/token.dart' show BeginToken; |
| 8 | 8 |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../common_elements.dart' show CommonElements, ElementEnvironment; | 10 import '../common_elements.dart' show CommonElements, ElementEnvironment; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 } | 73 } |
| 74 | 74 |
| 75 abstract class NativeMemberResolverBase implements NativeMemberResolver { | 75 abstract class NativeMemberResolverBase implements NativeMemberResolver { |
| 76 static final RegExp _identifier = new RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$'); | 76 static final RegExp _identifier = new RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$'); |
| 77 | 77 |
| 78 ElementEnvironment get elementEnvironment; | 78 ElementEnvironment get elementEnvironment; |
| 79 CommonElements get commonElements; | 79 CommonElements get commonElements; |
| 80 NativeBasicData get nativeBasicData; | 80 NativeBasicData get nativeBasicData; |
| 81 NativeDataBuilder get nativeDataBuilder; | 81 NativeDataBuilder get nativeDataBuilder; |
| 82 | 82 |
| 83 bool isJsInteropMember(MemberEntity element); | 83 bool isJsInteropMember(covariant MemberEntity element); |
| 84 bool isNativeMethod(FunctionEntity element); | 84 bool isNativeMethod(covariant FunctionEntity element); |
| 85 | 85 |
| 86 NativeBehavior computeNativeMethodBehavior(FunctionEntity function, | 86 NativeBehavior computeNativeMethodBehavior(covariant FunctionEntity function, |
| 87 {bool isJsInterop}); | 87 {bool isJsInterop}); |
| 88 NativeBehavior computeNativeFieldLoadBehavior(FieldEntity field, | 88 NativeBehavior computeNativeFieldLoadBehavior(covariant FieldEntity field, |
| 89 {bool isJsInterop}); | 89 {bool isJsInterop}); |
| 90 NativeBehavior computeNativeFieldStoreBehavior(FieldEntity field); | 90 NativeBehavior computeNativeFieldStoreBehavior(covariant FieldEntity field); |
| 91 | 91 |
| 92 @override | 92 @override |
| 93 void resolveNativeMember(MemberEntity element, [NativeRegistry registry]) { | 93 void resolveNativeMember(MemberEntity element, [NativeRegistry registry]) { |
| 94 bool isJsInterop = isJsInteropMember(element); | 94 bool isJsInterop = isJsInteropMember(element); |
| 95 if (element.isFunction || | 95 if (element.isFunction || |
| 96 element.isConstructor || | 96 element.isConstructor || |
| 97 element.isGetter || | 97 element.isGetter || |
| 98 element.isSetter) { | 98 element.isSetter) { |
| 99 FunctionEntity method = element; | 99 FunctionEntity method = element; |
| 100 bool isNative = _processMethodAnnotations(method); | 100 bool isNative = _processMethodAnnotations(method); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 121 // only get one look at each member and there might be a load or store | 121 // only get one look at each member and there might be a load or store |
| 122 // we have not seen yet. | 122 // we have not seen yet. |
| 123 registry?.registerNativeData(fieldLoadBehavior); | 123 registry?.registerNativeData(fieldLoadBehavior); |
| 124 registry?.registerNativeData(fieldStoreBehavior); | 124 registry?.registerNativeData(fieldStoreBehavior); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 | 128 |
| 129 /// Process the potentially native [field]. Adds information from metadata | 129 /// Process the potentially native [field]. Adds information from metadata |
| 130 /// attributes. Returns `true` of [method] is native. | 130 /// attributes. Returns `true` of [method] is native. |
| 131 bool _processFieldAnnotations(FieldEntity element) { | 131 bool _processFieldAnnotations(covariant FieldEntity element) { |
| 132 if (element.isInstanceMember && | 132 if (element.isInstanceMember && |
| 133 nativeBasicData.isNativeClass(element.enclosingClass)) { | 133 nativeBasicData.isNativeClass(element.enclosingClass)) { |
| 134 // Exclude non-instance (static) fields - they are not really native and | 134 // Exclude non-instance (static) fields - they are not really native and |
| 135 // are compiled as isolate globals. Access of a property of a constructor | 135 // are compiled as isolate globals. Access of a property of a constructor |
| 136 // function or a non-method property in the prototype chain, must be coded | 136 // function or a non-method property in the prototype chain, must be coded |
| 137 // using a JS-call. | 137 // using a JS-call. |
| 138 _setNativeName(element); | 138 _setNativeName(element); |
| 139 return true; | 139 return true; |
| 140 } | 140 } |
| 141 return false; | 141 return false; |
| 142 } | 142 } |
| 143 | 143 |
| 144 /// Process the potentially native [method]. Adds information from metadata | 144 /// Process the potentially native [method]. Adds information from metadata |
| 145 /// attributes. Returns `true` of [method] is native. | 145 /// attributes. Returns `true` of [method] is native. |
| 146 bool _processMethodAnnotations(FunctionEntity method) { | 146 bool _processMethodAnnotations(covariant FunctionEntity method) { |
| 147 if (isNativeMethod(method)) { | 147 if (isNativeMethod(method)) { |
| 148 if (method.isStatic) { | 148 if (method.isStatic) { |
| 149 _setNativeNameForStaticMethod(method); | 149 _setNativeNameForStaticMethod(method); |
| 150 } else { | 150 } else { |
| 151 _setNativeName(method); | 151 _setNativeName(method); |
| 152 } | 152 } |
| 153 return true; | 153 return true; |
| 154 } | 154 } |
| 155 return false; | 155 return false; |
| 156 } | 156 } |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 LibraryEntity library, Set<ClassEntity> nativeClasses) { | 428 LibraryEntity library, Set<ClassEntity> nativeClasses) { |
| 429 _elementEnvironment.forEachClass(library, (ClassEntity cls) { | 429 _elementEnvironment.forEachClass(library, (ClassEntity cls) { |
| 430 if (_nativeBasicData.isNativeClass(cls)) { | 430 if (_nativeBasicData.isNativeClass(cls)) { |
| 431 _processNativeClass(cls, nativeClasses); | 431 _processNativeClass(cls, nativeClasses); |
| 432 } | 432 } |
| 433 }); | 433 }); |
| 434 } | 434 } |
| 435 | 435 |
| 436 /// Adds [cls] to [nativeClasses] and performs further processing of [cls], | 436 /// Adds [cls] to [nativeClasses] and performs further processing of [cls], |
| 437 /// if necessary. | 437 /// if necessary. |
| 438 void _processNativeClass(ClassEntity cls, Set<ClassEntity> nativeClasses) { | 438 void _processNativeClass( |
| 439 covariant ClassEntity cls, Set<ClassEntity> nativeClasses) { |
| 439 nativeClasses.add(cls); | 440 nativeClasses.add(cls); |
| 440 // Js Interop interfaces do not have tags. | 441 // Js Interop interfaces do not have tags. |
| 441 if (_nativeBasicData.isJsInteropClass(cls)) return; | 442 if (_nativeBasicData.isJsInteropClass(cls)) return; |
| 442 // Since we map from dispatch tags to classes, a dispatch tag must be used | 443 // Since we map from dispatch tags to classes, a dispatch tag must be used |
| 443 // on only one native class. | 444 // on only one native class. |
| 444 for (String tag in _nativeBasicData.getNativeTagsOfClass(cls)) { | 445 for (String tag in _nativeBasicData.getNativeTagsOfClass(cls)) { |
| 445 ClassEntity owner = _tagOwner[tag]; | 446 ClassEntity owner = _tagOwner[tag]; |
| 446 if (owner != null) { | 447 if (owner != null) { |
| 447 if (owner != cls) { | 448 if (owner != cls) { |
| 448 throw new SpannableAssertionFailure( | 449 throw new SpannableAssertionFailure( |
| 449 cls, "Tag '$tag' already in use by '${owner.name}'"); | 450 cls, "Tag '$tag' already in use by '${owner.name}'"); |
| 450 } | 451 } |
| 451 } else { | 452 } else { |
| 452 _tagOwner[tag] = cls; | 453 _tagOwner[tag] = cls; |
| 453 } | 454 } |
| 454 } | 455 } |
| 455 } | 456 } |
| 456 | 457 |
| 457 /// Returns the name of the super class of [cls] or `null` of [cls] has | 458 /// Returns the name of the super class of [cls] or `null` of [cls] has |
| 458 /// no explicit superclass. | 459 /// no explicit superclass. |
| 459 String _findExtendsNameOfClass(ClassEntity cls) { | 460 String _findExtendsNameOfClass(covariant ClassEntity cls) { |
| 460 return _elementEnvironment | 461 return _elementEnvironment |
| 461 .getSuperClass(cls, skipUnnamedMixinApplications: true) | 462 .getSuperClass(cls, skipUnnamedMixinApplications: true) |
| 462 ?.name; | 463 ?.name; |
| 463 } | 464 } |
| 464 | 465 |
| 465 /// Adds all subclasses of [nativeClasses] found in [libraries] to | 466 /// Adds all subclasses of [nativeClasses] found in [libraries] to |
| 466 /// [nativeClasses]. | 467 /// [nativeClasses]. |
| 467 void _processSubclassesOfNativeClasses( | 468 void _processSubclassesOfNativeClasses( |
| 468 Iterable<LibraryEntity> libraries, Set<ClassEntity> nativeClasses) { | 469 Iterable<LibraryEntity> libraries, Set<ClassEntity> nativeClasses) { |
| 469 Set<ClassEntity> nativeClassesAndSubclasses = new Set<ClassEntity>(); | 470 Set<ClassEntity> nativeClassesAndSubclasses = new Set<ClassEntity>(); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 | 618 |
| 618 Iterable<ConstantValue> fields = constructedObject.fields.values; | 619 Iterable<ConstantValue> fields = constructedObject.fields.values; |
| 619 // TODO(sra): Better validation of the constant. | 620 // TODO(sra): Better validation of the constant. |
| 620 if (fields.length != 1 || fields.single is! StringConstantValue) { | 621 if (fields.length != 1 || fields.single is! StringConstantValue) { |
| 621 throw new SpannableAssertionFailure( | 622 throw new SpannableAssertionFailure( |
| 622 spannable, 'Annotations needs one string: ${value.toStructuredText()}'); | 623 spannable, 'Annotations needs one string: ${value.toStructuredText()}'); |
| 623 } | 624 } |
| 624 StringConstantValue specStringConstant = fields.single; | 625 StringConstantValue specStringConstant = fields.single; |
| 625 return specStringConstant.primitiveValue; | 626 return specStringConstant.primitiveValue; |
| 626 } | 627 } |
| OLD | NEW |