Add a FormalParameter.isExplicitlyTyped getter.

This is needed for my work on
https://github.com/dart-lang/language/issues/731 (improved inference
for fold etc.) because I want to use slightly different heuristics
when the closure passed to `fold` has explicitly parameter types.

Change-Id: I7567df620e22bb53fcdb0f5cd8ceadf0c58c2126
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/240504
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
Paul Berry
2022-04-08 14:47:39 +00:00
committed by Commit Bot
parent a1257544e0
commit a17bd9e9bc
3 changed files with 430 additions and 0 deletions
+3
View File
@@ -2070,6 +2070,9 @@ abstract class FormalParameter implements AstNode {
/// Return `true` if this parameter was declared with the 'const' modifier.
bool get isConst;
/// Indicates whether the parameter has an explicit type.
bool get isExplicitlyTyped;
/// Return `true` if this parameter was declared with the 'final' modifier.
///
/// Parameters that are declared with the 'const' modifier will return
+15
View File
@@ -3126,6 +3126,9 @@ class DefaultFormalParameterImpl extends FormalParameterImpl
@override
bool get isConst => _parameter.isConst;
@override
bool get isExplicitlyTyped => _parameter.isExplicitlyTyped;
@override
bool get isFinal => _parameter.isFinal;
@@ -4437,6 +4440,9 @@ class FieldFormalParameterImpl extends NormalFormalParameterImpl
@override
bool get isConst => keyword?.keyword == Keyword.CONST;
@override
bool get isExplicitlyTyped => _parameters != null || _type != null;
@override
bool get isFinal => keyword?.keyword == Keyword.FINAL;
@@ -5633,6 +5639,9 @@ class FunctionTypedFormalParameterImpl extends NormalFormalParameterImpl
@override
bool get isConst => false;
@override
bool get isExplicitlyTyped => true;
@override
bool get isFinal => false;
@@ -9523,6 +9532,9 @@ class SimpleFormalParameterImpl extends NormalFormalParameterImpl
@override
bool get isConst => keyword?.keyword == Keyword.CONST;
@override
bool get isExplicitlyTyped => _type != null;
@override
bool get isFinal => keyword?.keyword == Keyword.FINAL;
@@ -10348,6 +10360,9 @@ class SuperFormalParameterImpl extends NormalFormalParameterImpl
@override
bool get isConst => keyword?.keyword == Keyword.CONST;
@override
bool get isExplicitlyTyped => _parameters != null || _type != null;
@override
bool get isFinal => keyword?.keyword == Keyword.FINAL;
+412
View File
@@ -23,6 +23,7 @@ main() {
defineReflectiveTests(ClassTypeAliasTest);
defineReflectiveTests(ConstructorDeclarationTest);
defineReflectiveTests(FieldFormalParameterTest);
defineReflectiveTests(FormalParameterIsExplicitlyTypedTest);
defineReflectiveTests(IndexExpressionTest);
defineReflectiveTests(InterpolationStringTest);
defineReflectiveTests(MethodDeclarationTest);
@@ -239,6 +240,417 @@ class FieldFormalParameterTest {
}
}
@reflectiveTest
class FormalParameterIsExplicitlyTypedTest extends ParserTestCase {
test_field_functionTyped_explicitReturn() {
_checkExplicitlyTyped('''
class C {
C(int this.x());
final Object x;
}
''', true);
}
test_field_functionTyped_explicitReturn_default() {
_checkExplicitlyTyped('''
class C {
C([int this.x() = y]);
final Object x;
}
''', true);
}
test_field_functionTyped_explicitReturn_named() {
_checkExplicitlyTyped('''
class C {
C({required int this.x()});
final Object x;
}
''', true);
}
test_field_functionTyped_explicitReturn_named_default() {
_checkExplicitlyTyped('''
class C {
C({int this.x() = y});
final Object x;
}
''', true);
}
test_field_functionTyped_implicitReturn() {
_checkExplicitlyTyped('''
class C {
C(this.x());
final Object x;
}
''', true);
}
test_field_functionTyped_implicitReturn_default() {
_checkExplicitlyTyped('''
class C {
C([this.x() = y]);
final Object x;
}
''', true);
}
test_field_functionTyped_implicitReturn_named() {
_checkExplicitlyTyped('''
class C {
C({required this.x()});
final Object x;
}
''', true);
}
test_field_functionTyped_implicitReturn_named_default() {
_checkExplicitlyTyped('''
class C {
C({this.x() = y});
final Object x;
}
''', true);
}
test_field_simple_explicit() {
_checkExplicitlyTyped('''
class C {
C(int this.x);
final Object x;
}
''', true);
}
test_field_simple_explicit_default() {
_checkExplicitlyTyped('''
class C {
C([int this.x = y]);
final Object x;
}
''', true);
}
test_field_simple_explicit_named() {
_checkExplicitlyTyped('''
class C {
C({int? this.x});
final Object? x;
}
''', true);
}
test_field_simple_explicit_named_default() {
_checkExplicitlyTyped('''
class C {
C({int this.x = y});
final Object x;
}
''', true);
}
test_field_simple_implicit() {
_checkExplicitlyTyped('''
class C {
C(this.x);
final Object x;
}
''', false);
}
test_field_simple_implicit_default() {
_checkExplicitlyTyped('''
class C {
C([this.x = y]);
final Object x;
}
''', false);
}
test_field_simple_implicit_named() {
_checkExplicitlyTyped('''
class C {
C({this.x});
final Object? x;
}
''', false);
}
test_field_simple_implicit_named_default() {
_checkExplicitlyTyped('''
class C {
C({this.x = y});
final Object x;
}
''', false);
}
test_functionTyped_explicitReturn() {
_checkExplicitlyTyped('''
class C {
C(int x());
}
''', true);
}
test_functionTyped_explicitReturn_default() {
_checkExplicitlyTyped('''
class C {
C([int x() = y]);
}
''', true);
}
test_functionTyped_explicitReturn_named() {
_checkExplicitlyTyped('''
class C {
C({required int x()});
}
''', true);
}
test_functionTyped_explicitReturn_named_default() {
_checkExplicitlyTyped('''
class C {
C({int x() = y});
}
''', true);
}
test_functionTyped_implicitReturn() {
_checkExplicitlyTyped('''
class C {
C(x());
}
''', true);
}
test_functionTyped_implicitReturn_default() {
_checkExplicitlyTyped('''
class C {
C([x() = y]);
}
''', true);
}
test_functionTyped_implicitReturn_named() {
_checkExplicitlyTyped('''
class C {
C({required x()});
}
''', true);
}
test_functionTyped_implicitReturn_named_default() {
_checkExplicitlyTyped('''
class C {
C({x() = y});
}
''', true);
}
test_simple_explicit() {
_checkExplicitlyTyped('''
class C {
C(int x);
}
''', true);
}
test_simple_explicit_default() {
_checkExplicitlyTyped('''
class C {
C([int x = y]);
}
''', true);
}
test_simple_explicit_named() {
_checkExplicitlyTyped('''
class C {
C({int? x});
}
''', true);
}
test_simple_explicit_named_default() {
_checkExplicitlyTyped('''
class C {
C({int x = y});
}
''', true);
}
test_simple_implicit() {
_checkExplicitlyTyped('''
class C {
C(x);
}
''', false);
}
test_simple_implicit_default() {
_checkExplicitlyTyped('''
class C {
C([x = y]);
}
''', false);
}
test_simple_implicit_named() {
_checkExplicitlyTyped('''
class C {
C({x});
}
''', false);
}
test_simple_implicit_named_default() {
_checkExplicitlyTyped('''
class C {
C({x = y});
}
''', false);
}
test_super_functionTyped_explicitReturn() {
_checkExplicitlyTyped('''
class C extends B {
C(int super.x());
}
''', true);
}
test_super_functionTyped_explicitReturn_default() {
_checkExplicitlyTyped('''
class C extends B {
C([int super.x() = y]);
}
''', true);
}
test_super_functionTyped_explicitReturn_named() {
_checkExplicitlyTyped('''
class C extends B {
C({required int super.x()});
}
''', true);
}
test_super_functionTyped_explicitReturn_named_default() {
_checkExplicitlyTyped('''
class C extends B {
C({int super.x() = y});
}
''', true);
}
test_super_functionTyped_implicitReturn() {
_checkExplicitlyTyped('''
class C extends B {
C(super.x());
}
''', true);
}
test_super_functionTyped_implicitReturn_default() {
_checkExplicitlyTyped('''
class C extends B {
C([super.x() = y]);
}
''', true);
}
test_super_functionTyped_implicitReturn_named() {
_checkExplicitlyTyped('''
class C extends B {
C({required super.x()});
}
''', true);
}
test_super_functionTyped_implicitReturn_named_default() {
_checkExplicitlyTyped('''
class C extends B {
C({super.x() = y});
}
''', true);
}
test_super_simple_explicit() {
_checkExplicitlyTyped('''
class C extends B {
C(int super.x);
}
''', true);
}
test_super_simple_explicit_default() {
_checkExplicitlyTyped('''
class C extends B {
C([int super.x = y]);
}
''', true);
}
test_super_simple_explicit_named() {
_checkExplicitlyTyped('''
class C extends B {
C({int? super.x});
}
''', true);
}
test_super_simple_explicit_named_default() {
_checkExplicitlyTyped('''
class C extends B {
C({int super.x = y});
}
''', true);
}
test_super_simple_implicit() {
_checkExplicitlyTyped('''
class C extends B {
C(super.x);
}
''', false);
}
test_super_simple_implicit_default() {
_checkExplicitlyTyped('''
class C extends B {
C([super.x = y]);
}
''', false);
}
test_super_simple_implicit_named() {
_checkExplicitlyTyped('''
class C extends B {
C({super.x});
}
''', false);
}
test_super_simple_implicit_named_default() {
_checkExplicitlyTyped('''
class C extends B {
C({super.x = y});
}
''', false);
}
void _checkExplicitlyTyped(String input, bool expected) {
var parseResult = parseString(content: input);
var class_ = parseResult.unit.declarations[0] as ClassDeclaration;
var constructor = class_.members[0] as ConstructorDeclaration;
var parameter = constructor.parameters.parameters[0];
expect(parameter.isExplicitlyTyped, expected);
}
}
@reflectiveTest
class IndexExpressionTest extends _AstTest {
void test_inGetterContext_assignment_compound_left() {