Skip to content
Merged
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
3 changes: 2 additions & 1 deletion packages/go_router_builder/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 4.1.2

* Updates supported analyzer versions to 8.x or 9.x.
* Updates minimum supported SDK version to Flutter 3.32/Dart 3.8.

## 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
56 changes: 27 additions & 29 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 @@ -57,14 +57,14 @@ class ShellRouteConfig extends RouteBaseConfig {

@override
Iterable<String> classDeclarations() {
if (routeDataClass.unnamedConstructor2 == null) {
if (routeDataClass.unnamedConstructor == null) {
throw InvalidGenerationSourceError(
'The ShellRouteData "$_className" class must have an unnamed constructor.',
element: routeDataClass,
);
}

final bool isConst = routeDataClass.unnamedConstructor2!.isConst;
final bool isConst = routeDataClass.unnamedConstructor!.isConst;

return <String>[
'''
Expand Down Expand Up @@ -116,7 +116,7 @@ class StatefulShellRouteConfig extends RouteBaseConfig {
Iterable<String> classDeclarations() => <String>[
'''
extension $_extensionName on $_className {
static $_className _fromState(GoRouterState state) =>${routeDataClass.unnamedConstructor2!.isConst ? ' const' : ''} $_className();
static $_className _fromState(GoRouterState state) =>${routeDataClass.unnamedConstructor!.isConst ? ' const' : ''} $_className();
}
''',
];
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.unnamedConstructor;

if (ctor == null) {
throw InvalidGenerationSourceError(
Expand Down Expand Up @@ -465,7 +465,7 @@ class GoRouteConfig extends RouteBaseConfig with _GoRouteMixin {
getNodeDeclaration<ClassDeclaration>(routeDataClass)
?.withClause
?.mixinTypes
.any((NamedType e) => e.name2.toString() == _mixinName) ??
.any((NamedType e) => e.name.toString() == _mixinName) ??
false;

if (!hasMixin) {
Expand Down Expand Up @@ -540,7 +540,7 @@ class RelativeGoRouteConfig extends RouteBaseConfig with _GoRouteMixin {
getNodeDeclaration<ClassDeclaration>(routeDataClass)
?.withClause
?.mixinTypes
.any((NamedType e) => e.name2.toString() == _mixinName) ??
.any((NamedType e) => e.name.toString() == _mixinName) ??
false;

if (!hasMixin) {
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 definition = RouteBaseConfig._fromAnnotation(reader, element, null);

Expand All @@ -613,7 +613,7 @@ abstract class RouteBaseConfig {

factory RouteBaseConfig._fromAnnotation(
ConstantReader reader,
InterfaceElement2 element,
InterfaceElement element,
RouteBaseConfig? parent, {
bool isAncestorRelative = false,
}) {
Expand Down Expand Up @@ -641,8 +641,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 @@ -780,7 +779,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 @@ -793,11 +792,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 @@ -820,17 +819,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) {
final String? methodDisplayName = classElement.methods
.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 @@ -901,12 +900,12 @@ $routeDataClassName.$dataConvertionFunctionName(
''';
}

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

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

/// The name of `RouteData` subclass this configuration represents.
Expand Down Expand Up @@ -937,9 +936,8 @@ String _enumMapConst(InterfaceType type) {

final 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
66 changes: 29 additions & 37 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)
?.toFunctionValue();
if (_isStringToStringFunction(executableElement, name)) {
return executableElement!.displayName;
}
Expand Down Expand Up @@ -111,7 +112,7 @@ String decodeParameter(
} else {
throw InvalidGenerationSourceError(
'The parameter type '
'`${paramType.getDisplayString(withNullability: false)}` not have a well defined CustomParameterCodec decorator.',
'`${withoutNullability(paramType.getDisplayString())}` not have a well defined CustomParameterCodec decorator.',
element: element,
);
}
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 All @@ -161,7 +162,7 @@ String encodeField(
} else {
throw InvalidGenerationSourceError(
'The parameter type '
'`${element.type.getDisplayString(withNullability: false)}` not have a well defined CustomParameterCodec decorator.',
'`${withoutNullability(element.type.getDisplayString())}` not have a well defined CustomParameterCodec decorator.',
element: element,
);
}
Expand All @@ -182,18 +183,15 @@ String encodeField(
}

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

final 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,9 @@ 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,22 +712,21 @@ 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 ||
fromJsonMethod.formalParameters.length != 1 ||
fromJsonMethod.formalParameters.first.type.getDisplayString(
withNullability: false,
withoutNullability(
fromJsonMethod.formalParameters.first.type.getDisplayString(),
) !=
'Map<String, dynamic>') {
throw InvalidGenerationSourceError(
'The parameter type '
'`${type.getDisplayString(withNullability: false)}` not have a supported fromJson definition.',
// ignore: experimental_member_use
element: type.element3,
'`${withoutNullability(type.getDisplayString())}` not have a supported fromJson definition.',
element: type.element,
);
}

Expand Down Expand Up @@ -759,9 +755,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 @@ -778,13 +774,12 @@ class _TypeHelperJson extends _TypeHelperWithHelper {
}

final FormalParameterElement firstParam = parameters[0];
if (firstParam.type.getDisplayString(withNullability: false) !=
if (withoutNullability(firstParam.type.getDisplayString()) !=
'Map<String, dynamic>') {
throw InvalidGenerationSourceError(
'The parameter type '
'`${type.getDisplayString(withNullability: false)}` not have a supported fromJson definition.',
// ignore: experimental_member_use
element: type.element3,
'`${withoutNullability(type.getDisplayString())}` not have a supported fromJson definition.',
element: type.element,
);
}

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

final 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,
'`${withoutNullability(type.getDisplayString())}` not have a supported fromJson definition.',
element: type.element,
);
}

Expand Down Expand Up @@ -866,7 +858,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
Loading