Chromium Code Reviews| 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 |