Index: pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart |
diff --git a/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart b/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart |
index 3310536f2688c8f64d8d722e8c7aa6f09951bb13..7a148b197246f81ca0d10c652fd3728b5a952a21 100644 |
--- a/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart |
+++ b/pkg/front_end/lib/src/fasta/analyzer/ast_builder.dart |
@@ -4,46 +4,34 @@ |
library fasta.analyzer.ast_builder; |
-import 'package:front_end/src/fasta/scanner/token.dart' |
- show BeginGroupToken, Token; |
+import 'dart:collection' show Queue; |
import 'package:analyzer/analyzer.dart'; |
- |
-import 'package:analyzer/dart/ast/token.dart' as analyzer show Token; |
- |
-import 'package:analyzer/dart/element/element.dart' show Element; |
- |
import 'package:analyzer/dart/ast/ast_factory.dart' show AstFactory; |
- |
import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard; |
- |
+import 'package:analyzer/dart/ast/token.dart' as analyzer show Token; |
+import 'package:analyzer/dart/element/element.dart' show Element; |
+import 'package:front_end/src/fasta/scanner/token.dart' |
+ show BeginGroupToken, Token; |
import 'package:kernel/ast.dart' show AsyncMarker; |
import '../errors.dart' show internalError; |
- |
-import '../source/scope_listener.dart' |
- show JumpTargetKind, NullValue, Scope, ScopeListener; |
- |
import '../kernel/kernel_builder.dart' |
show Builder, KernelLibraryBuilder, ProcedureBuilder; |
- |
import '../parser/parser.dart' show optional; |
- |
import '../quote.dart'; |
- |
import '../source/outline_builder.dart' show asyncMarkerFromTokens; |
- |
+import '../source/scope_listener.dart' |
+ show JumpTargetKind, NullValue, Scope, ScopeListener; |
+import 'analyzer.dart' show toKernel; |
import 'element_store.dart' |
show |
AnalyzerLocalVariableElemment, |
AnalyzerParameterElement, |
ElementStore, |
KernelClassElement; |
- |
import 'token_utils.dart' show toAnalyzerToken; |
-import 'analyzer.dart' show toKernel; |
- |
class AstBuilder extends ScopeListener { |
final AstFactory ast = standard.astFactory; |
@@ -63,6 +51,18 @@ class AstBuilder extends ScopeListener { |
/// to the list. |
var accumulateIdentifierComponents = false; |
+ /// The kind of current formal parameters, optional or required. |
+ final Queue<ParameterKind> currentParameterKind = new Queue<ParameterKind>() |
+ ..add(ParameterKind.REQUIRED); |
+ |
+ /// The token `=` or `:` before the current parameter default value, or |
+ /// `null` if not the current parameter is not default. |
+ Token parameterDefaultValueToken; |
+ |
+ /// The current parameter default value expression, or `null` if not the |
+ /// current parameter is not default. |
+ Expression parameterDefaultValueExpression; |
+ |
AstBuilder(this.library, this.member, this.elementStore, Scope scope, |
[Uri uri]) |
: uri = uri ?? library.fileUri, |
@@ -502,6 +502,29 @@ class AstBuilder extends ScopeListener { |
push(ast.throwExpression(toAnalyzerToken(throwToken), pop())); |
} |
+ @override |
+ void beginOptionalFormalParameters(Token token) { |
+ String value = token.stringValue; |
+ if (identical('[', value)) { |
+ currentParameterKind.addLast(ParameterKind.POSITIONAL); |
ahe
2017/02/22 09:25:15
I suggest that you push this on the stack instead
scheglov
2017/02/22 17:18:14
How can I access it later?
After parsing the first
ahe
2017/02/22 17:30:23
That sounds like a good idea. We need to take adva
|
+ } else if (identical('{', value)) { |
+ currentParameterKind.addLast(ParameterKind.NAMED); |
+ } |
+ } |
+ |
+ @override |
+ void endOptionalFormalParameters( |
+ int count, Token beginToken, Token endToken) { |
+ debugEvent("OptionalFormalParameters"); |
+ currentParameterKind.removeLast(); |
+ } |
+ |
+ void handleValuedFormalParameter(Token equals, Token token) { |
+ debugEvent("ValuedFormalParameter"); |
+ parameterDefaultValueToken = equals; |
+ parameterDefaultValueExpression = pop(); |
ahe
2017/02/22 09:25:15
I would recommend against setting state in the lis
scheglov
2017/02/22 17:18:14
OK, I will add handleFormalParameterWithoutValue()
|
+ } |
+ |
void endFormalParameter(Token thisKeyword) { |
debugEvent("FormalParameter"); |
if (thisKeyword != null) { |
@@ -511,10 +534,21 @@ class AstBuilder extends ScopeListener { |
TypeName type = pop(); |
pop(); // Modifiers. |
pop(); // Metadata. |
- SimpleFormalParameter node = ast.simpleFormalParameter( |
+ FormalParameter node = ast.simpleFormalParameter( |
null, null, toAnalyzerToken(thisKeyword), type, name); |
+ |
+ if (parameterDefaultValueToken != null) { |
+ node = ast.defaultFormalParameter( |
+ node, |
+ currentParameterKind.last, |
+ toAnalyzerToken(parameterDefaultValueToken), |
+ parameterDefaultValueExpression); |
+ } |
+ |
scope[name.name] = name.staticElement = new AnalyzerParameterElement(node); |
push(node); |
+ parameterDefaultValueToken = null; |
+ parameterDefaultValueExpression = null; |
} |
void endFormalParameters(int count, Token beginToken, Token endToken) { |
@@ -873,8 +907,8 @@ class AstBuilder extends ScopeListener { |
} |
@override |
- void endNamedMixinApplication( |
- Token beginToken, Token equalsToken, Token implementsKeyword, Token endToken) { |
+ void endNamedMixinApplication(Token beginToken, Token equalsToken, |
+ Token implementsKeyword, Token endToken) { |
debugEvent("NamedMixinApplication"); |
ImplementsClause implementsClause; |
if (implementsKeyword != null) { |