Chromium Code Reviews| 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, | |
| 14 LibraryElement, | 13 LibraryElement, |
| 15 MemberElement, | 14 MemberElement, |
| 16 MethodElement; | 15 MethodElement; |
| 17 import '../elements/entities.dart'; | 16 import '../elements/entities.dart'; |
| 18 import '../native/behavior.dart' show NativeBehavior; | 17 import '../native/behavior.dart' show NativeBehavior; |
| 19 | 18 |
| 20 /// Basic information for native classes and methods and js-interop | 19 /// Basic information for native classes and methods and js-interop |
| 21 /// classes. | 20 /// classes. |
| 22 /// | 21 /// |
| 23 /// This information is computed during loading using [NativeClassDataBuilder]. | 22 /// This information is computed during loading using [NativeClassDataBuilder]. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 NativeBehavior getNativeMethodBehavior(MethodElement method); | 55 NativeBehavior getNativeMethodBehavior(MethodElement method); |
| 57 | 56 |
| 58 /// Returns the [NativeBehavior] for reading from the native [field]. | 57 /// Returns the [NativeBehavior] for reading from the native [field]. |
| 59 NativeBehavior getNativeFieldLoadBehavior(FieldElement field); | 58 NativeBehavior getNativeFieldLoadBehavior(FieldElement field); |
| 60 | 59 |
| 61 /// Returns the [NativeBehavior] for writing to the native [field]. | 60 /// Returns the [NativeBehavior] for writing to the native [field]. |
| 62 NativeBehavior getNativeFieldStoreBehavior(FieldElement field); | 61 NativeBehavior getNativeFieldStoreBehavior(FieldElement field); |
| 63 | 62 |
| 64 /// Returns `true` if the name of [element] is fixed for the generated | 63 /// Returns `true` if the name of [element] is fixed for the generated |
| 65 /// JavaScript. | 64 /// JavaScript. |
| 66 bool hasFixedBackendName(Element element); | 65 bool hasFixedBackendName(MemberElement element); |
| 67 | 66 |
| 68 /// Computes the name for [element] to use in the generated JavaScript. This | 67 /// Computes the name for [element] to use in the generated JavaScript. This |
| 69 /// is either given through a native annotation or a js interop annotation. | 68 /// is either given through a native annotation or a js interop annotation. |
| 70 String getFixedBackendName(Entity entity); | 69 String getFixedBackendName(MemberEntity element); |
| 70 | |
| 71 /// Computes the name prefix for [element to use in the generated JavaScript. | |
|
Siggi Cherem (dart-lang)
2017/03/14 04:48:19
nit: add missing ]
Johnni Winther
2017/03/15 11:42:14
Done.
| |
| 72 /// For static and top-level members and constructors this is based on the | |
| 73 /// names for the library and/or the enclosing class. | |
|
Siggi Cherem (dart-lang)
2017/03/14 04:48:19
might be worth clarifying that here you mean JS na
Johnni Winther
2017/03/15 11:42:14
Done.
| |
| 74 String getFixedBackendMethodPath(MethodElement element); | |
| 71 | 75 |
| 72 /// Returns the list of non-directive native tag words for [cls]. | 76 /// Returns the list of non-directive native tag words for [cls]. |
| 73 List<String> getNativeTagsOfClass(ClassElement cls); | 77 List<String> getNativeTagsOfClass(ClassElement cls); |
| 74 | 78 |
| 75 /// Returns `true` if [cls] has a `!nonleaf` tag word. | 79 /// Returns `true` if [cls] has a `!nonleaf` tag word. |
| 76 bool hasNativeTagsForcedNonLeaf(ClassElement cls); | 80 bool hasNativeTagsForcedNonLeaf(ClassElement cls); |
| 77 | 81 |
| 78 /// Returns `true` if [element] is part of JsInterop. | 82 /// Returns `true` if [element] is a JsInterop method. |
| 79 /// | 83 bool isJsInteropMember(MemberEntity element); |
| 80 /// Deprecated: Use [isJsInteropLibrary], [isJsInteropClass] or | |
| 81 /// [isJsInteropMember] instead. | |
| 82 @deprecated | |
| 83 bool isJsInterop(Element element); | |
| 84 | 84 |
| 85 /// Returns `true` if [element] is a JsInterop method. | 85 /// Returns the explicit js interop name for library [element]. |
| 86 bool isJsInteropMember(MethodElement element); | 86 String getJsInteropLibraryName(LibraryElement element); |
| 87 | 87 |
| 88 /// Returns the explicit js interop name for [element]. | 88 /// Returns the explicit js interop name for class [element]. |
| 89 String getJsInteropName(Element element); | 89 String getJsInteropClassName(ClassElement element); |
| 90 | |
| 91 /// Returns the explicit js interop name for member [element]. | |
| 92 String getJsInteropMemberName(MemberElement element); | |
| 90 | 93 |
| 91 /// Apply JS$ escaping scheme to convert possible escaped Dart names into | 94 /// Apply JS$ escaping scheme to convert possible escaped Dart names into |
| 92 /// JS names. | 95 /// JS names. |
| 93 String getUnescapedJSInteropName(String name); | 96 String computeUnescapedJSInteropName(String name); |
| 94 } | 97 } |
| 95 | 98 |
| 96 abstract class NativeClassDataBuilder { | 99 abstract class NativeClassDataBuilder { |
| 97 /// Sets the native tag info for [cls]. | 100 /// Sets the native tag info for [cls]. |
| 98 /// | 101 /// |
| 99 /// The tag info string contains comma-separated 'words' which are either | 102 /// The tag info string contains comma-separated 'words' which are either |
| 100 /// dispatch tags (having JavaScript identifier syntax) and directives that | 103 /// dispatch tags (having JavaScript identifier syntax) and directives that |
| 101 /// begin with `!`. | 104 /// begin with `!`. |
| 102 void setNativeClassTagInfo(ClassElement cls, String tagInfo); | 105 void setNativeClassTagInfo(ClassElement cls, String tagInfo); |
| 103 | 106 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 124 List<String> getNativeTagsOfClassRaw(ClassElement cls); | 127 List<String> getNativeTagsOfClassRaw(ClassElement cls); |
| 125 | 128 |
| 126 /// Returns [element] as an explicit part of JsInterop. The js interop name is | 129 /// Returns [element] as an explicit part of JsInterop. The js interop name is |
| 127 /// expected to be computed later. | 130 /// expected to be computed later. |
| 128 void markAsJsInteropMember(MemberElement element); | 131 void markAsJsInteropMember(MemberElement element); |
| 129 | 132 |
| 130 /// Sets the native [name] for the member [element]. This name is used for | 133 /// Sets the native [name] for the member [element]. This name is used for |
| 131 /// [element] in the generated JavaScript. | 134 /// [element] in the generated JavaScript. |
| 132 void setNativeMemberName(MemberElement element, String name); | 135 void setNativeMemberName(MemberElement element, String name); |
| 133 | 136 |
| 134 /// Sets the explicit js interop [name] for [element]. | 137 /// Sets the explicit js interop [name] for the library [element]. |
| 135 void setJsInteropName(Element element, String name); | 138 void setJsInteropLibraryName(LibraryElement element, String name); |
| 139 | |
| 140 /// Sets the explicit js interop [name] for the class [element]. | |
| 141 void setJsInteropClassName(ClassElement element, String name); | |
| 142 | |
| 143 /// Sets the explicit js interop [name] for the member [element]. | |
| 144 void setJsInteropMemberName(MemberElement element, String name); | |
| 136 } | 145 } |
| 137 | 146 |
| 138 class NativeDataImpl | 147 class NativeDataImpl |
| 139 implements NativeData, NativeDataBuilder, NativeClassDataBuilder { | 148 implements NativeData, NativeDataBuilder, NativeClassDataBuilder { |
| 140 /// The JavaScript names for elements implemented via typed JavaScript | 149 /// The JavaScript names for elements implemented via typed JavaScript |
| 141 /// interop. | 150 /// interop. |
| 142 Map<Element, String> jsInteropNames = <Element, String>{}; | 151 Map<LibraryElement, String> jsInteropLibraryNames = |
| 152 <LibraryElement, String>{}; | |
| 153 Map<ClassElement, String> jsInteropClassNames = <ClassElement, String>{}; | |
| 154 Map<MemberElement, String> jsInteropMemberNames = <MemberElement, String>{}; | |
| 143 | 155 |
| 144 /// The JavaScript names for native JavaScript elements implemented. | 156 /// The JavaScript names for native JavaScript elements implemented. |
| 145 Map<Element, String> nativeMemberName = <Element, String>{}; | 157 Map<Element, String> nativeMemberName = <Element, String>{}; |
| 146 | 158 |
| 147 /// Tag info for native JavaScript classes names. See | 159 /// Tag info for native JavaScript classes names. See |
| 148 /// [setNativeClassTagInfo]. | 160 /// [setNativeClassTagInfo]. |
| 149 Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{}; | 161 Map<ClassElement, String> nativeClassTagInfo = <ClassElement, String>{}; |
| 150 | 162 |
| 151 /// Cache for [NativeBehavior]s for calling native methods. | 163 /// Cache for [NativeBehavior]s for calling native methods. |
| 152 Map<MethodElement, NativeBehavior> nativeMethodBehavior = | 164 Map<MethodElement, NativeBehavior> nativeMethodBehavior = |
| 153 <MethodElement, NativeBehavior>{}; | 165 <MethodElement, NativeBehavior>{}; |
| 154 | 166 |
| 155 /// Cache for [NativeBehavior]s for reading from native fields. | 167 /// Cache for [NativeBehavior]s for reading from native fields. |
| 156 Map<MemberElement, NativeBehavior> nativeFieldLoadBehavior = | 168 Map<MemberElement, NativeBehavior> nativeFieldLoadBehavior = |
| 157 <FieldElement, NativeBehavior>{}; | 169 <FieldElement, NativeBehavior>{}; |
| 158 | 170 |
| 159 /// Cache for [NativeBehavior]s for writing to native fields. | 171 /// Cache for [NativeBehavior]s for writing to native fields. |
| 160 Map<MemberElement, NativeBehavior> nativeFieldStoreBehavior = | 172 Map<MemberElement, NativeBehavior> nativeFieldStoreBehavior = |
| 161 <FieldElement, NativeBehavior>{}; | 173 <FieldElement, NativeBehavior>{}; |
| 162 | 174 |
| 163 /// Prefix used to escape JS names that are not valid Dart names | 175 /// Prefix used to escape JS names that are not valid Dart names |
| 164 /// when using JSInterop. | 176 /// when using JSInterop. |
| 165 static const String _jsInteropEscapePrefix = r'JS$'; | 177 static const String _jsInteropEscapePrefix = r'JS$'; |
| 166 | 178 |
| 167 /// Returns `true` if [element] is explicitly marked as part of JsInterop. | 179 /// Returns `true` if [element] is explicitly marked as part of JsInterop. |
| 168 bool _isJsInterop(Element element) { | 180 bool _isJsInteropLibrary(LibraryElement element) { |
| 169 return jsInteropNames.containsKey(element.declaration); | 181 return jsInteropLibraryNames.containsKey(element); |
| 170 } | 182 } |
| 171 | 183 |
| 172 /// Marks [element] as an explicit part of JsInterop. The js interop name is | 184 /// Returns `true` if [element] is explicitly marked as part of JsInterop. |
| 173 /// expected to be computed later. | 185 bool _isJsInteropClass(ClassElement element) { |
| 174 void markAsJsInterop(Element element) { | 186 return jsInteropClassNames.containsKey(element); |
| 175 jsInteropNames[element.declaration] = null; | 187 } |
| 188 | |
| 189 /// Returns `true` if [element] is explicitly marked as part of JsInterop. | |
| 190 bool _isJsInteropMember(MemberElement element) { | |
| 191 return jsInteropMemberNames.containsKey(element); | |
| 176 } | 192 } |
| 177 | 193 |
| 178 @override | 194 @override |
| 179 void markAsJsInteropLibrary(LibraryElement element) { | 195 void markAsJsInteropLibrary(LibraryElement element) { |
| 180 markAsJsInterop(element); | 196 jsInteropLibraryNames[element] = null; |
| 181 } | 197 } |
| 182 | 198 |
| 183 @override | 199 @override |
| 184 void markAsJsInteropClass(ClassElement element) { | 200 void markAsJsInteropClass(ClassElement element) { |
| 185 markAsJsInterop(element); | 201 jsInteropClassNames[element] = null; |
| 186 } | 202 } |
| 187 | 203 |
| 188 @override | 204 @override |
| 189 void markAsJsInteropMember(MemberElement element) { | 205 void markAsJsInteropMember(MemberElement element) { |
| 190 markAsJsInterop(element); | 206 jsInteropMemberNames[element] = null; |
| 191 } | 207 } |
| 192 | 208 |
| 193 /// Sets the explicit js interop [name] for [element]. | 209 /// Sets the explicit js interop [name] for the library [element]. |
| 194 void setJsInteropName(Element element, String name) { | 210 void setJsInteropLibraryName(LibraryElement element, String name) { |
| 195 assert(invariant(element, isJsInterop(element), | 211 assert(invariant(element, _isJsInteropLibrary(element), |
| 196 message: | 212 message: |
| 197 'Element $element is not js interop but given a js interop name.')); | 213 'Library $element is not js interop but given a js interop name.')); |
| 198 jsInteropNames[element.declaration] = name; | 214 jsInteropLibraryNames[element] = name; |
| 199 } | 215 } |
| 200 | 216 |
| 201 /// Returns the explicit js interop name for [element]. | 217 /// Sets the explicit js interop [name] for the class [element]. |
| 202 String getJsInteropName(Element element) { | 218 void setJsInteropClassName(ClassElement element, String name) { |
| 203 return jsInteropNames[element.declaration]; | 219 assert(invariant(element, _isJsInteropClass(element), |
| 220 message: | |
| 221 'Class $element is not js interop but given a js interop name.')); | |
| 222 jsInteropClassNames[element] = name; | |
| 204 } | 223 } |
| 205 | 224 |
| 206 /// Returns `true` if [element] is part of JsInterop. | 225 /// Sets the explicit js interop [name] for the member [element]. |
| 207 bool isJsInterop(Element element) { | 226 void setJsInteropMemberName(MemberElement element, String name) { |
| 208 // An function is part of JsInterop in the following cases: | 227 assert(invariant(element, _isJsInteropMember(element), |
| 209 // * It has a jsInteropName annotation | 228 message: |
| 210 // * It is external member of a class or library tagged as JsInterop. | 229 'Member $element is not js interop but given a js interop name.')); |
| 230 jsInteropMemberNames[element] = name; | |
| 231 } | |
| 232 | |
| 233 /// Returns the explicit js interop name for library [element]. | |
| 234 String getJsInteropLibraryName(LibraryElement element) { | |
| 235 return jsInteropLibraryNames[element]; | |
| 236 } | |
| 237 | |
| 238 /// Returns the explicit js interop name for class [element]. | |
| 239 String getJsInteropClassName(ClassElement element) { | |
| 240 return jsInteropClassNames[element]; | |
| 241 } | |
| 242 | |
| 243 /// Returns the explicit js interop name for member [element]. | |
| 244 String getJsInteropMemberName(MemberElement element) { | |
| 245 return jsInteropMemberNames[element]; | |
| 246 } | |
| 247 | |
| 248 /// Returns `true` if [element] is a JsInterop library. | |
| 249 bool isJsInteropLibrary(LibraryElement element) => | |
| 250 _isJsInteropLibrary(element); | |
| 251 | |
| 252 /// Returns `true` if [element] is a JsInterop class. | |
| 253 bool isJsInteropClass(ClassElement element) => _isJsInteropClass(element); | |
| 254 | |
| 255 /// Returns `true` if [element] is a JsInterop method. | |
| 256 bool isJsInteropMember(MemberElement element) { | |
| 211 if (element.isFunction || element.isConstructor || element.isAccessor) { | 257 if (element.isFunction || element.isConstructor || element.isAccessor) { |
| 212 FunctionElement function = element; | 258 MethodElement function = element; |
| 213 if (!function.isExternal) return false; | 259 if (!function.isExternal) return false; |
| 214 | 260 |
| 215 if (_isJsInterop(function)) return true; | 261 if (_isJsInteropMember(function)) return true; |
| 216 if (function.isClassMember) return isJsInterop(function.contextClass); | 262 if (function.isClassMember) { |
| 217 if (function.isTopLevel) return isJsInterop(function.library); | 263 return _isJsInteropClass(function.enclosingClass); |
| 264 } | |
| 265 if (function.isTopLevel) { | |
| 266 return _isJsInteropLibrary(function.library); | |
| 267 } | |
| 218 return false; | 268 return false; |
| 219 } else { | 269 } else { |
| 220 return _isJsInterop(element); | 270 return _isJsInteropMember(element); |
| 221 } | 271 } |
| 222 } | 272 } |
| 223 | 273 |
| 224 /// Returns `true` if [element] is a JsInterop library. | |
| 225 bool isJsInteropLibrary(LibraryElement element) => isJsInterop(element); | |
| 226 | |
| 227 /// Returns `true` if [element] is a JsInterop class. | |
| 228 bool isJsInteropClass(ClassElement element) => isJsInterop(element); | |
| 229 | |
| 230 /// Returns `true` if [element] is a JsInterop method. | |
| 231 bool isJsInteropMember(MethodElement element) => isJsInterop(element); | |
| 232 | |
| 233 /// Returns `true` if the name of [element] is fixed for the generated | 274 /// Returns `true` if the name of [element] is fixed for the generated |
| 234 /// JavaScript. | 275 /// JavaScript. |
| 235 bool hasFixedBackendName(Element element) { | 276 bool hasFixedBackendName(MemberElement element) { |
| 236 return isJsInterop(element) || | 277 return isJsInteropMember(element) || |
| 237 nativeMemberName.containsKey(element.declaration); | 278 nativeMemberName.containsKey(element.declaration); |
| 238 } | 279 } |
| 239 | 280 |
| 240 String _jsNameHelper(Element element) { | |
| 241 String jsInteropName = jsInteropNames[element.declaration]; | |
| 242 assert(invariant(element, !(_isJsInterop(element) && jsInteropName == null), | |
| 243 message: | |
| 244 'Element $element is js interop but js interop name has not yet ' | |
| 245 'been computed.')); | |
| 246 if (jsInteropName != null && jsInteropName.isNotEmpty) { | |
| 247 return jsInteropName; | |
| 248 } | |
| 249 return element.isLibrary ? 'self' : getUnescapedJSInteropName(element.name); | |
| 250 } | |
| 251 | |
| 252 /// Computes the name for [element] to use in the generated JavaScript. This | 281 /// Computes the name for [element] to use in the generated JavaScript. This |
| 253 /// is either given through a native annotation or a js interop annotation. | 282 /// is either given through a native annotation or a js interop annotation. |
| 254 String getFixedBackendName(Entity entity) { | 283 String getFixedBackendName(MemberElement element) { |
| 255 // TODO(johnniwinther): Remove this assignment from [Entity] to [Element] | |
| 256 // when `.declaration` is no longer needed. | |
| 257 Element element = entity; | |
| 258 String name = nativeMemberName[element.declaration]; | 284 String name = nativeMemberName[element.declaration]; |
| 259 if (name == null && isJsInterop(element)) { | 285 if (name == null && isJsInteropMember(element)) { |
| 260 // If an element isJsInterop but _isJsInterop is false that means it is | 286 // If an element isJsInterop but _isJsInterop is false that means it is |
| 261 // considered interop as the parent class is interop. | 287 // considered interop as the parent class is interop. |
| 262 name = _jsNameHelper( | 288 name = element.isConstructor |
| 263 element.isConstructor ? element.enclosingClass : element); | 289 ? _jsClassNameHelper(element.enclosingClass) |
| 290 : _jsMemberNameHelper(element); | |
| 264 nativeMemberName[element.declaration] = name; | 291 nativeMemberName[element.declaration] = name; |
| 265 } | 292 } |
| 266 return name; | 293 return name; |
| 267 } | 294 } |
| 268 | 295 |
| 269 /// Whether [element] corresponds to a native JavaScript construct either | 296 String _jsLibraryNameHelper(LibraryElement element) { |
| 270 /// through the native mechanism (`@Native(...)` or the `native` pseudo | 297 String jsInteropName = getJsInteropLibraryName(element); |
| 271 /// keyword) which is only allowed for internal libraries or via the typed | 298 if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName; |
| 272 /// JavaScriptInterop mechanism which is allowed for user libraries. | 299 return 'self'; |
| 273 bool isNative(Element element) { | 300 } |
| 274 if (isJsInterop(element)) return true; | 301 |
| 275 if (element.isClass) { | 302 String _jsClassNameHelper(ClassElement element) { |
| 276 return nativeClassTagInfo.containsKey(element.declaration); | 303 String jsInteropName = getJsInteropClassName(element); |
| 277 } else { | 304 if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName; |
| 278 return nativeMemberName.containsKey(element.declaration); | 305 return computeUnescapedJSInteropName(element.name); |
| 306 } | |
| 307 | |
| 308 String _jsMemberNameHelper(MemberElement element) { | |
| 309 String jsInteropName = jsInteropMemberNames[element]; | |
| 310 assert(invariant(element, | |
| 311 !(jsInteropMemberNames.containsKey(element) && jsInteropName == null), | |
| 312 message: | |
| 313 'Member $element is js interop but js interop name has not yet ' | |
| 314 'been computed.')); | |
| 315 if (jsInteropName != null && jsInteropName.isNotEmpty) { | |
| 316 return jsInteropName; | |
| 279 } | 317 } |
| 318 return computeUnescapedJSInteropName(element.name); | |
| 319 } | |
| 320 | |
| 321 /// Returns a JavaScript path specifying the context in which | |
| 322 /// [element.fixedBackendName] should be evaluated. Only applicable for | |
| 323 /// elements using typed JavaScript interop. | |
| 324 /// For example: fixedBackendPath for the static method createMap in the | |
| 325 /// Map class of the goog.map JavaScript library would have path | |
| 326 /// "goog.maps.Map". | |
| 327 String getFixedBackendMethodPath(MethodElement element) { | |
| 328 if (!isJsInteropMember(element)) return null; | |
| 329 if (element.isInstanceMember) return 'this'; | |
| 330 if (element.isConstructor) { | |
| 331 return _fixedBackendClassPath(element.enclosingClass); | |
| 332 } | |
| 333 StringBuffer sb = new StringBuffer(); | |
| 334 sb.write(_jsLibraryNameHelper(element.library)); | |
| 335 if (element.enclosingClass != null) { | |
| 336 sb..write('.')..write(_jsClassNameHelper(element.enclosingClass)); | |
| 337 } | |
| 338 return sb.toString(); | |
| 339 } | |
| 340 | |
| 341 String _fixedBackendClassPath(ClassElement element) { | |
| 342 if (!isJsInteropClass(element)) return null; | |
| 343 return _jsLibraryNameHelper(element.library); | |
| 280 } | 344 } |
| 281 | 345 |
| 282 /// Returns `true` if [cls] is a native class. | 346 /// Returns `true` if [cls] is a native class. |
| 283 bool isNativeClass(ClassElement element) => isNative(element); | 347 bool isNativeClass(ClassElement element) { |
| 348 if (isJsInteropClass(element)) return true; | |
| 349 return nativeClassTagInfo.containsKey(element); | |
| 350 } | |
| 284 | 351 |
| 285 /// Returns `true` if [element] is a native member of a native class. | 352 /// Returns `true` if [element] is a native member of a native class. |
| 286 bool isNativeMember(MemberElement element) => isNative(element); | 353 bool isNativeMember(MemberElement element) { |
| 354 if (isJsInteropMember(element)) return true; | |
| 355 return nativeMemberName.containsKey(element); | |
| 356 } | |
| 287 | 357 |
| 288 /// Returns `true` if [element] or any of its superclasses is native. | 358 /// Returns `true` if [element] or any of its superclasses is native. |
| 289 bool isNativeOrExtendsNative(ClassElement element) { | 359 bool isNativeOrExtendsNative(ClassElement element) { |
| 290 if (element == null) return false; | 360 if (element == null) return false; |
| 291 if (isNativeClass(element) || isJsInteropClass(element)) { | 361 if (isNativeClass(element) || isJsInteropClass(element)) { |
| 292 return true; | 362 return true; |
| 293 } | 363 } |
| 294 assert(element.isResolved); | 364 assert(element.isResolved); |
| 295 return isNativeOrExtendsNative(element.superclass); | 365 return isNativeOrExtendsNative(element.superclass); |
| 296 } | 366 } |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 } | 453 } |
| 384 | 454 |
| 385 /// Registers the [behavior] for writing to the native [field]. | 455 /// Registers the [behavior] for writing to the native [field]. |
| 386 void setNativeFieldStoreBehavior( | 456 void setNativeFieldStoreBehavior( |
| 387 FieldElement field, NativeBehavior behavior) { | 457 FieldElement field, NativeBehavior behavior) { |
| 388 nativeFieldStoreBehavior[field] = behavior; | 458 nativeFieldStoreBehavior[field] = behavior; |
| 389 } | 459 } |
| 390 | 460 |
| 391 /// Apply JS$ escaping scheme to convert possible escaped Dart names into | 461 /// Apply JS$ escaping scheme to convert possible escaped Dart names into |
| 392 /// JS names. | 462 /// JS names. |
| 393 String getUnescapedJSInteropName(String name) { | 463 String computeUnescapedJSInteropName(String name) { |
| 394 return name.startsWith(_jsInteropEscapePrefix) | 464 return name.startsWith(_jsInteropEscapePrefix) |
| 395 ? name.substring(_jsInteropEscapePrefix.length) | 465 ? name.substring(_jsInteropEscapePrefix.length) |
| 396 : name; | 466 : name; |
| 397 } | 467 } |
| 398 } | 468 } |
| OLD | NEW |