OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library js_backend.native_data; | 5 library js_backend.native_data; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../elements/elements.dart' | 8 import '../elements/elements.dart' |
9 show | 9 show |
10 ClassElement, | 10 ClassElement, |
11 Element, | 11 Element, |
12 FieldElement, | 12 FieldElement, |
13 FunctionElement, | 13 FunctionElement, |
14 LibraryElement, | |
14 MemberElement, | 15 MemberElement, |
15 MethodElement; | 16 MethodElement; |
16 import '../elements/entities.dart'; | 17 import '../elements/entities.dart'; |
17 import '../native/behavior.dart' show NativeBehavior; | 18 import '../native/behavior.dart' show NativeBehavior; |
18 | 19 |
19 /// Basic information for native classes and methods and js-interop | 20 /// Basic information for native classes and methods and js-interop |
20 /// classes. | 21 /// classes. |
21 /// | 22 /// |
22 /// This information is computed during loading using [NativeClassDataBuilder]. | 23 /// This information is computed during loading using [NativeClassDataBuilder]. |
23 abstract class NativeClassData { | 24 abstract class NativeClassData { |
24 /// Returns `true` if [cls] corresponds to a native JavaScript class. | 25 /// Returns `true` if [cls] corresponds to a native JavaScript class. |
25 /// | 26 /// |
26 /// A class is marked as native either through the `@Native(...)` annotation | 27 /// A class is marked as native either through the `@Native(...)` annotation |
27 /// allowed for internal libraries or via the typed JavaScriptInterop | 28 /// allowed for internal libraries or via the typed JavaScriptInterop |
28 /// mechanism allowed for user libraries. | 29 /// mechanism allowed for user libraries. |
29 bool isNativeClass(ClassEntity element); | 30 bool isNativeClass(ClassEntity element); |
30 | 31 |
31 /// Returns `true` if [element] or any of its superclasses is native. | 32 /// Returns `true` if [element] or any of its superclasses is native. |
32 bool isNativeOrExtendsNative(ClassElement element); | 33 bool isNativeOrExtendsNative(ClassElement element); |
33 | 34 |
34 /// Returns `true` if [element] corresponds to a native JavaScript member. | 35 /// Returns `true` if [element] is a JsInterop library. |
35 /// | 36 bool isJsInteropLibrary(LibraryElement element); |
Siggi Cherem (dart-lang)
2017/03/14 04:09:15
couple random thoughts here:
- maybe this means w
Johnni Winther
2017/03/15 10:55:13
Acknowledged.
| |
36 /// A member is marked as native either through the native mechanism | |
37 /// (`@Native(...)` or the `native` pseudo keyword) allowed for internal | |
38 /// libraries or via the typed JavaScriptInterop mechanism allowed for user | |
39 /// libraries. | |
40 bool isNativeMember(MemberEntity element); | |
41 | 37 |
42 /// Returns `true` if [element] is a JsInterop class. | 38 /// Returns `true` if [element] is a JsInterop class. |
43 bool isJsInteropClass(ClassElement element); | 39 bool isJsInteropClass(ClassElement element); |
44 } | 40 } |
45 | 41 |
46 /// Additional element information for native classes and methods and js-interop | 42 /// Additional element information for native classes and methods and js-interop |
47 /// methods. | 43 /// methods. |
48 /// | 44 /// |
49 /// This information is computed during resolution using [NativeDataBuilder]. | 45 /// This information is computed during resolution using [NativeDataBuilder]. |
50 abstract class NativeData extends NativeClassData { | 46 abstract class NativeData extends NativeClassData { |
47 /// Returns `true` if [element] corresponds to a native JavaScript member. | |
48 /// | |
49 /// A member is marked as native either through the native mechanism | |
50 /// (`@Native(...)` or the `native` pseudo keyword) allowed for internal | |
51 /// libraries or via the typed JavaScriptInterop mechanism allowed for user | |
52 /// libraries. | |
53 bool isNativeMember(MemberEntity element); | |
54 | |
51 /// Returns the [NativeBehavior] for calling the native [method]. | 55 /// Returns the [NativeBehavior] for calling the native [method]. |
52 NativeBehavior getNativeMethodBehavior(MethodElement method); | 56 NativeBehavior getNativeMethodBehavior(MethodElement method); |
53 | 57 |
54 /// Returns the [NativeBehavior] for reading from the native [field]. | 58 /// Returns the [NativeBehavior] for reading from the native [field]. |
55 NativeBehavior getNativeFieldLoadBehavior(FieldElement field); | 59 NativeBehavior getNativeFieldLoadBehavior(FieldElement field); |
56 | 60 |
57 /// Returns the [NativeBehavior] for writing to the native [field]. | 61 /// Returns the [NativeBehavior] for writing to the native [field]. |
58 NativeBehavior getNativeFieldStoreBehavior(FieldElement field); | 62 NativeBehavior getNativeFieldStoreBehavior(FieldElement field); |
59 | 63 |
60 /// Returns `true` if the name of [element] is fixed for the generated | 64 /// Returns `true` if the name of [element] is fixed for the generated |
61 /// JavaScript. | 65 /// JavaScript. |
62 bool hasFixedBackendName(Element element); | 66 bool hasFixedBackendName(Element element); |
63 | 67 |
64 /// Computes the name for [element] to use in the generated JavaScript. This | 68 /// Computes the name for [element] to use in the generated JavaScript. This |
65 /// is either given through a native annotation or a js interop annotation. | 69 /// is either given through a native annotation or a js interop annotation. |
66 String getFixedBackendName(Entity entity); | 70 String getFixedBackendName(Entity entity); |
67 | 71 |
68 /// Returns the list of non-directive native tag words for [cls]. | 72 /// Returns the list of non-directive native tag words for [cls]. |
69 List<String> getNativeTagsOfClass(ClassElement cls); | 73 List<String> getNativeTagsOfClass(ClassElement cls); |
70 | 74 |
71 /// Returns `true` if [cls] has a `!nonleaf` tag word. | 75 /// Returns `true` if [cls] has a `!nonleaf` tag word. |
72 bool hasNativeTagsForcedNonLeaf(ClassElement cls); | 76 bool hasNativeTagsForcedNonLeaf(ClassElement cls); |
73 | 77 |
74 /// Returns `true` if [element] is part of JsInterop. | 78 /// Returns `true` if [element] is part of JsInterop. |
79 /// | |
80 /// Deprecated: Use [isJsInteropLibrary], [isJsInteropClass] or | |
81 /// [isJsInteropMember] instead. | |
82 @deprecated | |
75 bool isJsInterop(Element element); | 83 bool isJsInterop(Element element); |
76 | 84 |
77 /// Returns `true` if [element] is a JsInterop method. | 85 /// Returns `true` if [element] is a JsInterop method. |
78 bool isJsInteropMethod(MethodElement element); | 86 bool isJsInteropMember(MethodElement element); |
79 | 87 |
80 /// Returns the explicit js interop name for [element]. | 88 /// Returns the explicit js interop name for [element]. |
81 String getJsInteropName(Element element); | 89 String getJsInteropName(Element element); |
82 | 90 |
83 /// Apply JS$ escaping scheme to convert possible escaped Dart names into | 91 /// Apply JS$ escaping scheme to convert possible escaped Dart names into |
84 /// JS names. | 92 /// JS names. |
85 String getUnescapedJSInteropName(String name); | 93 String getUnescapedJSInteropName(String name); |
86 } | 94 } |
87 | 95 |
88 abstract class NativeClassDataBuilder { | 96 abstract class NativeClassDataBuilder { |
89 /// Sets the native tag info for [cls]. | 97 /// Sets the native tag info for [cls]. |
90 /// | 98 /// |
91 /// The tag info string contains comma-separated 'words' which are either | 99 /// The tag info string contains comma-separated 'words' which are either |
92 /// dispatch tags (having JavaScript identifier syntax) and directives that | 100 /// dispatch tags (having JavaScript identifier syntax) and directives that |
93 /// begin with `!`. | 101 /// begin with `!`. |
94 void setNativeClassTagInfo(ClassElement cls, String tagInfo); | 102 void setNativeClassTagInfo(ClassElement cls, String tagInfo); |
95 | 103 |
96 /// Returns the list of native tag words for [cls]. | 104 /// Marks [element] as an explicit part of JsInterop. The js interop name is |
97 List<String> getNativeTagsOfClassRaw(ClassElement cls); | 105 /// expected to be computed later. |
106 void markAsJsInteropLibrary(LibraryElement element); | |
98 | 107 |
99 /// Sets the native [name] for the member [element]. This name is used for | 108 /// Marks [element] as an explicit part of JsInterop. The js interop name is |
100 /// [element] in the generated JavaScript. | |
101 void setNativeMemberName(MemberElement element, String name); | |
102 | |
103 /// Returns [element] as an explicit part of JsInterop. The js interop name is | |
104 /// expected to be computed later. | 109 /// expected to be computed later. |
105 void markAsJsInterop(Element element); | 110 void markAsJsInteropClass(ClassElement element); |
106 | |
107 /// Sets the explicit js interop [name] for [element]. | |
108 void setJsInteropName(Element element, String name); | |
109 } | 111 } |
110 | 112 |
111 abstract class NativeDataBuilder { | 113 abstract class NativeDataBuilder { |
112 /// Registers the [behavior] for calling the native [method]. | 114 /// Registers the [behavior] for calling the native [method]. |
113 void setNativeMethodBehavior(MethodElement method, NativeBehavior behavior); | 115 void setNativeMethodBehavior(MethodElement method, NativeBehavior behavior); |
114 | 116 |
115 /// Registers the [behavior] for reading from the native [field]. | 117 /// Registers the [behavior] for reading from the native [field]. |
116 void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior); | 118 void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior); |
117 | 119 |
118 /// Registers the [behavior] for writing to the native [field]. | 120 /// Registers the [behavior] for writing to the native [field]. |
119 void setNativeFieldStoreBehavior(FieldElement field, NativeBehavior behavior); | 121 void setNativeFieldStoreBehavior(FieldElement field, NativeBehavior behavior); |
122 | |
123 /// Returns the list of native tag words for [cls]. | |
124 List<String> getNativeTagsOfClassRaw(ClassElement cls); | |
125 | |
126 /// Returns [element] as an explicit part of JsInterop. The js interop name is | |
127 /// expected to be computed later. | |
128 void markAsJsInteropMember(MemberElement element); | |
129 | |
130 /// Sets the native [name] for the member [element]. This name is used for | |
131 /// [element] in the generated JavaScript. | |
132 void setNativeMemberName(MemberElement element, String name); | |
133 | |
134 /// Sets the explicit js interop [name] for [element]. | |
135 void setJsInteropName(Element element, String name); | |
120 } | 136 } |
121 | 137 |
122 class NativeDataImpl | 138 class NativeDataImpl |
123 implements NativeData, NativeDataBuilder, NativeClassDataBuilder { | 139 implements NativeData, NativeDataBuilder, NativeClassDataBuilder { |
124 /// The JavaScript names for elements implemented via typed JavaScript | 140 /// The JavaScript names for elements implemented via typed JavaScript |
125 /// interop. | 141 /// interop. |
126 Map<Element, String> jsInteropNames = <Element, String>{}; | 142 Map<Element, String> jsInteropNames = <Element, String>{}; |
127 | 143 |
128 /// The JavaScript names for native JavaScript elements implemented. | 144 /// The JavaScript names for native JavaScript elements implemented. |
129 Map<Element, String> nativeMemberName = <Element, String>{}; | 145 Map<Element, String> nativeMemberName = <Element, String>{}; |
(...skipping 16 matching lines...) Expand all Loading... | |
146 | 162 |
147 /// Prefix used to escape JS names that are not valid Dart names | 163 /// Prefix used to escape JS names that are not valid Dart names |
148 /// when using JSInterop. | 164 /// when using JSInterop. |
149 static const String _jsInteropEscapePrefix = r'JS$'; | 165 static const String _jsInteropEscapePrefix = r'JS$'; |
150 | 166 |
151 /// Returns `true` if [element] is explicitly marked as part of JsInterop. | 167 /// Returns `true` if [element] is explicitly marked as part of JsInterop. |
152 bool _isJsInterop(Element element) { | 168 bool _isJsInterop(Element element) { |
153 return jsInteropNames.containsKey(element.declaration); | 169 return jsInteropNames.containsKey(element.declaration); |
154 } | 170 } |
155 | 171 |
156 /// Returns [element] as an explicit part of JsInterop. The js interop name is | 172 /// Marks [element] as an explicit part of JsInterop. The js interop name is |
157 /// expected to be computed later. | 173 /// expected to be computed later. |
158 void markAsJsInterop(Element element) { | 174 void markAsJsInterop(Element element) { |
159 jsInteropNames[element.declaration] = null; | 175 jsInteropNames[element.declaration] = null; |
160 } | 176 } |
161 | 177 |
178 @override | |
179 void markAsJsInteropLibrary(LibraryElement element) { | |
180 markAsJsInterop(element); | |
181 } | |
182 | |
183 @override | |
184 void markAsJsInteropClass(ClassElement element) { | |
185 markAsJsInterop(element); | |
186 } | |
187 | |
188 @override | |
189 void markAsJsInteropMember(MemberElement element) { | |
190 markAsJsInterop(element); | |
191 } | |
192 | |
162 /// Sets the explicit js interop [name] for [element]. | 193 /// Sets the explicit js interop [name] for [element]. |
163 void setJsInteropName(Element element, String name) { | 194 void setJsInteropName(Element element, String name) { |
164 assert(invariant(element, isJsInterop(element), | 195 assert(invariant(element, isJsInterop(element), |
165 message: | 196 message: |
166 'Element $element is not js interop but given a js interop name.')); | 197 'Element $element is not js interop but given a js interop name.')); |
167 jsInteropNames[element.declaration] = name; | 198 jsInteropNames[element.declaration] = name; |
168 } | 199 } |
169 | 200 |
170 /// Returns the explicit js interop name for [element]. | 201 /// Returns the explicit js interop name for [element]. |
171 String getJsInteropName(Element element) { | 202 String getJsInteropName(Element element) { |
(...skipping 11 matching lines...) Expand all Loading... | |
183 | 214 |
184 if (_isJsInterop(function)) return true; | 215 if (_isJsInterop(function)) return true; |
185 if (function.isClassMember) return isJsInterop(function.contextClass); | 216 if (function.isClassMember) return isJsInterop(function.contextClass); |
186 if (function.isTopLevel) return isJsInterop(function.library); | 217 if (function.isTopLevel) return isJsInterop(function.library); |
187 return false; | 218 return false; |
188 } else { | 219 } else { |
189 return _isJsInterop(element); | 220 return _isJsInterop(element); |
190 } | 221 } |
191 } | 222 } |
192 | 223 |
224 /// Returns `true` if [element] is a JsInterop library. | |
225 bool isJsInteropLibrary(LibraryElement element) => isJsInterop(element); | |
226 | |
193 /// Returns `true` if [element] is a JsInterop class. | 227 /// Returns `true` if [element] is a JsInterop class. |
194 bool isJsInteropClass(ClassElement element) => isJsInterop(element); | 228 bool isJsInteropClass(ClassElement element) => isJsInterop(element); |
195 | 229 |
196 /// Returns `true` if [element] is a JsInterop method. | 230 /// Returns `true` if [element] is a JsInterop method. |
197 bool isJsInteropMethod(MethodElement element) => isJsInterop(element); | 231 bool isJsInteropMember(MethodElement element) => isJsInterop(element); |
198 | 232 |
199 /// Returns `true` if the name of [element] is fixed for the generated | 233 /// Returns `true` if the name of [element] is fixed for the generated |
200 /// JavaScript. | 234 /// JavaScript. |
201 bool hasFixedBackendName(Element element) { | 235 bool hasFixedBackendName(Element element) { |
202 return isJsInterop(element) || | 236 return isJsInterop(element) || |
203 nativeMemberName.containsKey(element.declaration); | 237 nativeMemberName.containsKey(element.declaration); |
204 } | 238 } |
205 | 239 |
206 String _jsNameHelper(Element element) { | 240 String _jsNameHelper(Element element) { |
207 String jsInteropName = jsInteropNames[element.declaration]; | 241 String jsInteropName = jsInteropNames[element.declaration]; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 } | 389 } |
356 | 390 |
357 /// Apply JS$ escaping scheme to convert possible escaped Dart names into | 391 /// Apply JS$ escaping scheme to convert possible escaped Dart names into |
358 /// JS names. | 392 /// JS names. |
359 String getUnescapedJSInteropName(String name) { | 393 String getUnescapedJSInteropName(String name) { |
360 return name.startsWith(_jsInteropEscapePrefix) | 394 return name.startsWith(_jsInteropEscapePrefix) |
361 ? name.substring(_jsInteropEscapePrefix.length) | 395 ? name.substring(_jsInteropEscapePrefix.length) |
362 : name; | 396 : name; |
363 } | 397 } |
364 } | 398 } |
OLD | NEW |