Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Unified Diff: pkg/fasta/lib/src/source/outline_builder.dart

Issue 2633663002: Fasta outline builder. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/fasta/lib/src/source/outline_builder.dart
diff --git a/pkg/fasta/lib/src/source/outline_builder.dart b/pkg/fasta/lib/src/source/outline_builder.dart
new file mode 100644
index 0000000000000000000000000000000000000000..7a51e55bc964d1f6f8dad0d835f0aee3b0cba39a
--- /dev/null
+++ b/pkg/fasta/lib/src/source/outline_builder.dart
@@ -0,0 +1,477 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.outline_builder;
+
+import 'package:kernel/ast.dart' show
+ AsyncMarker,
+ ProcedureKind;
+
+import 'package:dart_parser/src/parser.dart' show
+ FormalParameterType,
+ optional;
+
+import 'package:dart_scanner/src/token.dart' show
+ Token;
+
+import '../combinator.dart' show
+ Combinator;
+
+import '../errors.dart' show
+ internalError;
+
+import '../builder/builder.dart';
+
+import '../modifier.dart' show
+ Modifier;
+
+import 'source_library_builder.dart' show
+ SourceLibraryBuilder;
+
+import 'unhandled_listener.dart' show
+ NullValue,
+ Unhandled,
+ UnhandledListener;
+
+enum MethodBody {
+ Abstract,
+ Regular,
+ RedirectingFactoryBody,
+}
+
+AsyncMarker asyncMarkerFromTokens(Token asyncToken, Token starToken) {
+ if (asyncToken == null || identical(asyncToken.stringValue, "sync")) {
+ if (starToken == null) {
+ return AsyncMarker.Sync;
+ } else {
+ assert(identical(starToken.stringValue, "*"));
+ return AsyncMarker.SyncStar;
+ }
+ } else if (identical(asyncToken.stringValue, "async")) {
+ if (starToken == null) {
+ return AsyncMarker.Async;
+ } else {
+ assert(identical(starToken.stringValue, "*"));
+ return AsyncMarker.AsyncStar;
+ }
+ } else {
+ return internalError("Unknown async modifier: $asyncToken");
+ }
+}
+
+class OutlineBuilder extends UnhandledListener {
+ final SourceLibraryBuilder library;
+
+ OutlineBuilder(this.library);
+
+ Uri get uri => library.uri;
+
+ void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
+ debugEvent("Metadata");
+ List arguments = pop();
+ String postfix = popIfNotNull(periodBeforeName);
+ List<TypeBuilder> typeArguments = pop();
+ if (arguments == null) {
+ String expression = pop();
+ push(new MetadataBuilder.fromExpression(expression, postfix));
+ } else {
+ String typeName = pop();
+ push(new MetadataBuilder.fromConstructor(
+ library.addConstructorReference(
+ typeName, typeArguments, postfix), arguments));
+ }
+ }
+
+ void endHide(Token hideKeyword) {
+ debugEvent("Hide");
+ List<String> names = pop();
+ push(new Combinator.hide(names));
+ }
+
+ void endShow(Token showKeyword) {
+ debugEvent("Show");
+ List<String> names = pop();
+ push(new Combinator.show(names));
+ }
+
+ void endCombinators(int count) {
+ debugEvent("Combinators");
+ push(popList(count) ?? NullValue.Combinators);
+ }
+
+ void endExport(Token exportKeyword, Token semicolon) {
+ debugEvent("Export");
+ List<Combinator> combinators = pop();
+ Unhandled conditionalUris = pop();
+ String uri = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addExport(metadata, uri, conditionalUris, combinators);
+ checkEmpty();
+ }
+
+ void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
+ Token semicolon) {
+ debugEvent("endImport");
+ List<Combinator> combinators = pop();
+ String prefix = popIfNotNull(asKeyword);
+ Unhandled conditionalUris = pop();
+ String uri = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addImport(metadata, uri, conditionalUris, prefix, combinators,
+ deferredKeyword != null);
+ checkEmpty();
+ }
+
+ void endPart(Token partKeyword, Token semicolon) {
+ debugEvent("Part");
+ String uri = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addPart(metadata, uri);
+ checkEmpty();
+ }
+
+ void handleOperatorName(Token operatorKeyword, Token token) {
+ debugEvent("OperatorName");
+ push(token.stringValue);
+ }
+
+ void endIdentifierList(int count) {
+ debugEvent("endIdentifierList");
+ push(popList(count) ?? NullValue.IdentifierList);
+ }
+
+ void handleQualified(Token period) {
+ debugEvent("handleQualified");
+ String name = pop();
+ String receiver = pop();
+ push("$receiver.$name");
+ }
+
+ void endLibraryName(Token libraryKeyword, Token semicolon) {
+ debugEvent("endLibraryName");
+ String name = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.name = name;
+ library.metadata = metadata;
+ }
+
+ void beginClassDeclaration(Token token) {
+ library.beginNestedScope();
+ }
+
+ void endClassDeclaration(int interfacesCount, Token beginToken,
+ Token extendsKeyword, Token implementsKeyword, Token endToken) {
+ debugEvent("endClassDeclaration");
+ List<TypeBuilder> interfaces = popList(interfacesCount);
+ TypeBuilder supertype = pop();
+ List<TypeVariableBuilder> typeVariables = pop();
+ String name = pop();
+ int modifiers = Modifier.validate(pop());
+ List<MetadataBuilder> metadata = pop();
+ library.addClass(
+ metadata, modifiers, name, typeVariables, supertype, interfaces);
+ checkEmpty();
+ }
+
+ ProcedureKind computeProcedureKind(Token token) {
+ if (token == null) return ProcedureKind.Method;
+ if (optional("get", token)) return ProcedureKind.Getter;
+ if (optional("set", token)) return ProcedureKind.Setter;
+ return internalError("Unhandled: ${token.value}");
+ }
+
+ ProcedureBuilder endTopLevelMethod(
+ Token beginToken, Token getOrSet, Token endToken) {
+ debugEvent("endTopLevelMethod");
+ MethodBody kind = pop();
+ AsyncMarker asyncModifier = pop();
+ List<FormalParameterBuilder> formals = pop();
+ List<TypeVariableBuilder> typeVariables = pop();
+ String name = pop();
+ TypeBuilder returnType = pop();
+ int modifiers = Modifier.validate(pop(),
+ isAbstract: kind == MethodBody.Abstract);
+ List<MetadataBuilder> metadata = pop();
+ checkEmpty();
+ return library.addProcedure(metadata, modifiers, returnType, name,
+ typeVariables, formals, asyncModifier, computeProcedureKind(getOrSet));
+ }
+
+ void handleNoFunctionBody(Token token) {
+ debugEvent("NoFunctionBody");
+ push(MethodBody.Abstract);
+ }
+
+ void skippedFunctionBody(Token token) {
+ debugEvent("skippedFunctionBody");
+ push(MethodBody.Regular);
+ }
+
+ void endMethod(Token getOrSet, Token beginToken, Token endToken) {
+ debugEvent("Method");
+ MethodBody kind = pop();
+ if (kind == MethodBody.RedirectingFactoryBody) {
+ // This will cause an error later.
+ pop();
+ }
+ AsyncMarker asyncModifier = pop();
+ List<FormalParameterBuilder> formals = pop();
+ List<TypeVariableBuilder> typeVariables = pop();
+ String name = pop();
+ if (identical("-", name) && formals == null) {
+ name = "unary-";
+ }
+ TypeBuilder returnType = pop();
+ int modifiers = Modifier.validate(pop(),
+ isAbstract: kind == MethodBody.Abstract);
+ List<MetadataBuilder> metadata = pop();
+ library.addProcedure(metadata, modifiers, returnType, name, typeVariables,
+ formals, asyncModifier, computeProcedureKind(getOrSet));
+ }
+
+ void endMixinApplication() {
+ debugEvent("MixinApplication");
+ List<TypeBuilder> mixins = pop();
+ TypeBuilder supertype = pop();
+ push(library.addMixinApplication(supertype, mixins));
+ }
+
+ void beginNamedMixinApplication(Token token) {
+ library.beginNestedScope();
+ }
+
+ void endNamedMixinApplication(
+ Token classKeyword, Token implementsKeyword, Token endToken) {
+ debugEvent("endNamedMixinApplication");
+ List<TypeBuilder> interfaces = popIfNotNull(implementsKeyword);
+ TypeBuilder mixinApplication = pop();
+ int modifiers = Modifier.validate(pop());
+ List<TypeVariableBuilder> typeVariables = pop();
+ String name = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addNamedMixinApplication(
+ metadata, name, typeVariables, modifiers, mixinApplication, interfaces);
+ checkEmpty();
+ }
+
+ void endTypeArguments(int count, Token beginToken, Token endToken) {
+ debugEvent("TypeArguments");
+ push(popList(count) ?? NullValue.TypeArguments);
+ }
+
+ void endType(Token beginToken, Token endToken) {
+ debugEvent("Type");
+ List<TypeBuilder> arguments = pop();
+ String name = pop();
+ push(library.addInterfaceType(name, arguments));
+ }
+
+ void endTypeList(int count) {
+ debugEvent("TypeList");
+ push(popList(count) ?? NullValue.TypeList);
+ }
+
+ void endTypeVariables(int count, Token beginToken, Token endToken) {
+ debugEvent("TypeVariables");
+ push(popList(count) ?? NullValue.TypeVariables);
+ }
+
+ void handleVoidKeyword(Token token) {
+ debugEvent("VoidKeyword");
+ push(library.addVoidType());
+ }
+
+ void endFormalParameter(Token thisKeyword) {
+ debugEvent("FormalParameter");
+ String name = pop();
+ TypeBuilder type = pop();
+ int modifiers = Modifier.validate(pop());
+ List<MetadataBuilder> metadata = pop();
+ push(library.addFormalParameter(metadata, modifiers, type, name,
+ thisKeyword != null));
+ }
+
+ void handleValuedFormalParameter(Token equals, Token token) {
+ debugEvent("ValuedFormalParameter");
+ // Ignored for now.
+ }
+
+ void handleFunctionTypedFormalParameter(Token token) {
+ debugEvent("FunctionTypedFormalParameter");
+ pop(); // Function type parameters.
+ pop(); // Type variables.
+ String name = pop();
+ pop(); // Return type.
+ push(NullValue.Type);
+ push(name);
+ }
+
+ void endOptionalFormalParameters(
+ int count, Token beginToken, Token endToken) {
+ debugEvent("OptionalFormalParameters");
+ FormalParameterType kind = optional("{", beginToken)
+ ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
+ List parameters = popList(count);
+ for (FormalParameterBuilder parameter in parameters) {
+ parameter.kind = kind;
+ }
+ push(parameters);
+ }
+
+ void endFormalParameters(int count, Token beginToken, Token endToken) {
+ debugEvent("FormalParameters");
+ List formals = popList(count);
+ if (formals != null && formals.isNotEmpty) {
+ var last = formals.last;
+ if (last is List) {
+ var newList =
+ new List<FormalParameterBuilder>(formals.length - 1 + last.length);
+ newList.setRange(0, formals.length - 1, formals);
+ newList.setRange(formals.length - 1, newList.length, last);
+ for (int i = 0; i < last.length; i++) {
+ newList[i + formals.length - 1] = last[i];
+ }
+ formals = newList;
+ }
+ }
+ if (formals != null) {
+ for (var formal in formals) {
+ if (formal is! FormalParameterBuilder) {
+ internalError(formals);
+ }
+ }
+ formals = new List<FormalParameterBuilder>.from(formals);
+ }
+ push(formals ?? NullValue.FormalParameters);
+ }
+
+ void endEnum(Token enumKeyword, Token endBrace, int count) {
+ List<String> constants = popList(count);
+ String name = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addEnum(metadata, name, constants);
+ checkEmpty();
+ }
+
+ void beginFunctionTypeAlias(Token token) {
+ library.beginNestedScope();
+ }
+
+ void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
+ debugEvent("endFunctionTypeAlias");
+ List<FormalParameterBuilder> formals = pop();
+ List<TypeVariableBuilder> typeVariables = pop();
+ String name = pop();
+ TypeBuilder returnType = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addFunctionTypeAlias(
+ metadata, returnType, name, typeVariables, formals);
+ checkEmpty();
+ }
+
+ void endTopLevelFields(int count, Token beginToken, Token endToken) {
+ debugEvent("endTopLevelFields");
+ List<String> names = popList(count);
+ TypeBuilder type = pop();
+ int modifiers = Modifier.validate(pop());
+ List<MetadataBuilder> metadata = pop();
+ library.addFields(metadata, modifiers, type, names);
+ checkEmpty();
+ }
+
+ void endFields(int count, Token beginToken, Token endToken) {
+ debugEvent("Fields");
+ List<String> names = popList(count);
+ TypeBuilder type = pop();
+ int modifiers = Modifier.validate(pop());
+ List<MetadataBuilder> metadata = pop();
+ library.addFields(metadata, modifiers, type, names);
+ }
+
+ void endTypeVariable(Token token, Token extendsOrSuper) {
+ debugEvent("endTypeVariable");
+ TypeBuilder bound = pop();
+ String name = pop();
+ push(library.addTypeVariable(name, bound));
+ }
+
+ void endPartOf(Token partKeyword, Token semicolon) {
+ debugEvent("endPartOf");
+ String name = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addPartOf(metadata, name);
+ }
+
+ void endConstructorReference(
+ Token start, Token periodBeforeName, Token endToken) {
+ debugEvent("ConstructorReference");
+ String suffix = popIfNotNull(periodBeforeName);
+ List<TypeBuilder> typeArguments = pop();
+ String name = pop();
+ push(library.addConstructorReference(name, typeArguments, suffix));
+ }
+
+ void endFactoryMethod(Token beginToken, Token endToken) {
+ debugEvent("FactoryMethod");
+ MethodBody kind = pop();
+ ConstructorReferenceBuilder redirectionTarget;
+ if (kind == MethodBody.RedirectingFactoryBody) {
+ redirectionTarget = pop();
+ }
+ AsyncMarker asyncModifier = pop();
+ List<FormalParameterBuilder> formals = pop();
+ var name = pop();
+ List<MetadataBuilder> metadata = pop();
+ library.addFactoryMethod(metadata, name, formals, asyncModifier,
+ redirectionTarget);
+ }
+
+ void endRedirectingFactoryBody(Token beginToken, Token endToken) {
+ debugEvent("RedirectingFactoryBody");
+ push(MethodBody.RedirectingFactoryBody);
+ }
+
+ void endInitializer(Token assignmentOperator) {
+ debugEvent("Initializer");
+ // This is a variable initializer and it's ignored for now. May also be
+ // constructor initializer.
+ }
+
+ void endInitializers(int count, Token beginToken, Token endToken) {
+ debugEvent("Initializers");
+ // Ignored for now.
+ }
+
+ void handleNoInitializers() {
+ debugEvent("NoInitializers");
+ // This is a constructor initializer and it's ignored for now.
+ }
+
+ void endMember() {
+ debugEvent("Member");
+ }
+
+ void endClassBody(int memberCount, Token beginToken, Token endToken) {
+ debugEvent("ClassBody");
+ }
+
+ void handleAsyncModifier(Token asyncToken, Token starToken) {
+ debugEvent("AsyncModifier");
+ push(asyncMarkerFromTokens(asyncToken, starToken));
+ }
+
+ void handleModifier(Token token) {
+ debugEvent("Modifier");
+ push(new Modifier.fromString(token.stringValue));
+ }
+
+ void handleModifiers(int count) {
+ debugEvent("Modifiers");
+ push(popList(count) ?? NullValue.Modifiers);
+ }
+
+ void debugEvent(String name) {
+ // printEvent(name);
+ }
+}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698