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 '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
9 | 9 |
10 import '../parser/parser.dart' | 10 import '../parser/parser.dart' |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 "Expected named argument.", arguments[i].fileOffset)) | 611 "Expected named argument.", arguments[i].fileOffset)) |
612 ..fileOffset = beginToken.charOffset; | 612 ..fileOffset = beginToken.charOffset; |
613 } | 613 } |
614 } | 614 } |
615 } | 615 } |
616 if (firstNamedArgumentIndex < arguments.length) { | 616 if (firstNamedArgumentIndex < arguments.length) { |
617 List<Expression> positional = new List<Expression>.from( | 617 List<Expression> positional = new List<Expression>.from( |
618 arguments.getRange(0, firstNamedArgumentIndex)); | 618 arguments.getRange(0, firstNamedArgumentIndex)); |
619 List<NamedExpression> named = new List<NamedExpression>.from( | 619 List<NamedExpression> named = new List<NamedExpression>.from( |
620 arguments.getRange(firstNamedArgumentIndex, arguments.length)); | 620 arguments.getRange(firstNamedArgumentIndex, arguments.length)); |
| 621 if (named.length == 2) { |
| 622 if (named[0].name == named[1].name) { |
| 623 named = <NamedExpression>[ |
| 624 new NamedExpression( |
| 625 named[1].name, |
| 626 buildCompileTimeError( |
| 627 "Duplicated named argument '${named[1].name}'.", |
| 628 named[1].fileOffset)) |
| 629 ]; |
| 630 } |
| 631 } else if (named.length > 2) { |
| 632 Map<String, NamedExpression> seenNames = <String, NamedExpression>{}; |
| 633 bool hasProblem = false; |
| 634 for (NamedExpression expression in named) { |
| 635 if (seenNames.containsKey(expression.name)) { |
| 636 hasProblem = true; |
| 637 seenNames[expression.name].value = buildCompileTimeError( |
| 638 "Duplicated named argument '${expression.name}'.", |
| 639 expression.fileOffset); |
| 640 } else { |
| 641 seenNames[expression.name] = expression; |
| 642 } |
| 643 } |
| 644 if (hasProblem) { |
| 645 named = new List<NamedExpression>.from(seenNames.values); |
| 646 } |
| 647 } |
621 push(new KernelArguments(positional, named: named) | 648 push(new KernelArguments(positional, named: named) |
622 ..fileOffset = beginToken.charOffset); | 649 ..fileOffset = beginToken.charOffset); |
623 } else { | 650 } else { |
624 push(new KernelArguments(arguments)..fileOffset = beginToken.charOffset); | 651 push(new KernelArguments(arguments)..fileOffset = beginToken.charOffset); |
625 } | 652 } |
626 } | 653 } |
627 | 654 |
628 @override | 655 @override |
629 void handleParenthesizedExpression(BeginToken token) { | 656 void handleParenthesizedExpression(BeginToken token) { |
630 debugEvent("ParenthesizedExpression"); | 657 debugEvent("ParenthesizedExpression"); |
(...skipping 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2209 } | 2236 } |
2210 | 2237 |
2211 @override | 2238 @override |
2212 void endFunctionName(Token beginToken, Token token) { | 2239 void endFunctionName(Token beginToken, Token token) { |
2213 debugEvent("FunctionName"); | 2240 debugEvent("FunctionName"); |
2214 Identifier name = pop(); | 2241 Identifier name = pop(); |
2215 VariableDeclaration variable = new KernelVariableDeclaration( | 2242 VariableDeclaration variable = new KernelVariableDeclaration( |
2216 name.name, functionNestingLevel, | 2243 name.name, functionNestingLevel, |
2217 isFinal: true, isLocalFunction: true) | 2244 isFinal: true, isLocalFunction: true) |
2218 ..fileOffset = offsetForToken(name.token); | 2245 ..fileOffset = offsetForToken(name.token); |
| 2246 if (scope.local[variable.name] != null) { |
| 2247 addCompileTimeError(offsetForToken(name.token), |
| 2248 "'${variable.name}' already declared in this scope."); |
| 2249 } |
2219 push(new KernelFunctionDeclaration( | 2250 push(new KernelFunctionDeclaration( |
2220 variable, | 2251 variable, |
2221 // The function node is created later. | 2252 // The function node is created later. |
2222 null) | 2253 null) |
2223 ..fileOffset = beginToken.charOffset); | 2254 ..fileOffset = beginToken.charOffset); |
2224 declareVariable(variable); | 2255 declareVariable(variable); |
2225 enterLocalScope(); | 2256 enterLocalScope(); |
2226 } | 2257 } |
2227 | 2258 |
2228 void enterFunction() { | 2259 void enterFunction() { |
(...skipping 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3511 if (starToken == null) { | 3542 if (starToken == null) { |
3512 return AsyncMarker.Async; | 3543 return AsyncMarker.Async; |
3513 } else { | 3544 } else { |
3514 assert(identical(starToken.stringValue, "*")); | 3545 assert(identical(starToken.stringValue, "*")); |
3515 return AsyncMarker.AsyncStar; | 3546 return AsyncMarker.AsyncStar; |
3516 } | 3547 } |
3517 } else { | 3548 } else { |
3518 return internalError("Unknown async modifier: $asyncToken"); | 3549 return internalError("Unknown async modifier: $asyncToken"); |
3519 } | 3550 } |
3520 } | 3551 } |
OLD | NEW |