diff --git a/pkg/analyzer/lib/src/test_utilities/mock_packages.dart b/pkg/analyzer/lib/src/test_utilities/mock_packages.dart index 642a820bf03..e0f38100654 100644 --- a/pkg/analyzer/lib/src/test_utilities/mock_packages.dart +++ b/pkg/analyzer/lib/src/test_utilities/mock_packages.dart @@ -5,6 +5,9 @@ import 'package:analyzer/file_system/file_system.dart'; /// Helper for creating mock packages. +// TODO(brianwilkerson): Deprecate or remove this class after the internal uses +// of the class have been removed. +// @Deprecated('Use MockPackagesMixin from analyzer_utilities') class MockPackages { /// Create a fake 'angular' package that can be used by tests. static void addAngularMetaPackageFiles(Folder rootFolder) { diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart index 46fa4ea249e..79bdf78caad 100644 --- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart +++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart @@ -20,7 +20,6 @@ import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/summary2/kernel_compilation_service.dart'; import 'package:analyzer/src/summary2/macro.dart'; -import 'package:analyzer/src/test_utilities/mock_packages.dart'; import 'package:analyzer/src/test_utilities/mock_sdk.dart'; import 'package:analyzer/src/test_utilities/package_config_file_builder.dart'; import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; @@ -489,44 +488,30 @@ class PubPackageResolutionTest extends ContextResolutionTest ); if (angularMeta) { - var angularMetaPath = '/packages/angular_meta'; - MockPackages.addAngularMetaPackageFiles( - getFolder(angularMetaPath), - ); + var angularMetaPath = addAngularMeta().parent.path; config.add(name: 'angular_meta', rootPath: angularMetaPath); } if (ffi) { - var ffiPath = '/packages/ffi'; - MockPackages.addFfiPackageFiles( - getFolder(ffiPath), - ); + var ffiPath = addFfi().parent.path; config.add(name: 'ffi', rootPath: ffiPath); } if (flutter) { - var uiPath = '/packages/ui'; - addUI(); + var uiPath = addUI().parent.path; config.add(name: 'ui', rootPath: uiPath); - var flutterPath = '/packages/flutter'; - addFlutter(); + var flutterPath = addFlutter().parent.path; config.add(name: 'flutter', rootPath: flutterPath); } if (js) { - var jsPath = '/packages/js'; - MockPackages.addJsPackageFiles( - getFolder(jsPath), - ); + var jsPath = addJs().parent.path; config.add(name: 'js', rootPath: jsPath); } if (meta || flutter) { - var metaPath = '/packages/meta'; - MockPackages.addMetaPackageFiles( - getFolder(metaPath), - ); + var metaPath = addMeta().parent.path; config.add(name: 'meta', rootPath: metaPath); } diff --git a/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart index 894bd2ea438..92717aa9734 100644 --- a/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart +++ b/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/src/error/codes.dart'; -import 'package:analyzer/src/test_utilities/mock_packages.dart'; +import 'package:analyzer_utilities/test/mock_packages/mock_packages.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; import '../dart/resolution/context_collection_resolution.dart'; @@ -20,7 +20,10 @@ main() { @reflectiveTest class InvalidExportOfInternalElement_BlazePackageTest extends BlazeWorkspaceResolutionTest - with InvalidExportOfInternalElementTest { + with InvalidExportOfInternalElementTest, MockPackagesMixin { + @override + String get packagesRootPath => workspaceThirdPartyDartPath; + String get testPackageBlazeBinPath => '$workspaceRootPath/blaze-bin/dart/my'; String get testPackageGenfilesPath => @@ -32,10 +35,7 @@ class InvalidExportOfInternalElement_BlazePackageTest @override void setUp() async { super.setUp(); - var metaPath = '$workspaceThirdPartyDartPath/meta'; - MockPackages.addMetaPackageFiles( - getFolder(metaPath), - ); + addMeta(); newFile('$testPackageBlazeBinPath/my.packages', ''); newFolder('$workspaceRootPath/blaze-out'); } diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart index 67032332f01..3128e9ab9a5 100644 --- a/pkg/analyzer_plugin/test/support/abstract_context.dart +++ b/pkg/analyzer_plugin/test/support/abstract_context.dart @@ -12,10 +12,10 @@ import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart'; import 'package:analyzer/src/dart/analysis/byte_store.dart'; import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine; -import 'package:analyzer/src/test_utilities/mock_packages.dart'; import 'package:analyzer/src/test_utilities/mock_sdk.dart'; import 'package:analyzer/src/test_utilities/package_config_file_builder.dart'; import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; +import 'package:analyzer_utilities/test/mock_packages/mock_packages.dart'; import 'package:linter/src/rules.dart'; /// Finds an [Element] with the given [name]. @@ -36,7 +36,7 @@ Element? findChildElement(Element root, String name, [ElementKind? kind]) { /// A function to be called for every [Element]. typedef _ElementVisitorFunction = void Function(Element element); -class AbstractContextTest with ResourceProviderMixin { +class AbstractContextTest with MockPackagesMixin, ResourceProviderMixin { final ByteStore _byteStore = MemoryByteStore(); final Map _declaredVariables = {}; @@ -45,6 +45,9 @@ class AbstractContextTest with ResourceProviderMixin { List get collectionIncludedPaths => [workspaceRootPath]; + @override + String get packagesRootPath => '/packages'; + Folder get sdkRoot => newFolder('/sdk'); Future get session async => sessionFor(testPackageRootPath); @@ -164,10 +167,7 @@ class AbstractContextTest with ResourceProviderMixin { ); if (meta) { - var metaPath = '/packages/meta'; - MockPackages.addMetaPackageFiles( - getFolder(metaPath), - ); + var metaPath = addMeta().parent.path; config.add(name: 'meta', rootPath: metaPath); } diff --git a/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta.dart b/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta.dart index 5dfd2cadebc..37966dcc20a 100644 --- a/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta.dart +++ b/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta.dart @@ -267,8 +267,39 @@ const _Literal literal = _Literal(); const _MustBeConst mustBeConst = _MustBeConst(); /// Used to annotate an instance member `m` declared on a class or mixin `C`. -/// Indicates that every subclass of `C`, concrete or abstract, must directly -/// override `m`. +/// Indicates that every concrete subclass of `C` must directly override `m`. +/// +/// The intention of this annotation is to "re-abtract" a member that was +/// previously concrete, and to ensure that subclasses provide their own +/// implementation of the member. For example: +/// +/// ```dart +/// base class Entity { +/// @mustBeOverridden +/// String toString(); +/// } +/// +/// abstract class AbstractEntity extends Entity { +/// // OK: AbstractEntity is abstract. +/// } +/// +/// sealed class SealedEntity extends Entity { +/// // OK: SealedEntity is sealed, which implies abstract. +/// } +/// +/// mixin MixinEntity on Entity { +/// // OK: MixinEntity is abstract. +/// } +/// +/// class Person extends Entity { +/// // ERROR: Missing new implementation of 'toString'. +/// } +/// +/// class Animal extends Entity { +/// // OK: Animal provides its own implementation of 'toString'. +/// String toString() => 'Animal'; +/// } +/// ``` /// /// This annotation places no restrictions on the overriding members. In /// particular, it does not require that the overriding members invoke the @@ -281,7 +312,7 @@ const _MustBeConst mustBeConst = _MustBeConst(); /// (a method, operator, field, getter, or setter) of a class or of a mixin, /// or /// * the annotation is associated with a member `m` in class or mixin `C`, and -/// there is a class or mixin `D` which is a subclass of `C` (directly or +/// there is a concrete class `D` which is a subclass of `C` (directly or /// indirectly), and `D` does not directly declare a concrete override of `m` /// and does not directly declare a concrete override of `noSuchMethod`. const _MustBeOverridden mustBeOverridden = _MustBeOverridden(); diff --git a/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta_meta.dart b/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta_meta.dart index 5b5765ace51..98339cbe658 100644 --- a/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta_meta.dart +++ b/pkg/analyzer_utilities/lib/test/mock_packages/package_content/meta/lib/meta_meta.dart @@ -18,24 +18,47 @@ library meta_meta; /// `const` constructor). /// * the annotated annotation is associated with anything other than the kinds /// of declarations listed as valid targets. +/// +/// This type is not intended to be extended and will be marked as `final` +/// in a future release of `package:meta`. @Target({TargetKind.classType}) class Target { /// The kinds of declarations with which the annotated annotation can be /// associated. final Set kinds; + /// Create a new instance of [Target] to be used as an annotation + /// on a class intended to be used as an annotation, with the + /// specified target [kinds] that it can be applied to. const Target(this.kinds); } /// An enumeration of the kinds of targets to which an annotation can be /// applied. +/// +/// This type is not intended to be extended and will be marked as `final` +/// in a future release of `package:meta`. class TargetKind { /// Indicates that an annotation is valid on any class declaration. static const classType = TargetKind._('classes', 'classType'); + /// Indicates that an annotation is valid on any constructor declaration, both + /// factory and generative constructors, whether it's in a class, enum, or + /// extension type. Extension type primary constructors are not supported, + /// because there is no way to annotate a primary constructor. + static const constructor = TargetKind._('constructors', 'constructor'); + + /// Indicates that an annotation is valid on any directive in a library or + /// part file, whether it's a `library`, `import`, `export`, `part`, or + /// `part of` directive. + static const directive = TargetKind._('directives', 'directive'); + /// Indicates that an annotation is valid on any enum declaration. static const enumType = TargetKind._('enums', 'enumType'); + /// Indicates that an annotation is valid on any enum value declaration. + static const enumValue = TargetKind._('enum values', 'enumValue'); + /// Indicates that an annotation is valid on any extension declaration. static const extension = TargetKind._('extensions', 'extension'); @@ -43,7 +66,8 @@ class TargetKind { static const extensionType = TargetKind._('extension types', 'extensionType'); /// Indicates that an annotation is valid on any field declaration, both - /// instance and static fields, whether it's in a class, mixin or extension. + /// instance and static fields, whether it's in a class, enum, mixin, or + /// extension. static const field = TargetKind._('fields', 'field'); /// Indicates that an annotation is valid on any top-level function @@ -56,12 +80,13 @@ class TargetKind { static const library = TargetKind._('libraries', 'library'); /// Indicates that an annotation is valid on any getter declaration, both - /// instance or static getters, whether it's in a class, mixin, extension, or - /// at the top-level of a library. + /// instance or static getters, whether it's in a class, enum, mixin, + /// extension, extension type, or at the top-level of a library. static const getter = TargetKind._('getters', 'getter'); /// Indicates that an annotation is valid on any method declaration, both - /// instance and static methods, whether it's in a class, mixin or extension. + /// instance and static methods, whether it's in a class, enum, mixin, + /// extension, or extension type. static const method = TargetKind._('methods', 'method'); /// Indicates that an annotation is valid on any mixin declaration. @@ -80,12 +105,13 @@ class TargetKind { TargetKind._('overridable members', 'overridableMember'); /// Indicates that an annotation is valid on any formal parameter declaration, - /// whether it's in a function, method, constructor, or closure. + /// whether it's in a constructor, function (named or anonymous), function + /// type, function-typed formal parameter, or method. static const parameter = TargetKind._('parameters', 'parameter'); /// Indicates that an annotation is valid on any setter declaration, both - /// instance or static setters, whether it's in a class, mixin, extension, or - /// at the top-level of a library. + /// instance or static setters, whether it's in a class, enum, mixin, + /// extension, extension type, or at the top-level of a library. static const setter = TargetKind._('setters', 'setter'); /// Indicates that an annotation is valid on any top-level variable @@ -94,17 +120,28 @@ class TargetKind { TargetKind._('top-level variables', 'topLevelVariable'); /// Indicates that an annotation is valid on any declaration that introduces a - /// type. This includes classes, enums, mixins and typedefs, but does not + /// type. This includes classes, enums, mixins, and typedefs, but does not /// include extensions because extensions don't introduce a type. + // TODO(srawlins): This should include extension types. static const type = TargetKind._('types (classes, enums, mixins, or typedefs)', 'type'); - /// Indicates that an annotation is valid on any typedef declaration.` + /// Indicates that an annotation is valid on any typedef declaration. static const typedefType = TargetKind._('typedefs', 'typedefType'); + /// Indicates that an annotation is valid on any type parameter declaration, + /// whether it's on a class, enum, function type, function, mixin, extension, + /// extension type, or typedef. + static const typeParameter = TargetKind._('type parameters', 'typeParameter'); + + /// All current [TargetKind] values of targets to + /// which an annotation can be applied. static const values = [ classType, + constructor, + directive, enumType, + enumValue, extension, extensionType, field, @@ -120,6 +157,7 @@ class TargetKind { topLevelVariable, type, typedefType, + typeParameter, ]; /// A user visible string used to describe this target kind. @@ -127,11 +165,12 @@ class TargetKind { /// The name of the [TargetKind] value. /// - /// The name is a string containing the source identifier used to declare the [TargetKind] value. - /// For example, the result of `TargetKind.classType.name` is the string "classType". + /// The name is a string containing the source identifier used + /// to declare the [TargetKind] value. For example, + /// the result of `TargetKind.classType.name`is the string "classType". final String name; - // This class isnot meant to be instantiated or extended; this constructor + // This class is not meant to be instantiated or extended; this constructor // prevents instantiation and extension. const TargetKind._(this.displayString, this.name);