Skip to content
Open
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/freezed/lib/src/templates/abstract_template.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ mixin _\$${data.name.public}${data.genericsDefinitionTemplate}$interfaces {

$abstractProperties
${copyWith?.copyWithGetter(needsCast: true) ?? ''}
${methods(data, globalData, properties: commonProperties, name: data.name, escapedName: data.escapedName, source: Source.mixin)}
// Fixed: Added isConst parameter for hashCode caching
${methods(data, globalData, properties: commonProperties, name: data.name, escapedName: data.escapedName, source: Source.mixin, isConst: false)}
}

${copyWith?.commonInterface ?? ''}
Expand Down
26 changes: 14 additions & 12 deletions packages/freezed/lib/src/templates/concrete_template.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ${constructor.redirectedName}${data.genericsDefinitionTemplate} $_concrete
$_properties

${copyWith?.copyWithGetter(needsCast: false) ?? ''}
${methods(data, globalData, properties: constructor.properties, name: constructor.redirectedName, escapedName: constructor.escapedName, source: Source.syntheticClass)}
${methods(data, globalData, properties: constructor.properties, name: constructor.redirectedName, escapedName: constructor.escapedName, source: Source.syntheticClass, isConst: constructor.isConst)}
}

${copyWith?.interface ?? ''}
Expand Down Expand Up @@ -325,12 +325,13 @@ String methods(
required String name,
required String escapedName,
required Source source,
required bool isConst,
}) {
return '''
${toJson(data, name: name, source: source)}
${debugFillProperties(data, globalData, properties, escapedClassName: escapedName)}
${operatorEqualMethod(data, properties, className: name, source: source)}
${hashCodeMethod(data, properties, source: source)}
${hashCodeMethod(data, properties, source: source, isConst: isConst)}
${toStringMethod(data, globalData, escapedClassName: escapedName, properties: properties)}
''';
}
Expand Down Expand Up @@ -467,6 +468,7 @@ String hashCodeMethod(
Class data,
List<Property> properties, {
required Source source,
required bool isConst,
}) {
if (!data.options.equal) return '';

Expand All @@ -491,25 +493,25 @@ String hashCodeMethod(
property.name,
];

if (hashedProperties.length == 1) {
final hashCodeExpression = hashedProperties.length == 1
? '${hashedProperties.first}.hashCode'
: hashedProperties.length >= 20
? 'Object.hashAll([${hashedProperties.join(',')}])'
: 'Object.hash(${hashedProperties.join(',')})';

if (isConst || source == Source.mixin) {
return '''
$jsonKey
@override
int get hashCode => ${hashedProperties.first}.hashCode;
''';
}
if (hashedProperties.length >= 20) {
return '''
$jsonKey
@override
int get hashCode => Object.hashAll([${hashedProperties.join(',')}]);
int get hashCode => $hashCodeExpression;
''';
}

return '''
$jsonKey
int? _cachedHashCode;
@override
int get hashCode => Object.hash(${hashedProperties.join(',')});
int get hashCode => _cachedHashCode ??= $hashCodeExpression;
''';
}

Expand Down
12 changes: 6 additions & 6 deletions packages/freezed_annotation/lib/freezed_annotation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class EqualUnmodifiableListView<T> extends UnmodifiableListView<T> {
bool operator ==(Object other) {
return other is EqualUnmodifiableListView<T> &&
other.runtimeType == runtimeType &&
other._source == _source;
const DeepCollectionEquality().equals(other._source, _source);
}

@override
int get hashCode => Object.hash(runtimeType, _source);
int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(_source));
}

/// An [UnmodifiableSetView] which overrides ==
Expand All @@ -36,11 +36,11 @@ class EqualUnmodifiableSetView<T> extends UnmodifiableSetView<T> {
bool operator ==(Object other) {
return other is EqualUnmodifiableSetView<T> &&
other.runtimeType == runtimeType &&
other._source == _source;
const DeepCollectionEquality().equals(other._source, _source);
}

@override
int get hashCode => Object.hash(runtimeType, _source);
int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(_source));
}

/// An [UnmodifiableMapView] which overrides ==
Expand All @@ -55,11 +55,11 @@ class EqualUnmodifiableMapView<Key, Value>
bool operator ==(Object other) {
return other is EqualUnmodifiableMapView<Key, Value> &&
other.runtimeType == runtimeType &&
other._source == _source;
const DeepCollectionEquality().equals(other._source, _source);
}

@override
int get hashCode => Object.hash(runtimeType, _source);
int get hashCode => Object.hash(runtimeType, const DeepCollectionEquality().hash(_source));
}

/// Options for enabling/disabling specific `Union.map` features;
Expand Down
Loading