Skip to content

Commit

Permalink
Let parser handle factory modifiers.
Browse files Browse the repository at this point in the history
R=johnniwinther@google.com

Review-Url: https://codereview.chromium.org/2721623002 .
  • Loading branch information
peter-ahe-google committed Mar 1, 2017
1 parent ea4a89b commit bb72d5e
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 40 deletions.
23 changes: 8 additions & 15 deletions pkg/compiler/lib/src/parser/node_listener.dart
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,8 @@ class NodeListener extends ElementListener {
typeParameters = functionType.typeParameters;
formals = functionType.formals;
}
pushNode(new Typedef(
isGeneralizedTypeAlias,
templateParameters,
returnType,
name,
typeParameters,
formals,
typedefKeyword,
endToken));
pushNode(new Typedef(isGeneralizedTypeAlias, templateParameters, returnType,
name, typeParameters, formals, typedefKeyword, endToken));
}

void handleNoName(Token token) {
Expand Down Expand Up @@ -234,8 +227,8 @@ class NodeListener extends ElementListener {
}

@override
void endFormalParameter(Token covariantKeyword, Token thisKeyword,
FormalParameterType kind) {
void endFormalParameter(
Token covariantKeyword, Token thisKeyword, FormalParameterType kind) {
Expression name = popNode();
if (thisKeyword != null) {
Identifier thisIdentifier = new Identifier(thisKeyword);
Expand Down Expand Up @@ -757,8 +750,8 @@ class NodeListener extends ElementListener {
}

@override
void endFunctionTypedFormalParameter(Token covariantKeyword,
Token thisKeyword, FormalParameterType kind) {
void endFunctionTypedFormalParameter(
Token covariantKeyword, Token thisKeyword, FormalParameterType kind) {
NodeList formals = popNode();
NodeList typeVariables = popNode();
Identifier name = popNode();
Expand All @@ -777,8 +770,7 @@ class NodeListener extends ElementListener {
}

@override
void handleFormalParameterWithoutValue(Token token) {
}
void handleFormalParameterWithoutValue(Token token) {}

@override
void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
Expand Down Expand Up @@ -865,6 +857,7 @@ class NodeListener extends ElementListener {
AsyncModifier asyncModifier = popNode();
NodeList formals = popNode();
Node name = popNode();
popNode(); // Discard modifiers. They're recomputed below.

// TODO(ahe): Move this parsing to the parser.
int modifierCount = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ class KernelLibraryBuilder

void addFactoryMethod(
List<MetadataBuilder> metadata,
int modifiers,
ConstructorReferenceBuilder constructorName,
List<FormalParameterBuilder> formals,
AsyncMarker asyncModifier,
Expand All @@ -216,7 +217,7 @@ class KernelLibraryBuilder
assert(constructorName.suffix == null);
KernelProcedureBuilder procedure = new KernelProcedureBuilder(
metadata,
staticMask,
staticMask | modifiers,
null,
name,
<TypeVariableBuilder>[],
Expand Down
51 changes: 48 additions & 3 deletions pkg/front_end/lib/src/fasta/kernel/verifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,46 @@

library fasta.verifier;

import 'package:kernel/ast.dart' show ExpressionStatement, Program;
import 'package:kernel/ast.dart'
show
Class,
ExpressionStatement,
Field,
Library,
Procedure,
Program,
TreeNode;

import 'package:kernel/verifier.dart' show VerifyingVisitor;
import 'package:kernel/verifier.dart' show VerificationError, VerifyingVisitor;

import '../errors.dart' show printUnexpected;

import 'redirecting_factory_body.dart' show RedirectingFactoryBody;

void verifyProgram(Program program, {bool isOutline: false}) {
program.accept(new FastaVerifyingVisitor(isOutline));
FastaVerifyingVisitor verifier = new FastaVerifyingVisitor(isOutline);
program.accept(verifier);
if (verifier.errors.isNotEmpty) {
throw verifier.errors.first;
}
}

class FastaVerifyingVisitor extends VerifyingVisitor {
final List<VerificationError> errors = <VerificationError>[];

String fileUri;

FastaVerifyingVisitor(bool isOutline) {
this.isOutline = isOutline;
}

@override
problem(TreeNode node, String details) {
VerificationError error = new VerificationError(context, node, details);
printUnexpected(Uri.parse(fileUri), node.fileOffset, "$error");
errors.add(error);
}

@override
visitExpressionStatement(ExpressionStatement node) {
// Bypass verification of the [StaticGet] in [RedirectingFactoryBody] as
Expand All @@ -27,4 +52,24 @@ class FastaVerifyingVisitor extends VerifyingVisitor {
super.visitExpressionStatement(node);
}
}

visitLibrary(Library node) {
fileUri = node.fileUri;
super.visitLibrary(node);
}

visitClass(Class node) {
fileUri = node.fileUri;
super.visitClass(node);
}

visitField(Field node) {
fileUri = node.fileUri;
super.visitField(node);
}

visitProcedure(Procedure node) {
fileUri = node.fileUri;
super.visitProcedure(node);
}
}
20 changes: 11 additions & 9 deletions pkg/front_end/lib/src/fasta/parser/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1816,24 +1816,26 @@ class Parser {
Token parseFactoryMethod(Token token) {
assert(isFactoryDeclaration(token));
Token start = token;
Token externalModifier;
if (identical(token.stringValue, 'external')) {
externalModifier = token;
token = token.next;
}
if (optional('const', token)) {
token = token.next; // Skip const.
bool isExternal = false;
int modifierCount = 0;
while (isModifier(token)) {
if (optional('external', token)) {
isExternal = true;
}
token = parseModifier(token);
modifierCount++;
}
listener.handleModifiers(modifierCount);
Token factoryKeyword = token;
listener.beginFactoryMethod(factoryKeyword);
token = token.next; // Skip 'factory'.
token = expect('factory', token);
token = parseConstructorReference(token);
token = parseFormalParameters(token);
token = parseAsyncModifier(token);
if (optional('=', token)) {
token = parseRedirectingFactoryBody(token);
} else {
token = parseFunctionBody(token, false, externalModifier != null);
token = parseFunctionBody(token, false, isExternal);
}
listener.endFactoryMethod(start, token);
return token.next;
Expand Down
3 changes: 2 additions & 1 deletion pkg/front_end/lib/src/fasta/source/outline_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -543,8 +543,9 @@ class OutlineBuilder extends UnhandledListener {
AsyncMarker asyncModifier = pop();
List<FormalParameterBuilder> formals = pop();
var name = pop();
int modifiers = Modifier.validate(pop());
List<MetadataBuilder> metadata = pop();
library.addFactoryMethod(metadata, name, formals, asyncModifier,
library.addFactoryMethod(metadata, modifiers, name, formals, asyncModifier,
redirectionTarget, beginToken.charOffset, nativeMethodName);
nativeMethodName = null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>

void addFactoryMethod(
List<MetadataBuilder> metadata,
int modifiers,
ConstructorReferenceBuilder name,
List<FormalParameterBuilder> formals,
AsyncMarker asyncModifier,
Expand Down
20 changes: 9 additions & 11 deletions pkg/front_end/test/fasta/bootstrap_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,27 @@ Future main() async {
Uri sourceCompiler = await Isolate.resolvePackageUri(
Uri.parse("package:front_end/src/fasta/bin/compile.dart"));
Uri packages = await Isolate.packageConfig;
Directory tmp = await Directory.systemTemp.createTemp("fasta_bootstrap");
Uri compiledOnceOutput = tmp.uri.resolve("fasta1.dill");
Uri compiledTwiceOutput = tmp.uri.resolve("fasta2.dill");
try {
Directory tmp = await Directory.systemTemp.createTemp("fasta_bootstrap");
Uri compiledOnceOutput = tmp.uri.resolve("fasta1.dill");
Uri compiledTwiceOutput = tmp.uri.resolve("fasta2.dill");
try {
await runCompiler(sourceCompiler, sourceCompiler, compiledOnceOutput);
await runCompiler(
compiledOnceOutput, sourceCompiler, compiledTwiceOutput);
} finally {
await tmp.delete(recursive: true);
}
await runCompiler(sourceCompiler, sourceCompiler, compiledOnceOutput);
await runCompiler(compiledOnceOutput, sourceCompiler, compiledTwiceOutput);
} finally {
asyncEnd();
await tmp.delete(recursive: true);
}
asyncEnd();
}

Future runCompiler(Uri compiler, Uri input, Uri output) async {
Uri patchedSdk = await computePatchedSdk();
Uri dartVm = Uri.base.resolve(Platform.resolvedExecutable);
StdioProcess result = await StdioProcess.run(dartVm.toFilePath(), <String>[
"-c",
compiler.toFilePath(),
"--compile-sdk=${patchedSdk.toFilePath()}",
"--output=${output.toFilePath()}",
"--verify",
input.toFilePath(),
]);
print(result.output);
Expand Down

0 comments on commit bb72d5e

Please sign in to comment.