diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart index d49cca39806..a1acd974122 100644 --- a/pkg/analyzer/lib/dart/ast/ast.dart +++ b/pkg/analyzer/lib/dart/ast/ast.dart @@ -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 diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 7c3815a566b..1a0b64c03fb 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -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; diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart index a29e78d3d7f..b1e5ccab31a 100644 --- a/pkg/analyzer/test/dart/ast/ast_test.dart +++ b/pkg/analyzer/test/dart/ast/ast_test.dart @@ -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() {