Index: pkg/front_end/lib/src/fasta/parser/identifier_context.dart |
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9a9d774952faf563405ed4a535f5fad0cbf1d8ee |
--- /dev/null |
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart |
@@ -0,0 +1,251 @@ |
+// 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. |
+ |
+/// Information about the parser state which is passed to the listener at the |
+/// time an identifier is encountered. |
+/// |
+/// This can be used by the listener to determine the context in which the |
+/// identifier appears; that in turn can help the listener decide how to resolve |
+/// the identifier (if the listener is doing resolution). |
+class IdentifierContext { |
+ /// Identifier is being declared as the name of an import prefix (i.e. `Foo` |
+ /// in `import "..." as Foo;`) |
+ static const importPrefixDeclaration = |
+ const IdentifierContext._('importPrefixDeclaration'); |
+ |
+ /// Identifier is the start of a dotted name in a conditional import or |
+ /// export. |
+ static const dottedName = const IdentifierContext._('dottedName'); |
+ |
+ /// Identifier is part of a dotted name in a conditional import or export, but |
+ /// it's not the first identifier of the dotted name. |
+ static const dottedNameContinuation = |
+ const IdentifierContext._('dottedNameContinuation', isContinuation: true); |
+ |
+ /// Identifier is one of the shown/hidden names in an import/export |
+ /// combinator. |
+ static const combinator = const IdentifierContext._('combinator'); |
+ |
+ /// Identifier is the start of a name in an annotation that precedes a |
+ /// declaration (i.e. it appears directly after an `@`). |
+ static const metadataReference = |
+ const IdentifierContext._('metadataReference', isScopeReference: true); |
+ |
+ /// Identifier is part of a name in an annotation that precedes a declaration, |
+ /// but it's not the first identifier in the name. |
+ static const metadataContinuation = |
+ const IdentifierContext._('metadataContinuation', isContinuation: true); |
+ |
+ /// Identifier is part of a name in an annotation that precedes a declaration, |
+ /// but it appears after type parameters (e.g. `foo` in `@X<Y>.foo()`). |
+ static const metadataContinuationAfterTypeArguments = |
+ const IdentifierContext._('metadataContinuationAfterTypeArguments', |
+ isContinuation: true); |
+ |
+ /// Identifier is the name being declared by a typedef declaration. |
+ static const typedefDeclaration = |
+ const IdentifierContext._('typedefDeclaration'); |
+ |
+ /// Identifier is a field initializer in a formal parameter list (i.e. it |
+ /// appears directly after `this.`). |
+ static const fieldInitializer = |
+ const IdentifierContext._('fieldInitializer', isContinuation: true); |
+ |
+ /// Identifier is a formal parameter being declared as part of a function, |
+ /// method, or typedef declaration. |
+ static const formalParameterDeclaration = |
+ const IdentifierContext._('formalParameterDeclaration'); |
+ |
+ /// Identifier is the start of a library name (e.g. `foo` in the directive |
+ /// 'library foo;`). |
+ static const libraryName = const IdentifierContext._('libraryName', |
+ inLibraryOrPartOfDeclaration: true); |
+ |
+ /// Identifier is part of a library name, but it's not the first identifier in |
+ /// the name. |
+ static const libraryNameContinuation = const IdentifierContext._( |
+ 'libraryNameContinuation', |
+ inLibraryOrPartOfDeclaration: true, |
+ isContinuation: true); |
+ |
+ /// Identifier is the start of a library name referenced by a `part of` |
+ /// directive (e.g. `foo` in the directive `part of foo;`). |
+ static const partName = |
+ const IdentifierContext._('partName', inLibraryOrPartOfDeclaration: true); |
+ |
+ /// Identifier is part of a library name referenced by a `part of` directive, |
+ /// but it's not the first identifier in the name. |
+ static const partNameContinuation = const IdentifierContext._( |
+ 'partNameContinuation', |
+ inLibraryOrPartOfDeclaration: true, |
+ isContinuation: true); |
+ |
+ /// Identifier is the type name being declared by an enum declaration. |
+ static const enumDeclaration = const IdentifierContext._('enumDeclaration'); |
+ |
+ /// Identifier is an enumerated value name being declared by an enum |
+ /// declaration. |
+ static const enumValueDeclaration = |
+ const IdentifierContext._('enumValueDeclaration'); |
+ |
+ /// Identifier is the name being declared by a named mixin declaration (e.g. |
+ /// `Foo` in `class Foo = X with Y;`). |
+ static const namedMixinDeclaration = |
+ const IdentifierContext._('namedMixinDeclaration'); |
+ |
+ /// Identifier is the name being declared by a class declaration. |
+ static const classDeclaration = const IdentifierContext._('classDeclaration'); |
+ |
+ /// Identifier is the name of a type variable being declared (e.g. `Foo` in |
+ /// `class C<Foo extends num> {}`). |
+ static const typeVariableDeclaration = |
+ const IdentifierContext._('typeVariableDeclaration'); |
+ |
+ /// Identifier is the start of a reference to a type declared elsewhere. |
+ static const typeReference = |
+ const IdentifierContext._('typeReference', isScopeReference: true); |
+ |
+ /// Identifier is part of a reference to a type declared elsewhere, but it's |
+ /// not the first identifier of the reference. |
+ static const typeReferenceContinuation = const IdentifierContext._( |
+ 'typeReferenceContinuation', |
+ isContinuation: true); |
+ |
+ /// Identifier is a name being declared by a top level variable declaration. |
+ static const topLevelVariableDeclaration = |
+ const IdentifierContext._('topLevelVariableDeclaration'); |
+ |
+ /// Identifier is a name being declared by a field declaration. |
+ static const fieldDeclaration = const IdentifierContext._('fieldDeclaration'); |
+ |
+ /// Identifier is the name being declared by a top level function declaration. |
+ static const topLevelFunctionDeclaration = |
+ const IdentifierContext._('topLevelFunctionDeclaration'); |
+ |
+ /// Identifier is the start of the name being declared by a method |
+ /// declaration. |
+ static const methodDeclaration = |
+ const IdentifierContext._('methodDeclaration'); |
+ |
+ /// Identifier is part of the name being declared by a method declaration, |
+ /// but it's not the first identifier of the name. |
+ /// |
+ /// In valid Dart, this can only happen if the identifier is the name of a |
+ /// named constructor which is being declared, e.g. `foo` in |
+ /// `class C { C.foo(); }`. |
+ static const methodDeclarationContinuation = const IdentifierContext._( |
+ 'methodDeclarationContinuation', |
+ isContinuation: true); |
+ |
+ /// Identifier appears after the word `operator` in a method declaration. |
+ /// |
+ /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only |
+ /// occur as part of error recovery? If it's only as part of error recovery, |
+ /// perhaps we should just re-use methodDeclaration. |
+ static const operatorName = const IdentifierContext._('operatorName'); |
+ |
+ /// Identifier is the name being declared by a local function declaration that |
+ /// uses a "get" or "set" keyword. |
+ /// |
+ /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only |
+ /// occur as part of error recovery? If it's only as part of error recovery, |
+ /// perhaps we should just re-use localFunctionDeclaration. |
+ static const localAccessorDeclaration = |
+ const IdentifierContext._('localAccessorDeclaration'); |
+ |
+ /// Identifier is the start of the name being declared by a local function |
+ /// declaration. |
+ static const localFunctionDeclaration = |
+ const IdentifierContext._('localFunctionDeclaration'); |
+ |
+ /// Identifier is part of the name being declared by a local function |
+ /// declaration, but it's not the first identifier of the name. |
+ /// |
+ /// TODO(paulberry,ahe): Does this ever occur in valid Dart, or does it only |
+ /// occur as part of error recovery? |
+ static const localFunctionDeclarationContinuation = const IdentifierContext._( |
+ 'localFunctionDeclarationContinuation', |
+ isContinuation: true); |
+ |
+ /// Identifier is the name appearing in a function exrpession. |
+ /// |
+ /// TODO(paulberry,ahe): What is an example of valid Dart code where this |
+ /// would occur? |
+ static const functionExpressionName = |
+ const IdentifierContext._('functionExpressionName'); |
+ |
+ /// Identifier is the start of a reference to a constructor declared |
+ /// elsewhere. |
+ static const constructorReference = |
+ const IdentifierContext._('constructorReference', isScopeReference: true); |
+ |
+ /// Identifier is part of a reference to a constructor declared elsewhere, but |
+ /// it's not the first identifier of the reference. |
+ static const constructorReferenceContinuation = const IdentifierContext._( |
+ 'constructorReferenceContinuation', |
+ isContinuation: true); |
+ |
+ /// Identifier is part of a reference to a constructor declared elsewhere, but |
+ /// it appears after type parameters (e.g. `foo` in `X<Y>.foo`). |
+ static const constructorReferenceContinuationAfterTypeArguments = |
+ const IdentifierContext._( |
+ 'constructorReferenceContinuationAfterTypeArguments', |
+ isContinuation: true); |
+ |
+ /// Identifier is the declaration of a label (i.e. it is followed by `:` and |
+ /// then a statement). |
+ static const labelDeclaration = const IdentifierContext._('labelDeclaration'); |
+ |
+ /// Identifier is the start of a reference occurring in a literal symbol (e.g. |
+ /// `foo` in `#foo`). |
+ static const literalSymbol = |
+ const IdentifierContext._('literalSymbol', isScopeReference: true); |
+ |
+ /// Identifier is part of a reference occurring in a literal symbol, but it's |
+ /// not the first identifier of the reference (e.g. `foo` in `#prefix.foo`). |
+ static const literalSymbolContinuation = const IdentifierContext._( |
+ 'literalSymbolContinuation', |
+ isContinuation: true); |
+ |
+ /// Identifier appears in an expression, and it does not immediately follow a |
+ /// `.`. |
+ static const expression = |
+ const IdentifierContext._('expression', isScopeReference: true); |
+ |
+ /// Identifier appears in an expression, and it immediately follows a `.`. |
+ static const expressionContinuation = |
+ const IdentifierContext._('expressionContinuation', isContinuation: true); |
+ |
+ /// Identifier is a reference to a named argument of a function or method |
+ /// invocation (e.g. `foo` in `f(foo: 0);`. |
+ static const namedArgumentReference = |
+ const IdentifierContext._('namedArgumentReference'); |
+ |
+ /// Identifier is a name being declared by a local variable declaration. |
+ static const localVariableDeclaration = |
+ const IdentifierContext._('localVariableDeclaration'); |
+ |
+ /// Identifier is a reference to a label (e.g. `foo` in `break foo;`). |
+ static const labelReference = |
+ const IdentifierContext._('labelReference', isScopeReference: true); |
+ |
+ final String _name; |
+ |
+ /// Indicates whether the identifier is within a `library` or `part of` |
+ /// declaration. |
+ final bool inLibraryOrPartOfDeclaration; |
+ |
+ /// Indicates whether the identifier follows a `.`. |
+ final bool isContinuation; |
+ |
+ /// Indicates whether the identifier should be looked up in the current scope. |
+ final bool isScopeReference; |
+ |
+ const IdentifierContext._(this._name, |
+ {this.inLibraryOrPartOfDeclaration: false, |
+ this.isContinuation: false, |
+ this.isScopeReference: false}); |
+ |
+ String toString() => _name; |
+} |