From dfdc7e45c5baea07de8de582ed2d50ed218df47a Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 9 Jul 2020 21:51:50 +0000 Subject: [PATCH] Report PRIVATE_SETTER. Change-Id: I823582328b4b9cc63ac734e9ea1c9354175a6e18 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153880 Commit-Queue: Konstantin Shcheglov Reviewed-by: Brian Wilkerson --- pkg/analyzer/lib/error/error.dart | 1 + pkg/analyzer/lib/src/error/codes.dart | 6 + .../lib/src/generated/element_resolver.dart | 9 +- .../src/diagnostics/private_setter_test.dart | 113 ++++++++++++++++++ .../test/src/diagnostics/test_all.dart | 2 + 5 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 pkg/analyzer/test/src/diagnostics/private_setter_test.dart diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart index 17ec5c42f052..fcfc708274d6 100644 --- a/pkg/analyzer/lib/error/error.dart +++ b/pkg/analyzer/lib/error/error.dart @@ -288,6 +288,7 @@ const List errorCodeValues = [ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION, CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, + CompileTimeErrorCode.PRIVATE_SETTER, CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart index 594b3754f943..21c9153e93de 100644 --- a/pkg/analyzer/lib/src/error/codes.dart +++ b/pkg/analyzer/lib/src/error/codes.dart @@ -5608,6 +5608,12 @@ class CompileTimeErrorCode extends AnalyzerErrorCode { CompileTimeErrorCode('PRIVATE_OPTIONAL_PARAMETER', "Named optional parameters can't start with an underscore."); + static const CompileTimeErrorCode PRIVATE_SETTER = CompileTimeErrorCode( + 'PRIVATE_SETTER', + "The setter '{0}' is private and can't be accessed outside of the " + "library that declares it.", + correction: "Try making it public."); + /** * 12.1 Constants: It is a compile-time error if the value of a compile-time * constant expression depends on itself. diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart index f4ecf9495d34..90cfb5662d8d 100644 --- a/pkg/analyzer/lib/src/generated/element_resolver.dart +++ b/pkg/analyzer/lib/src/generated/element_resolver.dart @@ -1334,8 +1334,15 @@ class ElementResolver extends SimpleAstVisitor { ExecutableElement element; var setter = typeReference.getSetter(propertyName.name); - if (setter != null && setter.isAccessibleIn(_definingLibrary)) { + if (setter != null) { element = setter; + if (!setter.isAccessibleIn(_definingLibrary)) { + _errorReporter.reportErrorForNode( + CompileTimeErrorCode.PRIVATE_SETTER, + propertyName, + [propertyName.name, typeReference.name], + ); + } } if (element != null) { diff --git a/pkg/analyzer/test/src/diagnostics/private_setter_test.dart b/pkg/analyzer/test/src/diagnostics/private_setter_test.dart new file mode 100644 index 000000000000..9566d3cd1e0e --- /dev/null +++ b/pkg/analyzer/test/src/diagnostics/private_setter_test.dart @@ -0,0 +1,113 @@ +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:analyzer/src/error/codes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import '../dart/resolution/driver_resolution.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(PrivateSetterTest); + }); +} + +@reflectiveTest +class PrivateSetterTest extends DriverResolutionTest { + test_typeLiteral_privateField_differentLibrary() async { + newFile('/test/lib/a.dart', content: r''' +class A { + static int _foo = 0; +} +'''); + await assertErrorsInCode(r''' +import 'a.dart'; + +main() { + A._foo = 0; +} +''', [ + error(CompileTimeErrorCode.PRIVATE_SETTER, 31, 4), + ]); + + var aImport = findElement.importFind('package:test/a.dart'); + assertElement( + findNode.simple('_foo = 0'), + aImport.setter('_foo'), + ); + } + + test_typeLiteral_privateField_sameLibrary() async { + await assertNoErrorsInCode(r''' +class A { + // ignore:unused_field + static int _foo = 0; +} + +main() { + A._foo = 0; +} +'''); + } + + test_typeLiteral_privateSetter__sameLibrary() async { + await assertNoErrorsInCode(r''' +class A { + static set _foo(int _) {} +} + +main() { + A._foo = 0; +} +'''); + } + + test_typeLiteral_privateSetter_differentLibrary_hasGetter() async { + newFile('/test/lib/a.dart', content: r''' +class A { + static set _foo(int _) {} + + static int get _foo => 0; +} +'''); + await assertErrorsInCode(r''' +import 'a.dart'; + +main() { + A._foo = 0; +} +''', [ + error(CompileTimeErrorCode.PRIVATE_SETTER, 31, 4), + ]); + + var aImport = findElement.importFind('package:test/a.dart'); + assertElement( + findNode.simple('_foo = 0'), + aImport.setter('_foo'), + ); + } + + test_typeLiteral_privateSetter_differentLibrary_noGetter() async { + newFile('/test/lib/a.dart', content: r''' +class A { + static set _foo(int _) {} +} +'''); + await assertErrorsInCode(r''' +import 'a.dart'; + +main() { + A._foo = 0; +} +''', [ + error(CompileTimeErrorCode.PRIVATE_SETTER, 31, 4), + ]); + + var aImport = findElement.importFind('package:test/a.dart'); + assertElement( + findNode.simple('_foo = 0'), + aImport.setter('_foo'), + ); + } +} diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart index 2091498e9116..2c9a764a2f2c 100644 --- a/pkg/analyzer/test/src/diagnostics/test_all.dart +++ b/pkg/analyzer/test/src/diagnostics/test_all.dart @@ -397,6 +397,7 @@ import 'prefix_identifier_not_followed_by_dot_test.dart' import 'private_collision_in_mixin_application_test.dart' as private_collision_in_mixin_application; import 'private_optional_parameter_test.dart' as private_optional_parameter; +import 'private_setter_test.dart' as private_setter; import 'receiver_of_type_never_test.dart' as receiver_of_type_never; import 'recursive_compile_time_constant_test.dart' as recursive_compile_time_constant; @@ -805,6 +806,7 @@ main() { prefix_identifier_not_followed_by_dot.main(); private_collision_in_mixin_application.main(); private_optional_parameter.main(); + private_setter.main(); receiver_of_type_never.main(); recursive_compile_time_constant.main(); recursive_constructor_redirect.main();