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

Side by Side Diff: lib/src/codegen/js_codegen.dart

Issue 1252953003: Implement more of dart:mirrors (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Address comments Created 5 years, 4 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
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 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 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 result.add(js.statement('#.# = dart.const(new #(#));', 502 result.add(js.statement('#.# = dart.const(new #(#));',
503 [id, fields[i].name, id, js.number(i)])); 503 [id, fields[i].name, id, js.number(i)]));
504 } 504 }
505 505
506 // Create static values list 506 // Create static values list
507 var values = new JS.ArrayInitializer(new List<JS.Expression>.from( 507 var values = new JS.ArrayInitializer(new List<JS.Expression>.from(
508 fields.map((f) => js.call('#.#', [id, f.name])))); 508 fields.map((f) => js.call('#.#', [id, f.name]))));
509 result.add(js.statement('#.values = dart.const(dart.list(#, #));', 509 result.add(js.statement('#.values = dart.const(dart.list(#, #));',
510 [id, values, _emitTypeName(type)])); 510 [id, values, _emitTypeName(type)]));
511 511
512 if (isPublic(type.name)) _addExport(type.name);
512 return _statement(result); 513 return _statement(result);
513 } 514 }
514 515
515 /// Given a class element and body, complete the class declaration. 516 /// Given a class element and body, complete the class declaration.
516 /// This handles generic type parameters, laziness (in library-cycle cases), 517 /// This handles generic type parameters, laziness (in library-cycle cases),
517 /// and ensuring dependencies are loaded first. 518 /// and ensuring dependencies are loaded first.
518 JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) { 519 JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) {
519 var name = type.name; 520 var name = type.name;
520 var genericName = '$name\$'; 521 var genericName = '$name\$';
521 522
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 } else { 745 } else {
745 tMethods.add(property); 746 tMethods.add(property);
746 } 747 }
747 } 748 }
748 } 749 }
749 750
750 var tCtors = <JS.Property>[]; 751 var tCtors = <JS.Property>[];
751 for (ConstructorDeclaration node in ctors) { 752 for (ConstructorDeclaration node in ctors) {
752 var memberName = _constructorName(node.element); 753 var memberName = _constructorName(node.element);
753 var element = node.element; 754 var element = node.element;
754 var parts = _emitFunctionTypeParts(element.type); 755 var parts = _emitFunctionTypeParts(element.type, node.parameters);
755 var property = 756 var property =
756 new JS.Property(memberName, new JS.ArrayInitializer(parts)); 757 new JS.Property(memberName, new JS.ArrayInitializer(parts));
757 tCtors.add(property); 758 tCtors.add(property);
758 } 759 }
759 760
760 JS.Property build(String name, List<JS.Property> elements) { 761 JS.Property build(String name, List<JS.Property> elements) {
761 var o = 762 var o =
762 new JS.ObjectInitializer(elements, multiline: elements.length > 1); 763 new JS.ObjectInitializer(elements, multiline: elements.length > 1);
763 var e = js.call('() => #', o); 764 var e = js.call('() => #', o);
764 return new JS.Property(_propertyName(name), e); 765 return new JS.Property(_propertyName(name), e);
(...skipping 22 matching lines...) Expand all
787 var methodNames = <JS.Expression>[]; 788 var methodNames = <JS.Expression>[];
788 for (var e in extensions) { 789 for (var e in extensions) {
789 methodNames.add(_elementMemberName(e)); 790 methodNames.add(_elementMemberName(e));
790 } 791 }
791 body.add(js.statement('dart.defineExtensionMembers(#, #);', [ 792 body.add(js.statement('dart.defineExtensionMembers(#, #);', [
792 name, 793 name,
793 new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4) 794 new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4)
794 ])); 795 ]));
795 } 796 }
796 797
798 // TODO(vsm): Make this optional per #268.
797 // Metadata 799 // Metadata
798 if (metadata.isNotEmpty) { 800 if (metadata.isNotEmpty) {
799 body.add(js.statement('#[dart.metadata] = () => #;', [ 801 body.add(js.statement('#[dart.metadata] = () => #;', [
800 name, 802 name,
801 new JS.ArrayInitializer( 803 new JS.ArrayInitializer(
802 new List<JS.Expression>.from(metadata.map(_instantiateAnnotation))) 804 new List<JS.Expression>.from(metadata.map(_instantiateAnnotation)))
803 ])); 805 ]));
804 } 806 }
805 807
806 return _statement(body); 808 return _statement(body);
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 return _getTemp(element, name); 1474 return _getTemp(element, name);
1473 } 1475 }
1474 } 1476 }
1475 1477
1476 return new JS.Identifier(name); 1478 return new JS.Identifier(name);
1477 } 1479 }
1478 1480
1479 JS.TemporaryId _getTemp(Element key, String name) => 1481 JS.TemporaryId _getTemp(Element key, String name) =>
1480 _temps.putIfAbsent(key, () => new JS.TemporaryId(name)); 1482 _temps.putIfAbsent(key, () => new JS.TemporaryId(name));
1481 1483
1482 JS.ArrayInitializer _emitTypeNames(List<DartType> types) { 1484 // TODO(vsm):
Jennifer Messerly 2015/08/07 18:52:59 forgot comment?
vsm 2015/08/07 19:38:30 Doh - thanks - this was the comment I "moved" to l
1483 return new JS.ArrayInitializer( 1485 List<Annotation> _parameterMetadata(FormalParameter p) =>
1484 new List<JS.Expression>.from(types.map(_emitTypeName))); 1486 (p is NormalFormalParameter)
1487 ? p.metadata
1488 : (p as DefaultFormalParameter).parameter.metadata;
1489
1490 JS.ArrayInitializer _emitTypeNames(List<DartType> types,
1491 [List<FormalParameter> parameters]) {
1492 var result = <JS.Expression>[];
1493 for (int i = 0; i < types.length; ++i) {
1494 var metadata =
1495 parameters != null ? _parameterMetadata(parameters[i]) : [];
1496 var typeName = _emitTypeName(types[i]);
1497 var value = typeName;
1498 // TODO(vsm): Make this optional per #268.
1499 if (metadata.isNotEmpty) {
1500 metadata = metadata.map(_instantiateAnnotation).toList();
1501 value = new JS.ArrayInitializer([typeName]..addAll(metadata));
1502 }
1503 result.add(value);
1504 }
1505 return new JS.ArrayInitializer(result);
1485 } 1506 }
1486 1507
1487 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) { 1508 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) {
1488 var properties = <JS.Property>[]; 1509 var properties = <JS.Property>[];
1489 types.forEach((name, type) { 1510 types.forEach((name, type) {
1490 var key = _propertyName(name); 1511 var key = _propertyName(name);
1491 var value = _emitTypeName(type); 1512 var value = _emitTypeName(type);
1492 properties.add(new JS.Property(key, value)); 1513 properties.add(new JS.Property(key, value));
1493 }); 1514 });
1494 return new JS.ObjectInitializer(properties); 1515 return new JS.ObjectInitializer(properties);
1495 } 1516 }
1496 1517
1497 /// Emit the pieces of a function type, as an array of return type, 1518 /// Emit the pieces of a function type, as an array of return type,
1498 /// regular args, and optional/named args. 1519 /// regular args, and optional/named args.
1499 List<JS.Expression> _emitFunctionTypeParts(FunctionType type) { 1520 List<JS.Expression> _emitFunctionTypeParts(FunctionType type,
1521 [FormalParameterList parameterList]) {
1522 var parameters = parameterList?.parameters;
1500 var returnType = type.returnType; 1523 var returnType = type.returnType;
1501 var parameterTypes = type.normalParameterTypes; 1524 var parameterTypes = type.normalParameterTypes;
1502 var optionalTypes = type.optionalParameterTypes; 1525 var optionalTypes = type.optionalParameterTypes;
1503 var namedTypes = type.namedParameterTypes; 1526 var namedTypes = type.namedParameterTypes;
1504 var rt = _emitTypeName(returnType); 1527 var rt = _emitTypeName(returnType);
1505 var ra = _emitTypeNames(parameterTypes); 1528 var ra = _emitTypeNames(parameterTypes, parameters);
1506 if (!namedTypes.isEmpty) { 1529 if (!namedTypes.isEmpty) {
1507 assert(optionalTypes.isEmpty); 1530 assert(optionalTypes.isEmpty);
1531 // TODO(vsm): Pass in annotations here as well.
1508 var na = _emitTypeProperties(namedTypes); 1532 var na = _emitTypeProperties(namedTypes);
1509 return [rt, ra, na]; 1533 return [rt, ra, na];
1510 } 1534 }
1511 if (!optionalTypes.isEmpty) { 1535 if (!optionalTypes.isEmpty) {
1512 assert(namedTypes.isEmpty); 1536 assert(namedTypes.isEmpty);
1513 var oa = _emitTypeNames(optionalTypes); 1537 var oa = _emitTypeNames(
1538 optionalTypes, parameters?.sublist(parameterTypes.length));
1514 return [rt, ra, oa]; 1539 return [rt, ra, oa];
1515 } 1540 }
1516 return [rt, ra]; 1541 return [rt, ra];
1517 } 1542 }
1518 1543
1519 JS.Expression _emitFunctionRTTI(FunctionType type) { 1544 JS.Expression _emitFunctionRTTI(FunctionType type) {
1520 var parts = _emitFunctionTypeParts(type); 1545 var parts = _emitFunctionTypeParts(type);
1521 return js.call('dart.definiteFunctionType(#)', [parts]); 1546 return js.call('dart.definiteFunctionType(#)', [parts]);
1522 } 1547 }
1523 1548
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 1712
1688 var type = getStaticType(target); 1713 var type = getStaticType(target);
1689 var name = node.methodName.name; 1714 var name = node.methodName.name;
1690 var element = node.methodName.staticElement; 1715 var element = node.methodName.staticElement;
1691 bool isStatic = element is ExecutableElement && element.isStatic; 1716 bool isStatic = element is ExecutableElement && element.isStatic;
1692 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); 1717 var memberName = _emitMemberName(name, type: type, isStatic: isStatic);
1693 1718
1694 if (DynamicInvoke.get(target)) { 1719 if (DynamicInvoke.get(target)) {
1695 code = 'dart.$DSEND(#, #, #)'; 1720 code = 'dart.$DSEND(#, #, #)';
1696 } else if (DynamicInvoke.get(node.methodName)) { 1721 } else if (DynamicInvoke.get(node.methodName)) {
1697 // This is a dynamic call to a statically know target. For example: 1722 // This is a dynamic call to a statically known target. For example:
1698 // class Foo { Function bar; } 1723 // class Foo { Function bar; }
1699 // new Foo().bar(); // dynamic call 1724 // new Foo().bar(); // dynamic call
1700 code = 'dart.$DCALL(#.#, #)'; 1725 code = 'dart.$DCALL(#.#, #)';
1701 } else if (_requiresStaticDispatch(target, name)) { 1726 } else if (_requiresStaticDispatch(target, name)) {
1702 assert(rules.objectMembers[name] is FunctionType); 1727 assert(rules.objectMembers[name] is FunctionType);
1703 // Object methods require a helper for null checks. 1728 // Object methods require a helper for null checks.
1704 return js.call('dart.#(#, #)', 1729 return js.call('dart.#(#, #)',
1705 [memberName, _visit(target), _visit(node.argumentList)]); 1730 [memberName, _visit(target), _visit(node.argumentList)]);
1706 } else { 1731 } else {
1707 code = '#.#(#)'; 1732 code = '#.#(#)';
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 3075
3051 /// A special kind of element created by the compiler, signifying a temporary 3076 /// A special kind of element created by the compiler, signifying a temporary
3052 /// variable. These objects use instance equality, and should be shared 3077 /// variable. These objects use instance equality, and should be shared
3053 /// everywhere in the tree where they are treated as the same variable. 3078 /// everywhere in the tree where they are treated as the same variable.
3054 class TemporaryVariableElement extends LocalVariableElementImpl { 3079 class TemporaryVariableElement extends LocalVariableElementImpl {
3055 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); 3080 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name);
3056 3081
3057 int get hashCode => identityHashCode(this); 3082 int get hashCode => identityHashCode(this);
3058 bool operator ==(Object other) => identical(this, other); 3083 bool operator ==(Object other) => identical(this, other);
3059 } 3084 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698