Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e0f1002

Browse files
Reverts "web_ui: drop internal hash code library (#53783)" (#53793)
Reverts: #53783 Initiated by: jiahaog Reason for reverting: There are still internal users of these hash functions (b/352191023). Flutter also exports it [here](https://github.com/flutter/flutter/blob/72f83d3237a051a8b1b849abd267d4a4e80ff774/packages/flutter/lib/src/painting/basic_types.dart#L58) so its easy for developers to use them even without importing `dart:ui`. Though it's an easy fix, I'd imagine this to be a breaking change for the OSS ecosystem a Original PR Author: kevmoo Reviewed By: {yjbanov} This change reverts the following previous change: We moved to dart:core Object functions a while ago
1 parent b584e1c commit e0f1002

File tree

4 files changed

+253
-0
lines changed

4 files changed

+253
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42780,6 +42780,7 @@ ORIGIN: ../../../flutter/lib/web_ui/lib/canvas.dart + ../../../flutter/LICENSE
4278042780
ORIGIN: ../../../flutter/lib/web_ui/lib/channel_buffers.dart + ../../../flutter/LICENSE
4278142781
ORIGIN: ../../../flutter/lib/web_ui/lib/compositing.dart + ../../../flutter/LICENSE
4278242782
ORIGIN: ../../../flutter/lib/web_ui/lib/geometry.dart + ../../../flutter/LICENSE
42783+
ORIGIN: ../../../flutter/lib/web_ui/lib/hash_codes.dart + ../../../flutter/LICENSE
4278342784
ORIGIN: ../../../flutter/lib/web_ui/lib/initialization.dart + ../../../flutter/LICENSE
4278442785
ORIGIN: ../../../flutter/lib/web_ui/lib/key.dart + ../../../flutter/LICENSE
4278542786
ORIGIN: ../../../flutter/lib/web_ui/lib/lerp.dart + ../../../flutter/LICENSE
@@ -45653,6 +45654,7 @@ FILE: ../../../flutter/lib/web_ui/lib/canvas.dart
4565345654
FILE: ../../../flutter/lib/web_ui/lib/channel_buffers.dart
4565445655
FILE: ../../../flutter/lib/web_ui/lib/compositing.dart
4565545656
FILE: ../../../flutter/lib/web_ui/lib/geometry.dart
45657+
FILE: ../../../flutter/lib/web_ui/lib/hash_codes.dart
4565645658
FILE: ../../../flutter/lib/web_ui/lib/initialization.dart
4565745659
FILE: ../../../flutter/lib/web_ui/lib/key.dart
4565845660
FILE: ../../../flutter/lib/web_ui/lib/lerp.dart

lib/web_ui/lib/hash_codes.dart

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
part of ui;
6+
7+
class _HashEnd { const _HashEnd(); }
8+
const _HashEnd _hashEnd = _HashEnd();
9+
10+
// ignore: avoid_classes_with_only_static_members
11+
/// Jenkins hash function, optimized for small integers.
12+
//
13+
// Borrowed from the dart sdk: sdk/lib/math/jenkins_smi_hash.dart.
14+
class _Jenkins {
15+
static int combine(int hash, Object? o) {
16+
assert(o is! Iterable);
17+
hash = 0x1fffffff & (hash + o.hashCode);
18+
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
19+
return hash ^ (hash >> 6);
20+
}
21+
22+
static int finish(int hash) {
23+
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
24+
hash = hash ^ (hash >> 11);
25+
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
26+
}
27+
}
28+
29+
/// Combine up to twenty objects' hash codes into one value.
30+
///
31+
/// If you only need to handle one object's hash code, then just refer to its
32+
/// [Object.hashCode] getter directly.
33+
///
34+
/// If you need to combine an arbitrary number of objects from a [List] or other
35+
/// [Iterable], use [hashList]. The output of [hashList] can be used as one of
36+
/// the arguments to this function.
37+
///
38+
/// For example:
39+
///
40+
/// ```dart
41+
/// int hashCode => hashValues(foo, bar, hashList(quux), baz);
42+
/// ```
43+
@Deprecated(
44+
'Use Object.hash() instead. '
45+
'This feature was deprecated in v3.1.0-0.0.pre.897'
46+
)
47+
int hashValues(
48+
Object? arg01, Object? arg02, [ Object? arg03 = _hashEnd,
49+
Object? arg04 = _hashEnd, Object? arg05 = _hashEnd, Object? arg06 = _hashEnd,
50+
Object? arg07 = _hashEnd, Object? arg08 = _hashEnd, Object? arg09 = _hashEnd,
51+
Object? arg10 = _hashEnd, Object? arg11 = _hashEnd, Object? arg12 = _hashEnd,
52+
Object? arg13 = _hashEnd, Object? arg14 = _hashEnd, Object? arg15 = _hashEnd,
53+
Object? arg16 = _hashEnd, Object? arg17 = _hashEnd, Object? arg18 = _hashEnd,
54+
Object? arg19 = _hashEnd, Object? arg20 = _hashEnd ]) {
55+
int result = 0;
56+
result = _Jenkins.combine(result, arg01);
57+
result = _Jenkins.combine(result, arg02);
58+
if (!identical(arg03, _hashEnd)) {
59+
result = _Jenkins.combine(result, arg03);
60+
if (!identical(arg04, _hashEnd)) {
61+
result = _Jenkins.combine(result, arg04);
62+
if (!identical(arg05, _hashEnd)) {
63+
result = _Jenkins.combine(result, arg05);
64+
if (!identical(arg06, _hashEnd)) {
65+
result = _Jenkins.combine(result, arg06);
66+
if (!identical(arg07, _hashEnd)) {
67+
result = _Jenkins.combine(result, arg07);
68+
if (!identical(arg08, _hashEnd)) {
69+
result = _Jenkins.combine(result, arg08);
70+
if (!identical(arg09, _hashEnd)) {
71+
result = _Jenkins.combine(result, arg09);
72+
if (!identical(arg10, _hashEnd)) {
73+
result = _Jenkins.combine(result, arg10);
74+
if (!identical(arg11, _hashEnd)) {
75+
result = _Jenkins.combine(result, arg11);
76+
if (!identical(arg12, _hashEnd)) {
77+
result = _Jenkins.combine(result, arg12);
78+
if (!identical(arg13, _hashEnd)) {
79+
result = _Jenkins.combine(result, arg13);
80+
if (!identical(arg14, _hashEnd)) {
81+
result = _Jenkins.combine(result, arg14);
82+
if (!identical(arg15, _hashEnd)) {
83+
result = _Jenkins.combine(result, arg15);
84+
if (!identical(arg16, _hashEnd)) {
85+
result = _Jenkins.combine(result, arg16);
86+
if (!identical(arg17, _hashEnd)) {
87+
result = _Jenkins.combine(result, arg17);
88+
if (!identical(arg18, _hashEnd)) {
89+
result = _Jenkins.combine(result, arg18);
90+
if (!identical(arg19, _hashEnd)) {
91+
result = _Jenkins.combine(result, arg19);
92+
if (!identical(arg20, _hashEnd)) {
93+
result = _Jenkins.combine(result, arg20);
94+
// I can see my house from here!
95+
}
96+
}
97+
}
98+
}
99+
}
100+
}
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}
107+
}
108+
}
109+
}
110+
}
111+
}
112+
}
113+
return _Jenkins.finish(result);
114+
}
115+
116+
/// Combine the [Object.hashCode] values of an arbitrary number of objects from
117+
/// an [Iterable] into one value. This function will return the same value if
118+
/// given null as if given an empty list.
119+
@Deprecated(
120+
'Use Object.hashAll() or Object.hashAllUnordered() instead. '
121+
'This feature was deprecated in v3.1.0-0.0.pre.897'
122+
)
123+
int hashList(Iterable<Object?>? arguments) {
124+
int result = 0;
125+
if (arguments != null) {
126+
for (final Object? argument in arguments) {
127+
result = _Jenkins.combine(result, argument);
128+
}
129+
}
130+
return _Jenkins.finish(result);
131+
}

lib/web_ui/lib/ui.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ part 'canvas.dart';
2121
part 'channel_buffers.dart';
2222
part 'compositing.dart';
2323
part 'geometry.dart';
24+
part 'hash_codes.dart';
2425
part 'initialization.dart';
2526
part 'key.dart';
2627
part 'lerp.dart';
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:test/bootstrap/browser.dart';
6+
import 'package:test/test.dart';
7+
import 'package:ui/ui.dart';
8+
9+
// The biggest integer value that can be represented in JavaScript is 1 << 53.
10+
// However, the 1 << 53 expression cannot be used in JavaScript because that
11+
// would apply the bitwise shift to a "number" (i.e. float64), which is
12+
// meaningless. Instead, a decimal literal is used here.
13+
const int _kBiggestExactJavaScriptInt = 9007199254740992;
14+
15+
void main() {
16+
internalBootstrapBrowserTest(() => testMain);
17+
}
18+
19+
void testMain() {
20+
test('hashValues and hashList can hash lots of huge values effectively', () {
21+
final int hashValueFromArgs = hashValues(
22+
_kBiggestExactJavaScriptInt,
23+
_kBiggestExactJavaScriptInt,
24+
_kBiggestExactJavaScriptInt,
25+
_kBiggestExactJavaScriptInt,
26+
_kBiggestExactJavaScriptInt,
27+
_kBiggestExactJavaScriptInt,
28+
_kBiggestExactJavaScriptInt,
29+
_kBiggestExactJavaScriptInt,
30+
_kBiggestExactJavaScriptInt,
31+
_kBiggestExactJavaScriptInt,
32+
_kBiggestExactJavaScriptInt,
33+
_kBiggestExactJavaScriptInt,
34+
_kBiggestExactJavaScriptInt,
35+
_kBiggestExactJavaScriptInt,
36+
_kBiggestExactJavaScriptInt,
37+
_kBiggestExactJavaScriptInt,
38+
_kBiggestExactJavaScriptInt,
39+
_kBiggestExactJavaScriptInt,
40+
_kBiggestExactJavaScriptInt,
41+
_kBiggestExactJavaScriptInt,
42+
);
43+
44+
// Hash the same values via a list
45+
final int hashValueFromList = hashList(<int>[
46+
_kBiggestExactJavaScriptInt,
47+
_kBiggestExactJavaScriptInt,
48+
_kBiggestExactJavaScriptInt,
49+
_kBiggestExactJavaScriptInt,
50+
_kBiggestExactJavaScriptInt,
51+
_kBiggestExactJavaScriptInt,
52+
_kBiggestExactJavaScriptInt,
53+
_kBiggestExactJavaScriptInt,
54+
_kBiggestExactJavaScriptInt,
55+
_kBiggestExactJavaScriptInt,
56+
_kBiggestExactJavaScriptInt,
57+
_kBiggestExactJavaScriptInt,
58+
_kBiggestExactJavaScriptInt,
59+
_kBiggestExactJavaScriptInt,
60+
_kBiggestExactJavaScriptInt,
61+
_kBiggestExactJavaScriptInt,
62+
_kBiggestExactJavaScriptInt,
63+
_kBiggestExactJavaScriptInt,
64+
_kBiggestExactJavaScriptInt,
65+
_kBiggestExactJavaScriptInt,
66+
]);
67+
68+
// Hash a slightly smaller number to verify that the hash code is different.
69+
final int slightlyDifferentHashValueFromArgs = hashValues(
70+
_kBiggestExactJavaScriptInt,
71+
_kBiggestExactJavaScriptInt,
72+
_kBiggestExactJavaScriptInt,
73+
_kBiggestExactJavaScriptInt,
74+
_kBiggestExactJavaScriptInt,
75+
_kBiggestExactJavaScriptInt,
76+
_kBiggestExactJavaScriptInt,
77+
_kBiggestExactJavaScriptInt,
78+
_kBiggestExactJavaScriptInt,
79+
_kBiggestExactJavaScriptInt,
80+
_kBiggestExactJavaScriptInt,
81+
_kBiggestExactJavaScriptInt,
82+
_kBiggestExactJavaScriptInt,
83+
_kBiggestExactJavaScriptInt,
84+
_kBiggestExactJavaScriptInt,
85+
_kBiggestExactJavaScriptInt,
86+
_kBiggestExactJavaScriptInt,
87+
_kBiggestExactJavaScriptInt,
88+
_kBiggestExactJavaScriptInt,
89+
_kBiggestExactJavaScriptInt - 1,
90+
);
91+
92+
final int slightlyDifferentHashValueFromList = hashList(<int>[
93+
_kBiggestExactJavaScriptInt,
94+
_kBiggestExactJavaScriptInt,
95+
_kBiggestExactJavaScriptInt,
96+
_kBiggestExactJavaScriptInt,
97+
_kBiggestExactJavaScriptInt,
98+
_kBiggestExactJavaScriptInt,
99+
_kBiggestExactJavaScriptInt,
100+
_kBiggestExactJavaScriptInt,
101+
_kBiggestExactJavaScriptInt,
102+
_kBiggestExactJavaScriptInt,
103+
_kBiggestExactJavaScriptInt,
104+
_kBiggestExactJavaScriptInt,
105+
_kBiggestExactJavaScriptInt,
106+
_kBiggestExactJavaScriptInt,
107+
_kBiggestExactJavaScriptInt,
108+
_kBiggestExactJavaScriptInt,
109+
_kBiggestExactJavaScriptInt,
110+
_kBiggestExactJavaScriptInt,
111+
_kBiggestExactJavaScriptInt,
112+
_kBiggestExactJavaScriptInt - 1,
113+
]);
114+
115+
expect(hashValueFromArgs, equals(hashValueFromList));
116+
expect(slightlyDifferentHashValueFromArgs, equals(slightlyDifferentHashValueFromList));
117+
expect(hashValueFromArgs, isNot(equals(slightlyDifferentHashValueFromArgs)));
118+
});
119+
}

0 commit comments

Comments
 (0)