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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.body_builder; | 5 library fasta.body_builder; |
6 | 6 |
7 import 'package:front_end/src/fasta/parser/parser.dart' show | 7 import 'package:front_end/src/fasta/parser/parser.dart' show |
8 FormalParameterType, | 8 FormalParameterType, |
9 optional; | 9 optional; |
10 | 10 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 List<Expression> popListForEffect(int n) { | 229 List<Expression> popListForEffect(int n) { |
230 List<Expression> list = | 230 List<Expression> list = |
231 new List<Expression>.filled(n, null, growable: true); | 231 new List<Expression>.filled(n, null, growable: true); |
232 for (int i = n - 1; i >= 0; i--) { | 232 for (int i = n - 1; i >= 0; i--) { |
233 list[i] = popForEffect(); | 233 list[i] = popForEffect(); |
234 } | 234 } |
235 return list; | 235 return list; |
236 } | 236 } |
237 | 237 |
238 Block popBlock(int count) { | 238 Block popBlock(int count) { |
239 List<Statement> statements = popList(count) ?? <Statement>[]; | 239 List<dynamic /*Statement | List<Statement>*/> statements = |
240 popList(count) ?? <Statement>[]; | |
240 List<Statement> copy; | 241 List<Statement> copy; |
241 for (int i = 0; i < statements.length; i++) { | 242 for (int i = 0; i < statements.length; i++) { |
242 var statement = statements[i]; | 243 var statement = statements[i]; |
243 if (statement is List) { | 244 if (statement is List) { |
244 copy ??= new List<Statement>.from(statements.getRange(0, i)); | 245 copy ??= new List<Statement>.from(statements.getRange(0, i)); |
245 copy.addAll(statement); | 246 // TODO(sigmund): remove this assignment (issue #28651) |
247 Iterable subStatements = statement; | |
248 copy.addAll(subStatements); | |
246 } else if (copy != null) { | 249 } else if (copy != null) { |
247 copy.add(statement); | 250 copy.add(statement); |
248 } | 251 } |
249 } | 252 } |
250 return new Block(copy ?? statements); | 253 return new Block(copy ?? statements); |
251 } | 254 } |
252 | 255 |
253 Statement popStatementIfNotNull(Object value) { | 256 Statement popStatementIfNotNull(Object value) { |
254 return value == null ? null : popStatement(); | 257 return value == null ? null : popStatement(); |
255 } | 258 } |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 @override | 501 @override |
499 void handleParenthesizedExpression(BeginGroupToken token) { | 502 void handleParenthesizedExpression(BeginGroupToken token) { |
500 debugEvent("ParenthesizedExpression"); | 503 debugEvent("ParenthesizedExpression"); |
501 push(popForValue()); | 504 push(popForValue()); |
502 } | 505 } |
503 | 506 |
504 @override | 507 @override |
505 void endSend(Token token) { | 508 void endSend(Token token) { |
506 debugEvent("Send"); | 509 debugEvent("Send"); |
507 Arguments arguments = pop(); | 510 Arguments arguments = pop(); |
508 List typeArguments = pop(); | 511 List<DartType> typeArguments = pop(); |
509 Object receiver = pop(); | 512 Object receiver = pop(); |
510 if (arguments != null && typeArguments != null) { | 513 if (arguments != null && typeArguments != null) { |
511 arguments.types.addAll(typeArguments); | 514 arguments.types.addAll(typeArguments); |
512 } else { | 515 } else { |
513 assert(typeArguments == null); | 516 assert(typeArguments == null); |
514 } | 517 } |
515 if (receiver is Identifier) { | 518 if (receiver is Identifier) { |
516 Name name = new Name(receiver.name, library.library); | 519 Name name = new Name(receiver.name, library.library); |
517 if (arguments == null) { | 520 if (arguments == null) { |
518 push(new IncompletePropertyAccessor(this, token.charOffset, name)); | 521 push(new IncompletePropertyAccessor(this, token.charOffset, name)); |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 Statement body = popStatement(); | 989 Statement body = popStatement(); |
987 List<Expression> updates = popListForEffect(updateExpressionCount); | 990 List<Expression> updates = popListForEffect(updateExpressionCount); |
988 Statement conditionStatement = popStatement(); | 991 Statement conditionStatement = popStatement(); |
989 Expression condition = null; | 992 Expression condition = null; |
990 if (conditionStatement is ExpressionStatement) { | 993 if (conditionStatement is ExpressionStatement) { |
991 condition = conditionStatement.expression; | 994 condition = conditionStatement.expression; |
992 } else { | 995 } else { |
993 assert(conditionStatement is EmptyStatement); | 996 assert(conditionStatement is EmptyStatement); |
994 } | 997 } |
995 List<VariableDeclaration> variables = <VariableDeclaration>[]; | 998 List<VariableDeclaration> variables = <VariableDeclaration>[]; |
996 var variableOrExpression = pop(); | 999 dynamic variableOrExpression = pop(); |
997 Statement begin; | 1000 Statement begin; |
998 if (variableOrExpression is BuilderAccessor) { | 1001 if (variableOrExpression is BuilderAccessor) { |
999 variableOrExpression = variableOrExpression.buildForEffect(); | 1002 variableOrExpression = variableOrExpression.buildForEffect(); |
1000 } | 1003 } |
1001 if (variableOrExpression is VariableDeclaration) { | 1004 if (variableOrExpression is VariableDeclaration) { |
1002 variables.add(variableOrExpression); | 1005 variables.add(variableOrExpression); |
1003 } else if (variableOrExpression is List) { | 1006 } else if (variableOrExpression is List) { |
1004 variables.addAll(variableOrExpression); | 1007 // TODO(sigmund): remove this assignment (see issue #28651) |
1008 Iterable vars = variableOrExpression; | |
1009 variables.addAll(vars); | |
1005 } else if (variableOrExpression == null) { | 1010 } else if (variableOrExpression == null) { |
1006 // Do nothing. | 1011 // Do nothing. |
1007 } else if (variableOrExpression is Expression) { | 1012 } else if (variableOrExpression is Expression) { |
1008 begin = new ExpressionStatement(variableOrExpression); | 1013 begin = new ExpressionStatement(variableOrExpression); |
1009 } else { | 1014 } else { |
1010 return internalError("Unhandled: ${variableOrExpression.runtimeType}"); | 1015 return internalError("Unhandled: ${variableOrExpression.runtimeType}"); |
1011 } | 1016 } |
1012 exitLocalScope(); | 1017 exitLocalScope(); |
1013 JumpTarget continueTarget = exitContinueTarget(); | 1018 JumpTarget continueTarget = exitContinueTarget(); |
1014 JumpTarget breakTarget = exitBreakTarget(); | 1019 JumpTarget breakTarget = exitBreakTarget(); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1154 } | 1159 } |
1155 // TODO(ahe): Create an error somehow. | 1160 // TODO(ahe): Create an error somehow. |
1156 return const DynamicType(); | 1161 return const DynamicType(); |
1157 } | 1162 } |
1158 | 1163 |
1159 @override | 1164 @override |
1160 void endType(Token beginToken, Token endToken) { | 1165 void endType(Token beginToken, Token endToken) { |
1161 // TODO(ahe): The scope is wrong for return types of generic functions. | 1166 // TODO(ahe): The scope is wrong for return types of generic functions. |
1162 debugEvent("Type"); | 1167 debugEvent("Type"); |
1163 List<DartType> arguments = pop(); | 1168 List<DartType> arguments = pop(); |
1164 var name = pop(); | 1169 dynamic name = pop(); |
1165 if (name is List) { | 1170 if (name is List) { |
1166 if (name.length != 2) { | 1171 if (name.length != 2) { |
1167 return internalError("Unexpected: $name.length"); | 1172 return internalError("Unexpected: $name.length"); |
1168 } | 1173 } |
1169 var prefix = name[0]; | 1174 var prefix = name[0]; |
1170 if (prefix is Identifier) { | 1175 if (prefix is Identifier) { |
1171 prefix = prefix.name; | 1176 prefix = prefix.name; |
1172 } | 1177 } |
1173 var suffix = name[1]; | 1178 var suffix = name[1]; |
1174 if (suffix is Identifier) { | 1179 if (suffix is Identifier) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1268 return inputError("'this' parameters can only be used on constructors.", | 1273 return inputError("'this' parameters can only be used on constructors.", |
1269 thisKeyword.charOffset); | 1274 thisKeyword.charOffset); |
1270 } | 1275 } |
1271 } | 1276 } |
1272 Identifier name = pop(); | 1277 Identifier name = pop(); |
1273 DartType type = pop(); | 1278 DartType type = pop(); |
1274 pop(); // Modifiers. | 1279 pop(); // Modifiers. |
1275 ignore(Unhandled.Metadata); | 1280 ignore(Unhandled.Metadata); |
1276 VariableDeclaration variable; | 1281 VariableDeclaration variable; |
1277 if (!inCatchClause && functionNestingLevel == 0) { | 1282 if (!inCatchClause && functionNestingLevel == 0) { |
1278 var builder = formalParameterScope.lookup(name.name); | 1283 dynamic builder = formalParameterScope.lookup(name.name); |
1279 if (builder == null) { | 1284 if (builder == null) { |
1280 return inputError("'${name.name}' isn't a field in this class.", | 1285 return inputError("'${name.name}' isn't a field in this class.", |
1281 name.fileOffset); | 1286 name.fileOffset); |
1282 } | 1287 } |
1283 if (thisKeyword == null) { | 1288 if (thisKeyword == null) { |
1284 variable = builder.build(); | 1289 variable = builder.build(); |
1285 variable.initializer = name.initializer; | 1290 variable.initializer = name.initializer; |
1286 } else if (builder.isField && builder.parent == classBuilder) { | 1291 } else if (builder.isField && builder.parent == classBuilder) { |
1287 FieldBuilder field = builder; | 1292 FieldBuilder field = builder; |
1288 if (type != null) { | 1293 if (type != null) { |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1497 // | 1502 // |
1498 // This method pops 2 (or 3 if periodBeforeName != null) values from the | 1503 // This method pops 2 (or 3 if periodBeforeName != null) values from the |
1499 // stack and pushes 3 values: a type, a list of type arguments, and a name. | 1504 // stack and pushes 3 values: a type, a list of type arguments, and a name. |
1500 // | 1505 // |
1501 // If the constructor reference can be resolved, type is either a | 1506 // If the constructor reference can be resolved, type is either a |
1502 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that | 1507 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that |
1503 // should be handled later. | 1508 // should be handled later. |
1504 Identifier suffix = popIfNotNull(periodBeforeName); | 1509 Identifier suffix = popIfNotNull(periodBeforeName); |
1505 Identifier identifier; | 1510 Identifier identifier; |
1506 List<DartType> typeArguments = pop(); | 1511 List<DartType> typeArguments = pop(); |
1507 var type = pop(); | 1512 dynamic type = pop(); |
1508 if (type is List) { | 1513 if (type is List) { |
1509 var prefix = type[0]; | 1514 var prefix = type[0]; |
1510 identifier = type[1]; | 1515 identifier = type[1]; |
1511 if (prefix is PrefixBuilder) { | 1516 if (prefix is PrefixBuilder) { |
1512 // TODO(ahe): Handle privacy in prefix.exports. | 1517 // TODO(ahe): Handle privacy in prefix.exports. |
1513 type = builderToFirstExpression( | 1518 type = builderToFirstExpression( |
1514 prefix.exports[identifier.name], identifier.name, start.charOffset); | 1519 prefix.exports[identifier.name], identifier.name, start.charOffset); |
1515 identifier = null; | 1520 identifier = null; |
1516 } else if (prefix is ClassBuilder) { | 1521 } else if (prefix is ClassBuilder) { |
1517 type = prefix; | 1522 type = prefix; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1614 library.addArgumentsWithMissingDefaultValues(arguments, function); | 1619 library.addArgumentsWithMissingDefaultValues(arguments, function); |
1615 } | 1620 } |
1616 return true; | 1621 return true; |
1617 } | 1622 } |
1618 | 1623 |
1619 @override | 1624 @override |
1620 void handleNewExpression(Token token) { | 1625 void handleNewExpression(Token token) { |
1621 debugEvent("NewExpression"); | 1626 debugEvent("NewExpression"); |
1622 Arguments arguments = pop(); | 1627 Arguments arguments = pop(); |
1623 String name = pop(); | 1628 String name = pop(); |
1624 List typeArguments = pop(); | 1629 List<DartType> typeArguments = pop(); |
1625 var type = pop(); | 1630 var type = pop(); |
1626 | 1631 |
1627 if (typeArguments != null) { | 1632 if (typeArguments != null) { |
1628 assert(arguments.types.isEmpty); | 1633 assert(arguments.types.isEmpty); |
1629 arguments.types.addAll(typeArguments); | 1634 arguments.types.addAll(typeArguments); |
1630 } | 1635 } |
1631 | 1636 |
1632 String errorName; | 1637 String errorName; |
1633 if (type is ClassBuilder) { | 1638 if (type is ClassBuilder) { |
1634 Builder b = type.findConstructorOrFactory(name); | 1639 Builder b = type.findConstructorOrFactory(name); |
1635 Member target; | 1640 Member target; |
1636 if (b == null) { | 1641 if (b == null) { |
1637 // Not found. Reported below. | 1642 // Not found. Reported below. |
1638 } else if (b.isConstructor) { | 1643 } else if (b.isConstructor) { |
1639 if (type.cls.isAbstract) { | 1644 if (type.isAbstract) { |
Siggi Cherem (dart-lang)
2017/02/10 19:20:31
FYI - I reverted this one change for now so I coul
| |
1640 // TODO(ahe): Generate abstract instantiation error. | 1645 // TODO(ahe): Generate abstract instantiation error. |
1641 } else { | 1646 } else { |
1642 target = b.target; | 1647 target = b.target; |
1643 } | 1648 } |
1644 } else if (b.isFactory) { | 1649 } else if (b.isFactory) { |
1645 target = getRedirectionTarget(b.target); | 1650 target = getRedirectionTarget(b.target); |
1646 if (target == null) { | 1651 if (target == null) { |
1647 push(buildCompileTimeError( | 1652 push(buildCompileTimeError( |
1648 "Cyclic definition of factory '${name}'.", | 1653 "Cyclic definition of factory '${name}'.", |
1649 token.charOffset)); | 1654 token.charOffset)); |
1650 return; | 1655 return; |
1651 } | 1656 } |
1652 } | 1657 } |
1653 if (target is Constructor || | 1658 if (target is Constructor || |
1654 (target is Procedure && target.kind == ProcedureKind.Factory)) { | 1659 (target is Procedure && target.kind == ProcedureKind.Factory)) { |
1655 push(buildStaticInvocation( | 1660 push(buildStaticInvocation( |
1656 target, arguments, isConst: optional("const", token))); | 1661 target, arguments, isConst: optional("const", token))); |
1657 return; | 1662 return; |
1658 } else { | 1663 } else { |
1659 errorName = debugName(type.cls.name, name); | 1664 errorName = debugName(type.name, name); |
1660 } | 1665 } |
1661 } else { | 1666 } else { |
1662 errorName = debugName(getNodeName(type), name); | 1667 errorName = debugName(getNodeName(type), name); |
1663 } | 1668 } |
1664 errorName ??= name; | 1669 errorName ??= name; |
1665 push(throwNoSuchMethodError(errorName, arguments, token.charOffset)); | 1670 push(throwNoSuchMethodError(errorName, arguments, token.charOffset)); |
1666 } | 1671 } |
1667 | 1672 |
1668 @override | 1673 @override |
1669 void handleConstExpression(Token token) { | 1674 void handleConstExpression(Token token) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1736 | 1741 |
1737 @override | 1742 @override |
1738 void endFunction(Token getOrSet, Token endToken) { | 1743 void endFunction(Token getOrSet, Token endToken) { |
1739 debugEvent("Function"); | 1744 debugEvent("Function"); |
1740 Statement body = popStatement(); | 1745 Statement body = popStatement(); |
1741 AsyncMarker asyncModifier = pop(); | 1746 AsyncMarker asyncModifier = pop(); |
1742 if (functionNestingLevel != 0) { | 1747 if (functionNestingLevel != 0) { |
1743 exitLocalScope(); | 1748 exitLocalScope(); |
1744 } | 1749 } |
1745 FormalParameters formals = pop(); | 1750 FormalParameters formals = pop(); |
1746 List typeParameters = pop(); | 1751 List<TypeParameter> typeParameters = pop(); |
1747 push(formals.addToFunction(new FunctionNode(body, | 1752 push(formals.addToFunction(new FunctionNode(body, |
1748 typeParameters: typeParameters, asyncMarker: asyncModifier))); | 1753 typeParameters: typeParameters, asyncMarker: asyncModifier))); |
1749 functionNestingLevel--; | 1754 functionNestingLevel--; |
1750 } | 1755 } |
1751 | 1756 |
1752 @override | 1757 @override |
1753 void endFunctionDeclaration(Token token) { | 1758 void endFunctionDeclaration(Token token) { |
1754 debugEvent("FunctionDeclaration"); | 1759 debugEvent("FunctionDeclaration"); |
1755 FunctionNode function = pop(); | 1760 FunctionNode function = pop(); |
1756 exitLocalScope(); | 1761 exitLocalScope(); |
1757 FunctionDeclaration declaration = pop(); | 1762 FunctionDeclaration declaration = pop(); |
1758 function.returnType = pop() ?? const DynamicType(); | 1763 function.returnType = pop() ?? const DynamicType(); |
1759 pop(); // Modifiers. | 1764 pop(); // Modifiers. |
1760 declaration.function = function; | 1765 declaration.function = function; |
1761 function.parent = declaration; | 1766 function.parent = declaration; |
1762 push(declaration); | 1767 push(declaration); |
1763 } | 1768 } |
1764 | 1769 |
1765 @override | 1770 @override |
1766 void endUnnamedFunction(Token token) { | 1771 void endUnnamedFunction(Token token) { |
1767 debugEvent("UnnamedFunction"); | 1772 debugEvent("UnnamedFunction"); |
1768 Statement body = popStatement(); | 1773 Statement body = popStatement(); |
1769 AsyncMarker asyncModifier = pop(); | 1774 AsyncMarker asyncModifier = pop(); |
1770 exitLocalScope(); | 1775 exitLocalScope(); |
1771 FormalParameters formals = pop(); | 1776 FormalParameters formals = pop(); |
1772 List typeParameters = pop(); | 1777 List<TypeParameter> typeParameters = pop(); |
1773 FunctionNode function = formals.addToFunction(new FunctionNode(body, | 1778 FunctionNode function = formals.addToFunction(new FunctionNode(body, |
1774 typeParameters: typeParameters, asyncMarker: asyncModifier)); | 1779 typeParameters: typeParameters, asyncMarker: asyncModifier)); |
1775 push(new FunctionExpression(function)); | 1780 push(new FunctionExpression(function)); |
1776 functionNestingLevel--; | 1781 functionNestingLevel--; |
1777 } | 1782 } |
1778 | 1783 |
1779 @override | 1784 @override |
1780 void endDoWhileStatement( | 1785 void endDoWhileStatement( |
1781 Token doKeyword, Token whileKeyword, Token endToken) { | 1786 Token doKeyword, Token whileKeyword, Token endToken) { |
1782 debugEvent("DoWhileStatement"); | 1787 debugEvent("DoWhileStatement"); |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2674 } else if (node is TypeDeclarationBuilder) { | 2679 } else if (node is TypeDeclarationBuilder) { |
2675 return node.name; | 2680 return node.name; |
2676 } else if (node is PrefixBuilder) { | 2681 } else if (node is PrefixBuilder) { |
2677 return node.name; | 2682 return node.name; |
2678 } else if (node is ThisPropertyAccessor) { | 2683 } else if (node is ThisPropertyAccessor) { |
2679 return node.name.name; | 2684 return node.name.name; |
2680 } else { | 2685 } else { |
2681 return internalError("Unhandled: ${node.runtimeType}"); | 2686 return internalError("Unhandled: ${node.runtimeType}"); |
2682 } | 2687 } |
2683 } | 2688 } |
OLD | NEW |