Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/go_router_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## NEXT

* Updates minimum supported SDK version to Flutter 3.32/Dart 3.8.
* Updates dependencies to use the latest `analyzer`, `build`, and `source_gen`.
* Updates dev dependencies to use the latest `build_test`.

## 4.1.1

Expand Down
6 changes: 3 additions & 3 deletions packages/go_router_builder/lib/src/go_router_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import 'dart:async';

import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:build/build.dart';
import 'package:source_gen/source_gen.dart';
Expand Down Expand Up @@ -76,7 +76,7 @@ ${getters.map((String e) => "$e,").join('\n')}
}

InfoIterable _generateForAnnotatedElement(
Element2 element,
Element element,
ConstantReader annotation,
) {
final String typedAnnotation = withoutNullability(
Expand All @@ -87,7 +87,7 @@ ${getters.map((String e) => "$e,").join('\n')}
typedAnnotation.indexOf('<'),
);
final String routeData = _annotations[type]!;
if (element is! ClassElement2) {
if (element is! ClassElement) {
throw InvalidGenerationSourceError(
'The @$type annotation can only be applied to classes.',
element: element,
Expand Down
38 changes: 19 additions & 19 deletions packages/go_router_builder/lib/src/route_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'dart:collection';

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:collection/collection.dart';
Expand Down Expand Up @@ -297,7 +297,7 @@ mixin _GoRouteMixin on RouteBaseConfig {
}

String _encodeFor(String fieldName) {
final PropertyAccessorElement2? field = _field(fieldName);
final PropertyAccessorElement? field = _field(fieldName);
if (field == null) {
throw InvalidGenerationSourceError(
'Could not find a field for the path parameter "$fieldName".',
Expand Down Expand Up @@ -363,8 +363,8 @@ mixin _GoRouteMixin on RouteBaseConfig {
)
.toList();

ConstructorElement2 get _ctor {
final ConstructorElement2? ctor = routeDataClass.unnamedConstructor2;
ConstructorElement get _ctor {
final ConstructorElement? ctor = routeDataClass.unnamedConstructor2;

if (ctor == null) {
throw InvalidGenerationSourceError(
Expand Down Expand Up @@ -596,7 +596,7 @@ abstract class RouteBaseConfig {
/// Creates a new [RouteBaseConfig] represented the annotation data in [reader].
factory RouteBaseConfig.fromAnnotation(
ConstantReader reader,
InterfaceElement2 element,
InterfaceElement element,
) {
final RouteBaseConfig definition = RouteBaseConfig._fromAnnotation(
reader,
Expand All @@ -617,7 +617,7 @@ abstract class RouteBaseConfig {

factory RouteBaseConfig._fromAnnotation(
ConstantReader reader,
InterfaceElement2 element,
InterfaceElement element,
RouteBaseConfig? parent, {
bool isAncestorRelative = false,
}) {
Expand Down Expand Up @@ -646,7 +646,7 @@ abstract class RouteBaseConfig {

// TODO(kevmoo): validate that this MUST be a subtype of `GoRouteData`
// ignore: experimental_member_use
final InterfaceElement2 classElement = typeParamType.element3;
final InterfaceElement classElement = typeParamType.element;

final RouteBaseConfig value;
switch (typeName) {
Expand Down Expand Up @@ -784,7 +784,7 @@ abstract class RouteBaseConfig {
final List<RouteBaseConfig> _children = <RouteBaseConfig>[];

/// The `RouteData` class this class represents.
final InterfaceElement2 routeDataClass;
final InterfaceElement routeDataClass;

/// The parent of this route config.
final RouteBaseConfig? parent;
Expand All @@ -797,11 +797,11 @@ abstract class RouteBaseConfig {
}

static String? _generateParameterGetterCode(
InterfaceElement2 classElement, {
InterfaceElement classElement, {
required String parameterName,
}) {
final String? fieldDisplayName = classElement.fields2
.where((FieldElement2 element) {
final String? fieldDisplayName = classElement.fields
.where((FieldElement element) {
if (!element.isStatic || element.displayName != parameterName) {
return false;
}
Expand All @@ -824,17 +824,17 @@ abstract class RouteBaseConfig {
}
return true;
})
.map<String>((FieldElement2 e) => e.displayName)
.map<String>((FieldElement e) => e.displayName)
.firstOrNull;

if (fieldDisplayName != null) {
return '${classElement.displayName}.$fieldDisplayName';
}
final String? methodDisplayName = classElement.methods2
.where((MethodElement2 element) {
.where((MethodElement element) {
return element.isStatic && element.displayName == parameterName;
})
.map<String>((MethodElement2 e) => e.displayName)
.map<String>((MethodElement e) => e.displayName)
.firstOrNull;

if (methodDisplayName != null) {
Expand Down Expand Up @@ -905,11 +905,11 @@ $routeDataClassName.$dataConvertionFunctionName(
''';
}

PropertyAccessorElement2? _field(String name) =>
PropertyAccessorElement? _field(String name) =>
routeDataClass.getGetter2(name);

List<ElementAnnotation>? _fieldMetadata(String name) => routeDataClass.fields2
.firstWhereOrNull((FieldElement2 element) => element.displayName == name)
List<ElementAnnotation>? _fieldMetadata(String name) => routeDataClass.fields
.firstWhereOrNull((FieldElement element) => element.displayName == name)
?.metadata2
.annotations;

Expand Down Expand Up @@ -942,8 +942,8 @@ String _enumMapConst(InterfaceType type) {
final StringBuffer buffer = StringBuffer('const ${enumMapName(type)} = {');

// ignore: experimental_member_use
for (final FieldElement2 enumField in type.element3.fields2.where(
(FieldElement2 element) => element.isEnumConstant,
for (final FieldElement enumField in type.element.fields.where(
(FieldElement element) => element.isEnumConstant,
)) {
buffer.writeln(
'$enumName.${enumField.displayName}: ${escapeDartString(enumField.displayName.kebab)},',
Expand Down
54 changes: 24 additions & 30 deletions packages/go_router_builder/lib/src/type_helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:collection/collection.dart';
import 'package:source_gen/source_gen.dart';
Expand Down Expand Up @@ -56,7 +56,7 @@ const List<_TypeHelper> _helpers = <_TypeHelper>[

/// Checks if has a function that converts string to string, such as encode and decode.
bool _isStringToStringFunction(
ExecutableElement2? executableElement,
ExecutableElement? executableElement,
String name,
) {
if (executableElement == null) {
Expand All @@ -71,9 +71,10 @@ bool _isStringToStringFunction(

/// Returns the custom codec for the annotation.
String? _getCustomCodec(ElementAnnotation annotation, String name) {
final ExecutableElement2? executableElement =
// ignore: experimental_member_use
annotation.computeConstantValue()?.getField(name)?.toFunctionValue2();
final ExecutableElement? executableElement = annotation
.computeConstantValue()
?.getField(name)
?.toFunctionValue2();
if (_isStringToStringFunction(executableElement, name)) {
return executableElement!.displayName;
}
Expand Down Expand Up @@ -141,7 +142,7 @@ String decodeParameter(
///
/// Otherwise, throws an [InvalidGenerationSourceError].
String encodeField(
PropertyAccessorElement2 element,
PropertyAccessorElement element,
List<ElementAnnotation>? metadata,
) {
for (final _TypeHelper helper in _helpers) {
Expand Down Expand Up @@ -181,19 +182,16 @@ String encodeField(
);
}

/// Returns an AstNode type from a InterfaceElement2.
T? getNodeDeclaration<T extends AstNode>(InterfaceElement2 element) {
/// Returns an AstNode type from a InterfaceElement.
T? getNodeDeclaration<T extends AstNode>(InterfaceElement element) {
final AnalysisSession? session = element.session;
if (session == null) {
return null;
}

final ParsedLibraryResult parsedLibrary =
// ignore: experimental_member_use
session.getParsedLibraryByElement2(element.library2)
as ParsedLibraryResult;
session.getParsedLibraryByElement(element.library) as ParsedLibraryResult;
final FragmentDeclarationResult? declaration = parsedLibrary
// ignore: experimental_member_use
.getFragmentDeclaration(element.firstFragment);
final AstNode? node = declaration?.node;

Expand Down Expand Up @@ -698,10 +696,10 @@ class _TypeHelperJson extends _TypeHelperWithHelper {
return false;
}

final MethodElement2? toJsonMethod = type.lookUpMethod3(
final MethodElement? toJsonMethod = type.lookUpMethod(
'toJson',
// ignore: experimental_member_use
type.element3.library2,

type.element.library,
);
if (toJsonMethod == null ||
!toJsonMethod.isPublic ||
Expand All @@ -715,9 +713,9 @@ class _TypeHelperJson extends _TypeHelperWithHelper {
return _matchesType(type.typeArguments.first);
}

// ignore: experimental_member_use
final ConstructorElement2? fromJsonMethod = type.element3
.getNamedConstructor2('fromJson');
final ConstructorElement? fromJsonMethod = type.element.getNamedConstructor(
'fromJson',
);

if (fromJsonMethod == null ||
!fromJsonMethod.isPublic ||
Expand All @@ -729,8 +727,8 @@ class _TypeHelperJson extends _TypeHelperWithHelper {
throw InvalidGenerationSourceError(
'The parameter type '
'`${type.getDisplayString(withNullability: false)}` not have a supported fromJson definition.',
// ignore: experimental_member_use
element: type.element3,

element: type.element,
);
}

Expand Down Expand Up @@ -759,9 +757,9 @@ class _TypeHelperJson extends _TypeHelperWithHelper {

bool _isNestedTemplate(InterfaceType type) {
// check if has fromJson constructor
// ignore: experimental_member_use
final ConstructorElement2? fromJsonMethod = type.element3
.getNamedConstructor2('fromJson');
final ConstructorElement? fromJsonMethod = type.element.getNamedConstructor(
'fromJson',
);
if (fromJsonMethod == null || !fromJsonMethod.isPublic) {
return false;
}
Expand All @@ -783,8 +781,7 @@ class _TypeHelperJson extends _TypeHelperWithHelper {
throw InvalidGenerationSourceError(
'The parameter type '
'`${type.getDisplayString(withNullability: false)}` not have a supported fromJson definition.',
// ignore: experimental_member_use
element: type.element3,
element: type.element,
);
}

Expand All @@ -795,17 +792,14 @@ class _TypeHelperJson extends _TypeHelperWithHelper {
}

final FunctionType functionType = secondParam.type as FunctionType;
// ignore: experimental_member_use
if (functionType.formalParameters.length != 1 ||
functionType.returnType.getDisplayString() !=
type.element.typeParameters.first.displayName ||
// ignore: experimental_member_use
functionType.formalParameters[0].type.getDisplayString() != 'Object?') {
throw InvalidGenerationSourceError(
'The parameter type '
'`${type.getDisplayString(withNullability: false)}` not have a supported fromJson definition.',
// ignore: experimental_member_use
element: type.element3,
element: type.element,
);
}

Expand Down Expand Up @@ -866,7 +860,7 @@ extension FormalParameterElementExtension on FormalParameterElement {
/// An error thrown when a default value is used with a nullable type.
class NullableDefaultValueError extends InvalidGenerationSourceError {
/// An error thrown when a default value is used with a nullable type.
NullableDefaultValueError(Element2 element)
NullableDefaultValueError(Element element)
: super(
'Default value used with a nullable type. Only non-nullable type can have a default value.',
todo: 'Remove the default value or make the type non-nullable.',
Expand Down
9 changes: 4 additions & 5 deletions packages/go_router_builder/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,18 @@ environment:
flutter: ">=3.32.0"

dependencies:
analyzer: ">=7.4.0 <9.0.0"
analyzer: ^8.1.1
async: ^2.8.0
# TODO(piinks): Pin version once new stable rolls.
build: ">=3.0.0 <5.0.0"
build: ^4.0.2
build_config: ^1.0.0
collection: ^1.14.0
meta: ^1.7.0
path: ^1.8.0
source_gen: ">=3.1.0 <5.0.0"
source_gen: ^4.0.2
source_helper: ^1.3.4

dev_dependencies:
build_test: ^3.3.0
build_test: ^3.4.1
dart_style: ">=2.3.7 <4.0.0"
flutter:
sdk: flutter
Expand Down
4 changes: 2 additions & 2 deletions packages/go_router_builder/tool/run_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import 'dart:io';
import 'dart:isolate';

import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:build/build.dart';
import 'package:build_test/build_test.dart';
import 'package:dart_style/dart_style.dart' as dart_style;
Expand Down Expand Up @@ -42,7 +42,7 @@ Future<void> main() async {
// Normalize path separators for cross-platform compatibility
final String path = file.path.replaceAll(r'\', '/');
final String targetLibraryAssetId = '__test__|$path';
final LibraryElement2 element = await resolveSources<LibraryElement2>(
final LibraryElement element = await resolveSources<LibraryElement>(
<String, String>{targetLibraryAssetId: file.readAsStringSync()},
(Resolver resolver) async {
final AssetId assetId = AssetId.parse(targetLibraryAssetId);
Expand Down