Improve part of identifier recovery
Change-Id: I16b5799e883ed0a04445809e329d9e7fba5afff4
Reviewed-on: https://dart-review.googlesource.com/56041
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
index 7432c7f..24b5890 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
@@ -12,17 +12,18 @@
class PartOfDirectivesTest extends PartialCodeTest {
buildAll() {
- List<String> allExceptEof = <String>[
- 'class',
+ List<String> identifiers = const [
'typedef',
- 'functionVoid',
'functionNonVoid',
- 'var',
- 'const',
- 'final',
'getter',
'setter'
];
+ List<TestSuffix> identifierSuffixes = PartialCodeTest.declarationSuffixes
+ .where((t) => identifiers.contains(t.name))
+ .toList();
+ List<TestSuffix> nonIdentifierSuffixes = PartialCodeTest.declarationSuffixes
+ .where((t) => !identifiers.contains(t.name))
+ .toList();
buildTests(
'part_of_directive',
[
@@ -30,11 +31,31 @@
'keyword',
'part of',
[
- ParserErrorCode.MISSING_NAME_IN_PART_OF_DIRECTIVE,
+ ParserErrorCode.EXPECTED_STRING_LITERAL,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ 'part of "";',
+ failing: []),
+ ],
+ nonIdentifierSuffixes);
+ buildTests(
+ 'part_of_directive',
+ [
+ new TestDescriptor(
+ 'keyword',
+ 'part of',
+ [
+ ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN
],
'part of _s_;',
- allFailing: true),
+ failing: ['functionNonVoid', 'getter']),
+ ],
+ identifierSuffixes,
+ includeEof: false);
+ buildTests(
+ 'part_of_directive',
+ [
new TestDescriptor('name', 'part of lib',
[ParserErrorCode.EXPECTED_TOKEN], 'library lib;',
allFailing: true),
@@ -46,7 +67,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
'part of lib._s_;',
- failing: allExceptEof),
+ failing: ['functionNonVoid', 'getter']),
new TestDescriptor('nameDotName', 'part of lib.a',
[ParserErrorCode.EXPECTED_TOKEN], 'part of lib.a;'),
new TestDescriptor('emptyUri', "part of ''",
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index a4d6a9e..9c65f14 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -77,15 +77,12 @@
/// 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);
+ static const partName = const LibraryIdentifierContext.partName();
/// 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);
+ static const partNameContinuation =
+ const LibraryIdentifierContext.partNameContinuation();
/// Identifier is the type name being declared by an enum declaration.
static const enumDeclaration = const EnumDeclarationIdentifierContext();
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 23e03bf..ab54ca0 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -372,7 +372,10 @@
}
}
-/// See [IdentifierContext.libraryName].
+/// See [IdentifierContext.libraryName],
+/// and [IdentifierContext.libraryNameContinuation]
+/// and [IdentifierContext.partName],
+/// and [IdentifierContext.partNameContinuation].
class LibraryIdentifierContext extends IdentifierContext {
const LibraryIdentifierContext()
: super('libraryName', inLibraryOrPartOfDeclaration: true);
@@ -381,6 +384,13 @@
: super('libraryNameContinuation',
inLibraryOrPartOfDeclaration: true, isContinuation: true);
+ const LibraryIdentifierContext.partName()
+ : super('partName', inLibraryOrPartOfDeclaration: true);
+
+ const LibraryIdentifierContext.partNameContinuation()
+ : super('partNameContinuation',
+ inLibraryOrPartOfDeclaration: true, isContinuation: true);
+
@override
Token ensureIdentifier(Token token, Parser parser) {
Token identifier = token.next;