From 718e1e6a474ee8b3ad7d4cb7f5e2bccc560003a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Ku=C3=9F?= Date: Fri, 3 May 2024 23:22:14 +0200 Subject: [PATCH] Use Object.hashAll when parameter count for hashCode exceeds 20 (#36) --- .../fixtures/many_param/input.dart | 29 ++ .../fixtures/many_param/input.genq.dart | 251 ++++++++++++++++++ tool/generation_test/gen_test.go | 4 + tool/templates/scaffold.go | 22 +- 4 files changed, 301 insertions(+), 5 deletions(-) create mode 100644 tool/generation_test/fixtures/many_param/input.dart create mode 100644 tool/generation_test/fixtures/many_param/input.genq.dart diff --git a/tool/generation_test/fixtures/many_param/input.dart b/tool/generation_test/fixtures/many_param/input.dart new file mode 100644 index 0000000..4e6e003 --- /dev/null +++ b/tool/generation_test/fixtures/many_param/input.dart @@ -0,0 +1,29 @@ +import 'package:genq/genq.dart'; + +part 'input.genq.dart'; + +@genq +class ManyParams with _$ManyParams { + factory ManyParams({ + required int a, + required int b, + required int c, + required int d, + required int e, + required int f, + required int g, + required int h, + required int i, + required int j, + required int k, + required int l, + required int m, + required int n, + required int o, + required int p, + required int q, + required int r, + required int s, + required int t, + }) = _ManyParams; +} diff --git a/tool/generation_test/fixtures/many_param/input.genq.dart b/tool/generation_test/fixtures/many_param/input.genq.dart new file mode 100644 index 0000000..d4de2ba --- /dev/null +++ b/tool/generation_test/fixtures/many_param/input.genq.dart @@ -0,0 +1,251 @@ +part of 'input.dart'; + +mixin _$ManyParams { + int get a => throw UnimplementedError(); + int get b => throw UnimplementedError(); + int get c => throw UnimplementedError(); + int get d => throw UnimplementedError(); + int get e => throw UnimplementedError(); + int get f => throw UnimplementedError(); + int get g => throw UnimplementedError(); + int get h => throw UnimplementedError(); + int get i => throw UnimplementedError(); + int get j => throw UnimplementedError(); + int get k => throw UnimplementedError(); + int get l => throw UnimplementedError(); + int get m => throw UnimplementedError(); + int get n => throw UnimplementedError(); + int get o => throw UnimplementedError(); + int get p => throw UnimplementedError(); + int get q => throw UnimplementedError(); + int get r => throw UnimplementedError(); + int get s => throw UnimplementedError(); + int get t => throw UnimplementedError(); + + $ManyParamsCopyWith get copyWith => throw UnimplementedError(); +} + +class _ManyParams implements ManyParams { + @override + final int a; + + @override + final int b; + + @override + final int c; + + @override + final int d; + + @override + final int e; + + @override + final int f; + + @override + final int g; + + @override + final int h; + + @override + final int i; + + @override + final int j; + + @override + final int k; + + @override + final int l; + + @override + final int m; + + @override + final int n; + + @override + final int o; + + @override + final int p; + + @override + final int q; + + @override + final int r; + + @override + final int s; + + @override + final int t; + + _ManyParams({ + required this.a, + required this.b, + required this.c, + required this.d, + required this.e, + required this.f, + required this.g, + required this.h, + required this.i, + required this.j, + required this.k, + required this.l, + required this.m, + required this.n, + required this.o, + required this.p, + required this.q, + required this.r, + required this.s, + required this.t, + }); + + @override + $ManyParamsCopyWith get copyWith => _$ManyParamsCopyWithImpl(this); + + @override + String toString() { + return "ManyParams(a: $a, b: $b, c: $c, d: $d, e: $e, f: $f, g: $g, h: $h, i: $i, j: $j, k: $k, l: $l, m: $m, n: $n, o: $o, p: $p, q: $q, r: $r, s: $s, t: $t)"; + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + if (other is! ManyParams) return false; + if (!identical(other.a, a) && other.a != a) return false; + if (!identical(other.b, b) && other.b != b) return false; + if (!identical(other.c, c) && other.c != c) return false; + if (!identical(other.d, d) && other.d != d) return false; + if (!identical(other.e, e) && other.e != e) return false; + if (!identical(other.f, f) && other.f != f) return false; + if (!identical(other.g, g) && other.g != g) return false; + if (!identical(other.h, h) && other.h != h) return false; + if (!identical(other.i, i) && other.i != i) return false; + if (!identical(other.j, j) && other.j != j) return false; + if (!identical(other.k, k) && other.k != k) return false; + if (!identical(other.l, l) && other.l != l) return false; + if (!identical(other.m, m) && other.m != m) return false; + if (!identical(other.n, n) && other.n != n) return false; + if (!identical(other.o, o) && other.o != o) return false; + if (!identical(other.p, p) && other.p != p) return false; + if (!identical(other.q, q) && other.q != q) return false; + if (!identical(other.r, r) && other.r != r) return false; + if (!identical(other.s, s) && other.s != s) return false; + if (!identical(other.t, t) && other.t != t) return false; + return true; + } + + @override + int get hashCode { + return Object.hashAll([ + runtimeType, + a, + b, + c, + d, + e, + f, + g, + h, + i, + j, + k, + l, + m, + n, + o, + p, + q, + r, + s, + t, + ]); + } +} + +abstract class $ManyParamsCopyWith { + ManyParams call({ + int a, + int b, + int c, + int d, + int e, + int f, + int g, + int h, + int i, + int j, + int k, + int l, + int m, + int n, + int o, + int p, + int q, + int r, + int s, + int t, + }); +} + +class _$ManyParamsCopyWithImpl implements $ManyParamsCopyWith { + final _$ManyParams value; + + _$ManyParamsCopyWithImpl(this.value); + + @override + ManyParams call({ + Object? a = genq, + Object? b = genq, + Object? c = genq, + Object? d = genq, + Object? e = genq, + Object? f = genq, + Object? g = genq, + Object? h = genq, + Object? i = genq, + Object? j = genq, + Object? k = genq, + Object? l = genq, + Object? m = genq, + Object? n = genq, + Object? o = genq, + Object? p = genq, + Object? q = genq, + Object? r = genq, + Object? s = genq, + Object? t = genq, + }) { + return ManyParams( + a: a == genq ? value.a : a as int, + b: b == genq ? value.b : b as int, + c: c == genq ? value.c : c as int, + d: d == genq ? value.d : d as int, + e: e == genq ? value.e : e as int, + f: f == genq ? value.f : f as int, + g: g == genq ? value.g : g as int, + h: h == genq ? value.h : h as int, + i: i == genq ? value.i : i as int, + j: j == genq ? value.j : j as int, + k: k == genq ? value.k : k as int, + l: l == genq ? value.l : l as int, + m: m == genq ? value.m : m as int, + n: n == genq ? value.n : n as int, + o: o == genq ? value.o : o as int, + p: p == genq ? value.p : p as int, + q: q == genq ? value.q : q as int, + r: r == genq ? value.r : r as int, + s: s == genq ? value.s : s as int, + t: t == genq ? value.t : t as int, + ); + } +} \ No newline at end of file diff --git a/tool/generation_test/gen_test.go b/tool/generation_test/gen_test.go index d6a99ab..36bbc2b 100644 --- a/tool/generation_test/gen_test.go +++ b/tool/generation_test/gen_test.go @@ -92,3 +92,7 @@ func TestJsonCollections(t *testing.T) { func TestSealedClasses(t *testing.T) { testGenOutput(t, "sealed_classes") } + +func TestManyParam(t *testing.T) { + testGenOutput(t, "many_param") +} diff --git a/tool/templates/scaffold.go b/tool/templates/scaffold.go index f09c23b..cce541c 100644 --- a/tool/templates/scaffold.go +++ b/tool/templates/scaffold.go @@ -103,12 +103,24 @@ func templateConstructor(str []string, classDecl GenqClassDeclaration) []string str = append(str, indent(2, fmt.Sprintf("int get hashCode {"))) if len(classDecl.Constructor.ParamList.NamedParams) > 0 { - str = append(str, indent(4, fmt.Sprintf("return Object.hash("))) - str = append(str, indent(6, "runtimeType,")) - for _, param := range classDecl.Constructor.ParamList.NamedParams { - str = append(str, indent(6, fmt.Sprintf("%s,", param.Name))) + // The +1 is for the runtimeType + totalParamCount := len(classDecl.Constructor.ParamList.NamedParams) + 1 + if totalParamCount > 20 { + str = append(str, indent(4, fmt.Sprintf("return Object.hashAll(["))) + str = append(str, indent(6, "runtimeType,")) + for _, param := range classDecl.Constructor.ParamList.NamedParams { + str = append(str, indent(6, fmt.Sprintf("%s,", param.Name))) + } + str = append(str, indent(4, fmt.Sprintf("]);"))) + } else { + str = append(str, indent(4, fmt.Sprintf("return Object.hash("))) + str = append(str, indent(6, "runtimeType,")) + for _, param := range classDecl.Constructor.ParamList.NamedParams { + str = append(str, indent(6, fmt.Sprintf("%s,", param.Name))) + } + str = append(str, indent(4, fmt.Sprintf(");"))) } - str = append(str, indent(4, fmt.Sprintf(");"))) + } else { str = append(str, indent(4, fmt.Sprintf("return runtimeType.hashCode;"))) }