fix(tl): insert true flags after flags field, support multiple flags fields, updated tests
This commit is contained in:
parent
916c41e70c
commit
44e6ffd368
5 changed files with 63 additions and 30 deletions
|
@ -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) => {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
Loading…
Reference in a new issue