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' show ClassElement; | 8 import '../common_elements.dart' show ElementEnvironment; |
9 import '../elements/entities.dart'; | 9 import '../elements/entities.dart'; |
10 import '../native/behavior.dart' show NativeBehavior; | 10 import '../native/behavior.dart' show NativeBehavior; |
11 import '../util/util.dart'; | 11 import '../util/util.dart'; |
12 | 12 |
13 /// Basic information for native classes and js-interop libraries and classes. | 13 /// Basic information for native classes and js-interop libraries and classes. |
14 /// | 14 /// |
15 /// This information is computed during loading using [NativeBasicDataBuilder]. | 15 /// This information is computed during loading using [NativeBasicDataBuilder]. |
16 abstract class NativeBasicData { | 16 abstract class NativeBasicData { |
17 /// Returns `true` if [cls] corresponds to a native JavaScript class. | 17 /// Returns `true` if [cls] corresponds to a native JavaScript class. |
18 /// | 18 /// |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 void setNativeClassTagInfo(ClassEntity cls, String tagInfo); | 99 void setNativeClassTagInfo(ClassEntity cls, String tagInfo); |
100 | 100 |
101 /// Marks [element] as an explicit part of JsInterop. The js interop name is | 101 /// Marks [element] as an explicit part of JsInterop. The js interop name is |
102 /// expected to be computed later. | 102 /// expected to be computed later. |
103 void markAsJsInteropLibrary(LibraryEntity element); | 103 void markAsJsInteropLibrary(LibraryEntity element); |
104 | 104 |
105 /// Marks [element] as an explicit part of JsInterop. The js interop name is | 105 /// Marks [element] as an explicit part of JsInterop. The js interop name is |
106 /// expected to be computed later. | 106 /// expected to be computed later. |
107 void markAsJsInteropClass(ClassEntity element); | 107 void markAsJsInteropClass(ClassEntity element); |
108 | 108 |
109 NativeBasicData close(); | 109 /// Creates the [NativeBasicData] object for the data collected in this |
| 110 /// builder. |
| 111 NativeBasicData close(ElementEnvironment environment); |
110 } | 112 } |
111 | 113 |
112 abstract class NativeDataBuilder { | 114 abstract class NativeDataBuilder { |
113 /// Registers the [behavior] for calling the native [method]. | 115 /// Registers the [behavior] for calling the native [method]. |
114 void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior); | 116 void setNativeMethodBehavior(FunctionEntity method, NativeBehavior behavior); |
115 | 117 |
116 /// Registers the [behavior] for reading from the native [field]. | 118 /// Registers the [behavior] for reading from the native [field]. |
117 void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior); | 119 void setNativeFieldLoadBehavior(FieldEntity field, NativeBehavior behavior); |
118 | 120 |
119 /// Registers the [behavior] for writing to the native [field]. | 121 /// Registers the [behavior] for writing to the native [field]. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 @override | 175 @override |
174 void markAsJsInteropLibrary(LibraryEntity element) { | 176 void markAsJsInteropLibrary(LibraryEntity element) { |
175 jsInteropLibraries.add(element); | 177 jsInteropLibraries.add(element); |
176 } | 178 } |
177 | 179 |
178 @override | 180 @override |
179 void markAsJsInteropClass(ClassEntity element) { | 181 void markAsJsInteropClass(ClassEntity element) { |
180 jsInteropClasses.add(element); | 182 jsInteropClasses.add(element); |
181 } | 183 } |
182 | 184 |
183 NativeBasicData close() { | 185 NativeBasicData close(ElementEnvironment environment) { |
184 return new NativeBasicDataImpl( | 186 return new NativeBasicDataImpl( |
185 nativeClassTagInfo, jsInteropLibraries, jsInteropClasses); | 187 environment, nativeClassTagInfo, jsInteropLibraries, jsInteropClasses); |
186 } | 188 } |
187 } | 189 } |
188 | 190 |
189 class NativeBasicDataImpl implements NativeBasicData { | 191 class NativeBasicDataImpl implements NativeBasicData { |
| 192 final ElementEnvironment _env; |
| 193 |
190 /// Tag info for native JavaScript classes names. See | 194 /// Tag info for native JavaScript classes names. See |
191 /// [setNativeClassTagInfo]. | 195 /// [setNativeClassTagInfo]. |
192 final Map<ClassEntity, NativeClassTag> nativeClassTagInfo; | 196 final Map<ClassEntity, NativeClassTag> nativeClassTagInfo; |
193 | 197 |
194 /// The JavaScript libraries implemented via typed JavaScript interop. | 198 /// The JavaScript libraries implemented via typed JavaScript interop. |
195 final Set<LibraryEntity> jsInteropLibraries; | 199 final Set<LibraryEntity> jsInteropLibraries; |
196 | 200 |
197 /// The JavaScript classes implemented via typed JavaScript interop. | 201 /// The JavaScript classes implemented via typed JavaScript interop. |
198 final Set<ClassEntity> jsInteropClasses; | 202 final Set<ClassEntity> jsInteropClasses; |
199 | 203 |
200 NativeBasicDataImpl( | 204 NativeBasicDataImpl(this._env, this.nativeClassTagInfo, |
201 this.nativeClassTagInfo, this.jsInteropLibraries, this.jsInteropClasses); | 205 this.jsInteropLibraries, this.jsInteropClasses); |
202 | 206 |
203 /// Returns `true` if [cls] is a native class. | 207 /// Returns `true` if [cls] is a native class. |
204 bool isNativeClass(ClassEntity element) { | 208 bool isNativeClass(ClassEntity element) { |
205 if (isJsInteropClass(element)) return true; | 209 if (isJsInteropClass(element)) return true; |
206 return nativeClassTagInfo.containsKey(element); | 210 return nativeClassTagInfo.containsKey(element); |
207 } | 211 } |
208 | 212 |
209 /// Returns the list of non-directive native tag words for [cls]. | 213 /// Returns the list of non-directive native tag words for [cls]. |
210 List<String> getNativeTagsOfClass(ClassEntity cls) { | 214 List<String> getNativeTagsOfClass(ClassEntity cls) { |
211 return nativeClassTagInfo[cls].names; | 215 return nativeClassTagInfo[cls].names; |
212 } | 216 } |
213 | 217 |
214 /// Returns `true` if [cls] has a `!nonleaf` tag word. | 218 /// Returns `true` if [cls] has a `!nonleaf` tag word. |
215 bool hasNativeTagsForcedNonLeaf(ClassEntity cls) { | 219 bool hasNativeTagsForcedNonLeaf(ClassEntity cls) { |
216 return nativeClassTagInfo[cls].isNonLeaf; | 220 return nativeClassTagInfo[cls].isNonLeaf; |
217 } | 221 } |
218 | 222 |
219 /// Returns `true` if [element] is explicitly marked as part of JsInterop. | 223 /// Returns `true` if [element] is explicitly marked as part of JsInterop. |
220 bool isJsInteropLibrary(LibraryEntity element) { | 224 bool isJsInteropLibrary(LibraryEntity element) { |
221 return jsInteropLibraries.contains(element); | 225 return jsInteropLibraries.contains(element); |
222 } | 226 } |
223 | 227 |
224 /// Returns `true` if [element] is explicitly marked as part of JsInterop. | 228 /// Returns `true` if [element] is explicitly marked as part of JsInterop. |
225 bool isJsInteropClass(ClassEntity element) { | 229 bool isJsInteropClass(ClassEntity element) { |
226 return jsInteropClasses.contains(element); | 230 return jsInteropClasses.contains(element); |
227 } | 231 } |
228 | 232 |
229 /// Returns `true` if [element] or any of its superclasses is native. | 233 /// Returns `true` if [element] or any of its superclasses is native. |
230 bool isNativeOrExtendsNative(ClassElement element) { | 234 bool isNativeOrExtendsNative(ClassEntity element) { |
231 if (element == null) return false; | 235 if (element == null) return false; |
232 if (isNativeClass(element) || isJsInteropClass(element)) { | 236 if (isNativeClass(element) || isJsInteropClass(element)) { |
233 return true; | 237 return true; |
234 } | 238 } |
235 assert(element.isResolved); | 239 return isNativeOrExtendsNative(_env.getSuperClass(element)); |
236 return isNativeOrExtendsNative(element.superclass); | |
237 } | 240 } |
238 } | 241 } |
239 | 242 |
240 class NativeDataImpl implements NativeDataBuilder, NativeData { | 243 class NativeDataImpl implements NativeDataBuilder, NativeData { |
241 /// Prefix used to escape JS names that are not valid Dart names | 244 /// Prefix used to escape JS names that are not valid Dart names |
242 /// when using JSInterop. | 245 /// when using JSInterop. |
243 static const String _jsInteropEscapePrefix = r'JS$'; | 246 static const String _jsInteropEscapePrefix = r'JS$'; |
244 | 247 |
245 final NativeBasicData _nativeBasicData; | 248 final NativeBasicData _nativeBasicData; |
246 | 249 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
531 int get hashCode => Hashing.listHash(names, isNonLeaf.hashCode); | 534 int get hashCode => Hashing.listHash(names, isNonLeaf.hashCode); |
532 | 535 |
533 bool operator ==(other) { | 536 bool operator ==(other) { |
534 if (identical(this, other)) return true; | 537 if (identical(this, other)) return true; |
535 if (other is! NativeClassTag) return false; | 538 if (other is! NativeClassTag) return false; |
536 return equalElements(names, other.names) && isNonLeaf == other.isNonLeaf; | 539 return equalElements(names, other.names) && isNonLeaf == other.isNonLeaf; |
537 } | 540 } |
538 | 541 |
539 String toString() => text; | 542 String toString() => text; |
540 } | 543 } |
OLD | NEW |