From f16b6e460d8f1aaa4c20ba50889623e12d5ce237 Mon Sep 17 00:00:00 2001 From: marcus-sa Date: Fri, 8 Dec 2023 01:16:07 +0100 Subject: [PATCH] save --- packages/type-compiler/dist/.gitkeep | 0 packages/type-compiler/src/compiler.ts | 62 ++--- packages/type-compiler/src/external.ts | 3 +- packages/type-compiler/src/reflection-ast.ts | 5 + .../inline-external-library-imports.spec.ts | 214 ++++++++++++------ .../tests/setup/suite1/tsconfig.json | 4 +- packages/type/dist/.gitkeep | 0 packages/type/src/default.ts | 5 +- packages/type/src/reference.ts | 4 +- packages/type/src/reflection/extends.ts | 6 +- packages/type/src/reflection/processor.ts | 14 +- packages/type/src/reflection/reflection.ts | 4 +- packages/type/src/reflection/type.ts | 32 ++- packages/type/src/registry.ts | 6 +- packages/type/src/serializer.ts | 8 +- packages/type/src/type-serialization.ts | 9 +- .../type/tests/type-serialization.spec.ts | 16 +- packages/type/tests/typedarray.spec.ts | 4 +- 18 files changed, 257 insertions(+), 139 deletions(-) delete mode 100644 packages/type-compiler/dist/.gitkeep delete mode 100644 packages/type/dist/.gitkeep diff --git a/packages/type-compiler/dist/.gitkeep b/packages/type-compiler/dist/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/type-compiler/src/compiler.ts b/packages/type-compiler/src/compiler.ts index 09d759bb1..5884ad2d1 100644 --- a/packages/type-compiler/src/compiler.ts +++ b/packages/type-compiler/src/compiler.ts @@ -82,7 +82,7 @@ import { getNameAsString, getPropertyName, getRuntimeTypeName, - hasModifier, + hasModifier, hasSourceFile, isBuiltType, isNodeWithLocals, NodeConverter, @@ -465,7 +465,7 @@ class CompilerProgram { return frame.variables.length - 1; } - pushTemplateParameter(name: string, withDefault: boolean = false): number { + pushTemplateParameter(name: string, withDefault: boolean = false): number { this.pushOp(withDefault ? ReflectionOp.typeParameterDefault : ReflectionOp.typeParameter, this.findOrAddStackEntry(name)); this.frame.variables.push({ index: this.frame.variables.length, @@ -1343,11 +1343,11 @@ export class ReflectionTransformer implements CustomTransformer { const narrowed = node as ClassDeclaration | ClassExpression; //class nodes have always their own program, so the start is always fresh, means we don't need a frame - if (this.external.isEmbeddingExternalLibraryImport()) { + /*if (this.external.isEmbeddingExternalLibraryImport()) { const declaration = this.nodeConverter.convertClassToInterface(narrowed); this.extractPackStructOfType(declaration, program); break; - } + }*/ if (node) { const members: ClassElement[] = []; @@ -1363,7 +1363,7 @@ export class ReflectionTransformer implements CustomTransformer { } } - if (narrowed.heritageClauses) { + if (!this.external.isEmbeddingExternalLibraryImport() && narrowed.heritageClauses) { for (const heritage of narrowed.heritageClauses) { if (heritage.token === SyntaxKind.ExtendsKeyword) { for (const extendType of heritage.types) { @@ -1394,7 +1394,8 @@ export class ReflectionTransformer implements CustomTransformer { this.extractPackStructOfType(member, program); } - program.pushOp(ReflectionOp.class); + program.pushOp(ReflectionOp.class) + // program.pushOp(!this.external.isEmbeddingExternalLibraryImport() ? ReflectionOp.class : ReflectionOp.objectLiteral); if (narrowed.heritageClauses) { for (const heritageClause of narrowed.heritageClauses) { @@ -1416,7 +1417,9 @@ export class ReflectionTransformer implements CustomTransformer { } } - if (narrowed.name) this.resolveTypeName(getIdentifierName(narrowed.name), program); + if (narrowed.name) { + this.resolveTypeName(getIdentifierName(narrowed.name), program); + } const description = extractJSDocAttribute(narrowed, 'description'); if (description) program.pushOp(ReflectionOp.description, program.findOrAddStackEntry(description)); @@ -1696,10 +1699,6 @@ export class ReflectionTransformer implements CustomTransformer { const narrowed = node as MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorTypeNode | ConstructSignatureDeclaration | ConstructorDeclaration | ArrowFunction | FunctionExpression | FunctionTypeNode | FunctionDeclaration; - if(this.external.isEmbeddingExternalLibraryImport() && (isFunctionDeclaration(node) || isFunctionExpression(node) || isMethodDeclaration(node))) { - console.log(getNameAsString(narrowed.name)); - } - const config = this.findReflectionConfig(narrowed, program); if (config.mode === 'never') return; @@ -2034,7 +2033,7 @@ export class ReflectionTransformer implements CustomTransformer { if (importDeclaration.importClause && importDeclaration.importClause.isTypeOnly) typeOnly = true; declaration = this.resolveImportSpecifier(typeName.escapedText, importDeclaration, this.sourceFile); //might be an external library - if (!declaration) { + if (!declaration && hasSourceFile(importDeclaration)) { sourceFile = importDeclaration.getSourceFile(); declaration = this.resolveImportSpecifier(typeName.escapedText, importDeclaration, sourceFile); } @@ -2096,6 +2095,7 @@ export class ReflectionTransformer implements CustomTransformer { // check if the referenced declaration has reflection disabled const declarationReflection = this.findReflectionConfig(declaration, program); if (declarationReflection.mode !== 'never') { + if (!hasSourceFile(importDeclaration)) return expression; const declarationSourceFile = importDeclaration.getSourceFile(); const runtimeTypeName = this.getRuntimeTypeName(typeName); @@ -2106,10 +2106,11 @@ export class ReflectionTransformer implements CustomTransformer { if (isEmbeddingExternalLibraryImport || (!builtType && this.external.shouldInlineExternalLibraryImport(importDeclaration, typeName, declarationReflection))) { const { module } = this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, importDeclaration); - const newExpression = this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName); - return !isEmbeddingExternalLibraryImport && (isClassDeclaration(declaration) || isFunctionDeclaration(declaration)) - ? this.wrapWithAssignType(expression, newExpression) - : newExpression + return this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName); + // const newExpression = this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName); + // return !isEmbeddingExternalLibraryImport && (isClassDeclaration(declaration) || isFunctionDeclaration(declaration)) + // ? this.wrapWithAssignType(expression, newExpression) + // : newExpression } } @@ -2215,7 +2216,6 @@ export class ReflectionTransformer implements CustomTransformer { if (isModuleDeclaration(declaration) && resolved.importDeclaration) { let expression: Expression = serializeEntityNameAsExpression(this.f, typeName); if (isIdentifier(typeName)) { - console.log(2, getNameAsString(typeName)); expression = this.resolveImportExpression(declaration, resolved.importDeclaration, typeName, expression, program) } @@ -2309,19 +2309,20 @@ export class ReflectionTransformer implements CustomTransformer { return; } - const builtType = isBuiltType(runtimeTypeName, found); - if (!builtType) { - if (!this.external.shouldInlineExternalLibraryImport(resolved.importDeclaration, typeName, declarationReflection)) return; - this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration); + const reflection = this.findReflectionFromPath(found.fileName); + if (reflection.mode !== 'never') { + this.addImports.push({ identifier: runtimeTypeName, from: resolved.importDeclaration.moduleSpecifier }); + return; } else { - //check if the referenced file has reflection info emitted. if not, any is emitted for that reference - const reflection = this.findReflectionFromPath(found.fileName); - if (reflection.mode === 'never') { - program.pushOp(ReflectionOp.any); - return; + const builtType = isBuiltType(runtimeTypeName, found); + if (!builtType) { + if (this.external.shouldInlineExternalLibraryImport(resolved.importDeclaration, typeName, declarationReflection)) { + this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration); + } else { + program.pushOp(ReflectionOp.any); + return; + } } - - this.addImports.push({ identifier: runtimeTypeName, from: resolved.importDeclaration.moduleSpecifier }); } } } else { @@ -2384,14 +2385,15 @@ export class ReflectionTransformer implements CustomTransformer { this.extractPackStructOfType(typeArgument, program); } } - if (this.external.isEmbeddingExternalLibraryImport()) { + /*if (this.external.isEmbeddingExternalLibraryImport()) { if (isClassDeclaration(declaration)) { program.pushOp(ReflectionOp.objectLiteral); } else { const index = program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, body)); program.pushOp(ReflectionOp.function, index); } - } else { + this.resolveTypeName(getNameAsString(typeName), program); + } else */{ const index = program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, body)); program.pushOp(isClassDeclaration(declaration) ? ReflectionOp.classReference : ReflectionOp.functionReference, index); } diff --git a/packages/type-compiler/src/external.ts b/packages/type-compiler/src/external.ts index 5cb076e4f..6e27ff491 100644 --- a/packages/type-compiler/src/external.ts +++ b/packages/type-compiler/src/external.ts @@ -8,7 +8,7 @@ const { isStringLiteral, } = ts; -import { getEntityName, getNameAsString } from './reflection-ast.js'; +import { getEntityName, getNameAsString, hasSourceFile } from './reflection-ast.js'; import { ReflectionConfig } from './compiler.js'; import { Resolver } from './resolver.js'; @@ -68,6 +68,7 @@ export class External { public shouldInlineExternalLibraryImport(importDeclaration: ImportDeclaration, entityName: EntityName, config: ReflectionConfig): boolean { if (!isStringLiteral(importDeclaration.moduleSpecifier)) return false; + if (!hasSourceFile(importDeclaration)) return false; if (config.options.inlineExternalLibraryImports === true) return true; const resolvedModule = this.resolver.resolveExternalLibraryImport(importDeclaration); const imports = config.options.inlineExternalLibraryImports?.[resolvedModule.packageId.name]; diff --git a/packages/type-compiler/src/reflection-ast.ts b/packages/type-compiler/src/reflection-ast.ts index bbc4c6485..e5d1e3535 100644 --- a/packages/type-compiler/src/reflection-ast.ts +++ b/packages/type-compiler/src/reflection-ast.ts @@ -64,6 +64,10 @@ export function getIdentifierName(node: Identifier | PrivateIdentifier): string return ts.unescapeLeadingUnderscores(node.escapedText); } +export function hasSourceFile(node: Node): boolean { + return typeof node.getSourceFile === 'function'; +} + export function joinQualifiedName(name: EntityName): string { if (isIdentifier(name)) return getIdentifierName(name); return joinQualifiedName(name.left) + '_' + getIdentifierName(name.right); @@ -162,6 +166,7 @@ export class NodeConverter { node.type, ); } else if (isConstructorDeclaration(node)) { + // return this.f.createm return this.f.createConstructSignature(node.typeParameters, node.parameters, node.type); } diff --git a/packages/type-compiler/tests/inline-external-library-imports.spec.ts b/packages/type-compiler/tests/inline-external-library-imports.spec.ts index 33ad23047..b559cb6d4 100644 --- a/packages/type-compiler/tests/inline-external-library-imports.spec.ts +++ b/packages/type-compiler/tests/inline-external-library-imports.spec.ts @@ -1,6 +1,5 @@ import { test, expect } from '@jest/globals'; -import { ReflectionKind, TypeClass, TypeFunction } from '@deepkit/type'; -import { Unsubscribable } from 'rxjs'; +import {ReflectionKind, TypeClass, TypeFunction, } from '@deepkit/type'; import { transpile, transpileAndRun } from './utils'; @@ -163,8 +162,6 @@ test('function type alias', () => { expect(res.app).toContain('() => __ɵΩrxjs_operators.Ωmap)'); }); -import { map } from 'rxjs'; - test('typeOf function type alias', () => { const res = transpileAndRun({ app: `import { map } from 'rxjs'; @@ -197,17 +194,17 @@ test('typeOf function type alias', () => { "parameters": [Circular], "return": { "annotations": {}, - "id": 6, + "id": 4, "implements": [ { "annotations": {}, - "id": 4, + "id": 2, "kind": 30, "typeArguments": [ { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": { "kind": 18, "name": "source", @@ -218,21 +215,31 @@ test('typeOf function type alias', () => { ], "parent": [Circular], "return": { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, "type": [Circular], }, + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": { "kind": 35, "parameters": [ @@ -241,10 +248,15 @@ test('typeOf function type alias', () => { "name": "source", "parent": [Circular], "type": { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, @@ -252,6 +264,11 @@ test('typeOf function type alias', () => { "parent": [Circular], "return": [Circular], }, + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, ], @@ -265,20 +282,30 @@ test('typeOf function type alias', () => { "name": "source", "parent": [Circular], "type": { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, ], "parent": [Circular], "return": { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, @@ -305,20 +332,30 @@ test('typeOf function type alias', () => { "name": "source", "parent": [Circular], "type": { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, ], "parent": [Circular], "return": { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, @@ -359,17 +396,17 @@ test('typeOf function type alias', () => { ], "return": { "annotations": {}, - "id": 6, + "id": 4, "implements": [ { "annotations": {}, - "id": 4, + "id": 2, "kind": 30, "typeArguments": [ { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": { "kind": 18, "name": "source", @@ -380,21 +417,31 @@ test('typeOf function type alias', () => { ], "parent": [Circular], "return": { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, "type": [Circular], }, + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": { "kind": 35, "parameters": [ @@ -403,10 +450,15 @@ test('typeOf function type alias', () => { "name": "source", "parent": [Circular], "type": { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, @@ -414,6 +466,11 @@ test('typeOf function type alias', () => { "parent": [Circular], "return": [Circular], }, + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, ], @@ -427,20 +484,30 @@ test('typeOf function type alias', () => { "name": "source", "parent": [Circular], "type": { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, ], "parent": [Circular], "return": { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, @@ -509,20 +576,30 @@ test('typeOf function type alias', () => { "name": "source", "parent": [Circular], "type": { - "annotations": {}, - "id": 1, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, ], "parent": [Circular], "return": { - "annotations": {}, - "id": 2, - "kind": 30, + "classType": undefined, + "external": true, + "kind": 20, "parent": [Circular], + "typeArguments": [ + { + "kind": 1, + }, + ], "types": [], }, }, @@ -549,19 +626,17 @@ test('class type var', () => { ""use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const __ɵΩrxjs = {}; -__ɵΩrxjs.Observable = ['source', () => __ɵΩrxjs.Operator, 'operator', 'this', 'subscriber', () => __ɵΩrxjs.TeardownLogic, '', 'subscribe', 'new', 'args', 'create', () => __ɵΩrxjs.Operator, 'lift', () => __ΩPartial, () => __ɵΩrxjs.Observer, 'observer', 'value', 'next', 'error', 'complete', 'forEach', () => __ΩPromiseConstructorLike, 'promiseCtor', 'pipe', () => __ɵΩrxjs.OperatorFunction, 'op1', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op2', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op3', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op4', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op5', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op6', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op7', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op8', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'op9', () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, () => __ɵΩrxjs.OperatorFunction, 'operations', 'toPromise', () => Promise, 'PromiseCtor', () => __ΩPromiseConstructorLike, 'PPP"M-J4!P"!o"#-J4#PPP!M2$P!M2%n&/\\'2(8"1)P"@2*"/\\'4+P!"o,#2#8P"M1-P!o/"o."208PM1(PP!21$/\\'22PM1(PPP!21$/\\',J228PP"23$/\\',J238PP$/\\',J248PM1(PP!21$/\\'22$\`15PP!21$/\\'22n627$\`15PP!M18P!"o9#2:P"M18P!"o;#2:""o<#2=P"M18P!"o>#2:""o?#2=""o@#2AP"M18P!"oB#2:""oC#2=""oD#2A""oE#2FP"M18P!"oG#2:""oH#2=""oI#2A""oJ#2F""oK#2LP"M18P!"oM#2:""oN#2=""oO#2A""oP#2F""oQ#2L""oR#2SP"M18P!"oT#2:""oU#2=""oV#2A""oW#2F""oX#2L""oY#2S""oZ#2[P"M18P!"o\\\\#2:""o]#2=""o^#2A""o_#2F""o\`#2L""oa#2S""ob#2[""oc#2dP"M18P!"oe#2:""of#2=""og#2A""oh#2F""oi#2L""oj#2S""ok#2[""ol#2d""om#2nP"M18P!"oo#2:""op#2=""oq#2A""or#2F""os#2L""ot#2S""ou#2[""ov#2d""ow#2n""ox#@2yP#M18PP!-J\`1zPi{2|P!-J\`1zPn}2|P!-J\`1zMy']; +__ɵΩrxjs.Observable = ['T', () => __ɵΩrxjs.Observable, 'source', () => __ɵΩrxjs.Operator, 'operator', () => __ɵΩrxjs.Observable, 'this', () => __ɵΩrxjs.Subscriber, 'subscriber', () => __ɵΩrxjs.TeardownLogic, '', 'subscribe', 'constructor', 'args', 'create', () => __ɵΩrxjs.Operator, () => __ɵΩrxjs.Observable, 'lift', () => __ΩPartial, () => __ɵΩrxjs.Observer, 'observer', () => __ɵΩrxjs.Subscription, 'value', 'next', 'forEach', () => __ɵΩrxjs.Observable, 'pipe', 'toPromise', () => __ɵΩrxjs.Subscribable, 'Observable', 'b!PP"7"-J3#P"e"!o$#-J3%PPPe$!7&2\\'Pe$!7(2)n*/+2,8"0-P"@2."/+3/sPe"!"o0#2%8P"7102Pe"!o4"o3"258P760,PPe#!27$/+28$\`09PPe#!7:0;PPe#!-J\`0<5e!!o="x"w>y']; const __ΩPartial = ['T', 'l+e#!e"!fRb!Pde"!gN#"y']; -const __ΩPromiseConstructorLike = [() => __ΩPromiseLike, 'value', '', 'resolve', 'reason', 'reject', 'executor', () => __ΩPromiseLike, 'new', 'PPPP""o!"J2"$/#2$P"2%8$/#2&$/#2\\'"o("/)y']; -__ɵΩrxjs.Operator = ['T', 'R', 'subscriber', 'source', () => __ɵΩrxjs.TeardownLogic, 'call', 'b!b"PPPe$"M2#"2$n%1&My']; -__ɵΩrxjs.Subscriber = ['x', '', 'next', 'e', 'error', 'complete', 'create', 'isStopped', () => __ɵΩrxjs.Observer, 'destination', () => __ɵΩrxjs.Observer, 'new', 'value', 'err', 'unsubscribe', '_next', '_error', '_complete', 'PPMPP"2!8$/"2#8P"2$8$/"2%8P$/"2&8P"M1\\')4(PP"M"o)"J4*PPP"M"o+"J2*8"1,P!2-8$1#P"2.8$1%P$1&P$1/P!2-$10P"2.$11P$12My']; -__ɵΩrxjs.TeardownLogic = [() => __ɵΩrxjs.Unsubscribable, '', 'PPMn!P$/"$Jy']; +__ɵΩrxjs.Operator = ['T', 'R', () => __ɵΩrxjs.Subscriber, 'subscriber', 'source', () => __ɵΩrxjs.TeardownLogic, 'call', 'b!b"PPPe$"7#2$"2%n&1\\'My']; +__ɵΩrxjs.Subscriber = ['T', 'x', '', 'next', 'e', 'error', 'complete', () => __ɵΩrxjs.Subscriber, 'create', 'isStopped', () => __ɵΩrxjs.Subscriber, () => __ɵΩrxjs.Observer, 'destination', () => __ɵΩrxjs.Subscriber, () => __ɵΩrxjs.Observer, 'constructor', 'value', 'err', 'unsubscribe', '_next', '_error', '_complete', () => __ɵΩrxjs.Observer, 'Subscriber', 'b!PPe#!2"8$/#2$8P"2%8$/#2&8P$/#2\\'8Pe#!7(0)s)3* __ɵΩrxjs.Subscription, () => __ɵΩrxjs.Unsubscribable, '', 'PP7!n"P$/#$Jy']; __ɵΩrxjs.Observer = ['T', 'value', '', 'next', 'err', 'error', 'complete', 'b!PPe#!2"$/#4$P"2%$/#4&P$/#4\\'My']; -__ɵΩrxjs.Subscription = ['EMPTY', 'closed', '', 'initialTeardown', 'new', 'unsubscribe', () => __ɵΩrxjs.TeardownLogic, 'teardown', 'add', () => __ΩExclude, () => __ɵΩrxjs.TeardownLogic, 'remove', 'PPM4!)4"PPP$/#-J2$8"1%P$1&Pn\\'2($1)Pn+$o*#2($1,My']; -__ɵΩrxjs.OperatorFunction = ['T', 'R', () => __ɵΩrxjs.UnaryFunction, 'b!b"PPe#!MPe#"Mo##My']; -const __ΩPromiseLike = ['T', 'value', 0, '', 'onfulfilled', 'reason', 0, 'onrejected', 0, 'then', 'b!PPPPe%!2"P""o#"J/$-,J2%8PP"2&P""o\\'"J/$-,J2(8P""Jo)"1*My']; +__ɵΩrxjs.Subscription = [() => __ɵΩrxjs.Subscription, 'EMPTY', 'closed', '', 'initialTeardown', 'constructor', 'unsubscribe', () => __ɵΩrxjs.TeardownLogic, 'teardown', 'add', () => __ΩExclude, () => __ɵΩrxjs.TeardownLogic, 'remove', () => __ɵΩrxjs.SubscriptionLike, 'Subscription', 'P7!3"s)3#PPP$/$-J2%8"0&P$0\\'Pn(2)$0*Pn,$o+#2)$0-5n.x"w/y']; +__ɵΩrxjs.Subscribable = ['T', () => __ΩPartial, () => __ɵΩrxjs.Observer, 'observer', () => __ɵΩrxjs.Unsubscribable, 'subscribe', 'b!PPe#!o#"o""2$n%1&My']; const __ΩExclude = ['T', 'U', 'l6!Re$!RPe#!e$"qk#%QRb!b"Pde"!p)y']; __ɵΩrxjs.Unsubscribable = ['unsubscribe', 'PP$1!My']; -__ɵΩrxjs.UnaryFunction = ['T', 'R', 'source', '', 'b!b"PPe#!2#e#"v$My']; +__ɵΩrxjs.SubscriptionLike = [() => __ɵΩrxjs.Unsubscribable, 'unsubscribe', 'closed', 'Pn!P$1")4#9My']; function __assignType(fn, args) { fn.__type = args; return fn; @@ -605,13 +680,18 @@ test('class typeOf', () => { console.log(res); + expect(res).toMatchObject({ + external: true, + classType: undefined, + }); + expect(res.implements![0]).toMatchObject({ kind: 30, typeName: 'Subscribable', // typeName: 'UnknownTypeName:() => __ɵΩrxjs.Subscribable', }); - expect(res.typeArguments).toHaveLength(1); - expect(res.types).toHaveLength(1); + // expect(res.typeArguments).toHaveLength(1); + // expect(res.types).toHaveLength(1); }) test('only a single type is transformed', () => { diff --git a/packages/type-compiler/tests/setup/suite1/tsconfig.json b/packages/type-compiler/tests/setup/suite1/tsconfig.json index d234bc79a..f2f76c67c 100644 --- a/packages/type-compiler/tests/setup/suite1/tsconfig.json +++ b/packages/type-compiler/tests/setup/suite1/tsconfig.json @@ -6,7 +6,9 @@ "module": "CommonJS", "esModuleInterop": true }, - "reflection": true, + "deepkitTypeCompilerOptions": { + "reflection": true + }, "files": [ "app.ts" ] diff --git a/packages/type/dist/.gitkeep b/packages/type/dist/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/type/src/default.ts b/packages/type/src/default.ts index 4671b16a3..b0507b3a5 100644 --- a/packages/type/src/default.ts +++ b/packages/type/src/default.ts @@ -1,4 +1,5 @@ -import { binaryTypes, ReflectionKind, resolveTypeMembers, Type } from './reflection/type.js'; +import { binaryTypes, getClassType, ReflectionKind, resolveTypeMembers, Type } from './reflection/type.js'; +import { ClassType } from '@deepkit/core'; /** * Returns a sensible default value for a given type. @@ -71,7 +72,7 @@ export function defaultValue(type: Type): any { if (type.classType === Date) return new Date; if (type.classType === Set) return new Set; if (type.classType === Map) return new Map; - if (binaryTypes.includes(type.classType)) return new type.classType; + if (binaryTypes.includes(getClassType(type))) return new (getClassType(type)); const result: any = {}; const types = resolveTypeMembers(type); diff --git a/packages/type/src/reference.ts b/packages/type/src/reference.ts index e3cac5a5c..a728777fe 100644 --- a/packages/type/src/reference.ts +++ b/packages/type/src/reference.ts @@ -11,7 +11,7 @@ import { ClassType, isObject } from '@deepkit/core'; import { ReflectionClass, reflectionClassSymbol } from './reflection/reflection.js'; import { typeSettings, UnpopulatedCheck, unpopulatedSymbol } from './core.js'; -import { ReflectionKind, Type } from './reflection/type.js'; +import { getClassType, ReflectionKind, Type } from './reflection/type.js'; export function isReferenceInstance(obj: any): boolean { return isObject(obj) && referenceSymbol in obj; @@ -71,7 +71,7 @@ export function createReferenceClass( ): ClassType { if (reflection.data.referenceClass) return reflection.data.referenceClass; - const Reference = reflection.type.kind === ReflectionKind.class ? class extends reflection.type.classType { + const Reference = reflection.type.kind === ReflectionKind.class ? class extends getClassType(reflection.type) { } : class { }; diff --git a/packages/type/src/reflection/extends.ts b/packages/type/src/reflection/extends.ts index 18264a3a1..81c9e0e99 100644 --- a/packages/type/src/reflection/extends.ts +++ b/packages/type/src/reflection/extends.ts @@ -11,7 +11,7 @@ import { addType, emptyObject, - flatten, getTypeJitContainer, + flatten, getClassType, getTypeJitContainer, indexAccess, isMember, isOptional, @@ -33,7 +33,7 @@ import { TypeString, TypeTemplateLiteral, TypeTuple, - TypeUnion + TypeUnion, } from './type.js'; import { isPrototypeOfBase } from '@deepkit/core'; import { typeInfer } from './processor.js'; @@ -274,7 +274,7 @@ export function _isExtendable(left: Type, right: Type, extendStack: StackEntry[] //class User extends Base {} //User extends Base = true if (left.classType === right.classType) return true; - return isPrototypeOfBase(left.classType, right.classType); + return isPrototypeOfBase(left.classType, getClassType(right)); } return true; diff --git a/packages/type/src/reflection/processor.ts b/packages/type/src/reflection/processor.ts index 4bbd85d39..2163f5269 100644 --- a/packages/type/src/reflection/processor.ts +++ b/packages/type/src/reflection/processor.ts @@ -590,7 +590,7 @@ export class Processor { break; case ReflectionOp.class: { const types = this.popFrame() as Type[]; - let t = { kind: ReflectionKind.class, id: state.nominalId++, classType: Object, types: [] } as TypeClass; + let t = { kind: ReflectionKind.class, id: state.nominalId++, types: [] } as TypeClass; function add(member: Type) { if (member.kind === ReflectionKind.propertySignature) { @@ -669,6 +669,8 @@ export class Processor { if (args.length) t.arguments = args; t.typeArguments = program.typeParameters; + console.log('class', t); + this.pushType(t); break; } @@ -712,13 +714,16 @@ export class Processor { case ReflectionOp.classReference: { const ref = this.eatParameter() as number; const classOrFunction = resolveFunction(program.stack[ref] as Function, program.object); + const external = isPack(classOrFunction); const inputs = this.popFrame() as Type[]; if (!classOrFunction) { this.pushType({ kind: ReflectionKind.unknown }); break; } - if (!classOrFunction.__type) { + const runtimeType = external ? classOrFunction : classOrFunction.__type; + + if (!runtimeType) { if (op === ReflectionOp.classReference) { this.pushType({ kind: ReflectionKind.class, classType: classOrFunction, typeArguments: inputs, types: [] }); } else if (op === ReflectionOp.functionReference) { @@ -727,7 +732,7 @@ export class Processor { } else { //when it's just a simple reference resolution like typeOf() then enable cache re-use (so always the same type is returned) const directReference = !!(this.isEnded() && program.previous && program.previous.end === 0); - const result = this.reflect(classOrFunction, inputs, { inline: !directReference, reuseCached: directReference }); + const result = this.reflect(runtimeType, inputs, { inline: !directReference, reuseCached: directReference }); if (directReference) program.directReturn = true; this.push(result, program); @@ -1284,7 +1289,7 @@ export class Processor { if (isType(result)) { if (program.object) { if (result.kind === ReflectionKind.class && result.classType === Object) { - result.classType = program.object; + // result.classType = program.object; applyClassDecorators(result); } if (result.kind === ReflectionKind.function && !result.function) { @@ -1778,7 +1783,6 @@ export function typeInfer(value: any): Type { } if (isClass(value)) { - //unknown class return { kind: ReflectionKind.class, classType: value as ClassType, types: [] }; } diff --git a/packages/type/src/reflection/reflection.ts b/packages/type/src/reflection/reflection.ts index 4c48cb7d4..a68d6eb1c 100644 --- a/packages/type/src/reflection/reflection.ts +++ b/packages/type/src/reflection/reflection.ts @@ -983,7 +983,7 @@ export class ReflectionClass { } getClassType(): ClassType { - return this.type.kind === ReflectionKind.class ? this.type.classType : Object; + return this.type.kind === ReflectionKind.class ? getClassType(this.type) : Object; } getClassName(): string { @@ -1233,7 +1233,7 @@ export class ReflectionClass { if (classTypeIn.kind !== ReflectionKind.class) throw new Error(`TypeClass or TypeObjectLiteral expected, not ${ReflectionKind[classTypeIn.kind]}`); } - const classType = isType(classTypeIn) ? (classTypeIn as TypeClass).classType : (classTypeIn as any)['prototype'] ? classTypeIn as ClassType : classTypeIn.constructor as ClassType; + const classType = isType(classTypeIn) ? getClassType(classTypeIn) : (classTypeIn as any)['prototype'] ? classTypeIn as ClassType : classTypeIn.constructor as ClassType; if (!classType.prototype.hasOwnProperty(reflectionClassSymbol)) { Object.defineProperty(classType.prototype, reflectionClassSymbol, { writable: true, enumerable: false }); diff --git a/packages/type/src/reflection/type.ts b/packages/type/src/reflection/type.ts index c188814e3..914480023 100644 --- a/packages/type/src/reflection/type.ts +++ b/packages/type/src/reflection/type.ts @@ -8,7 +8,17 @@ * You should have received a copy of the MIT License along with this program. */ -import { AbstractClassType, arrayRemoveItem, ClassType, getClassName, getParentClass, indent, isArray, isClass } from '@deepkit/core'; +import { + AbstractClassType, + arrayRemoveItem, + ClassType, + getClassName, + getParentClass, + indent, + isArray, + isClass, + isFunction, +} from '@deepkit/core'; import { TypeNumberBrand } from '@deepkit/type-spec'; import { getProperty, ReceiveType, reflect, ReflectionClass, resolveReceiveType, toSignature } from './reflection.js'; import { isExtendable } from './extends.js'; @@ -69,6 +79,8 @@ export enum ReflectionKind { infer, callSignature, + + externalClass, } export type TypeDecorator = (annotations: Annotations, decorator: TypeObjectLiteral) => boolean; @@ -307,6 +319,7 @@ export interface TypeFunction extends TypeAnnotations { parent?: Type; name?: number | string | symbol, description?: string; + external?: boolean; function?: Function; //reference to the real function if available parameters: TypeParameter[]; return: Type; @@ -328,7 +341,8 @@ export interface TypePromise extends TypeAnnotations { export interface TypeClass extends TypeAnnotations { kind: ReflectionKind.class, parent?: Type; - classType: ClassType; + external?: boolean; + classType?: ClassType; // reference to the real class if available description?: string; /** @@ -510,8 +524,7 @@ export type Type = | TypeTupleMember | TypeRest | TypeRegexp - | TypeCallSignature - ; + | TypeCallSignature; export type Widen = T extends string ? string @@ -540,7 +553,7 @@ export function isType(entry: any): entry is Type { } export function isBinary(type: Type): boolean { - return type.kind === ReflectionKind.class && binaryTypes.includes(type.classType); + return type.kind === ReflectionKind.class && binaryTypes.includes(getClassType(type)); } export function isPrimitive(type: T): boolean { @@ -1331,6 +1344,9 @@ export function assertType(t: Type | undefined, kin export function getClassType(type: Type): ClassType { if (type.kind !== ReflectionKind.class) throw new Error(`Type needs to be TypeClass, but ${ReflectionKind[type.kind]} given.`); + if (!type.classType) { + throw new Error('TypeClass is missing classType'); + } return type.classType; } @@ -2265,6 +2281,9 @@ export const binaryTypes: ClassType[] = [ */ export function isGlobalTypeClass(type: Type): type is TypeClass { if (type.kind !== ReflectionKind.class) return false; + if (!type.classType) { + throw new Error('TypeClass is missing classType'); + } if ('undefined' !== typeof window) { return (window as any)[getClassName(type.classType)] === type.classType; } @@ -2478,6 +2497,9 @@ export function stringifyType(type: Type, stateIn: Partial stack.push({ type: type.arguments![0], depth: depth + 1 }); break; } + + if (!type.classType) break; + if (binaryTypes.includes(type.classType)) { result.push(getClassName(type.classType)); break; diff --git a/packages/type/src/registry.ts b/packages/type/src/registry.ts index 772f40ba9..98d6fbd70 100644 --- a/packages/type/src/registry.ts +++ b/packages/type/src/registry.ts @@ -1,5 +1,5 @@ import { ClassType, isArray, isFunction } from '@deepkit/core'; -import { binaryTypes, ReflectionKind, Type } from './reflection/type.js'; +import { binaryTypes, getClassType, ReflectionKind, Type } from './reflection/type.js'; interface RegistryDecorator { predicate: (type: Type) => boolean, @@ -22,9 +22,9 @@ export class TypeRegistry { } if (type.kind === ReflectionKind.class) { - const classResult = this.classes.get(type.classType); + const classResult = this.classes.get(getClassType(type)); if (classResult) return classResult; - if (type.classType === Set || type.classType === Map || binaryTypes.includes(type.classType)) return undefined; + if (type.classType === Set || type.classType === Map || binaryTypes.includes(getClassType(type))) return undefined; } return this.results[type.kind]; } diff --git a/packages/type/src/serializer.ts b/packages/type/src/serializer.ts index 39e71a5d7..00dee6451 100644 --- a/packages/type/src/serializer.ts +++ b/packages/type/src/serializer.ts @@ -33,7 +33,7 @@ import { embeddedAnnotation, EmbeddedOptions, excludedAnnotation, - FindType, + FindType, getClassType, getConstructorProperties, getTypeJitContainer, getTypeObjectLiteralFromTypeClass, @@ -65,7 +65,7 @@ import { typeToObject, TypeTuple, TypeUnion, - validationAnnotation + validationAnnotation, } from './reflection/type.js'; import { TypeNumberBrand } from '@deepkit/type-spec'; import { hasCircularReference, ReflectionClass, ReflectionProperty } from './reflection/reflection.js'; @@ -586,9 +586,9 @@ export class TemplateRegistry { get(type: Type): Template[] { if (type.kind === ReflectionKind.class) { - const classTemplates = this.classTemplates.get(type.classType); + const classTemplates = this.classTemplates.get(getClassType(type)); if (classTemplates && classTemplates.length) return classTemplates; - if (type.classType === Set || type.classType === Map || binaryTypes.includes(type.classType)) return []; + if (type.classType === Set || type.classType === Map || binaryTypes.includes(getClassType(type))) return []; } return this.templates[type.kind] ||= []; } diff --git a/packages/type/src/type-serialization.ts b/packages/type/src/type-serialization.ts index ccf0cca13..49f439068 100644 --- a/packages/type/src/type-serialization.ts +++ b/packages/type/src/type-serialization.ts @@ -2,6 +2,7 @@ import { entityAnnotation, EntityOptions, findMember, + getClassType, isSameType, isTypeIncluded, isWithAnnotations, @@ -20,7 +21,7 @@ import { TypeProperty, TypeRest, TypeTuple, - TypeTupleMember + TypeTupleMember, } from './reflection/type.js'; import { getClassName, getParentClass } from '@deepkit/core'; import { reflect, ReflectionClass, typeOf } from './reflection/reflection.js'; @@ -345,14 +346,14 @@ function serialize(type: Type, state: SerializerState): SerializedTypeReference } case ReflectionKind.class: { const types = state.disableMethods ? type.types.filter(filterRemoveFunctions) : type.types; - const parent = getParentClass(type.classType); + const parent = getParentClass(getClassType(type)); let superClass: SerializedTypeReference | undefined = undefined; try { superClass = parent ? serialize(reflect(parent), state) : undefined; } catch { } - const classType = getClassName(type.classType); + const classType = getClassName(getClassType(type)); const globalObject: boolean = envGlobal && envGlobal[classType] === type.classType; Object.assign(result, { @@ -638,7 +639,7 @@ function deserialize(type: SerializedType | SerializedTypeReference, state: Dese } const classType = type.globalObject ? envGlobal[type.classType] : newClass - ? (type.superClass ? class extends (deserialize(type.superClass, state) as TypeClass).classType { + ? (type.superClass ? class extends getClassType(deserialize(type.superClass, state) as TypeClass) { constructor(...args: any[]) { super(...args); for (const init of initialize) { diff --git a/packages/type/tests/type-serialization.spec.ts b/packages/type/tests/type-serialization.spec.ts index 8cef1f9b8..9e5e3edc9 100644 --- a/packages/type/tests/type-serialization.spec.ts +++ b/packages/type/tests/type-serialization.spec.ts @@ -5,7 +5,7 @@ import { assertType, Entity, entityAnnotation, - findMember, + findMember, getClassType, isSameType, PrimaryKey, primaryKeyAnnotation, @@ -13,7 +13,7 @@ import { ReflectionKind, Type, TypeClass, - TypeProperty + TypeProperty, } from '../src/reflection/type.js'; import { deserializeType, serializeType } from '../src/type-serialization.js'; import { entity } from '../src/decorator.js'; @@ -199,7 +199,7 @@ test('roundTrip class static', () => { { const type = roundTrip(); assertType(type, ReflectionKind.class); - expect(getClassName(type.classType)).toBe('MyClass'); + expect(getClassName(getClassType(type))).toBe('MyClass'); assertType(type.types[0], ReflectionKind.property); assertType(type.types[1], ReflectionKind.property); @@ -225,7 +225,7 @@ test('roundTrip class generic', () => { { const type = roundTrip>(); assertType(type, ReflectionKind.class); - expect(getClassName(type.classType)).toBe('MyClass'); + expect(getClassName(getClassType(type))).toBe('MyClass'); assertType(type.types[0], ReflectionKind.property); assertType(type.types[1], ReflectionKind.property); @@ -273,11 +273,11 @@ test('circular basics', () => { const type = deserializeType(json); assertType(type, ReflectionKind.class); - expect(getClassName(type.classType)).toBe('MyModel'); + expect(getClassName(getClassType(type))).toBe('MyModel'); assertType(type.types[0], ReflectionKind.property); expect(type.types[0].name).toBe('sub'); assertType(type.types[0].type, ReflectionKind.class); - expect(getClassName(type.types[0].type.classType)).toBe('MyModel'); + expect(getClassName(getClassType(type.types[0].type))).toBe('MyModel'); }); test('circular with decorators', () => { @@ -289,12 +289,12 @@ test('circular with decorators', () => { const type = deserializeType(json); assertType(type, ReflectionKind.class); - expect(getClassName(type.classType)).toBe('MyModel'); + expect(getClassName(getClassType(type))).toBe('MyModel'); expect(primaryKeyAnnotation.isPrimaryKey(type)).toBe(false); assertType(type.types[0], ReflectionKind.property); expect(type.types[0].name).toBe('sub'); assertType(type.types[0].type, ReflectionKind.class); - expect(getClassName(type.types[0].type.classType)).toBe('MyModel'); + expect(getClassName(getClassType(type.types[0].type))).toBe('MyModel'); expect(primaryKeyAnnotation.isPrimaryKey(type.types[0].type)).toBe(true); }); diff --git a/packages/type/tests/typedarray.spec.ts b/packages/type/tests/typedarray.spec.ts index 1303e9eb1..edf51b02e 100644 --- a/packages/type/tests/typedarray.spec.ts +++ b/packages/type/tests/typedarray.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from '@jest/globals'; import { Buffer } from 'buffer'; import { ReflectionClass } from '../src/reflection/reflection.js'; -import { assertType, binaryTypes, ReflectionKind } from '../src/reflection/type.js'; +import { assertType, binaryTypes, getClassType, ReflectionKind } from '../src/reflection/type.js'; import { base64ToArrayBuffer, base64ToTypedArray, typedArrayToBase64, typedArrayToBuffer } from '../src/core.js'; import { deserialize, serialize } from '../src/serializer-facade.js'; @@ -25,7 +25,7 @@ test('mapping', async () => { for (const property of classSchema.getProperties()) { assertType(property.type, ReflectionKind.class); - expect(binaryTypes.includes(property.type.classType)).toBe(true); + expect(binaryTypes.includes(getClassType(property.type))).toBe(true); expect(typeof (json as any)[property.getNameAsString()]).toBe('string'); expect((back as any)[property.getNameAsString()]).toBeInstanceOf(property.type.classType); }