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