From b980dcb77bd2f0443503c5f103c98dbfeb13ee0c Mon Sep 17 00:00:00 2001 From: marcus-sa Date: Fri, 8 Dec 2023 12:11:47 +0100 Subject: [PATCH] save --- package-lock.json | 18 ++--- .../src/app/components/inputs/registry.ts | 3 +- packages/api-console-gui/src/app/utils.ts | 3 +- packages/bson/src/bson-parser.ts | 2 +- packages/injector/src/injector.ts | 20 ++--- packages/orm-browser-gui/src/app/registry.ts | 4 +- packages/sql/src/platform/default-platform.ts | 2 +- packages/type-compiler/src/compiler.ts | 73 ++++++++++--------- packages/type-compiler/src/external.ts | 5 +- packages/type-compiler/src/reflection-ast.ts | 9 ++- packages/type-compiler/src/resolver.ts | 1 + .../inline-external-library-imports.spec.ts | 19 +---- packages/type/src/default.ts | 2 +- packages/type/src/reference.ts | 2 +- packages/type/src/reflection/extends.ts | 2 +- packages/type/src/reflection/processor.ts | 15 ++-- packages/type/src/reflection/reflection.ts | 4 +- packages/type/src/reflection/type.ts | 28 +------ packages/type/src/registry.ts | 6 +- packages/type/src/serializer.ts | 6 +- packages/type/src/type-serialization.ts | 7 +- .../type/tests/type-serialization.spec.ts | 12 +-- packages/type/tests/typedarray.spec.ts | 2 +- 23 files changed, 101 insertions(+), 144 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4d06443e..549db92bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13712,6 +13712,7 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, "optional": true, "dependencies": { "iconv-lite": "^0.6.2" @@ -13721,6 +13722,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "optional": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -13858,7 +13860,6 @@ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "dev": true, "optional": true, - "peer": true, "dependencies": { "prr": "~1.0.1" }, @@ -20080,7 +20081,6 @@ "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", "dev": true, "optional": true, - "peer": true, "bin": { "image-size": "bin/image-size.js" }, @@ -20094,7 +20094,6 @@ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "optional": true, - "peer": true, "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -20109,7 +20108,6 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "dev": true, "optional": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -20123,7 +20121,6 @@ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=6" } @@ -20134,7 +20131,6 @@ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "optional": true, - "peer": true, "bin": { "semver": "bin/semver" } @@ -20145,7 +20141,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -21670,7 +21665,6 @@ "integrity": "sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.6.3", @@ -21689,7 +21683,6 @@ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "optional": true, - "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -21700,7 +21693,6 @@ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, "optional": true, - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -24070,8 +24062,7 @@ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true, - "optional": true, - "peer": true + "optional": true }, "node_modules/psl": { "version": "1.9.0", @@ -25171,7 +25162,7 @@ "version": "3.29.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", - "devOptional": true, + "dev": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -27809,6 +27800,7 @@ "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/packages/api-console-gui/src/app/components/inputs/registry.ts b/packages/api-console-gui/src/app/components/inputs/registry.ts index 79661c6a7..6a52d25a7 100644 --- a/packages/api-console-gui/src/app/components/inputs/registry.ts +++ b/packages/api-console-gui/src/app/components/inputs/registry.ts @@ -1,5 +1,4 @@ import { - getClassType, isMapType, isMongoIdType, isSetType, @@ -46,5 +45,5 @@ inputRegistry.set(type => { return isMapType(type); }, MapInputComponent); inputRegistry.set(type => { - return type.kind === ReflectionKind.class && getClassName(getClassType(type)) === 'UploadedFile'; + return type.kind === ReflectionKind.class && getClassName(type.classType) === 'UploadedFile'; }, BinaryInputComponent); diff --git a/packages/api-console-gui/src/app/utils.ts b/packages/api-console-gui/src/app/utils.ts index 811d9422e..a095baf37 100644 --- a/packages/api-console-gui/src/app/utils.ts +++ b/packages/api-console-gui/src/app/utils.ts @@ -2,7 +2,6 @@ import objectInspect from 'object-inspect'; import { getClassName } from '@deepkit/core'; import { - getClassType, getTypeJitContainer, isBackReferenceType, isReferenceType, @@ -20,7 +19,7 @@ export function isReferenceLike(type: Type): boolean { } function manualTypeStringify(type: Type): string | undefined { - if (type.kind === ReflectionKind.class && getClassName(getClassType(type)) === 'UploadedFile') return 'UploadedFile'; + if (type.kind === ReflectionKind.class && getClassName(type.classType) === 'UploadedFile') return 'UploadedFile'; //we are not interested in the methods if (type.kind === ReflectionKind.method || type.kind === ReflectionKind.methodSignature) return ''; return; diff --git a/packages/bson/src/bson-parser.ts b/packages/bson/src/bson-parser.ts index 2c6574ca3..230555337 100644 --- a/packages/bson/src/bson-parser.ts +++ b/packages/bson/src/bson-parser.ts @@ -159,7 +159,7 @@ export class BaseParser { return nodeBufferToArrayBuffer(b); } if (type && type.kind === ReflectionKind.class) { - const typedArrayConstructor = getClassType(type); + const typedArrayConstructor = type.classType; return new typedArrayConstructor(nodeBufferToArrayBuffer(b)); } diff --git a/packages/injector/src/injector.ts b/packages/injector/src/injector.ts index c6456048a..1306bdacc 100644 --- a/packages/injector/src/injector.ts +++ b/packages/injector/src/injector.ts @@ -609,7 +609,7 @@ export class Injector implements InjectorInterface { const destinationVar = compiler.reserveConst({ token: fromProvider.provide }); if (options.type.kind === ReflectionKind.class) { - const found = findModuleForConfig(getClassType(options.type), resolveDependenciesFrom); + const found = findModuleForConfig(options.type.classType, resolveDependenciesFrom); if (found) { return compiler.reserveVariable('fullConfig', getPathValue(found.module.getConfig(), found.path)); } @@ -629,14 +629,14 @@ export class Injector implements InjectorInterface { return compiler.reserveVariable('tagRegistry', this.buildContext.tagRegistry); } - if (options.type.kind === ReflectionKind.class && resolveDependenciesFrom[0] instanceof getClassType(options.type)) { + if (options.type.kind === ReflectionKind.class && resolveDependenciesFrom[0] instanceof options.type.classType) { return compiler.reserveConst(resolveDependenciesFrom[0], 'module'); } if (options.type.kind === ReflectionKind.class && isPrototypeOfBase(options.type.classType, Tag)) { const tokenVar = compiler.reserveVariable('token', options.type.classType); const resolvedVar = compiler.reserveVariable('tagResolved'); - const entries = this.buildContext.tagRegistry.resolve(getClassType(options.type)); + const entries = this.buildContext.tagRegistry.resolve(options.type.classType); const args: string[] = []; for (const entry of entries) { args.push(`${compiler.reserveConst(entry.module)}.injector.resolver(${compiler.reserveConst(getContainerToken(entry.tagProvider.provider.provide))}, scope, ${destinationVar})`); @@ -655,7 +655,7 @@ export class Injector implements InjectorInterface { const pickArguments = getPickArguments(options.type); if (pickArguments) { if (pickArguments[0].kind === ReflectionKind.class) { - const found = findModuleForConfig(getClassType(pickArguments[0]), resolveDependenciesFrom); + const found = findModuleForConfig(pickArguments[0].classType, resolveDependenciesFrom); if (found) { const fullConfig = compiler.reserveVariable('fullConfig', getPathValue(found.module.getConfig(), found.path)); let index = pickArguments[1]; @@ -778,24 +778,24 @@ export class Injector implements InjectorInterface { // } if (type.kind === ReflectionKind.class) { - const found = findModuleForConfig(getClassType(type), resolveDependenciesFrom); + const found = findModuleForConfig(type.l, resolveDependenciesFrom); if (found) return () => getPathValue(found.module.getConfig(), found.path); } if (type.kind === ReflectionKind.class && type.classType === TagRegistry) return () => this.buildContext.tagRegistry; - if (type.kind === ReflectionKind.class && resolveDependenciesFrom[0] instanceof getClassType(type)) { + if (type.kind === ReflectionKind.class && resolveDependenciesFrom[0] instanceof type.classType) { return () => resolveDependenciesFrom[0]; } if (type.kind === ReflectionKind.class && isPrototypeOfBase(type.classType, Tag)) { - const entries = this.buildContext.tagRegistry.resolve(getClassType(type)); + const entries = this.buildContext.tagRegistry.resolve(type.classType); const args: any[] = []; for (const entry of entries) { args.push(entry.module.injector!.resolver!(entry.tagProvider.provider.provide, scope)); } - return new (getClassType(type))(args); + return new (type.classType)(args); } if (type.kind === ReflectionKind.function && type.typeName === 'PartialFactory') { @@ -809,7 +809,7 @@ export class Injector implements InjectorInterface { const pickArguments = getPickArguments(type); if (pickArguments) { if (pickArguments[0].kind === ReflectionKind.class) { - const found = findModuleForConfig(getClassType(pickArguments[0]), resolveDependenciesFrom); + const found = findModuleForConfig(pickArguments[0].classType, resolveDependenciesFrom); if (found) { const fullConfig = getPathValue(found.module.getConfig(), found.path); let index = pickArguments[1]; @@ -1027,7 +1027,7 @@ export function partialFactory( } if (type.kind === ReflectionKind.class) { - const classType = getClassType(type); + const classType = type.classType; const reflectionClass = ReflectionClass.from(classType); const args: { name: string; resolve: (scope?: Scope) => ReturnType> }[] = []; diff --git a/packages/orm-browser-gui/src/app/registry.ts b/packages/orm-browser-gui/src/app/registry.ts index 4d47f1cbe..0b181a24e 100644 --- a/packages/orm-browser-gui/src/app/registry.ts +++ b/packages/orm-browser-gui/src/app/registry.ts @@ -43,7 +43,7 @@ inputRegistry.set(isMongoIdType, StringInputComponent); // return isMapType(type); // }, MapInputComponent); inputRegistry.set(type => { - return type.kind === ReflectionKind.class && getClassName(getClassType(type)) === 'UploadedFile'; + return type.kind === ReflectionKind.class && getClassName(type.classType) === 'UploadedFile'; }, BinaryInputComponent); @@ -81,5 +81,5 @@ cellRegistry.set(isMongoIdType, StringCellComponent); // return isMapType(type); // }, MapCellComponent); cellRegistry.set(type => { - return type.kind === ReflectionKind.class && getClassName(getClassType(type)) === 'UploadedFile'; + return type.kind === ReflectionKind.class && getClassName(type.classType) === 'UploadedFile'; }, BinaryCellComponent); diff --git a/packages/sql/src/platform/default-platform.ts b/packages/sql/src/platform/default-platform.ts index a65a7a40b..6abbfd1bb 100644 --- a/packages/sql/src/platform/default-platform.ts +++ b/packages/sql/src/platform/default-platform.ts @@ -130,7 +130,7 @@ export abstract class DefaultPlatform { addBinaryType(sqlType: string, size?: number, scale?: number) { this.addType((type: Type) => { - return type.kind === ReflectionKind.class && binaryTypes.includes(getClassType(type)); + return type.kind === ReflectionKind.class && binaryTypes.includes(type.classType); }, sqlType, size, scale); } diff --git a/packages/type-compiler/src/compiler.ts b/packages/type-compiler/src/compiler.ts index 5884ad2d1..bb1261593 100644 --- a/packages/type-compiler/src/compiler.ts +++ b/packages/type-compiler/src/compiler.ts @@ -1363,7 +1363,7 @@ export class ReflectionTransformer implements CustomTransformer { } } - if (!this.external.isEmbeddingExternalLibraryImport() && narrowed.heritageClauses) { + if (narrowed.heritageClauses) { for (const heritage of narrowed.heritageClauses) { if (heritage.token === SyntaxKind.ExtendsKeyword) { for (const extendType of heritage.types) { @@ -1871,7 +1871,8 @@ export class ReflectionTransformer implements CustomTransformer { if (isIdentifier(narrowed.exprName)) { const resolved = this.resolveDeclaration(narrowed.exprName); if (resolved && findSourceFile(resolved.declaration) !== this.sourceFile && resolved.importDeclaration) { - expression = this.resolveImportExpression(resolved.declaration, resolved.importDeclaration, narrowed.exprName, expression, program); + ensureImportIsEmitted(resolved.importDeclaration, narrowed.exprName); + // expression = this.resolveImportExpression(resolved.declaration, resolved.importDeclaration, narrowed.exprName, expression, program); } } program.pushOp(ReflectionOp.typeof, program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, expression))); @@ -2033,10 +2034,10 @@ 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 && hasSourceFile(importDeclaration)) { + /*if (!declaration && hasSourceFile(importDeclaration)) { sourceFile = importDeclaration.getSourceFile(); declaration = this.resolveImportSpecifier(typeName.escapedText, importDeclaration, sourceFile); - } + }*/ } if (declaration && declaration.kind === SyntaxKind.TypeParameter && declaration.parent.kind === SyntaxKind.TypeAliasDeclaration) { @@ -2074,8 +2075,7 @@ export class ReflectionTransformer implements CustomTransformer { } protected getExternalRuntimeTypeName(typeName: EntityName): Identifier { - const { module } = this.external.getEmbeddingExternalLibraryImport(); - return this.f.createIdentifier(`${getExternalRuntimeTypeName(module.packageId.name)}.${getNameAsString(typeName)}`); + return this.f.createIdentifier(this.nodeConverter.createExternalRuntimeTypePropertyAccessExpression(getNameAsString(typeName)).name.text); } protected getDeclarationVariableName(typeName: EntityName): Identifier { @@ -2087,15 +2087,14 @@ export class ReflectionTransformer implements CustomTransformer { protected resolveImportExpression(declaration: Node, importDeclaration: ImportDeclaration, typeName: Identifier, expression: Expression, program: CompilerProgram): Expression { ensureImportIsEmitted(importDeclaration, typeName); + if (!hasSourceFile(importDeclaration)) return expression; + // these will be inferred at runtime - if (isTypeAliasDeclaration(declaration) || isVariableDeclaration(declaration)) { - return expression; - } + if (isTypeAliasDeclaration(declaration) || isVariableDeclaration(declaration)) return expression; - // check if the referenced declaration has reflection disabled + // 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); @@ -2105,8 +2104,8 @@ export class ReflectionTransformer implements CustomTransformer { const isEmbeddingExternalLibraryImport = this.external.isEmbeddingExternalLibraryImport(); if (isEmbeddingExternalLibraryImport || (!builtType && this.external.shouldInlineExternalLibraryImport(importDeclaration, typeName, declarationReflection))) { - const { module } = this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, importDeclaration); - return this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName); + this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, importDeclaration); + return this.nodeConverter.createExternalRuntimeTypePropertyAccessExpression(getNameAsString(typeName)); // const newExpression = this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName); // return !isEmbeddingExternalLibraryImport && (isClassDeclaration(declaration) || isFunctionDeclaration(declaration)) // ? this.wrapWithAssignType(expression, newExpression) @@ -2216,7 +2215,8 @@ export class ReflectionTransformer implements CustomTransformer { if (isModuleDeclaration(declaration) && resolved.importDeclaration) { let expression: Expression = serializeEntityNameAsExpression(this.f, typeName); if (isIdentifier(typeName)) { - expression = this.resolveImportExpression(declaration, resolved.importDeclaration, typeName, expression, program) + ensureImportIsEmitted(resolved.importDeclaration, typeName); + // expression = this.resolveImportExpression(declaration, resolved.importDeclaration, typeName, expression, program) } //we can not infer from module declaration, so do `typeof T` in runtime @@ -2275,9 +2275,9 @@ export class ReflectionTransformer implements CustomTransformer { return; } - if (this.external.hasSourceFile(declarationSourceFile) && this.external.isEmbeddingExternalLibraryImport()) { + /*if (this.external.hasSourceFile(declarationSourceFile) && this.external.isEmbeddingExternalLibraryImport()) { this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration); - } else { + } else */{ const isGlobal = resolved.importDeclaration === undefined && declarationSourceFile.fileName !== this.sourceFile.fileName; const isFromImport = resolved.importDeclaration !== undefined; @@ -2310,9 +2310,21 @@ export class ReflectionTransformer implements CustomTransformer { } const reflection = this.findReflectionFromPath(found.fileName); + if (reflection.mode === 'never') { + if (this.external.shouldInlineExternalLibraryImport(resolved.importDeclaration, typeName, declarationReflection)) { + console.log('inline'); + this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration); + } else { + program.pushOp(ReflectionOp.any); + return; + } + } + + this.addImports.push({ identifier: runtimeTypeName, from: resolved.importDeclaration.moduleSpecifier }); + + /*const reflection = this.findReflectionFromPath(found.fileName); if (reflection.mode !== 'never') { this.addImports.push({ identifier: runtimeTypeName, from: resolved.importDeclaration.moduleSpecifier }); - return; } else { const builtType = isBuiltType(runtimeTypeName, found); if (!builtType) { @@ -2323,7 +2335,7 @@ export class ReflectionTransformer implements CustomTransformer { return; } } - } + }*/ } } else { //it's a reference type inside the same file. Make sure its type is reflected @@ -2342,7 +2354,7 @@ export class ReflectionTransformer implements CustomTransformer { } const index = program.pushStack( - program.forNode === declaration ? 0 : this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, this.getDeclarationVariableName(typeName)) + program.forNode === declaration ? 0 : this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, runtimeTypeName) ); if (type.typeArguments) { for (const argument of type.typeArguments) { @@ -2374,29 +2386,18 @@ export class ReflectionTransformer implements CustomTransformer { this.resolveTypeOnlyImport(typeName, program); return; } - - let body: Identifier | Expression = isIdentifier(typeName) ? typeName : this.createAccessorForEntityName(typeName); - if (resolved.importDeclaration && isIdentifier(typeName)) { - body = this.resolveImportExpression(resolved.declaration, resolved.importDeclaration, typeName, body, program); - } program.pushFrame(); if (type.typeArguments) { for (const typeArgument of type.typeArguments) { this.extractPackStructOfType(typeArgument, program); } } - /*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); - } - 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); - } + let body: Identifier | Expression = isIdentifier(typeName) ? typeName : this.createAccessorForEntityName(typeName); + /*if (resolved.importDeclaration && isIdentifier(typeName)) { + body = this.resolveImportExpression(resolved.declaration, resolved.importDeclaration, typeName, body, program); + }*/ + const index = program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, body)); + program.pushOp(isClassDeclaration(declaration) ? ReflectionOp.classReference : ReflectionOp.functionReference, index); program.popFrameImplicit(); } else if (isTypeParameterDeclaration(declaration)) { this.resolveTypeParameter(declaration, type, program); diff --git a/packages/type-compiler/src/external.ts b/packages/type-compiler/src/external.ts index 6e27ff491..97de5ea06 100644 --- a/packages/type-compiler/src/external.ts +++ b/packages/type-compiler/src/external.ts @@ -38,7 +38,7 @@ export class External { startEmbeddingExternalLibraryImport(value: ExternalLibraryImport): void { if (this.embeddingExternalLibraryImport) { - throw new Error('Already embedding module'); + throw new Error('Already embedding external library import'); } this.embeddingExternalLibraryImport = value; } @@ -70,7 +70,8 @@ export class External { 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 resolvedModule = this.resolver.resolveImport(importDeclaration); + if (!resolvedModule.isExternalLibraryImport || !resolvedModule.packageId) return false; const imports = config.options.inlineExternalLibraryImports?.[resolvedModule.packageId.name]; if (!imports) return false; if (imports === true) return true; diff --git a/packages/type-compiler/src/reflection-ast.ts b/packages/type-compiler/src/reflection-ast.ts index e5d1e3535..cce7d3bce 100644 --- a/packages/type-compiler/src/reflection-ast.ts +++ b/packages/type-compiler/src/reflection-ast.ts @@ -186,6 +186,11 @@ export class NodeConverter { ); } + createExternalRuntimeTypePropertyAccessExpression(name: string): PropertyAccessExpression { + const { module } = this.external.getEmbeddingExternalLibraryImport(); + return this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), name) + } + toExpression(node?: T): Expression { if (node === undefined) return this.f.createIdentifier('undefined'); @@ -210,8 +215,8 @@ export class NodeConverter { case SyntaxKind.Identifier: const name = getIdentifierName(node as Identifier); return this.external.isEmbeddingExternalLibraryImport() && !this.external.knownGlobalTypeNames.has(name) - ? this.f.createIdentifier(`${getExternalRuntimeTypeName(this.external.getEmbeddingExternalLibraryImport().module.packageId.name)}.${name}`) - : finish(node, this.f.createIdentifier(getRuntimeTypeName(name))); + ? this.createExternalRuntimeTypePropertyAccessExpression(name) + : finish(node, this.f.createIdentifier(name)); case SyntaxKind.StringLiteral: return finish(node, this.f.createStringLiteral((node as StringLiteral).text)); case SyntaxKind.NumericLiteral: diff --git a/packages/type-compiler/src/resolver.ts b/packages/type-compiler/src/resolver.ts index 20f37e1bf..e8df63886 100644 --- a/packages/type-compiler/src/resolver.ts +++ b/packages/type-compiler/src/resolver.ts @@ -74,6 +74,7 @@ export class Resolver { resolveExternalLibraryImport(importDeclaration: ImportDeclaration): Required { const resolvedModule = this.resolveImport(importDeclaration); if (!resolvedModule.packageId) { + // FIXME: packageId is undefined when module specifier text is `rxjs/operators` throw new Error('Missing package id for resolved module'); /*resolvedModule.packageId = { name: (importDeclaration.moduleSpecifier as StringLiteral).text.replace(/[^a-zA-Z0-9]+/g, '_'), 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 b559cb6d4..f7b028f53 100644 --- a/packages/type-compiler/tests/inline-external-library-imports.spec.ts +++ b/packages/type-compiler/tests/inline-external-library-imports.spec.ts @@ -637,12 +637,8 @@ __ɵΩrxjs.Subscribable = ['T', () => __ΩPartial, () => __ɵΩrxjs.Observer, 'o const __ΩExclude = ['T', 'U', 'l6!Re$!RPe#!e$"qk#%QRb!b"Pde"!p)y']; __ɵΩrxjs.Unsubscribable = ['unsubscribe', 'PP$1!My']; __ɵΩrxjs.SubscriptionLike = [() => __ɵΩrxjs.Unsubscribable, 'unsubscribe', 'closed', 'Pn!P$1")4#9My']; -function __assignType(fn, args) { - fn.__type = args; - return fn; -} const rxjs_1 = require("rxjs"); -const __ΩA = [() => __assignType(rxjs_1.Observable, __ɵΩrxjs.Observable), 'P#7!y']; +const __ΩA = [() => __ɵΩrxjs.Observable, 'P#7!y']; " `); }) @@ -679,19 +675,6 @@ test('class typeOf', () => { }) as TypeClass; 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); }) test('only a single type is transformed', () => { diff --git a/packages/type/src/default.ts b/packages/type/src/default.ts index b0507b3a5..b7095b5a0 100644 --- a/packages/type/src/default.ts +++ b/packages/type/src/default.ts @@ -72,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(getClassType(type))) return new (getClassType(type)); + if (binaryTypes.includes(type.classType)) return new type.classType; const result: any = {}; const types = resolveTypeMembers(type); diff --git a/packages/type/src/reference.ts b/packages/type/src/reference.ts index a728777fe..9fd42a141 100644 --- a/packages/type/src/reference.ts +++ b/packages/type/src/reference.ts @@ -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 getClassType(reflection.type) { + const Reference = reflection.type.kind === ReflectionKind.class ? class extends reflection.type.classType { } : class { }; diff --git a/packages/type/src/reflection/extends.ts b/packages/type/src/reflection/extends.ts index 81c9e0e99..376463ab2 100644 --- a/packages/type/src/reflection/extends.ts +++ b/packages/type/src/reflection/extends.ts @@ -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, getClassType(right)); + return isPrototypeOfBase(left.classType, right.classType); } return true; diff --git a/packages/type/src/reflection/processor.ts b/packages/type/src/reflection/processor.ts index 2163f5269..4d01e7128 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++, types: [] } as TypeClass; + let t = { kind: ReflectionKind.class, id: state.nominalId++, classType: Object, types: [] } as TypeClass; function add(member: Type) { if (member.kind === ReflectionKind.propertySignature) { @@ -669,8 +669,6 @@ export class Processor { if (args.length) t.arguments = args; t.typeArguments = program.typeParameters; - console.log('class', t); - this.pushType(t); break; } @@ -720,10 +718,10 @@ export class Processor { this.pushType({ kind: ReflectionKind.unknown }); break; } + const pack = external ? classOrFunction : classOrFunction.__type; - const runtimeType = external ? classOrFunction : classOrFunction.__type; - - if (!runtimeType) { + if (!classOrFunction.__type) { + console.log('unknown'); if (op === ReflectionOp.classReference) { this.pushType({ kind: ReflectionKind.class, classType: classOrFunction, typeArguments: inputs, types: [] }); } else if (op === ReflectionOp.functionReference) { @@ -732,7 +730,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(runtimeType, inputs, { inline: !directReference, reuseCached: directReference }); + const result = this.reflect(classOrFunction, inputs, { inline: !directReference, reuseCached: directReference }); if (directReference) program.directReturn = true; this.push(result, program); @@ -1193,6 +1191,7 @@ export class Processor { const p = isFunction(pOrFn) ? pOrFn() : pOrFn; // process.stdout.write(`inline ${pOrFn.toString()}\n`); if (p === undefined) { + console.log('unknown'); // console.log('inline with invalid reference', pOrFn.toString()); this.push({ kind: ReflectionKind.unknown }); } else if ('number' === typeof p) { @@ -1289,7 +1288,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) { diff --git a/packages/type/src/reflection/reflection.ts b/packages/type/src/reflection/reflection.ts index a68d6eb1c..4c48cb7d4 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 ? getClassType(this.type) : Object; + return this.type.kind === ReflectionKind.class ? this.type.classType : 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) ? getClassType(classTypeIn) : (classTypeIn as any)['prototype'] ? classTypeIn as ClassType : classTypeIn.constructor as ClassType; + const classType = isType(classTypeIn) ? (classTypeIn as TypeClass).classType : (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 914480023..855854ec3 100644 --- a/packages/type/src/reflection/type.ts +++ b/packages/type/src/reflection/type.ts @@ -8,17 +8,7 @@ * You should have received a copy of the MIT License along with this program. */ -import { - AbstractClassType, - arrayRemoveItem, - ClassType, - getClassName, - getParentClass, - indent, - isArray, - isClass, - isFunction, -} from '@deepkit/core'; +import { AbstractClassType, arrayRemoveItem, ClassType, getClassName, getParentClass, indent, isArray, isClass } from '@deepkit/core'; import { TypeNumberBrand } from '@deepkit/type-spec'; import { getProperty, ReceiveType, reflect, ReflectionClass, resolveReceiveType, toSignature } from './reflection.js'; import { isExtendable } from './extends.js'; @@ -79,8 +69,6 @@ export enum ReflectionKind { infer, callSignature, - - externalClass, } export type TypeDecorator = (annotations: Annotations, decorator: TypeObjectLiteral) => boolean; @@ -319,7 +307,6 @@ 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; @@ -341,8 +328,7 @@ export interface TypePromise extends TypeAnnotations { export interface TypeClass extends TypeAnnotations { kind: ReflectionKind.class, parent?: Type; - external?: boolean; - classType?: ClassType; // reference to the real class if available + classType: ClassType; description?: string; /** @@ -553,7 +539,7 @@ export function isType(entry: any): entry is Type { } export function isBinary(type: Type): boolean { - return type.kind === ReflectionKind.class && binaryTypes.includes(getClassType(type)); + return type.kind === ReflectionKind.class && binaryTypes.includes(type.classType); } export function isPrimitive(type: T): boolean { @@ -1344,9 +1330,6 @@ 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; } @@ -2281,9 +2264,6 @@ 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; } @@ -2498,8 +2478,6 @@ export function stringifyType(type: Type, stateIn: Partial 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 98d6fbd70..772f40ba9 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, getClassType, ReflectionKind, Type } from './reflection/type.js'; +import { binaryTypes, 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(getClassType(type)); + const classResult = this.classes.get(type.classType); if (classResult) return classResult; - if (type.classType === Set || type.classType === Map || binaryTypes.includes(getClassType(type))) return undefined; + if (type.classType === Set || type.classType === Map || binaryTypes.includes(type.classType)) return undefined; } return this.results[type.kind]; } diff --git a/packages/type/src/serializer.ts b/packages/type/src/serializer.ts index 00dee6451..ba08180cc 100644 --- a/packages/type/src/serializer.ts +++ b/packages/type/src/serializer.ts @@ -33,7 +33,7 @@ import { embeddedAnnotation, EmbeddedOptions, excludedAnnotation, - FindType, getClassType, + FindType, getConstructorProperties, getTypeJitContainer, getTypeObjectLiteralFromTypeClass, @@ -586,9 +586,9 @@ export class TemplateRegistry { get(type: Type): Template[] { if (type.kind === ReflectionKind.class) { - const classTemplates = this.classTemplates.get(getClassType(type)); + const classTemplates = this.classTemplates.get(type.classType); if (classTemplates && classTemplates.length) return classTemplates; - if (type.classType === Set || type.classType === Map || binaryTypes.includes(getClassType(type))) return []; + if (type.classType === Set || type.classType === Map || binaryTypes.includes(type.classType)) return []; } return this.templates[type.kind] ||= []; } diff --git a/packages/type/src/type-serialization.ts b/packages/type/src/type-serialization.ts index 49f439068..063f51958 100644 --- a/packages/type/src/type-serialization.ts +++ b/packages/type/src/type-serialization.ts @@ -2,7 +2,6 @@ import { entityAnnotation, EntityOptions, findMember, - getClassType, isSameType, isTypeIncluded, isWithAnnotations, @@ -346,14 +345,14 @@ function serialize(type: Type, state: SerializerState): SerializedTypeReference } case ReflectionKind.class: { const types = state.disableMethods ? type.types.filter(filterRemoveFunctions) : type.types; - const parent = getParentClass(getClassType(type)); + const parent = getParentClass(type.classType); let superClass: SerializedTypeReference | undefined = undefined; try { superClass = parent ? serialize(reflect(parent), state) : undefined; } catch { } - const classType = getClassName(getClassType(type)); + const classType = getClassName(type.classType); const globalObject: boolean = envGlobal && envGlobal[classType] === type.classType; Object.assign(result, { @@ -639,7 +638,7 @@ function deserialize(type: SerializedType | SerializedTypeReference, state: Dese } const classType = type.globalObject ? envGlobal[type.classType] : newClass - ? (type.superClass ? class extends getClassType(deserialize(type.superClass, state) as TypeClass) { + ? (type.superClass ? class extends (deserialize(type.superClass, state) as TypeClass).classType { 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 9e5e3edc9..8cbee6407 100644 --- a/packages/type/tests/type-serialization.spec.ts +++ b/packages/type/tests/type-serialization.spec.ts @@ -199,7 +199,7 @@ test('roundTrip class static', () => { { const type = roundTrip(); assertType(type, ReflectionKind.class); - expect(getClassName(getClassType(type))).toBe('MyClass'); + expect(getClassName(type.classType)).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(getClassType(type))).toBe('MyClass'); + expect(getClassName(type.classType)).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(getClassType(type))).toBe('MyModel'); + expect(getClassName(type.classType)).toBe('MyModel'); assertType(type.types[0], ReflectionKind.property); expect(type.types[0].name).toBe('sub'); assertType(type.types[0].type, ReflectionKind.class); - expect(getClassName(getClassType(type.types[0].type))).toBe('MyModel'); + expect(getClassName(type.types[0].type.classType)).toBe('MyModel'); }); test('circular with decorators', () => { @@ -289,12 +289,12 @@ test('circular with decorators', () => { const type = deserializeType(json); assertType(type, ReflectionKind.class); - expect(getClassName(getClassType(type))).toBe('MyModel'); + expect(getClassName(type.classType)).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(getClassType(type.types[0].type))).toBe('MyModel'); + expect(getClassName(type.types[0].type.classType)).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 edf51b02e..1c80ffe25 100644 --- a/packages/type/tests/typedarray.spec.ts +++ b/packages/type/tests/typedarray.spec.ts @@ -25,7 +25,7 @@ test('mapping', async () => { for (const property of classSchema.getProperties()) { assertType(property.type, ReflectionKind.class); - expect(binaryTypes.includes(getClassType(property.type))).toBe(true); + expect(binaryTypes.includes(property.type.classType)).toBe(true); expect(typeof (json as any)[property.getNameAsString()]).toBe('string'); expect((back as any)[property.getNameAsString()]).toBeInstanceOf(property.type.classType); }