@travetto/transformer 3.0.0-rc.3 → 3.0.0-rc.6
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/README.md +7 -12
- package/__index__.ts +15 -0
- package/package.json +13 -6
- package/src/importer.ts +125 -35
- package/src/manager.ts +66 -0
- package/src/manifest-index.ts +29 -0
- package/src/register.ts +40 -11
- package/src/resolver/builder.ts +37 -37
- package/src/resolver/cache.ts +2 -2
- package/src/resolver/coerce.ts +103 -0
- package/src/resolver/service.ts +12 -5
- package/src/resolver/types.ts +6 -3
- package/src/state.ts +93 -61
- package/src/types/shared.ts +1 -1
- package/src/types/visitor.ts +7 -5
- package/src/util/core.ts +8 -6
- package/src/util/declaration.ts +1 -1
- package/src/util/decorator.ts +1 -1
- package/src/util/doc.ts +1 -1
- package/src/util/import.ts +17 -10
- package/src/util/literal.ts +3 -2
- package/src/util/log.ts +2 -4
- package/src/util/system.ts +31 -0
- package/src/visitor.ts +11 -30
- package/index.ts +0 -7
- package/src/util/index.ts +0 -6
- package/test-support/util.ts +0 -57
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
|
|
3
|
+
export class SystemUtil {
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate a random UUID
|
|
7
|
+
* @param len The length of the uuid to generate
|
|
8
|
+
*/
|
|
9
|
+
static uuid(len: number = 32): string {
|
|
10
|
+
const bytes = crypto.randomBytes(Math.ceil(len / 2));
|
|
11
|
+
// eslint-disable-next-line no-bitwise
|
|
12
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
|
13
|
+
// eslint-disable-next-line no-bitwise
|
|
14
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
15
|
+
return bytes.toString('hex').substring(0, len);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Naive hashing
|
|
20
|
+
*/
|
|
21
|
+
static naiveHash(text: string): number {
|
|
22
|
+
let hash = 5381;
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < text.length; i++) {
|
|
25
|
+
// eslint-disable-next-line no-bitwise
|
|
26
|
+
hash = (hash * 33) ^ text.charCodeAt(i);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return Math.abs(hash);
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/visitor.ts
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { createWriteStream } from 'fs';
|
|
3
|
-
|
|
4
|
-
import { ConsoleManager } from '@travetto/base/src/console';
|
|
5
|
-
import { AppCache } from '@travetto/boot';
|
|
1
|
+
import ts from 'typescript';
|
|
6
2
|
|
|
7
3
|
import { DecoratorMeta, TransformerType, NodeTransformer, TransformerSet, State, TransformPhase } from './types/visitor';
|
|
8
|
-
import { LogUtil } from './util/log';
|
|
9
4
|
import { CoreUtil } from './util/core';
|
|
10
5
|
|
|
11
6
|
/**
|
|
@@ -28,26 +23,24 @@ export class VisitorFactory<S extends State = State> {
|
|
|
28
23
|
return 'class';
|
|
29
24
|
} else if (ts.isParameter(node)) {
|
|
30
25
|
return 'parameter';
|
|
31
|
-
} else if (ts.isFunctionDeclaration(node) || (ts.isFunctionExpression(node) && !ts.isArrowFunction(node))) {
|
|
26
|
+
} else if ((ts.isFunctionDeclaration(node) && node.body) || (ts.isFunctionExpression(node) && !ts.isArrowFunction(node))) {
|
|
32
27
|
return 'function';
|
|
33
28
|
} else if (ts.isGetAccessor(node)) {
|
|
34
29
|
return 'getter';
|
|
35
30
|
} else if (ts.isSetAccessor(node)) {
|
|
36
31
|
return 'setter';
|
|
32
|
+
} else if (ts.isSourceFile(node)) {
|
|
33
|
+
return 'file';
|
|
37
34
|
}
|
|
38
35
|
}
|
|
39
36
|
|
|
40
37
|
#transformers = new Map<TransformerType, TransformerSet<S>>();
|
|
41
|
-
#logTarget: string;
|
|
42
38
|
#getState: (context: ts.TransformationContext, src: ts.SourceFile) => S;
|
|
43
|
-
#logger: Console | undefined;
|
|
44
39
|
|
|
45
40
|
constructor(
|
|
46
41
|
getState: (context: ts.TransformationContext, src: ts.SourceFile) => S,
|
|
47
|
-
transformers: NodeTransformer<S, TransformerType, ts.Node>[]
|
|
48
|
-
logTarget = 'compiler.log'
|
|
42
|
+
transformers: NodeTransformer<S, TransformerType, ts.Node>[]
|
|
49
43
|
) {
|
|
50
|
-
this.#logTarget = logTarget;
|
|
51
44
|
this.#getState = getState;
|
|
52
45
|
this.#init(transformers);
|
|
53
46
|
}
|
|
@@ -79,26 +72,16 @@ export class VisitorFactory<S extends State = State> {
|
|
|
79
72
|
}
|
|
80
73
|
}
|
|
81
74
|
|
|
82
|
-
get logger(): Console {
|
|
83
|
-
this.#logger ??= new console.Console({
|
|
84
|
-
stdout: createWriteStream(AppCache.toEntryName(this.#logTarget), { flags: 'a' }),
|
|
85
|
-
inspectOptions: { depth: 4 },
|
|
86
|
-
});
|
|
87
|
-
return this.#logger;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
75
|
/**
|
|
91
76
|
* Produce a visitor for a given a file
|
|
92
77
|
*/
|
|
93
78
|
visitor(): ts.TransformerFactory<ts.SourceFile> {
|
|
94
79
|
return (context: ts.TransformationContext) => (file: ts.SourceFile): ts.SourceFile => {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
onLog: (level, ctx, args) => c[level](level, ctx, ...LogUtil.collapseNodes(args))
|
|
99
|
-
});
|
|
80
|
+
if (!file.fileName.endsWith('.ts')) { // Skip all non-ts files
|
|
81
|
+
return file;
|
|
82
|
+
}
|
|
100
83
|
|
|
101
|
-
|
|
84
|
+
try {
|
|
102
85
|
const state = this.#getState(context, file);
|
|
103
86
|
let ret = this.visit(state, context, file);
|
|
104
87
|
|
|
@@ -106,7 +89,7 @@ export class VisitorFactory<S extends State = State> {
|
|
|
106
89
|
const changed = state.added.size;
|
|
107
90
|
let statements: ts.NodeArray<ts.Statement> | ts.Statement[] = ret.statements;
|
|
108
91
|
while (state.added.size) {
|
|
109
|
-
for (const [k, all] of [...state.added]) {
|
|
92
|
+
for (const [k, all] of [...state.added].sort(([idxA], [idxB]) => idxB - idxA)) {
|
|
110
93
|
const idx = k === -1 ? state.added.size : k;
|
|
111
94
|
statements = [
|
|
112
95
|
...statements.slice(0, idx),
|
|
@@ -125,12 +108,10 @@ export class VisitorFactory<S extends State = State> {
|
|
|
125
108
|
if (!(err instanceof Error)) {
|
|
126
109
|
throw err;
|
|
127
110
|
}
|
|
128
|
-
console
|
|
111
|
+
console!.error('Failed transforming', { error: `${err.message}\n${err.stack}`, file: file.fileName });
|
|
129
112
|
const out = new Error(`Failed transforming: ${file.fileName}: ${err.message}`);
|
|
130
113
|
out.stack = err.stack;
|
|
131
114
|
throw out;
|
|
132
|
-
} finally {
|
|
133
|
-
ConsoleManager.clear(); // Reset logging
|
|
134
115
|
}
|
|
135
116
|
};
|
|
136
117
|
}
|
package/index.ts
DELETED
package/src/util/index.ts
DELETED
package/test-support/util.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import * as ts from 'typescript';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
|
|
4
|
-
import { FsUtil, ScanFs } from '@travetto/boot';
|
|
5
|
-
import { Util } from '@travetto/base';
|
|
6
|
-
|
|
7
|
-
import { VisitorFactory, TransformerState, getAllTransformers } from '..';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Utils for testing transformers
|
|
11
|
-
*/
|
|
12
|
-
export class TransformerTestUtil {
|
|
13
|
-
/**
|
|
14
|
-
* Compile a single file from a folder
|
|
15
|
-
*/
|
|
16
|
-
static async compile(folder: string, file?: string): Promise<string> {
|
|
17
|
-
|
|
18
|
-
const tsconfigObj = await import('@travetto/boot/tsconfig.trv.json');
|
|
19
|
-
|
|
20
|
-
const prog = ts.createProgram({
|
|
21
|
-
options: ts.convertCompilerOptionsFromJson(tsconfigObj, '').options,
|
|
22
|
-
rootNames: (await ScanFs.scanDir({ testFile: f => f.startsWith('src/') && f.endsWith('.ts') }, folder))
|
|
23
|
-
.filter(x => x.stats?.isFile())
|
|
24
|
-
.filter(x => !file || x.file.endsWith(file))
|
|
25
|
-
.map(x => x.file),
|
|
26
|
-
});
|
|
27
|
-
const log = `${folder}/.trv_compiler.log`;
|
|
28
|
-
|
|
29
|
-
await FsUtil.unlinkRecursive(log);
|
|
30
|
-
|
|
31
|
-
const transformers =
|
|
32
|
-
(await ScanFs.scanDir({ testFile: f => f.startsWith('support/transformer') }, folder))
|
|
33
|
-
.filter(x => x.stats?.isFile())
|
|
34
|
-
.map(x => import(x.file).then(getAllTransformers));
|
|
35
|
-
|
|
36
|
-
const visitor = new VisitorFactory(
|
|
37
|
-
(ctx, src) => new TransformerState(src, ctx.factory, prog.getTypeChecker()),
|
|
38
|
-
(await Promise.all(transformers)).flat(),
|
|
39
|
-
log
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
const out = await new Promise<string>(res => {
|
|
43
|
-
prog.emit(prog.getSourceFile(`src/${file}`), (__, data) => res(data), undefined, false,
|
|
44
|
-
{ before: [visitor.visitor()] }
|
|
45
|
-
);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
await Util.wait('1s'); // Wait for file buffer to sync
|
|
49
|
-
try {
|
|
50
|
-
console.info(readFileSync(log, 'utf8'));
|
|
51
|
-
} catch { }
|
|
52
|
-
|
|
53
|
-
await FsUtil.unlinkRecursive(log);
|
|
54
|
-
|
|
55
|
-
return out;
|
|
56
|
-
}
|
|
57
|
-
}
|