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