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 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 | 457 |
458 // Create static values list | 458 // Create static values list |
459 var values = new JS.ArrayInitializer(new List<JS.Expression>.from( | 459 var values = new JS.ArrayInitializer(new List<JS.Expression>.from( |
460 fields.map((f) => js.call('#.#', [id, f.name])))); | 460 fields.map((f) => js.call('#.#', [id, f.name])))); |
461 result.add(js.statement('#.values = dart.const(dart.list(#, #));', [ | 461 result.add(js.statement('#.values = dart.const(dart.list(#, #));', [ |
462 id, | 462 id, |
463 values, | 463 values, |
464 _emitTypeName(type) | 464 _emitTypeName(type) |
465 ])); | 465 ])); |
466 | 466 |
467 if (isPublic(type.name)) _addExport(type.name); | |
467 return _statement(result); | 468 return _statement(result); |
468 } | 469 } |
469 | 470 |
470 /// Given a class element and body, complete the class declaration. | 471 /// Given a class element and body, complete the class declaration. |
471 /// This handles generic type parameters, laziness (in library-cycle cases), | 472 /// This handles generic type parameters, laziness (in library-cycle cases), |
472 /// and ensuring dependencies are loaded first. | 473 /// and ensuring dependencies are loaded first. |
473 JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) { | 474 JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) { |
474 var name = type.name; | 475 var name = type.name; |
475 var genericName = '$name\$'; | 476 var genericName = '$name\$'; |
476 | 477 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 } else { | 711 } else { |
711 tMethods.add(property); | 712 tMethods.add(property); |
712 } | 713 } |
713 } | 714 } |
714 } | 715 } |
715 | 716 |
716 var tCtors = <JS.Property>[]; | 717 var tCtors = <JS.Property>[]; |
717 for (ConstructorDeclaration node in ctors) { | 718 for (ConstructorDeclaration node in ctors) { |
718 var memberName = _constructorName(node.element); | 719 var memberName = _constructorName(node.element); |
719 var element = node.element; | 720 var element = node.element; |
720 var parts = _emitFunctionTypeParts(element.type); | 721 var parts = _emitFunctionTypeParts(element.type, node.parameters); |
721 var property = | 722 var property = |
722 new JS.Property(memberName, new JS.ArrayInitializer(parts)); | 723 new JS.Property(memberName, new JS.ArrayInitializer(parts)); |
723 tCtors.add(property); | 724 tCtors.add(property); |
724 } | 725 } |
725 | 726 |
726 JS.Property build(String name, List<JS.Property> elements) { | 727 JS.Property build(String name, List<JS.Property> elements) { |
727 var o = | 728 var o = |
728 new JS.ObjectInitializer(elements, multiline: elements.length > 1); | 729 new JS.ObjectInitializer(elements, multiline: elements.length > 1); |
729 var e = js.call('() => #', o); | 730 var e = js.call('() => #', o); |
730 return new JS.Property(_propertyName(name), e); | 731 return new JS.Property(_propertyName(name), e); |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1378 return _getTemp(element, name); | 1379 return _getTemp(element, name); |
1379 } | 1380 } |
1380 } | 1381 } |
1381 | 1382 |
1382 return new JS.Identifier(name); | 1383 return new JS.Identifier(name); |
1383 } | 1384 } |
1384 | 1385 |
1385 JS.TemporaryId _getTemp(Element key, String name) => | 1386 JS.TemporaryId _getTemp(Element key, String name) => |
1386 _temps.putIfAbsent(key, () => new JS.TemporaryId(name)); | 1387 _temps.putIfAbsent(key, () => new JS.TemporaryId(name)); |
1387 | 1388 |
1388 JS.ArrayInitializer _emitTypeNames(List<DartType> types) { | 1389 JS.ArrayInitializer _emitTypeNames(List<DartType> types, |
Jennifer Messerly
2015/07/24 16:28:28
thought for future:
should we only emit mirrors un
vsm
2015/08/07 17:07:32
Makes sense. Added a comment.
| |
1389 return new JS.ArrayInitializer( | 1390 [List<FormalParameter> parameters]) { |
1390 new List<JS.Expression>.from(types.map(_emitTypeName))); | 1391 var result = <JS.Expression>[]; |
1392 for (int i = 0; i < types.length; ++i) { | |
1393 var parameter = parameters != null ? parameters[i] : null; | |
Jennifer Messerly
2015/07/24 16:28:28
parameters[i] will never be null right? i'd be tem
vsm
2015/08/07 17:07:32
Done.
| |
1394 var metadata = parameter != null | |
1395 ? parameter is NormalFormalParameter | |
1396 ? parameter.metadata | |
1397 : (parameter as DefaultFormalParameter).parameter.metadata | |
Jennifer Messerly
2015/07/24 16:28:28
hmm, this might be good feedback to analyzer. Woul
vsm
2015/08/07 17:07:32
Factored it out a bit to a helper here. A forward
| |
1398 : []; | |
1399 var typeName = _emitTypeName(types[i]); | |
1400 var value = typeName; | |
1401 if (metadata.isNotEmpty) { | |
1402 metadata = metadata.map(_instantiateAnnotation).toList(); | |
1403 value = new JS.ArrayInitializer([typeName]..addAll(metadata)); | |
1404 } | |
1405 result.add(value); | |
1406 } | |
1407 return new JS.ArrayInitializer(result); | |
1391 } | 1408 } |
1392 | 1409 |
1393 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) { | 1410 JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types) { |
1394 var properties = <JS.Property>[]; | 1411 var properties = <JS.Property>[]; |
1395 types.forEach((name, type) { | 1412 types.forEach((name, type) { |
1396 var key = _propertyName(name); | 1413 var key = _propertyName(name); |
1397 var value = _emitTypeName(type); | 1414 var value = _emitTypeName(type); |
1398 properties.add(new JS.Property(key, value)); | 1415 properties.add(new JS.Property(key, value)); |
1399 }); | 1416 }); |
1400 return new JS.ObjectInitializer(properties); | 1417 return new JS.ObjectInitializer(properties); |
1401 } | 1418 } |
1402 | 1419 |
1403 /// Emit the pieces of a function type, as an array of return type, | 1420 /// Emit the pieces of a function type, as an array of return type, |
1404 /// regular args, and optional/named args. | 1421 /// regular args, and optional/named args. |
1405 List<JS.Expression> _emitFunctionTypeParts(FunctionType type) { | 1422 List<JS.Expression> _emitFunctionTypeParts(FunctionType type, |
1423 [FormalParameterList parameterList]) { | |
1424 List<FormalParameter> parameters = | |
Jennifer Messerly
2015/07/24 16:28:28
should this be:
var parameters = parameterLis
vsm
2015/08/07 17:07:32
Done.
| |
1425 parameterList != null ? parameterList.parameters : null; | |
1406 var returnType = type.returnType; | 1426 var returnType = type.returnType; |
1407 var parameterTypes = type.normalParameterTypes; | 1427 var parameterTypes = type.normalParameterTypes; |
1408 var optionalTypes = type.optionalParameterTypes; | 1428 var optionalTypes = type.optionalParameterTypes; |
1409 var namedTypes = type.namedParameterTypes; | 1429 var namedTypes = type.namedParameterTypes; |
1410 var rt = _emitTypeName(returnType); | 1430 var rt = _emitTypeName(returnType); |
1411 var ra = _emitTypeNames(parameterTypes); | 1431 var ra = _emitTypeNames(parameterTypes, parameters); |
1412 if (!namedTypes.isEmpty) { | 1432 if (!namedTypes.isEmpty) { |
1413 assert(optionalTypes.isEmpty); | 1433 assert(optionalTypes.isEmpty); |
1434 // TODO(vsm): Pass in annotations here as well. | |
1414 var na = _emitTypeProperties(namedTypes); | 1435 var na = _emitTypeProperties(namedTypes); |
1415 return [rt, ra, na]; | 1436 return [rt, ra, na]; |
1416 } | 1437 } |
1417 if (!optionalTypes.isEmpty) { | 1438 if (!optionalTypes.isEmpty) { |
1418 assert(namedTypes.isEmpty); | 1439 assert(namedTypes.isEmpty); |
1419 var oa = _emitTypeNames(optionalTypes); | 1440 var oa = _emitTypeNames(optionalTypes, parameters != null |
Jennifer Messerly
2015/07/24 16:28:28
ditto:
parameters?.sublist(parameterTypes.len
vsm
2015/08/07 17:07:32
Done.
| |
1441 ? parameters.sublist(parameterTypes.length) | |
1442 : null); | |
1420 return [rt, ra, oa]; | 1443 return [rt, ra, oa]; |
1421 } | 1444 } |
1422 return [rt, ra]; | 1445 return [rt, ra]; |
1423 } | 1446 } |
1424 | 1447 |
1425 JS.Expression _emitFunctionRTTI(FunctionType type) { | 1448 JS.Expression _emitFunctionRTTI(FunctionType type) { |
1426 var parts = _emitFunctionTypeParts(type); | 1449 var parts = _emitFunctionTypeParts(type); |
1427 return js.call('dart.definiteFunctionType(#)', [parts]); | 1450 return js.call('dart.definiteFunctionType(#)', [parts]); |
1428 } | 1451 } |
1429 | 1452 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1594 | 1617 |
1595 var type = getStaticType(target); | 1618 var type = getStaticType(target); |
1596 var name = node.methodName.name; | 1619 var name = node.methodName.name; |
1597 var element = node.methodName.staticElement; | 1620 var element = node.methodName.staticElement; |
1598 bool isStatic = element is ExecutableElement && element.isStatic; | 1621 bool isStatic = element is ExecutableElement && element.isStatic; |
1599 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); | 1622 var memberName = _emitMemberName(name, type: type, isStatic: isStatic); |
1600 | 1623 |
1601 if (DynamicInvoke.get(target)) { | 1624 if (DynamicInvoke.get(target)) { |
1602 code = 'dart.$DSEND(#, #, #)'; | 1625 code = 'dart.$DSEND(#, #, #)'; |
1603 } else if (DynamicInvoke.get(node.methodName)) { | 1626 } else if (DynamicInvoke.get(node.methodName)) { |
1604 // This is a dynamic call to a statically know target. For example: | 1627 // This is a dynamic call to a statically known target. For example: |
1605 // class Foo { Function bar; } | 1628 // class Foo { Function bar; } |
1606 // new Foo().bar(); // dynamic call | 1629 // new Foo().bar(); // dynamic call |
1607 code = 'dart.$DCALL(#.#, #)'; | 1630 code = 'dart.$DCALL(#.#, #)'; |
1631 // code = 'dart.$DSEND(#, #, #)'; | |
Jennifer Messerly
2015/07/24 16:28:28
remove commented code?
vsm
2015/08/07 17:07:32
Done.
vsm
2015/08/07 17:07:32
Done.
| |
1608 } else if (_requiresStaticDispatch(target, name)) { | 1632 } else if (_requiresStaticDispatch(target, name)) { |
1609 assert(rules.objectMembers[name] is FunctionType); | 1633 assert(rules.objectMembers[name] is FunctionType); |
1610 // Object methods require a helper for null checks. | 1634 // Object methods require a helper for null checks. |
1611 return js.call('dart.#(#, #)', [ | 1635 return js.call('dart.#(#, #)', [ |
1612 memberName, | 1636 memberName, |
1613 _visit(target), | 1637 _visit(target), |
1614 _visit(node.argumentList) | 1638 _visit(node.argumentList) |
1615 ]); | 1639 ]); |
1616 } else { | 1640 } else { |
1617 code = '#.#(#)'; | 1641 code = '#.#(#)'; |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2862 | 2886 |
2863 class _JsThisFinder extends JS.BaseVisitor { | 2887 class _JsThisFinder extends JS.BaseVisitor { |
2864 bool found = false; | 2888 bool found = false; |
2865 visitThis(JS.This node) { | 2889 visitThis(JS.This node) { |
2866 found = true; | 2890 found = true; |
2867 } | 2891 } |
2868 visitNode(JS.Node node) { | 2892 visitNode(JS.Node node) { |
2869 if (!found) super.visitNode(node); | 2893 if (!found) super.visitNode(node); |
2870 } | 2894 } |
2871 } | 2895 } |
OLD | NEW |