ts-const-value-transformer 0.5.1 → 0.6.0
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/CHANGELOG.md +10 -0
- package/README.md +18 -1
- package/dist/createPortalTransformer.d.mts +13 -0
- package/dist/createPortalTransformer.mjs +56 -10
- package/dist/createTransformer.d.mts +2 -1
- package/dist/createTransformer.mjs +2 -2
- package/dist/loader.d.mts +2 -6
- package/dist/loader.mjs +7 -5
- package/dist/transform.d.mts +4 -4
- package/dist/transform.mjs +40 -43
- package/dist/version.d.mts +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.6.0
|
|
4
|
+
|
|
5
|
+
- Remove skipping satisfies expression
|
|
6
|
+
- Accept `undefined` for `context` and remove dependencies for `context`
|
|
7
|
+
- Fix referring `ts` instance and add `ts` parameter for printSource
|
|
8
|
+
- Add cache to createPortalTransformer
|
|
9
|
+
- Add `recreateProgramOnTransformCount` option for PortalTransformer
|
|
10
|
+
- Fix to use `createPortalTransformerSync` for webpack loader
|
|
11
|
+
- Search tsconfig before loading
|
|
12
|
+
|
|
3
13
|
## v0.5.1
|
|
4
14
|
|
|
5
15
|
- Fix missing for handling `ignoreFiles` for `createTransformer` (used from ts-loader, etc.)
|
package/README.md
CHANGED
|
@@ -279,7 +279,24 @@ See [Transform options](#transform-options).
|
|
|
279
279
|
Creates 'portal transformer', which can be used the transformer easily from the code which does not use TypeScript Compiler API.
|
|
280
280
|
The return object has `transform` method with signature: `(content: string, fileName: string, sourceMap?: string | RawSourceMap | null, options?: TransformOptions) => [newSource: string, newSourceMap: RawSourceMap | undefined]`. You can call to transform TypeScript source code. (Note that this API does not transpile to JavaScript; the output code is still TypeScript code.)
|
|
281
281
|
|
|
282
|
-
`CreatePortalTransformerOptions` has
|
|
282
|
+
`CreatePortalTransformerOptions` has a following signature. Also, `ignoreFiles` of `TransformOptions` can be used.
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
interface CreatePortalTransformerOptions extends TransformOptions {
|
|
286
|
+
/** Path to tsconfig.json. If omitted, `tsconfig.json` will be used. */
|
|
287
|
+
project?: string;
|
|
288
|
+
/** Package path to `typescript` or `typescript` namespace object. */
|
|
289
|
+
typescript?: string | typeof tsNamespace;
|
|
290
|
+
/** The current directory for file search. Also affects to `project` option. */
|
|
291
|
+
cwd?: string;
|
|
292
|
+
/**
|
|
293
|
+
* Speficies the count. When the transformation count reaches this value, `program` instance will be recreated (and count will be reset).
|
|
294
|
+
* This is useful if the project is big and out-of-memory occurs during transformation, but the process may be slower.
|
|
295
|
+
* If 0 or `undefined`, recreation will not be performed.
|
|
296
|
+
*/
|
|
297
|
+
recreateProgramOnTransformCount?: number;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
283
300
|
|
|
284
301
|
If `Promise` cannot be used for some reason, use `createPortalTransformerSync` instead.
|
|
285
302
|
|
|
@@ -2,15 +2,28 @@ import type { RawSourceMap } from 'source-map';
|
|
|
2
2
|
import type * as tsNamespace from 'typescript';
|
|
3
3
|
import { type TransformOptions } from './transform.mjs';
|
|
4
4
|
export interface CreatePortalTransformerOptions extends TransformOptions {
|
|
5
|
+
/** Path to tsconfig.json. If omitted, `tsconfig.json` will be used. */
|
|
5
6
|
project?: string;
|
|
7
|
+
/** Package path to `typescript` or `typescript` namespace object. */
|
|
6
8
|
typescript?: string | typeof tsNamespace;
|
|
9
|
+
/** The current directory for file search. Also affects to `project` option. */
|
|
7
10
|
cwd?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Speficies the count. When the transformation count reaches this value, `program` instance will be recreated (and count will be reset).
|
|
13
|
+
* This is useful if the project is big and out-of-memory occurs during transformation, but the process may be slower.
|
|
14
|
+
* If 0 or `undefined`, recreation will not be performed.
|
|
15
|
+
*/
|
|
16
|
+
recreateProgramOnTransformCount?: number;
|
|
8
17
|
}
|
|
9
18
|
export interface PortalTransformer {
|
|
10
19
|
/** The `typescript` namespace object */
|
|
11
20
|
readonly ts: typeof tsNamespace;
|
|
12
21
|
/** Active `Program` instance for the transformer */
|
|
13
22
|
readonly program: tsNamespace.Program;
|
|
23
|
+
/** Clears transformed cache. */
|
|
24
|
+
clearCache(): void;
|
|
25
|
+
/** Forces `program` recreation. The transformation count for `recreateProgramOnTransformCount` will also be resetted. */
|
|
26
|
+
recreateProgram(): void;
|
|
14
27
|
/**
|
|
15
28
|
* Performs transformation.
|
|
16
29
|
* @param content Base source code. If null, uses loaded source code in the TS project.
|
|
@@ -4,12 +4,29 @@ import * as path from 'path';
|
|
|
4
4
|
import createTransformer from './createTransformer.mjs';
|
|
5
5
|
import { getIgnoreFilesFunction, printSourceWithMap, } from './transform.mjs';
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
|
+
function optionsToString(options) {
|
|
8
|
+
return JSON.stringify(options, (key, value) => {
|
|
9
|
+
if (typeof value === 'function' || value instanceof RegExp) {
|
|
10
|
+
return value.toString();
|
|
11
|
+
}
|
|
12
|
+
if (key === 'typescript' && typeof value === 'object' && value != null) {
|
|
13
|
+
return '[object typescript]';
|
|
14
|
+
}
|
|
15
|
+
return value;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
7
18
|
function createPortalTransformerImpl(options, ts) {
|
|
8
19
|
const project = options.project ?? 'tsconfig.json';
|
|
9
20
|
const ignoreFiles = getIgnoreFilesFunction(options.ignoreFiles);
|
|
10
21
|
const cwd = options.cwd ?? process.cwd();
|
|
22
|
+
const recreateProgramOnTransformCount = options.recreateProgramOnTransformCount ?? 0;
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
24
|
+
const foundConfigPath = ts.findConfigFile(cwd, ts.sys.fileExists, project);
|
|
25
|
+
if (foundConfigPath == null) {
|
|
26
|
+
throw new Error(`[ts-const-value-transformer] Unable to load tsconfig file (effective name = '${project}')`);
|
|
27
|
+
}
|
|
11
28
|
const getCurrentDirectory = () => cwd;
|
|
12
|
-
const config = ts.getParsedCommandLineOfConfigFile(
|
|
29
|
+
const config = ts.getParsedCommandLineOfConfigFile(foundConfigPath, void 0, {
|
|
13
30
|
fileExists: fs.existsSync,
|
|
14
31
|
getCurrentDirectory,
|
|
15
32
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
@@ -25,16 +42,37 @@ function createPortalTransformerImpl(options, ts) {
|
|
|
25
42
|
},
|
|
26
43
|
});
|
|
27
44
|
if (!config) {
|
|
28
|
-
throw new Error(`[ts-const-value-transformer] Unable to load tsconfig file (effective name = '${
|
|
45
|
+
throw new Error(`[ts-const-value-transformer] Unable to load tsconfig file (effective name = '${foundConfigPath}')`);
|
|
29
46
|
}
|
|
30
|
-
|
|
47
|
+
let program = ts.createProgram({
|
|
31
48
|
options: config.options,
|
|
32
49
|
rootNames: config.fileNames,
|
|
33
50
|
});
|
|
34
|
-
|
|
51
|
+
let transformationCount = 0;
|
|
52
|
+
const recreateProgram = () => {
|
|
53
|
+
const oldProgram = program;
|
|
54
|
+
program = ts.createProgram({
|
|
55
|
+
options: config.options,
|
|
56
|
+
rootNames: config.fileNames,
|
|
57
|
+
oldProgram,
|
|
58
|
+
});
|
|
59
|
+
instance.program = program;
|
|
60
|
+
transformationCount = 0;
|
|
61
|
+
};
|
|
62
|
+
const cache = new Map();
|
|
63
|
+
const instance = {
|
|
35
64
|
ts,
|
|
36
65
|
program,
|
|
66
|
+
clearCache: () => cache.clear(),
|
|
67
|
+
recreateProgram,
|
|
37
68
|
transform: (content, fileName, sourceMap, individualOptions) => {
|
|
69
|
+
const individualOptionsJson = optionsToString(individualOptions ?? {});
|
|
70
|
+
const cachedData = cache.get(fileName);
|
|
71
|
+
if (cachedData &&
|
|
72
|
+
cachedData.content === content &&
|
|
73
|
+
cachedData.optJson === individualOptionsJson) {
|
|
74
|
+
return cachedData.result;
|
|
75
|
+
}
|
|
38
76
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
39
77
|
const rawSourceMap = typeof sourceMap === 'string'
|
|
40
78
|
? JSON.parse(sourceMap)
|
|
@@ -42,30 +80,38 @@ function createPortalTransformerImpl(options, ts) {
|
|
|
42
80
|
if (ignoreFiles(fileName)) {
|
|
43
81
|
return [content, rawSourceMap];
|
|
44
82
|
}
|
|
83
|
+
transformationCount++;
|
|
84
|
+
if (recreateProgramOnTransformCount > 0 &&
|
|
85
|
+
transformationCount >= recreateProgramOnTransformCount) {
|
|
86
|
+
recreateProgram();
|
|
87
|
+
}
|
|
45
88
|
const sourceFile = program.getSourceFile(fileName);
|
|
46
89
|
if (!sourceFile) {
|
|
47
90
|
return [content, rawSourceMap];
|
|
48
91
|
}
|
|
49
92
|
// If input content is changed, replace it
|
|
50
|
-
if (content != null && sourceFile.
|
|
93
|
+
if (content != null && sourceFile.text !== content) {
|
|
51
94
|
sourceFile.update(content, {
|
|
52
95
|
span: { start: 0, length: sourceFile.end },
|
|
53
96
|
newLength: content.length,
|
|
54
97
|
});
|
|
98
|
+
sourceFile.text = content;
|
|
55
99
|
}
|
|
56
100
|
const transformer = createTransformer(program, {
|
|
57
101
|
options: { ...options, ...individualOptions, ts },
|
|
58
102
|
});
|
|
59
|
-
const
|
|
60
|
-
const transformedSource =
|
|
103
|
+
const transformResult = ts.transform(sourceFile, [transformer], program.getCompilerOptions());
|
|
104
|
+
const transformedSource = transformResult.transformed[0];
|
|
61
105
|
// If unchanged, return base file as-is
|
|
62
106
|
if (transformedSource === sourceFile) {
|
|
63
|
-
return [content ?? sourceFile.
|
|
107
|
+
return [content ?? sourceFile.text, rawSourceMap];
|
|
64
108
|
}
|
|
65
|
-
const
|
|
66
|
-
|
|
109
|
+
const result = printSourceWithMap(transformedSource, fileName, rawSourceMap, ts);
|
|
110
|
+
cache.set(fileName, { content, optJson: individualOptionsJson, result });
|
|
111
|
+
return result;
|
|
67
112
|
},
|
|
68
113
|
};
|
|
114
|
+
return instance;
|
|
69
115
|
}
|
|
70
116
|
/**
|
|
71
117
|
* Creates the new portal transformer instance for the TS project.
|
|
@@ -3,7 +3,8 @@ import { type TransformOptions } from './transform.mjs';
|
|
|
3
3
|
interface Config {
|
|
4
4
|
options?: TransformOptions;
|
|
5
5
|
}
|
|
6
|
+
export type TransformerFactory = (context?: ts.TransformationContext) => (sourceFile: ts.SourceFile) => ts.SourceFile;
|
|
6
7
|
export default function createTransformer(program: ts.Program, config?: Config, extras?: {
|
|
7
8
|
ts?: typeof ts;
|
|
8
|
-
}):
|
|
9
|
+
}): TransformerFactory;
|
|
9
10
|
export {};
|
|
@@ -9,12 +9,12 @@ extras) {
|
|
|
9
9
|
...(extras?.ts && { ts: extras?.ts }),
|
|
10
10
|
};
|
|
11
11
|
const ignoreFiles = getIgnoreFilesFunction(options.ignoreFiles);
|
|
12
|
-
return (context) => {
|
|
12
|
+
return ((context) => {
|
|
13
13
|
return (sourceFile) => {
|
|
14
14
|
if (ignoreFiles(sourceFile.fileName)) {
|
|
15
15
|
return sourceFile;
|
|
16
16
|
}
|
|
17
17
|
return transformSource(sourceFile, program, context, options);
|
|
18
18
|
};
|
|
19
|
-
};
|
|
19
|
+
});
|
|
20
20
|
}
|
package/dist/loader.d.mts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import type * as tsNamespace from 'typescript';
|
|
2
1
|
import type * as webpack from 'webpack';
|
|
3
|
-
import type
|
|
4
|
-
export
|
|
5
|
-
project?: string;
|
|
6
|
-
typescript?: string | typeof tsNamespace;
|
|
7
|
-
}
|
|
2
|
+
import { type CreatePortalTransformerOptions } from './createPortalTransformer.mjs';
|
|
3
|
+
export type TsConstValueTransformerLoaderOptions = CreatePortalTransformerOptions;
|
|
8
4
|
declare const loader: webpack.LoaderDefinitionFunction<TsConstValueTransformerLoaderOptions | undefined>;
|
|
9
5
|
export default loader;
|
package/dist/loader.mjs
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import * as path from 'path';
|
|
2
|
-
import
|
|
2
|
+
import { createPortalTransformerSync, } from './createPortalTransformer.mjs';
|
|
3
3
|
const transformerMap = new Map();
|
|
4
4
|
const loader = function (content, sourceMap) {
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions, @typescript-eslint/strict-boolean-expressions
|
|
6
|
+
this.cacheable && this.cacheable();
|
|
5
7
|
this.async();
|
|
6
|
-
void (
|
|
8
|
+
void Promise.resolve().then(() => {
|
|
7
9
|
try {
|
|
8
10
|
const options = this.getOptions() || {};
|
|
9
11
|
const project = options.project ?? 'tsconfig.json';
|
|
10
12
|
let transformer = transformerMap.get(project);
|
|
11
13
|
if (!transformer) {
|
|
12
|
-
transformer =
|
|
13
|
-
...options,
|
|
14
|
+
transformer = createPortalTransformerSync({
|
|
14
15
|
cwd: path.dirname(this.resourcePath),
|
|
16
|
+
...options,
|
|
15
17
|
});
|
|
16
18
|
transformerMap.set(project, transformer);
|
|
17
19
|
}
|
|
@@ -21,6 +23,6 @@ const loader = function (content, sourceMap) {
|
|
|
21
23
|
catch (e) {
|
|
22
24
|
this.callback(e);
|
|
23
25
|
}
|
|
24
|
-
})
|
|
26
|
+
});
|
|
25
27
|
};
|
|
26
28
|
export default loader;
|
package/dist/transform.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as sourceMap from 'source-map';
|
|
2
|
-
import * as ts from 'typescript';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
3
|
export interface TransformOptions {
|
|
4
4
|
/** `typescript` namespace object */
|
|
5
5
|
ts?: typeof ts;
|
|
@@ -36,6 +36,6 @@ export interface TransformOptions {
|
|
|
36
36
|
ignoreFiles?: ReadonlyArray<string | RegExp> | ((fileName: string) => boolean);
|
|
37
37
|
}
|
|
38
38
|
export declare function getIgnoreFilesFunction(ignoreFiles: TransformOptions['ignoreFiles']): (fileName: string) => boolean;
|
|
39
|
-
export declare function transformSource(sourceFile: ts.SourceFile, program: ts.Program, context: ts.TransformationContext, options?: TransformOptions): ts.SourceFile;
|
|
40
|
-
export declare function printSource(sourceFile: ts.SourceFile): string;
|
|
41
|
-
export declare function printSourceWithMap(sourceFile: ts.SourceFile, originalSourceName: string, startOfSourceMap?: sourceMap.RawSourceMap): [string, sourceMap.RawSourceMap];
|
|
39
|
+
export declare function transformSource(sourceFile: ts.SourceFile, program: ts.Program, context: ts.TransformationContext | undefined, options?: TransformOptions): ts.SourceFile;
|
|
40
|
+
export declare function printSource(sourceFile: ts.SourceFile, tsInstance?: typeof ts): string;
|
|
41
|
+
export declare function printSourceWithMap(sourceFile: ts.SourceFile, originalSourceName: string, startOfSourceMap?: sourceMap.RawSourceMap, tsInstance?: typeof ts): [string, sourceMap.RawSourceMap];
|
package/dist/transform.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as sourceMap from 'source-map';
|
|
2
|
-
import * as
|
|
2
|
+
import * as tsNamespace from 'typescript';
|
|
3
3
|
const SYMBOL_ORIGINAL_NODE = Symbol('originalNode');
|
|
4
4
|
function assignDefaultValues(options = {}) {
|
|
5
5
|
return {
|
|
6
6
|
// avoid using spread syntax to override `undefined` (not missing) values
|
|
7
|
-
ts: options.ts ??
|
|
7
|
+
ts: options.ts ?? tsNamespace,
|
|
8
8
|
hoistProperty: options.hoistProperty ?? true,
|
|
9
9
|
hoistEnumValues: options.hoistEnumValues ?? true,
|
|
10
10
|
hoistExternalValues: options.hoistExternalValues ?? true,
|
|
@@ -40,17 +40,15 @@ export function getIgnoreFilesFunction(ignoreFiles) {
|
|
|
40
40
|
}
|
|
41
41
|
////////////////////////////////////////////////////////////////////////////////
|
|
42
42
|
export function transformSource(sourceFile, program, context, options) {
|
|
43
|
-
|
|
43
|
+
const requiredOptions = assignDefaultValues(options);
|
|
44
|
+
return requiredOptions.ts.visitEachChild(sourceFile, (node) => visitNodeChildren(node, sourceFile, sourceFile, program, requiredOptions), context);
|
|
44
45
|
}
|
|
45
|
-
function visitNodeChildren(node, parent, sourceFile, program,
|
|
46
|
-
const
|
|
46
|
+
function visitNodeChildren(node, parent, sourceFile, program, options) {
|
|
47
|
+
const ts = options.ts;
|
|
48
|
+
const newNode = visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options);
|
|
47
49
|
if (newNode[SYMBOL_ORIGINAL_NODE]) {
|
|
48
50
|
return newNode;
|
|
49
51
|
}
|
|
50
|
-
// skip children for satisifes expression
|
|
51
|
-
if (ts.isSatisfiesExpression(newNode)) {
|
|
52
|
-
return newNode;
|
|
53
|
-
}
|
|
54
52
|
// skip statements which would not have 'value' expressions
|
|
55
53
|
if (ts.isInterfaceDeclaration(newNode) ||
|
|
56
54
|
ts.isTypeAliasDeclaration(newNode) ||
|
|
@@ -59,9 +57,9 @@ function visitNodeChildren(node, parent, sourceFile, program, context, options)
|
|
|
59
57
|
ts.isTypeOnlyExportDeclaration(newNode)) {
|
|
60
58
|
return newNode;
|
|
61
59
|
}
|
|
62
|
-
return ts.visitEachChild(newNode, (node) => visitNodeChildren(node, newNode, sourceFile, program,
|
|
60
|
+
return ts.visitEachChild(newNode, (node) => visitNodeChildren(node, newNode, sourceFile, program, options), void 0);
|
|
63
61
|
}
|
|
64
|
-
function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program,
|
|
62
|
+
function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options) {
|
|
65
63
|
const ts = options.ts;
|
|
66
64
|
if (ts.isCallLikeExpression(node)) {
|
|
67
65
|
if (!ts.isExpression(node) ||
|
|
@@ -107,12 +105,11 @@ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, context,
|
|
|
107
105
|
return node;
|
|
108
106
|
}
|
|
109
107
|
if (!options.hoistExternalValues &&
|
|
110
|
-
isExternalReference(node, program, options.externalNames)) {
|
|
108
|
+
isExternalReference(node, program, options.externalNames, ts)) {
|
|
111
109
|
return node;
|
|
112
110
|
}
|
|
113
111
|
if (!options.unsafeHoistAsExpresion &&
|
|
114
|
-
(hasAsExpression(node,
|
|
115
|
-
hasParentAsExpression(parent, context, ts))) {
|
|
112
|
+
(hasAsExpression(node, ts) || hasParentAsExpression(parent, ts))) {
|
|
116
113
|
return node;
|
|
117
114
|
}
|
|
118
115
|
if (!options.unsafeHoistWritableValues) {
|
|
@@ -130,35 +127,33 @@ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, context,
|
|
|
130
127
|
return node;
|
|
131
128
|
}
|
|
132
129
|
if (type.isStringLiteral()) {
|
|
133
|
-
newNode =
|
|
130
|
+
newNode = ts.factory.createStringLiteral(type.value);
|
|
134
131
|
}
|
|
135
132
|
else if (type.isNumberLiteral()) {
|
|
136
133
|
if (type.value < 0) {
|
|
137
|
-
newNode =
|
|
134
|
+
newNode = ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, ts.factory.createNumericLiteral(-type.value));
|
|
138
135
|
}
|
|
139
136
|
else {
|
|
140
|
-
newNode =
|
|
137
|
+
newNode = ts.factory.createNumericLiteral(type.value);
|
|
141
138
|
}
|
|
142
139
|
}
|
|
143
140
|
else if (flags & ts.TypeFlags.BigIntLiteral) {
|
|
144
|
-
newNode =
|
|
141
|
+
newNode = ts.factory.createBigIntLiteral(typeChecker.typeToString(type));
|
|
145
142
|
}
|
|
146
143
|
else if (flags & ts.TypeFlags.BooleanLiteral) {
|
|
147
144
|
const text = typeChecker.typeToString(type);
|
|
148
145
|
newNode =
|
|
149
|
-
text === 'true'
|
|
150
|
-
? context.factory.createTrue()
|
|
151
|
-
: context.factory.createFalse();
|
|
146
|
+
text === 'true' ? ts.factory.createTrue() : ts.factory.createFalse();
|
|
152
147
|
}
|
|
153
148
|
else if (flags & ts.TypeFlags.Null) {
|
|
154
|
-
newNode =
|
|
149
|
+
newNode = ts.factory.createNull();
|
|
155
150
|
}
|
|
156
151
|
else if (flags & ts.TypeFlags.Undefined) {
|
|
157
152
|
if (options.useUndefinedSymbolForUndefinedValue) {
|
|
158
|
-
newNode =
|
|
153
|
+
newNode = ts.factory.createIdentifier('undefined');
|
|
159
154
|
}
|
|
160
155
|
else {
|
|
161
|
-
newNode =
|
|
156
|
+
newNode = ts.factory.createVoidZero();
|
|
162
157
|
}
|
|
163
158
|
}
|
|
164
159
|
else {
|
|
@@ -185,7 +180,8 @@ function isEnumIdentifier(node, program, tsInstance) {
|
|
|
185
180
|
const type = typeChecker.getTypeAtLocation(node);
|
|
186
181
|
return (type.getFlags() & ts.TypeFlags.EnumLiteral) !== 0;
|
|
187
182
|
}
|
|
188
|
-
function isExternalReference(node, program, externalNames) {
|
|
183
|
+
function isExternalReference(node, program, externalNames, tsInstance) {
|
|
184
|
+
const ts = tsInstance;
|
|
189
185
|
const typeChecker = program.getTypeChecker();
|
|
190
186
|
const nodeSym = typeChecker.getSymbolAtLocation(node);
|
|
191
187
|
let nodeFrom = nodeSym?.getDeclarations()?.[0];
|
|
@@ -238,7 +234,7 @@ function isExternalReference(node, program, externalNames) {
|
|
|
238
234
|
function isAsConstExpression(node) {
|
|
239
235
|
return node.type.getText() === 'const';
|
|
240
236
|
}
|
|
241
|
-
function hasAsExpression(node,
|
|
237
|
+
function hasAsExpression(node, tsInstance) {
|
|
242
238
|
const ts = tsInstance;
|
|
243
239
|
// including 'as const'
|
|
244
240
|
if (ts.isAsExpression(node)) {
|
|
@@ -247,13 +243,13 @@ function hasAsExpression(node, context, tsInstance) {
|
|
|
247
243
|
let found = false;
|
|
248
244
|
ts.visitEachChild(node, (node) => {
|
|
249
245
|
if (!found) {
|
|
250
|
-
found = hasAsExpression(node,
|
|
246
|
+
found = hasAsExpression(node, ts);
|
|
251
247
|
}
|
|
252
248
|
return node;
|
|
253
|
-
},
|
|
249
|
+
}, void 0);
|
|
254
250
|
return found;
|
|
255
251
|
}
|
|
256
|
-
function hasParentAsExpression(node,
|
|
252
|
+
function hasParentAsExpression(node, tsInstance) {
|
|
257
253
|
const ts = tsInstance;
|
|
258
254
|
if (node == null) {
|
|
259
255
|
return false;
|
|
@@ -264,11 +260,11 @@ function hasParentAsExpression(node, context, tsInstance) {
|
|
|
264
260
|
}
|
|
265
261
|
if (ts.isPropertyAccessExpression(node) ||
|
|
266
262
|
ts.isElementAccessExpression(node)) {
|
|
267
|
-
if (hasAsExpression(node.expression,
|
|
263
|
+
if (hasAsExpression(node.expression, ts)) {
|
|
268
264
|
return true;
|
|
269
265
|
}
|
|
270
266
|
}
|
|
271
|
-
return hasParentAsExpression(node.parent,
|
|
267
|
+
return hasParentAsExpression(node.parent, ts);
|
|
272
268
|
}
|
|
273
269
|
function hasPureAnnotation(node, sourceFile, tsInstance) {
|
|
274
270
|
const ts = tsInstance;
|
|
@@ -408,19 +404,19 @@ function isUndefinedIdentifier(node, parent, program, tsInstance) {
|
|
|
408
404
|
return false;
|
|
409
405
|
}
|
|
410
406
|
if (type.isUnionOrIntersection() ||
|
|
411
|
-
!(type.getFlags() &
|
|
407
|
+
!(type.getFlags() & tsInstance.TypeFlags.Undefined)) {
|
|
412
408
|
return false;
|
|
413
409
|
}
|
|
414
410
|
return true;
|
|
415
411
|
}
|
|
416
412
|
////////////////////////////////////////////////////////////////////////////////
|
|
417
|
-
export function printSource(sourceFile) {
|
|
418
|
-
return printSourceImpl(sourceFile)[0];
|
|
413
|
+
export function printSource(sourceFile, tsInstance) {
|
|
414
|
+
return printSourceImpl(tsInstance, sourceFile)[0];
|
|
419
415
|
}
|
|
420
|
-
export function printSourceWithMap(sourceFile, originalSourceName, startOfSourceMap) {
|
|
416
|
+
export function printSourceWithMap(sourceFile, originalSourceName, startOfSourceMap, tsInstance) {
|
|
421
417
|
const generator = new sourceMap.SourceMapGenerator(startOfSourceMap);
|
|
422
418
|
generator.setSourceContent(originalSourceName, sourceFile.getFullText());
|
|
423
|
-
return printSourceImpl(sourceFile, originalSourceName, generator);
|
|
419
|
+
return printSourceImpl(tsInstance, sourceFile, originalSourceName, generator);
|
|
424
420
|
}
|
|
425
421
|
function positionToLineAndColumn(sourceFile, pos, generatedDiff) {
|
|
426
422
|
let line = 0;
|
|
@@ -434,16 +430,17 @@ function positionToLineAndColumn(sourceFile, pos, generatedDiff) {
|
|
|
434
430
|
}
|
|
435
431
|
return { line, column: pos - lastLinePos + generatedDiff };
|
|
436
432
|
}
|
|
437
|
-
function printSourceImpl(sourceFile, originalSourceName, mapGenerator) {
|
|
433
|
+
function printSourceImpl(tsInstance, sourceFile, originalSourceName, mapGenerator) {
|
|
434
|
+
const ts = tsInstance ?? tsNamespace;
|
|
438
435
|
const printer = ts.createPrinter({ removeComments: true });
|
|
439
|
-
const r = printNode(printer, sourceFile.getFullText(), sourceFile, sourceFile, { pos: 0, diff: 0, lastLine: 0 }, originalSourceName, mapGenerator);
|
|
436
|
+
const r = printNode(ts, printer, sourceFile.getFullText(), sourceFile, sourceFile, { pos: 0, diff: 0, lastLine: 0 }, originalSourceName, mapGenerator);
|
|
440
437
|
return [r, mapGenerator?.toJSON()];
|
|
441
438
|
}
|
|
442
|
-
function printNode(printer, baseSource, sourceFile, node, posContext, originalSourceName, mapGenerator) {
|
|
439
|
+
function printNode(tsInstance, printer, baseSource, sourceFile, node, posContext, originalSourceName, mapGenerator) {
|
|
443
440
|
const originalNode = node[SYMBOL_ORIGINAL_NODE];
|
|
444
441
|
if (originalNode) {
|
|
445
|
-
let result = printer.printNode(
|
|
446
|
-
const comments =
|
|
442
|
+
let result = printer.printNode(tsInstance.EmitHint.Unspecified, node, sourceFile);
|
|
443
|
+
const comments = tsInstance.getSyntheticTrailingComments(node);
|
|
447
444
|
if (comments) {
|
|
448
445
|
for (const comment of comments) {
|
|
449
446
|
result += ` /*${comment.text}*/`;
|
|
@@ -477,7 +474,7 @@ function printNode(printer, baseSource, sourceFile, node, posContext, originalSo
|
|
|
477
474
|
let output = '';
|
|
478
475
|
let headPrinted = false;
|
|
479
476
|
let lastChildPos = 0;
|
|
480
|
-
|
|
477
|
+
tsInstance.visitEachChild(node, (child) => {
|
|
481
478
|
if (!headPrinted) {
|
|
482
479
|
headPrinted = true;
|
|
483
480
|
if (child.pos > node.pos) {
|
|
@@ -493,7 +490,7 @@ function printNode(printer, baseSource, sourceFile, node, posContext, originalSo
|
|
|
493
490
|
addMappingForCurrent();
|
|
494
491
|
posContext.pos = child.pos;
|
|
495
492
|
}
|
|
496
|
-
output += printNode(printer, baseSource, sourceFile, child, posContext, originalSourceName, mapGenerator);
|
|
493
|
+
output += printNode(tsInstance, printer, baseSource, sourceFile, child, posContext, originalSourceName, mapGenerator);
|
|
497
494
|
lastChildPos = child.end;
|
|
498
495
|
return child;
|
|
499
496
|
}, void 0);
|
package/dist/version.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "0.
|
|
1
|
+
declare const _default: "0.6.0";
|
|
2
2
|
export default _default;
|
package/dist/version.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '0.
|
|
1
|
+
export default '0.6.0';
|