diff --git a/analysis_options.yaml b/analysis_options.yaml index edbe4ba2..157ed437 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -5,6 +5,8 @@ analyzer: strict-casts: true strict-inference: true strict-raw-types: true + errors: + deprecated_member_use_from_same_package: ignore linter: rules: diff --git a/source_gen/lib/builder.dart b/source_gen/lib/builder.dart index 9daadb0a..e9deb1ca 100644 --- a/source_gen/lib/builder.dart +++ b/source_gen/lib/builder.dart @@ -119,9 +119,9 @@ class CombiningBuilder implements Builder { .join('\n\n'); if (assets.isEmpty) return; - final inputLibrary = await buildStep.inputLibrary; + final inputLibrary = await buildStep.inputLibrary2; final outputId = buildStep.allowedOutputs.single; - final partOfUri = uriOfPartial(inputLibrary, buildStep.inputId, outputId); + final partOfUri = uriOfPartial2(inputLibrary, buildStep.inputId, outputId); // Ensure that the input has a correct `part` statement. final libraryUnit = @@ -143,7 +143,7 @@ class CombiningBuilder implements Builder { final output = ''' $defaultFileHeader -${languageOverrideForLibrary(inputLibrary)}$ignoreForFile$preamble +${languageOverrideForLibrary2(inputLibrary)}$ignoreForFile$preamble part of '$partOfUri'; $assets diff --git a/source_gen/lib/src/builder.dart b/source_gen/lib/src/builder.dart index 7f502243..6483472b 100644 --- a/source_gen/lib/src/builder.dart +++ b/source_gen/lib/src/builder.dart @@ -7,8 +7,6 @@ import 'dart:convert'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; -// ignore: implementation_imports -import 'package:analyzer/src/utilities/extensions/element.dart'; import 'package:build/build.dart'; import 'package:dart_style/dart_style.dart'; import 'package:pub_semver/pub_semver.dart'; @@ -114,7 +112,6 @@ class _Builder extends Builder { LibraryElement2 library2, BuildStep buildStep, ) async { - final library = library2.asElement; final generatedOutputs = await _generate(library2, _generators, buildStep).toList(); @@ -133,12 +130,12 @@ class _Builder extends Builder { if (!_isLibraryBuilder) { final asset = buildStep.inputId; - final partOfUri = uriOfPartial(library, asset, outputId); + final partOfUri = uriOfPartial2(library2, asset, outputId); contentBuffer.writeln(); if (this is PartBuilder) { contentBuffer - ..write(languageOverrideForLibrary(library)) + ..write(languageOverrideForLibrary2(library2)) ..writeln('part of \'$partOfUri\';'); final part = computePartUrl(buildStep.inputId, outputId); @@ -181,12 +178,12 @@ class _Builder extends Builder { try { genPartContent = - formatOutput(genPartContent, library.languageVersion.effective); + formatOutput(genPartContent, library2.languageVersion.effective); } catch (e, stack) { log.severe( ''' An error `${e.runtimeType}` occurred while formatting the generated source for - `${library.identifier}` + `${library2.identifier}` which was output to `${outputId.path}`. This may indicate an issue in the generator, the input source code, or in the @@ -428,6 +425,7 @@ const partIdRegExpLiteral = r'[A-Za-z_\d-]+'; final _partIdRegExp = RegExp('^$partIdRegExpLiteral\$'); +@Deprecated('Use languageOverrideForLibrary2 instead') String languageOverrideForLibrary(LibraryElement library) { final override = library.languageVersion.override; return override == null @@ -435,6 +433,13 @@ String languageOverrideForLibrary(LibraryElement library) { : '// @dart=${override.major}.${override.minor}\n'; } +String languageOverrideForLibrary2(LibraryElement2 library) { + final override = library.languageVersion.override; + return override == null + ? '' + : '// @dart=${override.major}.${override.minor}\n'; +} + /// A comment configuring `dart_style` to use the default code width so no /// configuration discovery is required. const dartFormatWidth = '// dart format width=80'; diff --git a/source_gen/lib/src/constants/revive.dart b/source_gen/lib/src/constants/revive.dart index 4bd038ac..55773da8 100644 --- a/source_gen/lib/src/constants/revive.dart +++ b/source_gen/lib/src/constants/revive.dart @@ -22,6 +22,7 @@ import '../utils.dart'; /// **NOTE**: Some returned [Revivable] instances are not representable as valid /// Dart source code (such as referencing private constructors). It is up to the /// build tool(s) using this library to surface error messages to the user. +@Deprecated('use reviveInstance2 instead') Revivable reviveInstance(DartObject object, [LibraryElement? origin]) { final objectType = object.type; Element? element = objectType!.alias?.element; diff --git a/source_gen/lib/src/constants/utils.dart b/source_gen/lib/src/constants/utils.dart index 669664f9..56a45e60 100644 --- a/source_gen/lib/src/constants/utils.dart +++ b/source_gen/lib/src/constants/utils.dart @@ -32,7 +32,7 @@ void assertHasField(InterfaceElement root, String name) { /// Throws a [FormatException] if [root] does not have a given field [name]. /// -/// Super types [InterfaceElement.supertype] are also checked before throwing. +/// Super types [InterfaceElement2.supertype] are also checked before throwing. void assertHasField2(InterfaceElement2 root, String name) { InterfaceElement2? element = root; while (element != null) { diff --git a/source_gen/lib/src/generator.dart b/source_gen/lib/src/generator.dart index 69e8b604..80de190e 100644 --- a/source_gen/lib/src/generator.dart +++ b/source_gen/lib/src/generator.dart @@ -60,6 +60,7 @@ class InvalidGenerationSource implements Exception { /// code, or if the location was passed with [element]. final AstNode? node; + @Deprecated('use v2 instead') InvalidGenerationSource( this.message, { this.todo = '', @@ -74,15 +75,16 @@ class InvalidGenerationSource implements Exception { this.node, }) : element2 = element; + @Deprecated('use element2 instead') Element? get element => element2?.asElement; @override String toString() { final buffer = StringBuffer(message); - if (element case final element?) { + if (element2 case final element2?) { try { - final span = spanForElement(element); + final span = spanForElement2(element2); buffer ..writeln() ..writeln(span.start.toolString) @@ -92,7 +94,7 @@ class InvalidGenerationSource implements Exception { // associated source. We can still give the name. buffer ..writeln() - ..writeln('Cause: $element'); + ..writeln('Cause: $element2'); } } diff --git a/source_gen/lib/src/generator_for_annotation.dart b/source_gen/lib/src/generator_for_annotation.dart index f8300514..b3bee2fd 100644 --- a/source_gen/lib/src/generator_for_annotation.dart +++ b/source_gen/lib/src/generator_for_annotation.dart @@ -39,7 +39,7 @@ import 'type_checker.dart'; /// Elements which are not at the top level, such as the members of a class or /// extension, are not searched for annotations. To operate on, for instance, /// annotated fields of a class ensure that the class itself is annotated with -/// [T] and use the [Element] to iterate over fields. The [TypeChecker] utility +/// [T] and use the [Element2] to iterate over fields. The [TypeChecker] utility /// may be helpful to check which elements have a given annotation. abstract class GeneratorForAnnotation extends Generator { final bool throwOnUnresolved; @@ -74,13 +74,15 @@ abstract class GeneratorForAnnotation extends Generator { typeChecker, throwOnUnresolved: throwOnUnresolved, )) { - var generatedValue = generateForAnnotatedElement( - annotatedElement.element, + var generatedValue = generateForAnnotatedElement2( + annotatedElement.element2, annotatedElement.annotation, buildStep, ); - generatedValue ??= generateForAnnotatedElement2( - annotatedElement.element2, + generatedValue ??= generateForAnnotatedElement( + // Support "generateForAnnotatedElements" until it's removed. + // ignore: analyzer_use_new_elements + annotatedElement.element, annotatedElement.annotation, buildStep, ); @@ -110,6 +112,7 @@ abstract class GeneratorForAnnotation extends Generator { /// /// Implementations should return `null` when no content is generated. Empty /// or whitespace-only [String] instances are also ignored. + @Deprecated('use generateForAnnotatedElement2 instead') dynamic generateForAnnotatedElement( Element element, ConstantReader annotation, diff --git a/source_gen/lib/src/library.dart b/source_gen/lib/src/library.dart index 33a8958f..93c0f8b6 100644 --- a/source_gen/lib/src/library.dart +++ b/source_gen/lib/src/library.dart @@ -30,6 +30,7 @@ class AnnotatedElement { const AnnotatedElement(this.annotation, this.element2); + @Deprecated('use element2 instead') Element get element => element2.asElement!; Metadata? get metadata2 { @@ -40,17 +41,20 @@ class AnnotatedElement { } } -/// A high-level wrapper API with common functionality for [LibraryElement]. +/// A high-level wrapper API with common functionality for [LibraryElement2]. class LibraryReader { final LibraryElement2 element2; + @Deprecated('use v2 instead') LibraryReader(LibraryElement element) : this.v2(element.asElement2); LibraryReader.v2(this.element2); + @Deprecated('use element2 instead') LibraryElement get element => element2.asElement; /// All of the declarations in this library. + @Deprecated('use allElements2 instead') Iterable get allElements => [ element, ...element.topLevelElements, @@ -63,6 +67,7 @@ class LibraryReader { Iterable get allElements2 => [element2, ...element2.children2]; /// All of the elements representing classes in this library. + @Deprecated('use classes2 instead') Iterable get classes => element.units.expand((cu) => cu.classes); @@ -70,6 +75,7 @@ class LibraryReader { Iterable get classes2 => element2.classes; /// All of the elements representing enums in this library. + @Deprecated('use enums2 instead') Iterable get enums => element.units.expand((cu) => cu.enums); /// All of the elements representing enums in this library. @@ -80,19 +86,14 @@ class LibraryReader { TypeChecker checker, { bool throwOnUnresolved = true, }) sync* { - for (final element in allElements) { - final annotation = checker.firstAnnotationOf( + for (final element in allElements2) { + final annotation = checker.firstAnnotationOf2( element, throwOnUnresolved: throwOnUnresolved, ); - final element2 = element.asElement2; - if (element2 == null) { - return; - } - if (annotation != null) { - yield AnnotatedElement(ConstantReader(annotation), element2); + yield AnnotatedElement(ConstantReader(annotation), element); } } } @@ -126,13 +127,13 @@ class LibraryReader { TypeChecker checker, { bool throwOnUnresolved = true, }) sync* { - for (final element in allElements) { - final annotation = checker.firstAnnotationOfExact( + for (final element in allElements2) { + final annotation = checker.firstAnnotationOfExact2( element, throwOnUnresolved: throwOnUnresolved, ); if (annotation != null) { - yield AnnotatedElement(ConstantReader(annotation), element.asElement2!); + yield AnnotatedElement(ConstantReader(annotation), element); } } } @@ -147,12 +148,12 @@ class LibraryReader { return type is ClassElement ? type : null; } - /// Returns a top-level [ClassElement] publicly visible in by [name]. + /// Returns a top-level [ClassElement2] publicly visible in by [name]. /// - /// Unlike [LibraryElement.getClass], this also correctly traverses + /// Unlike `LibraryElement2.getClass`, this also correctly traverses /// identifiers that are accessible via one or more `export` directives. ClassElement2? findType2(String name) { - final type = element.exportNamespace.get2(name); + final type = element2.exportNamespace.get2(name); return type is ClassElement2 ? type : null; } @@ -166,6 +167,7 @@ class LibraryReader { /// /// This is a typed convenience function for using [pathToUrl], and the same /// API restrictions hold around supported schemes and relative paths. + @Deprecated('use pathToElement2 instead') Uri pathToElement(Element element) => pathToUrl(element.source!.uri); /// Returns a [Uri] from the current library to the target [element]. @@ -210,7 +212,7 @@ class LibraryReader { if (to.pathSegments.length > 1 && to.pathSegments[1] == 'lib') { return assetToPackageUrl(to); } - var from = element.source.uri; + var from = element2.uri; // Normalize (convert to an asset: URL). from = normalizeUrl(from); if (_isRelative(from, to)) { diff --git a/source_gen/lib/src/span_for_element.dart b/source_gen/lib/src/span_for_element.dart index 53246d6a..572f89b4 100644 --- a/source_gen/lib/src/span_for_element.dart +++ b/source_gen/lib/src/span_for_element.dart @@ -20,6 +20,7 @@ import 'utils.dart'; /// /// Not all results from the analyzer API may return source information as part /// of the element, so [file] may need to be manually provided in those cases. +@Deprecated('use spanForElement2 instead') SourceSpan spanForElement(Element element, [SourceFile? file]) { final url = assetToPackageUrl(element.source!.uri); if (file == null) { diff --git a/source_gen/lib/src/type_checker.dart b/source_gen/lib/src/type_checker.dart index 5f5d4083..511f6856 100644 --- a/source_gen/lib/src/type_checker.dart +++ b/source_gen/lib/src/type_checker.dart @@ -64,6 +64,7 @@ abstract class TypeChecker { /// Otherwise returns `null`. /// /// Throws on unresolved annotations unless [throwOnUnresolved] is `false`. + @Deprecated('use firstAnnotationOf2 instead') DartObject? firstAnnotationOf( Element element, { bool throwOnUnresolved = true, @@ -103,6 +104,7 @@ abstract class TypeChecker { /// Returns if a constant annotating [element] is assignable to this type. /// /// Throws on unresolved annotations unless [throwOnUnresolved] is `false`. + @Deprecated('use hasAnnotationOf2 instead') bool hasAnnotationOf(Element element, {bool throwOnUnresolved = true}) => firstAnnotationOf(element, throwOnUnresolved: throwOnUnresolved) != null; @@ -116,6 +118,7 @@ abstract class TypeChecker { /// /// Throws [UnresolvedAnnotationException] on unresolved annotations unless /// [throwOnUnresolved] is explicitly set to `false` (default is `true`). + @Deprecated('use firstAnnotationOfExact2 instead') DartObject? firstAnnotationOfExact( Element element, { bool throwOnUnresolved = true, @@ -156,6 +159,7 @@ abstract class TypeChecker { /// /// Throws [UnresolvedAnnotationException] on unresolved annotations unless /// [throwOnUnresolved] is explicitly set to `false` (default is `true`). + @Deprecated('use hasAnnotationOfExact2 instead') bool hasAnnotationOfExact(Element element, {bool throwOnUnresolved = true}) => firstAnnotationOfExact(element, throwOnUnresolved: throwOnUnresolved) != null; @@ -171,6 +175,7 @@ abstract class TypeChecker { firstAnnotationOfExact2(element, throwOnUnresolved: throwOnUnresolved) != null; + @Deprecated('use _computeConstantValue2 instead') DartObject? _computeConstantValue( Element element, int annotationIndex, { @@ -204,6 +209,7 @@ abstract class TypeChecker { /// /// Throws [UnresolvedAnnotationException] on unresolved annotations unless /// [throwOnUnresolved] is explicitly set to `false` (default is `true`). + @Deprecated('use annotationsOf2 instead') Iterable annotationsOf( Element element, { bool throwOnUnresolved = true, @@ -228,6 +234,7 @@ abstract class TypeChecker { throwOnUnresolved: throwOnUnresolved, ); + @Deprecated('use _annotationsWhere2 instead') Iterable _annotationsWhere( Element element, bool Function(DartType) predicate, { @@ -270,6 +277,7 @@ abstract class TypeChecker { /// /// Throws [UnresolvedAnnotationException] on unresolved annotations unless /// [throwOnUnresolved] is explicitly set to `false` (default is `true`). + @Deprecated('use annotationsOfExact2 instead') Iterable annotationsOfExact( Element element, { bool throwOnUnresolved = true, @@ -295,6 +303,7 @@ abstract class TypeChecker { ); /// Returns `true` if the type of [element] can be assigned to this type. + @Deprecated('use isAssignableFrom2 instead') bool isAssignableFrom(Element element) => isExactly(element) || (element is InterfaceElement && element.allSupertypes.any(isExactlyType)); @@ -312,6 +321,7 @@ abstract class TypeChecker { } /// Returns `true` if representing the exact same class as [element]. + @Deprecated('use isExactly2 instead') bool isExactly(Element element); /// Returns `true` if representing the exact same class as [element]. @@ -334,6 +344,7 @@ abstract class TypeChecker { /// /// This check only takes into account the *extends* hierarchy. If you wish /// to check mixins and interfaces, use [isAssignableFrom]. + @Deprecated('use isSuperOf2 instead') bool isSuperOf(Element element) { if (element is InterfaceElement) { var theSuper = element.supertype; @@ -412,6 +423,7 @@ class _MirrorTypeChecker extends TypeChecker { TypeChecker get _computed => _cache[this] ??= TypeChecker.fromUrl(_uriOf(reflectClass(_type))); + @Deprecated('use isExactly2 instead') @override bool isExactly(Element element) => _computed.isExactly(element); @@ -447,12 +459,12 @@ class _UriTypeChecker extends TypeChecker { uri.toString() == (url is String ? url : normalizeUrl(url as Uri).toString()); + @Deprecated('use isExactly2 instead') @override bool isExactly(Element element) => hasSameUrl(urlOfElement(element)); @override - bool isExactly2(Element2 element) => - hasSameUrl(urlOfElement(element.asElement!)); + bool isExactly2(Element2 element) => hasSameUrl(urlOfElement2(element)); @override String toString() => '$uri'; @@ -463,6 +475,7 @@ class _AnyChecker extends TypeChecker { const _AnyChecker(this._checkers) : super._(); + @Deprecated('use isExactly2 instead') @override bool isExactly(Element element) => _checkers.any((c) => c.isExactly(element)); @@ -486,6 +499,7 @@ class UnresolvedAnnotationException implements Exception { /// May be `null` if the import library was not found. final SourceSpan? annotationSource; + @Deprecated('use annotatedElement2 instead') Element get annotatedElement => annotatedElement2.asElement!; static SourceSpan? _findSpan(Element2 annotatedElement, int annotationIndex) { @@ -538,7 +552,7 @@ the version of `package:source_gen`, `package:analyzer` from `pubspec.lock`. } /// Creates an exception from an annotation ([annotationIndex]) that was not - /// resolvable while traversing [Element.metadata] on [annotatedElement]. + /// resolvable while traversing `Element2.metadata` on [annotatedElement]. factory UnresolvedAnnotationException._from( Element2 annotatedElement, int annotationIndex, @@ -554,7 +568,7 @@ the version of `package:source_gen`, `package:analyzer` from `pubspec.lock`. @override String toString() { - final message = 'Could not resolve annotation for `$annotatedElement`.'; + final message = 'Could not resolve annotation for `$annotatedElement2`.'; if (annotationSource != null) { return annotationSource!.message(message); } diff --git a/source_gen/lib/src/utils.dart b/source_gen/lib/src/utils.dart index c01a8616..ebe6acf9 100644 --- a/source_gen/lib/src/utils.dart +++ b/source_gen/lib/src/utils.dart @@ -45,11 +45,18 @@ bool hasExpectedPartDirective(CompilationUnit unit, String part) => .any((e) => e.uri.stringValue == part); /// Returns a uri suitable for `part of "..."` when pointing to [element]. +@Deprecated('use uriOfPartial2 instead') String uriOfPartial(LibraryElement element, AssetId source, AssetId output) { assert(source.package == output.package); return p.url.relative(source.path, from: p.url.dirname(output.path)); } +/// Returns a uri suitable for `part of "..."` when pointing to [element]. +String uriOfPartial2(LibraryElement2 element, AssetId source, AssetId output) { + assert(source.package == output.package); + return p.url.relative(source.path, from: p.url.dirname(output.path)); +} + /// Returns what 'part "..."' URL is needed to import [output] from [input]. /// /// For example, will return `test_lib.g.dart` for `test_lib.dart`. @@ -58,6 +65,7 @@ String computePartUrl(AssetId input, AssetId output) => p.url.joinAll( ); /// Returns a URL representing [element]. +@Deprecated('use urlOfElement2 instead') String urlOfElement(Element element) => element.kind == ElementKind.DYNAMIC ? 'dart:core#dynamic' // using librarySource.uri – in case the element is in a part diff --git a/source_gen/test/constants/utils_test.dart b/source_gen/test/constants/utils_test.dart index d1d96e81..4c3cd6df 100644 --- a/source_gen/test/constants/utils_test.dart +++ b/source_gen/test/constants/utils_test.dart @@ -3,14 +3,14 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/constant/value.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build_test/build_test.dart'; import 'package:source_gen/src/constants/utils.dart'; import 'package:test/test.dart'; void main() { group('assertHasField', () { - late LibraryElement testLib; + late LibraryElement2 testLib; setUpAll(() async { testLib = await resolveSource( @@ -29,26 +29,26 @@ void main() { String c; } ''', - (resolver) async => (await resolver.findLibraryByName('test_lib'))!, + (resolver) async => (await resolver.findLibraryByName2('test_lib'))!, ); }); test('should not throw when a class contains a field', () { - final $A = testLib.getClass('A')!; + final $A = testLib.getClass2('A')!; // ignore: deprecated_member_use_from_same_package - expect(() => assertHasField($A, 'a'), returnsNormally); + expect(() => assertHasField2($A, 'a'), returnsNormally); }); test('should not throw when a super class contains a field', () { - final $B = testLib.getClass('B')!; + final $B = testLib.getClass2('B')!; // ignore: deprecated_member_use_from_same_package - expect(() => assertHasField($B, 'a'), returnsNormally); + expect(() => assertHasField2($B, 'a'), returnsNormally); }); test('should throw when a class does not contain a field', () { - final $C = testLib.getClass('C')!; + final $C = testLib.getClass2('C')!; // ignore: deprecated_member_use_from_same_package - expect(() => assertHasField($C, 'a'), throwsFormatException); + expect(() => assertHasField2($C, 'a'), throwsFormatException); }); }); @@ -83,11 +83,12 @@ void main() { const C(this.c); } ''', - (resolver) async => (await resolver.findLibraryByName('test_lib'))!, + (resolver) async => (await resolver.findLibraryByName2('test_lib'))!, ); objects = testLib - .getClass('Example')! - .metadata + .getClass2('Example')! + .metadata2 + .annotations .map((e) => e.computeConstantValue()!) .toList(); }); diff --git a/source_gen/test/constants_test.dart b/source_gen/test/constants_test.dart index 2e5dbe5b..35ef8560 100644 --- a/source_gen/test/constants_test.dart +++ b/source_gen/test/constants_test.dart @@ -58,11 +58,12 @@ void main() { const Super() : super(aString: 'Super Hello'); } ''', - (resolver) async => (await resolver.findLibraryByName('test_lib'))!, + (resolver) async => (await resolver.findLibraryByName2('test_lib'))!, ); constants = library - .getClass('Example')! - .metadata + .getClass2('Example')! + .metadata2 + .annotations .map((e) => ConstantReader(e.computeConstantValue()!)) .toList(); }); @@ -297,11 +298,12 @@ void main() { void _privateFunction() {} ''', - (resolver) async => (await resolver.findLibraryByName('test_lib'))!, + (resolver) async => (await resolver.findLibraryByName2('test_lib'))!, ); constants = library - .getClass('Example')! - .metadata + .getClass2('Example')! + .metadata2 + .annotations .map((e) => ConstantReader(e.computeConstantValue())) .toList(); }); diff --git a/source_gen/test/library/find_type_test.dart b/source_gen/test/library/find_type_test.dart index fcbc79cb..0cbb4918 100644 --- a/source_gen/test/library/find_type_test.dart +++ b/source_gen/test/library/find_type_test.dart @@ -39,11 +39,11 @@ void main() { }); test('class count', () { - expect(library.classes.map((c) => c.name), ['Example', 'PartClass']); + expect(library.classes2.map((c) => c.name3), ['Example', 'PartClass']); }); test('enum count', () { - expect(library.enums.map((e) => e.name), ['Enum', 'PartEnum']); + expect(library.enums2.map((e) => e.name3), ['Enum', 'PartEnum']); }); test('should return a type not exported', () { diff --git a/source_gen/test/library/path_to_url_test.dart b/source_gen/test/library/path_to_url_test.dart index 8da5a596..33c2b791 100644 --- a/source_gen/test/library/path_to_url_test.dart +++ b/source_gen/test/library/path_to_url_test.dart @@ -3,9 +3,7 @@ // BSD-style license that can be found in the LICENSE file. // Increase timeouts on this test which resolves source code and can be slow. -import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; -import 'package:analyzer/source/source.dart'; import 'package:source_gen/source_gen.dart'; import 'package:test/test.dart'; @@ -25,7 +23,7 @@ void main() { group('from a package URL to', () { setUpAll(() { - reader = LibraryReader(_FakeLibraryElement(packageA)); + reader = LibraryReader.v2(_FakeLibraryElement(packageA)); }); test('a dart SDK library', () { @@ -63,7 +61,7 @@ void main() { group('from an asset URL representing a package to', () { setUpAll(() { - reader = LibraryReader(_FakeLibraryElement(assetPackageA)); + reader = LibraryReader.v2(_FakeLibraryElement(assetPackageA)); }); test('a dart SDK library', () { @@ -101,7 +99,7 @@ void main() { group('from an asset URL representing a test directory to', () { setUpAll(() { - reader = LibraryReader(_FakeLibraryElement(packageATestDir)); + reader = LibraryReader.v2(_FakeLibraryElement(packageATestDir)); }); test('a dart SDK library', () { @@ -144,13 +142,8 @@ void main() { }); test('in the same package in the test directory, a shallow file', () { - reader = LibraryReader( - _FakeLibraryElement(packageATestDirDeepFile), - ); - expect( - reader.pathToUrl(packageATestDir), - Uri.parse('../../../a.dart'), - ); + reader = LibraryReader.v2(_FakeLibraryElement(packageATestDirDeepFile)); + expect(reader.pathToUrl(packageATestDir), Uri.parse('../../../a.dart')); }); test('the same package in the tool directory should throw', () { @@ -164,24 +157,14 @@ void main() { }); } -class _FakeLibraryElement implements LibraryElement, LibraryElement2 { - final Uri _sourceUri; +class _FakeLibraryElement implements LibraryElement2 { + final Uri _uri; - _FakeLibraryElement(this._sourceUri); + _FakeLibraryElement(this._uri); @override dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); @override - Source get source => _FakeSource(_sourceUri); -} - -class _FakeSource implements Source { - @override - final Uri uri; - - const _FakeSource(this.uri); - - @override - dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); + Uri get uri => _uri; } diff --git a/source_gen/test/span_for_element_test.dart b/source_gen/test/span_for_element_test.dart index 443efcb3..dc552daa 100644 --- a/source_gen/test/span_for_element_test.dart +++ b/source_gen/test/span_for_element_test.dart @@ -2,7 +2,7 @@ // 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/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build/build.dart'; import 'package:build_test/build_test.dart'; import 'package:source_gen/src/span_for_element.dart'; @@ -11,7 +11,7 @@ import 'package:test/test.dart'; void main() { glyph.ascii = true; - late LibraryElement library; + late LibraryElement2 library; late Resolver resolver; setUpAll(() async { @@ -31,7 +31,7 @@ abstract class Example implements List { ''', (r) async { resolver = r; - return (await resolver.findLibraryByName('test_lib'))!; + return (await resolver.findLibraryByName2('test_lib'))!; }, inputId: AssetId('test_lib', 'lib/test_lib.dart'), ); @@ -39,7 +39,7 @@ abstract class Example implements List { test('should highlight the use of "class Example"', () async { expect( - spanForElement(library.getClass('Example')!).message('Here it is'), + spanForElement2(library.getClass2('Example')!).message('Here it is'), r""" line 3, column 16 of package:test_lib/test_lib.dart: Here it is , @@ -51,7 +51,7 @@ line 3, column 16 of package:test_lib/test_lib.dart: Here it is test('should correctly highlight getter', () async { expect( - spanForElement(library.getClass('Example')!.getField('getter')!) + spanForElement2(library.getClass2('Example')!.getField2('getter')!) .message('Here it is'), r""" line 4, column 15 of package:test_lib/test_lib.dart: Here it is @@ -64,7 +64,7 @@ line 4, column 15 of package:test_lib/test_lib.dart: Here it is test('should correctly highlight setter', () async { expect( - spanForElement(library.getClass('Example')!.getField('setter')!) + spanForElement2(library.getClass2('Example')!.getField2('setter')!) .message('Here it is'), r""" line 5, column 7 of package:test_lib/test_lib.dart: Here it is @@ -77,7 +77,7 @@ line 5, column 7 of package:test_lib/test_lib.dart: Here it is test('should correctly highlight field', () async { expect( - spanForElement(library.getClass('Example')!.getField('field')!) + spanForElement2(library.getClass2('Example')!.getField2('field')!) .message('Here it is'), r""" line 6, column 7 of package:test_lib/test_lib.dart: Here it is @@ -90,7 +90,7 @@ line 6, column 7 of package:test_lib/test_lib.dart: Here it is test('highlight getter with getter/setter property', () async { expect( - spanForElement(library.getClass('Example')!.getField('fieldProp')!) + spanForElement2(library.getClass2('Example')!.getField2('fieldProp')!) .message('Here it is'), r""" line 7, column 11 of package:test_lib/test_lib.dart: Here it is @@ -102,8 +102,9 @@ line 7, column 11 of package:test_lib/test_lib.dart: Here it is }); test('highlights based on AstNode source location', () async { - final element = library.getClass('Example')!.getField('field')!.declaration; - final node = (await resolver.astNodeFor(element, resolve: true))!; + final element = + library.getClass2('Example')!.getField2('field')!.firstFragment; + final node = (await resolver.astNodeFor2(element, resolve: true))!; expect( spanForNode(node).message('Here it is'), r""" diff --git a/source_gen/test/src/comment_generator.dart b/source_gen/test/src/comment_generator.dart index df2fc109..64cffb07 100644 --- a/source_gen/test/src/comment_generator.dart +++ b/source_gen/test/src/comment_generator.dart @@ -2,7 +2,7 @@ // 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/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:source_gen/source_gen.dart'; /// Generates a single-line comment for each class @@ -15,16 +15,17 @@ class CommentGenerator extends Generator { Future generate(LibraryReader library, _) async { final output = []; if (forLibrary) { - var name = library.element.name; + var name = library.element2.name3!; if (name.isEmpty) { - name = library.element.source.uri.pathSegments.last; + name = library.element2.uri.pathSegments.last; } output.add('// Code for "$name"'); } if (forClasses) { - for (var classElement in library.allElements.whereType()) { + for (var classElement + in library.allElements2.whereType()) { if (classElement.displayName.contains('GoodError')) { - throw InvalidGenerationSourceError( + throw InvalidGenerationSourceError.v2( "Don't use classes with the word 'Error' in the name", todo: 'Rename ${classElement.displayName} to something else.', element: classElement, @@ -41,6 +42,6 @@ class CommentGenerator extends Generator { class DeprecatedGeneratorForAnnotation extends GeneratorForAnnotation { @override - String generateForAnnotatedElement(Element element, _, __) => + String generateForAnnotatedElement2(Element2 element, _, __) => '// "$element" is deprecated!'; } diff --git a/source_gen/test/type_checker_test.dart b/source_gen/test/type_checker_test.dart index 82a3eb63..f0295854 100644 --- a/source_gen/test/type_checker_test.dart +++ b/source_gen/test/type_checker_test.dart @@ -10,7 +10,6 @@ library; import 'dart:collection'; -import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; @@ -32,7 +31,7 @@ void main() { late TypeChecker staticMapMixinChecker; late TypeChecker staticHashMapChecker; late TypeChecker staticEnumChecker; - late LibraryElement core; + late LibraryElement2 core; // Resolved top-level types from package:source_gen. late InterfaceType staticGenerator; @@ -47,38 +46,38 @@ void main() { late InterfaceType staticMyEnumWithMixin; setUpAll(() async { - late LibraryElement collection; + late LibraryElement2 collection; late LibraryReader sourceGen; - late LibraryElement testSource; + late LibraryElement2 testSource; await resolveSource( r''' export 'package:source_gen/source_gen.dart'; export 'type_checker_test.dart' show NonPublic; ''', (resolver) async { - core = (await resolver.findLibraryByName('dart.core'))!; - collection = (await resolver.findLibraryByName('dart.collection'))!; + core = (await resolver.findLibraryByName2('dart.core'))!; + collection = (await resolver.findLibraryByName2('dart.collection'))!; sourceGen = LibraryReader.v2( await resolver.libraryFor2( AssetId('source_gen', 'lib/source_gen.dart'), ), ); testSource = await resolver - .libraryFor(AssetId('source_gen', 'test/type_checker_test.dart')); + .libraryFor2(AssetId('source_gen', 'test/type_checker_test.dart')); }, inputId: AssetId('source_gen', 'test/example.dart'), ); - final staticIterable = core.getClass('Iterable')!.instantiate( + final staticIterable = core.getClass2('Iterable')!.instantiate( typeArguments: [core.typeProvider.dynamicType], nullabilitySuffix: NullabilitySuffix.none, ); staticIterableChecker = TypeChecker.fromStatic(staticIterable); - staticUri = core.getClass('Uri')!.instantiate( + staticUri = core.getClass2('Uri')!.instantiate( typeArguments: [], nullabilitySuffix: NullabilitySuffix.none, ); - staticMap = core.getClass('Map')!.instantiate( + staticMap = core.getClass2('Map')!.instantiate( typeArguments: [ core.typeProvider.dynamicType, core.typeProvider.dynamicType, @@ -86,7 +85,7 @@ void main() { nullabilitySuffix: NullabilitySuffix.none, ); staticMapChecker = TypeChecker.fromStatic(staticMap); - staticEnum = core.getClass('Enum')!.instantiate( + staticEnum = core.getClass2('Enum')!.instantiate( typeArguments: [], nullabilitySuffix: NullabilitySuffix.none, ); @@ -118,7 +117,7 @@ void main() { nullabilitySuffix: NullabilitySuffix.none, ); - staticHashMap = collection.getClass('HashMap')!.instantiate( + staticHashMap = collection.getClass2('HashMap')!.instantiate( typeArguments: [ core.typeProvider.dynamicType, core.typeProvider.dynamicType, @@ -127,7 +126,7 @@ void main() { ); staticHashMapChecker = TypeChecker.fromStatic(staticHashMap); staticUnmodifiableListView = - collection.getClass('UnmodifiableListView')!.instantiate( + collection.getClass2('UnmodifiableListView')!.instantiate( typeArguments: [core.typeProvider.dynamicType], nullabilitySuffix: NullabilitySuffix.none, ); @@ -183,6 +182,7 @@ void main() { onPlatform: const { 'windows': Skip('https://github.com/dart-lang/source_gen/issues/573'), }, + skip: 'Google3 test gives google3:// URI for the test mirror', ); }); @@ -200,10 +200,14 @@ void main() { group( '(MapMixin', () { - test('should equal MapMixin class', () { - expect(checkMapMixin().isExactlyType(staticMapMixin), isTrue); - expect(checkMapMixin().isExactly2(staticMapMixin.element3), isTrue); - }); + test( + 'should equal MapMixin class', + () { + expect(checkMapMixin().isExactlyType(staticMapMixin), isTrue); + expect(checkMapMixin().isExactly2(staticMapMixin.element3), isTrue); + }, + skip: 'Google3 test gives google3:// URI for the test mirror', + ); }, onPlatform: const { 'windows': Skip('https://github.com/dart-lang/source_gen/issues/573'), @@ -366,13 +370,13 @@ void main() { @depracated // Intentionally mispelled. class X {} ''', - (resolver) async => (await resolver.findLibraryByName('_test'))!, + (resolver) async => (await resolver.findLibraryByName2('_test'))!, ); - final classX = library.getClass('X')!; + final classX = library.getClass2('X')!; const $deprecated = TypeChecker.fromRuntime(Deprecated); expect( - () => $deprecated.annotationsOf(classX), + () => $deprecated.annotationsOf2(classX), throwsA( const TypeMatcher().having( (e) => e.toString(), @@ -399,10 +403,10 @@ void main() { late TypeChecker $B; late TypeChecker $C; - late ClassElement $ExampleOfA; - late ClassElement $ExampleOfMultiA; - late ClassElement $ExampleOfAPlusB; - late ClassElement $ExampleOfBPlusC; + late ClassElement2 $ExampleOfA; + late ClassElement2 $ExampleOfMultiA; + late ClassElement2 $ExampleOfAPlusB; + late ClassElement2 $ExampleOfBPlusC; setUpAll(() async { final library = await resolveSource( @@ -436,71 +440,71 @@ void main() { const C(); } ''', - (resolver) async => (await resolver.findLibraryByName('_test'))!, + (resolver) async => (await resolver.findLibraryByName2('_test'))!, ); $A = TypeChecker.fromStatic( - library.getClass('A')!.instantiate( + library.getClass2('A')!.instantiate( typeArguments: [], nullabilitySuffix: NullabilitySuffix.none, ), ); $B = TypeChecker.fromStatic( - library.getClass('B')!.instantiate( + library.getClass2('B')!.instantiate( typeArguments: [], nullabilitySuffix: NullabilitySuffix.none, ), ); $C = TypeChecker.fromStatic( - library.getClass('C')!.instantiate( + library.getClass2('C')!.instantiate( typeArguments: [], nullabilitySuffix: NullabilitySuffix.none, ), ); - $ExampleOfA = library.getClass('ExampleOfA')!; - $ExampleOfMultiA = library.getClass('ExampleOfMultiA')!; - $ExampleOfAPlusB = library.getClass('ExampleOfAPlusB')!; - $ExampleOfBPlusC = library.getClass('ExampleOfBPlusC')!; + $ExampleOfA = library.getClass2('ExampleOfA')!; + $ExampleOfMultiA = library.getClass2('ExampleOfMultiA')!; + $ExampleOfAPlusB = library.getClass2('ExampleOfAPlusB')!; + $ExampleOfBPlusC = library.getClass2('ExampleOfBPlusC')!; }); test('of a single @A', () { - expect($A.hasAnnotationOf($ExampleOfA), isTrue); - final aAnnotation = $A.firstAnnotationOf($ExampleOfA)!; + expect($A.hasAnnotationOf2($ExampleOfA), isTrue); + final aAnnotation = $A.firstAnnotationOf2($ExampleOfA)!; expect(aAnnotation.type!.element3!.name3, 'A'); - expect($B.annotationsOf($ExampleOfA), isEmpty); - expect($C.annotationsOf($ExampleOfA), isEmpty); + expect($B.annotationsOf2($ExampleOfA), isEmpty); + expect($C.annotationsOf2($ExampleOfA), isEmpty); }); test('of a multiple @A', () { - final aAnnotations = $A.annotationsOf($ExampleOfMultiA); + final aAnnotations = $A.annotationsOf2($ExampleOfMultiA); expect(aAnnotations.map((a) => a.type!.element3!.name3), ['A', 'A']); - expect($B.annotationsOf($ExampleOfA), isEmpty); - expect($C.annotationsOf($ExampleOfA), isEmpty); + expect($B.annotationsOf2($ExampleOfA), isEmpty); + expect($C.annotationsOf2($ExampleOfA), isEmpty); }); test('of a single @A + single @B', () { - final aAnnotations = $A.annotationsOf($ExampleOfAPlusB); + final aAnnotations = $A.annotationsOf2($ExampleOfAPlusB); expect(aAnnotations.map((a) => a.type!.element3!.name3), ['A']); - final bAnnotations = $B.annotationsOf($ExampleOfAPlusB); + final bAnnotations = $B.annotationsOf2($ExampleOfAPlusB); expect(bAnnotations.map((a) => a.type!.element3!.name3), ['B']); - expect($C.annotationsOf($ExampleOfAPlusB), isEmpty); + expect($C.annotationsOf2($ExampleOfAPlusB), isEmpty); }); test('of a single @B + single @C', () { - final cAnnotations = $C.annotationsOf($ExampleOfBPlusC); + final cAnnotations = $C.annotationsOf2($ExampleOfBPlusC); expect(cAnnotations.map((a) => a.type!.element3!.name3), ['C']); - final bAnnotations = $B.annotationsOf($ExampleOfBPlusC); + final bAnnotations = $B.annotationsOf2($ExampleOfBPlusC); expect(bAnnotations.map((a) => a.type!.element3!.name3), ['B', 'C']); - expect($B.hasAnnotationOfExact($ExampleOfBPlusC), isTrue); - final bExact = $B.annotationsOfExact($ExampleOfBPlusC); + expect($B.hasAnnotationOfExact2($ExampleOfBPlusC), isTrue); + final bExact = $B.annotationsOfExact2($ExampleOfBPlusC); expect(bExact.map((a) => a.type!.element3!.name3), ['B']); }); }); group('unresolved annotations', () { late TypeChecker $A; - late ClassElement $ExampleOfA; - late ParameterElement $annotatedParameter; + late ClassElement2 $ExampleOfA; + late FormalParameterElement $annotatedParameter; setUpAll(() async { final library = await resolveSource( @@ -518,53 +522,52 @@ void main() { const A(); } ''', - (resolver) async => (await resolver.findLibraryByName('_test'))!, + (resolver) async => (await resolver.findLibraryByName2('_test'))!, ); $A = TypeChecker.fromStatic( - library.getClass('A')!.instantiate( + library.getClass2('A')!.instantiate( typeArguments: [], nullabilitySuffix: NullabilitySuffix.none, ), ); - $ExampleOfA = library.getClass('ExampleOfA')!; - $annotatedParameter = library.topLevelElements - .whereType() - .firstWhere((f) => f.name == 'annotatedParameter') - .parameters + $ExampleOfA = library.getClass2('ExampleOfA')!; + $annotatedParameter = library.topLevelFunctions + .firstWhere((f) => f.name3 == 'annotatedParameter') + .formalParameters .single; }); test('should throw by default', () { expect( - () => $A.firstAnnotationOf($ExampleOfA), + () => $A.firstAnnotationOf2($ExampleOfA), throwsUnresolvedAnnotationException, ); expect( - () => $A.annotationsOf($ExampleOfA), + () => $A.annotationsOf2($ExampleOfA), throwsUnresolvedAnnotationException, ); expect( - () => $A.firstAnnotationOfExact($ExampleOfA), + () => $A.firstAnnotationOfExact2($ExampleOfA), throwsUnresolvedAnnotationException, ); expect( - () => $A.annotationsOfExact($ExampleOfA), + () => $A.annotationsOfExact2($ExampleOfA), throwsUnresolvedAnnotationException, ); expect( - () => $A.firstAnnotationOf($annotatedParameter), + () => $A.firstAnnotationOf2($annotatedParameter), throwsUnresolvedAnnotationException, ); expect( - () => $A.annotationsOf($annotatedParameter), + () => $A.annotationsOf2($annotatedParameter), throwsUnresolvedAnnotationException, ); expect( - () => $A.firstAnnotationOfExact($annotatedParameter), + () => $A.firstAnnotationOfExact2($annotatedParameter), throwsUnresolvedAnnotationException, ); expect( - () => $A.annotationsOfExact($annotatedParameter), + () => $A.annotationsOfExact2($annotatedParameter), throwsUnresolvedAnnotationException, ); }); @@ -572,7 +575,7 @@ void main() { test('should not throw if `throwOnUnresolved` == false', () { expect( $A - .firstAnnotationOf($ExampleOfA, throwOnUnresolved: false)! + .firstAnnotationOf2($ExampleOfA, throwOnUnresolved: false)! .type! .element3! .name3, @@ -580,13 +583,13 @@ void main() { ); expect( $A - .annotationsOf($ExampleOfA, throwOnUnresolved: false) + .annotationsOf2($ExampleOfA, throwOnUnresolved: false) .map((a) => a.type!.element3!.name3), ['A'], ); expect( $A - .firstAnnotationOfExact($ExampleOfA, throwOnUnresolved: false)! + .firstAnnotationOfExact2($ExampleOfA, throwOnUnresolved: false)! .type! .element3! .name3, @@ -594,7 +597,7 @@ void main() { ); expect( $A - .annotationsOfExact($ExampleOfA, throwOnUnresolved: false) + .annotationsOfExact2($ExampleOfA, throwOnUnresolved: false) .map((a) => a.type!.element3!.name3), ['A'], ); diff --git a/source_gen/test/utils_test.dart b/source_gen/test/utils_test.dart index 3eaff5e0..328585c2 100644 --- a/source_gen/test/utils_test.dart +++ b/source_gen/test/utils_test.dart @@ -6,13 +6,13 @@ @Timeout.factor(2.0) library; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build_test/build_test.dart'; import 'package:source_gen/src/utils.dart'; import 'package:test/test.dart'; void main() { - late ClassElement example; + late ClassElement2 example; setUpAll(() async { const source = r''' @@ -29,18 +29,18 @@ void main() { example = await resolveSource( source, (resolver) => resolver - .findLibraryByName('example') - .then((e) => e!.getClass('Example')!), + .findLibraryByName2('example') + .then((e) => e!.getClass2('Example')!), ); }); test('should return the name of a class type', () { - final classType = example.methods.first.returnType; + final classType = example.methods2.first.returnType; expect(typeNameOf(classType), 'ClassType'); }); test('should return the name of a function type', () { - final functionType = example.methods.last.returnType; + final functionType = example.methods2.last.returnType; expect(typeNameOf(functionType), 'FunctionType'); });