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}'}},`
}
ret += `var o={_:'${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
}
ret += `return{_:'${entry.name}',`
const flagsFields: Record<string, 1> = {}
entry.arguments.forEach((arg, idx) => {
entry.arguments.forEach((arg) => {
if (arg.type === '#') {
const code = `var ${arg.name}=r.uint();`
if (idx === 0) {
ret = ret.replace('var o=', code + 'var o=')
} else {
finalizeObject(idx)
ret += code
}
ret = ret.replace('return{', code + 'return{')
flagsFields[arg.name] = 1
return
}
@ -64,25 +43,13 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
const condition = `${fieldName}&${1 << bitIndex}`
if (arg.type === 'true') {
if (inObject) {
ret += `${argName}:!!(${condition}),`
} else {
ret += `o.${argName}=!!(${condition});`
}
ret += `${argName}:!!(${condition}),`
return
}
if (inObject) {
ret += `${argName}:${condition}?`
} else {
ret += `if(${condition})o.${argName}=`
}
ret += `${argName}:${condition}?`
} else {
if (inObject) {
ret += `${argName}:`
} else {
ret += `o.${argName}=`
}
ret += `${argName}:`
}
let vector = false
@ -105,19 +72,14 @@ export function generateReaderCodeForTlEntry(entry: TlEntry): string {
ret += `r.${type}()`
}
if (arg.predicate && inObject) {
if (arg.predicate) {
ret += ':void 0'
}
ret += inObject ? ',' : ';'
ret += ','
})
if (inObject) {
// simple object, direct return
return ret.replace('var o=', 'return') + '}},'
}
return ret + 'return o},'
return ret + '}},'
}
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', () => {
test(
'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', () => {
test(
'contacts.resolvedPeer#7f077ad9 peer:Peer chats:Vector<Chat> users:Vector<User> = contacts.ResolvedPeer;',