Skip to content

Commit e200712

Browse files
author
danrubel
committed
Revert support for simple nullable type return value in generalized function type
This reverts commit 11d081d Reason for revert: Breaks parsing less common conditionals (e.g. b ? c = true : g();) Original change's description: > Add support for simple nullable type return value in generalized function type > > This only supports nullable return values of the form > > <identifier> '?' 'Function' '(' ... > > This is an increment CL in the ongoing effort to add nullable type support > as outlined in dart-lang/language#110 Change-Id: I99bce29619d4e448193e3c81fa86a982791b1f77 Reviewed-on: https://dart-review.googlesource.com/c/87283 Reviewed-by: Dan Rubel <[email protected]>
1 parent 4949f89 commit e200712

File tree

4 files changed

+22
-115
lines changed

4 files changed

+22
-115
lines changed

pkg/analyzer/test/generated/parser_test.dart

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,46 +2013,6 @@ mixin ComplexParserTestMixin implements AbstractParserTestCase {
20132013
expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
20142014
}
20152015

2016-
void test_conditionalExpression_precedence_nullableTypeWithTypeArg1_is() {
2017-
Expression expression = parseExpression('x is String<S> ? (x + y) : z');
2018-
expect(expression, isNotNull);
2019-
expect(expression, new TypeMatcher<ConditionalExpression>());
2020-
ConditionalExpression conditional = expression;
2021-
Expression condition = conditional.condition;
2022-
expect(condition, new TypeMatcher<IsExpression>());
2023-
Expression thenExpression = conditional.thenExpression;
2024-
expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
2025-
Expression elseExpression = conditional.elseExpression;
2026-
expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
2027-
}
2028-
2029-
void test_conditionalExpression_precedence_nullableTypeWithTypeArg1GFT_is() {
2030-
Expression expression =
2031-
parseExpression('x is String<S> Function() ? (x + y) : z');
2032-
expect(expression, isNotNull);
2033-
expect(expression, new TypeMatcher<ConditionalExpression>());
2034-
ConditionalExpression conditional = expression;
2035-
Expression condition = conditional.condition;
2036-
expect(condition, new TypeMatcher<IsExpression>());
2037-
Expression thenExpression = conditional.thenExpression;
2038-
expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
2039-
Expression elseExpression = conditional.elseExpression;
2040-
expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
2041-
}
2042-
2043-
void test_conditionalExpression_precedence_nullableTypeWithTypeArg2_is() {
2044-
Expression expression = parseExpression('x is String<S,T> ? (x + y) : z');
2045-
expect(expression, isNotNull);
2046-
expect(expression, new TypeMatcher<ConditionalExpression>());
2047-
ConditionalExpression conditional = expression;
2048-
Expression condition = conditional.condition;
2049-
expect(condition, new TypeMatcher<IsExpression>());
2050-
Expression thenExpression = conditional.thenExpression;
2051-
expect(thenExpression, new TypeMatcher<ParenthesizedExpression>());
2052-
Expression elseExpression = conditional.elseExpression;
2053-
expect(elseExpression, new TypeMatcher<SimpleIdentifier>());
2054-
}
2055-
20562016
void test_constructor_initializer_withParenthesizedExpression() {
20572017
CompilationUnit unit = parseCompilationUnit(r'''
20582018
class C {

pkg/front_end/lib/src/fasta/parser/type_info.dart

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ TypeInfo computeType(final Token token, bool required,
187187
if (isGeneralizedFunctionType(next)) {
188188
// `Function` ...
189189
return new ComplexTypeInfo(token, noTypeParamOrArg)
190-
.computeNoTypeGFT(token, required);
190+
.computeNoTypeGFT(required);
191191
}
192192

193193
// We've seen an identifier.
@@ -262,17 +262,20 @@ TypeInfo computeType(final Token token, bool required,
262262
}
263263

264264
if (optional('?', next)) {
265-
next = next.next;
266-
if (isGeneralizedFunctionType(next)) {
267-
// identifier `?` Function `(`
268-
return new ComplexTypeInfo(token, noTypeParamOrArg)
269-
.computeIdentifierQuestionGFT(required);
270-
} else if (required ||
271-
(looksLikeName(next) &&
272-
isOneOfOrEof(
273-
next.next, const [';', ',', '=', '>', '>=', '>>', '>>>']))) {
265+
if (required) {
274266
// identifier `?`
275267
return simpleNullableType;
268+
} else {
269+
next = next.next;
270+
if (isGeneralizedFunctionType(next)) {
271+
// identifier `?` Function `(`
272+
return simpleNullableType;
273+
} else if (looksLikeName(next) &&
274+
isOneOfOrEof(
275+
next.next, const [';', ',', '=', '>', '>=', '>>', '>>>'])) {
276+
// identifier `?` identifier `=`
277+
return simpleNullableType;
278+
}
276279
}
277280
} else if (required || looksLikeName(next)) {
278281
// identifier identifier

pkg/front_end/lib/src/fasta/parser/type_info_impl.dart

Lines changed: 9 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,6 @@ class ComplexTypeInfo implements TypeInfo {
376376
/// Type arguments were seen during analysis.
377377
final TypeParamOrArgInfo typeArguments;
378378

379-
/// The token before the trailing question mark or `null` if none.
380-
Token beforeQuestionMark;
381-
382379
/// The last token in the type reference.
383380
Token end;
384381

@@ -393,18 +390,12 @@ class ComplexTypeInfo implements TypeInfo {
393390
ComplexTypeInfo(Token beforeStart, this.typeArguments)
394391
: this.start = beforeStart.next;
395392

396-
ComplexTypeInfo._nonNullable(this.start, this.typeArguments, this.end,
397-
this.typeVariableStarters, this.gftHasReturnType);
398-
399393
@override
400394
bool get couldBeExpression => false;
401395

402396
@override
403397
TypeInfo asNonNullableType() {
404-
return beforeQuestionMark == null
405-
? this
406-
: new ComplexTypeInfo._nonNullable(start, typeArguments,
407-
beforeQuestionMark, typeVariableStarters, gftHasReturnType);
398+
return this;
408399
}
409400

410401
@override
@@ -461,15 +452,7 @@ class ComplexTypeInfo implements TypeInfo {
461452
}
462453
}
463454
token = typeArguments.parseArguments(token, parser);
464-
Token questionMark = token.next;
465-
if (optional('?', questionMark) &&
466-
(typeVariableEndGroups.isNotEmpty || beforeQuestionMark != null)) {
467-
// Only consume the `?` if it is part of the complex type
468-
token = questionMark;
469-
} else {
470-
questionMark = null;
471-
}
472-
parser.listener.handleType(typeRefOrPrefix, questionMark);
455+
parser.listener.handleType(typeRefOrPrefix, null);
473456
}
474457
}
475458

@@ -509,11 +492,10 @@ class ComplexTypeInfo implements TypeInfo {
509492

510493
/// Given `Function` non-identifier, compute the type
511494
/// and return the receiver or one of the [TypeInfo] constants.
512-
TypeInfo computeNoTypeGFT(Token beforeStart, bool required) {
495+
TypeInfo computeNoTypeGFT(bool required) {
513496
assert(optional('Function', start));
514-
assert(beforeStart.next == start);
515497

516-
computeRest(beforeStart, required);
498+
computeRest(start, required);
517499
if (gftHasReturnType == null) {
518500
return required ? simpleType : noType;
519501
}
@@ -527,7 +509,7 @@ class ComplexTypeInfo implements TypeInfo {
527509
assert(optional('void', start));
528510
assert(optional('Function', start.next));
529511

530-
computeRest(start, required);
512+
computeRest(start.next, required);
531513
if (gftHasReturnType == null) {
532514
return voidType;
533515
}
@@ -541,36 +523,21 @@ class ComplexTypeInfo implements TypeInfo {
541523
assert(isValidTypeReference(start));
542524
assert(optional('Function', start.next));
543525

544-
computeRest(start, required);
526+
computeRest(start.next, required);
545527
if (gftHasReturnType == null) {
546528
return simpleType;
547529
}
548530
assert(end != null);
549531
return this;
550532
}
551533

552-
/// Given identifier `?` `Function` non-identifier, compute the type
553-
/// and return the receiver or one of the [TypeInfo] constants.
554-
TypeInfo computeIdentifierQuestionGFT(bool required) {
555-
assert(isValidTypeReference(start));
556-
assert(optional('?', start.next));
557-
assert(optional('Function', start.next.next));
558-
559-
computeRest(start, required);
560-
if (gftHasReturnType == null) {
561-
return simpleNullableType;
562-
}
563-
assert(end != null);
564-
return this;
565-
}
566-
567534
/// Given a builtin, return the receiver so that parseType will report
568535
/// an error for the builtin used as a type.
569536
TypeInfo computeBuiltinOrVarAsType(bool required) {
570537
assert(start.type.isBuiltIn || optional('var', start));
571538

572539
end = typeArguments.skip(start);
573-
computeRest(end, required);
540+
computeRest(end.next, required);
574541
assert(end != null);
575542
return this;
576543
}
@@ -583,7 +550,7 @@ class ComplexTypeInfo implements TypeInfo {
583550
assert(typeArguments != noTypeParamOrArg);
584551

585552
end = typeArguments.skip(start);
586-
computeRest(end, required);
553+
computeRest(end.next, required);
587554

588555
if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
589556
return noType;
@@ -607,7 +574,7 @@ class ComplexTypeInfo implements TypeInfo {
607574
}
608575

609576
end = typeArguments.skip(token);
610-
computeRest(end, required);
577+
computeRest(end.next, required);
611578
if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
612579
return noType;
613580
}
@@ -616,11 +583,6 @@ class ComplexTypeInfo implements TypeInfo {
616583
}
617584

618585
void computeRest(Token token, bool required) {
619-
if (optional('?', token.next)) {
620-
beforeQuestionMark = token;
621-
end = token = token.next;
622-
}
623-
token = token.next;
624586
while (optional('Function', token)) {
625587
Token typeVariableStart = token;
626588
// TODO(danrubel): Consider caching TypeParamOrArgInfo
@@ -641,14 +603,9 @@ class ComplexTypeInfo implements TypeInfo {
641603
assert(optional(')', token));
642604
gftHasReturnType ??= typeVariableStart != start;
643605
typeVariableStarters = typeVariableStarters.prepend(typeVariableStart);
644-
beforeQuestionMark = null;
645606
end = token;
646607
token = token.next;
647608
}
648-
if (optional('?', token)) {
649-
beforeQuestionMark = end;
650-
end = token;
651-
}
652609
}
653610
}
654611

pkg/front_end/test/fasta/parser/type_info_test.dart

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -800,19 +800,6 @@ class TypeInfoTest {
800800
]);
801801
}
802802

803-
void test_computeType_identifierComplex_questionMark() {
804-
expectComplexInfo('C? Function()', required: true, expectedCalls: [
805-
'handleNoTypeVariables (',
806-
'beginFunctionType C',
807-
'handleIdentifier C typeReference',
808-
'handleNoTypeArguments ?',
809-
'handleType C ?',
810-
'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
811-
'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
812-
'endFunctionType Function null',
813-
]);
814-
}
815-
816803
void test_computeType_identifierTypeArg() {
817804
expectComplexInfo('C<void>', required: true, expectedCalls: [
818805
'handleIdentifier C typeReference',

0 commit comments

Comments
 (0)