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

Side by Side Diff: tool/input_sdk/private/ddc_runtime/classes.dart

Issue 2164763005: Library custom formatters (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Revert test files Created 4 years, 4 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
« no previous file with comments | « lib/src/compiler/code_generator.dart ('k') | tool/input_sdk/private/ddc_runtime/rtti.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 /// This library defines the operations that define and manipulate Dart 5 /// This library defines the operations that define and manipulate Dart
6 /// classes. Included in this are: 6 /// classes. Included in this are:
7 /// - Generics 7 /// - Generics
8 /// - Class metadata 8 /// - Class metadata
9 /// - Extension methods 9 /// - Extension methods
10 /// 10 ///
11 11
12 // TODO(leafp): Consider splitting some of this out. 12 // TODO(leafp): Consider splitting some of this out.
13 part of dart._runtime; 13 part of dart._runtime;
14 14
15 /// 15 ///
16 /// Returns a new type that mixes members from base and all mixins. 16 /// Returns a new type that mixes members from base and all mixins.
17 /// 17 ///
18 /// Each mixin applies in sequence, with further to the right ones overriding 18 /// Each mixin applies in sequence, with further to the right ones overriding
19 /// previous entries. 19 /// previous entries.
20 /// 20 ///
21 /// For each mixin, we only take its own properties, not anything from its 21 /// For each mixin, we only take its own properties, not anything from its
22 /// superclass (prototype). 22 /// superclass (prototype).
23 /// 23 ///
24 mixin(base, @rest mixins) => JS('', '''(() => { 24 mixin(base, @rest mixins) => JS(
25 '',
26 '''(() => {
25 // Create an initializer for the mixin, so when derived constructor calls 27 // Create an initializer for the mixin, so when derived constructor calls
26 // super, we can correctly initialize base and mixins. 28 // super, we can correctly initialize base and mixins.
27 29
28 // Create a class that will hold all of the mixin methods. 30 // Create a class that will hold all of the mixin methods.
29 class Mixin extends $base {} 31 class Mixin extends $base {}
30 // Copy each mixin's methods, with later ones overwriting earlier entries. 32 // Copy each mixin's methods, with later ones overwriting earlier entries.
31 for (let m of $mixins) { 33 for (let m of $mixins) {
32 $copyProperties(Mixin.prototype, m.prototype); 34 $copyProperties(Mixin.prototype, m.prototype);
33 } 35 }
34 // Initializer method: run mixin initializers, then the base. 36 // Initializer method: run mixin initializers, then the base.
(...skipping 17 matching lines...) Expand all
52 } 54 }
53 return s; 55 return s;
54 } 56 }
55 }); 57 });
56 58
57 // Save mixins for reflection 59 // Save mixins for reflection
58 Mixin[$_mixins] = $mixins; 60 Mixin[$_mixins] = $mixins;
59 return Mixin; 61 return Mixin;
60 })()'''); 62 })()''');
61 63
62
63 /// The Symbol for storing type arguments on a specialized generic type. 64 /// The Symbol for storing type arguments on a specialized generic type.
64 final _mixins = JS('', 'Symbol("mixins")'); 65 final _mixins = JS('', 'Symbol("mixins")');
65 66
66 getMixins(clazz) => JS('', '$clazz[$_mixins]'); 67 getMixins(clazz) => JS('', '$clazz[$_mixins]');
67 68
68 @JSExportName('implements') 69 @JSExportName('implements')
69 final _implements = JS('', 'Symbol("implements")'); 70 final _implements = JS('', 'Symbol("implements")');
70 71
71 getImplements(clazz) => JS('', '#[#]', clazz, _implements); 72 getImplements(clazz) => JS('', '#[#]', clazz, _implements);
72 73
73 /// The Symbol for storing type arguments on a specialized generic type. 74 /// The Symbol for storing type arguments on a specialized generic type.
74 final _typeArguments = JS('', 'Symbol("typeArguments")'); 75 final _typeArguments = JS('', 'Symbol("typeArguments")');
75 76
76 final _originalDeclaration = JS('', 'Symbol("originalDeclaration")'); 77 final _originalDeclaration = JS('', 'Symbol("originalDeclaration")');
77 78
78 /// Wrap a generic class builder function with future flattening. 79 /// Wrap a generic class builder function with future flattening.
79 flattenFutures(builder) => JS('', '''(() => { 80 flattenFutures(builder) => JS(
81 '',
82 '''(() => {
80 function flatten(T) { 83 function flatten(T) {
81 if (!T) return $builder($dynamic); 84 if (!T) return $builder($dynamic);
82 let futureClass = $getGenericClass($Future); 85 let futureClass = $getGenericClass($Future);
83 //TODO(leafp): This only handles the direct flattening case. 86 //TODO(leafp): This only handles the direct flattening case.
84 // It would probably be good to at least search up the class 87 // It would probably be good to at least search up the class
85 // hierarchy. If we keep doing flattening long term, we may 88 // hierarchy. If we keep doing flattening long term, we may
86 // want to implement the full future flattening per spec. 89 // want to implement the full future flattening per spec.
87 if ($getGenericClass(T) == futureClass) { 90 if ($getGenericClass(T) == futureClass) {
88 let args = $getGenericArgs(T); 91 let args = $getGenericArgs(T);
89 if (args) return $builder(args[0]); 92 if (args) return $builder(args[0]);
90 } 93 }
91 return $builder(T); 94 return $builder(T);
92 } 95 }
93 return flatten; 96 return flatten;
94 })()'''); 97 })()''');
95 98
96 /// Memoize a generic type constructor function. 99 /// Memoize a generic type constructor function.
97 generic(typeConstructor) => JS('', '''(() => { 100 generic(typeConstructor) => JS(
101 '',
102 '''(() => {
98 let length = $typeConstructor.length; 103 let length = $typeConstructor.length;
99 if (length < 1) { 104 if (length < 1) {
100 $throwInternalError('must have at least one generic type argument'); 105 $throwInternalError('must have at least one generic type argument');
101 } 106 }
102 let resultMap = new Map(); 107 let resultMap = new Map();
103 function makeGenericType(...args) { 108 function makeGenericType(...args) {
104 if (args.length != length && args.length != 0) { 109 if (args.length != length && args.length != 0) {
105 $throwInternalError('requires ' + length + ' or 0 type arguments'); 110 $throwInternalError('requires ' + length + ' or 0 type arguments');
106 } 111 }
107 while (args.length < length) args.push($dynamic); 112 while (args.length < length) args.push($dynamic);
(...skipping 16 matching lines...) Expand all
124 value[$_originalDeclaration] = makeGenericType; 129 value[$_originalDeclaration] = makeGenericType;
125 } 130 }
126 } else { 131 } else {
127 value = new Map(); 132 value = new Map();
128 } 133 }
129 map.set(arg, value); 134 map.set(arg, value);
130 } 135 }
131 } 136 }
132 return value; 137 return value;
133 } 138 }
139 makeGenericType[$_genericTypeCtor] = $typeConstructor;
134 return makeGenericType; 140 return makeGenericType;
135 })()'''); 141 })()''');
136 142
137 getGenericClass(type) => 143 getGenericClass(type) =>
138 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)'); 144 JS('', '$safeGetOwnProperty($type, $_originalDeclaration)');
139 145
140 getGenericArgs(type) => 146 getGenericArgs(type) => JS('', '$safeGetOwnProperty($type, $_typeArguments)');
141 JS('', '$safeGetOwnProperty($type, $_typeArguments)');
142 147
143 final _constructorSig = JS('', 'Symbol("sigCtor")'); 148 final _constructorSig = JS('', 'Symbol("sigCtor")');
144 final _methodSig = JS('', 'Symbol("sig")'); 149 final _methodSig = JS('', 'Symbol("sig")');
145 final _staticSig = JS('', 'Symbol("sigStatic")'); 150 final _staticSig = JS('', 'Symbol("sigStatic")');
151 final _genericTypeCtor = JS('', 'Symbol("genericType")');
152
153 getMethodSig(value) => JS('', '#[#]', value, _methodSig);
154 getGenericTypeCtor(value) => JS('', '#[#]', value, _genericTypeCtor);
146 155
147 /// Get the type of a method from an object using the stored signature 156 /// Get the type of a method from an object using the stored signature
148 getMethodType(obj, name) => JS('', '''(() => { 157 getMethodType(obj, name) => JS(
158 '',
159 '''(() => {
149 let type = $obj == null ? $Object : $obj.__proto__.constructor; 160 let type = $obj == null ? $Object : $obj.__proto__.constructor;
150 return $getMethodTypeFromType(type, $name); 161 return $getMethodTypeFromType(type, $name);
151 })()'''); 162 })()''');
152 163
153 /// Get the type of a method from a type using the stored signature 164 /// Get the type of a method from a type using the stored signature
154 getMethodTypeFromType(type, name) => JS('', '''(() => { 165 getMethodTypeFromType(type, name) => JS(
166 '',
167 '''(() => {
155 let sigObj = $type[$_methodSig]; 168 let sigObj = $type[$_methodSig];
156 if (sigObj === void 0) return void 0; 169 if (sigObj === void 0) return void 0;
157 return sigObj[$name]; 170 return sigObj[$name];
158 })()'''); 171 })()''');
159 172
160 /// Get the type of a constructor from a class using the stored signature 173 /// Get the type of a constructor from a class using the stored signature
161 /// If name is undefined, returns the type of the default constructor 174 /// If name is undefined, returns the type of the default constructor
162 /// Returns undefined if the constructor is not found. 175 /// Returns undefined if the constructor is not found.
163 classGetConstructorType(cls, name) => JS('', '''(() => { 176 classGetConstructorType(cls, name) => JS(
177 '',
178 '''(() => {
164 if(!$name) $name = $cls.name; 179 if(!$name) $name = $cls.name;
165 if ($cls === void 0) return void 0; 180 if ($cls === void 0) return void 0;
166 if ($cls == null) return void 0; 181 if ($cls == null) return void 0;
167 let sigCtor = $cls[$_constructorSig]; 182 let sigCtor = $cls[$_constructorSig];
168 if (sigCtor === void 0) return void 0; 183 if (sigCtor === void 0) return void 0;
169 return sigCtor[$name]; 184 return sigCtor[$name];
170 })()'''); 185 })()''');
171 186
172 /// Given an object and a method name, tear off the method. 187 /// Given an object and a method name, tear off the method.
173 /// Sets the runtime type of the torn off method appropriately, 188 /// Sets the runtime type of the torn off method appropriately,
174 /// and also binds the object. 189 /// and also binds the object.
175 /// 190 ///
176 /// If the optional `f` argument is passed in, it will be used as the method. 191 /// If the optional `f` argument is passed in, it will be used as the method.
177 /// This supports cases like `super.foo` where we need to tear off the method 192 /// This supports cases like `super.foo` where we need to tear off the method
178 /// from the superclass, not from the `obj` directly. 193 /// from the superclass, not from the `obj` directly.
179 /// TODO(leafp): Consider caching the tearoff on the object? 194 /// TODO(leafp): Consider caching the tearoff on the object?
180 bind(obj, name, f) => JS('', '''(() => { 195 bind(obj, name, f) => JS(
196 '',
197 '''(() => {
181 if ($f === void 0) $f = $obj[$name]; 198 if ($f === void 0) $f = $obj[$name];
182 $f = $f.bind($obj); 199 $f = $f.bind($obj);
183 // TODO(jmesserly): track the function's signature on the function, instead 200 // TODO(jmesserly): track the function's signature on the function, instead
184 // of having to go back to the class? 201 // of having to go back to the class?
185 let sig = $getMethodType($obj, $name); 202 let sig = $getMethodType($obj, $name);
186 $assert_(sig); 203 $assert_(sig);
187 $tag($f, sig); 204 $tag($f, sig);
188 return $f; 205 return $f;
189 })()'''); 206 })()''');
190 207
191 /// Instantiate a generic method. 208 /// Instantiate a generic method.
192 /// 209 ///
193 /// We need to apply the type arguments both to the function, as well as its 210 /// We need to apply the type arguments both to the function, as well as its
194 /// associated function type. 211 /// associated function type.
195 gbind(f, @rest typeArgs) { 212 gbind(f, @rest typeArgs) {
196 var result = JS('', '#.apply(null, #)', f, typeArgs); 213 var result = JS('', '#.apply(null, #)', f, typeArgs);
197 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs); 214 var sig = JS('', '#.apply(null, #)', _getRuntimeType(f), typeArgs);
198 tag(result, sig); 215 tag(result, sig);
199 return result; 216 return result;
200 } 217 }
201 218
202 // Set up the method signature field on the constructor 219 // Set up the method signature field on the constructor
203 _setMethodSignature(f, sigF) => JS('', '''(() => { 220 _setMethodSignature(f, sigF) => JS(
221 '',
222 '''(() => {
204 $defineMemoizedGetter($f, $_methodSig, () => { 223 $defineMemoizedGetter($f, $_methodSig, () => {
205 let sigObj = $sigF(); 224 let sigObj = $sigF();
206 sigObj.__proto__ = $f.__proto__[$_methodSig]; 225 sigObj.__proto__ = $f.__proto__[$_methodSig];
207 return sigObj; 226 return sigObj;
208 }); 227 });
209 })()'''); 228 })()''');
210 229
211 // Set up the constructor signature field on the constructor 230 // Set up the constructor signature field on the constructor
212 _setConstructorSignature(f, sigF) => 231 _setConstructorSignature(f, sigF) =>
213 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)'); 232 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)');
214 233
215 // Set up the static signature field on the constructor 234 // Set up the static signature field on the constructor
216 _setStaticSignature(f, sigF) => 235 _setStaticSignature(f, sigF) =>
217 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)'); 236 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)');
218 237
219 // Set the lazily computed runtime type field on static methods 238 // Set the lazily computed runtime type field on static methods
220 _setStaticTypes(f, names) => JS('', '''(() => { 239 _setStaticTypes(f, names) => JS(
240 '',
241 '''(() => {
221 for (let name of $names) { 242 for (let name of $names) {
222 // TODO(vsm): Need to generate static methods. 243 // TODO(vsm): Need to generate static methods.
223 if (!$f[name]) continue; 244 if (!$f[name]) continue;
224 $tagLazy($f[name], function() { 245 $tagLazy($f[name], function() {
225 return $f[$_staticSig][name]; 246 return $f[$_staticSig][name];
226 }) 247 })
227 } 248 }
228 })()'''); 249 })()''');
229 250
230 /// Set up the type signature of a class (constructor object) 251 /// Set up the type signature of a class (constructor object)
231 /// f is a constructor object 252 /// f is a constructor object
232 /// signature is an object containing optional properties as follows: 253 /// signature is an object containing optional properties as follows:
233 /// methods: A function returning an object mapping method names 254 /// methods: A function returning an object mapping method names
234 /// to method types. The function is evaluated lazily and cached. 255 /// to method types. The function is evaluated lazily and cached.
235 /// statics: A function returning an object mapping static method 256 /// statics: A function returning an object mapping static method
236 /// names to types. The function is evalutated lazily and cached. 257 /// names to types. The function is evalutated lazily and cached.
237 /// names: An array of the names of the static methods. Used to 258 /// names: An array of the names of the static methods. Used to
238 /// permit eagerly setting the runtimeType field on the methods 259 /// permit eagerly setting the runtimeType field on the methods
239 /// while still lazily computing the type descriptor object. 260 /// while still lazily computing the type descriptor object.
240 setSignature(f, signature) => JS('', '''(() => { 261 setSignature(f, signature) => JS(
262 '',
263 '''(() => {
241 // TODO(ochafik): Deconstruct these when supported by Chrome. 264 // TODO(ochafik): Deconstruct these when supported by Chrome.
242 let constructors = 265 let constructors =
243 ('constructors' in signature) ? signature.constructors : () => ({}); 266 ('constructors' in signature) ? signature.constructors : () => ({});
244 let methods = 267 let methods =
245 ('methods' in signature) ? signature.methods : () => ({}); 268 ('methods' in signature) ? signature.methods : () => ({});
246 let statics = 269 let statics =
247 ('statics' in signature) ? signature.statics : () => ({}); 270 ('statics' in signature) ? signature.statics : () => ({});
248 let names = 271 let names =
249 ('names' in signature) ? signature.names : []; 272 ('names' in signature) ? signature.names : [];
250 $_setConstructorSignature($f, constructors); 273 $_setConstructorSignature($f, constructors);
251 $_setMethodSignature($f, methods); 274 $_setMethodSignature($f, methods);
252 $_setStaticSignature($f, statics); 275 $_setStaticSignature($f, statics);
253 $_setStaticTypes($f, names); 276 $_setStaticTypes($f, names);
254 })()'''); 277 })()''');
255 278
256 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); 279 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0');
257 280
258 /// Given a class and an initializer method name, creates a constructor 281 /// Given a class and an initializer method name, creates a constructor
259 /// function with the same name. 282 /// function with the same name.
260 /// 283 ///
261 /// After we define the named constructor, the class can be constructed with 284 /// After we define the named constructor, the class can be constructed with
262 /// `new SomeClass.name(args)`. 285 /// `new SomeClass.name(args)`.
263 defineNamedConstructor(clazz, name) => JS('', '''(() => { 286 defineNamedConstructor(clazz, name) => JS(
287 '',
288 '''(() => {
264 let proto = $clazz.prototype; 289 let proto = $clazz.prototype;
265 let initMethod = proto[$name]; 290 let initMethod = proto[$name];
266 let ctor = function(...args) { initMethod.apply(this, args); }; 291 let ctor = function(...args) { initMethod.apply(this, args); };
292 ctor[$isNamedConstructor] = true;
267 ctor.prototype = proto; 293 ctor.prototype = proto;
268 // Use defineProperty so we don't hit a property defined on Function, 294 // Use defineProperty so we don't hit a property defined on Function,
269 // like `caller` and `arguments`. 295 // like `caller` and `arguments`.
270 $defineProperty($clazz, $name, { value: ctor, configurable: true }); 296 $defineProperty($clazz, $name, { value: ctor, configurable: true });
271 })()'''); 297 })()''');
272 298
273
274 final _extensionType = JS('', 'Symbol("extensionType")'); 299 final _extensionType = JS('', 'Symbol("extensionType")');
275 300
276 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); 301 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType);
277 302
278 final dartx = JS('', 'dartx'); 303 final dartx = JS('', 'dartx');
279 304
280 getExtensionSymbol(name) { 305 getExtensionSymbol(name) {
281 var sym = JS('', 'dartx[#]', name); 306 var sym = JS('', 'dartx[#]', name);
282 if (sym == null) { 307 if (sym == null) {
283 sym = JS('', 'Symbol("dartx." + #.toString())', name); 308 sym = JS('', 'Symbol("dartx." + #.toString())', name);
284 JS('', 'dartx[#] = #', name, sym); 309 JS('', 'dartx[#] = #', name, sym);
285 } 310 }
286 return sym; 311 return sym;
287 } 312 }
288 313
289 defineExtensionNames(names) => 314 defineExtensionNames(names) =>
290 JS('', '#.forEach(#)', names, getExtensionSymbol); 315 JS('', '#.forEach(#)', names, getExtensionSymbol);
291 316
292
293 /// Install properties in prototype-first order. Properties / descriptors from 317 /// Install properties in prototype-first order. Properties / descriptors from
294 /// more specific types should overwrite ones from less specific types. 318 /// more specific types should overwrite ones from less specific types.
295 void _installProperties(jsProto, extProto) { 319 void _installProperties(jsProto, extProto) {
296
297 // This relies on the Dart type literal evaluating to the JavaScript 320 // This relies on the Dart type literal evaluating to the JavaScript
298 // constructor. 321 // constructor.
299 var coreObjProto = JS('', '#.prototype', Object); 322 var coreObjProto = JS('', '#.prototype', Object);
300 323
301 var parentsExtension = 324 var parentsExtension = JS('', '(#.__proto__)[#]', jsProto, _extensionType);
302 JS('', '(#.__proto__)[#]', jsProto, _extensionType);
303 var installedParent = 325 var installedParent =
304 JS('', '# && #.prototype', parentsExtension, parentsExtension); 326 JS('', '# && #.prototype', parentsExtension, parentsExtension);
305 327
306 _installProperties2(jsProto, extProto, coreObjProto, installedParent); 328 _installProperties2(jsProto, extProto, coreObjProto, installedParent);
307 } 329 }
308 330
309 void _installProperties2(jsProto, extProto, coreObjProto, installedParent) { 331 void _installProperties2(jsProto, extProto, coreObjProto, installedParent) {
310 if (JS('bool', '# === #', extProto, coreObjProto)) { 332 if (JS('bool', '# === #', extProto, coreObjProto)) {
311 _installPropertiesForObject(jsProto, coreObjProto); 333 _installPropertiesForObject(jsProto, coreObjProto);
312 return; 334 return;
313 } 335 }
314 if (JS('bool', '# !== #', jsProto, extProto)) { 336 if (JS('bool', '# !== #', jsProto, extProto)) {
315 var extParent = JS('', '#.__proto__', extProto); 337 var extParent = JS('', '#.__proto__', extProto);
316 338
317 // If the extension methods of the parent have been installed on the parent 339 // If the extension methods of the parent have been installed on the parent
318 // of [jsProto], the methods will be available via prototype inheritance. 340 // of [jsProto], the methods will be available via prototype inheritance.
319 341
320 if(JS('bool', '# !== #', installedParent, extParent)) { 342 if (JS('bool', '# !== #', installedParent, extParent)) {
321 _installProperties2(jsProto, extParent, coreObjProto, installedParent); 343 _installProperties2(jsProto, extParent, coreObjProto, installedParent);
322 } 344 }
323 } 345 }
324 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); 346 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto));
325 } 347 }
326 348
327 void _installPropertiesForObject(jsProto, coreObjProto) { 349 void _installPropertiesForObject(jsProto, coreObjProto) {
328 // core.Object members need to be copied from the non-symbol name to the 350 // core.Object members need to be copied from the non-symbol name to the
329 // symbol name. 351 // symbol name.
330 var names = getOwnPropertyNames(coreObjProto); 352 var names = getOwnPropertyNames(coreObjProto);
331 for (int i = 0; i < JS('int', '#.length', names); ++i) { 353 for (int i = 0; i < JS('int', '#.length', names); ++i) {
332 var name = JS('', '#[#]', names, i); 354 var name = JS('', '#[#]', names, i);
333 var desc = getOwnPropertyDescriptor(coreObjProto, name); 355 var desc = getOwnPropertyDescriptor(coreObjProto, name);
334 defineProperty(jsProto, getExtensionSymbol(name), desc); 356 defineProperty(jsProto, getExtensionSymbol(name), desc);
335 } 357 }
336 return; 358 return;
337 } 359 }
338 360
339 /// Copy symbols from the prototype of the source to destination. 361 /// Copy symbols from the prototype of the source to destination.
340 /// These are the only properties safe to copy onto an existing public 362 /// These are the only properties safe to copy onto an existing public
341 /// JavaScript class. 363 /// JavaScript class.
342 registerExtension(jsType, dartExtType) => JS('', '''(() => { 364 registerExtension(jsType, dartExtType) => JS(
365 '',
366 '''(() => {
343 // TODO(vsm): Not all registered js types are real. 367 // TODO(vsm): Not all registered js types are real.
344 if (!jsType) return; 368 if (!jsType) return;
345 369
346 let extProto = $dartExtType.prototype; 370 let extProto = $dartExtType.prototype;
347 let jsProto = $jsType.prototype; 371 let jsProto = $jsType.prototype;
348 372
349 // Mark the JS type's instances so we can easily check for extensions. 373 // Mark the JS type's instances so we can easily check for extensions.
350 jsProto[$_extensionType] = $dartExtType; 374 jsProto[$_extensionType] = $dartExtType;
351 $_installProperties(jsProto, extProto); 375 $_installProperties(jsProto, extProto);
352 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get; 376 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get;
(...skipping 13 matching lines...) Expand all
366 /// 390 ///
367 /// Results in: 391 /// Results in:
368 /// 392 ///
369 /// MyType.prototype[dartx.add] = MyType.prototype.add; 393 /// MyType.prototype[dartx.add] = MyType.prototype.add;
370 /// MyType.prototype[dartx.remove] = MyType.prototype.remove; 394 /// MyType.prototype[dartx.remove] = MyType.prototype.remove;
371 /// 395 ///
372 // TODO(jmesserly): essentially this gives two names to the same method. 396 // TODO(jmesserly): essentially this gives two names to the same method.
373 // This benefit is roughly equivalent call performance either way, but the 397 // This benefit is roughly equivalent call performance either way, but the
374 // cost is we need to call defineExtensionMembers any time a subclass 398 // cost is we need to call defineExtensionMembers any time a subclass
375 // overrides one of these methods. 399 // overrides one of these methods.
376 defineExtensionMembers(type, methodNames) => JS('', '''(() => { 400 defineExtensionMembers(type, methodNames) => JS(
401 '',
402 '''(() => {
377 let proto = $type.prototype; 403 let proto = $type.prototype;
378 for (let name of $methodNames) { 404 for (let name of $methodNames) {
379 let method = $getOwnPropertyDescriptor(proto, name); 405 let method = $getOwnPropertyDescriptor(proto, name);
380 // TODO(vsm): We should be able to generate code to avoid this case. 406 // TODO(vsm): We should be able to generate code to avoid this case.
381 // The method may be null if this type implements a potentially native 407 // The method may be null if this type implements a potentially native
382 // interface but isn't native itself. For a field on this type, we're not 408 // interface but isn't native itself. For a field on this type, we're not
383 // generating a corresponding getter/setter method - it's just a field. 409 // generating a corresponding getter/setter method - it's just a field.
384 if (!method) continue; 410 if (!method) continue;
385 $defineProperty(proto, $getExtensionSymbol(name), method); 411 $defineProperty(proto, $getExtensionSymbol(name), method);
386 } 412 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 JS('', '#.__proto__ = #.__proto__', callableCtor, classExpr); 471 JS('', '#.__proto__ = #.__proto__', callableCtor, classExpr);
446 return callableCtor; 472 return callableCtor;
447 } 473 }
448 474
449 /// Given a class and an initializer method name and a call method, creates a 475 /// Given a class and an initializer method name and a call method, creates a
450 /// constructor function with the same name. 476 /// constructor function with the same name.
451 /// 477 ///
452 /// For example it can be called with `new SomeClass.name(args)`. 478 /// For example it can be called with `new SomeClass.name(args)`.
453 /// 479 ///
454 /// The constructor 480 /// The constructor
455 defineNamedConstructorCallable(clazz, name, ctor) => JS('', '''(() => { 481 defineNamedConstructorCallable(clazz, name, ctor) => JS(
482 '',
483 '''(() => {
456 ctor.prototype = $clazz.prototype; 484 ctor.prototype = $clazz.prototype;
457 // Use defineProperty so we don't hit a property defined on Function, 485 // Use defineProperty so we don't hit a property defined on Function,
458 // like `caller` and `arguments`. 486 // like `caller` and `arguments`.
459 $defineProperty($clazz, $name, { value: ctor, configurable: true }); 487 $defineProperty($clazz, $name, { value: ctor, configurable: true });
460 })()'''); 488 })()''');
OLDNEW
« no previous file with comments | « lib/src/compiler/code_generator.dart ('k') | tool/input_sdk/private/ddc_runtime/rtti.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698