Chromium Code Reviews| 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 library js_backend.namer; | 5 library js_backend.namer; |
| 6 | 6 |
| 7 import 'dart:collection' show HashMap; | 7 import 'dart:collection' show HashMap; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' show JsGetName; | 9 import 'package:js_runtime/shared/embedded_names.dart' show JsGetName; |
| 10 | 10 |
| (...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 return '$name\$${suffix.join(r'$')}'; | 765 return '$name\$${suffix.join(r'$')}'; |
| 766 } | 766 } |
| 767 | 767 |
| 768 /// Name for a constructor body. | 768 /// Name for a constructor body. |
| 769 jsAst.Name constructorBodyName(FunctionElement ctor) { | 769 jsAst.Name constructorBodyName(FunctionElement ctor) { |
| 770 return _disambiguateInternalMember( | 770 return _disambiguateInternalMember( |
| 771 ctor, () => _proposeNameForConstructorBody(ctor)); | 771 ctor, () => _proposeNameForConstructorBody(ctor)); |
| 772 } | 772 } |
| 773 | 773 |
| 774 /// Annotated name for [method] encoding arity and named parameters. | 774 /// Annotated name for [method] encoding arity and named parameters. |
| 775 jsAst.Name instanceMethodName(MethodElement method) { | 775 jsAst.Name instanceMethodName(FunctionEntity method) { |
| 776 if (method.isGenerativeConstructorBody) { | 776 if (method is ConstructorBodyElement) { |
|
Siggi Cherem (dart-lang)
2017/05/30 22:10:20
we'll need this for the J model too, correct? Mayb
Johnni Winther
2017/05/31 08:19:31
Done.
| |
| 777 return constructorBodyName(method); | 777 return constructorBodyName(method); |
| 778 } | 778 } |
| 779 return invocationName(new Selector.fromElement(method)); | 779 return invocationName(new Selector.fromElement(method)); |
| 780 } | 780 } |
| 781 | 781 |
| 782 /// Returns the annotated name for a variant of `call`. | 782 /// Returns the annotated name for a variant of `call`. |
| 783 /// The result has the form: | 783 /// The result has the form: |
| 784 /// | 784 /// |
| 785 /// call$<N>$namedParam1...$namedParam<M> | 785 /// call$<N>$namedParam1...$namedParam<M> |
| 786 /// | 786 /// |
| (...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1414 | 1414 |
| 1415 /// Returns the runtime name for [element]. | 1415 /// Returns the runtime name for [element]. |
| 1416 /// | 1416 /// |
| 1417 /// This name is used as the basis for deriving `is` and `as` property names | 1417 /// This name is used as the basis for deriving `is` and `as` property names |
| 1418 /// for the given type. | 1418 /// for the given type. |
| 1419 /// | 1419 /// |
| 1420 /// The result is not always safe as a property name unless prefixing | 1420 /// The result is not always safe as a property name unless prefixing |
| 1421 /// [operatorIsPrefix] or [operatorAsPrefix]. If this is a function type, | 1421 /// [operatorIsPrefix] or [operatorAsPrefix]. If this is a function type, |
| 1422 /// then by convention, an underscore must also separate [operatorIsPrefix] | 1422 /// then by convention, an underscore must also separate [operatorIsPrefix] |
| 1423 /// from the type name. | 1423 /// from the type name. |
| 1424 jsAst.Name runtimeTypeName(TypeDeclarationElement element) { | 1424 jsAst.Name runtimeTypeName(Entity element) { |
| 1425 if (element == null) return _literalDynamic; | 1425 if (element == null) return _literalDynamic; |
| 1426 // The returned name affects both the global and instance member namespaces: | 1426 // The returned name affects both the global and instance member namespaces: |
| 1427 // | 1427 // |
| 1428 // - If given a class, this must coincide with the class name, which | 1428 // - If given a class, this must coincide with the class name, which |
| 1429 // is also the GLOBAL property name of its constructor. | 1429 // is also the GLOBAL property name of its constructor. |
| 1430 // | 1430 // |
| 1431 // - The result is used to derive `$isX` and `$asX` names, which are used | 1431 // - The result is used to derive `$isX` and `$asX` names, which are used |
| 1432 // as INSTANCE property names. | 1432 // as INSTANCE property names. |
| 1433 // | 1433 // |
| 1434 // To prevent clashes in both namespaces at once, we disambiguate the name | 1434 // To prevent clashes in both namespaces at once, we disambiguate the name |
| 1435 // as a global here, and in [_sanitizeForAnnotations] we ensure that | 1435 // as a global here, and in [_sanitizeForAnnotations] we ensure that |
| 1436 // ordinary instance members cannot start with `$is` or `$as`. | 1436 // ordinary instance members cannot start with `$is` or `$as`. |
| 1437 return _disambiguateGlobalType(element); | 1437 return _disambiguateGlobalType(element); |
| 1438 } | 1438 } |
| 1439 | 1439 |
| 1440 /// Returns the disambiguated name of [class_]. | 1440 /// Returns the disambiguated name of [class_]. |
| 1441 /// | 1441 /// |
| 1442 /// This is both the *runtime type* of the class (see [runtimeTypeName]) | 1442 /// This is both the *runtime type* of the class (see [runtimeTypeName]) |
| 1443 /// and a global property name in which to store its JS constructor. | 1443 /// and a global property name in which to store its JS constructor. |
| 1444 jsAst.Name className(ClassElement class_) => _disambiguateGlobalType(class_); | 1444 jsAst.Name className(ClassEntity class_) => _disambiguateGlobalType(class_); |
| 1445 | 1445 |
| 1446 /// Property name on which [member] can be accessed directly, | 1446 /// Property name on which [member] can be accessed directly, |
| 1447 /// without clashing with another JS property name. | 1447 /// without clashing with another JS property name. |
| 1448 /// | 1448 /// |
| 1449 /// This is used for implementing super-calls, where ordinary dispatch | 1449 /// This is used for implementing super-calls, where ordinary dispatch |
| 1450 /// semantics must be circumvented. For example: | 1450 /// semantics must be circumvented. For example: |
| 1451 /// | 1451 /// |
| 1452 /// class A { foo() } | 1452 /// class A { foo() } |
| 1453 /// class B extends A { | 1453 /// class B extends A { |
| 1454 /// foo() { super.foo() } | 1454 /// foo() { super.foo() } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1470 return "super\$${member.enclosingClass.name}\$$invocationName"; | 1470 return "super\$${member.enclosingClass.name}\$$invocationName"; |
| 1471 }); | 1471 }); |
| 1472 } | 1472 } |
| 1473 | 1473 |
| 1474 /// Property name in which to store the given static or instance [method]. | 1474 /// Property name in which to store the given static or instance [method]. |
| 1475 /// For instance methods, this includes the suffix encoding arity and named | 1475 /// For instance methods, this includes the suffix encoding arity and named |
| 1476 /// parameters. | 1476 /// parameters. |
| 1477 /// | 1477 /// |
| 1478 /// The name is not necessarily unique to [method], since a static method | 1478 /// The name is not necessarily unique to [method], since a static method |
| 1479 /// may share its name with an instance method. | 1479 /// may share its name with an instance method. |
| 1480 jsAst.Name methodPropertyName(MethodElement method) { | 1480 jsAst.Name methodPropertyName(FunctionEntity method) { |
| 1481 return method.isInstanceMember | 1481 return method.isInstanceMember |
| 1482 ? instanceMethodName(method) | 1482 ? instanceMethodName(method) |
| 1483 : globalPropertyNameForMember(method); | 1483 : globalPropertyNameForMember(method); |
| 1484 } | 1484 } |
| 1485 | 1485 |
| 1486 /// Returns true if [element] is stored in the static state holder | 1486 /// Returns true if [element] is stored in the static state holder |
| 1487 /// ([staticStateHolder]). We intend to store only mutable static state | 1487 /// ([staticStateHolder]). We intend to store only mutable static state |
| 1488 /// there, whereas constants are stored in 'C'. Functions, accessors, | 1488 /// there, whereas constants are stored in 'C'. Functions, accessors, |
| 1489 /// classes, etc. are stored in one of the other objects in | 1489 /// classes, etc. are stored in one of the other objects in |
| 1490 /// [reservedGlobalObjectNames]. | 1490 /// [reservedGlobalObjectNames]. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1503 !element.isClass && | 1503 !element.isClass && |
| 1504 !element.isTypedef && | 1504 !element.isTypedef && |
| 1505 !element.isConstructor && | 1505 !element.isConstructor && |
| 1506 !element.isFunction && | 1506 !element.isFunction && |
| 1507 !element.isLibrary; | 1507 !element.isLibrary; |
| 1508 } | 1508 } |
| 1509 return element.isField; | 1509 return element.isField; |
| 1510 } | 1510 } |
| 1511 | 1511 |
| 1512 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. | 1512 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. |
| 1513 // TODO(johnniwinther): Verify that the implementation can be changed to | |
| 1514 // `globalObjectForLibrary(element.library)`. | |
| 1515 String globalObjectForMethod(MethodElement element) => | |
| 1516 globalObjectForMember(element); | |
| 1517 | |
| 1518 /// Returns [staticStateHolder] or one of [reservedGlobalObjectNames]. | |
| 1519 String globalObjectForMember(MemberEntity element) { | 1513 String globalObjectForMember(MemberEntity element) { |
| 1520 if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder; | 1514 if (_isPropertyOfStaticStateHolder(element)) return staticStateHolder; |
| 1521 return globalObjectForLibrary(element.library); | 1515 return globalObjectForLibrary(element.library); |
| 1522 } | 1516 } |
| 1523 | 1517 |
| 1524 String globalObjectForClass(ClassEntity element) { | 1518 String globalObjectForClass(ClassEntity element) { |
| 1525 return globalObjectForLibrary(element.library); | 1519 return globalObjectForLibrary(element.library); |
| 1526 } | 1520 } |
| 1527 | 1521 |
| 1528 String globalObjectForType(Entity element) { | 1522 String globalObjectForType(Entity element) { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1549 return new CompoundName([_literalLazyGetterPrefix, name]); | 1543 return new CompoundName([_literalLazyGetterPrefix, name]); |
| 1550 } | 1544 } |
| 1551 | 1545 |
| 1552 jsAst.Name lazyInitializerName(FieldEntity element) { | 1546 jsAst.Name lazyInitializerName(FieldEntity element) { |
| 1553 assert(element.isTopLevel || element.isStatic); | 1547 assert(element.isTopLevel || element.isStatic); |
| 1554 jsAst.Name name = _disambiguateGlobalMember(element); | 1548 jsAst.Name name = _disambiguateGlobalMember(element); |
| 1555 // These are not real dart getters, so do not use GetterName; | 1549 // These are not real dart getters, so do not use GetterName; |
| 1556 return deriveLazyInitializerName(name); | 1550 return deriveLazyInitializerName(name); |
| 1557 } | 1551 } |
| 1558 | 1552 |
| 1559 jsAst.Name staticClosureName(Element element) { | 1553 jsAst.Name staticClosureName(FunctionEntity element) { |
| 1560 assert(Elements.isStaticOrTopLevelFunction(element)); | 1554 assert(element.isTopLevel || element.isStatic); |
| 1561 String enclosing = | 1555 String enclosing = |
| 1562 element.enclosingClass == null ? "" : element.enclosingClass.name; | 1556 element.enclosingClass == null ? "" : element.enclosingClass.name; |
| 1563 String library = _proposeNameForLibrary(element.library); | 1557 String library = _proposeNameForLibrary(element.library); |
| 1564 return _disambiguateInternalGlobal( | 1558 return _disambiguateInternalGlobal( |
| 1565 "${library}_${enclosing}_${element.name}\$closure"); | 1559 "${library}_${enclosing}_${element.name}\$closure"); |
| 1566 } | 1560 } |
| 1567 | 1561 |
| 1568 // This name is used as part of the name of a TypeConstant | 1562 // This name is used as part of the name of a TypeConstant |
| 1569 String uniqueNameForTypeConstantElement( | 1563 String uniqueNameForTypeConstantElement( |
| 1570 LibraryEntity library, Entity element) { | 1564 LibraryEntity library, Entity element) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1615 return new CompoundName([ | 1609 return new CompoundName([ |
| 1616 new StringBackedName(operatorIsPrefix), | 1610 new StringBackedName(operatorIsPrefix), |
| 1617 _literalUnderscore, | 1611 _literalUnderscore, |
| 1618 getFunctionTypeName(type) | 1612 getFunctionTypeName(type) |
| 1619 ]); | 1613 ]); |
| 1620 } | 1614 } |
| 1621 InterfaceType interfaceType = type; | 1615 InterfaceType interfaceType = type; |
| 1622 return operatorIs(interfaceType.element); | 1616 return operatorIs(interfaceType.element); |
| 1623 } | 1617 } |
| 1624 | 1618 |
| 1625 jsAst.Name operatorIs(ClassElement element) { | 1619 jsAst.Name operatorIs(ClassEntity element) { |
| 1626 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. | 1620 // TODO(erikcorry): Reduce from $isx to ix when we are minifying. |
| 1627 return new CompoundName( | 1621 return new CompoundName( |
| 1628 [new StringBackedName(operatorIsPrefix), runtimeTypeName(element)]); | 1622 [new StringBackedName(operatorIsPrefix), runtimeTypeName(element)]); |
| 1629 } | 1623 } |
| 1630 | 1624 |
| 1631 /// Returns a name that does not clash with reserved JS keywords. | 1625 /// Returns a name that does not clash with reserved JS keywords. |
| 1632 String _sanitizeForKeywords(String name) { | 1626 String _sanitizeForKeywords(String name) { |
| 1633 if (jsReserved.contains(name)) { | 1627 if (jsReserved.contains(name)) { |
| 1634 name = '\$$name'; | 1628 name = '\$$name'; |
| 1635 } | 1629 } |
| 1636 assert(!jsReserved.contains(name)); | 1630 assert(!jsReserved.contains(name)); |
| 1637 return name; | 1631 return name; |
| 1638 } | 1632 } |
| 1639 | 1633 |
| 1640 jsAst.Name substitutionName(ClassElement element) { | 1634 jsAst.Name substitutionName(ClassEntity element) { |
| 1641 return new CompoundName( | 1635 return new CompoundName( |
| 1642 [new StringBackedName(operatorAsPrefix), runtimeTypeName(element)]); | 1636 [new StringBackedName(operatorAsPrefix), runtimeTypeName(element)]); |
| 1643 } | 1637 } |
| 1644 | 1638 |
| 1645 /// Translates a [String] into the corresponding [Name] data structure as | 1639 /// Translates a [String] into the corresponding [Name] data structure as |
| 1646 /// used by the namer. | 1640 /// used by the namer. |
| 1647 /// | 1641 /// |
| 1648 /// If [name] is a setter or getter name, the corresponding [GetterName] or | 1642 /// If [name] is a setter or getter name, the corresponding [GetterName] or |
| 1649 /// [SetterName] data structure is used. | 1643 /// [SetterName] data structure is used. |
| 1650 jsAst.Name asName(String name) { | 1644 jsAst.Name asName(String name) { |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2233 void addSuggestion(String original, String suggestion) { | 2227 void addSuggestion(String original, String suggestion) { |
| 2234 assert(!_suggestedNames.containsKey(original)); | 2228 assert(!_suggestedNames.containsKey(original)); |
| 2235 _suggestedNames[original] = suggestion; | 2229 _suggestedNames[original] = suggestion; |
| 2236 } | 2230 } |
| 2237 | 2231 |
| 2238 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); | 2232 bool hasSuggestion(String original) => _suggestedNames.containsKey(original); |
| 2239 bool isSuggestion(String candidate) { | 2233 bool isSuggestion(String candidate) { |
| 2240 return _suggestedNames.containsValue(candidate); | 2234 return _suggestedNames.containsValue(candidate); |
| 2241 } | 2235 } |
| 2242 } | 2236 } |
| OLD | NEW |