mtcute/packages/tl-utils/src/calculator.ts
Alina Tumanova f5976a2d74
ESM + end-to-end tests (#11)
* feat: moved tl-runtime to esm and native ArrayBuffers

* feat: migration to esm

* fix(core): web-related fixes

* test: finally, some good fucking e2e

* chore: fixed linters etc

* ci: added e2e to ci

* build(tl): fixed gen-code on node 20

* fix: codegen Uint8Array, not Buffer

never `git reset --hard` kids

* build: only do type-aware linting for `packages/*`

* build: ignore no-unresolved in ci for e2e

* fix: node 16 doesn't have subtle crypto apparently?

* fix(tests): use Uint8Array

for gods sake please can i just merge this already

* ci: don't parallel tasks in ci

because machines are utter garbage and it may just randomly break

* ci: pass secrets to e2e tests

* ci: separate cli command for ci

apparently im retarded

* fix: run codegen in e2e

im actually retarded

* ci: more fixes for e2e

* ci: debugging stuff

* ci: still debugging

* ci: hopefully fix ci???
2023-10-16 19:23:53 +03:00

99 lines
2.6 KiB
TypeScript

import { TlEntry } from './types.js'
const PRIMITIVES_SIZES: Record<string, number> = {
int: 4,
long: 8,
int53: 8,
int128: 16,
int256: 32,
double: 8,
boolFalse: 4,
boolTrue: 4,
bool: 4,
Bool: 4,
'#': 4,
}
export function calculateStaticSizes(entries: TlEntry[]): Record<string, number> {
const staticSizes: Record<string, number> = {}
const unionSizes: Record<string, Record<string, number | null>> = {}
let changedInLastIteration = true
function getUnionStaticSize(name: string): number | null {
const values = Object.values(unionSizes[name] ?? {})
if (values.length === 0) return null
const first = values[0]
if (first === null) return null
for (const value of values) {
if (value !== first) return null
}
return first
}
function calculateStaticSize(entry: TlEntry): number | null {
if (entry.generics) return null // definitely not static sized
let size = 4 // constructor id
for (const arg of entry.arguments) {
if (arg.typeModifiers?.predicate) {
if (arg.type === 'true') {
continue // zero-size type
}
// cant be static sized
return null
}
if (arg.typeModifiers?.isVector || arg.typeModifiers?.isBareVector) {
// cant be static sized
return null
}
let unionSize
if (arg.type in PRIMITIVES_SIZES) {
size += PRIMITIVES_SIZES[arg.type]
} else if (arg.type in staticSizes) {
size += staticSizes[arg.type] - 4 // subtract constructor id
} else if ((unionSize = getUnionStaticSize(arg.type))) {
size += unionSize
} else {
// likely not static sized
return null
}
}
return size
}
while (changedInLastIteration) {
changedInLastIteration = false
for (const entry of entries) {
if (staticSizes[entry.name] !== undefined) continue
const size = calculateStaticSize(entry)
if (entry.kind === 'class') {
if (!unionSizes[entry.type]) {
unionSizes[entry.type] = {}
}
unionSizes[entry.type][entry.name] = size
}
if (size === null) {
continue
}
staticSizes[entry.name] = size
changedInLastIteration = true
}
}
return staticSizes
}