mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 09:01:42 +00:00
Fix parsing [a]sync[*] function body modifiers with Fasta.
The Fasta'a parser is crazy as it is now. It says that something is a return statement, but it is actually an expression function body. That seems too much dart2js specific. R=paulberry@google.com, ahe@google.com BUG= Review-Url: https://codereview.chromium.org/2728773002 .
This commit is contained in:
parent
b17f4b2b5d
commit
ce58e89d3c
|
@ -57,13 +57,6 @@ class ClassMemberParserTest_Fasta extends FastaParserTestCase
|
|||
super.test_constFactory();
|
||||
}
|
||||
|
||||
@override
|
||||
@assertFailingTest
|
||||
void test_parseAwaitExpression_asStatement_inAsync() {
|
||||
// TODO(paulberry): Add support for async
|
||||
super.test_parseAwaitExpression_asStatement_inAsync();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseClassMember_constructor_withInitializers() {
|
||||
|
@ -459,24 +452,6 @@ class ExpressionParserTest_Fasta extends FastaParserTestCase
|
|||
super.test_parseExpression_assign_compound();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseExpression_function_async() {
|
||||
super.test_parseExpression_function_async();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseExpression_function_asyncStar() {
|
||||
super.test_parseExpression_function_asyncStar();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseExpression_function_syncStar() {
|
||||
super.test_parseExpression_function_syncStar();
|
||||
}
|
||||
|
||||
@override
|
||||
@failingTest
|
||||
void test_parseExpression_superMethodInvocation_typeArgumentComments() {
|
||||
|
|
|
@ -302,6 +302,10 @@ class NodeListener extends ElementListener {
|
|||
pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
|
||||
}
|
||||
|
||||
void endExpressionFunctionBody(Token arrowToken, Token endToken) {
|
||||
endReturnStatement(true, arrowToken, endToken);
|
||||
}
|
||||
|
||||
@override
|
||||
void endReturnStatement(
|
||||
bool hasExpression, Token beginToken, Token endToken) {
|
||||
|
|
|
@ -13,14 +13,12 @@ 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;
|
||||
|
||||
import '../errors.dart' show internalError;
|
||||
import '../kernel/kernel_builder.dart'
|
||||
show Builder, KernelLibraryBuilder, ProcedureBuilder;
|
||||
import '../parser/identifier_context.dart' show IdentifierContext;
|
||||
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;
|
||||
|
@ -222,13 +220,22 @@ class AstBuilder extends ScopeListener {
|
|||
if (beginToken != null) {
|
||||
exitLocalScope();
|
||||
}
|
||||
push(ast.block(
|
||||
toAnalyzerToken(beginToken), statements, toAnalyzerToken(endToken)));
|
||||
Block block = ast.block(
|
||||
toAnalyzerToken(beginToken), statements, toAnalyzerToken(endToken));
|
||||
analyzer.Token star = pop();
|
||||
analyzer.Token asyncKeyword = pop();
|
||||
push(ast.blockFunctionBody(asyncKeyword, star, block));
|
||||
}
|
||||
|
||||
void finishFunction(formals, asyncModifier, Statement body) {
|
||||
void finishFunction(formals, asyncModifier, FunctionBody body) {
|
||||
debugEvent("finishFunction");
|
||||
var kernel = toKernel(body, elementStore, library.library, scope);
|
||||
Statement bodyStatement;
|
||||
if (body is ExpressionFunctionBody) {
|
||||
bodyStatement = ast.returnStatement(null, body.expression, null);
|
||||
} else {
|
||||
bodyStatement = (body as BlockFunctionBody).block;
|
||||
}
|
||||
var kernel = toKernel(bodyStatement, elementStore, library.library, scope);
|
||||
if (member is ProcedureBuilder) {
|
||||
ProcedureBuilder builder = member;
|
||||
builder.body = kernel;
|
||||
|
@ -299,6 +306,16 @@ class AstBuilder extends ScopeListener {
|
|||
push(ast.integerLiteral(toAnalyzerToken(token), int.parse(token.value)));
|
||||
}
|
||||
|
||||
void endExpressionFunctionBody(Token arrowToken, Token endToken) {
|
||||
debugEvent("ExpressionFunctionBody");
|
||||
Expression expression = pop();
|
||||
analyzer.Token star = pop();
|
||||
analyzer.Token asyncKeyword = pop();
|
||||
assert(star == null);
|
||||
push(ast.expressionFunctionBody(asyncKeyword, toAnalyzerToken(arrowToken),
|
||||
expression, toAnalyzerToken(endToken)));
|
||||
}
|
||||
|
||||
void endReturnStatement(
|
||||
bool hasExpression, Token beginToken, Token endToken) {
|
||||
debugEvent("ReturnStatement");
|
||||
|
@ -430,7 +447,8 @@ class AstBuilder extends ScopeListener {
|
|||
|
||||
void handleAsyncModifier(Token asyncToken, Token starToken) {
|
||||
debugEvent("AsyncModifier");
|
||||
push(asyncMarkerFromTokens(asyncToken, starToken));
|
||||
push(toAnalyzerToken(asyncToken) ?? NullValue.FunctionBodyAsyncToken);
|
||||
push(toAnalyzerToken(starToken) ?? NullValue.FunctionBodyStarToken);
|
||||
}
|
||||
|
||||
void endAwaitExpression(Token beginToken, Token endToken) {
|
||||
|
@ -766,31 +784,11 @@ class AstBuilder extends ScopeListener {
|
|||
}
|
||||
}
|
||||
|
||||
FunctionBody _endFunctionBody() {
|
||||
AstNode body = pop();
|
||||
// TODO(paulberry): asyncMarker should have a type that allows constructing
|
||||
// the necessary analyzer AST data structures.
|
||||
AsyncMarker asyncMarker = pop();
|
||||
assert(asyncMarker == AsyncMarker.Sync);
|
||||
analyzer.Token asyncKeyword = null;
|
||||
analyzer.Token star = null;
|
||||
if (body is Block) {
|
||||
return ast.blockFunctionBody(asyncKeyword, star, body);
|
||||
} else if (body is ReturnStatement) {
|
||||
assert(star == null);
|
||||
return ast.expressionFunctionBody(
|
||||
asyncKeyword, body.returnKeyword, body.expression, body.semicolon);
|
||||
} else {
|
||||
return internalError(
|
||||
'Unexpected function body type: ${body.runtimeType}');
|
||||
}
|
||||
}
|
||||
|
||||
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
|
||||
// TODO(paulberry): set up scopes properly to resolve parameters and type
|
||||
// variables.
|
||||
debugEvent("TopLevelMethod");
|
||||
FunctionBody body = _endFunctionBody();
|
||||
FunctionBody body = pop();
|
||||
FormalParameterList parameters = pop();
|
||||
TypeParameterList typeParameters = pop();
|
||||
SimpleIdentifier name = pop();
|
||||
|
@ -1115,7 +1113,7 @@ class AstBuilder extends ScopeListener {
|
|||
// in constructors, so the logic should be shared with BodyBuilder as much
|
||||
// as possible.
|
||||
debugEvent("UnnamedFunction");
|
||||
var body = _endFunctionBody();
|
||||
FunctionBody body = pop();
|
||||
FormalParameterList parameters = pop();
|
||||
TypeParameterList typeParameters = pop();
|
||||
push(ast.functionExpression(typeParameters, parameters, body));
|
||||
|
@ -1178,7 +1176,7 @@ class AstBuilder extends ScopeListener {
|
|||
@override
|
||||
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
|
||||
debugEvent("Method");
|
||||
FunctionBody body = _endFunctionBody();
|
||||
FunctionBody body = pop();
|
||||
ConstructorName redirectedConstructor = null; // TODO(paulberry)
|
||||
List<ConstructorInitializer> initializers = null; // TODO(paulberry)
|
||||
Token separator = null; // TODO(paulberry)
|
||||
|
|
|
@ -841,6 +841,12 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
|
|||
push(new IntLiteral(int.parse(token.value)));
|
||||
}
|
||||
|
||||
@override
|
||||
void endExpressionFunctionBody(Token arrowToken, Token endToken) {
|
||||
debugEvent("ExpressionFunctionBody");
|
||||
endReturnStatement(true, arrowToken, endToken);
|
||||
}
|
||||
|
||||
@override
|
||||
void endReturnStatement(
|
||||
bool hasExpression, Token beginToken, Token endToken) {
|
||||
|
|
|
@ -551,6 +551,10 @@ class Listener {
|
|||
|
||||
void beginReturnStatement(Token token) {}
|
||||
|
||||
void endExpressionFunctionBody(Token arrowToken, Token endToken) {
|
||||
logEvent("ExpressionFunctionBody");
|
||||
}
|
||||
|
||||
void endReturnStatement(
|
||||
bool hasExpression, Token beginToken, Token endToken) {
|
||||
logEvent("ReturnStatement");
|
||||
|
|
|
@ -2016,9 +2016,9 @@ class Parser {
|
|||
token = parseExpression(token.next);
|
||||
if (!isExpression) {
|
||||
expectSemicolon(token);
|
||||
listener.endReturnStatement(true, begin, token);
|
||||
listener.endExpressionFunctionBody(begin, token);
|
||||
} else {
|
||||
listener.endReturnStatement(true, begin, null);
|
||||
listener.endExpressionFunctionBody(begin, null);
|
||||
}
|
||||
return token;
|
||||
} else if (optional('=', token)) {
|
||||
|
@ -2028,9 +2028,9 @@ class Parser {
|
|||
token = parseExpression(token.next);
|
||||
if (!isExpression) {
|
||||
expectSemicolon(token);
|
||||
listener.endReturnStatement(true, begin, token);
|
||||
listener.endExpressionFunctionBody(begin, token);
|
||||
} else {
|
||||
listener.endReturnStatement(true, begin, null);
|
||||
listener.endExpressionFunctionBody(begin, null);
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
|
|
@ -496,7 +496,8 @@ class DietListener extends StackListener {
|
|||
listener.prepareInitializers();
|
||||
token = parser.parseInitializersOpt(token);
|
||||
token = parser.parseAsyncModifier(token);
|
||||
AsyncMarker asyncModifier = listener.pop();
|
||||
AsyncMarker asyncModifier =
|
||||
astKind == AstKind.Analyzer ? null : listener.pop();
|
||||
bool isExpression = false;
|
||||
bool allowAbstract = true;
|
||||
parser.parseFunctionBody(token, isExpression, allowAbstract);
|
||||
|
|
|
@ -32,6 +32,8 @@ enum NullValue {
|
|||
FieldInitializer,
|
||||
FormalParameters,
|
||||
FunctionBody,
|
||||
FunctionBodyAsyncToken,
|
||||
FunctionBodyStarToken,
|
||||
IdentifierList,
|
||||
Initializers,
|
||||
Metadata,
|
||||
|
|
Loading…
Reference in a new issue