From e2db9676d9e08cccd5c7a32e75fdf855ade779ca Mon Sep 17 00:00:00 2001 From: Dan Rubel Date: Tue, 11 Dec 2018 23:48:04 +0000 Subject: [PATCH] add asNonNullable() to existing type infos This adds code to ignore trailing `?` in `as` and `is` expressions because the trailing `?` may be part of the larger expression. At the moment, this change is a no-op, but will become active when a subsequent CL lands support for nullable types as part of https://github.com/dart-lang/language/issues/110 Change-Id: I829d6aee0f11957ca9b5e143000005031649449f Reviewed-on: https://dart-review.googlesource.com/c/86960 Reviewed-by: Brian Wilkerson --- .../lib/src/fasta/parser/parser.dart | 8 ++++++-- .../lib/src/fasta/parser/type_info.dart | 4 ++++ .../lib/src/fasta/parser/type_info_impl.dart | 20 +++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart index 480d68deace..9e1f0159ad4 100644 --- a/pkg/front_end/lib/src/fasta/parser/parser.dart +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart @@ -4875,7 +4875,9 @@ class Parser { if (optional('!', token.next)) { not = token = token.next; } - token = computeType(token, true).ensureTypeNotVoid(token, this); + // Ignore trailing `?` if there is one as it may be part of an expression + TypeInfo typeInfo = computeType(token, true).asNonNullableType(); + token = typeInfo.ensureTypeNotVoid(token, this); listener.handleIsOperator(operator, not); return skipChainedAsIsOperators(token); } @@ -4888,7 +4890,9 @@ class Parser { Token parseAsOperatorRest(Token token) { Token operator = token = token.next; assert(optional('as', operator)); - token = computeType(token, true).ensureTypeNotVoid(token, this); + // Ignore trailing `?` if there is one as it may be part of an expression + TypeInfo typeInfo = computeType(token, true).asNonNullableType(); + token = typeInfo.ensureTypeNotVoid(token, this); listener.handleAsOperator(operator); return skipChainedAsIsOperators(token); } diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart index 585fedf332a..5e9f6363a3f 100644 --- a/pkg/front_end/lib/src/fasta/parser/type_info.dart +++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart @@ -17,6 +17,10 @@ import 'util.dart' show isOneOf, optional; /// [TypeInfo] provides information collected by [computeType] /// about a particular type reference. abstract class TypeInfo { + /// Return type info representing the receiver without the trailing `?` + /// or the receiver if the receiver does not represent a nullable type. + TypeInfo asNonNullableType(); + /// Return `true` if the tokens comprising the type represented by the /// receiver could be interpreted as a valid standalone expression. /// For example, `A` or `A.b` could be interpreted as a type references diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart index 6ec0d201459..8a29317b80b 100644 --- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart +++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart @@ -84,6 +84,9 @@ class NoType implements TypeInfo { @override bool get couldBeExpression => false; + @override + TypeInfo asNonNullableType() => this; + @override Token ensureTypeNotVoid(Token token, Parser parser) { parser.reportRecoverableErrorWithToken( @@ -119,6 +122,9 @@ class PrefixedType implements TypeInfo { @override bool get couldBeExpression => true; + @override + TypeInfo asNonNullableType() => this; + @override Token ensureTypeNotVoid(Token token, Parser parser) => parseType(token, parser); @@ -167,6 +173,9 @@ class SimpleTypeWith1Argument implements TypeInfo { @override bool get couldBeExpression => false; + @override + TypeInfo asNonNullableType() => this; + @override Token ensureTypeNotVoid(Token token, Parser parser) => parseType(token, parser); @@ -208,6 +217,9 @@ class SimpleType implements TypeInfo { @override bool get couldBeExpression => true; + @override + TypeInfo asNonNullableType() => this; + @override Token ensureTypeNotVoid(Token token, Parser parser) => parseType(token, parser); @@ -247,6 +259,9 @@ class VoidType implements TypeInfo { @override bool get couldBeExpression => false; + @override + TypeInfo asNonNullableType() => this; + @override Token ensureTypeNotVoid(Token token, Parser parser) { // Report an error, then parse `void` as if it were a type name. @@ -324,6 +339,11 @@ class ComplexTypeInfo implements TypeInfo { @override bool get couldBeExpression => false; + @override + TypeInfo asNonNullableType() { + return this; + } + @override Token ensureTypeNotVoid(Token token, Parser parser) => parseType(token, parser);