Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: pkg/compiler/lib/src/js_backend/native_data.dart

Issue 2732793002: Add NativeDataResolver (Closed)
Patch Set: Fix. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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, 13 FunctionElement,
14 LibraryElement,
14 MemberElement, 15 MemberElement,
15 MethodElement; 16 MethodElement;
16 import '../elements/entities.dart'; 17 import '../elements/entities.dart';
17 import '../native/behavior.dart' show NativeBehavior; 18 import '../native/behavior.dart' show NativeBehavior;
18 19
19 /// Basic information for native classes and methods and js-interop 20 /// Basic information for native classes and methods and js-interop
20 /// classes. 21 /// classes.
21 /// 22 ///
22 /// This information is computed during loading using [NativeClassDataBuilder]. 23 /// This information is computed during loading using [NativeClassDataBuilder].
23 abstract class NativeClassData { 24 abstract class NativeClassData {
24 /// Returns `true` if [cls] corresponds to a native JavaScript class. 25 /// Returns `true` if [cls] corresponds to a native JavaScript class.
25 /// 26 ///
26 /// A class is marked as native either through the `@Native(...)` annotation 27 /// A class is marked as native either through the `@Native(...)` annotation
27 /// allowed for internal libraries or via the typed JavaScriptInterop 28 /// allowed for internal libraries or via the typed JavaScriptInterop
28 /// mechanism allowed for user libraries. 29 /// mechanism allowed for user libraries.
29 bool isNativeClass(ClassEntity element); 30 bool isNativeClass(ClassEntity element);
30 31
31 /// Returns `true` if [element] or any of its superclasses is native. 32 /// Returns `true` if [element] or any of its superclasses is native.
32 bool isNativeOrExtendsNative(ClassElement element); 33 bool isNativeOrExtendsNative(ClassElement element);
33 34
34 /// Returns `true` if [element] corresponds to a native JavaScript member. 35 /// Returns `true` if [element] is a JsInterop library.
35 /// 36 bool isJsInteropLibrary(LibraryElement element);
Siggi Cherem (dart-lang) 2017/03/14 04:09:15 couple random thoughts here: - maybe this means w
Johnni Winther 2017/03/15 10:55:13 Acknowledged.
36 /// A member is marked as native either through the native mechanism
37 /// (`@Native(...)` or the `native` pseudo keyword) allowed for internal
38 /// libraries or via the typed JavaScriptInterop mechanism allowed for user
39 /// libraries.
40 bool isNativeMember(MemberEntity element);
41 37
42 /// Returns `true` if [element] is a JsInterop class. 38 /// Returns `true` if [element] is a JsInterop class.
43 bool isJsInteropClass(ClassElement element); 39 bool isJsInteropClass(ClassElement element);
44 } 40 }
45 41
46 /// Additional element information for native classes and methods and js-interop 42 /// Additional element information for native classes and methods and js-interop
47 /// methods. 43 /// methods.
48 /// 44 ///
49 /// This information is computed during resolution using [NativeDataBuilder]. 45 /// This information is computed during resolution using [NativeDataBuilder].
50 abstract class NativeData extends NativeClassData { 46 abstract class NativeData extends NativeClassData {
47 /// Returns `true` if [element] corresponds to a native JavaScript member.
48 ///
49 /// A member is marked as native either through the native mechanism
50 /// (`@Native(...)` or the `native` pseudo keyword) allowed for internal
51 /// libraries or via the typed JavaScriptInterop mechanism allowed for user
52 /// libraries.
53 bool isNativeMember(MemberEntity element);
54
51 /// Returns the [NativeBehavior] for calling the native [method]. 55 /// Returns the [NativeBehavior] for calling the native [method].
52 NativeBehavior getNativeMethodBehavior(MethodElement method); 56 NativeBehavior getNativeMethodBehavior(MethodElement method);
53 57
54 /// Returns the [NativeBehavior] for reading from the native [field]. 58 /// Returns the [NativeBehavior] for reading from the native [field].
55 NativeBehavior getNativeFieldLoadBehavior(FieldElement field); 59 NativeBehavior getNativeFieldLoadBehavior(FieldElement field);
56 60
57 /// Returns the [NativeBehavior] for writing to the native [field]. 61 /// Returns the [NativeBehavior] for writing to the native [field].
58 NativeBehavior getNativeFieldStoreBehavior(FieldElement field); 62 NativeBehavior getNativeFieldStoreBehavior(FieldElement field);
59 63
60 /// Returns `true` if the name of [element] is fixed for the generated 64 /// Returns `true` if the name of [element] is fixed for the generated
61 /// JavaScript. 65 /// JavaScript.
62 bool hasFixedBackendName(Element element); 66 bool hasFixedBackendName(Element element);
63 67
64 /// Computes the name for [element] to use in the generated JavaScript. This 68 /// Computes the name for [element] to use in the generated JavaScript. This
65 /// is either given through a native annotation or a js interop annotation. 69 /// is either given through a native annotation or a js interop annotation.
66 String getFixedBackendName(Entity entity); 70 String getFixedBackendName(Entity entity);
67 71
68 /// Returns the list of non-directive native tag words for [cls]. 72 /// Returns the list of non-directive native tag words for [cls].
69 List<String> getNativeTagsOfClass(ClassElement cls); 73 List<String> getNativeTagsOfClass(ClassElement cls);
70 74
71 /// Returns `true` if [cls] has a `!nonleaf` tag word. 75 /// Returns `true` if [cls] has a `!nonleaf` tag word.
72 bool hasNativeTagsForcedNonLeaf(ClassElement cls); 76 bool hasNativeTagsForcedNonLeaf(ClassElement cls);
73 77
74 /// Returns `true` if [element] is part of JsInterop. 78 /// Returns `true` if [element] is part of JsInterop.
79 ///
80 /// Deprecated: Use [isJsInteropLibrary], [isJsInteropClass] or
81 /// [isJsInteropMember] instead.
82 @deprecated
75 bool isJsInterop(Element element); 83 bool isJsInterop(Element element);
76 84
77 /// Returns `true` if [element] is a JsInterop method. 85 /// Returns `true` if [element] is a JsInterop method.
78 bool isJsInteropMethod(MethodElement element); 86 bool isJsInteropMember(MethodElement element);
79 87
80 /// Returns the explicit js interop name for [element]. 88 /// Returns the explicit js interop name for [element].
81 String getJsInteropName(Element element); 89 String getJsInteropName(Element element);
82 90
83 /// Apply JS$ escaping scheme to convert possible escaped Dart names into 91 /// Apply JS$ escaping scheme to convert possible escaped Dart names into
84 /// JS names. 92 /// JS names.
85 String getUnescapedJSInteropName(String name); 93 String getUnescapedJSInteropName(String name);
86 } 94 }
87 95
88 abstract class NativeClassDataBuilder { 96 abstract class NativeClassDataBuilder {
89 /// Sets the native tag info for [cls]. 97 /// Sets the native tag info for [cls].
90 /// 98 ///
91 /// The tag info string contains comma-separated 'words' which are either 99 /// The tag info string contains comma-separated 'words' which are either
92 /// dispatch tags (having JavaScript identifier syntax) and directives that 100 /// dispatch tags (having JavaScript identifier syntax) and directives that
93 /// begin with `!`. 101 /// begin with `!`.
94 void setNativeClassTagInfo(ClassElement cls, String tagInfo); 102 void setNativeClassTagInfo(ClassElement cls, String tagInfo);
95 103
96 /// Returns the list of native tag words for [cls]. 104 /// Marks [element] as an explicit part of JsInterop. The js interop name is
97 List<String> getNativeTagsOfClassRaw(ClassElement cls); 105 /// expected to be computed later.
106 void markAsJsInteropLibrary(LibraryElement element);
98 107
99 /// Sets the native [name] for the member [element]. This name is used for 108 /// Marks [element] as an explicit part of JsInterop. The js interop name is
100 /// [element] in the generated JavaScript.
101 void setNativeMemberName(MemberElement element, String name);
102
103 /// Returns [element] as an explicit part of JsInterop. The js interop name is
104 /// expected to be computed later. 109 /// expected to be computed later.
105 void markAsJsInterop(Element element); 110 void markAsJsInteropClass(ClassElement element);
106
107 /// Sets the explicit js interop [name] for [element].
108 void setJsInteropName(Element element, String name);
109 } 111 }
110 112
111 abstract class NativeDataBuilder { 113 abstract class NativeDataBuilder {
112 /// Registers the [behavior] for calling the native [method]. 114 /// Registers the [behavior] for calling the native [method].
113 void setNativeMethodBehavior(MethodElement method, NativeBehavior behavior); 115 void setNativeMethodBehavior(MethodElement method, NativeBehavior behavior);
114 116
115 /// Registers the [behavior] for reading from the native [field]. 117 /// Registers the [behavior] for reading from the native [field].
116 void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior); 118 void setNativeFieldLoadBehavior(FieldElement field, NativeBehavior behavior);
117 119
118 /// Registers the [behavior] for writing to the native [field]. 120 /// Registers the [behavior] for writing to the native [field].
119 void setNativeFieldStoreBehavior(FieldElement field, NativeBehavior behavior); 121 void setNativeFieldStoreBehavior(FieldElement field, NativeBehavior behavior);
122
123 /// Returns the list of native tag words for [cls].
124 List<String> getNativeTagsOfClassRaw(ClassElement cls);
125
126 /// Returns [element] as an explicit part of JsInterop. The js interop name is
127 /// expected to be computed later.
128 void markAsJsInteropMember(MemberElement element);
129
130 /// Sets the native [name] for the member [element]. This name is used for
131 /// [element] in the generated JavaScript.
132 void setNativeMemberName(MemberElement element, String name);
133
134 /// Sets the explicit js interop [name] for [element].
135 void setJsInteropName(Element element, String name);
120 } 136 }
121 137
122 class NativeDataImpl 138 class NativeDataImpl
123 implements NativeData, NativeDataBuilder, NativeClassDataBuilder { 139 implements NativeData, NativeDataBuilder, NativeClassDataBuilder {
124 /// The JavaScript names for elements implemented via typed JavaScript 140 /// The JavaScript names for elements implemented via typed JavaScript
125 /// interop. 141 /// interop.
126 Map<Element, String> jsInteropNames = <Element, String>{}; 142 Map<Element, String> jsInteropNames = <Element, String>{};
127 143
128 /// The JavaScript names for native JavaScript elements implemented. 144 /// The JavaScript names for native JavaScript elements implemented.
129 Map<Element, String> nativeMemberName = <Element, String>{}; 145 Map<Element, String> nativeMemberName = <Element, String>{};
(...skipping 16 matching lines...) Expand all
146 162
147 /// Prefix used to escape JS names that are not valid Dart names 163 /// Prefix used to escape JS names that are not valid Dart names
148 /// when using JSInterop. 164 /// when using JSInterop.
149 static const String _jsInteropEscapePrefix = r'JS$'; 165 static const String _jsInteropEscapePrefix = r'JS$';
150 166
151 /// Returns `true` if [element] is explicitly marked as part of JsInterop. 167 /// Returns `true` if [element] is explicitly marked as part of JsInterop.
152 bool _isJsInterop(Element element) { 168 bool _isJsInterop(Element element) {
153 return jsInteropNames.containsKey(element.declaration); 169 return jsInteropNames.containsKey(element.declaration);
154 } 170 }
155 171
156 /// Returns [element] as an explicit part of JsInterop. The js interop name is 172 /// Marks [element] as an explicit part of JsInterop. The js interop name is
157 /// expected to be computed later. 173 /// expected to be computed later.
158 void markAsJsInterop(Element element) { 174 void markAsJsInterop(Element element) {
159 jsInteropNames[element.declaration] = null; 175 jsInteropNames[element.declaration] = null;
160 } 176 }
161 177
178 @override
179 void markAsJsInteropLibrary(LibraryElement element) {
180 markAsJsInterop(element);
181 }
182
183 @override
184 void markAsJsInteropClass(ClassElement element) {
185 markAsJsInterop(element);
186 }
187
188 @override
189 void markAsJsInteropMember(MemberElement element) {
190 markAsJsInterop(element);
191 }
192
162 /// Sets the explicit js interop [name] for [element]. 193 /// Sets the explicit js interop [name] for [element].
163 void setJsInteropName(Element element, String name) { 194 void setJsInteropName(Element element, String name) {
164 assert(invariant(element, isJsInterop(element), 195 assert(invariant(element, isJsInterop(element),
165 message: 196 message:
166 'Element $element is not js interop but given a js interop name.')); 197 'Element $element is not js interop but given a js interop name.'));
167 jsInteropNames[element.declaration] = name; 198 jsInteropNames[element.declaration] = name;
168 } 199 }
169 200
170 /// Returns the explicit js interop name for [element]. 201 /// Returns the explicit js interop name for [element].
171 String getJsInteropName(Element element) { 202 String getJsInteropName(Element element) {
(...skipping 11 matching lines...) Expand all
183 214
184 if (_isJsInterop(function)) return true; 215 if (_isJsInterop(function)) return true;
185 if (function.isClassMember) return isJsInterop(function.contextClass); 216 if (function.isClassMember) return isJsInterop(function.contextClass);
186 if (function.isTopLevel) return isJsInterop(function.library); 217 if (function.isTopLevel) return isJsInterop(function.library);
187 return false; 218 return false;
188 } else { 219 } else {
189 return _isJsInterop(element); 220 return _isJsInterop(element);
190 } 221 }
191 } 222 }
192 223
224 /// Returns `true` if [element] is a JsInterop library.
225 bool isJsInteropLibrary(LibraryElement element) => isJsInterop(element);
226
193 /// Returns `true` if [element] is a JsInterop class. 227 /// Returns `true` if [element] is a JsInterop class.
194 bool isJsInteropClass(ClassElement element) => isJsInterop(element); 228 bool isJsInteropClass(ClassElement element) => isJsInterop(element);
195 229
196 /// Returns `true` if [element] is a JsInterop method. 230 /// Returns `true` if [element] is a JsInterop method.
197 bool isJsInteropMethod(MethodElement element) => isJsInterop(element); 231 bool isJsInteropMember(MethodElement element) => isJsInterop(element);
198 232
199 /// Returns `true` if the name of [element] is fixed for the generated 233 /// Returns `true` if the name of [element] is fixed for the generated
200 /// JavaScript. 234 /// JavaScript.
201 bool hasFixedBackendName(Element element) { 235 bool hasFixedBackendName(Element element) {
202 return isJsInterop(element) || 236 return isJsInterop(element) ||
203 nativeMemberName.containsKey(element.declaration); 237 nativeMemberName.containsKey(element.declaration);
204 } 238 }
205 239
206 String _jsNameHelper(Element element) { 240 String _jsNameHelper(Element element) {
207 String jsInteropName = jsInteropNames[element.declaration]; 241 String jsInteropName = jsInteropNames[element.declaration];
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 } 389 }
356 390
357 /// Apply JS$ escaping scheme to convert possible escaped Dart names into 391 /// Apply JS$ escaping scheme to convert possible escaped Dart names into
358 /// JS names. 392 /// JS names.
359 String getUnescapedJSInteropName(String name) { 393 String getUnescapedJSInteropName(String name) {
360 return name.startsWith(_jsInteropEscapePrefix) 394 return name.startsWith(_jsInteropEscapePrefix)
361 ? name.substring(_jsInteropEscapePrefix.length) 395 ? name.substring(_jsInteropEscapePrefix.length)
362 : name; 396 : name;
363 } 397 }
364 } 398 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698