fix(tl): insert true flags after flags field, support multiple flags fields, updated tests

This commit is contained in:
teidesu 2022-04-29 16:36:41 +03:00
parent 916c41e70c
commit 44e6ffd368
5 changed files with 63 additions and 30 deletions

View file

@ -21,7 +21,7 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
entry.arguments.forEach((arg) => {
if (arg.type === '#') {
const code = `var ${arg.name}=r.uint();`
ret = ret.replace('return{', code + 'return{')
ret = ret.replace('return{', code + 'return{')
flagsFields[arg.name] = 1
return
}
@ -34,10 +34,14 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
const bitIndex = parseInt(s[1])
if (!(fieldName in flagsFields)) {
throw new Error(`Invalid predicate: ${arg.predicate} - unknown field`)
throw new Error(
`Invalid predicate: ${arg.predicate} - unknown field (in ${entry.name})`
)
}
if (isNaN(bitIndex) || bitIndex < 0 || bitIndex > 32) {
throw new Error(`Invalid predicate: ${arg.predicate} - invalid bit`)
throw new Error(
`Invalid predicate: ${arg.predicate} - invalid bit`
)
}
const condition = `${fieldName}&${1 << bitIndex}`
@ -82,7 +86,11 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
return ret + '}},'
}
export function generateReaderCodeForTlEntries(entries: TlEntry[], varName: string, methods = true): string {
export function generateReaderCodeForTlEntries(
entries: TlEntry[],
varName: string,
methods = true
): string {
let ret = `var ${varName}={\n`
entries.forEach((entry) => {

View file

@ -17,13 +17,18 @@ export function mergeTlEntries(entries: TlEntry[]): TlEntry | string {
// even if the entry contains id, let's re-calculate it just to be sure
result.id = computeConstructorIdFromEntry(result)
const argsIndex: Record<string, TlArgument> = {}
let lastTrueFlagIdx = -1
const argsIndex: Record<string, true> = {}
const flagsLastIndex: Record<string, number> = {}
result.arguments.forEach((arg, idx) => {
argsIndex[arg.name] = arg
argsIndex[arg.name] = true
if (arg.predicate && arg.type === 'true') lastTrueFlagIdx = idx
if (arg.type === '#') {
flagsLastIndex[arg.name] = idx
} if (arg.predicate) {
const flagsField = arg.predicate.split('.')[0]
flagsLastIndex[flagsField] = idx
}
})
for (let i = 1; i < entries.length; i++) {
@ -60,9 +65,24 @@ export function mergeTlEntries(entries: TlEntry[]): TlEntry | string {
// yay a new arg
// we can only add optional true args, since any others will change id
// ids match, so this must be the case
//
// we also need to make sure we put it *after* the respective flags field
result.arguments.splice(lastTrueFlagIdx += 1, 0, entryArgument)
argsIndex[entryArgument.name] = entryArgument
const flagsField = entryArgument.predicate!.split('.')[0]
const targetIdx = flagsLastIndex[flagsField]
// targetIdx *must* exist, otherwise ids wouldn't match
result.arguments.splice(targetIdx + 1, 0, entryArgument)
argsIndex[entryArgument.name] = true
// update last indexes
// we also need to update subsequent flags if there are any
Object.keys(flagsLastIndex).forEach((flag) => {
if (flagsLastIndex[flag] >= targetIdx) {
flagsLastIndex[flag]++
}
})
}
// args exists both in result and current entry

View file

@ -34,30 +34,35 @@ describe('mergeTlEntries', () => {
test('test = Test;\ntest foo:int = Test;', 'basic info mismatch')
})
it('fails on conflicting ids', () => {
test('test = Test;\ntest foo:int = Test;', 'basic info mismatch')
})
it('merges true flags', () => {
test(
'test = Test;\n' +
'test foo:flags.0?true = Test;\n' +
'test bar:flags.0?true = Test;\n' +
'test baz:flags.1?true = Test;',
'test#1c173316 foo:flags.0?true bar:flags.0?true baz:flags.1?true = Test;'
'test flags:# = Test;\n' +
'test flags:# foo:flags.0?true = Test;\n' +
'test flags:# bar:flags.0?true = Test;\n' +
'test flags:# baz:flags.1?true = Test;',
'test#e86481ba flags:# foo:flags.0?true bar:flags.0?true baz:flags.1?true = Test;'
)
test(
'test foo:flags.0?true = Test;\n' +
'test bar:flags.0?true = Test;\n' +
'test baz:flags.1?true = Test;',
'test#1c173316 foo:flags.0?true bar:flags.0?true baz:flags.1?true = Test;'
'test flags:# foo:flags.0?true = Test;\n' +
'test flags:# bar:flags.0?true = Test;\n' +
'test flags:# baz:flags.1?true = Test;',
'test#e86481ba flags:# foo:flags.0?true bar:flags.0?true baz:flags.1?true = Test;'
)
test(
'test foo:flags.0?true = Test;\n' +
'test foo:flags.0?true bar:flags.0?true = Test;\n' +
'test baz:flags.1?true = Test;\n' +
'test bar:flags.0?true baz:flags.1?true = Test;',
'test#1c173316 foo:flags.0?true bar:flags.0?true baz:flags.1?true = Test;'
'test flags:# foo:flags.0?true = Test;\n' +
'test flags:# foo:flags.0?true bar:flags.0?true = Test;\n' +
'test flags:# baz:flags.1?true = Test;\n' +
'test flags:# bar:flags.0?true baz:flags.1?true = Test;',
'test#e86481ba flags:# foo:flags.0?true bar:flags.0?true baz:flags.1?true = Test;'
)
})
it('merges true flags with multiple flags fields', () => {
test(
'test flags:# flags2:# = Test;\n' +
'test flags:# foo:flags.0?true flags2:# = Test;\n' +
'test flags:# flags2:# bar:flags2.0?true = Test;\n',
'test#5ca39a98 flags:# foo:flags.0?true flags2:# bar:flags2.0?true = Test;'
)
})
})

View file

@ -2,7 +2,7 @@
> TL schema and related utils used for MTCute.
Generated from TL layer **140** (last updated on 28.04.2022).
Generated from TL layer **140** (last updated on 29.04.2022).
## About

File diff suppressed because one or more lines are too long