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

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

Issue 1700153002: Wrapperless dart:html and friends (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: A couple more tweaks Created 4 years, 10 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 | « tool/input_sdk/lib/web_sql/ddc/web_sql_ddc.dart ('k') | tool/sdk_expected_errors.txt » ('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 ///
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 _setConstructorSignature(f, sigF) => 179 _setConstructorSignature(f, sigF) =>
180 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)'); 180 JS('', '$defineMemoizedGetter($f, $_constructorSig, $sigF)');
181 181
182 // Set up the static signature field on the constructor 182 // Set up the static signature field on the constructor
183 _setStaticSignature(f, sigF) => 183 _setStaticSignature(f, sigF) =>
184 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)'); 184 JS('', '$defineMemoizedGetter($f, $_staticSig, $sigF)');
185 185
186 // Set the lazily computed runtime type field on static methods 186 // Set the lazily computed runtime type field on static methods
187 _setStaticTypes(f, names) => JS('', '''(() => { 187 _setStaticTypes(f, names) => JS('', '''(() => {
188 for (let name of $names) { 188 for (let name of $names) {
189 // TODO(vsm): Need to generate static methods.
190 if (!$f[name]) continue;
189 $tagMemoized($f[name], function() { 191 $tagMemoized($f[name], function() {
190 let parts = $f[$_staticSig][name]; 192 let parts = $f[$_staticSig][name];
191 return $definiteFunctionType.apply(null, parts); 193 return $definiteFunctionType.apply(null, parts);
192 }) 194 })
193 } 195 }
194 })()'''); 196 })()''');
195 197
196 /// Set up the type signature of a class (constructor object) 198 /// Set up the type signature of a class (constructor object)
197 /// f is a constructor object 199 /// f is a constructor object
198 /// signature is an object containing optional properties as follows: 200 /// signature is an object containing optional properties as follows:
(...skipping 30 matching lines...) Expand all
229 /// This is important because otherwise, trying to read or write the field 231 /// This is important because otherwise, trying to read or write the field
230 /// would end up calling the getter or setter, and one of those might not even 232 /// would end up calling the getter or setter, and one of those might not even
231 /// exist, resulting in a runtime error. Even if they did exist, that's the 233 /// exist, resulting in a runtime error. Even if they did exist, that's the
232 /// wrong behavior if a new field was declared. 234 /// wrong behavior if a new field was declared.
233 /// 235 ///
234 virtualField(subclass, fieldName) => JS('', '''(() => { 236 virtualField(subclass, fieldName) => JS('', '''(() => {
235 // If the field is already overridden, do nothing. 237 // If the field is already overridden, do nothing.
236 let prop = $getOwnPropertyDescriptor($subclass.prototype, $fieldName); 238 let prop = $getOwnPropertyDescriptor($subclass.prototype, $fieldName);
237 if (prop) return; 239 if (prop) return;
238 240
239 let symbol = Symbol($subclass.name + '.' + $fieldName); 241 let symbol = Symbol($subclass.name + '.' + $fieldName.toString());
240 $defineProperty($subclass.prototype, $fieldName, { 242 $defineProperty($subclass.prototype, $fieldName, {
241 get: function() { return this[symbol]; }, 243 get: function() { return this[symbol]; },
242 set: function(x) { this[symbol] = x; } 244 set: function(x) { this[symbol] = x; }
243 }); 245 });
244 })()'''); 246 })()''');
245 247
246 /// 248 ///
247 /// Given a class and an initializer method name, creates a constructor 249 /// Given a class and an initializer method name, creates a constructor
248 /// function with the same name. For example `new SomeClass.name(args)`. 250 /// function with the same name. For example `new SomeClass.name(args)`.
249 /// 251 ///
250 defineNamedConstructor(clazz, name) => JS('', '''(() => { 252 defineNamedConstructor(clazz, name) => JS('', '''(() => {
251 let proto = $clazz.prototype; 253 let proto = $clazz.prototype;
252 let initMethod = proto[$name]; 254 let initMethod = proto[$name];
253 let ctor = function() { return initMethod.apply(this, arguments); }; 255 let ctor = function() { return initMethod.apply(this, arguments); };
254 ctor.prototype = proto; 256 ctor.prototype = proto;
255 // Use defineProperty so we don't hit a property defined on Function, 257 // Use defineProperty so we don't hit a property defined on Function,
256 // like `caller` and `arguments`. 258 // like `caller` and `arguments`.
257 $defineProperty($clazz, $name, { value: ctor, configurable: true }); 259 $defineProperty($clazz, $name, { value: ctor, configurable: true });
258 })()'''); 260 })()''');
259 261
260 final _extensionType = JS('', 'Symbol("extensionType")'); 262 final _extensionType = JS('', 'Symbol("extensionType")');
261 263
262 getExtensionType(obj) => JS('', '$obj[$_extensionType]'); 264 getExtensionType(obj) => JS('', '$obj[$_extensionType]');
263 265
264 final dartx = JS('', '{}'); 266 final dartx = JS('', '{}');
265 267
266 getExtensionSymbol(name) => JS('', '''(() => { 268 getExtensionSymbol(name) => JS('', '''(() => {
267 let sym = $dartx[$name]; 269 let sym = $dartx[$name];
268 if (!sym) $dartx[$name] = sym = Symbol('dartx.' + $name); 270 if (!sym) $dartx[$name] = sym = Symbol('dartx.' + $name.toString());
269 return sym; 271 return sym;
270 })()'''); 272 })()''');
271 273
272 defineExtensionNames(names) => JS('', '$names.forEach($getExtensionSymbol)'); 274 defineExtensionNames(names) => JS('', '$names.forEach($getExtensionSymbol)');
273 275
274 // Install properties in prototype order. Properties / descriptors from 276 // Install properties in prototype order. Properties / descriptors from
275 // more specific types should overwrite ones from less specific types. 277 // more specific types should overwrite ones from less specific types.
276 _installProperties(jsProto, extProto) => JS('', '''(() => { 278 _installProperties(jsProto, extProto) => JS('', '''(() => {
277 if (extProto !== $Object.prototype && extProto !== jsProto) { 279 if (extProto !== $Object.prototype && extProto !== jsProto) {
278 $_installProperties(jsProto, extProto.__proto__); 280 $_installProperties(jsProto, extProto.__proto__);
279 } 281 }
280 $copyTheseProperties(jsProto, extProto, $getOwnPropertySymbols(extProto)); 282 $copyTheseProperties(jsProto, extProto, $getOwnPropertySymbols(extProto));
281 })()'''); 283 })()''');
282 284
283 /// 285 ///
284 /// Copy symbols from the prototype of the source to destination. 286 /// Copy symbols from the prototype of the source to destination.
285 /// These are the only properties safe to copy onto an existing public 287 /// These are the only properties safe to copy onto an existing public
286 /// JavaScript class. 288 /// JavaScript class.
287 /// 289 ///
288 registerExtension(jsType, dartExtType) => JS('', '''(() => { 290 registerExtension(jsType, dartExtType) => JS('', '''(() => {
291 // TODO(vsm): Not all registered js types are real.
292 if (!jsType) return;
293
289 let extProto = $dartExtType.prototype; 294 let extProto = $dartExtType.prototype;
290 let jsProto = $jsType.prototype; 295 let jsProto = $jsType.prototype;
291 296
292 // Mark the JS type's instances so we can easily check for extensions. 297 // Mark the JS type's instances so we can easily check for extensions.
293 $assert_(jsProto[$_extensionType] === void 0);
294 jsProto[$_extensionType] = $dartExtType; 298 jsProto[$_extensionType] = $dartExtType;
295 $_installProperties(jsProto, extProto); 299 $_installProperties(jsProto, extProto);
296 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get; 300 let originalSigFn = $getOwnPropertyDescriptor($dartExtType, $_methodSig).get;
297 $assert_(originalSigFn); 301 $assert_(originalSigFn);
298 $defineMemoizedGetter($jsType, $_methodSig, originalSigFn); 302 $defineMemoizedGetter($jsType, $_methodSig, originalSigFn);
299 })()'''); 303 })()''');
300 304
301 /// 305 ///
302 /// Mark a concrete type as implementing extension methods. 306 /// Mark a concrete type as implementing extension methods.
303 /// For example: `class MyIter implements Iterable`. 307 /// For example: `class MyIter implements Iterable`.
(...skipping 10 matching lines...) Expand all
314 /// MyType.prototype[dartx.remove] = MyType.prototype.remove; 318 /// MyType.prototype[dartx.remove] = MyType.prototype.remove;
315 /// 319 ///
316 // TODO(jmesserly): essentially this gives two names to the same method. 320 // TODO(jmesserly): essentially this gives two names to the same method.
317 // This benefit is roughly equivalent call performance either way, but the 321 // This benefit is roughly equivalent call performance either way, but the
318 // cost is we need to call defineExtensionMembers any time a subclass 322 // cost is we need to call defineExtensionMembers any time a subclass
319 // overrides one of these methods. 323 // overrides one of these methods.
320 defineExtensionMembers(type, methodNames) => JS('', '''(() => { 324 defineExtensionMembers(type, methodNames) => JS('', '''(() => {
321 let proto = $type.prototype; 325 let proto = $type.prototype;
322 for (let name of $methodNames) { 326 for (let name of $methodNames) {
323 let method = $getOwnPropertyDescriptor(proto, name); 327 let method = $getOwnPropertyDescriptor(proto, name);
328 // TODO(vsm): We should be able to generate code to avoid this case.
329 // The method may be null if this type implements a potentially native
330 // interface but isn't native itself. For a field on this type, we're not
331 // generating a corresponding getter/setter method - it's just a field.
332 if (!method) continue;
324 $defineProperty(proto, $getExtensionSymbol(name), method); 333 $defineProperty(proto, $getExtensionSymbol(name), method);
325 } 334 }
326 // Ensure the signature is available too. 335 // Ensure the signature is available too.
327 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially 336 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially
328 // we need to copy the signature (and in the future, other data like 337 // we need to copy the signature (and in the future, other data like
329 // annotations) any time we copy a method as part of our metaprogramming. 338 // annotations) any time we copy a method as part of our metaprogramming.
330 // It might be more friendly to JS metaprogramming if we include this info 339 // It might be more friendly to JS metaprogramming if we include this info
331 // on the function. 340 // on the function.
332 let originalSigFn = $getOwnPropertyDescriptor($type, $_methodSig).get; 341 let originalSigFn = $getOwnPropertyDescriptor($type, $_methodSig).get;
333 $defineMemoizedGetter(type, $_methodSig, function() { 342 $defineMemoizedGetter(type, $_methodSig, function() {
(...skipping 24 matching lines...) Expand all
358 })()'''); 367 })()''');
359 368
360 /// Sets the element type of a list literal. 369 /// Sets the element type of a list literal.
361 list(obj, elementType) => 370 list(obj, elementType) =>
362 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))'); 371 JS('', '$setType($obj, ${getGenericClass(JSArray)}($elementType))');
363 372
364 setBaseClass(derived, base) => JS('', '''(() => { 373 setBaseClass(derived, base) => JS('', '''(() => {
365 // Link the extension to the type it's extending as a base class. 374 // Link the extension to the type it's extending as a base class.
366 $derived.prototype.__proto__ = $base.prototype; 375 $derived.prototype.__proto__ = $base.prototype;
367 })()'''); 376 })()''');
OLDNEW
« no previous file with comments | « tool/input_sdk/lib/web_sql/ddc/web_sql_ddc.dart ('k') | tool/sdk_expected_errors.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698