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) => { entry.arguments.forEach((arg) => {
if (arg.type === '#') { if (arg.type === '#') {
const code = `var ${arg.name}=r.uint();` const code = `var ${arg.name}=r.uint();`
ret = ret.replace('return{', code + 'return{') ret = ret.replace('return{', code + 'return{')
flagsFields[arg.name] = 1 flagsFields[arg.name] = 1
return return
} }
@ -34,10 +34,14 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
const bitIndex = parseInt(s[1]) const bitIndex = parseInt(s[1])
if (!(fieldName in flagsFields)) { 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) { 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}` const condition = `${fieldName}&${1 << bitIndex}`
@ -82,7 +86,11 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
return ret + '}},' 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` let ret = `var ${varName}={\n`
entries.forEach((entry) => { 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 // even if the entry contains id, let's re-calculate it just to be sure
result.id = computeConstructorIdFromEntry(result) result.id = computeConstructorIdFromEntry(result)
const argsIndex: Record<string, TlArgument> = {} const argsIndex: Record<string, true> = {}
let lastTrueFlagIdx = -1 const flagsLastIndex: Record<string, number> = {}
result.arguments.forEach((arg, idx) => { 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++) { for (let i = 1; i < entries.length; i++) {
@ -60,9 +65,24 @@ export function mergeTlEntries(entries: TlEntry[]): TlEntry | string {
// yay a new arg // yay a new arg
// we can only add optional true args, since any others will change id // we can only add optional true args, since any others will change id
// ids match, so this must be the case // 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) const flagsField = entryArgument.predicate!.split('.')[0]
argsIndex[entryArgument.name] = entryArgument 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 // 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') 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', () => { it('merges true flags', () => {
test( test(
'test = Test;\n' + 'test flags:# = Test;\n' +
'test foo:flags.0?true = Test;\n' + 'test flags:# foo:flags.0?true = Test;\n' +
'test bar:flags.0?true = Test;\n' + 'test flags:# bar:flags.0?true = Test;\n' +
'test baz:flags.1?true = Test;', 'test flags:# baz:flags.1?true = Test;',
'test#1c173316 foo:flags.0?true 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;'
) )
test( test(
'test foo:flags.0?true = Test;\n' + 'test flags:# foo:flags.0?true = Test;\n' +
'test bar:flags.0?true = Test;\n' + 'test flags:# bar:flags.0?true = Test;\n' +
'test baz:flags.1?true = Test;', 'test flags:# baz:flags.1?true = Test;',
'test#1c173316 foo:flags.0?true 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;'
) )
test( test(
'test foo:flags.0?true = Test;\n' + 'test flags:# foo:flags.0?true = Test;\n' +
'test foo:flags.0?true bar:flags.0?true = Test;\n' + 'test flags:# foo:flags.0?true bar:flags.0?true = Test;\n' +
'test baz:flags.1?true = Test;\n' + 'test flags:# baz:flags.1?true = Test;\n' +
'test bar:flags.0?true baz:flags.1?true = Test;', 'test flags:# 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#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. > 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 ## About

File diff suppressed because one or more lines are too long