mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:12:08 +00:00
Parse optional and named parameters.
I'm not a big fan of the currentParameterKind stack, this information is almost accessible from parseFormalParameter(), but we don't pass the type to the listener. R=ahe@google.com, paulberry@google.com BUG= Review-Url: https://codereview.chromium.org/2709783003 .
This commit is contained in:
parent
86c1ef03ee
commit
4500bb0920
|
@ -333,20 +333,19 @@ class FastaParserTestCase extends Object
|
|||
@override
|
||||
FormalParameter parseFormalParameter(String code, ParameterKind kind,
|
||||
{List<ErrorCode> errorCodes: const <ErrorCode>[]}) {
|
||||
fasta.FormalParameterType type;
|
||||
String parametersCode;
|
||||
if (kind == ParameterKind.REQUIRED) {
|
||||
type = fasta.FormalParameterType.REQUIRED;
|
||||
parametersCode = '($code)';
|
||||
} else if (kind == ParameterKind.POSITIONAL) {
|
||||
type = fasta.FormalParameterType.POSITIONAL;
|
||||
parametersCode = '([$code])';
|
||||
} else if (kind == ParameterKind.NAMED) {
|
||||
type = fasta.FormalParameterType.NAMED;
|
||||
parametersCode = '({$code})';
|
||||
} else {
|
||||
fail('$kind');
|
||||
}
|
||||
return _runParser(
|
||||
code,
|
||||
(parser) => (token) => parser.parseFormalParameter(token, type),
|
||||
errorCodes) as FormalParameter;
|
||||
FormalParameterList list = parseFormalParameterList(parametersCode,
|
||||
inFunctionType: false, errorCodes: errorCodes);
|
||||
return list.parameters.single;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -496,34 +495,6 @@ class FormalParameterParserTest_Fasta extends FastaParserTestCase
|
|||
super.test_parseFormalParameter_covariant_var_positional();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_final_named() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_final_named();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_final_positional() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_final_positional();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_final_type_named() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_final_type_named();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_final_type_positional() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_final_type_positional();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_type_function() {
|
||||
|
@ -531,34 +502,6 @@ class FormalParameterParserTest_Fasta extends FastaParserTestCase
|
|||
super.test_parseFormalParameter_type_function();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_type_named() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_type_named();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_type_positional() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_type_positional();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_var_named() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_var_named();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameter_var_positional() {
|
||||
// TODO(scheglov): Unhandled event: ValuedFormalParameter
|
||||
super.test_parseFormalParameter_var_positional();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseFormalParameterList_named_multiple() {
|
||||
|
|
|
@ -6,6 +6,8 @@ library dart2js.parser.node_listener;
|
|||
|
||||
import '../common.dart';
|
||||
import '../elements/elements.dart' show CompilationUnitElement;
|
||||
import 'package:front_end/src/fasta/parser/parser.dart'
|
||||
show FormalParameterType;
|
||||
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence
|
||||
show INDEX_INFO;
|
||||
import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
|
||||
|
@ -229,7 +231,7 @@ class NodeListener extends ElementListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword) {
|
||||
void endFormalParameter(Token thisKeyword, FormalParameterType kind) {
|
||||
Expression name = popNode();
|
||||
if (thisKeyword != null) {
|
||||
Identifier thisIdentifier = new Identifier(thisKeyword);
|
||||
|
@ -769,6 +771,10 @@ class NodeListener extends ElementListener {
|
|||
new NodeList.singleton(defaultValue)));
|
||||
}
|
||||
|
||||
@override
|
||||
void handleFormalParameterWithoutValue(Token token) {
|
||||
}
|
||||
|
||||
@override
|
||||
void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
|
||||
Block finallyBlock = null;
|
||||
|
|
|
@ -9,6 +9,8 @@ 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/parser/parser.dart'
|
||||
show FormalParameterType;
|
||||
import 'package:front_end/src/fasta/scanner/token.dart'
|
||||
show BeginGroupToken, Token;
|
||||
import 'package:kernel/ast.dart' show AsyncMarker;
|
||||
|
@ -42,6 +44,11 @@ class AstBuilder extends ScopeListener {
|
|||
@override
|
||||
final Uri uri;
|
||||
|
||||
/// If `true`, the first call to [handleIdentifier] should push a
|
||||
/// List<SimpleIdentifier> on the stack, and [handleQualified] should append
|
||||
/// to the list.
|
||||
var accumulateIdentifierComponents = false;
|
||||
|
||||
AstBuilder(this.library, this.member, this.elementStore, Scope scope,
|
||||
[Uri uri])
|
||||
: uri = uri ?? library.fileUri,
|
||||
|
@ -470,8 +477,26 @@ class AstBuilder extends ScopeListener {
|
|||
push(ast.throwExpression(toAnalyzerToken(throwToken), pop()));
|
||||
}
|
||||
|
||||
void endFormalParameter(Token thisKeyword) {
|
||||
@override
|
||||
void endOptionalFormalParameters(
|
||||
int count, Token beginToken, Token endToken) {
|
||||
debugEvent("OptionalFormalParameters");
|
||||
}
|
||||
|
||||
void handleValuedFormalParameter(Token equals, Token token) {
|
||||
debugEvent("ValuedFormalParameter");
|
||||
Expression value = pop();
|
||||
push(new _ParameterDefaultValue(equals, value));
|
||||
}
|
||||
|
||||
void handleFormalParameterWithoutValue(Token token) {
|
||||
debugEvent("FormalParameterWithoutValue");
|
||||
push(NullValue.ParameterDefaultValue);
|
||||
}
|
||||
|
||||
void endFormalParameter(Token thisKeyword, FormalParameterType kind) {
|
||||
debugEvent("FormalParameter");
|
||||
_ParameterDefaultValue defaultValue = pop();
|
||||
SimpleIdentifier name = pop();
|
||||
TypeName type = pop();
|
||||
Token keyword = _popOptionalSingleModifier();
|
||||
|
@ -501,6 +526,11 @@ class AstBuilder extends ScopeListener {
|
|||
formalParameters);
|
||||
}
|
||||
|
||||
if (defaultValue != null) {
|
||||
node = ast.defaultFormalParameter(node, _toAnalyzerParameterKind(kind),
|
||||
toAnalyzerToken(defaultValue.separator), defaultValue.value);
|
||||
}
|
||||
|
||||
scope[name.name] = name.staticElement = new AnalyzerParameterElement(node);
|
||||
push(node);
|
||||
}
|
||||
|
@ -1177,6 +1207,16 @@ class AstBuilder extends ScopeListener {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
ParameterKind _toAnalyzerParameterKind(FormalParameterType type) {
|
||||
if (type == FormalParameterType.POSITIONAL) {
|
||||
return ParameterKind.POSITIONAL;
|
||||
} else if (type == FormalParameterType.NAMED) {
|
||||
return ParameterKind.NAMED;
|
||||
} else {
|
||||
return ParameterKind.REQUIRED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Data structure placed on the stack to represent a class body.
|
||||
|
@ -1209,3 +1249,12 @@ class _MixinApplication {
|
|||
|
||||
_MixinApplication(this.supertype, this.withKeyword, this.mixinTypes);
|
||||
}
|
||||
|
||||
/// Data structure placed on the stack to represent the default parameter
|
||||
/// value with the separator token.
|
||||
class _ParameterDefaultValue {
|
||||
final Token separator;
|
||||
final Expression value;
|
||||
|
||||
_ParameterDefaultValue(this.separator, this.value);
|
||||
}
|
||||
|
|
|
@ -1277,7 +1277,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword) {
|
||||
void endFormalParameter(Token thisKeyword, FormalParameterType kind) {
|
||||
debugEvent("FormalParameter");
|
||||
// TODO(ahe): Need beginToken here.
|
||||
int charOffset = thisKeyword?.charOffset;
|
||||
|
@ -1363,6 +1363,11 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
push(new InitializedIdentifier(name.name, initializer));
|
||||
}
|
||||
|
||||
@override
|
||||
void handleFormalParameterWithoutValue(Token token) {
|
||||
debugEvent("FormalParameterWithoutValue");
|
||||
}
|
||||
|
||||
@override
|
||||
void endFormalParameters(int count, Token beginToken, Token endToken) {
|
||||
debugEvent("FormalParameters");
|
||||
|
|
|
@ -9,6 +9,7 @@ import '../scanner/token.dart' show BeginGroupToken, Token;
|
|||
import '../util/link.dart' show Link;
|
||||
|
||||
import 'error_kind.dart' show ErrorKind;
|
||||
import 'parser.dart' show FormalParameterType;
|
||||
|
||||
import 'identifier_context.dart' show IdentifierContext;
|
||||
|
||||
|
@ -163,7 +164,7 @@ class Listener {
|
|||
|
||||
void beginFormalParameter(Token token) {}
|
||||
|
||||
void endFormalParameter(Token thisKeyword) {
|
||||
void endFormalParameter(Token thisKeyword, FormalParameterType kind) {
|
||||
logEvent("FormalParameter");
|
||||
}
|
||||
|
||||
|
@ -901,6 +902,10 @@ class Listener {
|
|||
logEvent("ValuedFormalParameter");
|
||||
}
|
||||
|
||||
void handleFormalParameterWithoutValue(Token token) {
|
||||
logEvent("FormalParameterWithoutValue");
|
||||
}
|
||||
|
||||
void handleVoidKeyword(Token token) {
|
||||
logEvent("VoidKeyword");
|
||||
}
|
||||
|
|
|
@ -490,7 +490,7 @@ class Parser {
|
|||
return expect(')', token);
|
||||
}
|
||||
|
||||
Token parseFormalParameter(Token token, FormalParameterType type,
|
||||
Token parseFormalParameter(Token token, FormalParameterType kind,
|
||||
{bool inFunctionType: false}) {
|
||||
token = parseMetadataStar(token, forParameter: true);
|
||||
listener.beginFormalParameter(token);
|
||||
|
@ -504,7 +504,7 @@ class Parser {
|
|||
token = token.next;
|
||||
}
|
||||
token = parseModifiers(token);
|
||||
bool isNamedParameter = type == FormalParameterType.NAMED;
|
||||
bool isNamedParameter = kind == FormalParameterType.NAMED;
|
||||
|
||||
Token thisKeyword = null;
|
||||
if (inFunctionType && isNamedParameter) {
|
||||
|
@ -564,15 +564,17 @@ class Parser {
|
|||
Token equal = token;
|
||||
token = parseExpression(token.next);
|
||||
listener.handleValuedFormalParameter(equal, token);
|
||||
if (type.isRequired) {
|
||||
if (kind.isRequired) {
|
||||
reportRecoverableError(
|
||||
equal, ErrorKind.RequiredParameterWithDefault);
|
||||
} else if (type.isPositional && identical(':', value)) {
|
||||
} else if (kind.isPositional && identical(':', value)) {
|
||||
reportRecoverableError(
|
||||
equal, ErrorKind.PositionalParameterWithEquals);
|
||||
}
|
||||
} else {
|
||||
listener.handleFormalParameterWithoutValue(token);
|
||||
}
|
||||
listener.endFormalParameter(thisKeyword);
|
||||
listener.endFormalParameter(thisKeyword, kind);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ class OutlineBuilder extends UnhandledListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword) {
|
||||
void endFormalParameter(Token thisKeyword, FormalParameterType kind) {
|
||||
debugEvent("FormalParameter");
|
||||
String name = pop();
|
||||
TypeBuilder type = pop();
|
||||
|
@ -389,6 +389,12 @@ class OutlineBuilder extends UnhandledListener {
|
|||
// Ignored for now.
|
||||
}
|
||||
|
||||
@override
|
||||
void handleFormalParameterWithoutValue(Token token) {
|
||||
debugEvent("FormalParameterWithoutValue");
|
||||
// Ignored for now.
|
||||
}
|
||||
|
||||
@override
|
||||
void endFunctionTypedFormalParameter(Token token) {
|
||||
debugEvent("FunctionTypedFormalParameter");
|
||||
|
|
|
@ -35,6 +35,7 @@ enum NullValue {
|
|||
Initializers,
|
||||
Metadata,
|
||||
Modifiers,
|
||||
ParameterDefaultValue,
|
||||
SwitchScope,
|
||||
Type,
|
||||
TypeArguments,
|
||||
|
|
Loading…
Reference in a new issue