diff --git a/lib/src/rules/library_private_types_in_public_api.dart b/lib/src/rules/library_private_types_in_public_api.dart index 050a327fe..26043d78e 100644 --- a/lib/src/rules/library_private_types_in_public_api.dart +++ b/lib/src/rules/library_private_types_in_public_api.dart @@ -132,8 +132,20 @@ class Validator extends SimpleAstVisitor { node.members.accept(this); } + @override + void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { + if (Identifier.isPrivateName(node.name.lexeme)) return; + node.typeParameters?.accept(this); + var representation = node.representation; + if (!Identifier.isPrivateName(representation.fieldName.lexeme)) { + representation.fieldType.accept(this); + } + node.members.accept(this); + } + @override void visitFieldDeclaration(FieldDeclaration node) { + if (node.isInvalidExtensionTypeField) return; if (node.fields.variables .any((field) => !Identifier.isPrivateName(field.name.lexeme))) { node.fields.type?.accept(this); diff --git a/lib/src/rules/public_member_api_docs.dart b/lib/src/rules/public_member_api_docs.dart index a8d21477d..1d433d76f 100644 --- a/lib/src/rules/public_member_api_docs.dart +++ b/lib/src/rules/public_member_api_docs.dart @@ -172,13 +172,6 @@ class _Visitor extends SimpleAstVisitor { _visitMembers(node, node.name, node.members); } - @override - void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { - var element = node.declaredElement; - if (element == null || element.hasInternal) return; - _visitMembers(node, node.name, node.members); - } - @override void visitClassTypeAlias(ClassTypeAlias node) { if (!isPrivate(node.name)) { @@ -272,6 +265,13 @@ class _Visitor extends SimpleAstVisitor { checkMethods(node.members); } + @override + void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { + var element = node.declaredElement; + if (element == null || element.hasInternal) return; + _visitMembers(node, node.name, node.members); + } + @override void visitFieldDeclaration(FieldDeclaration node) { // todo(pq): update this to be called from the parent (like with visitMembers) diff --git a/test/rules/library_private_types_in_public_api_test.dart b/test/rules/library_private_types_in_public_api_test.dart index f65f08d5a..ecc17da4a 100644 --- a/test/rules/library_private_types_in_public_api_test.dart +++ b/test/rules/library_private_types_in_public_api_test.dart @@ -9,6 +9,7 @@ import '../rule_test_support.dart'; main() { defineReflectiveSuite(() { defineReflectiveTests(LibraryPrivateTypesInPublicApiEnumTest); + defineReflectiveTests(LibraryPrivateTypesInPublicApiExtensionTypeTest); defineReflectiveTests(LibraryPrivateTypesInPublicApiSuperParamTest); }); } @@ -84,6 +85,140 @@ sealed class E { } } +@reflectiveTest +class LibraryPrivateTypesInPublicApiExtensionTypeTest extends LintRuleTest { + @override + List get experiments => ['inline-class']; + + @override + String get lintRule => 'library_private_types_in_public_api'; + + test_constructorParam() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + E.e(_C c) : o = c; +} +''', [ + lint(47, 2), + ]); + } + + test_extensionTypeDeclaration_representation() async { + await assertDiagnostics(r''' +class _C {} +extension type E(_C c) {} +''', [ + lint(29, 2), + ]); + } + + test_extensionTypeDeclaration_representation_private() async { + await assertNoDiagnostics(r''' +class _C {} +extension type E(_C _c) {} +'''); + } + + test_extensionTypeDeclaration_typeParam() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) {} +''', [ + lint(39, 2), + ]); + } + + test_field_instance() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + _C? c; +} +''', [ + // No lint. + // todo(pq): add compilation error once reported + ]); + } + + test_field_static() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + static _C? c; +} +''', [ + lint(50, 2), + ]); + } + + test_method_instance_param() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + m(_C c){} +} +''', [ + lint(45, 2), + ]); + } + + test_method_instance_private_param() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + _m(_C c){} +} +''', [ + error(WarningCode.UNUSED_ELEMENT, 43, 2), + ]); + } + + test_method_instance_returnType() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + _C? m() => null; +} +''', [ + lint(43, 2), + ]); + } + + test_method_static_param() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + static m(_C c){} +} +''', [ + lint(52, 2), + ]); + } + + test_method_static_private_returnType() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + static _C? _m() => null; +} +''', [ + error(WarningCode.UNUSED_ELEMENT, 54, 2), + ]); + } + + test_method_static_returnType() async { + await assertDiagnostics(r''' +class _C {} +extension type E(Object o) { + static _C? m() => null; +} +''', [ + lint(50, 2), + ]); + } +} + @reflectiveTest class LibraryPrivateTypesInPublicApiSuperParamTest extends LintRuleTest { @override