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
34 changes: 17 additions & 17 deletions packages/freezed/lib/src/ast.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:analyzer/dart/element/element.dart';

extension AstX on AstNode {
String? get documentation {
Expand Down Expand Up @@ -28,10 +28,10 @@ extension ClassX on ClassDeclaration {
element,
...element.allSupertypes
.where((e) => !e.isDartCoreObject)
.map((e) => e.element3),
.map((e) => e.element),
]) {
for (final method in type.methods2) {
if (method.name3 == 'toString') {
for (final method in type.methods) {
if (method.name == 'toString') {
return true;
}
}
Expand All @@ -42,50 +42,50 @@ extension ClassX on ClassDeclaration {

bool get hasSuperEqual => declaredFragment!.element.allSupertypes
.where((e) => !e.isDartCoreObject)
.map((e) => e.element3)
.map((e) => e.element)
.any((e) => e.hasEqual);

bool get hasCustomEquals => declaredFragment!.element.hasEqual;

bool get hasSuperHashCode => declaredFragment!.element.allSupertypes
.where((e) => !e.isDartCoreObject)
.map((e) => e.element3)
.map((e) => e.element)
.any((e) => e.hasHashCode);
}

extension on InterfaceElement2 {
bool get hasEqual => methods2.any(((e) => e.isOperator && e.name3 == '=='));
extension on InterfaceElement {
bool get hasEqual => methods.any(((e) => e.isOperator && e.name == '=='));

bool get hasHashCode => getters2.any((e) => e.name3 == 'hashCode');
bool get hasHashCode => getters.any((e) => e.name == 'hashCode');
}

extension ConstructorX on ConstructorDeclaration {
String get fullName {
final classElement = declaredFragment!.element.enclosingElement2;
final classElement = declaredFragment!.element.enclosingElement;

var generics = classElement.typeParameters2
.map((e) => '\$${e.name3}')
var generics = classElement.typeParameters
.map((e) => '\$${e.name}')
.join(', ');
if (generics.isNotEmpty) {
generics = '<$generics>';
}

final className = classElement.enclosingElement2.name3;
final className = classElement.enclosingElement.name;

return name == null ? '$className$generics' : '$className$generics.$name';
}
Comment on lines 63 to 76
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bug: fullName uses the library name instead of the class name

classElement.enclosingElement.name returns the library’s name. Use the class element’s name.

   String get fullName {
     final classElement = declaredFragment!.element.enclosingElement;
 
     var generics = classElement.typeParameters
         .map((e) => '\$${e.name}')
         .join(', ');
     if (generics.isNotEmpty) {
       generics = '<$generics>';
     }
 
-    final className = classElement.enclosingElement.name;
+    final className = classElement.name!;
 
     return name == null ? '$className$generics' : '$className$generics.$name';
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
String get fullName {
final classElement = declaredFragment!.element.enclosingElement2;
final classElement = declaredFragment!.element.enclosingElement;
var generics = classElement.typeParameters2
.map((e) => '\$${e.name3}')
var generics = classElement.typeParameters
.map((e) => '\$${e.name}')
.join(', ');
if (generics.isNotEmpty) {
generics = '<$generics>';
}
final className = classElement.enclosingElement2.name3;
final className = classElement.enclosingElement.name;
return name == null ? '$className$generics' : '$className$generics.$name';
}
String get fullName {
final classElement = declaredFragment!.element.enclosingElement;
var generics = classElement.typeParameters
.map((e) => '\$${e.name}')
.join(', ');
if (generics.isNotEmpty) {
generics = '<$generics>';
}
final className = classElement.name!;
return name == null ? '$className$generics' : '$className$generics.$name';
}
🤖 Prompt for AI Agents
In packages/freezed/lib/src/ast.dart around lines 63 to 76, the code grabs the
enclosingElement (library) instead of the class element so className becomes the
library name; change the code so classElement refers to
declaredFragment!.element (the class element) and use classElement.name for the
className, keeping the existing handling of typeParameters/generics and adding a
null-safe fallback (e.g., empty string) if name is null to avoid crashes.


String get escapedName {
final classElement = declaredFragment!.element.enclosingElement2;
final classElement = declaredFragment!.element.enclosingElement;

var generics = classElement.typeParameters2
.map((e) => '\$${e.name3}')
var generics = classElement.typeParameters
.map((e) => '\$${e.name}')
.join(', ');
if (generics.isNotEmpty) {
generics = '<$generics>';
}

final escapedElementName = classElement.name3!.replaceAll(r'$', r'\$');
final escapedElementName = classElement.name!.replaceAll(r'$', r'\$');
final escapedConstructorName = name?.lexeme.replaceAll(r'$', r'\$');

return escapedConstructorName == null
Expand Down
87 changes: 45 additions & 42 deletions packages/freezed/lib/src/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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 All @@ -27,7 +27,7 @@ class _Sentinel {
const _Sentinel();
}

extension on Element2 {
extension on Element {
bool get hasJsonSerializable {
return const TypeChecker.typeNamed(
JsonSerializable,
Expand All @@ -36,9 +36,9 @@ extension on Element2 {
}
}

extension on ConstructorElement2 {
extension on ConstructorElement {
bool isFallbackUnion(String? fallbackConstructorName) {
final constructorName = isDefaultConstructor(this) ? 'default' : name3;
final constructorName = isDefaultConstructor(this) ? 'default' : name;
return constructorName == fallbackConstructorName;
}

Expand All @@ -51,7 +51,7 @@ extension on ConstructorElement2 {
return annotation.getField('value')!.toStringValue()!;
}

final constructorName = isDefaultConstructor(this) ? 'default' : name3!;
final constructorName = isDefaultConstructor(this) ? 'default' : name!;
switch (unionCase) {
case null:
case FreezedUnionCase.none:
Expand Down Expand Up @@ -97,8 +97,8 @@ class DeepCloneableProperty {

final parameterType = parameter.type;
if (parameterType is! InterfaceType) continue;
final typeElement = parameterType.element3;
if (typeElement is! ClassElement2) continue;
final typeElement = parameterType.element;
if (typeElement is! ClassElement) continue;

final freezedAnnotation = freezedType.firstAnnotationOf(
typeElement,
Expand All @@ -116,10 +116,10 @@ class DeepCloneableProperty {
if (configs.copyWith == false) continue;

yield DeepCloneableProperty(
name: parameter.name3!,
name: parameter.name!,
type: type,
nullable: parameter.type.isNullable,
typeName: typeElement.name3!,
typeName: typeElement.name!,
genericParameters: GenericsParameterTemplate(
(parameter.type as InterfaceType).typeArguments
.map((e) => e.getDisplayString())
Expand Down Expand Up @@ -269,7 +269,7 @@ When specifying fields in non-factory constructor then specifying factory constr
}

final redirectedName =
constructor.redirectedConstructor?.type.name2.lexeme;
constructor.redirectedConstructor?.type.name.lexeme;

if (redirectedName == null) {
_assertValidNormalConstructorUsage(declaration, constructor);
Expand All @@ -283,7 +283,7 @@ When specifying fields in non-factory constructor then specifying factory constr

final excludedProperties =
manualConstructor?.parameters.parameters
.map((e) => e.declaredFragment!.element.name3!)
.map((e) => e.declaredFragment!.element.name!)
.toSet() ??
<String>{};

Expand Down Expand Up @@ -318,7 +318,7 @@ When specifying fields in non-factory constructor then specifying factory constr
decorators: constructor.metadata
.where((element) {
final elementSourceUri =
element.element2?.baseElement.library2?.uri;
element.element?.baseElement.library?.uri;

final isFreezedAnnotation =
elementSourceUri != null &&
Expand Down Expand Up @@ -424,7 +424,7 @@ class ImplementsAnnotation {
ImplementsAnnotation({required this.type});

static Iterable<ImplementsAnnotation> parseAll(
ConstructorElement2 constructor,
ConstructorElement constructor,
) sync* {
for (final meta in const TypeChecker.typeNamed(
Implements,
Expand All @@ -436,7 +436,7 @@ class ImplementsAnnotation {
} else {
yield ImplementsAnnotation(
type: resolveFullTypeStringFrom(
constructor.library2,
constructor.library,
(meta.type! as InterfaceType).typeArguments.single,
),
);
Expand All @@ -451,9 +451,9 @@ class WithAnnotation {
WithAnnotation({required this.type});

static Iterable<WithAnnotation> parseAll(
ConstructorElement2 constructor,
ConstructorElement constructor,
) sync* {
for (final metadata in constructor.metadata2.annotations) {
for (final metadata in constructor.metadata.annotations) {
if (!metadata.isWith) continue;
final object = metadata.computeConstantValue()!;

Expand All @@ -463,7 +463,7 @@ class WithAnnotation {
} else {
yield WithAnnotation(
type: resolveFullTypeStringFrom(
constructor.library2,
constructor.library,
(object.type! as InterfaceType).typeArguments.single,
),
);
Expand Down Expand Up @@ -522,7 +522,7 @@ class CopyWithTarget {

extension on NamedType {
bool isSuperMixin(ClassDeclaration declaration) =>
name2.lexeme == '_\$${declaration.name.lexeme.public}';
name.lexeme == '_\$${declaration.name.lexeme.public}';
}

class Class {
Expand Down Expand Up @@ -552,7 +552,7 @@ class Class {
final ClassDeclaration _node;
final Set<Class> parents = {};

LibraryElement2 get library => _node.declaredFragment!.element.library2;
LibraryElement get library => _node.declaredFragment!.element.library;

static Class _from(
ClassDeclaration declaration,
Expand All @@ -570,7 +570,7 @@ class Class {
);

if (constructors.isNotEmpty) {
for (final field in declaration.declaredFragment!.element.fields2) {
for (final field in declaration.declaredFragment!.element.fields) {
_assertValidFieldUsage(field, shouldUseExtends: privateCtor != null);
}
}
Expand Down Expand Up @@ -676,14 +676,14 @@ To fix, either:
options: configs,
constructors: constructors,
concretePropertiesName: [
for (final p in declaration.declaredFragment!.element.fields2)
if (!p.isStatic) p.name3!,
for (final p in declaration.declaredFragment!.element.fields)
if (!p.isStatic) p.name!,
],
genericsDefinitionTemplate: GenericsDefinitionTemplate.fromGenericElement(
declaration.declaredFragment!.element.typeParameters2,
declaration.declaredFragment!.element.typeParameters,
),
genericsParameterTemplate: GenericsParameterTemplate.fromGenericElement(
declaration.declaredFragment!.element.typeParameters2,
declaration.declaredFragment!.element.typeParameters,
),
);
}
Expand Down Expand Up @@ -745,7 +745,7 @@ To fix, either:
if (clazz._node.extendsClause case final extend?) extend.superclass,
...?clazz._node.implementsClause?.interfaces,
...?clazz._node.withClause?.mixinTypes,
].map((e) => e.name2.lexeme);
].map((e) => e.name.lexeme);

for (final superType in superTypes) {
final superTypeClass = classMap[superType];
Expand Down Expand Up @@ -833,7 +833,10 @@ To fix, either:
isFinal: property.$1.fields.isFinal,
isSynthetic: false,
decorators: switch (property.$1.declaredFragment?.element) {
final Annotatable e => parseDecorators(e.metadata2.annotations),
Fragment(metadata: final metadata) ||
Element(
metadata: final metadata,
) => parseDecorators(metadata.annotations),
_ => [],
},
);
Expand Down Expand Up @@ -862,9 +865,9 @@ To fix, either:
}

late final typeSystem =
declaration.declaredFragment!.element.library2.typeSystem;
declaration.declaredFragment!.element.library.typeSystem;
late final typeProvider =
declaration.declaredFragment!.element.library2.typeProvider;
declaration.declaredFragment!.element.library.typeProvider;

fieldLoop:
for (final entry in typesMap.entries) {
Expand Down Expand Up @@ -918,7 +921,7 @@ To fix, either:
isFinal = true;

typeString = resolveFullTypeStringFrom(
declaration.declaredFragment!.element.library2,
declaration.declaredFragment!.element.library,
type,
);
}
Expand Down Expand Up @@ -964,7 +967,7 @@ To fix, either:
param: parameter.name,
);

final library = parameter.parameterElement!.library2!;
final library = parameter.parameterElement!.library!;

var commonTypeBetweenAllUnionConstructors =
parameter.parameterElement!.type;
Expand Down Expand Up @@ -1061,12 +1064,12 @@ To fix, either:
}

static void _assertValidFieldUsage(
FieldElement2 field, {
FieldElement field, {
required bool shouldUseExtends,
}) {
if (field.isStatic) return;

if (field.setter2 != null) {
if (field.setter != null) {
throw InvalidGenerationSourceError(
'Classes decorated with @freezed cannot have mutable properties',
element: field,
Expand All @@ -1075,9 +1078,9 @@ To fix, either:

// The field is a "Type get name => "
if (!shouldUseExtends &&
field.getter2 != null &&
!field.getter2!.isAbstract &&
!field.getter2!.isSynthetic) {
field.getter != null &&
!field.getter!.isAbstract &&
!field.getter!.isSynthetic) {
throw InvalidGenerationSourceError(
'Getters require a MyClass._() constructor',
element: field,
Expand Down Expand Up @@ -1129,10 +1132,10 @@ class Library {
return Library(
hasJson: units.any(
(unit) =>
unit.declaredFragment!.element.library2.importsJsonSerializable,
unit.declaredFragment!.element.library.importsJsonSerializable,
),
hasDiagnostics: units.any(
(unit) => unit.declaredFragment!.element.library2.importsDiagnosticable,
(unit) => unit.declaredFragment!.element.library.importsDiagnosticable,
),
);
}
Expand Down Expand Up @@ -1357,18 +1360,18 @@ extension ClassDeclarationX on ClassDeclaration {
}
}

extension on LibraryElement2 {
extension on LibraryElement {
bool get importsJsonSerializable {
return findAllAvailableTopLevelElements().any((element) {
return element.name3 == 'JsonSerializable' &&
(element.library2?.isFromPackage('json_annotation') ?? false);
return element.name == 'JsonSerializable' &&
(element.library?.isFromPackage('json_annotation') ?? false);
});
}

bool get importsDiagnosticable {
return findAllAvailableTopLevelElements().any((element) {
return element.name3 == 'DiagnosticableTreeMixin' &&
(element.library2?.isFromPackage('flutter') ?? false);
return element.name == 'DiagnosticableTreeMixin' &&
(element.library?.isFromPackage('flutter') ?? false);
});
}
}
Expand Down
Loading