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

Unified Diff: pkg/analyzer/lib/src/summary/fasta/summary_builder.dart

Issue 2972093002: Remove code for computing summaries based on the Fasta parser. (Closed)
Patch Set: Created 3 years, 5 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
Index: pkg/analyzer/lib/src/summary/fasta/summary_builder.dart
diff --git a/pkg/analyzer/lib/src/summary/fasta/summary_builder.dart b/pkg/analyzer/lib/src/summary/fasta/summary_builder.dart
deleted file mode 100644
index 6425913c2dfb326d64cbc880578941205e5a9a29..0000000000000000000000000000000000000000
--- a/pkg/analyzer/lib/src/summary/fasta/summary_builder.dart
+++ /dev/null
@@ -1,1568 +0,0 @@
-// Copyright (c) 2017, 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.
-
-/// Logic to build unlinked summaries.
-library summary.src.summary_builder;
-
-import 'package:front_end/src/fasta/parser.dart'
- show
- ClassMemberParser,
- FormalParameterType,
- IdentifierContext,
- MemberKind,
- Parser;
-
-import 'package:front_end/src/fasta/scanner.dart' show Token, scan;
-
-import 'package:front_end/src/fasta/scanner/token_constants.dart';
-
-import 'expression_serializer.dart';
-import 'model.dart';
-import 'stack_listener.dart';
-
-const _abstract_flag = 1 << 2;
-
-const _async_flag = 1;
-
-const _const_flag = 1 << 1;
-
-const _external_flag = 1 << 4;
-
-const _final_flag = 1;
-
-/// Maps modifier names to their bit-mask.
-const _modifierFlag = const {
- 'const': _const_flag,
- 'abstract': _abstract_flag,
- 'static': _static_flag,
- 'external': _external_flag,
- 'final': _final_flag,
- 'var': _var_flag,
-};
-
-// bit-masks to encode modifiers as bits on an int.
-
-const _star_flag = 1 << 2;
-
-const _static_flag = 1 << 3;
-const _sync_flag = 1 << 1;
-const _var_flag = 0;
-
-/// Retrieve the operator from an assignment operator (e.g. + from +=).
-/// Operators are encoded using the scanner token kind id.
-int opForAssignOp(int kind) {
- switch (kind) {
- case AMPERSAND_EQ_TOKEN:
- return AMPERSAND_TOKEN;
- // TODO(paulberry): add support for &&=
- // case AMPERSAND_AMPERSAND_EQ_TOKEN: return AMPERSAND_AMPERSAND_TOKEN;
- case BAR_EQ_TOKEN:
- return BAR_TOKEN;
- // TODO(paulberry): add support for ||=
- // case BAR_BAR_EQ_TOKEN: return BAR_BAR_TOKEN;
- case CARET_EQ_TOKEN:
- return CARET_TOKEN;
- case GT_GT_EQ_TOKEN:
- return GT_GT_TOKEN;
- case LT_LT_EQ_TOKEN:
- return LT_LT_TOKEN;
- case MINUS_EQ_TOKEN:
- return MINUS_TOKEN;
- case PERCENT_EQ_TOKEN:
- return PERCENT_TOKEN;
- case PLUS_EQ_TOKEN:
- return PLUS_TOKEN;
- case QUESTION_QUESTION_EQ_TOKEN:
- return QUESTION_QUESTION_TOKEN;
- case SLASH_EQ_TOKEN:
- return SLASH_TOKEN;
- case STAR_EQ_TOKEN:
- return STAR_TOKEN;
- case TILDE_SLASH_EQ_TOKEN:
- return TILDE_SLASH_TOKEN;
- case PLUS_EQ_TOKEN:
- return PLUS_TOKEN;
- default:
- throw "Unhandled kind $kind";
- }
-}
-
-/// Create an unlinked summary given a null-terminated byte buffer with the
-/// contents of a file.
-UnlinkedUnit summarize(Uri uri, List<int> contents) {
- var listener = new SummaryBuilder(uri);
- var parser = new ClassMemberParser(listener);
- parser.parseUnit(scan(contents).tokens);
- return listener.topScope.unit;
-}
-
-/// Builder for constant expressions.
-///
-/// Any invalid subexpression is denoted with [Invalid].
-class ConstExpressionBuilder extends ExpressionListener {
- final Uri uri;
- Parser parser;
- ConstExpressionBuilder(this.uri) {
- parser = new Parser(this);
- }
- bool get forConst => true;
-
- void endArguments(int count, Token begin, Token end) {
- debugEvent("Arguments");
- if (ignore) return;
- push(popList(count) ?? const []);
- }
-
- void handleAsOperator(Token op, Token next) {
- debugEvent("As");
- if (ignore) return;
- push(new As(pop(), pop()));
- }
-
- void handleAssignmentExpression(Token operator) {
- pop(); // lhs
- pop(); // rhs
- push(new Invalid(hint: "assign"));
- }
-
- void handleIndexedExpression(
- Token openSquareBracket, Token closeSquareBracket) {
- debugEvent("Index");
- if (ignore) return;
- pop(); // receiver
- pop(); // index
- push(new Invalid(hint: "index"));
- }
-
- void handleNamedArgument(colon) {
- debugEvent("NamedArg");
- if (ignore) return;
- var value = pop();
- Ref name = pop();
- push(new NamedArg(name.name, value));
- }
-
- void endNewExpression(Token token) {
- debugEvent("NewExpression");
- if (ignore) return;
- pop(); // args
- pop(); // ctor
- push(new Invalid(hint: "new"));
- }
-
- void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
- debugEvent("NoConstructorReferenceContinuationAfterTypeArguments");
- }
-
- void handleUnaryPostfixAssignmentExpression(Token operator) {
- pop();
- push(new Invalid(hint: "postfixOp"));
- }
-
- void handleUnaryPrefixAssignmentExpression(Token operator) {
- pop();
- push(new Invalid(hint: "prefixOp"));
- }
-
- void _endFunction() {
- assert(_withinFunction >= 0);
- push(new Invalid(hint: 'function'));
- }
-
- // TODO(paulberry): is this needed?
- //void _endCascade() {
- // push(new Invalid(hint: 'cascades'));
- //}
-
- void _unhandledSend() {
- push(new Invalid(hint: "call"));
- }
-}
-
-// bit-masks to encode async modifiers as bits on an int.
-
-/// Parser listener to build simplified AST expressions.
-///
-/// The parser produces different trees depending on whether it is used for
-/// constants or initializers, so subclasses specialize the logic accordingly.
-abstract class ExpressionListener extends StackListener {
- // Underlying parser that invokes this listener.
- static const _invariantCheckToken = "invariant check: starting a function";
-
- int _withinFunction = 0;
-
- int _withinCascades = 0;
-
- /// Whether this listener is used to build const expressions.
- bool get forConst => false;
-
- /// Whether to ignore the next reduction. Used to ignore nested expressions
- /// that are either invalid (in constants) or unnecessary (for initializers).
- bool get ignore => _withinFunction > 0 || _withinCascades > 0;
-
- Parser get parser;
-
- void beginCascade(Token token) {
- _withinCascades++;
- }
-
- void beginFunctionDeclaration(token) {
- debugEvent("BeginFunctionDeclaration");
- _withinFunction++;
- }
-
- void beginLiteralString(Token token) {
- debugEvent("beginLiteralString");
- if (ignore) return;
- push(new StringLiteral(token.lexeme));
- }
-
- void beginUnnamedFunction(token) {
- debugEvent("BeginUnnamedFunction");
- var check = pop();
- assert(check == _invariantCheckToken);
- _withinFunction++;
- }
-
- UnlinkedExprBuilder computeExpression(Token token, Scope scope) {
- debugStart(token);
- parser.parseExpression(token);
- debugEvent('---- END ---');
- Expression node = pop();
- checkEmpty();
- return new Serializer(scope, forConst).run(node);
- }
-
- void debugEvent(String name) {
- if (const bool.fromEnvironment('CDEBUG', defaultValue: false)) {
- var s = stack.join(' :: ');
- if (s == '') s = '<empty>';
- var bits = '$_withinFunction,$_withinCascades';
- var prefix = ignore ? "ignore $name on:" : "do $name on:";
- prefix = '$prefix${" " * (30 - prefix.length)}';
- print('$prefix $bits $s');
- }
- }
-
- void debugStart(Token token) {
- debugEvent('\n---- START: $runtimeType ---');
- if (const bool.fromEnvironment('CDEBUG', defaultValue: false)) {
- _printExpression(token);
- }
- }
-
- void endCascade() {
- _withinCascades--;
- throw new UnimplementedError(); // TODO(paulberry): fix the code below.
- // _endCascade();
- }
-
- void endConstructorReference(
- Token start, Token periodBeforeName, Token endToken) {
- debugEvent("ConstructorReference $start $periodBeforeName");
- Ref ctorName = popIfNotNull(periodBeforeName);
- assert(ctorName?.prefix == null);
- List<TypeRef> typeArgs = pop();
- Ref type = pop();
- push(new ConstructorName(new TypeRef(type, typeArgs), ctorName?.name));
- }
-
- void endFormalParameter(Token thisKeyword, Token nameToken,
- FormalParameterType kind, MemberKind memberKind) {
- debugEvent("FormalParameter");
- assert(ignore);
- }
-
- void endFormalParameters(
- int count, Token beginToken, Token endToken, MemberKind kind) {
- debugEvent("FormalParameters");
- assert(ignore);
- }
-
- void endBlockFunctionBody(int count, Token begin, Token end) {
- debugEvent("BlockFunctionBody");
- assert(ignore);
- }
-
- void endFunctionDeclaration(token) {
- debugEvent("FunctionDeclaration");
- _withinFunction--;
- if (ignore) return;
- _endFunction();
- }
-
- void endFunctionName(Token beginToken, Token token) {
- debugEvent("FunctionName");
- assert(ignore);
- }
-
- void endLiteralMapEntry(colon, token) {
- debugEvent('MapEntry');
- if (ignore) return;
- var value = pop();
- var key = pop();
- push(new KeyValuePair(key, value));
- }
-
- void endLiteralString(int interpolationCount, Token endToken) {
- debugEvent("endLiteralString");
- if (interpolationCount != 0) {
- popList(2 * interpolationCount + 1);
- push(new StringLiteral("<interpolate $interpolationCount>"));
- }
- }
-
- void endLiteralSymbol(token, int dots) {
- debugEvent('LiteralSymbol');
- if (ignore) return;
- push(new SymbolLiteral(popList(dots).join('.')));
- }
-
- void endReturnStatement(hasValue, Token begin, Token end) {
- debugEvent("ReturnStatement");
- assert(ignore);
- }
-
- // type-arguments are expected to be type references passed to constructors
- // and generic methods, we need them to model instantiations.
- void endSend(Token beginToken, Token endToken) {
- debugEvent("EndSend");
- if (ignore) return;
- List<Expression> args = pop();
- if (args != null) {
- /* var typeArgs = */ pop();
- var receiver = pop();
- // TODO(sigmund): consider making identical a binary operator.
- if (receiver is Ref && receiver.name == 'identical') {
- assert(receiver.prefix == null);
- assert(args.length == 2);
- push(new Identical(args[0], args[1]));
- return;
- }
- _unhandledSend();
- }
- }
-
- void endThrowExpression(throwToken, token) {
- debugEvent("Throw");
- assert(ignore);
- }
-
- void endTypeArguments(int count, Token beginToken, Token endToken) {
- debugEvent("TypeArguments");
- if (ignore) return;
- push(popList(count) ?? const <TypeRef>[]);
- }
-
- void endTypeList(int count) {
- debugEvent("TypeList");
- push(popList(count) ?? const <TypeRef>[]);
- }
-
- void endTypeVariable(Token token, Token extendsOrSuper) {
- debugEvent("endTypeVariable");
- assert(ignore);
- }
-
- void endTypeVariables(int count, Token beginToken, Token endToken) {
- debugEvent("TypeVariables");
- assert(ignore);
- }
-
- void endUnnamedFunction(Token beginToken, Token token) {
- debugEvent("UnnamedFunction");
- _withinFunction--;
- if (ignore) return;
- _endFunction();
- }
-
- void handleAsyncModifier(Token asyncToken, Token starToken) {
- debugEvent("AsyncModifier");
- assert(ignore);
- }
-
- void handleBinaryExpression(Token operator) {
- debugEvent("BinaryExpression");
- if (ignore) return;
- Expression right = pop();
- Expression left = pop();
- var kind = operator.kind;
- if (kind == PERIOD_TOKEN) {
- if (left is Ref &&
- right is Ref &&
- right.prefix == null &&
- left.prefixDepth < 2) {
- push(new Ref(right.name, left));
- return;
- }
- if (right is Ref) {
- push(new Load(left, right.name));
- return;
- }
- }
- push(new Binary(left, right, kind));
- }
-
- void handleConditionalExpression(Token question, Token colon) {
- debugEvent("ConditionalExpression");
- if (ignore) return;
- var falseBranch = pop();
- var trueBranch = pop();
- var cond = pop();
- push(new Conditional(cond, trueBranch, falseBranch));
- }
-
- @override
- void endConstExpression(Token token) {
- debugEvent("ConstExpression");
- if (ignore) return;
- List args = pop();
- var constructorName = pop();
- var positional = args.where((a) => a is! NamedArg).toList();
- var named = args.where((a) => a is NamedArg).toList();
- push(new ConstCreation(constructorName, positional, named));
- }
-
- void handleIdentifier(Token token, IdentifierContext context) {
- debugEvent("Identifier");
- if (ignore) return;
- push(new Ref(token.lexeme));
- }
-
- void handleIsOperator(Token operator, Token not, Token endToken) {
- debugEvent("Is");
- if (ignore) return;
- push(new Is(pop(), pop()));
- }
-
- void handleLiteralBool(Token token) {
- debugEvent("LiteralBool");
- if (ignore) return;
- push(new BoolLiteral(token.lexeme == 'true'));
- }
-
- void handleLiteralDouble(Token token) {
- debugEvent("LiteralDouble");
- if (ignore) return;
- push(new DoubleLiteral(double.parse(token.lexeme)));
- }
-
- void handleLiteralInt(Token token) {
- debugEvent("LiteralInt");
- if (ignore) return;
- push(new IntLiteral(int.parse(token.lexeme)));
- }
-
- void handleLiteralList(count, begin, constKeyword, end) {
- debugEvent("LiteralList");
- if (ignore) return;
- var values = popList(count) ?? const <Expression>[];
- List<TypeRef> typeArguments = pop();
- var type = typeArguments?.single;
- push(new ListLiteral(type, values, constKeyword != null));
- }
-
- void handleLiteralMap(count, begin, constKeyword, end) {
- debugEvent('LiteralMap');
- if (ignore) return;
- var values = popList(count) ?? const <KeyValuePair>[];
- var typeArgs = pop() ?? const <TypeRef>[];
- push(new MapLiteral(typeArgs, values, constKeyword != null));
- }
-
- void handleLiteralNull(Token token) {
- debugEvent("LiteralNull");
- if (ignore) return;
- push(new NullLiteral());
- }
-
- void handleModifier(Token token) {
- debugEvent("Modifier");
- assert(ignore);
- }
-
- // TODO(sigmund): remove
- void handleModifiers(int count) {
- debugEvent("Modifiers");
- assert(ignore);
- }
-
- // type-variables are the declared parameters on declarations.
- void handleNoArguments(Token token) {
- debugEvent("NoArguments");
- if (ignore) return;
- var typeArguments = pop();
- assert(typeArguments == null);
- push(NullValue.Arguments);
- }
-
- void handleNoFormalParameters(Token token, MemberKind kind) {
- debugEvent("NoFormalParameters");
- assert(ignore);
- }
-
- void handleNoFunctionBody(Token token) {
- debugEvent("NoFunctionBody");
- assert(ignore);
- }
-
- void handleNoInitializer() {}
-
- void handleNoInitializers() {
- debugEvent("NoInitializers");
- assert(ignore);
- }
-
- void handleNoType(Token token) {
- debugEvent("NoType");
- if (ignore) return;
- push(NullValue.Type);
- }
-
- void handleNoTypeArguments(Token token) {
- debugEvent("NoTypeArguments");
- if (ignore) return;
- push(NullValue.TypeArguments);
- }
-
- void handleNoTypeVariables(Token token) {
- debugEvent("NoTypeVariables");
- if (ignore) return;
- push(_invariantCheckToken);
- }
-
- void handleQualified(period) {
- debugEvent('Qualified');
- if (ignore) return;
- Ref name = pop();
- Ref prefix = pop();
- assert(name.prefix == null);
- assert(prefix.prefix == null);
- push(new Ref(name.name, prefix));
- }
-
- void handleStringJuxtaposition(int count) {
- debugEvent("StringJuxtaposition");
- if (ignore) return;
- popList(count);
- push(new StringLiteral('<juxtapose $count>'));
- }
-
- void handleStringPart(token) {
- debugEvent("handleStringPart");
- if (ignore) return;
- push(new StringLiteral(token.lexeme));
- }
-
- void handleType(Token beginToken, Token endToken) {
- debugEvent("Type");
- if (ignore) return;
- List<TypeRef> arguments = pop();
- Ref name = pop();
- push(new TypeRef(name, arguments));
- }
-
- void handleUnaryPrefixExpression(Token operator) {
- debugEvent("UnaryPrefix");
- if (ignore) return;
- push(new Unary(pop(), operator.kind));
- }
-
- void handleVoidKeyword(Token token) {
- debugEvent("VoidKeyword");
- assert(ignore);
- }
-
- /// Overriden: the base class throws when something is not handled, we avoid
- /// implementing a few handlers when we know we can ignore them.
- @override
- void logEvent(e) {
- if (ignore) return;
- super.logEvent(e);
- }
-
- void push(Object o);
-
- // debug helpers
-
- void _endFunction();
-
- void _printExpression(Token token) {
- var current = token;
- var end = new ClassMemberParser(this).skipExpression(current);
- var str = new StringBuffer();
- while (current != end) {
- if (!["(", ",", ")"].contains(current.lexeme)) str.write(' ');
- str.write(current.lexeme);
- current = current.next;
- }
- print('exp: $str');
- }
-
- void _unhandledSend();
-}
-
-/// Builder for initializer expressions. These expressions exclude any nested
-/// expression that is not needed to infer strong mode types.
-class InitializerBuilder extends ExpressionListener {
- final Uri uri;
- Parser parser;
-
- int _inArguments = 0;
-
- InitializerBuilder(this.uri) {
- parser = new Parser(this);
- }
-
- bool get ignore => super.ignore || _inArguments > 0;
-
- void beginArguments(Token token) {
- // TODO(sigmund): determine if we can ignore arguments.
- //_inArguments++;
- }
-
- // Not necessary, but we don't use the value, so we can abstract it:
- void endArguments(int count, Token begin, Token end) {
- debugEvent("Arguments");
- //_inArguments--;
- if (ignore) return;
- push(popList(count) ?? const []);
- //push([new Opaque(hint: "arguments")]);
- }
-
- void handleAsOperator(Token op, Token next) {
- debugEvent("As");
- if (ignore) return;
- TypeRef type = pop();
- pop();
- push(new Opaque(type: type));
- }
-
- void handleAssignmentExpression(Token operator) {
- debugEvent("Assign");
- if (ignore) return;
- var left = pop();
- var right = pop();
- var kind = operator.kind;
- if (kind == EQ_TOKEN) {
- push(new OpaqueOp(right));
- } else {
- push(new OpaqueOp(new Binary(left, right, opForAssignOp(kind))));
- }
- }
-
- void handleIndexedExpression(
- Token openSquareBracket, Token closeSquareBracket) {
- debugEvent("Index");
- if (ignore) return;
- pop();
- pop();
- push(new Opaque());
- }
-
- void handleIsOperator(Token operator, Token not, Token endToken) {
- debugEvent("Is");
- if (ignore) return;
- throw new UnimplementedError(); // TODO(paulberry): fix the code below.
- // push(new Opaque(type: new TypeRef(new Ref('bool'))));
- }
-
- void handleNamedArgument(colon) {
- debugEvent("NamedArg");
- if (ignore) return;
- pop();
- pop();
- push(NullValue.Arguments);
- }
-
- void endNewExpression(Token token) {
- debugEvent("NewExpression");
- if (ignore) return;
- pop(); // args
- /* var ctor = */ pop(); // ctor
- throw new UnimplementedError(); // TODO(paulberry): fix the code below.
- // push(new Opaque(type: ctor.type, hint: "new"));
- }
-
- void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
- debugEvent("NoConstructorReferenceContinuationAfterTypeArguments");
- }
-
- void handleUnaryPostfixAssignmentExpression(Token operator) {
- debugEvent("PostFix");
- if (ignore) return;
- // the post-fix effect is not visible to the enclosing expression
- push(new OpaqueOp(pop()));
- }
-
- void handleUnaryPrefixAssignmentExpression(Token operator) {
- debugEvent("Prefix");
- if (ignore) return;
- var kind = operator.kind == PLUS_PLUS_TOKEN ? PLUS_TOKEN : MINUS_TOKEN;
- push(new OpaqueOp(new Binary(pop(), new IntLiteral(1), kind)));
- }
-
- void _endFunction() {
- push(new Opaque(hint: "function"));
- }
-
- // TODO(paulberry): is this needed?
- //void _endCascade() {
- // push(new OpaqueOp(pop(), hint: 'cascades'));
- //}
-
- void _unhandledSend() {
- push(new Opaque(hint: "call"));
- }
-}
-
-/// A listener of parser events that builds summary information as parsing
-/// progresses.
-class SummaryBuilder extends StackListener {
- static int parsed = 0;
-
- static int total = 0;
-
- /// Whether 'dart:core' was imported explicitly by the current unit.
- bool isDartCoreImported = false;
-
- /// Whether the current unit is part of 'dart:core'.
- bool isCoreLibrary = false;
-
- /// Topmost scope.
- TopScope topScope;
-
- /// Current scope where name references are resolved from.
- Scope scope;
-
- /// Helper to build constant expressions.
- final ConstExpressionBuilder constBuilder;
-
- /// Helper to build initializer expressions.
- final InitializerBuilder initializerBuilder;
-
- /// Whether the current initializer has a type declared.
- ///
- /// Because initializers are only used for strong-mode inference, we can skip
- /// parsing and building initializer expressions when a type is declared.
- bool typeSeen = false;
-
- /// Whether we are currently in the context of a const expression.
- bool inConstContext = false;
-
- /// Uri of the file currently being processed, used for error reporting only.
- final Uri uri;
-
- /// Summaries preassign slots for computed information, this is the next
- /// available slot.
- int _slots = 0;
-
- UnlinkedParamKind _nextParamKind;
-
- SummaryBuilder(Uri uri)
- : uri = uri,
- constBuilder = new ConstExpressionBuilder(uri),
- initializerBuilder = new InitializerBuilder(uri);
-
- /// Whether we need to parse the initializer of a declaration.
- bool get needInitializer => !typeSeen || inConstContext;
-
- // Directives: imports, exports, parts
-
- /// Assign the next slot.
- int assignSlot() => ++_slots;
-
- void beginClassDeclaration(Token beginToken, Token name) {
- debugEvent("beginClass");
- var classScope = scope = new ClassScope(scope);
- classScope.className = name.lexeme;
- }
-
- void beginCompilationUnit(Token token) {
- scope = topScope = new TopScope();
- }
-
- void beginEnum(Token token) {
- debugEvent("beginEnum");
- scope = new EnumScope(scope);
- }
-
- beginFieldInitializer(Token token) {
- debugEvent("beginFieldInitializer");
- total++;
- if (needInitializer) {
- parsed++;
- if (inConstContext) {
- push(constBuilder.computeExpression(token.next, scope));
- } else {
- push(initializerBuilder.computeExpression(token.next, scope));
- }
- }
- }
-
- void beginFormalParameters(Token token, MemberKind kind) {
- _nextParamKind = UnlinkedParamKind.required;
- }
-
- void beginFunctionTypeAlias(Token token) {
- debugEvent('beginFunctionTypeAlias');
- // TODO: use a single scope
- scope = new TypeParameterScope(scope);
- }
-
- beginInitializer(Token token) {
- // TODO(paulberry): Add support for this.
- }
-
- void beginLiteralString(Token token) {
- debugEvent("beginLiteralString");
- push(token.lexeme.substring(1, token.lexeme.length - 1));
- }
-
- void beginMember(Token token) {
- typeSeen = false;
- inConstContext = false;
- }
-
- // classes, enums, mixins, and typedefs.
-
- void beginNamedMixinApplication(Token beginToken, Token name) {
- debugEvent('beginNamedMixinApplication');
- scope = new ClassScope(scope);
- }
-
- void beginOptionalFormalParameters(Token begin) {
- _nextParamKind =
- begin == '{' ? UnlinkedParamKind.named : UnlinkedParamKind.positional;
- }
-
- void beginTopLevelMember(Token token) {
- typeSeen = false;
- inConstContext = false;
- }
-
- /// If enabled, show a debug message.
- void debugEvent(String name) {
- if (const bool.fromEnvironment('DEBUG', defaultValue: false)) {
- var s = stack.join(' :: ');
- if (s == '') s = '<empty>';
- var bits = 'type?: $typeSeen, const?: $inConstContext';
- var prefix = "do $name on:";
- prefix = '$prefix${" " * (30 - prefix.length)}';
- print('$prefix $bits $s');
- }
- }
-
- void endClassBody(int memberCount, Token beginToken, Token endToken) {
- debugEvent("ClassBody");
- }
-
- void endClassDeclaration(
- int interfacesCount,
- Token beginToken,
- Token classKeyword,
- Token extendsKeyword,
- Token implementsKeyword,
- Token endToken) {
- debugEvent("endClassDeclaration");
- List<EntityRefBuilder> interfaces = popList(interfacesCount);
- EntityRef supertype = pop();
- List<UnlinkedTypeParamBuilder> typeVariables = pop();
- String name = pop();
- int modifiers = pop();
- List metadata = pop();
- checkEmpty();
-
- ClassScope s = scope;
- s.className = name;
- s.currentClass
- ..name = name
- ..isAbstract = modifiers & _abstract_flag != 0
- ..annotations = metadata
- ..typeParameters = typeVariables
- ..interfaces = interfaces;
- if (supertype != null) {
- s.currentClass.supertype = supertype;
- } else {
- s.currentClass.hasNoSupertype = isCoreLibrary && name == 'Object';
- }
- scope = scope.parent;
- topScope.unit.classes.add(s.currentClass);
- if (_isPrivate(name)) return;
- s.publicName
- ..name = name
- ..kind = ReferenceKind.classOrEnum
- ..numTypeParameters = typeVariables?.length;
- topScope.publicNamespace.names.add(s.publicName);
- }
-
- void endCombinators(int count) {
- debugEvent("Combinators");
- push(popList(count) ?? NullValue.Combinators);
- }
-
- void endCompilationUnit(int count, Token token) {
- if (!isDartCoreImported) {
- topScope.unit.imports.add(new UnlinkedImportBuilder(isImplicit: true));
- }
-
- topScope.expandLazyReferences();
-
- // TODO(sigmund): could this be be optional: done by whoever consumes it?
- if (const bool.fromEnvironment('SKIP_API')) return;
- var apiSignature = new ApiSignature();
- topScope.unit.collectApiSignature(apiSignature);
- topScope.unit.apiSignature = apiSignature.toByteList();
- }
-
- void endConditionalUri(Token ifKeyword, Token equalitySign) {
- String dottedName = pop();
- String value = pop();
- String uri = pop();
- uri = uri.substring(1, uri.length - 1);
- push(new UnlinkedConfigurationBuilder(
- name: dottedName, value: value, uri: uri));
- }
-
- void endConditionalUris(int count) {
- push(popList(count) ?? const <UnlinkedConfigurationBuilder>[]);
- }
-
- // members: fields, methods.
-
- void endConstructorReference(
- Token start, Token periodBeforeName, Token endToken) {
- var ctorName = popIfNotNull(periodBeforeName);
- var typeArguments = pop();
- var className = pop();
- push(['ctor-ref:', className, typeArguments, ctorName]);
- }
-
- void endDottedName(count, firstIdentifier) {
- push(popList(count).join('.'));
- }
-
- void endEnum(Token enumKeyword, Token endBrace, int count) {
- debugEvent("Enum");
- List<String> constants = popList(count);
- String name = pop();
- List metadata = pop();
- checkEmpty();
- EnumScope s = scope;
- scope = s.parent;
- s.currentEnum
- ..name = name
- ..annotations = metadata;
- s.top.unit.enums.add(s.currentEnum);
-
- // public namespace:
- var e = new UnlinkedPublicNameBuilder(
- name: name, kind: ReferenceKind.classOrEnum, numTypeParameters: 0);
- for (var s in constants) {
- e.members.add(new UnlinkedPublicNameBuilder(
- name: s, kind: ReferenceKind.propertyAccessor, numTypeParameters: 0));
- }
- topScope.publicNamespace.names.add(e);
- }
-
- void endExport(Token exportKeyword, Token semicolon) {
- debugEvent("Export");
- List<UnlinkedCombinator> combinators = pop();
- List<UnlinkedConfiguration> conditionalUris = pop();
- String uri = pop();
- List<UnlinkedExpr> metadata = pop();
- topScope.unit.exports
- .add(new UnlinkedExportNonPublicBuilder(annotations: metadata));
- topScope.publicNamespace.exports.add(new UnlinkedExportPublicBuilder(
- uri: uri, combinators: combinators, configurations: conditionalUris));
- checkEmpty();
- }
-
- void endFactoryMethod(
- Token beginToken, Token factoryKeyword, Token endToken) {
- debugEvent("FactoryMethod");
- throw new UnimplementedError(); // TODO(paulberry)
- // pop(); // async-modifiers
- // /* List<FormalParameterBuilder> formals = */ pop();
- // var name = pop();
- // /* List<MetadataBuilder> metadata = */ pop();
- }
-
- void endFieldInitializer(Token assignmentOperator, Token token) {
- debugEvent("FieldInitializer $typeSeen $assignmentOperator");
- // This is a variable initializer and it's ignored for now. May also be
- // constructor initializer.
- var initializer =
- needInitializer && assignmentOperator != null ? pop() : null;
- var name = pop();
- push(new _InitializedName(
- name, new UnlinkedExecutableBuilder(bodyExpr: initializer)));
- }
-
- void endFields(int count, Token beginToken, Token endToken) {
- debugEvent("Fields");
- var s = scope;
- if (s is ClassScope) {
- _endFields(count, s.currentClass.fields, false);
- } else {
- throw new UnimplementedError(); // TODO(paulberry): does this ever occur?
- // _endFields(count, s.currentEnum.values, false);
- }
- }
-
- void endFormalParameter(Token thisKeyword, Token nameToken,
- FormalParameterType kind, MemberKind memberKind) {
- debugEvent("FormalParameter");
- // TODO(sigmund): clean up?
- var nameOrFormal = pop();
- if (nameOrFormal is String) {
- EntityRef type = pop();
- pop(); // Modifiers
- List metadata = pop();
- push(new UnlinkedParamBuilder(
- name: nameOrFormal,
- kind: _nextParamKind,
- inheritsCovariantSlot: slotIf(type == null),
- annotations: metadata,
- isInitializingFormal: thisKeyword != null,
- type: type));
- } else {
- push(nameOrFormal);
- }
- }
-
- void endFormalParameters(
- int count, Token beginToken, Token endToken, MemberKind kind) {
- debugEvent("FormalParameters");
- List formals = popList(count);
- if (formals != null && formals.isNotEmpty) {
- var last = formals.last;
- if (last is List) {
- var newList = new List(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;
- }
- }
- push(formals ?? NullValue.FormalParameters);
- }
-
- void endFunctionTypeAlias(
- Token typedefKeyword, Token equals, Token endToken) {
- debugEvent("endFunctionTypeAlias");
- List formals = pop();
- List typeVariables = pop();
- String name = pop();
- EntityRef returnType = pop();
- List metadata = pop();
- // print('TODO: type alias $name');
- checkEmpty();
-
- scope = scope.parent;
- topScope.unit.typedefs.add(new UnlinkedTypedefBuilder(
- name: name,
- typeParameters: typeVariables,
- returnType: returnType,
- parameters: formals,
- annotations: metadata));
-
- _addNameIfPublic(name, ReferenceKind.typedef, typeVariables.length);
- }
-
- void endFunctionTypedFormalParameter() {
- debugEvent("FunctionTypedFormalParameter");
- List<UnlinkedParamBuilder> formals = pop();
- if (formals != null) formals.forEach((p) => p.inheritsCovariantSlot = null);
-
- String name = pop();
- EntityRef returnType = pop();
- /* List typeVariables = */ pop();
- /* int modifiers = */ pop();
- List metadata = pop();
-
- push(new UnlinkedParamBuilder(
- name: name,
- kind: _nextParamKind,
- isFunctionTyped: true,
- parameters: formals,
- annotations: metadata,
- type: returnType));
- }
-
- void endHide(_) {
- push(new UnlinkedCombinatorBuilder(hides: pop()));
- }
-
- void endIdentifierList(int count) {
- debugEvent("endIdentifierList");
- push(popList(count) ?? NullValue.IdentifierList);
- }
-
- void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
- Token semicolon) {
- debugEvent("endImport");
- List<UnlinkedCombinator> combinators = pop();
- String prefix = popIfNotNull(asKeyword);
- int prefixIndex =
- prefix == null ? null : topScope.serializeReference(null, prefix);
- List<UnlinkedConfiguration> conditionalUris = pop();
- String uri = pop();
- List<UnlinkedExpr> metadata = pop(); // metadata
-
- topScope.unit.imports.add(new UnlinkedImportBuilder(
- uri: uri,
- prefixReference: prefixIndex,
- combinators: combinators,
- configurations: conditionalUris,
- isDeferred: deferredKeyword != null,
- annotations: metadata,
- ));
- if (uri == 'dart:core') isDartCoreImported = true;
- checkEmpty();
- }
-
- void endInitializer(Token assignmentOperator) {
- // TODO(paulberry): add support for this.
- debugEvent("Initializer $typeSeen $assignmentOperator");
- }
-
- void endInitializers(int count, Token beginToken, Token endToken) {
- debugEvent("Initializers");
- // TODO(sigmund): include const-constructor initializers
- }
-
- void endLibraryName(Token libraryKeyword, Token semicolon) {
- debugEvent("endLibraryName");
- String name = pop();
- List<UnlinkedExpr> metadata = pop(); // metadata
-
- topScope.unit.libraryName = name;
- topScope.unit.libraryAnnotations = metadata;
- if (name == 'dart.core') isCoreLibrary = true;
- }
-
- void endLiteralString(int interpolationCount, Token endToken) {
- assert(interpolationCount == 0); // TODO(sigmund): handle interpolation
- }
-
- void endMember() {
- debugEvent("Member");
- }
-
- // TODO(sigmund): handle metadata (this code is incomplete).
- void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- debugEvent("Metadata");
- List arguments = pop();
- var result = new UnlinkedExprBuilder();
- // If arguments are null, this is an expression, otherwise a constructor
- // reference.
- if (arguments == null) {
- /* String postfix = */ popIfNotNull(periodBeforeName);
- /* String expression = */ pop();
- //push([expression, postfix]); // @x or @p.x
- } else {
- /* String name = */ popIfNotNull(periodBeforeName);
- // TODO(ahe): Type arguments are missing, eventually they should be
- // available as part of [arguments].
- // List<String> typeArguments = null;
- /* EntityRef typeName = */ pop();
- //push([typeName, typeArguments, name, arguments]);
- }
- push(result);
- }
-
- void endMetadataStar(int count, bool forParameter) {
- debugEvent("MetadataStar");
- push(popList(count) ?? NullValue.Metadata);
- }
-
- void endMethod(Token getOrSet, Token beginToken, Token endToken) {
- debugEvent("Method");
- int asyncModifier = pop();
- List<UnlinkedParam> formals = pop();
- List<UnlinkedTypeParamBuilder> typeVariables = pop();
- String name = pop();
- EntityRef returnType = pop();
- int modifiers = pop();
- List metadata = pop();
-
- ClassScope s = scope;
- bool isStatic = modifiers & _static_flag != 0;
- bool isConst = modifiers & _const_flag != 0;
- bool isGetter = getOrSet == 'get';
- bool isSetter = getOrSet == 'set';
- bool isOperator = name == "operator"; // TODO
- bool isConstructor =
- name == s.className || name.startsWith('${s.className}.');
-
- if (isConstructor) {
- name = name == s.className ? '' : name.substring(name.indexOf('.') + 1);
- }
-
- name = isSetter ? '$name=' : name;
- // Note: we don't include bodies for any method.
- s.currentClass.executables.add(new UnlinkedExecutableBuilder(
- name: name,
- kind: isGetter
- ? UnlinkedExecutableKind.getter
- : (isSetter
- ? UnlinkedExecutableKind.setter
- : (isConstructor
- ? UnlinkedExecutableKind.constructor
- : UnlinkedExecutableKind.functionOrMethod)),
- isExternal: modifiers & _external_flag != 0,
- isAbstract: modifiers & _abstract_flag != 0,
- isAsynchronous: asyncModifier & _async_flag != 0,
- isGenerator: asyncModifier & _star_flag != 0,
- isStatic: isStatic,
- isConst: isConst,
- constCycleSlot: slotIf(isConst),
- typeParameters: typeVariables,
- returnType: returnType,
- parameters: formals, // TODO: add inferred slot to args
- annotations: metadata,
- inferredReturnTypeSlot:
- slotIf(returnType == null && !isStatic && !isConstructor)));
-
- if (isConstructor && name == '') return;
- if (_isPrivate(name)) return;
- if (isSetter || isOperator) return;
- if (!isStatic && !isConstructor) return;
- s.publicName.members.add(new UnlinkedPublicNameBuilder(
- name: name,
- kind: isGetter
- ? ReferenceKind.propertyAccessor
- : (isConstructor
- ? ReferenceKind.constructor
- : ReferenceKind.method),
- numTypeParameters: typeVariables.length));
- }
-
- void endMixinApplication(Token withKeyword) {
- debugEvent("MixinApplication");
- ClassScope s = scope;
- s.currentClass.mixins = pop();
- }
-
- void endNamedMixinApplication(Token begin, Token classKeyword, Token equals,
- Token implementsKeyword, Token endToken) {
- debugEvent("endNamedMixinApplication");
- List<EntityRef> interfaces = popIfNotNull(implementsKeyword);
- EntityRef supertype = pop();
- List typeVariables = pop();
- String name = pop();
- int modifiers = pop();
- List metadata = pop();
- // print('TODO: end mix, $name');
- checkEmpty();
-
- ClassScope s = scope;
- s.currentClass
- ..name = name
- ..isAbstract = modifiers & _abstract_flag != 0
- ..isMixinApplication = true
- ..annotations = metadata
- ..typeParameters = typeVariables
- ..interfaces = interfaces;
- if (supertype != null) {
- s.currentClass.supertype = supertype;
- } else {
- s.currentClass.hasNoSupertype = isCoreLibrary && name == 'Object';
- }
- scope = scope.parent;
- topScope.unit.classes.add(s.currentClass);
-
- _addNameIfPublic(name, ReferenceKind.classOrEnum, typeVariables.length);
- }
-
- void endOptionalFormalParameters(
- int count, Token beginToken, Token endToken) {
- debugEvent("OptionalFormalParameters");
- push(popList(count));
- }
-
- void endPart(Token partKeyword, Token semicolon) {
- debugEvent("Part");
- String uri = pop();
- List<UnlinkedExpr> metadata = pop();
- topScope.unit.parts.add(new UnlinkedPartBuilder(annotations: metadata));
- topScope.publicNamespace.parts.add(uri);
- checkEmpty();
- }
-
- void endPartOf(Token partKeyword, Token semicolon, bool hasName) {
- debugEvent("endPartOf");
- String name = pop();
- pop(); // metadata
- topScope.unit.isPartOf = true;
- if (name == 'dart.core') isCoreLibrary = true;
- }
-
- void endRedirectingFactoryBody(Token beginToken, Token endToken) {
- debugEvent("RedirectingFactoryBody");
- pop(); // Discard ConstructorReferenceBuilder.
- }
-
- void endShow(_) {
- push(new UnlinkedCombinatorBuilder(shows: pop()));
- }
-
- void endTopLevelFields(int count, Token beginToken, Token endToken) {
- debugEvent("endTopLevelFields");
- _endFields(count, topScope.unit.variables, true);
- checkEmpty();
- }
-
- void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
- debugEvent("endTopLevelMethod");
- int asyncModifier = pop();
- List formals = pop();
- List typeVariables = pop();
- String name = pop();
- EntityRef returnType = pop();
- int modifiers = pop();
- List metadata = pop();
- checkEmpty();
-
- topScope.unit.executables.add(new UnlinkedExecutableBuilder(
- name: getOrSet == 'set' ? '$name=' : name,
- kind: getOrSet == 'get'
- ? UnlinkedExecutableKind.getter
- : (getOrSet == 'set'
- ? UnlinkedExecutableKind.setter
- : UnlinkedExecutableKind.functionOrMethod),
- isExternal: modifiers & _external_flag != 0,
- isAbstract: modifiers & _abstract_flag != 0,
- isAsynchronous: asyncModifier & _async_flag != 0,
- isGenerator: asyncModifier & _star_flag != 0,
- isStatic: modifiers & _static_flag != 0,
- typeParameters: [], // TODO
- returnType: returnType,
- parameters: formals,
- annotations: metadata,
- inferredReturnTypeSlot: null, // not needed for top-levels
- // skip body.
- ));
-
- String normalizedName = getOrSet == 'set' ? '$name=' : name;
- _addNameIfPublic(
- normalizedName,
- getOrSet != null
- ? ReferenceKind.topLevelPropertyAccessor
- : ReferenceKind.topLevelFunction,
- typeVariables?.length ?? 0 /* todo */);
- }
-
- void endTypeArguments(int count, Token beginToken, Token endToken) {
- debugEvent("TypeArguments");
- push(popList(count) ?? const []);
- }
-
- void endTypeList(int count) {
- debugEvent("TypeList");
- push(popList(count) ?? NullValue.TypeList);
- }
-
- void endTypeVariable(Token token, Token extendsOrSuper) {
- debugEvent("endTypeVariable");
- EntityRef bound = pop();
- String name = pop();
-
- var s = scope;
- if (s is TypeParameterScope) {
- s.typeParameters.add(name);
- } else {
- throw new UnimplementedError(); // TODO(paulberry)
- }
- push(new UnlinkedTypeParamBuilder(name: name, bound: bound));
- }
-
- void endTypeVariables(int count, Token beginToken, Token endToken) {
- debugEvent("TypeVariables");
- push(popList(count) ?? const []);
- }
-
- void handleAsyncModifier(Token asyncToken, Token starToken) {
- debugEvent("AsyncModifier");
- int asyncModifier = 0;
- if (asyncToken == "async") asyncModifier |= _async_flag;
- if (asyncToken == "sync") asyncModifier |= _sync_flag;
- if (starToken != null) asyncModifier |= _star_flag;
- push(asyncModifier);
- }
-
- void handleFormalParameterWithoutValue(Token token) {
- debugEvent("FormalParameterWithoutValue");
- }
-
- void handleModifier(Token token) {
- debugEvent("Modifier");
- var modifier = _modifierFlag[token.stringValue];
- if (modifier & _const_flag != 0) inConstContext = true;
- push(modifier);
- }
-
- void handleModifiers(int count) {
- debugEvent("Modifiers");
- push((popList(count) ?? const []).fold/*<int>*/(0, (a, b) => a | b));
- }
-
- void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
- debugEvent("NoConstructorReferenceContinuationAfterTypeArguments");
- }
-
- void handleNoFieldInitializer(Token token) {
- debugEvent("NoFieldInitializer");
- push(new _InitializedName(pop(), null));
- }
-
- void handleNoFunctionBody(Token token) {
- debugEvent("NoFunctionBody");
- // Ignored for now. We shouldn't see any function bodies.
- }
-
- void handleNoInitializers() {
- debugEvent("NoInitializers");
- // This is a constructor initializer and it's ignored for now.
- }
-
- void handleNoTypeVariables(Token token) {
- debugEvent("NoTypeVariables");
- push(const []);
- }
-
- void handleOperatorName(Token operatorKeyword, Token token) {
- // TODO(sigmund): convert operator names to name used by summaries.
- debugEvent("OperatorName");
- push(operatorKeyword.lexeme);
- }
-
- void handleQualified(Token period) {
- debugEvent("handleQualified");
- String name = pop();
- String receiver = pop();
- push("$receiver.$name");
- }
-
- void handleStringPart(token) {
- debugEvent("handleStringPart");
- push(token.lexeme.substring(1, token.lexeme.length - 1));
- }
-
- void handleType(Token beginToken, Token endToken) {
- debugEvent("Type");
- List<EntityRef> arguments = pop();
- String name = pop();
-
- var type;
- if (name.contains('.')) {
- var parts = name.split('.');
- for (var p in parts) {
- type = type == null
- ? new LazyEntityRef(p, scope)
- : new NestedLazyEntityRef(type, p, scope);
- }
- } else {
- type = new LazyEntityRef(name, scope);
- }
- type.typeArguments = arguments;
- push(type);
- typeSeen = true;
- }
-
- // helpers to work with the summary format.
-
- void handleValuedFormalParameter(Token equals, Token token) {
- debugEvent("ValuedFormalParameter");
- // TODO(sigmund): include default value on optional args.
- }
-
- void handleVoidKeyword(Token token) {
- debugEvent("VoidKeyword");
- // TODO: skip the lazy mechanism
- push(new LazyEntityRef("void", scope.top));
- }
-
- /// Assign the next slot if [condition] is true.
- int slotIf(bool condition) => condition ? assignSlot() : 0;
-
- /// Add [name] to the public namespace.
- void _addName(String name, ReferenceKind kind, {int numTypeParameters: 0}) {
- topScope.publicNamespace.names.add(new UnlinkedPublicNameBuilder(
- name: name, kind: kind, numTypeParameters: numTypeParameters));
- }
-
- /// Add [name] to the public namespace if it's public.
- void _addNameIfPublic(
- String name, ReferenceKind kind, int numTypeParameters) {
- if (_isPrivate(name)) return null;
- _addName(name, kind, numTypeParameters: numTypeParameters);
- }
-
- /// Add `name` and, if requested, `name=` to the public namespace.
- void _addPropertyName(String name, {bool includeSetter: false}) {
- _addName(name, ReferenceKind.topLevelPropertyAccessor);
- if (includeSetter) {
- _addName('$name=', ReferenceKind.topLevelPropertyAccessor);
- }
- }
-
- void _endFields(int count, List result, bool isTopLevel) {
- debugEvent('EndFields: $count $isTopLevel');
- List<_InitializedName> fields = popList(count);
- EntityRef type = pop();
- int modifiers = pop();
- List metadata = pop();
-
- bool isStatic = modifiers & _static_flag != 0;
- bool isFinal = modifiers & _final_flag != 0;
- bool isConst = modifiers & _const_flag != 0;
- bool isInstance = !isStatic && !isTopLevel;
- for (var field in fields) {
- var name = field.name;
- var initializer = field.initializer;
- bool needsPropagatedType = initializer != null && (isFinal || isConst);
- bool needsInferredType =
- type == null && (initializer != null || isInstance);
- result.add(new UnlinkedVariableBuilder(
- isFinal: isFinal,
- isConst: isConst,
- isStatic: isStatic,
- name: name,
- type: type,
- annotations: metadata,
- initializer: initializer,
- propagatedTypeSlot: slotIf(needsPropagatedType),
- inferredTypeSlot: slotIf(needsInferredType)));
-
- if (_isPrivate(name)) continue;
- if (isTopLevel) {
- _addPropertyName(name, includeSetter: !isFinal && !isConst);
- } else if (isStatic) {
- // Any reason setters are not added as well?
- (scope as ClassScope).publicName.members.add(
- new UnlinkedPublicNameBuilder(
- name: name,
- kind: ReferenceKind.propertyAccessor,
- numTypeParameters: 0));
- }
- }
- }
-
- /// Whether a name is private and should be excluded from the public
- /// namespace.
- bool _isPrivate(String name) => name.startsWith('_');
-}
-
-/// Internal representation of an initialized name.
-class _InitializedName {
- final String name;
- final UnlinkedExecutableBuilder initializer;
- _InitializedName(this.name, this.initializer);
-
- toString() => "II:" + (initializer != null ? "$name = $initializer" : name);
-}
« no previous file with comments | « pkg/analyzer/lib/src/summary/fasta/stack_listener.dart ('k') | pkg/analyzer/lib/src/summary/fasta/visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698