Skip to content

Commit 5e1c214

Browse files
committed
binary objects working similarly as tun-types branch
1 parent de0340c commit 5e1c214

File tree

3 files changed

+30
-237
lines changed

3 files changed

+30
-237
lines changed

packages/run-types/src/jitCompilers/binary/binarySpec/06JsonFunctions.spec.ts

Lines changed: 0 additions & 213 deletions
This file was deleted.

packages/run-types/src/jitCompilers/binary/fromBinary.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,17 +211,16 @@ export function _compileFromBinary(runType: BaseRunType, comp: BinaryCompiler):
211211
// required props that are simple expressions are restored as: '{a: deserializeA, b: deserializeB, c: deserializeC};
212212
// and are serialized/deserialised in the same order they are declared in the type
213213
const requiredItemsJit = required.map((prop) => prop.compile(comp, fnID, 'S'));
214-
const expressionsPropsCode = requiredItemsJit
214+
const expressionItemsJit = requiredItemsJit
215215
.filter((childJit, i) => childIsExpression(childJit, required[i]))
216216
.map((prop) => prop.code)
217+
.filter(Boolean);
218+
const statementItemsCode = requiredItemsJit
217219
.filter(Boolean)
218-
.join(',');
219-
const requiredPropsCode = requiredItemsJit
220220
.filter((childJit, i) => !childIsExpression(childJit, required[i]))
221-
.map((prop) => prop.code)
222-
.filter(Boolean)
223-
.join(';');
224-
const objectCode = `${comp.vλl} = {${expressionsPropsCode}};${requiredPropsCode}`;
221+
.map((prop) => prop.code);
222+
const expressionsPropsCode = expressionItemsJit.join(',');
223+
const requiredPropsCode = statementItemsCode.join(';');
225224

226225
// optional props are initialized as obj.a = deserializeA; obj.b = deserializeB; obj.c = deserializeC;
227226
// bitmap is used to determine which optional props are present
@@ -242,10 +241,13 @@ export function _compileFromBinary(runType: BaseRunType, comp: BinaryCompiler):
242241
})
243242
.filter(Boolean)
244243
.join('');
245-
optionalPropsCode = `${bitMapInit}\n${propsCode}`;
244+
const sep = requiredPropsCode ? ';' : '';
245+
optionalPropsCode = `${sep}\n${bitMapInit}\n${propsCode}`;
246246
}
247247

248-
return {code: `${objectCode}\n${optionalPropsCode}`, type: 'S'};
248+
const canBeExpression = !requiredPropsCode && !optionalPropsCode;
249+
if (canBeExpression) return {code: `{${expressionsPropsCode}}`, type: 'E'};
250+
return {code: `${comp.vλl} = {${expressionsPropsCode}}\n${requiredPropsCode}${optionalPropsCode}`, type: 'S'};
249251
}
250252

251253
case ReflectionKind.class:
@@ -275,7 +277,8 @@ export function _compileFromBinary(runType: BaseRunType, comp: BinaryCompiler):
275277
const desFnInit = `let ${desFnVarName} = utl.${jitUtils.getDeserializeFn.name}(${toLiteral(rt.getClassName())})`;
276278
const desFnCode = `if (${desFnVarName}) {${comp.vλl} = ${desFnVarName}(${comp.vλl})}`;
277279
const desClassCode = `else if (${desFnVarName} = utl.${jitUtils.getSerializeClass.name}(${toLiteral(rt.getClassName())})) {${comp.vλl} = new ${desFnVarName}(${comp.vλl})}`;
278-
return {code: `${plainObjCode?.code};${desFnInit};${desFnCode} ${desClassCode}`, type: 'S'};
280+
const initCode = plainObjCode.type === 'E' ? `${comp.vλl} = ${plainObjCode.code}` : plainObjCode.code;
281+
return {code: `${initCode};${desFnInit};${desFnCode} ${desClassCode}`, type: 'S'};
279282
}
280283
}
281284
break;

packages/run-types/src/lib/baseRunTypes.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,10 @@ export abstract class BaseRunType<T extends Type = Type> implements RunType {
285285
throw new Error(`Unknown compile operation: ${fnID}`);
286286
}
287287
if (jCode?.code) {
288-
const handledCode = this.handleReturnValues(comp, jCode, expectedCType);
289-
jCode = {code: handledCode.code, type: jCode.type};
288+
// endure the child code type is compatible with the parent code type.
289+
// ie: a code statement can not be interpolated within an expression
290+
const compatibleCode = this.handleCodeInterpolation(comp, jCode, expectedCType);
291+
jCode = {code: compatibleCode, type: jCode.type};
290292
}
291293
}
292294
comp.popStack(jCode);
@@ -368,37 +370,38 @@ export abstract class BaseRunType<T extends Type = Type> implements RunType {
368370
}
369371

370372
/** Ensures the child code type is compatible with the parent code type */
371-
handleReturnValues(comp: JitCompiler, childJCode: JitCode, parentCodeType: CodeType): JitCode {
373+
handleCodeInterpolation(comp: JitCompiler, childJCode: JitCode, parentCodeType: CodeType): string {
372374
const code = (childJCode.code || '').trim();
373375
const childCodeType = childJCode.type;
374376
const isRoot = comp.length === 1;
375377
// root code must ensure values are returned
376378
if (isRoot) {
377379
// prettier-ignore
378380
switch (childCodeType) {
379-
case E: return {code: `return ${code}`, type: RB};
380-
case S: return {code: `${addFullStop(code)} return ${comp.returnName}`, type: RB};
381-
case RB: return {code, type: RB};
381+
case E: return `return ${code}`;
382+
case S: return `${addFullStop(code)} return ${comp.returnName}`;
383+
case RB: return code;
382384
}
383385
}
384386
switch (true) {
385387
case parentCodeType === E && childCodeType === E:
386-
return childJCode;
388+
return code;
387389
case parentCodeType === E && childCodeType === S:
388390
return this.callSelfInvokingFunction(childJCode);
389391
case parentCodeType === E && childCodeType === RB:
390392
return this.callSelfInvokingFunction(childJCode);
391393
case parentCodeType === S && childCodeType === E:
394+
return code; // no need for full stop, parent should handle it
392395
case parentCodeType === S && childCodeType === S:
393-
return {code: addFullStop(code), type: childCodeType};
396+
return addFullStop(code);
394397
case parentCodeType === S && childCodeType === RB:
395398
return this.callSelfInvokingFunction(childJCode);
396399
case parentCodeType === RB && childCodeType === E:
397400
throw new Error('Expected an block code but got an expression, this should not happen as would be useless code.');
398401
case parentCodeType === RB && childCodeType === S:
399-
return {code: addFullStop(code), type: S};
402+
return addFullStop(code);
400403
case parentCodeType === RB && childCodeType === RB:
401-
return {code: `${addFullStop(code)} return ${comp.returnName}`, type: RB};
404+
return `${addFullStop(code)} return ${comp.returnName}`;
402405
default:
403406
throw new Error(`Unexpected code type (expected: ${parentCodeType}, got: ${childCodeType})`);
404407
}
@@ -411,15 +414,15 @@ export abstract class BaseRunType<T extends Type = Type> implements RunType {
411414
* IE: comp.selfInvoke(code), this will create a new function in context and call that function instead of self invoking
412415
* this is specially for atomic types as we can be sure there are no references to children types inside the code block
413416
*/
414-
callSelfInvokingFunction(jCode: JitCode): JitCode {
417+
callSelfInvokingFunction(jCode: JitCode): string {
415418
if (jCode.type === E) throw new Error('Javascript expressions never need to be wrapped in a self invoking function.');
416-
if (!jCode.code) return {code: '', type: jCode.type};
419+
if (!jCode.code) return '';
417420
const code = jCode.code.trim();
418421
const isSelfInvoking = code.startsWith('(function()') && code.endsWith(')()');
419-
if (isSelfInvoking) return jCode;
422+
if (isSelfInvoking) return code;
420423
const addReturn = jCode.type !== RB;
421424
const returnCode = addReturn ? `return ` : '';
422-
return {code: `(function(){${returnCode}${jCode.code}})()`, type: E};
425+
return `(function(){${returnCode}${jCode.code}})()`;
423426
}
424427

425428
getTypeTraceInfo(comp: JitCompiler): string {

0 commit comments

Comments
 (0)