Split DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE off; fixes #30084 and
fixes https://github.com/dart-lang/linter/issues/1349
Bug: https://github.com/dart-lang/sdk/issues/30084
Change-Id: I4954b883c1baf019a62776fec108eac60960b22e
Reviewed-on: https://dart-review.googlesource.com/c/88881
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 3e41b50..fdaed1b 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -277,9 +277,10 @@
HintCode.DEAD_CODE,
HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH,
HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
- HintCode.DEPRECATED_MEMBER_USE,
- HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION,
HintCode.DEPRECATED_EXTENDS_FUNCTION,
+ HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION,
+ HintCode.DEPRECATED_MEMBER_USE,
+ HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE,
HintCode.DEPRECATED_MIXIN_FUNCTION,
HintCode.DIVISION_OPTIMIZATION,
HintCode.DUPLICATE_IMPORT,
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 9c10fe7..62c6a8a 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -68,6 +68,23 @@
"Try replacing the use of the deprecated member with the replacement.");
/**
+ * Deprecated members should not be invoked or used from within the package
+ * where they are declared.
+ *
+ * Intentionally separate from DEPRECATED_MEMBER_USE, so that package owners
+ * can ignore same-package deprecate member use Hints if they like, and
+ * continue to see cross-package deprecated member use Hints.
+ *
+ * Parameters:
+ * 0: the name of the member
+ */
+ static const HintCode DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE = const HintCode(
+ 'DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE',
+ "'{0}' is deprecated and shouldn't be used.",
+ correction:
+ "Try replacing the use of the deprecated member with the replacement.");
+
+ /**
* Users should not create a class named `Function` anymore.
*/
static const HintCode DEPRECATED_FUNCTION_CLASS_DECLARATION = const HintCode(
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 050e255..9dc3ff1 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -716,11 +716,16 @@
} else if (displayName == FunctionElement.CALL_METHOD_NAME &&
node is MethodInvocation &&
node.staticInvokeType is InterfaceType) {
- displayName =
- "${resolutionMap.staticInvokeTypeForInvocationExpression(node).displayName}.${element.displayName}";
+ DartType staticInvokeType =
+ resolutionMap.staticInvokeTypeForInvocationExpression(node);
+ displayName = "${staticInvokeType.displayName}.${element.displayName}";
}
- _errorReporter.reportErrorForNode(
- HintCode.DEPRECATED_MEMBER_USE, node, [displayName]);
+ LibraryElement library =
+ element is LibraryElement ? element : element.library;
+ HintCode hintCode = _workspacePackage.contains(library.source.fullName)
+ ? HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE
+ : HintCode.DEPRECATED_MEMBER_USE;
+ _errorReporter.reportErrorForNode(hintCode, node, [displayName]);
}
}
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 485d871..a682c9d 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -35,6 +35,8 @@
import 'analysis_context_factory.dart';
import 'test_support.dart';
+const String _defaultSourceName = "/test.dart";
+
/**
* An AST visitor used to verify that all of the nodes in an AST structure that
* should have been resolved were resolved.
@@ -407,7 +409,8 @@
* file will have the given [contents] set in the content provider. Return the
* source representing the added file.
*/
- Source addSource(String contents) => addNamedSource("/test.dart", contents);
+ Source addSource(String contents) =>
+ addNamedSource(_defaultSourceName, contents);
/**
* The [code] that assigns the value to the variable "v", no matter how. We
@@ -457,8 +460,8 @@
*/
// TODO(rnystrom): Use this in more tests that have the same structure.
Future<void> assertErrorsInCode(String code, List<ErrorCode> errors,
- {bool verify: true}) async {
- Source source = addSource(code);
+ {bool verify: true, String sourceName: _defaultSourceName}) async {
+ Source source = addNamedSource(sourceName, code);
await computeAnalysisResult(source);
assertErrors(source, errors);
if (verify) {
diff --git a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
index b65409d..1dcc23e 100644
--- a/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/deprecated_member_use_test.dart
@@ -3,12 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../generated/resolver_test_case.dart';
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(DeprecatedMemberUseFromSamePackageTest);
+ defineReflectiveTests(DeprecatedMemberUseFromSamePackageTest_Driver);
defineReflectiveTests(DeprecatedMemberUseTest);
defineReflectiveTests(DeprecatedMemberUseTest_Driver);
});
@@ -16,14 +19,92 @@
@reflectiveTest
class DeprecatedMemberUseTest extends ResolverTestCase {
- test__methodInvocation_contructor() async {
- await assertErrorsInCode(r'''
+ /// Write a pubspec file at [root], so that BestPracticesVerifier can see that
+ /// [root] is the root of a BasicWorkspace, and a BasicWorkspacePackage.
+ void newBasicPackage(String root) {
+ newFile('$root/pubspec.yaml');
+ }
+
+ test_methodInvocation_contructor() async {
+ resetWithFooLibrary(r'''
+class A {
+ @Deprecated('0.9')
+ m() {}
+}
+''');
+
+ newBasicPackage('/pkg1');
+ assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+void main() => A().m();
+''', [HintCode.DEPRECATED_MEMBER_USE], sourceName: '/pkg1/lib/lib1.dart');
+ }
+
+ test_methodInvocation_constant() async {
+ resetWithFooLibrary(r'''
+class A {
+ @deprecated
+ m() {}
+}
+''');
+
+ newBasicPackage('/pkg1');
+ assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+void main() => A().m();
+''', [HintCode.DEPRECATED_MEMBER_USE], sourceName: '/pkg1/lib/lib1.dart');
+ }
+
+ void resetWithFooLibrary(String source) {
+ super.resetWith(packages: [
+ ['foo', source]
+ ]);
+ }
+
+ test_export() async {
+ resetWithFooLibrary(r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+ newBasicPackage('/pkg1');
+ assertErrorsInCode('''
+export 'package:foo/foo.dart';
+''', [HintCode.DEPRECATED_MEMBER_USE], sourceName: '/pkg1/lib/lib1.dart');
+ }
+
+ test_import() async {
+ resetWithFooLibrary(r'''
+@deprecated
+library deprecated_library;
+class A {}
+''');
+
+ newBasicPackage('/pkg1');
+ assertErrorsInCode(r'''
+import 'package:foo/foo.dart';
+f(A a) {}
+''', [HintCode.DEPRECATED_MEMBER_USE], sourceName: '/pkg1/lib/lib1.dart');
+ }
+}
+
+@reflectiveTest
+class DeprecatedMemberUseTest_Driver extends DeprecatedMemberUseTest {
+ @override
+ bool get enableNewAnalysisDriver => true;
+}
+
+@reflectiveTest
+class DeprecatedMemberUseFromSamePackageTest extends ResolverTestCase {
+ test_methodInvocation_contructor() async {
+ assertErrorsInCode(r'''
class A {
@Deprecated('0.9')
m() {}
n() {m();}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_call() async {
@@ -36,7 +117,7 @@
a();
}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_compoundAssignment() async {
@@ -49,7 +130,7 @@
A b;
a += b;
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_export() async {
@@ -60,7 +141,7 @@
''');
await assertErrorsInCode('''
export 'deprecated_library.dart';
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_field() async {
@@ -72,7 +153,7 @@
f(A a) {
return a.x;
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_getter() async {
@@ -84,7 +165,7 @@
f(A a) {
return a.m;
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_import() async {
@@ -96,7 +177,7 @@
await assertErrorsInCode(r'''
import 'deprecated_library.dart';
f(A a) {}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_inDeprecatedClass() async {
@@ -215,7 +296,7 @@
f(A a) {
return a[1];
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_instanceCreation_defaultConstructor() async {
@@ -227,7 +308,7 @@
f() {
A a = new A(1);
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_instanceCreation_namedConstructor() async {
@@ -239,7 +320,7 @@
f() {
A a = new A.named(1);
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_methodInvocation_constant() async {
@@ -249,7 +330,7 @@
m() {}
n() {m();}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_operator() async {
@@ -262,7 +343,7 @@
A b;
return a + b;
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_parameter_named() async {
@@ -271,7 +352,7 @@
m({@deprecated int x}) {}
n() {m(x: 1);}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_parameter_named_inDefiningFunction() async {
@@ -322,7 +403,7 @@
m([@deprecated int x]) {}
n() {m(1);}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_setter() async {
@@ -334,7 +415,7 @@
f(A a) {
return a.s = 1;
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_superConstructor_defaultConstructor() async {
@@ -346,7 +427,7 @@
class B extends A {
B() : super() {}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
test_superConstructor_namedConstructor() async {
@@ -358,12 +439,13 @@
class B extends A {
B() : super.named() {}
}
-''', [HintCode.DEPRECATED_MEMBER_USE]);
+''', [HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE]);
}
}
@reflectiveTest
-class DeprecatedMemberUseTest_Driver extends DeprecatedMemberUseTest {
+class DeprecatedMemberUseFromSamePackageTest_Driver
+ extends DeprecatedMemberUseFromSamePackageTest {
@override
bool get enableNewAnalysisDriver => true;
}
diff --git a/pkg/compiler/analysis_options.yaml b/pkg/compiler/analysis_options.yaml
index 3400954..af22f6b 100644
--- a/pkg/compiler/analysis_options.yaml
+++ b/pkg/compiler/analysis_options.yaml
@@ -5,4 +5,8 @@
analyzer:
errors:
todo: ignore
+ # Allow cross-package deprecated calls
+ # TODO(srawlins): clean these up and remove this "ignore."
deprecated_member_use: ignore
+ # Allow deprecated calls from within the same package
+ deprecated_member_use_from_same_package: ignore
diff --git a/pkg/front_end/analysis_options.yaml b/pkg/front_end/analysis_options.yaml
index d5ea4fe..ae13d06 100644
--- a/pkg/front_end/analysis_options.yaml
+++ b/pkg/front_end/analysis_options.yaml
@@ -9,6 +9,8 @@
# Allow having TODOs in the code
todo: ignore
- # Allow deprecated calls (although it would be nice to have a distinction
- # between internal and external deprecated calls).
+ # Allow cross-package deprecated calls
+ # TODO(srawlins): clean these up and remove this "ignore."
deprecated_member_use: ignore
+ # Allow deprecated calls from within the same package
+ deprecated_member_use_from_same_package: ignore