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 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 |