Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 | 7 |
| 8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 new jsAst.FunctionDeclaration( | 301 new jsAst.FunctionDeclaration( |
| 302 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; | 302 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; |
| 303 } | 303 } |
| 304 | 304 |
| 305 /** Needs defineClass to be defined. */ | 305 /** Needs defineClass to be defined. */ |
| 306 List buildInheritFrom() { | 306 List buildInheritFrom() { |
| 307 return [js(r''' | 307 return [js(r''' |
| 308 var inheritFrom = function() { | 308 var inheritFrom = function() { |
| 309 function tmp() {} | 309 function tmp() {} |
| 310 var hasOwnProperty = Object.prototype.hasOwnProperty; | 310 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 311 return function (constructor, superConstructor) { | 311 return function (constructor, superConstructor, aliases) { |
| 312 tmp.prototype = superConstructor.prototype; | 312 tmp.prototype = superConstructor.prototype; |
| 313 var object = new tmp(); | 313 var object = new tmp(); |
| 314 if (aliases) { | |
| 315 for (var pos = 0; pos < aliases.length; pos++) { | |
| 316 var member = aliases[pos].split(':'); | |
| 317 object[member[0]] = object[member[1]]; | |
| 318 } | |
| 319 } | |
| 314 var properties = constructor.prototype; | 320 var properties = constructor.prototype; |
| 315 for (var member in properties) | 321 for (var member in properties) |
| 316 if (hasOwnProperty.call(properties, member)) | 322 if (hasOwnProperty.call(properties, member)) |
| 317 object[member] = properties[member]; | 323 object[member] = properties[member]; |
|
sra1
2014/11/03 18:30:56
If you moved the alias logic here (split member),
herhut
2014/11/04 12:52:49
No, great suggestion. Done.
| |
| 318 object.constructor = constructor; | 324 object.constructor = constructor; |
| 319 constructor.prototype = object; | 325 constructor.prototype = object; |
| 320 return object; | 326 return object; |
| 321 }; | 327 }; |
| 322 }() | 328 }() |
| 323 ''')]; | 329 ''')]; |
| 324 } | 330 } |
| 325 | 331 |
| 326 jsAst.Fun get finishClassesFunction { | 332 jsAst.Fun get finishClassesFunction { |
| 327 // Class descriptions are collected in a JS object. | 333 // Class descriptions are collected in a JS object. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 343 jsAst.Expression metadataAccess = | 349 jsAst.Expression metadataAccess = |
| 344 generateEmbeddedGlobalAccess(embeddedNames.METADATA); | 350 generateEmbeddedGlobalAccess(embeddedNames.METADATA); |
| 345 jsAst.Expression interceptorsByTagAccess = | 351 jsAst.Expression interceptorsByTagAccess = |
| 346 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 352 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| 347 jsAst.Expression leafTagsAccess = | 353 jsAst.Expression leafTagsAccess = |
| 348 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 354 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 349 | 355 |
| 350 return js(''' | 356 return js(''' |
| 351 function(collectedClasses, isolateProperties, existingIsolateProperties) { | 357 function(collectedClasses, isolateProperties, existingIsolateProperties) { |
| 352 var pendingClasses = Object.create(null); | 358 var pendingClasses = Object.create(null); |
| 359 var pendingAliases = Object.create(null); | |
| 353 if (!#) # = Object.create(null); // embedded allClasses. | 360 if (!#) # = Object.create(null); // embedded allClasses. |
| 354 var allClasses = #; // embedded allClasses; | 361 var allClasses = #; // embedded allClasses; |
| 355 | 362 |
| 356 if (#) // DEBUG_FAST_OBJECTS | 363 if (#) // DEBUG_FAST_OBJECTS |
| 357 print("Number of classes: " + | 364 print("Number of classes: " + |
| 358 Object.getOwnPropertyNames(\$\$).length); | 365 Object.getOwnPropertyNames(\$\$).length); |
| 359 | 366 |
| 360 var hasOwnProperty = Object.prototype.hasOwnProperty; | 367 var hasOwnProperty = Object.prototype.hasOwnProperty; |
| 361 | 368 |
| 362 if (typeof dart_precompiled == "function") { | 369 if (typeof dart_precompiled == "function") { |
| 363 var constructors = dart_precompiled(collectedClasses); | 370 var constructors = dart_precompiled(collectedClasses); |
| 364 } else { | 371 } else { |
| 365 var combinedConstructorFunction = | 372 var combinedConstructorFunction = |
| 366 "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+ | 373 "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+ |
| 367 "var \$desc;\\n"; | 374 "var \$desc;\\n"; |
| 368 var constructorsList = []; | 375 var constructorsList = []; |
| 369 } | 376 } |
| 370 | 377 |
| 371 for (var cls in collectedClasses) { | 378 for (var cls in collectedClasses) { |
| 372 var desc = collectedClasses[cls]; | 379 var desc = collectedClasses[cls]; |
| 373 if (desc instanceof Array) desc = desc[1]; | 380 if (desc instanceof Array) desc = desc[1]; |
| 374 | 381 |
| 375 /* The 'fields' are either a constructor function or a | 382 /* The 'fields' are either a constructor function or a |
| 376 * string encoding fields, constructor and superclass. Get | 383 * string encoding fields, constructor, superclass and methods from |
| 377 * the superclass and the fields in the format | 384 * the superclass that need aliasing. Get the superclass, fields |
| 378 * '[name/]Super;field1,field2' | 385 * and aliases in the format |
| 386 * '[name/]Super;field1,field2;alias,alias2' | |
| 379 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor. | 387 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor. |
| 380 * The 'name/' is optional and contains the name that should be used | 388 * The 'name/' is optional and contains the name that should be used |
| 381 * when printing the runtime type string. It is used, for example, | 389 * when printing the runtime type string. It is used, for example, |
| 382 * to print the runtime type JSInt as 'int'. | 390 * to print the runtime type JSInt as 'int'. |
| 383 */ | 391 */ |
| 384 var classData = desc["${namer.classDescriptorProperty}"], | 392 var classData = desc["${namer.classDescriptorProperty}"], |
| 385 supr, name = cls, fields = classData; | 393 supr, name = cls, fields = classData, aliases = false; |
| 386 if (#) // backend.hasRetainedMetadata | 394 if (#) // backend.hasRetainedMetadata |
| 387 if (typeof classData == "object" && | 395 if (typeof classData == "object" && |
| 388 classData instanceof Array) { | 396 classData instanceof Array) { |
| 389 classData = fields = classData[0]; | 397 classData = fields = classData[0]; |
| 390 } | 398 } |
| 391 if (typeof classData == "string") { | 399 if (typeof classData == "string") { |
| 392 var split = classData.split("/"); | 400 var split = classData.split("/"); |
| 393 if (split.length == 2) { | 401 if (split.length == 2) { |
| 394 name = split[0]; | 402 name = split[0]; |
| 395 fields = split[1]; | 403 fields = split[1]; |
| 396 } | 404 } |
| 397 } | 405 } |
| 398 | 406 |
| 399 var s = fields.split(";"); | 407 var s = fields.split(";"); |
| 400 fields = s[1] == "" ? [] : s[1].split(","); | 408 fields = s[1] == "" ? [] : s[1].split(","); |
| 409 if (s.length == 3) aliases = s[2].split(","); | |
| 401 supr = s[0]; | 410 supr = s[0]; |
| 411 | |
| 402 split = supr.split(":"); | 412 split = supr.split(":"); |
| 403 if (split.length == 2) { | 413 if (split.length == 2) { |
| 404 supr = split[0]; | 414 supr = split[0]; |
| 405 var functionSignature = split[1]; | 415 var functionSignature = split[1]; |
| 406 if (functionSignature) | 416 if (functionSignature) |
| 407 desc.\$signature = (function(s) { | 417 desc.\$signature = (function(s) { |
| 408 return function(){ return #[s]; }; // embedded metadata. | 418 return function(){ return #[s]; }; // embedded metadata. |
| 409 })(functionSignature); | 419 })(functionSignature); |
| 410 } | 420 } |
| 411 | 421 |
| 412 if (#) // needsMixinSupport | 422 if (#) // needsMixinSupport |
| 413 if (supr && supr.indexOf("+") > 0) { | 423 if (supr && supr.indexOf("+") > 0) { |
| 414 s = supr.split("+"); | 424 s = supr.split("+"); |
| 415 supr = s[0]; | 425 supr = s[0]; |
| 416 var mixin = collectedClasses[s[1]]; | 426 var mixin = collectedClasses[s[1]]; |
| 417 if (mixin instanceof Array) mixin = mixin[1]; | 427 if (mixin instanceof Array) mixin = mixin[1]; |
| 418 for (var d in mixin) { | 428 for (var d in mixin) { |
| 419 if (hasOwnProperty.call(mixin, d) && | 429 if (hasOwnProperty.call(mixin, d) && |
| 420 !hasOwnProperty.call(desc, d)) | 430 !hasOwnProperty.call(desc, d)) |
| 421 desc[d] = mixin[d]; | 431 desc[d] = mixin[d]; |
| 422 } | 432 } |
| 423 } | 433 } |
| 424 | 434 |
| 425 if (typeof dart_precompiled != "function") { | 435 if (typeof dart_precompiled != "function") { |
| 426 combinedConstructorFunction += defineClass(name, cls, fields); | 436 combinedConstructorFunction += defineClass(name, cls, fields); |
| 427 constructorsList.push(cls); | 437 constructorsList.push(cls); |
| 428 } | 438 } |
| 429 if (supr) pendingClasses[cls] = supr; | 439 if (supr) pendingClasses[cls] = supr; |
| 440 if (aliases) pendingAliases[cls] = aliases; | |
| 430 } | 441 } |
| 431 | 442 |
| 432 if (typeof dart_precompiled != "function") { | 443 if (typeof dart_precompiled != "function") { |
| 433 combinedConstructorFunction += | 444 combinedConstructorFunction += |
| 434 "return [\\n " + constructorsList.join(",\\n ") + "\\n]"; | 445 "return [\\n " + constructorsList.join(",\\n ") + "\\n]"; |
| 435 var constructors = | 446 var constructors = |
| 436 new Function("\$collectedClasses", combinedConstructorFunction) | 447 new Function("\$collectedClasses", combinedConstructorFunction) |
| 437 (collectedClasses); | 448 (collectedClasses); |
| 438 combinedConstructorFunction = null; | 449 combinedConstructorFunction = null; |
| 439 } | 450 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 jsAst.Expression leafTagsAccess = | 501 jsAst.Expression leafTagsAccess = |
| 491 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 502 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 492 | 503 |
| 493 return js.statement(''' | 504 return js.statement(''' |
| 494 function finishClass(cls) { | 505 function finishClass(cls) { |
| 495 | 506 |
| 496 if (finishedClasses[cls]) return; | 507 if (finishedClasses[cls]) return; |
| 497 finishedClasses[cls] = true; | 508 finishedClasses[cls] = true; |
| 498 | 509 |
| 499 var superclass = pendingClasses[cls]; | 510 var superclass = pendingClasses[cls]; |
| 511 var aliases = pendingAliases[cls]; | |
| 500 | 512 |
| 501 // The superclass is only false (empty string) for the Dart Object | 513 // The superclass is only false (empty string) for the Dart Object |
| 502 // class. The minifier together with noSuchMethod can put methods on | 514 // class. The minifier together with noSuchMethod can put methods on |
| 503 // the Object.prototype object, and they show through here, so we check | 515 // the Object.prototype object, and they show through here, so we check |
| 504 // that we have a string. | 516 // that we have a string. |
| 505 if (!superclass || typeof superclass != "string") return; | 517 if (!superclass || typeof superclass != "string") return; |
| 506 finishClass(superclass); | 518 finishClass(superclass); |
| 507 var constructor = allClasses[cls]; | 519 var constructor = allClasses[cls]; |
| 508 var superConstructor = allClasses[superclass]; | 520 var superConstructor = allClasses[superclass]; |
| 509 | 521 |
| 510 if (!superConstructor) | 522 if (!superConstructor) |
| 511 superConstructor = existingIsolateProperties[superclass]; | 523 superConstructor = existingIsolateProperties[superclass]; |
| 512 | 524 |
| 513 var prototype = inheritFrom(constructor, superConstructor); | 525 var prototype = inheritFrom(constructor, superConstructor, aliases); |
| 514 | 526 |
| 515 if (#) { // !nativeClasses.isEmpty, | 527 if (#) { // !nativeClasses.isEmpty, |
| 516 // The property looks like this: | 528 // The property looks like this: |
| 517 // | 529 // |
| 518 // HtmlElement: { | 530 // HtmlElement: { |
| 519 // "%": "HTMLDivElement|HTMLAnchorElement;HTMLElement;FancyButton" | 531 // "%": "HTMLDivElement|HTMLAnchorElement;HTMLElement;FancyButton" |
| 520 // | 532 // |
| 521 // The first two semicolon-separated parts contain dispatch tags, the | 533 // The first two semicolon-separated parts contain dispatch tags, the |
| 522 // third contains the JavaScript names for classes. | 534 // third contains the JavaScript names for classes. |
| 523 // | 535 // |
| (...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1989 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2001 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 1990 if (element.isInstanceMember) { | 2002 if (element.isInstanceMember) { |
| 1991 cachedClassBuilders.remove(element.enclosingClass); | 2003 cachedClassBuilders.remove(element.enclosingClass); |
| 1992 | 2004 |
| 1993 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2005 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 1994 | 2006 |
| 1995 } | 2007 } |
| 1996 } | 2008 } |
| 1997 } | 2009 } |
| 1998 } | 2010 } |
| OLD | NEW |