blob: 117bfa09a3af197991d2a9478e39a26ca69f5571 [file] [log] [blame]
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
/// A hasher is used to give a unique hash to a given anonymous declaration
class AnonymousHasher {
static String hashUnion(List<String> parts) {
final cloneParts = parts;
cloneParts.sort((a, b) => a.compareTo(b));
return _hashValues(cloneParts).toString().substring(0, 7);
}
static String hashTuple(List<String> parts) {
return _hashValues(parts).toString().substring(0, 7);
}
static String hashObject(List<(String, String)> parts) {
final cloneParts = parts;
cloneParts.sort((a, b) => a.$1.compareTo(b.$1));
final hashes = cloneParts.map((v) {
return _hashValues([v.$1, v.$2]).toString();
});
return _hashValues(hashes).toString().substring(0, 7);
}
static String hashFun(List<(String, String)> params, String returnType,
[bool constructor = false]) {
final hashes = params.map((v) {
return _hashValues([v.$1, v.$2]).toString();
});
final paramHash = _hashValues(hashes);
return _hashValues(
[constructor.toString(), paramHash.toString(), returnType])
.toString()
.substring(0, 7);
}
}
// TODO: A better way for hashing values
int _hashValues(Iterable<String> values) {
final output = AccumulatorSink<Digest>();
final input = sha512.startChunkedConversion(output);
for (final v in values) {
final encoded = jsonEncode(v);
input.add(utf8.encode(encoded));
}
input.close();
final digest = output.events.single.bytes;
return BigInt.parse(
digest
.sublist(0, 8)
.map((b) => b.toRadixString(16).padLeft(2, '0'))
.join(),
radix: 16)
.toInt();
}