| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 import 'package:kernel/frontend/accessors.dart' | 6 import 'package:kernel/frontend/accessors.dart' |
| 7 show | 7 show |
| 8 Accessor, | 8 Accessor, |
| 9 IndexAccessor, | 9 IndexAccessor, |
| 10 NullAwarePropertyAccessor, | 10 NullAwarePropertyAccessor, |
| 11 PropertyAccessor, | 11 PropertyAccessor, |
| 12 ReadOnlyAccessor, | 12 ReadOnlyAccessor, |
| 13 StaticAccessor, | 13 StaticAccessor, |
| 14 SuperIndexAccessor, | 14 SuperIndexAccessor, |
| 15 SuperPropertyAccessor, | 15 SuperPropertyAccessor, |
| 16 ThisPropertyAccessor, | 16 ThisPropertyAccessor, |
| 17 VariableAccessor, | 17 VariableAccessor, |
| 18 buildIsNull, | 18 buildIsNull, |
| 19 makeBinary, | 19 makeBinary, |
| 20 makeLet, | 20 makeLet, |
| 21 makeOrReuseVariable; | 21 makeOrReuseVariable; |
| 22 import 'package:kernel/transformations/flags.dart'; | 22 import 'package:kernel/transformations/flags.dart'; |
| 23 | 23 |
| 24 import '../common.dart'; | 24 import '../common.dart'; |
| 25 import '../common/names.dart'; |
| 25 import '../constants/expressions.dart' | 26 import '../constants/expressions.dart' |
| 26 show | 27 show |
| 27 BoolFromEnvironmentConstantExpression, | 28 BoolFromEnvironmentConstantExpression, |
| 28 ConstantExpression, | 29 ConstantExpression, |
| 29 ConstructedConstantExpression, | 30 ConstructedConstantExpression, |
| 30 IntFromEnvironmentConstantExpression, | 31 IntFromEnvironmentConstantExpression, |
| 31 StringFromEnvironmentConstantExpression, | 32 StringFromEnvironmentConstantExpression, |
| 32 TypeConstantExpression; | 33 TypeConstantExpression; |
| 33 import '../dart_types.dart' show DartType, InterfaceType; | 34 import '../dart_types.dart' show DartType, InterfaceType; |
| 34 import '../diagnostics/spannable.dart' show Spannable; | 35 import '../diagnostics/spannable.dart' show Spannable; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 TryStatement, | 139 TryStatement, |
| 139 TypeAnnotation, | 140 TypeAnnotation, |
| 140 TypeVariable, | 141 TypeVariable, |
| 141 VariableDefinitions, | 142 VariableDefinitions, |
| 142 While, | 143 While, |
| 143 Yield; | 144 Yield; |
| 144 import '../universe/call_structure.dart' show CallStructure; | 145 import '../universe/call_structure.dart' show CallStructure; |
| 145 import '../universe/selector.dart' show Selector; | 146 import '../universe/selector.dart' show Selector; |
| 146 import '../util/util.dart' show Link; | 147 import '../util/util.dart' show Link; |
| 147 import 'error.dart' show KernelError; | 148 import 'error.dart' show KernelError; |
| 148 import 'fall_through_visitor.dart' show fallsThrough; | |
| 149 import 'kernel.dart' show ConstructorTarget, Kernel; | 149 import 'kernel.dart' show ConstructorTarget, Kernel; |
| 150 import 'unavailable.dart' show UnavailableVisitor; | 150 import 'unavailable.dart' show UnavailableVisitor; |
| 151 import 'unresolved.dart' show UnresolvedVisitor; | 151 import 'unresolved.dart' show UnresolvedVisitor; |
| 152 | 152 |
| 153 /// Translates dart2js AST nodes [Node] into Kernel IR [ir.TreeNode]. | 153 /// Translates dart2js AST nodes [Node] into Kernel IR [ir.TreeNode]. |
| 154 /// | 154 /// |
| 155 /// Most methods in this class have a prefix that follows these conventions: | 155 /// Most methods in this class have a prefix that follows these conventions: |
| 156 /// | 156 /// |
| 157 /// * `visit` for overridden visitor methods. | 157 /// * `visit` for overridden visitor methods. |
| 158 /// * `handle` for methods that implement common behavior for several `visit` | 158 /// * `handle` for methods that implement common behavior for several `visit` |
| (...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 // [Label]. We ignore cases, as any users have been resolved to use the | 988 // [Label]. We ignore cases, as any users have been resolved to use the |
| 989 // case directly. | 989 // case directly. |
| 990 assert(labelOrCase.asLabel() != null); | 990 assert(labelOrCase.asLabel() != null); |
| 991 } | 991 } |
| 992 } | 992 } |
| 993 // We ignore the node's statements here, they're generated below in | 993 // We ignore the node's statements here, they're generated below in |
| 994 // [visitSwitchStatement] once we've set up all the jump targets. | 994 // [visitSwitchStatement] once we've set up all the jump targets. |
| 995 return new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase); | 995 return new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase); |
| 996 } | 996 } |
| 997 | 997 |
| 998 /// Returns true if [node] would let execution reach the next node (aka |
| 999 /// fall-through in switch cases). |
| 1000 bool fallsThrough(ir.Statement node) { |
| 1001 return !(node is ir.BreakStatement || |
| 1002 node is ir.ReturnStatement || |
| 1003 node is ir.ContinueSwitchStatement || |
| 1004 (node is ir.ExpressionStatement && node.expression is ir.Throw)); |
| 1005 } |
| 1006 |
| 998 @override | 1007 @override |
| 999 ir.Statement visitSwitchStatement(SwitchStatement node) { | 1008 ir.Statement visitSwitchStatement(SwitchStatement node) { |
| 1000 ir.Expression expression = visitForValue(node.expression); | 1009 ir.Expression expression = visitForValue(node.expression); |
| 1001 List<ir.SwitchCase> cases = <ir.SwitchCase>[]; | 1010 List<ir.SwitchCase> cases = <ir.SwitchCase>[]; |
| 1002 for (SwitchCase caseNode in node.cases.nodes) { | 1011 for (SwitchCase caseNode in node.cases.nodes) { |
| 1003 cases.add(caseNode.accept(this)); | 1012 cases.add(caseNode.accept(this)); |
| 1004 JumpTarget jumpTarget = elements.getTargetDefinition(caseNode); | 1013 JumpTarget jumpTarget = elements.getTargetDefinition(caseNode); |
| 1005 if (jumpTarget != null) { | 1014 if (jumpTarget != null) { |
| 1006 assert(jumpTarget.isContinueTarget); | 1015 assert(jumpTarget.isContinueTarget); |
| 1007 assert(!continueSwitchTargets.containsKey(jumpTarget)); | 1016 assert(!continueSwitchTargets.containsKey(jumpTarget)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1019 internalError(caseNode, "case node mismatch"); | 1028 internalError(caseNode, "case node mismatch"); |
| 1020 } | 1029 } |
| 1021 ir.SwitchCase irCase = casesIterator.current; | 1030 ir.SwitchCase irCase = casesIterator.current; |
| 1022 List<ir.Statement> statements = <ir.Statement>[]; | 1031 List<ir.Statement> statements = <ir.Statement>[]; |
| 1023 bool hasVariableDeclaration = false; | 1032 bool hasVariableDeclaration = false; |
| 1024 for (Statement statement in caseNode.statements.nodes) { | 1033 for (Statement statement in caseNode.statements.nodes) { |
| 1025 if (buildStatement(statement, statements)) { | 1034 if (buildStatement(statement, statements)) { |
| 1026 hasVariableDeclaration = true; | 1035 hasVariableDeclaration = true; |
| 1027 } | 1036 } |
| 1028 } | 1037 } |
| 1029 if (!isLastCase && | 1038 if (statements.isEmpty || fallsThrough(statements.last)) { |
| 1030 (statements.isEmpty || fallsThrough(statements.last))) { | 1039 if (isLastCase) { |
| 1031 statements.add(new ir.ExpressionStatement(new ir.Throw( | 1040 statements.add(new ir.BreakStatement( |
| 1032 new ir.StaticInvocation(kernel.getFallThroughErrorBuilder(), | 1041 getBreakTarget(elements.getTargetDefinition(node)))); |
| 1033 new ir.Arguments.empty())))); | 1042 } else { |
| 1043 statements.add(new ir.ExpressionStatement(new ir.Throw( |
| 1044 new ir.ConstructorInvocation( |
| 1045 kernel.getFallThroughErrorConstructor(), |
| 1046 new ir.Arguments.empty())))); |
| 1047 } |
| 1034 } | 1048 } |
| 1035 ir.Statement body; | 1049 ir.Statement body = new ir.Block(statements); |
| 1036 if (!hasVariableDeclaration && statements.length == 1) { | |
| 1037 body = statements.single; | |
| 1038 } else { | |
| 1039 body = new ir.Block(statements); | |
| 1040 } | |
| 1041 irCase.body = body; | 1050 irCase.body = body; |
| 1042 body.parent = irCase; | 1051 body.parent = irCase; |
| 1043 } | 1052 } |
| 1044 assert(!casesIterator.moveNext()); | 1053 assert(!casesIterator.moveNext()); |
| 1045 | 1054 |
| 1046 return buildBreakTarget(new ir.SwitchStatement(expression, cases), node, | 1055 return buildBreakTarget(new ir.SwitchStatement(expression, cases), node, |
| 1047 elements.getTargetDefinition(node)); | 1056 elements.getTargetDefinition(node)); |
| 1048 } | 1057 } |
| 1049 | 1058 |
| 1050 @override | 1059 @override |
| (...skipping 984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 function, "Unknown async maker: ${function.asyncMarker}"); | 2044 function, "Unknown async maker: ${function.asyncMarker}"); |
| 2036 break; | 2045 break; |
| 2037 } | 2046 } |
| 2038 } | 2047 } |
| 2039 ir.Statement body; | 2048 ir.Statement body; |
| 2040 if (function.isExternal) { | 2049 if (function.isExternal) { |
| 2041 // [body] must be `null`. | 2050 // [body] must be `null`. |
| 2042 } else if (function.isConstructor) { | 2051 } else if (function.isConstructor) { |
| 2043 // TODO(johnniwinther): Clean this up pending kernel issue #28. | 2052 // TODO(johnniwinther): Clean this up pending kernel issue #28. |
| 2044 ConstructorElement constructor = function; | 2053 ConstructorElement constructor = function; |
| 2045 if (constructor.isDefaultConstructor) { | 2054 if (bodyNode == null || bodyNode.asEmptyStatement() != null) { |
| 2046 body = new ir.EmptyStatement(); | 2055 body = new ir.EmptyStatement(); |
| 2047 } else if (bodyNode != null && bodyNode.asEmptyStatement() == null) { | 2056 } else { |
| 2048 body = buildStatementInBlock(bodyNode); | 2057 body = buildStatementInBlock(bodyNode); |
| 2049 } | 2058 } |
| 2050 } else if (bodyNode != null) { | 2059 } else if (bodyNode != null) { |
| 2051 body = buildStatementInBlock(bodyNode); | 2060 Return returnStatement = bodyNode.asReturn(); |
| 2061 if ((function.isSetter || function.name == Names.INDEX_SET_NAME.text) && |
| 2062 returnStatement != null) { |
| 2063 // Avoid encoding the implicit return of setters with arrow body: |
| 2064 // set setter(value) => this.value = value; |
| 2065 // operator []=(index, value) => this[index] = value; |
| 2066 body = new ir.ExpressionStatement( |
| 2067 visitForEffect(returnStatement.expression)); |
| 2068 } else { |
| 2069 body = buildStatementInBlock(bodyNode); |
| 2070 } |
| 2052 } | 2071 } |
| 2053 return associateElement( | 2072 return associateElement( |
| 2054 new ir.FunctionNode(body, | 2073 new ir.FunctionNode(body, |
| 2055 asyncMarker: asyncMarker, | 2074 asyncMarker: asyncMarker, |
| 2056 returnType: returnType, | 2075 returnType: returnType, |
| 2057 typeParameters: typeParameters, | 2076 typeParameters: typeParameters, |
| 2058 positionalParameters: positionalParameters, | 2077 positionalParameters: positionalParameters, |
| 2059 namedParameters: namedParameters, | 2078 namedParameters: namedParameters, |
| 2060 requiredParameterCount: requiredParameterCount), | 2079 requiredParameterCount: requiredParameterCount), |
| 2061 function); | 2080 function); |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2776 : this(null, true, node, initializers); | 2795 : this(null, true, node, initializers); |
| 2777 | 2796 |
| 2778 accept(ir.Visitor v) => throw "unsupported"; | 2797 accept(ir.Visitor v) => throw "unsupported"; |
| 2779 | 2798 |
| 2780 visitChildren(ir.Visitor v) => throw "unsupported"; | 2799 visitChildren(ir.Visitor v) => throw "unsupported"; |
| 2781 | 2800 |
| 2782 String toString() { | 2801 String toString() { |
| 2783 return "IrFunction($kind, $isConstructor, $node, $initializers)"; | 2802 return "IrFunction($kind, $isConstructor, $node, $initializers)"; |
| 2784 } | 2803 } |
| 2785 } | 2804 } |
| OLD | NEW |