Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 library dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; | 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 | 356 |
| 357 var classExpr = new JS.ClassExpression(new JS.Identifier(type.name), | 357 var classExpr = new JS.ClassExpression(new JS.Identifier(type.name), |
| 358 _classHeritage(classElem), _emitClassMethods(node, ctors, fields)); | 358 _classHeritage(classElem), _emitClassMethods(node, ctors, fields)); |
| 359 | 359 |
| 360 String jsPeerName; | 360 String jsPeerName; |
| 361 var jsPeer = findAnnotation(classElem, _isJsPeerInterface); | 361 var jsPeer = findAnnotation(classElem, _isJsPeerInterface); |
| 362 if (jsPeer != null) { | 362 if (jsPeer != null) { |
| 363 jsPeerName = getConstantField(jsPeer, 'name', types.stringType); | 363 jsPeerName = getConstantField(jsPeer, 'name', types.stringType); |
| 364 } | 364 } |
| 365 | 365 |
| 366 var body = _finishClassMembers( | 366 var body = _finishClassMembers(classElem, classExpr, ctors, fields, methods, |
| 367 classElem, classExpr, ctors, fields, methods, jsPeerName); | 367 node.metadata, jsPeerName); |
| 368 | 368 |
| 369 var result = _finishClassDef(type, body); | 369 var result = _finishClassDef(type, body); |
| 370 | 370 |
| 371 if (jsPeerName != null) { | 371 if (jsPeerName != null) { |
| 372 // This class isn't allowed to be lazy, because we need to set up | 372 // This class isn't allowed to be lazy, because we need to set up |
| 373 // the native JS type eagerly at this point. | 373 // the native JS type eagerly at this point. |
| 374 // If we wanted to support laziness, we could defer the hookup until | 374 // If we wanted to support laziness, we could defer the hookup until |
| 375 // the end of the Dart library cycle load. | 375 // the end of the Dart library cycle load. |
| 376 assert(_loader.isLoaded(classElem)); | 376 assert(_loader.isLoaded(classElem)); |
| 377 | 377 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 var parentType = findSupertype(t, _implementsIterable); | 534 var parentType = findSupertype(t, _implementsIterable); |
| 535 if (parentType != null) return null; | 535 if (parentType != null) return null; |
| 536 | 536 |
| 537 // Otherwise, emit the adapter method, which wraps the Dart iterator in | 537 // Otherwise, emit the adapter method, which wraps the Dart iterator in |
| 538 // an ES6 iterator. | 538 // an ES6 iterator. |
| 539 return new JS.Method(js.call('$_SYMBOL.iterator'), js.call( | 539 return new JS.Method(js.call('$_SYMBOL.iterator'), js.call( |
| 540 'function() { return new dart.JsIterator(this.#); }', | 540 'function() { return new dart.JsIterator(this.#); }', |
| 541 [_emitMemberName('iterator', type: t)])); | 541 [_emitMemberName('iterator', type: t)])); |
| 542 } | 542 } |
| 543 | 543 |
| 544 JS.Expression _instantiateAnnotation(Annotation node) { | |
| 545 var element = node.element; | |
| 546 if (element is ConstructorElement) { | |
| 547 return _emitInstanceCreationExpression( | |
| 548 element, element.returnType, node.constructorName, node.arguments, tru e); | |
|
Jennifer Messerly
2015/06/09 23:29:53
./tool/format.sh ? :)
vsm
2015/06/10 13:28:27
Done. Sorry - uploaded too early.
| |
| 549 } else { | |
| 550 return _visit(node.name); | |
| 551 } | |
| 552 } | |
| 553 | |
| 544 /// Emit class members that need to come after the class declaration, such | 554 /// Emit class members that need to come after the class declaration, such |
| 545 /// as static fields. See [_emitClassMethods] for things that are emitted | 555 /// as static fields. See [_emitClassMethods] for things that are emitted |
| 546 /// inside the ES6 `class { ... }` node. | 556 /// inside the ES6 `class { ... }` node. |
| 547 JS.Statement _finishClassMembers(ClassElement classElem, | 557 JS.Statement _finishClassMembers(ClassElement classElem, |
| 548 JS.ClassExpression cls, List<ConstructorDeclaration> ctors, | 558 JS.ClassExpression cls, List<ConstructorDeclaration> ctors, |
| 549 List<FieldDeclaration> fields, List<MethodDeclaration> methods, | 559 List<FieldDeclaration> fields, List<MethodDeclaration> methods, |
| 550 String jsPeerName) { | 560 List<Annotation> metadata, String jsPeerName) { |
| 551 var name = classElem.name; | 561 var name = classElem.name; |
| 552 var body = <JS.Statement>[]; | 562 var body = <JS.Statement>[]; |
| 553 | 563 |
| 554 if (jsPeerName != null) { | 564 if (jsPeerName != null) { |
| 555 var dartxNames = []; | 565 var dartxNames = []; |
| 556 for (var m in methods) { | 566 for (var m in methods) { |
| 557 if (!m.isAbstract && !m.isStatic && m.element.isPublic) { | 567 if (!m.isAbstract && !m.isStatic && m.element.isPublic) { |
| 558 dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); | 568 dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); |
| 559 } | 569 } |
| 560 } | 570 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 var property = | 630 var property = |
| 621 new JS.Property(memberName, new JS.ArrayInitializer(parts)); | 631 new JS.Property(memberName, new JS.ArrayInitializer(parts)); |
| 622 if (node.isStatic) { | 632 if (node.isStatic) { |
| 623 tStatics.add(property); | 633 tStatics.add(property); |
| 624 sNames.add(memberName); | 634 sNames.add(memberName); |
| 625 } else { | 635 } else { |
| 626 tMethods.add(property); | 636 tMethods.add(property); |
| 627 } | 637 } |
| 628 } | 638 } |
| 629 } | 639 } |
| 640 | |
| 630 var tCtors = []; | 641 var tCtors = []; |
| 631 for (ConstructorDeclaration node in ctors) { | 642 for (ConstructorDeclaration node in ctors) { |
| 632 var memberName = _constructorName(node.element); | 643 var memberName = _constructorName(node.element); |
| 633 var element = node.element; | 644 var element = node.element; |
| 634 var parts = | 645 var parts = |
| 635 _emitFunctionTypeParts(element.type, dynamicIsBottom: false); | 646 _emitFunctionTypeParts(element.type, dynamicIsBottom: false); |
| 636 var property = | 647 var property = |
| 637 new JS.Property(memberName, new JS.ArrayInitializer(parts)); | 648 new JS.Property(memberName, new JS.ArrayInitializer(parts)); |
| 638 tCtors.add(property); | 649 tCtors.add(property); |
| 639 } | 650 } |
| 651 | |
| 640 build(name, elements) { | 652 build(name, elements) { |
| 641 var o = | 653 var o = |
| 642 new JS.ObjectInitializer(elements, multiline: elements.length > 1); | 654 new JS.ObjectInitializer(elements, multiline: elements.length > 1); |
| 643 var e = js.call('() => #', o); | 655 var e = js.call('() => #', o); |
| 644 var p = new JS.Property(_propertyName(name), e); | 656 var p = new JS.Property(_propertyName(name), e); |
| 645 return p; | 657 return p; |
| 646 } | 658 } |
| 647 var sigFields = []; | 659 var sigFields = []; |
| 648 if (!tCtors.isEmpty) sigFields.add(build('constructors', tCtors)); | 660 if (!tCtors.isEmpty) sigFields.add(build('constructors', tCtors)); |
| 649 if (!tMethods.isEmpty) sigFields.add(build('methods', tMethods)); | 661 if (!tMethods.isEmpty) sigFields.add(build('methods', tMethods)); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 668 var methodNames = []; | 680 var methodNames = []; |
| 669 for (var e in extensions) { | 681 for (var e in extensions) { |
| 670 methodNames.add(_elementMemberName(e)); | 682 methodNames.add(_elementMemberName(e)); |
| 671 } | 683 } |
| 672 body.add(js.statement('dart.defineExtensionMembers(#, #);', [ | 684 body.add(js.statement('dart.defineExtensionMembers(#, #);', [ |
| 673 name, | 685 name, |
| 674 new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4) | 686 new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4) |
| 675 ])); | 687 ])); |
| 676 } | 688 } |
| 677 | 689 |
| 690 // Metadata | |
| 691 if (metadata.isNotEmpty) { | |
| 692 body.add(js.statement('#[dart.metadata] = () => #;', [ | |
| 693 name, | |
| 694 new JS.ArrayInitializer(metadata.map(_instantiateAnnotation).toList()) | |
| 695 ])); | |
| 696 } | |
| 697 | |
| 678 return _statement(body); | 698 return _statement(body); |
| 679 } | 699 } |
| 680 | 700 |
| 681 List<ExecutableElement> _extensionsToImplement(ClassElement element) { | 701 List<ExecutableElement> _extensionsToImplement(ClassElement element) { |
| 682 var members = <ExecutableElement>[]; | 702 var members = <ExecutableElement>[]; |
| 683 if (_extensionTypes.contains(element)) return members; | 703 if (_extensionTypes.contains(element)) return members; |
| 684 | 704 |
| 685 // Collect all extension types we implement. | 705 // Collect all extension types we implement. |
| 686 var type = element.type; | 706 var type = element.type; |
| 687 var types = new Set<ClassElement>(); | 707 var types = new Set<ClassElement>(); |
| (...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1736 | 1756 |
| 1737 void _flushLibraryProperties(List<JS.Statement> body) { | 1757 void _flushLibraryProperties(List<JS.Statement> body) { |
| 1738 if (_properties.isEmpty) return; | 1758 if (_properties.isEmpty) return; |
| 1739 body.add(js.statement('dart.copyProperties(#, { # });', [ | 1759 body.add(js.statement('dart.copyProperties(#, { # });', [ |
| 1740 _exportsVar, | 1760 _exportsVar, |
| 1741 _properties.map(_emitTopLevelProperty) | 1761 _properties.map(_emitTopLevelProperty) |
| 1742 ])); | 1762 ])); |
| 1743 _properties.clear(); | 1763 _properties.clear(); |
| 1744 } | 1764 } |
| 1745 | 1765 |
| 1746 @override | 1766 _emitConstructorName(ConstructorElement element, DartType type, SimpleIdentifi er name) { |
|
Jennifer Messerly
2015/06/09 23:29:53
return type?
vsm
2015/06/10 13:28:27
Done.
| |
| 1747 visitConstructorName(ConstructorName node) { | 1767 var typeName = _emitTypeName(type); |
| 1748 var typeName = _visit(node.type); | 1768 if (name != null || element.isFactory) { |
| 1749 var element = node.staticElement; | |
| 1750 if (node.name != null || element.isFactory) { | |
| 1751 var namedCtor = _constructorName(element); | 1769 var namedCtor = _constructorName(element); |
| 1752 return new JS.PropertyAccess(typeName, namedCtor); | 1770 return new JS.PropertyAccess(typeName, namedCtor); |
| 1753 } | 1771 } |
| 1754 return typeName; | 1772 return typeName; |
| 1755 } | 1773 } |
| 1756 | 1774 |
| 1757 @override | 1775 @override |
| 1776 visitConstructorName(ConstructorName node) { | |
| 1777 return _emitConstructorName(node.staticElement, node.type.type, node.name); | |
| 1778 } | |
| 1779 | |
| 1780 _emitInstanceCreationExpression(ConstructorElement element, DartType type, Sim pleIdentifier name, | |
| 1781 ArgumentList argumentList, bool isConst) { | |
| 1782 emitNew() { | |
| 1783 JS.Expression ctor; | |
| 1784 bool isFactory = false; | |
| 1785 // var element = node.staticElement; | |
| 1786 if (element == null) { | |
| 1787 // TODO(jmesserly): this only happens if we had a static error. | |
| 1788 // Should we generate a throw instead? | |
| 1789 ctor = _emitTypeName(type); | |
| 1790 if (name != null) { | |
| 1791 ctor = new JS.PropertyAccess(ctor, _propertyName(name.name)); | |
| 1792 } | |
| 1793 } else { | |
| 1794 ctor = _emitConstructorName(element, type, name); | |
| 1795 isFactory = element.isFactory; | |
| 1796 } | |
| 1797 var args = _visit(argumentList); | |
| 1798 return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args); | |
| 1799 } | |
| 1800 if (isConst) return _emitConst(emitNew); | |
| 1801 return emitNew(); | |
| 1802 } | |
| 1803 | |
| 1804 @override | |
| 1758 visitInstanceCreationExpression(InstanceCreationExpression node) { | 1805 visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 1759 emitNew() { | 1806 var element = node.staticElement; |
| 1760 JS.Expression ctor; | 1807 var constructor = node.constructorName; |
| 1761 bool isFactory = false; | 1808 var name = constructor.name; |
| 1762 var element = node.staticElement; | 1809 var type = constructor.type.type; |
| 1763 if (element == null) { | 1810 return _emitInstanceCreationExpression( |
| 1764 // TODO(jmesserly): this only happens if we had a static error. | 1811 element, type, name, node.argumentList, node.isConst); |
| 1765 // Should we generate a throw instead? | |
| 1766 ctor = _visit(node.constructorName.type); | |
| 1767 var ctorName = node.constructorName.name; | |
| 1768 if (ctorName != null) { | |
| 1769 ctor = new JS.PropertyAccess(ctor, _propertyName(ctorName.name)); | |
| 1770 } | |
| 1771 } else { | |
| 1772 ctor = _visit(node.constructorName); | |
| 1773 isFactory = element.isFactory; | |
| 1774 } | |
| 1775 var args = _visit(node.argumentList); | |
| 1776 return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args); | |
| 1777 } | |
| 1778 if (node.isConst) return _emitConst(node, emitNew); | |
| 1779 return emitNew(); | |
| 1780 } | 1812 } |
| 1781 | 1813 |
| 1782 /// True if this type is built-in to JS, and we use the values unwrapped. | 1814 /// True if this type is built-in to JS, and we use the values unwrapped. |
| 1783 /// For these types we generate a calling convention via static | 1815 /// For these types we generate a calling convention via static |
| 1784 /// "extension methods". This allows types to be extended without adding | 1816 /// "extension methods". This allows types to be extended without adding |
| 1785 /// extensions directly on the prototype. | 1817 /// extensions directly on the prototype. |
| 1786 bool _isJSBuiltinType(DartType t) => | 1818 bool _isJSBuiltinType(DartType t) => |
| 1787 typeIsPrimitiveInJS(t) || rules.isStringType(t); | 1819 typeIsPrimitiveInJS(t) || rules.isStringType(t); |
| 1788 | 1820 |
| 1789 bool typeIsPrimitiveInJS(DartType t) => rules.isIntType(t) || | 1821 bool typeIsPrimitiveInJS(DartType t) => rules.isIntType(t) || |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1869 var jsExpr = _visit(expr); | 1901 var jsExpr = _visit(expr); |
| 1870 if (_isNonNullableExpression(expr)) return jsExpr; | 1902 if (_isNonNullableExpression(expr)) return jsExpr; |
| 1871 return js.call('dart.notNull(#)', jsExpr); | 1903 return js.call('dart.notNull(#)', jsExpr); |
| 1872 } | 1904 } |
| 1873 | 1905 |
| 1874 @override | 1906 @override |
| 1875 JS.Expression visitBinaryExpression(BinaryExpression node) { | 1907 JS.Expression visitBinaryExpression(BinaryExpression node) { |
| 1876 var op = node.operator; | 1908 var op = node.operator; |
| 1877 var left = node.leftOperand; | 1909 var left = node.leftOperand; |
| 1878 var right = node.rightOperand; | 1910 var right = node.rightOperand; |
| 1911 | |
| 1879 var leftType = getStaticType(left); | 1912 var leftType = getStaticType(left); |
| 1880 var rightType = getStaticType(right); | 1913 var rightType = getStaticType(right); |
| 1881 | 1914 |
| 1882 var code; | 1915 var code; |
| 1883 if (op.type.isEqualityOperator) { | 1916 if (op.type.isEqualityOperator) { |
| 1884 // If we statically know LHS or RHS is null we can generate a clean check. | 1917 // If we statically know LHS or RHS is null we can generate a clean check. |
| 1885 // We can also do this if both sides are the same primitive type. | 1918 // We can also do this if both sides are the same primitive type. |
| 1886 if (_canUsePrimitiveEquality(left, right)) { | 1919 if (_canUsePrimitiveEquality(left, right)) { |
| 1887 code = op.type == TokenType.EQ_EQ ? '# == #' : '# != #'; | 1920 code = op.type == TokenType.EQ_EQ ? '# == #' : '# != #'; |
| 1888 } else { | 1921 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1938 // LocalVariableElementImpl, so we could repurpose to mean "temp". | 1971 // LocalVariableElementImpl, so we could repurpose to mean "temp". |
| 1939 // * add a new property to LocalVariableElementImpl. | 1972 // * add a new property to LocalVariableElementImpl. |
| 1940 // * create a new subtype of LocalVariableElementImpl to mark a temp. | 1973 // * create a new subtype of LocalVariableElementImpl to mark a temp. |
| 1941 var id = | 1974 var id = |
| 1942 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); | 1975 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, -1)); |
| 1943 id.staticElement = new TemporaryVariableElement.forNode(id); | 1976 id.staticElement = new TemporaryVariableElement.forNode(id); |
| 1944 id.staticType = type; | 1977 id.staticType = type; |
| 1945 return id; | 1978 return id; |
| 1946 } | 1979 } |
| 1947 | 1980 |
| 1948 JS.Expression _emitConst(Expression node, JS.Expression expr()) { | 1981 JS.Expression _emitConst(JS.Expression expr()) { |
| 1949 // TODO(jmesserly): emit the constants at top level if possible. | 1982 // TODO(jmesserly): emit the constants at top level if possible. |
| 1950 // This wasn't quite working, so disabled for now. | 1983 // This wasn't quite working, so disabled for now. |
| 1951 return js.call('dart.const(#)', expr()); | 1984 return js.call('dart.const(#)', expr()); |
| 1952 } | 1985 } |
| 1953 | 1986 |
| 1954 /// Returns a new expression, which can be be used safely *once* on the | 1987 /// Returns a new expression, which can be be used safely *once* on the |
| 1955 /// left hand side, and *once* on the right side of an assignment. | 1988 /// left hand side, and *once* on the right side of an assignment. |
| 1956 /// For example: `expr1[expr2] += y` can be compiled as | 1989 /// For example: `expr1[expr2] += y` can be compiled as |
| 1957 /// `expr1[expr2] = expr1[expr2] + y`. | 1990 /// `expr1[expr2] = expr1[expr2] + y`. |
| 1958 /// | 1991 /// |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2429 visitNullLiteral(NullLiteral node) => new JS.LiteralNull(); | 2462 visitNullLiteral(NullLiteral node) => new JS.LiteralNull(); |
| 2430 | 2463 |
| 2431 @override | 2464 @override |
| 2432 visitSymbolLiteral(SymbolLiteral node) { | 2465 visitSymbolLiteral(SymbolLiteral node) { |
| 2433 emitSymbol() { | 2466 emitSymbol() { |
| 2434 // TODO(vsm): When we canonicalize, we need to treat private symbols | 2467 // TODO(vsm): When we canonicalize, we need to treat private symbols |
| 2435 // correctly. | 2468 // correctly. |
| 2436 var name = js.string(node.components.join('.'), "'"); | 2469 var name = js.string(node.components.join('.'), "'"); |
| 2437 return new JS.New(_emitTypeName(types.symbolType), [name]); | 2470 return new JS.New(_emitTypeName(types.symbolType), [name]); |
| 2438 } | 2471 } |
| 2439 return _emitConst(node, emitSymbol); | 2472 return _emitConst(emitSymbol); |
| 2440 } | 2473 } |
| 2441 | 2474 |
| 2442 @override | 2475 @override |
| 2443 visitListLiteral(ListLiteral node) { | 2476 visitListLiteral(ListLiteral node) { |
| 2444 emitList() { | 2477 emitList() { |
| 2445 JS.Expression list = new JS.ArrayInitializer(_visitList(node.elements)); | 2478 JS.Expression list = new JS.ArrayInitializer(_visitList(node.elements)); |
| 2446 ParameterizedType type = node.staticType; | 2479 ParameterizedType type = node.staticType; |
| 2447 var elementType = type.typeArguments.single; | 2480 var elementType = type.typeArguments.single; |
| 2448 if (elementType != types.dynamicType) { | 2481 if (elementType != types.dynamicType) { |
| 2449 list = js.call('dart.list(#, #)', [list, _emitTypeName(elementType)]); | 2482 list = js.call('dart.list(#, #)', [list, _emitTypeName(elementType)]); |
| 2450 } | 2483 } |
| 2451 return list; | 2484 return list; |
| 2452 } | 2485 } |
| 2453 if (node.constKeyword != null) return _emitConst(node, emitList); | 2486 if (node.constKeyword != null) return _emitConst(emitList); |
| 2454 return emitList(); | 2487 return emitList(); |
| 2455 } | 2488 } |
| 2456 | 2489 |
| 2457 @override | 2490 @override |
| 2458 visitMapLiteral(MapLiteral node) { | 2491 visitMapLiteral(MapLiteral node) { |
| 2459 // TODO(jmesserly): we can likely make these faster. | 2492 // TODO(jmesserly): we can likely make these faster. |
| 2460 emitMap() { | 2493 emitMap() { |
| 2461 var entries = node.entries; | 2494 var entries = node.entries; |
| 2462 var mapArguments = null; | 2495 var mapArguments = null; |
| 2463 if (entries.isEmpty) { | 2496 if (entries.isEmpty) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2475 var values = []; | 2508 var values = []; |
| 2476 for (var e in entries) { | 2509 for (var e in entries) { |
| 2477 values.add(_visit(e.key)); | 2510 values.add(_visit(e.key)); |
| 2478 values.add(_visit(e.value)); | 2511 values.add(_visit(e.value)); |
| 2479 } | 2512 } |
| 2480 mapArguments = new JS.ArrayInitializer(values); | 2513 mapArguments = new JS.ArrayInitializer(values); |
| 2481 } | 2514 } |
| 2482 // TODO(jmesserly): add generic types args. | 2515 // TODO(jmesserly): add generic types args. |
| 2483 return js.call('dart.map(#)', [mapArguments]); | 2516 return js.call('dart.map(#)', [mapArguments]); |
| 2484 } | 2517 } |
| 2485 if (node.constKeyword != null) return _emitConst(node, emitMap); | 2518 if (node.constKeyword != null) return _emitConst(emitMap); |
| 2486 return emitMap(); | 2519 return emitMap(); |
| 2487 } | 2520 } |
| 2488 | 2521 |
| 2489 @override | 2522 @override |
| 2490 JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) => | 2523 JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) => |
| 2491 js.escapedString(node.value, node.isSingleQuoted ? "'" : '"'); | 2524 js.escapedString(node.value, node.isSingleQuoted ? "'" : '"'); |
| 2492 | 2525 |
| 2493 @override | 2526 @override |
| 2494 JS.Expression visitAdjacentStrings(AdjacentStrings node) => | 2527 JS.Expression visitAdjacentStrings(AdjacentStrings node) => |
| 2495 _visitListToBinary(node.strings, '+'); | 2528 _visitListToBinary(node.strings, '+'); |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2738 | 2771 |
| 2739 /// A special kind of element created by the compiler, signifying a temporary | 2772 /// A special kind of element created by the compiler, signifying a temporary |
| 2740 /// variable. These objects use instance equality, and should be shared | 2773 /// variable. These objects use instance equality, and should be shared |
| 2741 /// everywhere in the tree where they are treated as the same variable. | 2774 /// everywhere in the tree where they are treated as the same variable. |
| 2742 class TemporaryVariableElement extends LocalVariableElementImpl { | 2775 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 2743 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 2776 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 2744 | 2777 |
| 2745 int get hashCode => identityHashCode(this); | 2778 int get hashCode => identityHashCode(this); |
| 2746 bool operator ==(Object other) => identical(this, other); | 2779 bool operator ==(Object other) => identical(this, other); |
| 2747 } | 2780 } |
| OLD | NEW |