mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
General TypeInfo and IdentifierContext cleanup
* Assert computeType and TypeInfo.skipType do not modify the token stream * Rename TokenInfoTest to TypeInfoTest * Move skipMetadata to util.dart * Address comments in https://dart-review.googlesource.com/c/sdk/+/53300 Change-Id: Id2dbe54c5bc688db268e18b0a491367115f7b091 Reviewed-on: https://dart-review.googlesource.com/53640 Commit-Queue: Dan Rubel <danrubel@google.com> Reviewed-by: Peter von der Ahé <ahe@google.com>
This commit is contained in:
parent
e93b2ee250
commit
73768a5342
|
@ -15,9 +15,9 @@ import 'parser.dart' show Parser;
|
|||
import 'type_info.dart'
|
||||
show insertSyntheticIdentifierAfter, isValidTypeReference;
|
||||
|
||||
import 'util.dart' show optional;
|
||||
import 'util.dart' show optional, skipMetadata;
|
||||
|
||||
/// See [IdentifierContext].classOrNamedMixin
|
||||
/// See [IdentifierContext.classOrNamedMixinDeclaration].
|
||||
class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
|
||||
const ClassOrNamedMixinIdentifierContext()
|
||||
: super('classOrNamedMixinDeclaration',
|
||||
|
@ -53,7 +53,7 @@ class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext].dottedName
|
||||
/// See [IdentifierContext.dottedName].
|
||||
class DottedNameIdentifierContext extends IdentifierContext {
|
||||
const DottedNameIdentifierContext() : super('dottedName');
|
||||
|
||||
|
@ -95,7 +95,7 @@ class DottedNameIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext].expression
|
||||
/// See [IdentifierContext.expression].
|
||||
class ExpressionIdentifierContext extends IdentifierContext {
|
||||
const ExpressionIdentifierContext()
|
||||
: super('expression', isScopeReference: true);
|
||||
|
@ -145,6 +145,7 @@ class ExpressionIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext.fieldDeclaration].
|
||||
class FieldDeclarationIdentifierContext extends IdentifierContext {
|
||||
const FieldDeclarationIdentifierContext()
|
||||
: super('fieldDeclaration', inDeclaration: true);
|
||||
|
@ -175,7 +176,7 @@ class FieldDeclarationIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext].fieldInitializer
|
||||
/// See [IdentifierContext.fieldInitializer].
|
||||
class FieldInitializerIdentifierContext extends IdentifierContext {
|
||||
const FieldInitializerIdentifierContext()
|
||||
: super('fieldInitializer', isContinuation: true);
|
||||
|
@ -234,7 +235,7 @@ class ImportPrefixIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext].libraryName
|
||||
/// See [IdentifierContext.libraryName].
|
||||
class LibraryIdentifierContext extends IdentifierContext {
|
||||
const LibraryIdentifierContext()
|
||||
: super('libraryName', inLibraryOrPartOfDeclaration: true);
|
||||
|
@ -276,7 +277,7 @@ class LibraryIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext].localVariableDeclaration
|
||||
/// See [IdentifierContext.localVariableDeclaration].
|
||||
class LocalVariableDeclarationIdentifierContext extends IdentifierContext {
|
||||
const LocalVariableDeclarationIdentifierContext()
|
||||
: super('localVariableDeclaration', inDeclaration: true);
|
||||
|
@ -308,6 +309,7 @@ class LocalVariableDeclarationIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext.methodDeclaration].
|
||||
class MethodDeclarationIdentifierContext extends IdentifierContext {
|
||||
const MethodDeclarationIdentifierContext()
|
||||
: super('methodDeclaration', inDeclaration: true);
|
||||
|
@ -383,7 +385,7 @@ class TypedefDeclarationIdentifierContext extends IdentifierContext {
|
|||
}
|
||||
}
|
||||
|
||||
/// See [IdentifierContext].typeReference
|
||||
/// See [IdentifierContext.typeReference].
|
||||
class TypeReferenceIdentifierContext extends IdentifierContext {
|
||||
const TypeReferenceIdentifierContext()
|
||||
: super('typeReference',
|
||||
|
@ -415,7 +417,7 @@ class TypeReferenceIdentifierContext extends IdentifierContext {
|
|||
// annotation is not allowed before type arguments.
|
||||
parser.reportRecoverableErrorWithToken(
|
||||
next, fasta.templateUnexpectedToken);
|
||||
token = skipMetadata(next);
|
||||
token = skipMetadata(token);
|
||||
next = token.next;
|
||||
}
|
||||
|
||||
|
@ -490,25 +492,3 @@ bool looksLikeStartOfNextStatement(Token token) => isOneOfOrEof(token, const [
|
|||
bool looksLikeStartOfNextTopLevelDeclaration(Token token) =>
|
||||
token.isTopLevelKeyword ||
|
||||
isOneOfOrEof(token, const ['const', 'get', 'final', 'set', 'var', 'void']);
|
||||
|
||||
Token skipMetadata(Token token) {
|
||||
assert(optional('@', token));
|
||||
Token next = token.next;
|
||||
if (next.isIdentifier) {
|
||||
token = next;
|
||||
next = token.next;
|
||||
while (optional('.', next)) {
|
||||
token = next;
|
||||
next = token.next;
|
||||
if (next.isIdentifier) {
|
||||
token = next;
|
||||
next = token.next;
|
||||
}
|
||||
}
|
||||
if (optional('(', next)) {
|
||||
token = next.endGroup;
|
||||
next = token.next;
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
|
|
@ -53,3 +53,26 @@ int lengthOfSpan(Token begin, Token end) {
|
|||
if (end == null) return lengthForToken(begin);
|
||||
return end.offset + end.length - begin.offset;
|
||||
}
|
||||
|
||||
Token skipMetadata(Token token) {
|
||||
token = token.next;
|
||||
assert(optional('@', token));
|
||||
Token next = token.next;
|
||||
if (next.isIdentifier) {
|
||||
token = next;
|
||||
next = token.next;
|
||||
while (optional('.', next)) {
|
||||
token = next;
|
||||
next = token.next;
|
||||
if (next.isIdentifier) {
|
||||
token = next;
|
||||
next = token.next;
|
||||
}
|
||||
}
|
||||
if (optional('(', next)) {
|
||||
token = next.endGroup;
|
||||
next = token.next;
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
|
|
@ -13,12 +13,12 @@ import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(TokenInfoTest);
|
||||
defineReflectiveTests(TypeInfoTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class TokenInfoTest {
|
||||
class TypeInfoTest {
|
||||
void test_noType() {
|
||||
final Token start = scanString('before ;').tokens;
|
||||
|
||||
|
@ -790,12 +790,18 @@ void compute(
|
|||
String expectedAfter,
|
||||
List<String> expectedCalls,
|
||||
List<ExpectedError> expectedErrors) {
|
||||
int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
|
||||
TypeInfo typeInfo = computeType(start, required);
|
||||
expect(typeInfo, expectedInfo, reason: source);
|
||||
expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
|
||||
reason: 'computeType should not modify the token stream');
|
||||
|
||||
if (typeInfo is ComplexTypeInfo) {
|
||||
expect(typeInfo.start, start.next, reason: source);
|
||||
expect(typeInfo.couldBeExpression, isFalse);
|
||||
expectEnd(expectedAfter, typeInfo.skipType(start));
|
||||
expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
|
||||
reason: 'TypeInfo.skipType should not modify the token stream');
|
||||
|
||||
TypeInfoListener listener;
|
||||
assertResult(Token actualEnd) {
|
||||
|
@ -838,6 +844,18 @@ Token scan(String source) {
|
|||
return new SyntheticToken(TokenType.EOF, 0)..setNext(start);
|
||||
}
|
||||
|
||||
int countGtGtAndNullEnd(Token token) {
|
||||
int count = 0;
|
||||
while (!token.isEof) {
|
||||
if ((optional('<', token) && token.endGroup == null) ||
|
||||
optional('>>', token)) {
|
||||
++count;
|
||||
}
|
||||
token = token.next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
class TypeInfoListener implements Listener {
|
||||
List<String> calls = <String>[];
|
||||
List<ExpectedError> errors;
|
||||
|
|
Loading…
Reference in a new issue