build(codegen): refactored reader codegen (removed the need in additional object), added tests for multiple flags fields

i honestly don't know why i did what i did, it's such an over-complication, lol.
This commit is contained in:
teidesu 2022-04-29 16:13:07 +03:00
parent a1ea1315df
commit 916c41e70c
3 changed files with 41 additions and 47 deletions

View file

@ -14,35 +14,14 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
return ret + `return{_:'${entry.name}'}},` return ret + `return{_:'${entry.name}'}},`
} }
ret += `var o={_:'${entry.name}',` ret += `return{_:'${entry.name}',`
let inObject = true
function finalizeObject(pos: number) {
if (!inObject) return
for (let i = pos; i < entry.arguments.length; i++) {
const arg = entry.arguments[i]
if (arg.type !== '#') {
ret += arg.name + ':void 0,'
}
}
ret += '};'
inObject = false
}
const flagsFields: Record<string, 1> = {} const flagsFields: Record<string, 1> = {}
entry.arguments.forEach((arg, idx) => { entry.arguments.forEach((arg) => {
if (arg.type === '#') { if (arg.type === '#') {
const code = `var ${arg.name}=r.uint();` const code = `var ${arg.name}=r.uint();`
if (idx === 0) { ret = ret.replace('return{', code + 'return{')
ret = ret.replace('var o=', code + 'var o=')
} else {
finalizeObject(idx)
ret += code
}
flagsFields[arg.name] = 1 flagsFields[arg.name] = 1
return return
} }
@ -64,25 +43,13 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
const condition = `${fieldName}&${1 << bitIndex}` const condition = `${fieldName}&${1 << bitIndex}`
if (arg.type === 'true') { if (arg.type === 'true') {
if (inObject) {
ret += `${argName}:!!(${condition}),` ret += `${argName}:!!(${condition}),`
} else {
ret += `o.${argName}=!!(${condition});`
}
return return
} }
if (inObject) {
ret += `${argName}:${condition}?` ret += `${argName}:${condition}?`
} else { } else {
ret += `if(${condition})o.${argName}=`
}
} else {
if (inObject) {
ret += `${argName}:` ret += `${argName}:`
} else {
ret += `o.${argName}=`
}
} }
let vector = false let vector = false
@ -105,19 +72,14 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
ret += `r.${type}()` ret += `r.${type}()`
} }
if (arg.predicate && inObject) { if (arg.predicate) {
ret += ':void 0' ret += ':void 0'
} }
ret += inObject ? ',' : ';' ret += ','
}) })
if (inObject) { return ret + '}},'
// simple object, direct return
return ret.replace('var o=', 'return') + '}},'
}
return ret + 'return o},'
} }
export function generateReaderCodeForTlEntries(entries: TlEntry[], varName: string, methods = true): string { export function generateReaderCodeForTlEntries(entries: TlEntry[], varName: string, methods = true): string {

View file

@ -72,6 +72,21 @@ describe('generateReaderCodeForTlEntry', () => {
) )
}) })
it('generates code for constructors with multiple flags fields', () => {
test(
'updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int flags2:# can_delete_channel:flags2.0?true = updates.ChannelDifference;',
'var flags=r.uint();',
'var flags2=r.uint();',
'return{',
"_:'updates.channelDifferenceEmpty',",
'final:!!(flags&1),',
'pts:r.int(),',
'timeout:flags&2?r.int():void 0,',
'canDeleteChannel:!!(flags2&1),',
'}'
)
})
it('generates code for constructors with vector arguments', () => { it('generates code for constructors with vector arguments', () => {
test( test(
'contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;', 'contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;',

View file

@ -70,6 +70,23 @@ describe('generateWriterCodeForTlEntry', () => {
) )
}) })
it('generates code for constructors with multiple flags fields', () => {
test(
'updates.channelDifferenceEmpty#3e11affb flags:# final:flags.0?true pts:int timeout:flags.1?int flags2:# can_delete_channel:flags2.0?true = updates.ChannelDifference;',
'var flags=0;',
'if(v.final===true)flags|=1;',
'var _timeout=v.timeout!==undefined;',
'if(_timeout)flags|=2;',
'w.uint(flags);',
"h(v,'pts');",
'w.int(v.pts);',
'if(_timeout)w.int(v.timeout);',
'var flags2=0;',
'if(v.canDeleteChannel===true)flags2|=1;',
'w.uint(flags2);',
)
})
it('generates code for constructors with vector arguments', () => { it('generates code for constructors with vector arguments', () => {
test( test(
'contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;', 'contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;',