OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 elements.modelx; | 5 library elements.modelx; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart' show | 8 import '../common/resolution.dart' show |
9 Resolution, | 9 Resolution, |
10 Parsing; | 10 Parsing; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 ? enclosingElement.name | 227 ? enclosingElement.name |
228 : '${enclosingElement.kind}?'; | 228 : '${enclosingElement.kind}?'; |
229 return '$kind($holderName#${nameText})'; | 229 return '$kind($holderName#${nameText})'; |
230 } else { | 230 } else { |
231 return '$kind(${nameText})'; | 231 return '$kind(${nameText})'; |
232 } | 232 } |
233 } | 233 } |
234 | 234 |
235 String _fixedBackendName = null; | 235 String _fixedBackendName = null; |
236 bool _isNative = false; | 236 bool _isNative = false; |
237 bool get isNative => _isNative; | 237 String _jsInteropName = null; |
238 bool get hasFixedBackendName => _fixedBackendName != null; | 238 bool _isJsInterop = false; |
239 String get fixedBackendName => _fixedBackendName; | 239 |
| 240 /// Whether the element is implemented via typed JavaScript interop. |
| 241 bool get isJsInterop => _isJsInterop; |
| 242 /// JavaScript name for the element if it is implemented via typed JavaScript |
| 243 /// interop. |
| 244 String get jsInteropName => _jsInteropName; |
| 245 |
| 246 void markAsJsInterop() { |
| 247 _isJsInterop = true; |
| 248 } |
| 249 |
| 250 void setJsInteropName(String name) { |
| 251 assert(invariant(this, |
| 252 _isJsInterop, |
| 253 message: 'Element is not js interop but given a js interop name.')); |
| 254 _jsInteropName = name; |
| 255 } |
| 256 |
| 257 /// Whether the element corresponds to a native JavaScript construct either |
| 258 /// through the existing [setNative] mechanism which is only allowed |
| 259 /// for internal libraries or via the new typed JavaScriptInterop mechanism |
| 260 /// which is allowed for user libraries. |
| 261 bool get isNative => _isNative || isJsInterop; |
| 262 bool get hasFixedBackendName => fixedBackendName != null || isJsInterop; |
| 263 |
| 264 String _jsNameHelper(Element e) { |
| 265 assert(invariant(this, |
| 266 !(_isJsInterop && _jsInteropName == null), |
| 267 message: |
| 268 'Element is js interop but js interop name has not yet been' |
| 269 'computed.')); |
| 270 if (e.jsInteropName != null && e.jsInteropName.isNotEmpty) { |
| 271 return e.jsInteropName; |
| 272 } |
| 273 return e.isLibrary ? 'self' : e.name; |
| 274 } |
| 275 |
| 276 String get fixedBackendName { |
| 277 if (_fixedBackendName == null && isJsInterop) { |
| 278 // If an element isJsInterop but _isJsInterop is false that means it is |
| 279 // considered interop as the parent class is interop. |
| 280 _fixedBackendName = _jsNameHelper(isConstructor ? enclosingClass : this); |
| 281 } |
| 282 return _fixedBackendName; |
| 283 } |
| 284 |
240 // Marks this element as a native element. | 285 // Marks this element as a native element. |
241 void setNative(String name) { | 286 void setNative(String name) { |
242 _isNative = true; | 287 _isNative = true; |
243 _fixedBackendName = name; | 288 _fixedBackendName = name; |
244 } | 289 } |
245 | 290 |
246 FunctionElement asFunctionElement() => null; | 291 FunctionElement asFunctionElement() => null; |
247 | 292 |
248 bool get isAbstract => modifiers.isAbstract; | 293 bool get isAbstract => modifiers.isAbstract; |
249 | 294 |
(...skipping 1751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 | 2046 |
2002 void set functionSignature(FunctionSignature value) { | 2047 void set functionSignature(FunctionSignature value) { |
2003 // TODO(johnniwinther): Strengthen the invariant to `!hasFunctionSignature` | 2048 // TODO(johnniwinther): Strengthen the invariant to `!hasFunctionSignature` |
2004 // when checked mode checks are not enqueued eagerly. | 2049 // when checked mode checks are not enqueued eagerly. |
2005 assert(invariant(this, !hasFunctionSignature || type == value.type, | 2050 assert(invariant(this, !hasFunctionSignature || type == value.type, |
2006 message: "Function signature has already been computed for $this.")); | 2051 message: "Function signature has already been computed for $this.")); |
2007 _functionSignatureCache = value; | 2052 _functionSignatureCache = value; |
2008 typeCache = _functionSignatureCache.type; | 2053 typeCache = _functionSignatureCache.type; |
2009 } | 2054 } |
2010 | 2055 |
| 2056 /// An function is part of JsInterop in the following cases: |
| 2057 /// * It has a jsInteropName annotation |
| 2058 /// * It is external member of a class or library tagged as JsInterop. |
| 2059 bool get isJsInterop { |
| 2060 if (!isExternal) return false; |
| 2061 |
| 2062 if (super.isJsInterop) return true; |
| 2063 if (isClassMember) return contextClass.isJsInterop; |
| 2064 if (isTopLevel) return library.isJsInterop; |
| 2065 return false; |
| 2066 } |
| 2067 |
2011 List<ParameterElement> get parameters { | 2068 List<ParameterElement> get parameters { |
2012 // TODO(johnniwinther): Store the list directly, possibly by using List | 2069 // TODO(johnniwinther): Store the list directly, possibly by using List |
2013 // instead of Link in FunctionSignature. | 2070 // instead of Link in FunctionSignature. |
2014 List<ParameterElement> list = <ParameterElement>[]; | 2071 List<ParameterElement> list = <ParameterElement>[]; |
2015 functionSignature.forEachParameter((e) => list.add(e)); | 2072 functionSignature.forEachParameter((e) => list.add(e)); |
2016 return list; | 2073 return list; |
2017 } | 2074 } |
2018 | 2075 |
2019 FunctionType computeType(Resolution resolution) { | 2076 FunctionType computeType(Resolution resolution) { |
2020 if (typeCache != null) return typeCache; | 2077 if (typeCache != null) return typeCache; |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2621 } | 2678 } |
2622 | 2679 |
2623 void forEachBackendMember(void f(Element member)) { | 2680 void forEachBackendMember(void f(Element member)) { |
2624 backendMembers.forEach(f); | 2681 backendMembers.forEach(f); |
2625 } | 2682 } |
2626 | 2683 |
2627 bool implementsFunction(Compiler compiler) { | 2684 bool implementsFunction(Compiler compiler) { |
2628 return asInstanceOf(compiler.functionClass) != null || callType != null; | 2685 return asInstanceOf(compiler.functionClass) != null || callType != null; |
2629 } | 2686 } |
2630 | 2687 |
2631 bool get isNative => nativeTagInfo != null; | 2688 bool get isNative => nativeTagInfo != null || isJsInterop; |
2632 | 2689 |
2633 void setNative(String name) { | 2690 void setNative(String name) { |
2634 // TODO(johnniwinther): Assert that this is only called once. The memory | 2691 // TODO(johnniwinther): Assert that this is only called once. The memory |
2635 // compiler copies pre-processed elements into a new compiler through | 2692 // compiler copies pre-processed elements into a new compiler through |
2636 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this | 2693 // [Compiler.onLibraryScanned] and thereby causes multiple calls to this |
2637 // method. | 2694 // method. |
2638 assert(invariant(this, nativeTagInfo == null || nativeTagInfo == name, | 2695 assert(invariant(this, nativeTagInfo == null || nativeTagInfo == name, |
2639 message: "Native tag info set inconsistently on $this: " | 2696 message: "Native tag info set inconsistently on $this: " |
2640 "Existing name '$nativeTagInfo', new name '$name'.")); | 2697 "Existing name '$nativeTagInfo', new name '$name'.")); |
2641 nativeTagInfo = name; | 2698 nativeTagInfo = name; |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3126 AstElement get definingElement; | 3183 AstElement get definingElement; |
3127 | 3184 |
3128 bool get hasResolvedAst => definingElement.hasTreeElements; | 3185 bool get hasResolvedAst => definingElement.hasTreeElements; |
3129 | 3186 |
3130 ResolvedAst get resolvedAst { | 3187 ResolvedAst get resolvedAst { |
3131 return new ResolvedAst(declaration, | 3188 return new ResolvedAst(declaration, |
3132 definingElement.node, definingElement.treeElements); | 3189 definingElement.node, definingElement.treeElements); |
3133 } | 3190 } |
3134 | 3191 |
3135 } | 3192 } |
OLD | NEW |