Skip to content

Commit

Permalink
fix(type): handle more circular types
Browse files Browse the repository at this point in the history
Previously each serializer template was required to handle circular structures when needed. Now, the serializer framework itself handles it.

Also, BSON property name writer refactored so that auto-handling of circular references works correctly.

For JIT code generation env DEBUG=deepkit now pretty formats it for easier debugging.

ref #477
  • Loading branch information
marcj committed Feb 4, 2024
1 parent 03b2428 commit 5f6bd12
Show file tree
Hide file tree
Showing 13 changed files with 597 additions and 386 deletions.
27 changes: 7 additions & 20 deletions packages/bson/src/bson-deserializer-templates.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import { isPropertyMemberType } from '@deepkit/type';
import {
binaryBigIntAnnotation,
BinaryBigIntType,
buildFunction,
callExtractedFunctionIfAvailable,
collapsePath,
ContainerAccessor,
createTypeGuardFunction,
Expand All @@ -12,13 +9,13 @@ import {
excludedAnnotation,
executeTemplates,
extendTemplateLiteral,
extractStateToFunctionAndCallIt,
getIndexCheck,
getNameExpression,
getStaticDefaultCodeForProperty,
hasDefaultValue,
isNullable,
isOptional,
isPropertyMemberType,
mongoIdAnnotation,
ReflectionClass,
ReflectionKind,
Expand All @@ -27,6 +24,7 @@ import {
sortSignatures,
TemplateState,
Type,
TypeArray,
TypeClass,
TypeGuardRegistry,
TypeIndexSignature,
Expand All @@ -37,7 +35,7 @@ import {
TypeTemplateLiteral,
TypeTuple,
TypeUnion,
uuidAnnotation
uuidAnnotation,
} from '@deepkit/type';
import { seekElementSize } from './continuation.js';
import { BSONType, digitByteSize, isSerializable } from './utils.js';
Expand Down Expand Up @@ -531,7 +529,8 @@ export function bsonTypeGuardTuple(type: TypeTuple, state: TemplateState) {
`);
}

export function deserializeArray(elementType: Type, state: TemplateState) {
export function deserializeArray(type: TypeArray, state: TemplateState) {
const elementType = type.type;
const result = state.compilerContext.reserveName('result');
const v = state.compilerContext.reserveName('v');
const i = state.compilerContext.reserveName('i');
Expand Down Expand Up @@ -567,7 +566,8 @@ export function deserializeArray(elementType: Type, state: TemplateState) {
* This array type guard goes through all array elements in order to determine the correct type.
* This is only necessary when a union has at least 2 array members, otherwise a simple array check is enough.
*/
export function bsonTypeGuardArray(elementType: Type, state: TemplateState) {
export function bsonTypeGuardArray(type: TypeArray, state: TemplateState) {
const elementType = type.type;
const v = state.compilerContext.reserveName('v');
const i = state.compilerContext.reserveName('i');
state.setContext({ digitByteSize, seekElementSize });
Expand Down Expand Up @@ -643,11 +643,6 @@ export function deserializeObjectLiteral(type: TypeClass | TypeObjectLiteral, st
// return;
// }
// }

if (callExtractedFunctionIfAvailable(state, type)) return;
const extract = extractStateToFunctionAndCallIt(state, type);
state = extract.state;

const lines: string[] = [];
const signatures: TypeIndexSignature[] = [];
const object = state.compilerContext.reserveName('object');
Expand Down Expand Up @@ -843,8 +838,6 @@ export function deserializeObjectLiteral(type: TypeClass | TypeObjectLiteral, st
state.elementType = oldElementType;
}
`);

extract.setFunction(buildFunction(state, type));
}

export function bsonTypeGuardObjectLiteral(type: TypeClass | TypeObjectLiteral, state: TemplateState) {
Expand All @@ -862,10 +855,6 @@ export function bsonTypeGuardObjectLiteral(type: TypeClass | TypeObjectLiteral,
// return;
// }

if (callExtractedFunctionIfAvailable(state, type)) return;
const extract = extractStateToFunctionAndCallIt(state, type);
state = extract.state;

const lines: string[] = [];
const signatures: TypeIndexSignature[] = [];
const valid = state.compilerContext.reserveName('valid');
Expand Down Expand Up @@ -987,8 +976,6 @@ export function bsonTypeGuardObjectLiteral(type: TypeClass | TypeObjectLiteral,
${state.setter} = ${valid};
}
`);

extract.setFunction(buildFunction(state, type));
}

export function bsonTypeGuardForBsonTypes(types: BSONType[]): (type: Type, state: TemplateState) => void {
Expand Down
3 changes: 2 additions & 1 deletion packages/bson/src/bson-deserializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ export function getBSONDeserializer<T>(serializer: BSONBinarySerializer = bsonBi
}

export function deserializeBSON<T>(data: Uint8Array, offset?: number, serializer: BSONBinarySerializer = bsonBinarySerializer, receiveType?: ReceiveType<T>): T {
return getBSONDeserializer(serializer, receiveType)(data, offset) as T;
const deserialize = getBSONDeserializer(serializer, receiveType);
return deserialize(data, offset) as T;
}
Loading

0 comments on commit 5f6bd12

Please sign in to comment.