Index: pkg/compiler/lib/src/js_backend/native_data.dart |
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart |
index 6480e32885b5ae2474f7c3f7a322b699e9365b5f..283e16d1d08c1804d4cedd58eff5807cc71ce5ae 100644 |
--- a/pkg/compiler/lib/src/js_backend/native_data.dart |
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart |
@@ -5,14 +5,7 @@ |
library js_backend.native_data; |
import '../common.dart'; |
-import '../elements/elements.dart' |
- show |
- ClassElement, |
- Element, |
- FieldElement, |
- LibraryElement, |
- MemberElement, |
- MethodElement; |
+import '../elements/elements.dart' show ClassElement; |
import '../elements/entities.dart'; |
import '../native/behavior.dart' show NativeBehavior; |
@@ -29,13 +22,13 @@ abstract class NativeClassData { |
bool isNativeClass(ClassEntity element); |
/// Returns `true` if [element] or any of its superclasses is native. |
- bool isNativeOrExtendsNative(ClassElement element); |
+ bool isNativeOrExtendsNative(ClassEntity element); |
/// Returns `true` if [element] is a JsInterop library. |
- bool isJsInteropLibrary(LibraryElement element); |
+ bool isJsInteropLibrary(LibraryEntity element); |
/// Returns `true` if [element] is a JsInterop class. |
- bool isJsInteropClass(ClassElement element); |
+ bool isJsInteropClass(ClassEntity element); |
} |
/// Additional element information for native classes and methods and js-interop |
@@ -52,17 +45,17 @@ abstract class NativeData extends NativeClassData { |
bool isNativeMember(MemberEntity element); |
/// Returns the [NativeBehavior] for calling the native [method]. |
- NativeBehavior getNativeMethodBehavior(MethodElement method); |
+ NativeBehavior getNativeMethodBehavior(FunctionEntity method); |
/// Returns the [NativeBehavior] for reading from the native [field]. |
- NativeBehavior getNativeFieldLoadBehavior(FieldElement field); |
+ NativeBehavior getNativeFieldLoadBehavior(FieldEntity field); |
/// Returns the [NativeBehavior] for writing to the native [field]. |
- NativeBehavior getNativeFieldStoreBehavior(FieldElement field); |
+ NativeBehavior getNativeFieldStoreBehavior(FieldEntity field); |
/// Returns `true` if the name of [element] is fixed for the generated |
/// JavaScript. |
- bool hasFixedBackendName(MemberElement element); |
+ bool hasFixedBackendName(MemberEntity element); |
/// Computes the name for [element] to use in the generated JavaScript. This |
/// is either given through a native annotation or a js interop annotation. |
@@ -71,25 +64,25 @@ abstract class NativeData extends NativeClassData { |
/// Computes the name prefix for [element to use in the generated JavaScript. |
/// For static and top-level members and constructors this is based on the |
/// names for the library and/or the enclosing class. |
- String getFixedBackendMethodPath(MethodElement element); |
+ String getFixedBackendMethodPath(FunctionEntity element); |
/// Returns the list of non-directive native tag words for [cls]. |
- List<String> getNativeTagsOfClass(ClassElement cls); |
+ List<String> getNativeTagsOfClass(ClassEntity cls); |
/// Returns `true` if [cls] has a `!nonleaf` tag word. |
- bool hasNativeTagsForcedNonLeaf(ClassElement cls); |
+ bool hasNativeTagsForcedNonLeaf(ClassEntity cls); |
/// Returns `true` if [element] is a JsInterop method. |
bool isJsInteropMember(MemberEntity element); |
/// Returns the explicit js interop name for library [element]. |
- String getJsInteropLibraryName(LibraryElement element); |
+ String getJsInteropLibraryName(LibraryEntity element); |
/// Returns the explicit js interop name for class [element]. |
- String getJsInteropClassName(ClassElement element); |
+ String getJsInteropClassName(ClassEntity element); |
/// Returns the explicit js interop name for member [element]. |
- String getJsInteropMemberName(MemberElement element); |
+ String getJsInteropMemberName(MemberEntity element); |
/// Apply JS$ escaping scheme to convert possible escaped Dart names into |
/// JS names. |
@@ -102,112 +95,111 @@ abstract class NativeClassDataBuilder { |
/// The tag info string contains comma-separated 'words' which are either |
/// dispatch tags (having JavaScript identifier syntax) and directives that |
/// begin with `!`. |
- void setNativeClassTagInfo(ClassElement cls, String tagInfo); |
+ void setNativeClassTagInfo(ClassEntity cls, String tagInfo); |
/// Marks [element] as an explicit part of JsInterop. The js interop name is |
/// expected to be computed later. |
- void markAsJsInteropLibrary(LibraryElement element); |
+ void markAsJsInteropLibrary(LibraryEntity element); |
/// Marks [element] as an explicit part of JsInterop. The js interop name is |
/// expected to be computed later. |
- void markAsJsInteropClass(ClassElement element); |
+ void markAsJsInteropClass(ClassEntity element); |
} |
abstract class NativeDataBuilder { |
/// Registers the [behavior] for calling the native [method]. |
- void setNativeMethodBehavior(MethodElement method, NativeBehavior behavior); |
+ void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior); |
/// Registers the [behavior] for reading from the native [field]. |
- void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior); |
+ void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior); |
/// Registers the [behavior] for writing to the native [field]. |
- void setNativeFieldStoreBehavior(FieldElement field, NativeBehavior behavior); |
+ void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior); |
/// Returns the list of native tag words for [cls]. |
- List<String> getNativeTagsOfClassRaw(ClassElement cls); |
+ List<String> getNativeTagsOfClassRaw(ClassEntity cls); |
/// Returns [element] as an explicit part of JsInterop. The js interop name is |
/// expected to be computed later. |
- void markAsJsInteropMember(MemberElement element); |
+ void markAsJsInteropMember(MemberEntity element); |
/// Sets the native [name] for the member [element]. This name is used for |
/// [element] in the generated JavaScript. |
- void setNativeMemberName(MemberElement element, String name); |
+ void setNativeMemberName(MemberEntity element, String name); |
/// Sets the explicit js interop [name] for the library [element]. |
- void setJsInteropLibraryName(LibraryElement element, String name); |
+ void setJsInteropLibraryName(LibraryEntity element, String name); |
/// Sets the explicit js interop [name] for the class [element]. |
- void setJsInteropClassName(ClassElement element, String name); |
+ void setJsInteropClassName(ClassEntity element, String name); |
/// Sets the explicit js interop [name] for the member [element]. |
- void setJsInteropMemberName(MemberElement element, String name); |
+ void setJsInteropMemberName(MemberEntity element, String name); |
} |
class NativeDataImpl |
implements NativeData, NativeDataBuilder, NativeClassDataBuilder { |
/// The JavaScript names for elements implemented via typed JavaScript |
/// interop. |
- Map<LibraryElement, String> jsInteropLibraryNames = |
- <LibraryElement, String>{}; |
- Map<ClassElement, String> jsInteropClassNames = <ClassElement, String>{}; |
- Map<MemberElement, String> jsInteropMemberNames = <MemberElement, String>{}; |
+ Map<LibraryEntity, String> jsInteropLibraryNames = <LibraryEntity, String>{}; |
+ Map<ClassEntity, String> jsInteropClassNames = <ClassEntity, String>{}; |
+ Map<MemberEntity, String> jsInteropMemberNames = <MemberEntity, String>{}; |
/// The JavaScript names for native JavaScript elements implemented. |
- Map<Element, String> nativeMemberName = <Element, String>{}; |
+ Map<MemberEntity, String> nativeMemberName = <MemberEntity, String>{}; |
/// Tag info for native JavaScript classes names. See |
/// [setNativeClassTagInfo]. |
- Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{}; |
+ Map<ClassEntity, String> nativeClassTagInfo = <ClassEntity, String>{}; |
/// Cache for [NativeBehavior]s for calling native methods. |
- Map<MethodElement, NativeBehavior> nativeMethodBehavior = |
- <MethodElement, NativeBehavior>{}; |
+ Map<FunctionEntity, NativeBehavior> nativeMethodBehavior = |
+ <FunctionEntity, NativeBehavior>{}; |
/// Cache for [NativeBehavior]s for reading from native fields. |
- Map<MemberElement, NativeBehavior> nativeFieldLoadBehavior = |
- <FieldElement, NativeBehavior>{}; |
+ Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior = |
+ <FieldEntity, NativeBehavior>{}; |
/// Cache for [NativeBehavior]s for writing to native fields. |
- Map<MemberElement, NativeBehavior> nativeFieldStoreBehavior = |
- <FieldElement, NativeBehavior>{}; |
+ Map<MemberEntity, NativeBehavior> nativeFieldStoreBehavior = |
+ <FieldEntity, NativeBehavior>{}; |
/// Prefix used to escape JS names that are not valid Dart names |
/// when using JSInterop. |
static const String _jsInteropEscapePrefix = r'JS$'; |
/// Returns `true` if [element] is explicitly marked as part of JsInterop. |
- bool _isJsInteropLibrary(LibraryElement element) { |
+ bool _isJsInteropLibrary(LibraryEntity element) { |
return jsInteropLibraryNames.containsKey(element); |
} |
/// Returns `true` if [element] is explicitly marked as part of JsInterop. |
- bool _isJsInteropClass(ClassElement element) { |
+ bool _isJsInteropClass(ClassEntity element) { |
return jsInteropClassNames.containsKey(element); |
} |
/// Returns `true` if [element] is explicitly marked as part of JsInterop. |
- bool _isJsInteropMember(MemberElement element) { |
+ bool _isJsInteropMember(MemberEntity element) { |
return jsInteropMemberNames.containsKey(element); |
} |
@override |
- void markAsJsInteropLibrary(LibraryElement element) { |
+ void markAsJsInteropLibrary(LibraryEntity element) { |
jsInteropLibraryNames[element] = null; |
} |
@override |
- void markAsJsInteropClass(ClassElement element) { |
+ void markAsJsInteropClass(ClassEntity element) { |
jsInteropClassNames[element] = null; |
} |
@override |
- void markAsJsInteropMember(MemberElement element) { |
+ void markAsJsInteropMember(MemberEntity element) { |
jsInteropMemberNames[element] = null; |
} |
/// Sets the explicit js interop [name] for the library [element]. |
- void setJsInteropLibraryName(LibraryElement element, String name) { |
+ void setJsInteropLibraryName(LibraryEntity element, String name) { |
assert(invariant(element, _isJsInteropLibrary(element), |
message: |
'Library $element is not js interop but given a js interop name.')); |
@@ -215,7 +207,7 @@ class NativeDataImpl |
} |
/// Sets the explicit js interop [name] for the class [element]. |
- void setJsInteropClassName(ClassElement element, String name) { |
+ void setJsInteropClassName(ClassEntity element, String name) { |
assert(invariant(element, _isJsInteropClass(element), |
message: |
'Class $element is not js interop but given a js interop name.')); |
@@ -223,7 +215,7 @@ class NativeDataImpl |
} |
/// Sets the explicit js interop [name] for the member [element]. |
- void setJsInteropMemberName(MemberElement element, String name) { |
+ void setJsInteropMemberName(MemberEntity element, String name) { |
assert(invariant(element, _isJsInteropMember(element), |
message: |
'Member $element is not js interop but given a js interop name.')); |
@@ -231,35 +223,38 @@ class NativeDataImpl |
} |
/// Returns the explicit js interop name for library [element]. |
- String getJsInteropLibraryName(LibraryElement element) { |
+ String getJsInteropLibraryName(LibraryEntity element) { |
return jsInteropLibraryNames[element]; |
} |
/// Returns the explicit js interop name for class [element]. |
- String getJsInteropClassName(ClassElement element) { |
+ String getJsInteropClassName(ClassEntity element) { |
return jsInteropClassNames[element]; |
} |
/// Returns the explicit js interop name for member [element]. |
- String getJsInteropMemberName(MemberElement element) { |
+ String getJsInteropMemberName(MemberEntity element) { |
return jsInteropMemberNames[element]; |
} |
/// Returns `true` if [element] is a JsInterop library. |
- bool isJsInteropLibrary(LibraryElement element) => |
+ bool isJsInteropLibrary(LibraryEntity element) => |
_isJsInteropLibrary(element); |
/// Returns `true` if [element] is a JsInterop class. |
- bool isJsInteropClass(ClassElement element) => _isJsInteropClass(element); |
+ bool isJsInteropClass(ClassEntity element) => _isJsInteropClass(element); |
/// Returns `true` if [element] is a JsInterop method. |
- bool isJsInteropMember(MemberElement element) { |
- if (element.isFunction || element.isConstructor || element.isAccessor) { |
- MethodElement function = element; |
+ bool isJsInteropMember(MemberEntity element) { |
+ if (element.isFunction || |
+ element.isConstructor || |
+ element.isGetter || |
+ element.isSetter) { |
+ FunctionEntity function = element; |
if (!function.isExternal) return false; |
if (_isJsInteropMember(function)) return true; |
- if (function.isClassMember) { |
+ if (function.enclosingClass != null) { |
return _isJsInteropClass(function.enclosingClass); |
} |
if (function.isTopLevel) { |
@@ -273,39 +268,38 @@ class NativeDataImpl |
/// Returns `true` if the name of [element] is fixed for the generated |
/// JavaScript. |
- bool hasFixedBackendName(MemberElement element) { |
- return isJsInteropMember(element) || |
- nativeMemberName.containsKey(element.declaration); |
+ bool hasFixedBackendName(MemberEntity element) { |
+ return isJsInteropMember(element) || nativeMemberName.containsKey(element); |
} |
/// Computes the name for [element] to use in the generated JavaScript. This |
/// is either given through a native annotation or a js interop annotation. |
- String getFixedBackendName(MemberElement element) { |
- String name = nativeMemberName[element.declaration]; |
+ String getFixedBackendName(MemberEntity element) { |
+ String name = nativeMemberName[element]; |
if (name == null && isJsInteropMember(element)) { |
// If an element isJsInterop but _isJsInterop is false that means it is |
// considered interop as the parent class is interop. |
name = element.isConstructor |
? _jsClassNameHelper(element.enclosingClass) |
: _jsMemberNameHelper(element); |
- nativeMemberName[element.declaration] = name; |
+ nativeMemberName[element] = name; |
} |
return name; |
} |
- String _jsLibraryNameHelper(LibraryElement element) { |
+ String _jsLibraryNameHelper(LibraryEntity element) { |
String jsInteropName = getJsInteropLibraryName(element); |
if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName; |
return 'self'; |
} |
- String _jsClassNameHelper(ClassElement element) { |
+ String _jsClassNameHelper(ClassEntity element) { |
String jsInteropName = getJsInteropClassName(element); |
if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName; |
return computeUnescapedJSInteropName(element.name); |
} |
- String _jsMemberNameHelper(MemberElement element) { |
+ String _jsMemberNameHelper(MemberEntity element) { |
String jsInteropName = jsInteropMemberNames[element]; |
assert(invariant(element, |
!(jsInteropMemberNames.containsKey(element) && jsInteropName == null), |
@@ -324,7 +318,7 @@ class NativeDataImpl |
/// For example: fixedBackendPath for the static method createMap in the |
/// Map class of the goog.map JavaScript library would have path |
/// "goog.maps.Map". |
- String getFixedBackendMethodPath(MethodElement element) { |
+ String getFixedBackendMethodPath(FunctionEntity element) { |
if (!isJsInteropMember(element)) return null; |
if (element.isInstanceMember) return 'this'; |
if (element.isConstructor) { |
@@ -338,19 +332,19 @@ class NativeDataImpl |
return sb.toString(); |
} |
- String _fixedBackendClassPath(ClassElement element) { |
+ String _fixedBackendClassPath(ClassEntity element) { |
if (!isJsInteropClass(element)) return null; |
return _jsLibraryNameHelper(element.library); |
} |
/// Returns `true` if [cls] is a native class. |
- bool isNativeClass(ClassElement element) { |
+ bool isNativeClass(ClassEntity element) { |
if (isJsInteropClass(element)) return true; |
return nativeClassTagInfo.containsKey(element); |
} |
/// Returns `true` if [element] is a native member of a native class. |
- bool isNativeMember(MemberElement element) { |
+ bool isNativeMember(MemberEntity element) { |
if (isJsInteropMember(element)) return true; |
return nativeMemberName.containsKey(element); |
} |
@@ -367,18 +361,16 @@ class NativeDataImpl |
/// Sets the native [name] for the member [element]. This name is used for |
/// [element] in the generated JavaScript. |
- void setNativeMemberName(MemberElement element, String name) { |
+ void setNativeMemberName(MemberEntity element, String name) { |
// TODO(johnniwinther): Avoid setting this more than once. The enqueuer |
// might enqueue [element] several times (before processing it) and computes |
// name on each call to `internalAddToWorkList`. |
- assert(invariant( |
- element, |
- nativeMemberName[element.declaration] == null || |
- nativeMemberName[element.declaration] == name, |
+ assert(invariant(element, |
+ nativeMemberName[element] == null || nativeMemberName[element] == name, |
message: "Native member name set inconsistently on $element: " |
- "Existing name '${nativeMemberName[element.declaration]}', " |
+ "Existing name '${nativeMemberName[element]}', " |
"new name '$name'.")); |
- nativeMemberName[element.declaration] = name; |
+ nativeMemberName[element] = name; |
} |
/// Sets the native tag info for [cls]. |
@@ -386,48 +378,46 @@ class NativeDataImpl |
/// The tag info string contains comma-separated 'words' which are either |
/// dispatch tags (having JavaScript identifier syntax) and directives that |
/// begin with `!`. |
- void setNativeClassTagInfo(ClassElement cls, String tagInfo) { |
+ void setNativeClassTagInfo(ClassEntity cls, String tagInfo) { |
// TODO(johnniwinther): Assert that this is only called once. The memory |
// compiler copies pre-processed elements into a new compiler through |
// [Compiler.onLibraryScanned] and thereby causes multiple calls to this |
// method. |
- assert(invariant( |
- cls, |
- nativeClassTagInfo[cls.declaration] == null || |
- nativeClassTagInfo[cls.declaration] == tagInfo, |
+ assert(invariant(cls, |
+ nativeClassTagInfo[cls] == null || nativeClassTagInfo[cls] == tagInfo, |
message: "Native tag info set inconsistently on $cls: " |
- "Existing tag info '${nativeClassTagInfo[cls.declaration]}', " |
+ "Existing tag info '${nativeClassTagInfo[cls]}', " |
"new tag info '$tagInfo'.")); |
- nativeClassTagInfo[cls.declaration] = tagInfo; |
+ nativeClassTagInfo[cls] = tagInfo; |
} |
/// Returns the list of native tag words for [cls]. |
- List<String> getNativeTagsOfClassRaw(ClassElement cls) { |
- String quotedName = nativeClassTagInfo[cls.declaration]; |
+ List<String> getNativeTagsOfClassRaw(ClassEntity cls) { |
+ String quotedName = nativeClassTagInfo[cls]; |
return quotedName.substring(1, quotedName.length - 1).split(','); |
} |
/// Returns the list of non-directive native tag words for [cls]. |
- List<String> getNativeTagsOfClass(ClassElement cls) { |
+ List<String> getNativeTagsOfClass(ClassEntity cls) { |
return getNativeTagsOfClassRaw(cls) |
.where((s) => !s.startsWith('!')) |
.toList(); |
} |
/// Returns `true` if [cls] has a `!nonleaf` tag word. |
- bool hasNativeTagsForcedNonLeaf(ClassElement cls) { |
+ bool hasNativeTagsForcedNonLeaf(ClassEntity cls) { |
return getNativeTagsOfClassRaw(cls).contains('!nonleaf'); |
} |
/// Returns the [NativeBehavior] for calling the native [method]. |
- NativeBehavior getNativeMethodBehavior(MethodElement method) { |
+ NativeBehavior getNativeMethodBehavior(FunctionEntity method) { |
assert(invariant(method, nativeMethodBehavior.containsKey(method), |
message: "No native method behavior has been computed for $method.")); |
return nativeMethodBehavior[method]; |
} |
/// Returns the [NativeBehavior] for reading from the native [field]. |
- NativeBehavior getNativeFieldLoadBehavior(FieldElement field) { |
+ NativeBehavior getNativeFieldLoadBehavior(FieldEntity field) { |
assert(invariant(field, nativeFieldLoadBehavior.containsKey(field), |
message: "No native field load behavior has been " |
"computed for $field.")); |
@@ -435,7 +425,7 @@ class NativeDataImpl |
} |
/// Returns the [NativeBehavior] for writing to the native [field]. |
- NativeBehavior getNativeFieldStoreBehavior(FieldElement field) { |
+ NativeBehavior getNativeFieldStoreBehavior(FieldEntity field) { |
assert(invariant(field, nativeFieldStoreBehavior.containsKey(field), |
message: "No native field store behavior has been " |
"computed for $field.")); |
@@ -443,18 +433,17 @@ class NativeDataImpl |
} |
/// Registers the [behavior] for calling the native [method]. |
- void setNativeMethodBehavior(MethodElement method, NativeBehavior behavior) { |
+ void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior) { |
nativeMethodBehavior[method] = behavior; |
} |
/// Registers the [behavior] for reading from the native [field]. |
- void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior) { |
+ void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior) { |
nativeFieldLoadBehavior[field] = behavior; |
} |
/// Registers the [behavior] for writing to the native [field]. |
- void setNativeFieldStoreBehavior( |
- FieldElement field, NativeBehavior behavior) { |
+ void setNativeFieldStoreBehavior(FieldEntity field, NativeBehavior behavior) { |
nativeFieldStoreBehavior[field] = behavior; |
} |