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 statements = popList(count) ?? <Statement>[]; |
240 List<Statement> copy; | 240 // TODO(sigmund): should be List<Statement>. In strong mode the .addAll |
241 // below shows an error (and will fail at runtime). The core issue is that | |
242 // `statements` is a List< Statement or List<Statement>>, but we expect that | |
243 // some of the nested lists will have a reified type of List not | |
244 // List<Statement>. | |
ahe
2017/02/07 11:03:07
How about:
List<dynamic /* Statement | List<State
Siggi Cherem (dart-lang)
2017/02/07 21:59:25
Done. added the comment on the type, but had to do
| |
245 List copy; | |
ahe
2017/02/07 11:03:07
This should be List<Statement>.
Siggi Cherem (dart-lang)
2017/02/07 21:59:25
Done. Sorry for the confusion - the TODO was refer
| |
241 for (int i = 0; i < statements.length; i++) { | 246 for (int i = 0; i < statements.length; i++) { |
242 var statement = statements[i]; | 247 var statement = statements[i]; |
243 if (statement is List) { | 248 if (statement is List) { |
244 copy ??= new List<Statement>.from(statements.getRange(0, i)); | 249 copy ??= new List<Statement>.from(statements.getRange(0, i)); |
245 copy.addAll(statement); | 250 copy.addAll(statement); |
246 } else if (copy != null) { | 251 } else if (copy != null) { |
247 copy.add(statement); | 252 copy.add(statement); |
248 } | 253 } |
249 } | 254 } |
250 return new Block(copy ?? statements); | 255 return new Block(copy ?? statements); |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 @override | 503 @override |
499 void handleParenthesizedExpression(BeginGroupToken token) { | 504 void handleParenthesizedExpression(BeginGroupToken token) { |
500 debugEvent("ParenthesizedExpression"); | 505 debugEvent("ParenthesizedExpression"); |
501 push(popForValue()); | 506 push(popForValue()); |
502 } | 507 } |
503 | 508 |
504 @override | 509 @override |
505 void endSend(Token token) { | 510 void endSend(Token token) { |
506 debugEvent("Send"); | 511 debugEvent("Send"); |
507 Arguments arguments = pop(); | 512 Arguments arguments = pop(); |
508 List typeArguments = pop(); | 513 List<DartType> typeArguments = pop(); |
509 Object receiver = pop(); | 514 Object receiver = pop(); |
510 if (arguments != null && typeArguments != null) { | 515 if (arguments != null && typeArguments != null) { |
511 arguments.types.addAll(typeArguments); | 516 arguments.types.addAll(typeArguments); |
512 } else { | 517 } else { |
513 assert(typeArguments == null); | 518 assert(typeArguments == null); |
514 } | 519 } |
515 if (receiver is Identifier) { | 520 if (receiver is Identifier) { |
516 Name name = new Name(receiver.name, library.library); | 521 Name name = new Name(receiver.name, library.library); |
517 if (arguments == null) { | 522 if (arguments == null) { |
518 push(new IncompletePropertyAccessor(this, token.charOffset, name)); | 523 push(new IncompletePropertyAccessor(this, token.charOffset, name)); |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 Statement body = popStatement(); | 991 Statement body = popStatement(); |
987 List<Expression> updates = popListForEffect(updateExpressionCount); | 992 List<Expression> updates = popListForEffect(updateExpressionCount); |
988 Statement conditionStatement = popStatement(); | 993 Statement conditionStatement = popStatement(); |
989 Expression condition = null; | 994 Expression condition = null; |
990 if (conditionStatement is ExpressionStatement) { | 995 if (conditionStatement is ExpressionStatement) { |
991 condition = conditionStatement.expression; | 996 condition = conditionStatement.expression; |
992 } else { | 997 } else { |
993 assert(conditionStatement is EmptyStatement); | 998 assert(conditionStatement is EmptyStatement); |
994 } | 999 } |
995 List<VariableDeclaration> variables = <VariableDeclaration>[]; | 1000 List<VariableDeclaration> variables = <VariableDeclaration>[]; |
996 var variableOrExpression = pop(); | 1001 dynamic variableOrExpression = pop(); |
997 Statement begin; | 1002 Statement begin; |
998 if (variableOrExpression is BuilderAccessor) { | 1003 if (variableOrExpression is BuilderAccessor) { |
999 variableOrExpression = variableOrExpression.buildForEffect(); | 1004 variableOrExpression = variableOrExpression.buildForEffect(); |
1000 } | 1005 } |
1001 if (variableOrExpression is VariableDeclaration) { | 1006 if (variableOrExpression is VariableDeclaration) { |
1002 variables.add(variableOrExpression); | 1007 variables.add(variableOrExpression); |
1003 } else if (variableOrExpression is List) { | 1008 } else if (variableOrExpression is List) { |
1004 variables.addAll(variableOrExpression); | 1009 // TODO(sigmund): remove this assignment (see issue #28651) |
1010 Iterable vars = variableOrExpression; | |
1011 variables.addAll(vars); | |
1005 } else if (variableOrExpression == null) { | 1012 } else if (variableOrExpression == null) { |
1006 // Do nothing. | 1013 // Do nothing. |
1007 } else if (variableOrExpression is Expression) { | 1014 } else if (variableOrExpression is Expression) { |
1008 begin = new ExpressionStatement(variableOrExpression); | 1015 begin = new ExpressionStatement(variableOrExpression); |
1009 } else { | 1016 } else { |
1010 return internalError("Unhandled: ${variableOrExpression.runtimeType}"); | 1017 return internalError("Unhandled: ${variableOrExpression.runtimeType}"); |
1011 } | 1018 } |
1012 exitLocalScope(); | 1019 exitLocalScope(); |
1013 JumpTarget continueTarget = exitContinueTarget(); | 1020 JumpTarget continueTarget = exitContinueTarget(); |
1014 JumpTarget breakTarget = exitBreakTarget(); | 1021 JumpTarget breakTarget = exitBreakTarget(); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1154 } | 1161 } |
1155 // TODO(ahe): Create an error somehow. | 1162 // TODO(ahe): Create an error somehow. |
1156 return const DynamicType(); | 1163 return const DynamicType(); |
1157 } | 1164 } |
1158 | 1165 |
1159 @override | 1166 @override |
1160 void endType(Token beginToken, Token endToken) { | 1167 void endType(Token beginToken, Token endToken) { |
1161 // TODO(ahe): The scope is wrong for return types of generic functions. | 1168 // TODO(ahe): The scope is wrong for return types of generic functions. |
1162 debugEvent("Type"); | 1169 debugEvent("Type"); |
1163 List<DartType> arguments = pop(); | 1170 List<DartType> arguments = pop(); |
1164 var name = pop(); | 1171 dynamic name = pop(); |
1165 if (name is List) { | 1172 if (name is List) { |
1166 if (name.length != 2) { | 1173 if (name.length != 2) { |
1167 return internalError("Unexpected: $name.length"); | 1174 return internalError("Unexpected: $name.length"); |
1168 } | 1175 } |
1169 var prefix = name[0]; | 1176 var prefix = name[0]; |
1170 if (prefix is Identifier) { | 1177 if (prefix is Identifier) { |
1171 prefix = prefix.name; | 1178 prefix = prefix.name; |
1172 } | 1179 } |
1173 var suffix = name[1]; | 1180 var suffix = name[1]; |
1174 if (suffix is Identifier) { | 1181 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.", | 1275 return inputError("'this' parameters can only be used on constructors.", |
1269 thisKeyword.charOffset); | 1276 thisKeyword.charOffset); |
1270 } | 1277 } |
1271 } | 1278 } |
1272 Identifier name = pop(); | 1279 Identifier name = pop(); |
1273 DartType type = pop(); | 1280 DartType type = pop(); |
1274 pop(); // Modifiers. | 1281 pop(); // Modifiers. |
1275 ignore(Unhandled.Metadata); | 1282 ignore(Unhandled.Metadata); |
1276 VariableDeclaration variable; | 1283 VariableDeclaration variable; |
1277 if (!inCatchClause && functionNestingLevel == 0) { | 1284 if (!inCatchClause && functionNestingLevel == 0) { |
1278 var builder = formalParameterScope.lookup(name.name); | 1285 var builder = formalParameterScope.lookup(name.name); |
ahe
2017/02/07 11:03:08
dynamic.
Siggi Cherem (dart-lang)
2017/02/07 21:59:25
Done.
| |
1279 if (builder == null) { | 1286 if (builder == null) { |
1280 return inputError("'${name.name}' isn't a field in this class.", | 1287 return inputError("'${name.name}' isn't a field in this class.", |
1281 name.fileOffset); | 1288 name.fileOffset); |
1282 } | 1289 } |
1283 if (thisKeyword == null) { | 1290 if (thisKeyword == null) { |
1284 variable = builder.build(); | 1291 KernelFormalParameterBuilder formalBuilder = builder; |
ahe
2017/02/07 11:03:08
Remove this.
Siggi Cherem (dart-lang)
2017/02/07 21:59:25
Done.
| |
1292 variable = formalBuilder.build(); | |
1285 variable.initializer = name.initializer; | 1293 variable.initializer = name.initializer; |
1286 } else if (builder.isField && builder.parent == classBuilder) { | 1294 } else if (builder.isField && builder.parent == classBuilder) { |
1287 FieldBuilder field = builder; | 1295 FieldBuilder field = builder; |
1288 if (type != null) { | 1296 if (type != null) { |
1289 nit("Ignoring type on 'this' parameter '${name.name}'.", | 1297 nit("Ignoring type on 'this' parameter '${name.name}'.", |
1290 name.fileOffset); | 1298 name.fileOffset); |
1291 } | 1299 } |
1292 type = field.target.type ?? const DynamicType(); | 1300 type = field.target.type ?? const DynamicType(); |
1293 variable = new VariableDeclaration(name.name, type: type, | 1301 variable = new VariableDeclaration(name.name, type: type, |
1294 initializer: name.initializer); | 1302 initializer: name.initializer); |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1497 // | 1505 // |
1498 // This method pops 2 (or 3 if periodBeforeName != null) values from the | 1506 // 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. | 1507 // stack and pushes 3 values: a type, a list of type arguments, and a name. |
1500 // | 1508 // |
1501 // If the constructor reference can be resolved, type is either a | 1509 // If the constructor reference can be resolved, type is either a |
1502 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that | 1510 // ClassBuilder, or a ThisPropertyAccessor. Otherwise, it's an error that |
1503 // should be handled later. | 1511 // should be handled later. |
1504 Identifier suffix = popIfNotNull(periodBeforeName); | 1512 Identifier suffix = popIfNotNull(periodBeforeName); |
1505 Identifier identifier; | 1513 Identifier identifier; |
1506 List<DartType> typeArguments = pop(); | 1514 List<DartType> typeArguments = pop(); |
1507 var type = pop(); | 1515 dynamic type = pop(); |
1508 if (type is List) { | 1516 if (type is List) { |
1509 var prefix = type[0]; | 1517 var prefix = type[0]; |
1510 identifier = type[1]; | 1518 identifier = type[1]; |
1511 if (prefix is PrefixBuilder) { | 1519 if (prefix is PrefixBuilder) { |
1512 // TODO(ahe): Handle privacy in prefix.exports. | 1520 // TODO(ahe): Handle privacy in prefix.exports. |
1513 type = builderToFirstExpression( | 1521 type = builderToFirstExpression( |
1514 prefix.exports[identifier.name], identifier.name, start.charOffset); | 1522 prefix.exports[identifier.name], identifier.name, start.charOffset); |
1515 identifier = null; | 1523 identifier = null; |
1516 } else if (prefix is ClassBuilder) { | 1524 } else if (prefix is ClassBuilder) { |
1517 type = prefix; | 1525 type = prefix; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1614 library.addArgumentsWithMissingDefaultValues(arguments, function); | 1622 library.addArgumentsWithMissingDefaultValues(arguments, function); |
1615 } | 1623 } |
1616 return true; | 1624 return true; |
1617 } | 1625 } |
1618 | 1626 |
1619 @override | 1627 @override |
1620 void handleNewExpression(Token token) { | 1628 void handleNewExpression(Token token) { |
1621 debugEvent("NewExpression"); | 1629 debugEvent("NewExpression"); |
1622 Arguments arguments = pop(); | 1630 Arguments arguments = pop(); |
1623 String name = pop(); | 1631 String name = pop(); |
1624 List typeArguments = pop(); | 1632 List<DartType> typeArguments = pop(); |
1625 var type = pop(); | 1633 var type = pop(); |
1626 | 1634 |
1627 if (typeArguments != null) { | 1635 if (typeArguments != null) { |
1628 assert(arguments.types.isEmpty); | 1636 assert(arguments.types.isEmpty); |
1629 arguments.types.addAll(typeArguments); | 1637 arguments.types.addAll(typeArguments); |
1630 } | 1638 } |
1631 | 1639 |
1632 String errorName; | 1640 String errorName; |
1633 if (type is ClassBuilder) { | 1641 if (type is KernelClassBuilder) { |
ahe
2017/02/07 11:03:07
Change this back.
Siggi Cherem (dart-lang)
2017/02/07 21:59:25
Sorry, I totally meant to ask you a follow up ques
ahe
2017/02/08 19:59:23
I don't think it can happen currently, but I'd lik
Siggi Cherem (dart-lang)
2017/02/09 04:44:02
Done.
| |
1634 Builder b = type.findConstructorOrFactory(name); | 1642 Builder b = type.findConstructorOrFactory(name); |
1635 Member target; | 1643 Member target; |
1636 if (b == null) { | 1644 if (b == null) { |
1637 // Not found. Reported below. | 1645 // Not found. Reported below. |
1638 } else if (b.isConstructor) { | 1646 } else if (b.isConstructor) { |
1639 if (type.cls.isAbstract) { | 1647 if (type.cls.isAbstract) { |
ahe
2017/02/08 19:59:23
I don't think we have isAbstract on ClassBuilder,
Siggi Cherem (dart-lang)
2017/02/09 04:44:02
Done.
| |
1640 // TODO(ahe): Generate abstract instantiation error. | 1648 // TODO(ahe): Generate abstract instantiation error. |
1641 } else { | 1649 } else { |
1642 target = b.target; | 1650 target = b.target; |
1643 } | 1651 } |
1644 } else if (b.isFactory) { | 1652 } else if (b.isFactory) { |
1645 target = getRedirectionTarget(b.target); | 1653 target = getRedirectionTarget(b.target); |
1646 if (target == null) { | 1654 if (target == null) { |
1647 push(buildCompileTimeError( | 1655 push(buildCompileTimeError( |
1648 "Cyclic definition of factory '${name}'.", | 1656 "Cyclic definition of factory '${name}'.", |
1649 token.charOffset)); | 1657 token.charOffset)); |
1650 return; | 1658 return; |
1651 } | 1659 } |
1652 } | 1660 } |
1653 if (target is Constructor || | 1661 if (target is Constructor || |
1654 (target is Procedure && target.kind == ProcedureKind.Factory)) { | 1662 (target is Procedure && target.kind == ProcedureKind.Factory)) { |
1655 push(buildStaticInvocation( | 1663 push(buildStaticInvocation( |
1656 target, arguments, isConst: optional("const", token))); | 1664 target, arguments, isConst: optional("const", token))); |
1657 return; | 1665 return; |
1658 } else { | 1666 } else { |
1659 errorName = debugName(type.cls.name, name); | 1667 errorName = debugName(type.cls.name, name); |
ahe
2017/02/08 19:59:23
I think debugName(type.name, name) should work ins
Siggi Cherem (dart-lang)
2017/02/09 04:44:02
Done.
| |
1660 } | 1668 } |
1661 } else { | 1669 } else { |
1662 errorName = debugName(getNodeName(type), name); | 1670 errorName = debugName(getNodeName(type), name); |
1663 } | 1671 } |
1664 errorName ??= name; | 1672 errorName ??= name; |
1665 push(throwNoSuchMethodError(errorName, arguments, token.charOffset)); | 1673 push(throwNoSuchMethodError(errorName, arguments, token.charOffset)); |
1666 } | 1674 } |
1667 | 1675 |
1668 @override | 1676 @override |
1669 void handleConstExpression(Token token) { | 1677 void handleConstExpression(Token token) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1736 | 1744 |
1737 @override | 1745 @override |
1738 void endFunction(Token getOrSet, Token endToken) { | 1746 void endFunction(Token getOrSet, Token endToken) { |
1739 debugEvent("Function"); | 1747 debugEvent("Function"); |
1740 Statement body = popStatement(); | 1748 Statement body = popStatement(); |
1741 AsyncMarker asyncModifier = pop(); | 1749 AsyncMarker asyncModifier = pop(); |
1742 if (functionNestingLevel != 0) { | 1750 if (functionNestingLevel != 0) { |
1743 exitLocalScope(); | 1751 exitLocalScope(); |
1744 } | 1752 } |
1745 FormalParameters formals = pop(); | 1753 FormalParameters formals = pop(); |
1746 List typeParameters = pop(); | 1754 List<TypeParameter> typeParameters = pop(); |
1747 push(formals.addToFunction(new FunctionNode(body, | 1755 push(formals.addToFunction(new FunctionNode(body, |
1748 typeParameters: typeParameters, asyncMarker: asyncModifier))); | 1756 typeParameters: typeParameters, asyncMarker: asyncModifier))); |
1749 functionNestingLevel--; | 1757 functionNestingLevel--; |
1750 } | 1758 } |
1751 | 1759 |
1752 @override | 1760 @override |
1753 void endFunctionDeclaration(Token token) { | 1761 void endFunctionDeclaration(Token token) { |
1754 debugEvent("FunctionDeclaration"); | 1762 debugEvent("FunctionDeclaration"); |
1755 FunctionNode function = pop(); | 1763 FunctionNode function = pop(); |
1756 exitLocalScope(); | 1764 exitLocalScope(); |
1757 FunctionDeclaration declaration = pop(); | 1765 FunctionDeclaration declaration = pop(); |
1758 function.returnType = pop() ?? const DynamicType(); | 1766 function.returnType = pop() ?? const DynamicType(); |
1759 pop(); // Modifiers. | 1767 pop(); // Modifiers. |
1760 declaration.function = function; | 1768 declaration.function = function; |
1761 function.parent = declaration; | 1769 function.parent = declaration; |
1762 push(declaration); | 1770 push(declaration); |
1763 } | 1771 } |
1764 | 1772 |
1765 @override | 1773 @override |
1766 void endUnnamedFunction(Token token) { | 1774 void endUnnamedFunction(Token token) { |
1767 debugEvent("UnnamedFunction"); | 1775 debugEvent("UnnamedFunction"); |
1768 Statement body = popStatement(); | 1776 Statement body = popStatement(); |
1769 AsyncMarker asyncModifier = pop(); | 1777 AsyncMarker asyncModifier = pop(); |
1770 exitLocalScope(); | 1778 exitLocalScope(); |
1771 FormalParameters formals = pop(); | 1779 FormalParameters formals = pop(); |
1772 List typeParameters = pop(); | 1780 List<TypeParameter> typeParameters = pop(); |
1773 FunctionNode function = formals.addToFunction(new FunctionNode(body, | 1781 FunctionNode function = formals.addToFunction(new FunctionNode(body, |
1774 typeParameters: typeParameters, asyncMarker: asyncModifier)); | 1782 typeParameters: typeParameters, asyncMarker: asyncModifier)); |
1775 push(new FunctionExpression(function)); | 1783 push(new FunctionExpression(function)); |
1776 functionNestingLevel--; | 1784 functionNestingLevel--; |
1777 } | 1785 } |
1778 | 1786 |
1779 @override | 1787 @override |
1780 void endDoWhileStatement( | 1788 void endDoWhileStatement( |
1781 Token doKeyword, Token whileKeyword, Token endToken) { | 1789 Token doKeyword, Token whileKeyword, Token endToken) { |
1782 debugEvent("DoWhileStatement"); | 1790 debugEvent("DoWhileStatement"); |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2674 } else if (node is TypeDeclarationBuilder) { | 2682 } else if (node is TypeDeclarationBuilder) { |
2675 return node.name; | 2683 return node.name; |
2676 } else if (node is PrefixBuilder) { | 2684 } else if (node is PrefixBuilder) { |
2677 return node.name; | 2685 return node.name; |
2678 } else if (node is ThisPropertyAccessor) { | 2686 } else if (node is ThisPropertyAccessor) { |
2679 return node.name.name; | 2687 return node.name.name; |
2680 } else { | 2688 } else { |
2681 return internalError("Unhandled: ${node.runtimeType}"); | 2689 return internalError("Unhandled: ${node.runtimeType}"); |
2682 } | 2690 } |
2683 } | 2691 } |
OLD | NEW |