@travetto/transformer 3.1.0-rc.2 → 3.1.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/transformer",
3
- "version": "3.1.0-rc.2",
3
+ "version": "3.1.0-rc.4",
4
4
  "description": "Functionality for AST transformations, with transformer registration, and general utils",
5
5
  "keywords": [
6
6
  "typescript",
@@ -24,7 +24,7 @@
24
24
  "directory": "module/transformer"
25
25
  },
26
26
  "dependencies": {
27
- "@travetto/manifest": "^3.1.0-rc.1",
27
+ "@travetto/manifest": "^3.1.0-rc.3",
28
28
  "tslib": "^2.5.0",
29
29
  "typescript": "^5.0.2"
30
30
  },
package/src/importer.ts CHANGED
@@ -2,7 +2,7 @@ import ts from 'typescript';
2
2
 
3
3
  import { PackageUtil, path } from '@travetto/manifest';
4
4
 
5
- import { AnyType, TransformResolver, ExternalType } from './resolver/types';
5
+ import { AnyType, TransformResolver, ManagedType } from './resolver/types';
6
6
  import { ImportUtil } from './util/import';
7
7
  import { CoreUtil } from './util/core';
8
8
  import { Import } from './types/shared';
@@ -128,11 +128,11 @@ export class ImportManager {
128
128
  */
129
129
  importFromResolved(...types: AnyType[]): void {
130
130
  for (const type of types) {
131
- if (type.key === 'external' && type.importName && type.importName !== this.#importName) {
131
+ if (type.key === 'managed' && type.importName && type.importName !== this.#importName) {
132
132
  this.importFile(type.importName);
133
133
  }
134
134
  switch (type.key) {
135
- case 'external':
135
+ case 'managed':
136
136
  case 'literal': this.importFromResolved(...type.typeArguments || []); break;
137
137
  case 'union':
138
138
  case 'tuple': this.importFromResolved(...type.subTypes || []); break;
@@ -217,7 +217,7 @@ export class ImportManager {
217
217
  /**
218
218
  * Get the identifier and import if needed
219
219
  */
220
- getOrImport(factory: ts.NodeFactory, type: ExternalType): ts.Identifier | ts.PropertyAccessExpression {
220
+ getOrImport(factory: ts.NodeFactory, type: ManagedType): ts.Identifier | ts.PropertyAccessExpression {
221
221
  if (type.importName === this.#importName) {
222
222
  return factory.createIdentifier(type.name!);
223
223
  } else {
@@ -33,7 +33,7 @@ const GLOBAL_SIMPLE: Record<string, Function> = {
33
33
  PromiseConstructor: Promise.constructor
34
34
  };
35
35
 
36
- type Category = 'void' | 'undefined' | 'concrete' | 'unknown' | 'tuple' | 'shape' | 'literal' | 'external' | 'union';
36
+ type Category = 'void' | 'undefined' | 'concrete' | 'unknown' | 'tuple' | 'shape' | 'literal' | 'managed' | 'union' | 'foreign';
37
37
 
38
38
  /**
39
39
  * Type categorizer, input for builder
@@ -53,7 +53,13 @@ export function TypeCategorize(resolver: TransformResolver, type: ts.Type): { ca
53
53
  } else if (objectFlags & ts.ObjectFlags.Reference && !CoreUtil.getSymbol(type)) { // Tuple type?
54
54
  return { category: 'tuple', type };
55
55
  } else if (objectFlags & ts.ObjectFlags.Anonymous) {
56
- return { category: 'shape', type };
56
+ const source = DeclarationUtil.getPrimaryDeclarationNode(type).getSourceFile();
57
+ const sourceFile = source.fileName;
58
+ if (sourceFile?.endsWith('.d.ts') && !resolver.isKnownFile(sourceFile)) {
59
+ return { category: 'foreign', type };
60
+ } else {
61
+ return { category: 'shape', type };
62
+ }
57
63
  } else if (objectFlags & (ts.ObjectFlags.Reference | ts.ObjectFlags.Class | ts.ObjectFlags.Interface)) {
58
64
  let resolvedType = type;
59
65
  if (CoreUtil.hasTarget(resolvedType)) {
@@ -66,14 +72,14 @@ export function TypeCategorize(resolver: TransformResolver, type: ts.Type): { ca
66
72
 
67
73
  const source = DeclarationUtil.getPrimaryDeclarationNode(resolvedType).getSourceFile();
68
74
  const sourceFile = source.fileName;
69
- if (sourceFile?.includes('@types/node/globals') || sourceFile?.includes('typescript/lib')) {
75
+ if (sourceFile?.includes('typescript/lib')) {
70
76
  return { category: 'literal', type };
71
77
  } else if (sourceFile?.endsWith('.d.ts') && !resolver.isKnownFile(sourceFile)) {
72
- return { category: 'unknown', type };
78
+ return { category: 'foreign', type: resolvedType };
73
79
  } else if (!resolvedType.isClass()) { // Not a real type
74
80
  return { category: 'shape', type: resolvedType };
75
81
  } else {
76
- return { category: 'external', type: resolvedType };
82
+ return { category: 'managed', type: resolvedType };
77
83
  }
78
84
  } else if (flags & (
79
85
  ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral |
@@ -142,12 +148,19 @@ export const TypeBuilder: {
142
148
  }
143
149
  }
144
150
  },
145
- external: {
151
+ foreign: {
152
+ build: (resolver, type) => {
153
+ const name = CoreUtil.getSymbol(type)?.getName();
154
+ const source = DeclarationUtil.getPrimaryDeclarationNode(type).getSourceFile();
155
+ return { key: 'foreign', name, source: source.fileName };
156
+ }
157
+ },
158
+ managed: {
146
159
  build: (resolver, type) => {
147
160
  const name = CoreUtil.getSymbol(type)?.getName();
148
161
  const importName = resolver.getTypeImportName(type)!;
149
162
  const tsTypeArguments = resolver.getAllTypeArguments(type);
150
- return { key: 'external', name, importName, tsTypeArguments };
163
+ return { key: 'managed', name, importName, tsTypeArguments };
151
164
  }
152
165
  },
153
166
  union: {
@@ -226,7 +239,7 @@ export const TypeBuilder: {
226
239
  importName = resolver.getFileImportName(path.resolve(base, importName));
227
240
  }
228
241
  }
229
- return { key: 'external', name, importName };
242
+ return { key: 'managed', name, importName };
230
243
  }
231
244
  }
232
245
  }
@@ -16,7 +16,7 @@ export class VisitCache {
16
16
  // Check for recursion
17
17
  switch (type?.key) {
18
18
  case 'shape':
19
- case 'external': {
19
+ case 'managed': {
20
20
  if (this.storage.has(tsType)) {
21
21
  const target = this.storage.get(tsType)!;
22
22
  if (target.key !== 'pointer') {
@@ -31,9 +31,9 @@ export interface Type<K extends string> {
31
31
  }
32
32
 
33
33
  /**
34
- * A type that is not defined in the scope of the given file
34
+ * A type that is not defined in the scope of the given file, but is importable from the project
35
35
  */
36
- export interface ExternalType extends Type<'external'> {
36
+ export interface ManagedType extends Type<'managed'> {
37
37
  /**
38
38
  * Location the type came from, for class references
39
39
  */
@@ -141,12 +141,27 @@ export interface PointerType extends Type<'pointer'> {
141
141
  target: Exclude<AnyType, PointerType>;
142
142
  }
143
143
 
144
+ /**
145
+ * Foreign type, outside of framework
146
+ */
147
+ export interface ForeignType extends Type<'foreign'> {
148
+ /**
149
+ * Identifier for type
150
+ */
151
+ name: string;
152
+
153
+ /**
154
+ * Primary source file
155
+ */
156
+ source: string;
157
+ }
158
+
144
159
  /**
145
160
  * Unknown type, should default to object
146
161
  */
147
162
  export interface UnknownType extends Type<'unknown'> { }
148
163
 
149
- export type AnyType = TupleType | ShapeType | UnionType | LiteralType | ExternalType | PointerType | UnknownType;
164
+ export type AnyType = TupleType | ShapeType | UnionType | LiteralType | ManagedType | PointerType | UnknownType | ForeignType;
150
165
 
151
166
  /**
152
167
  * Simple interface for checked methods
package/src/state.ts CHANGED
@@ -2,7 +2,7 @@ import ts from 'typescript';
2
2
 
3
3
  import { ManifestIndex, path } from '@travetto/manifest';
4
4
 
5
- import { ExternalType, AnyType } from './resolver/types';
5
+ import { ManagedType, AnyType } from './resolver/types';
6
6
  import { State, DecoratorMeta, Transformer, ModuleNameⲐ } from './types/visitor';
7
7
  import { SimpleResolver } from './resolver/service';
8
8
  import { ImportManager } from './importer';
@@ -53,7 +53,7 @@ export class TransformerState implements State {
53
53
  /**
54
54
  * Get or import the node or external type
55
55
  */
56
- getOrImport(type: ExternalType): ts.Identifier | ts.PropertyAccessExpression {
56
+ getOrImport(type: ManagedType): ts.Identifier | ts.PropertyAccessExpression {
57
57
  return this.#imports.getOrImport(this.factory, type);
58
58
  }
59
59
 
@@ -76,9 +76,9 @@ export class TransformerState implements State {
76
76
  /**
77
77
  * Resolve external type
78
78
  */
79
- resolveExternalType(node: ts.Node): ExternalType {
79
+ resolveManagedType(node: ts.Node): ManagedType {
80
80
  const resolved = this.resolveType(node);
81
- if (resolved.key !== 'external') {
81
+ if (resolved.key !== 'managed') {
82
82
  const file = node.getSourceFile().fileName;
83
83
  const src = this.#resolver.getFileImportName(file);
84
84
  throw new Error(`Unable to import non-external type: ${node.getText()} ${resolved.key}: ${src}`);
@@ -93,7 +93,7 @@ export class TransformerState implements State {
93
93
  const type = 'flags' in node ? this.resolveType(node) : node;
94
94
  switch (type.key) {
95
95
  case 'literal': return this.factory.createIdentifier(type.ctor!.name);
96
- case 'external': return this.getOrImport(type);
96
+ case 'managed': return this.getOrImport(type);
97
97
  case 'shape': return;
98
98
  }
99
99
  }
@@ -348,4 +348,12 @@ export class TransformerState implements State {
348
348
  }
349
349
  }
350
350
  }
351
+
352
+ /**
353
+ * Get import name for a given file
354
+ * @param file
355
+ */
356
+ getFileImportName(file: string): string {
357
+ return this.#resolver.getFileImportName(file);
358
+ }
351
359
  }