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 <brianwilkerson@google.com>
This commit is contained in:
Dan Rubel
2018-12-11 23:48:04 +00:00
committed by commit-bot@chromium.org
parent ca70671e85
commit e2db9676d9
3 changed files with 30 additions and 2 deletions
@@ -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);
}
@@ -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
@@ -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);