Skip to content

Commit f8b1505

Browse files
committed
improve
1 parent 6d88feb commit f8b1505

File tree

4 files changed

+243
-706
lines changed

4 files changed

+243
-706
lines changed

packages/type-compiler/src/compiler.ts

+70-32
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ export class ReflectionTransformer implements CustomTransformer {
975975
break;
976976
}
977977

978-
if (this.embedDeclarations.size === 0 && this.external.libraryImports.size === 0 && allCompiled) break;
978+
if (this.embedDeclarations.size === 0 && this.external.compileExternalLibraryImports.size === 0 && allCompiled) break;
979979

980980
for (const [node, d] of [...this.compileDeclarations.entries()]) {
981981
if (d.compiled) continue;
@@ -993,14 +993,14 @@ export class ReflectionTransformer implements CustomTransformer {
993993
}
994994
}
995995

996-
if (this.external.libraryImports.size) {
997-
for (const imports of this.external.libraryImports.values()) {
998-
for (const { declaration } of imports) {
996+
if (this.external.compileExternalLibraryImports.size) {
997+
for (const imports of this.external.compileExternalLibraryImports.values()) {
998+
for (const { declaration } of imports.values()) {
999999
this.compiledDeclarations.add(declaration);
10001000
}
10011001
}
1002-
const entries = Array.from(this.external.libraryImports.entries());
1003-
this.external.libraryImports.clear();
1002+
const entries = Array.from(this.external.compileExternalLibraryImports.entries());
1003+
this.external.compileExternalLibraryImports.clear();
10041004
for (const [library, imports] of entries) {
10051005
if (!this.external.embeddedLibraryVariables.has(library)) {
10061006
const objectLiteral = this.f.createObjectLiteralExpression();
@@ -1020,8 +1020,8 @@ export class ReflectionTransformer implements CustomTransformer {
10201020
this.external.embeddedLibraryVariables.add(library);
10211021
}
10221022

1023-
for (const value of imports) {
1024-
this.external.setEmbeddingExternalLibraryImport(value);
1023+
for (const value of imports.values()) {
1024+
this.external.startEmbeddingExternalLibraryImport(value);
10251025
newTopStatements.push(this.createProgramVarForExternalLibraryImport(value.declaration, value.name, value.sourceFile, value.module.packageId.name));
10261026
this.external.finishEmbeddingExternalLibraryImport();
10271027
}
@@ -1132,6 +1132,23 @@ export class ReflectionTransformer implements CustomTransformer {
11321132
newTopStatements.push(assignType);
11331133
}
11341134

1135+
if (this.tempResultIdentifier) {
1136+
newTopStatements.push(
1137+
this.f.createVariableStatement(
1138+
undefined,
1139+
this.f.createVariableDeclarationList(
1140+
[this.f.createVariableDeclaration(
1141+
this.tempResultIdentifier,
1142+
undefined,
1143+
undefined,
1144+
undefined
1145+
)],
1146+
ts.NodeFlags.None
1147+
)
1148+
)
1149+
);
1150+
}
1151+
11351152
if (newTopStatements.length) {
11361153
// we want to keep "use strict", or "use client", etc at the very top
11371154
const indexOfFirstLiteralExpression = this.sourceFile.statements.findIndex(v => isExpressionStatement(v) && isStringLiteral(v.expression));
@@ -1326,6 +1343,12 @@ export class ReflectionTransformer implements CustomTransformer {
13261343
const narrowed = node as ClassDeclaration | ClassExpression;
13271344
//class nodes have always their own program, so the start is always fresh, means we don't need a frame
13281345

1346+
if (this.external.isEmbeddingExternalLibraryImport()) {
1347+
const declaration = this.nodeConverter.convertClassToInterface(narrowed);
1348+
this.extractPackStructOfType(declaration, program);
1349+
break;
1350+
}
1351+
13291352
if (node) {
13301353
const members: ClassElement[] = [];
13311354

@@ -1673,6 +1696,10 @@ export class ReflectionTransformer implements CustomTransformer {
16731696
const narrowed = node as MethodSignature | MethodDeclaration | CallSignatureDeclaration | ConstructorTypeNode
16741697
| ConstructSignatureDeclaration | ConstructorDeclaration | ArrowFunction | FunctionExpression | FunctionTypeNode | FunctionDeclaration;
16751698

1699+
if(this.external.isEmbeddingExternalLibraryImport() && (isFunctionDeclaration(node) || isFunctionExpression(node) || isMethodDeclaration(node))) {
1700+
console.log(getNameAsString(narrowed.name));
1701+
}
1702+
16761703
const config = this.findReflectionConfig(narrowed, program);
16771704
if (config.mode === 'never') return;
16781705

@@ -2043,11 +2070,19 @@ export class ReflectionTransformer implements CustomTransformer {
20432070
// return node;
20442071
// }
20452072

2073+
protected getRuntimeTypeName(typeName: EntityName): Identifier {
2074+
return this.f.createIdentifier(getRuntimeTypeName(getNameAsString(typeName)));
2075+
}
2076+
2077+
protected getExternalRuntimeTypeName(typeName: EntityName): Identifier {
2078+
const { module } = this.external.getEmbeddingExternalLibraryImport();
2079+
return this.f.createIdentifier(`${getExternalRuntimeTypeName(module.packageId.name)}.${getNameAsString(typeName)}`);
2080+
}
2081+
20462082
protected getDeclarationVariableName(typeName: EntityName): Identifier {
2047-
const name = getNameAsString(typeName);
2048-
return this.external.isEmbeddingExternalLibraryImport() && !this.external.globalTypeNames.has(name)
2049-
? this.f.createIdentifier(`${getExternalRuntimeTypeName(this.external.getEmbeddingExternalLibraryImport().module.packageId.name)}.${name}`)
2050-
: this.f.createIdentifier(getRuntimeTypeName(name));
2083+
return this.external.isEmbeddingExternalLibraryImport() && !this.external.knownGlobalTypeNames.has(getNameAsString(typeName))
2084+
? this.getExternalRuntimeTypeName(typeName)
2085+
: this.getRuntimeTypeName(typeName);
20512086
}
20522087

20532088
protected resolveImportExpression(declaration: Node, importDeclaration: ImportDeclaration, typeName: Identifier, expression: Expression, program: CompilerProgram): Expression {
@@ -2063,18 +2098,18 @@ export class ReflectionTransformer implements CustomTransformer {
20632098
if (declarationReflection.mode !== 'never') {
20642099
const declarationSourceFile = importDeclaration.getSourceFile();
20652100

2066-
const runtimeTypeName = this.getDeclarationVariableName(typeName);
2101+
const runtimeTypeName = this.getRuntimeTypeName(typeName);
20672102

20682103
const builtType = isBuiltType(runtimeTypeName, declarationSourceFile);
20692104

20702105
const isEmbeddingExternalLibraryImport = this.external.isEmbeddingExternalLibraryImport();
20712106

20722107
if (isEmbeddingExternalLibraryImport || (!builtType && this.external.shouldInlineExternalLibraryImport(importDeclaration, typeName, declarationReflection))) {
2073-
const { module } = this.external.embedExternalLibraryImport(typeName, declaration, declarationSourceFile, importDeclaration);
2108+
const { module } = this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, importDeclaration);
2109+
const newExpression = this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName);
20742110
return !isEmbeddingExternalLibraryImport && (isClassDeclaration(declaration) || isFunctionDeclaration(declaration))
2075-
// TODO: figure out what to do with referenced classes/functions in external declaration files
2076-
? this.wrapWithAssignType(expression, this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName))
2077-
: this.f.createPropertyAccessExpression(this.f.createIdentifier(getExternalRuntimeTypeName(module.packageId.name)), typeName);
2111+
? this.wrapWithAssignType(expression, newExpression)
2112+
: newExpression
20782113
}
20792114
}
20802115

@@ -2180,6 +2215,7 @@ export class ReflectionTransformer implements CustomTransformer {
21802215
if (isModuleDeclaration(declaration) && resolved.importDeclaration) {
21812216
let expression: Expression = serializeEntityNameAsExpression(this.f, typeName);
21822217
if (isIdentifier(typeName)) {
2218+
console.log(2, getNameAsString(typeName));
21832219
expression = this.resolveImportExpression(declaration, resolved.importDeclaration, typeName, expression, program)
21842220
}
21852221

@@ -2228,8 +2264,7 @@ export class ReflectionTransformer implements CustomTransformer {
22282264
return;
22292265
}
22302266

2231-
const runtimeTypeName = this.getDeclarationVariableName(typeName)
2232-
// const runtimeTypeName = this.f.createIdentifier(getRuntimeTypeName(getNameAsString(typeName)));
2267+
const runtimeTypeName = this.getRuntimeTypeName(typeName);
22332268

22342269
//to break recursion, we track which declaration has already been compiled
22352270
if (!this.compiledDeclarations.has(declaration) && !this.compileDeclarations.has(declaration)) {
@@ -2240,18 +2275,14 @@ export class ReflectionTransformer implements CustomTransformer {
22402275
return;
22412276
}
22422277

2243-
if (this.external.hasSourceFile(declarationSourceFile)) {
2244-
if (this.external.isEmbeddingExternalLibraryImport()) {
2245-
this.external.embedExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration);
2246-
}
2278+
if (this.external.hasSourceFile(declarationSourceFile) && this.external.isEmbeddingExternalLibraryImport()) {
2279+
this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration);
22472280
} else {
22482281
const isGlobal = resolved.importDeclaration === undefined && declarationSourceFile.fileName !== this.sourceFile.fileName;
22492282
const isFromImport = resolved.importDeclaration !== undefined;
22502283

22512284
if (isGlobal) {
2252-
if (this.external.isEmbeddingExternalLibraryImport()) {
2253-
this.external.addGlobalType(getNameAsString(typeName));
2254-
}
2285+
this.external.knownGlobalTypeNames.add(getNameAsString(typeName));
22552286
this.embedDeclarations.set(declaration, {
22562287
name: typeName,
22572288
sourceFile: declarationSourceFile
@@ -2281,7 +2312,7 @@ export class ReflectionTransformer implements CustomTransformer {
22812312
const builtType = isBuiltType(runtimeTypeName, found);
22822313
if (!builtType) {
22832314
if (!this.external.shouldInlineExternalLibraryImport(resolved.importDeclaration, typeName, declarationReflection)) return;
2284-
this.external.embedExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration);
2315+
this.external.processExternalLibraryImport(typeName, declaration, declarationSourceFile, resolved.importDeclaration);
22852316
} else {
22862317
//check if the referenced file has reflection info emitted. if not, any is emitted for that reference
22872318
const reflection = this.findReflectionFromPath(found.fileName);
@@ -2310,7 +2341,7 @@ export class ReflectionTransformer implements CustomTransformer {
23102341
}
23112342

23122343
const index = program.pushStack(
2313-
program.forNode === declaration ? 0 : this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, runtimeTypeName)
2344+
program.forNode === declaration ? 0 : this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, this.getDeclarationVariableName(typeName))
23142345
);
23152346
if (type.typeArguments) {
23162347
for (const argument of type.typeArguments) {
@@ -2343,8 +2374,6 @@ export class ReflectionTransformer implements CustomTransformer {
23432374
return;
23442375
}
23452376

2346-
const isEmbeddingExternalLibraryImport = this.external.isEmbeddingExternalLibraryImport();
2347-
23482377
let body: Identifier | Expression = isIdentifier(typeName) ? typeName : this.createAccessorForEntityName(typeName);
23492378
if (resolved.importDeclaration && isIdentifier(typeName)) {
23502379
body = this.resolveImportExpression(resolved.declaration, resolved.importDeclaration, typeName, body, program);
@@ -2355,8 +2384,17 @@ export class ReflectionTransformer implements CustomTransformer {
23552384
this.extractPackStructOfType(typeArgument, program);
23562385
}
23572386
}
2358-
const index = program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, body));
2359-
program.pushOp(isClassDeclaration(declaration) ? ReflectionOp.classReference : ReflectionOp.functionReference, index);
2387+
if (this.external.isEmbeddingExternalLibraryImport()) {
2388+
if (isClassDeclaration(declaration)) {
2389+
program.pushOp(ReflectionOp.objectLiteral);
2390+
} else {
2391+
const index = program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, body));
2392+
program.pushOp(ReflectionOp.function, index);
2393+
}
2394+
} else {
2395+
const index = program.pushStack(this.f.createArrowFunction(undefined, undefined, [], undefined, undefined, body));
2396+
program.pushOp(isClassDeclaration(declaration) ? ReflectionOp.classReference : ReflectionOp.functionReference, index);
2397+
}
23602398
program.popFrameImplicit();
23612399
} else if (isTypeParameterDeclaration(declaration)) {
23622400
this.resolveTypeParameter(declaration, type, program);

packages/type-compiler/src/external.ts

+43-47
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,23 @@ export interface ExternalLibraryImport {
2020
}
2121

2222
export class External {
23-
public sourceFileNames = new Set<string>();
23+
protected sourceFileNames = new Set<string>();
2424

25-
public runtimeTypeNames = new Set<string>();
25+
public compileExternalLibraryImports = new Map<string, Map<string, ExternalLibraryImport>>;
2626

27-
public libraryImports = new Map<string, Set<ExternalLibraryImport>>;
27+
protected processedEntities = new Set<string>;
2828

2929
public embeddedLibraryVariables = new Set<string>();
3030

31-
public globalTypeNames = new Set<string>();
31+
public knownGlobalTypeNames = new Set<string>();
3232

3333
public sourceFile?: SourceFile;
3434

3535
protected embeddingExternalLibraryImport?: ExternalLibraryImport;
3636

3737
constructor(protected resolver: Resolver) {}
3838

39-
setEmbeddingExternalLibraryImport(value: ExternalLibraryImport): void {
39+
startEmbeddingExternalLibraryImport(value: ExternalLibraryImport): void {
4040
if (this.embeddingExternalLibraryImport) {
4141
throw new Error('Already embedding module');
4242
}
@@ -50,10 +50,6 @@ export class External {
5050
return this.embeddingExternalLibraryImport;
5151
}
5252

53-
addGlobalType(typeName: string) {
54-
this.globalTypeNames.add(typeName);
55-
}
56-
5753
isEmbeddingExternalLibraryImport(): boolean {
5854
return !!this.embeddingExternalLibraryImport;
5955
}
@@ -62,35 +58,6 @@ export class External {
6258
delete this.embeddingExternalLibraryImport;
6359
}
6460

65-
public hasExternalLibraryImport(
66-
entityName: EntityName,
67-
module: Required<ResolvedModuleFull> = this.getEmbeddingExternalLibraryImport().module,
68-
): boolean {
69-
const imports = this.libraryImports.get(module.packageId.name);
70-
if (!imports) return false;
71-
const typeName = getEntityName(entityName);
72-
return [...imports].some(d => getNameAsString(d.name) === typeName)
73-
}
74-
75-
public addExternalLibraryImport(name: EntityName, declaration: Node, sourceFile: SourceFile, module?: Required<ResolvedModuleFull>): ExternalLibraryImport {
76-
if (!module) {
77-
module = this.getEmbeddingExternalLibraryImport().module;
78-
}
79-
const imports = this.libraryImports.get(module.packageId.name) || new Set();
80-
const externalLibraryImport: ExternalLibraryImport = {
81-
name,
82-
declaration,
83-
sourceFile,
84-
module,
85-
}
86-
this.libraryImports.set(module.packageId.name, imports.add(externalLibraryImport));
87-
return externalLibraryImport;
88-
}
89-
90-
public addRuntimeTypeName(typeName: EntityName): void {
91-
this.runtimeTypeNames.add(getNameAsString(typeName));
92-
}
93-
9461
public addSourceFile(sourceFile: SourceFile): void {
9562
this.sourceFileNames.add(sourceFile.fileName);
9663
}
@@ -111,21 +78,50 @@ export class External {
11178
return imports.includes(typeName);
11279
}
11380

114-
public embedExternalLibraryImport(typeName: EntityName, declaration: Node, sourceFile: SourceFile, importDeclaration?: ImportDeclaration): ExternalLibraryImport {
115-
let externalLibraryImport: ExternalLibraryImport;
116-
if (importDeclaration) {
117-
const resolvedModule = this.resolver.resolveExternalLibraryImport(importDeclaration);
118-
externalLibraryImport = this.addExternalLibraryImport(typeName, declaration, sourceFile, resolvedModule);
119-
} else {
120-
externalLibraryImport = this.addExternalLibraryImport(typeName, declaration, sourceFile);
81+
public processExternalLibraryImport(typeName: EntityName, declaration: Node, sourceFile: SourceFile, importDeclaration?: ImportDeclaration): ExternalLibraryImport {
82+
const module = importDeclaration
83+
? this.resolver.resolveExternalLibraryImport(importDeclaration)
84+
: this.getEmbeddingExternalLibraryImport().module;
85+
86+
const entityName = getNameAsString(typeName);
87+
if (this.processedEntities.has(entityName)) {
88+
return {
89+
name: typeName,
90+
declaration,
91+
sourceFile,
92+
module,
93+
}
12194
}
12295

123-
this.addRuntimeTypeName(typeName);
96+
this.processedEntities.add(entityName);
97+
// const libraryFiles = this.processedExternalLibraryImports.get(module.packageId.name) || new Map();
98+
// const libraryFileEntities = libraryFiles.get(module.resolvedFileName) || new Set();
99+
// if (libraryFileEntities.has(entityName)) {
100+
// return {
101+
// name: typeName,
102+
// declaration,
103+
// sourceFile,
104+
// module,
105+
// }
106+
// }
107+
//
108+
// libraryFileEntities.add(entityName);
109+
// libraryFiles.set(module.resolvedFileName, libraryFileEntities);
110+
// this.processedExternalLibraryImports.set(module.packageId.name, libraryFiles);
111+
112+
const imports = this.compileExternalLibraryImports.get(module.packageId.name) || new Map<string, ExternalLibraryImport>();
113+
const externalLibraryImport: ExternalLibraryImport = {
114+
name: typeName,
115+
declaration,
116+
sourceFile,
117+
module,
118+
}
119+
this.compileExternalLibraryImports.set(module.packageId.name, imports.set(entityName, externalLibraryImport));
124120

125121
if (sourceFile.fileName !== this.sourceFile?.fileName) {
126122
this.addSourceFile(sourceFile);
127123
}
128124

129-
return externalLibraryImport;
125+
return externalLibraryImport!;
130126
}
131127
}

0 commit comments

Comments
 (0)