OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * Assigns JavaScript identifiers to Dart variables, class-names and members. | 8 * Assigns JavaScript identifiers to Dart variables, class-names and members. |
9 * | 9 * |
10 * Names are generated through three stages: | 10 * Names are generated through three stages: |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 constantHasher = new ConstantCanonicalHasher(compiler), | 450 constantHasher = new ConstantCanonicalHasher(compiler), |
451 functionTypeNamer = new FunctionTypeNamer(compiler) { | 451 functionTypeNamer = new FunctionTypeNamer(compiler) { |
452 _literalAsyncPrefix = new StringBackedName(asyncPrefix); | 452 _literalAsyncPrefix = new StringBackedName(asyncPrefix); |
453 _literalGetterPrefix = new StringBackedName(getterPrefix); | 453 _literalGetterPrefix = new StringBackedName(getterPrefix); |
454 _literalSetterPrefix = new StringBackedName(setterPrefix); | 454 _literalSetterPrefix = new StringBackedName(setterPrefix); |
455 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); | 455 _literalLazyGetterPrefix = new StringBackedName(lazyGetterPrefix); |
456 } | 456 } |
457 | 457 |
458 JavaScriptBackend get backend => compiler.backend; | 458 JavaScriptBackend get backend => compiler.backend; |
459 | 459 |
| 460 DiagnosticReporter get reporter => compiler.reporter; |
| 461 |
460 String get deferredTypesName => 'deferredTypes'; | 462 String get deferredTypesName => 'deferredTypes'; |
461 String get isolateName => 'Isolate'; | 463 String get isolateName => 'Isolate'; |
462 String get isolatePropertiesName => r'$isolateProperties'; | 464 String get isolatePropertiesName => r'$isolateProperties'; |
463 jsAst.Name get noSuchMethodName => invocationName(Selectors.noSuchMethod_); | 465 jsAst.Name get noSuchMethodName => invocationName(Selectors.noSuchMethod_); |
464 | 466 |
465 /** | 467 /** |
466 * Some closures must contain their name. The name is stored in | 468 * Some closures must contain their name. The name is stored in |
467 * [STATIC_CLOSURE_NAME_NAME]. | 469 * [STATIC_CLOSURE_NAME_NAME]. |
468 */ | 470 */ |
469 String get STATIC_CLOSURE_NAME_NAME => r'$name'; | 471 String get STATIC_CLOSURE_NAME_NAME => r'$name'; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 case JsGetName.IS_INDEXABLE_FIELD_NAME: | 508 case JsGetName.IS_INDEXABLE_FIELD_NAME: |
507 Element cls = backend.findHelper('JavaScriptIndexingBehavior'); | 509 Element cls = backend.findHelper('JavaScriptIndexingBehavior'); |
508 return operatorIs(cls); | 510 return operatorIs(cls); |
509 case JsGetName.NULL_CLASS_TYPE_NAME: | 511 case JsGetName.NULL_CLASS_TYPE_NAME: |
510 return runtimeTypeName(compiler.nullClass); | 512 return runtimeTypeName(compiler.nullClass); |
511 case JsGetName.OBJECT_CLASS_TYPE_NAME: | 513 case JsGetName.OBJECT_CLASS_TYPE_NAME: |
512 return runtimeTypeName(compiler.objectClass); | 514 return runtimeTypeName(compiler.objectClass); |
513 case JsGetName.FUNCTION_CLASS_TYPE_NAME: | 515 case JsGetName.FUNCTION_CLASS_TYPE_NAME: |
514 return runtimeTypeName(compiler.functionClass); | 516 return runtimeTypeName(compiler.functionClass); |
515 default: | 517 default: |
516 compiler.reportErrorMessage( | 518 reporter.reportErrorMessage( |
517 node, | 519 node, |
518 MessageKind.GENERIC, | 520 MessageKind.GENERIC, |
519 {'text': 'Error: Namer has no name for "$name".'}); | 521 {'text': 'Error: Namer has no name for "$name".'}); |
520 return asName('BROKEN'); | 522 return asName('BROKEN'); |
521 } | 523 } |
522 } | 524 } |
523 | 525 |
524 /// Return a reference to the given [name]. | 526 /// Return a reference to the given [name]. |
525 /// | 527 /// |
526 /// This is used to ensure that every use site of a name has a unique node so | 528 /// This is used to ensure that every use site of a name has a unique node so |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 List<String> suffix = callSuffixForStructure(selector.callStructure); | 700 List<String> suffix = callSuffixForStructure(selector.callStructure); |
699 if (selector.name == Identifiers.call) { | 701 if (selector.name == Identifiers.call) { |
700 // Derive the annotated name for this variant of 'call'. | 702 // Derive the annotated name for this variant of 'call'. |
701 return deriveCallMethodName(suffix); | 703 return deriveCallMethodName(suffix); |
702 } | 704 } |
703 jsAst.Name disambiguatedName = | 705 jsAst.Name disambiguatedName = |
704 _disambiguateMember(selector.memberName, suffix); | 706 _disambiguateMember(selector.memberName, suffix); |
705 return disambiguatedName; // Methods other than call are not annotated. | 707 return disambiguatedName; // Methods other than call are not annotated. |
706 | 708 |
707 default: | 709 default: |
708 compiler.internalError(compiler.currentElement, | 710 reporter.internalError( |
| 711 CURRENT_ELEMENT_SPANNABLE, |
709 'Unexpected selector kind: ${selector.kind}'); | 712 'Unexpected selector kind: ${selector.kind}'); |
710 return null; | 713 return null; |
711 } | 714 } |
712 } | 715 } |
713 | 716 |
714 /** | 717 /** |
715 * Returns the internal name used for an invocation mirror of this selector. | 718 * Returns the internal name used for an invocation mirror of this selector. |
716 */ | 719 */ |
717 jsAst.Name invocationMirrorInternalName(Selector selector) | 720 jsAst.Name invocationMirrorInternalName(Selector selector) |
718 => invocationName(selector); | 721 => invocationName(selector); |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 final Compiler compiler; | 1577 final Compiler compiler; |
1575 final ConstantCanonicalHasher hasher; | 1578 final ConstantCanonicalHasher hasher; |
1576 | 1579 |
1577 String root = null; // First word, usually a type name. | 1580 String root = null; // First word, usually a type name. |
1578 bool failed = false; // Failed to generate something pretty. | 1581 bool failed = false; // Failed to generate something pretty. |
1579 List<String> fragments = <String>[]; | 1582 List<String> fragments = <String>[]; |
1580 int length = 0; | 1583 int length = 0; |
1581 | 1584 |
1582 ConstantNamingVisitor(this.compiler, this.hasher); | 1585 ConstantNamingVisitor(this.compiler, this.hasher); |
1583 | 1586 |
| 1587 DiagnosticReporter get reporter => compiler.reporter; |
| 1588 |
1584 String getName(ConstantValue constant) { | 1589 String getName(ConstantValue constant) { |
1585 _visit(constant); | 1590 _visit(constant); |
1586 if (root == null) return 'CONSTANT'; | 1591 if (root == null) return 'CONSTANT'; |
1587 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; | 1592 if (failed) return '${root}_${getHashTag(constant, DEFAULT_TAG_LENGTH)}'; |
1588 if (fragments.length == 1) return 'C_${root}'; | 1593 if (fragments.length == 1) return 'C_${root}'; |
1589 return fragments.join('_'); | 1594 return fragments.join('_'); |
1590 } | 1595 } |
1591 | 1596 |
1592 String getHashTag(ConstantValue constant, int width) => | 1597 String getHashTag(ConstantValue constant, int width) => |
1593 hashWord(hasher.getHash(constant), width); | 1598 hashWord(hasher.getHash(constant), width); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 case SyntheticConstantKind.DUMMY_INTERCEPTOR: | 1741 case SyntheticConstantKind.DUMMY_INTERCEPTOR: |
1737 add('dummy_receiver'); | 1742 add('dummy_receiver'); |
1738 break; | 1743 break; |
1739 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: | 1744 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: |
1740 // Omit. These are opaque deferred indexes with nothing helpful to add. | 1745 // Omit. These are opaque deferred indexes with nothing helpful to add. |
1741 break; | 1746 break; |
1742 case SyntheticConstantKind.NAME: | 1747 case SyntheticConstantKind.NAME: |
1743 add('name'); | 1748 add('name'); |
1744 break; | 1749 break; |
1745 default: | 1750 default: |
1746 compiler.internalError(compiler.currentElement, | 1751 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
1747 "Unexpected SyntheticConstantValue"); | 1752 "Unexpected SyntheticConstantValue"); |
1748 } | 1753 } |
1749 } | 1754 } |
1750 | 1755 |
1751 @override | 1756 @override |
1752 void visitDeferred(DeferredConstantValue constant, [_]) { | 1757 void visitDeferred(DeferredConstantValue constant, [_]) { |
1753 addRoot('Deferred'); | 1758 addRoot('Deferred'); |
1754 } | 1759 } |
1755 } | 1760 } |
1756 | 1761 |
1757 /** | 1762 /** |
1758 * Generates canonical hash values for [ConstantValue]s. | 1763 * Generates canonical hash values for [ConstantValue]s. |
1759 * | 1764 * |
1760 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, | 1765 * Unfortunately, [Constant.hashCode] is not stable under minor perturbations, |
1761 * so it can't be used for generating names. This hasher keeps consistency | 1766 * so it can't be used for generating names. This hasher keeps consistency |
1762 * between runs by basing hash values of the names of elements, rather than | 1767 * between runs by basing hash values of the names of elements, rather than |
1763 * their hashCodes. | 1768 * their hashCodes. |
1764 */ | 1769 */ |
1765 class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> { | 1770 class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> { |
1766 | 1771 |
1767 static const _MASK = 0x1fffffff; | 1772 static const _MASK = 0x1fffffff; |
1768 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; | 1773 static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024; |
1769 | 1774 |
1770 | 1775 |
1771 final Compiler compiler; | 1776 final Compiler compiler; |
1772 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); | 1777 final Map<ConstantValue, int> hashes = new Map<ConstantValue, int>(); |
1773 | 1778 |
1774 ConstantCanonicalHasher(this.compiler); | 1779 ConstantCanonicalHasher(this.compiler); |
1775 | 1780 |
| 1781 DiagnosticReporter get reporter => compiler.reporter; |
| 1782 |
1776 int getHash(ConstantValue constant) => _visit(constant); | 1783 int getHash(ConstantValue constant) => _visit(constant); |
1777 | 1784 |
1778 int _visit(ConstantValue constant) { | 1785 int _visit(ConstantValue constant) { |
1779 int hash = hashes[constant]; | 1786 int hash = hashes[constant]; |
1780 if (hash == null) { | 1787 if (hash == null) { |
1781 hash = _finish(constant.accept(this, null)); | 1788 hash = _finish(constant.accept(this, null)); |
1782 hashes[constant] = hash; | 1789 hashes[constant] = hash; |
1783 } | 1790 } |
1784 return hash; | 1791 return hash; |
1785 } | 1792 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 | 1856 |
1850 @override | 1857 @override |
1851 int visitSynthetic(SyntheticConstantValue constant, [_]) { | 1858 int visitSynthetic(SyntheticConstantValue constant, [_]) { |
1852 switch (constant.kind) { | 1859 switch (constant.kind) { |
1853 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: | 1860 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: |
1854 // These contain a deferred opaque index into metadata. There is nothing | 1861 // These contain a deferred opaque index into metadata. There is nothing |
1855 // we can access that is stable between compiles. Luckily, since they | 1862 // we can access that is stable between compiles. Luckily, since they |
1856 // resolve to integer indexes, they're always part of a larger constant. | 1863 // resolve to integer indexes, they're always part of a larger constant. |
1857 return 0; | 1864 return 0; |
1858 default: | 1865 default: |
1859 compiler.internalError(NO_LOCATION_SPANNABLE, | 1866 reporter.internalError( |
1860 'SyntheticConstantValue should never be named and
' | 1867 NO_LOCATION_SPANNABLE, |
1861 'never be subconstant'); | 1868 'SyntheticConstantValue should never be named and ' |
| 1869 'never be subconstant'); |
1862 return 0; | 1870 return 0; |
1863 } | 1871 } |
1864 } | 1872 } |
1865 | 1873 |
1866 @override | 1874 @override |
1867 int visitDeferred(DeferredConstantValue constant, [_]) { | 1875 int visitDeferred(DeferredConstantValue constant, [_]) { |
1868 int hash = constant.prefix.hashCode; | 1876 int hash = constant.prefix.hashCode; |
1869 return _combine(hash, _visit(constant.referenced)); | 1877 return _combine(hash, _visit(constant.referenced)); |
1870 } | 1878 } |
1871 | 1879 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1993 } | 2001 } |
1994 } | 2002 } |
1995 } | 2003 } |
1996 } | 2004 } |
1997 | 2005 |
1998 enum NamingScope { | 2006 enum NamingScope { |
1999 global, | 2007 global, |
2000 instance, | 2008 instance, |
2001 constant | 2009 constant |
2002 } | 2010 } |
OLD | NEW |