Skip to content

Commit

Permalink
Revert support for parsing simple nullable types
Browse files Browse the repository at this point in the history
This reverts commit bc8c7cf

Reason for revert: Breaks parsing less common conditionals (e.g. b ? c = true : g();)

Original change's description:
> Add support for parsing simple nullable types
>
> ... as part of adding NNBD as outlined in
> dart-lang/language#110
>
> This only supports parsing simple nullable types
> such as int? and List<int>? while subsequent CLs
> will add support for parsing more complex types.

Change-Id: I49a21a85dca19241e3b23ed5c9fb6084e70f2000
Reviewed-on: https://dart-review.googlesource.com/c/87284
Reviewed-by: Dan Rubel <danrubel@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
  • Loading branch information
danrubel authored and commit-bot@chromium.org committed Dec 14, 2018
1 parent 162d0d1 commit 9de66d8
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 210 deletions.
36 changes: 7 additions & 29 deletions pkg/front_end/lib/src/fasta/parser/type_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'parser.dart' show Parser;

import 'type_info_impl.dart';

import 'util.dart' show isOneOf, isOneOfOrEof, optional;
import 'util.dart' show isOneOf, optional;

/// [TypeInfo] provides information collected by [computeType]
/// about a particular type reference.
Expand Down Expand Up @@ -199,19 +199,13 @@ TypeInfo computeType(final Token token, bool required,
// We've seen identifier `<` identifier `>`
next = typeParamOrArg.skip(next).next;
if (!isGeneralizedFunctionType(next)) {
if (optional('?', next) && typeParamOrArg == simpleTypeArgument1) {
if (required || looksLikeName(next.next)) {
// identifier `<` identifier `>` `?` identifier
return simpleNullableTypeWith1Argument;
}
if (required || looksLikeName(next)) {
// identifier `<` identifier `>` identifier
return typeParamOrArg.typeInfo;
} else {
if (required || looksLikeName(next)) {
// identifier `<` identifier `>` identifier
return typeParamOrArg.typeInfo;
}
// identifier `<` identifier `>` non-identifier
return noType;
}
// identifier `<` identifier `>` non-identifier
return noType;
}
}
// TODO(danrubel): Consider adding a const for
Expand Down Expand Up @@ -261,23 +255,7 @@ TypeInfo computeType(final Token token, bool required,
.computeIdentifierGFT(required);
}

if (optional('?', next)) {
if (required) {
// identifier `?`
return simpleNullableType;
} else {
next = next.next;
if (isGeneralizedFunctionType(next)) {
// identifier `?` Function `(`
return simpleNullableType;
} else if (looksLikeName(next) &&
isOneOfOrEof(
next.next, const [';', ',', '=', '>', '>=', '>>', '>>>'])) {
// identifier `?` identifier `=`
return simpleNullableType;
}
}
} else if (required || looksLikeName(next)) {
if (required || looksLikeName(next)) {
// identifier identifier
return simpleType;
}
Expand Down
54 changes: 0 additions & 54 deletions pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ import 'util.dart'
/// when there is a single identifier as the type reference.
const TypeInfo simpleType = const SimpleType();

/// [SimpleNullableType] is a specialized [TypeInfo] returned by [computeType]
/// when there is a single identifier followed by `?` as the type reference.
const TypeInfo simpleNullableType = const SimpleNullableType();

/// [PrefixedType] is a specialized [TypeInfo] returned by [computeType]
/// when the type reference is of the form: identifier `.` identifier.
const TypeInfo prefixedType = const PrefixedType();
Expand All @@ -64,12 +60,6 @@ const TypeInfo simpleTypeWith1ArgumentGtEq =
const TypeInfo simpleTypeWith1ArgumentGtGt =
const SimpleTypeWith1Argument(simpleTypeArgument1GtGt);

/// [SimpleNullableTypeWith1Argument] is a specialized [TypeInfo] returned by
/// [computeType] when the type reference is of the form:
/// identifier `<` identifier `>` `?`.
const TypeInfo simpleNullableTypeWith1Argument =
const SimpleNullableTypeWith1Argument();

/// [SimpleTypeArgument1] is a specialized [TypeParamOrArgInfo] returned by
/// [computeTypeParamOrArg] when the type reference is of the form:
/// `<` identifier `>`.
Expand Down Expand Up @@ -174,29 +164,6 @@ class PrefixedType implements TypeInfo {
}
}

/// See documentation on the [simpleNullableTypeWith1Argument] const.
class SimpleNullableTypeWith1Argument extends SimpleTypeWith1Argument {
const SimpleNullableTypeWith1Argument() : super(simpleTypeArgument1);

@override
TypeInfo asNonNullableType() => simpleTypeWith1Argument;

@override
Token parseTypeRest(Token start, Token token, Parser parser) {
token = token.next;
assert(optional('?', token));
parser.listener.handleType(start, token);
return token;
}

@override
Token skipType(Token token) {
token = super.skipType(token).next;
assert(optional('?', token));
return token;
}
}

/// See documentation on the [simpleTypeWith1Argument] const.
class SimpleTypeWith1Argument implements TypeInfo {
final TypeParamOrArgInfo typeArg;
Expand Down Expand Up @@ -243,27 +210,6 @@ class SimpleTypeWith1Argument implements TypeInfo {
}
}

/// See documentation on the [simpleNullableType] const.
class SimpleNullableType extends SimpleType {
const SimpleNullableType();

@override
TypeInfo asNonNullableType() => simpleType;

@override
Token parseTypeRest(Token start, Parser parser) {
Token token = start.next;
assert(optional('?', token));
parser.listener.handleType(start, token);
return token;
}

@override
Token skipType(Token token) {
return token.next.next;
}
}

/// See documentation on the [simpleType] const.
class SimpleType implements TypeInfo {
const SimpleType();
Expand Down
130 changes: 3 additions & 127 deletions pkg/front_end/test/fasta/parser/type_info_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ main() {
defineReflectiveSuite(() {
defineReflectiveTests(NoTypeInfoTest);
defineReflectiveTests(PrefixedTypeInfoTest);
defineReflectiveTests(SimpleNullableTypeTest);
defineReflectiveTests(SimpleNullableTypeWith1ArgumentTest);
defineReflectiveTests(SimpleTypeTest);
defineReflectiveTests(SimpleTypeInfoTest);
defineReflectiveTests(SimpleTypeWith1ArgumentTest);
defineReflectiveTests(TypeInfoTest);
defineReflectiveTests(VoidTypeInfoTest);
Expand Down Expand Up @@ -311,124 +309,7 @@ class PrefixedTypeInfoTest {
}

@reflectiveTest
class SimpleNullableTypeTest {
void test_compute() {
expectInfo(simpleNullableType, 'C?', required: true);
expectInfo(simpleNullableType, 'C?;', required: true);
expectInfo(simpleNullableType, 'C?(', required: true);
expectInfo(simpleNullableType, 'C?<', required: true);
expectInfo(simpleNullableType, 'C?=', required: true);
expectInfo(simpleNullableType, 'C?*', required: true);
expectInfo(simpleNullableType, 'C? do', required: true);

expectInfo(simpleNullableType, 'C? foo');
expectInfo(simpleNullableType, 'C? get');
expectInfo(simpleNullableType, 'C? set');
expectInfo(simpleNullableType, 'C? operator');
expectInfo(simpleNullableType, 'C? this');
expectInfo(simpleNullableType, 'C? Function');

expectInfo(simpleNullableType, 'C? Function()', required: false);
expectInfo(simpleNullableType, 'C? Function<T>()', required: false);
expectInfo(simpleNullableType, 'C? Function(int)', required: false);
expectInfo(simpleNullableType, 'C? Function<T>(int)', required: false);
expectInfo(simpleNullableType, 'C? Function(int x)', required: false);
expectInfo(simpleNullableType, 'C? Function<T>(int x)', required: false);
}

void test_simpleNullableType() {
final Token start = scanString('before C? ;').tokens;
final Token expectedEnd = start.next.next;

expect(simpleNullableType.skipType(start), expectedEnd);
expect(simpleNullableType.couldBeExpression, isTrue);

TypeInfoListener listener;
assertResult(Token actualEnd) {
expect(actualEnd, expectedEnd);
expect(listener.calls, [
'handleIdentifier C typeReference',
'handleNoTypeArguments ?',
'handleType C ?',
]);
expect(listener.errors, isNull);
}

listener = new TypeInfoListener();
assertResult(
simpleNullableType.ensureTypeNotVoid(start, new Parser(listener)));

listener = new TypeInfoListener();
assertResult(
simpleNullableType.ensureTypeOrVoid(start, new Parser(listener)));

listener = new TypeInfoListener();
assertResult(
simpleNullableType.parseTypeNotVoid(start, new Parser(listener)));

listener = new TypeInfoListener();
assertResult(simpleNullableType.parseType(start, new Parser(listener)));
}
}

@reflectiveTest
class SimpleNullableTypeWith1ArgumentTest {
void test_compute() {
expectInfo(simpleNullableTypeWith1Argument, 'C<T>?', required: true);
expectInfo(simpleNullableTypeWith1Argument, 'C<T>?;', required: true);
expectInfo(simpleNullableTypeWith1Argument, 'C<T>?(', required: true);
expectInfo(simpleNullableTypeWith1Argument, 'C<T>? do', required: true);

expectInfo(simpleNullableTypeWith1Argument, 'C<T>? foo');
expectInfo(simpleNullableTypeWith1Argument, 'C<T>? get');
expectInfo(simpleNullableTypeWith1Argument, 'C<T>? set');
expectInfo(simpleNullableTypeWith1Argument, 'C<T>? operator');
expectInfo(simpleNullableTypeWith1Argument, 'C<T>? Function');
}

void test_gt_questionMark() {
final Token start = scanString('before C<T>? ;').tokens;
final Token expectedEnd = start.next.next.next.next.next;
expect(expectedEnd.lexeme, '?');

expect(simpleNullableTypeWith1Argument.skipType(start), expectedEnd);
expect(simpleNullableTypeWith1Argument.couldBeExpression, isFalse);

TypeInfoListener listener;
assertResult(Token actualEnd) {
expect(actualEnd, expectedEnd);
expect(listener.calls, [
'handleIdentifier C typeReference',
'beginTypeArguments <',
'handleIdentifier T typeReference',
'handleNoTypeArguments >',
'handleType T null',
'endTypeArguments 1 < >',
'handleType C ?',
]);
expect(listener.errors, isNull);
}

listener = new TypeInfoListener();
assertResult(simpleNullableTypeWith1Argument.ensureTypeNotVoid(
start, new Parser(listener)));

listener = new TypeInfoListener();
assertResult(simpleNullableTypeWith1Argument.ensureTypeOrVoid(
start, new Parser(listener)));

listener = new TypeInfoListener();
assertResult(simpleNullableTypeWith1Argument.parseTypeNotVoid(
start, new Parser(listener)));

listener = new TypeInfoListener();
assertResult(
simpleNullableTypeWith1Argument.parseType(start, new Parser(listener)));
}
}

@reflectiveTest
class SimpleTypeTest {
class SimpleTypeInfoTest {
void test_compute() {
expectInfo(simpleType, 'C', required: true);
expectInfo(simpleType, 'C;', required: true);
Expand All @@ -455,7 +336,7 @@ class SimpleTypeTest {
expectInfo(simpleType, 'C Function<T>(int x)', required: false);
}

void test_simpleType() {
void test_simpleTypeInfo() {
final Token start = scanString('before C ;').tokens;
final Token expectedEnd = start.next;

Expand Down Expand Up @@ -937,15 +818,10 @@ class TypeInfoTest {
expectedErrors: [
error(codeExpectedType, 2, 1)
]);
}

void test_computeType_statements() {
// Statements that should not have a type
expectInfo(noType, 'C<T ; T>U;', required: false);
expectInfo(noType, 'C<T && T>U;', required: false);

expectInfo(noType, 'C? D : E;', required: false);
expectInfo(noType, 'C? D.foo : E;', required: false);
}

void test_computeType_nested() {
Expand Down

0 comments on commit 9de66d8

Please sign in to comment.