@esportsplus/typescript 0.27.5 → 0.28.1
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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ts } from '../index.js';
|
|
2
2
|
import imports from './imports.js';
|
|
3
|
+
const DIRECTORY_SEPARATOR = /\\/g;
|
|
3
4
|
function applyImports(code, file, intents) {
|
|
4
5
|
for (let i = 0, n = intents.length; i < n; i++) {
|
|
5
6
|
let intent = intents[i];
|
|
@@ -43,6 +44,24 @@ function applyPrepend(code, file, prepend) {
|
|
|
43
44
|
}
|
|
44
45
|
return code.slice(0, position) + prepend.join('\n') + code.slice(position);
|
|
45
46
|
}
|
|
47
|
+
function createUpdatedProgram(originalProgram, fileName, newCode) {
|
|
48
|
+
let options = originalProgram.getCompilerOptions(), originalHost = ts.createCompilerHost(options), originalGetSourceFile = originalHost.getSourceFile.bind(originalHost), originalReadFile = originalHost.readFile.bind(originalHost);
|
|
49
|
+
originalHost.getSourceFile = (name, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
50
|
+
if (name === fileName ||
|
|
51
|
+
name.replace(DIRECTORY_SEPARATOR, '/') === fileName.replace(DIRECTORY_SEPARATOR, '/')) {
|
|
52
|
+
return ts.createSourceFile(name, newCode, languageVersion, true);
|
|
53
|
+
}
|
|
54
|
+
return originalGetSourceFile(name, languageVersion, onError, shouldCreateNewSourceFile);
|
|
55
|
+
};
|
|
56
|
+
originalHost.readFile = (name) => {
|
|
57
|
+
if (name === fileName ||
|
|
58
|
+
name.replace(DIRECTORY_SEPARATOR, '/') === fileName.replace(DIRECTORY_SEPARATOR, '/')) {
|
|
59
|
+
return newCode;
|
|
60
|
+
}
|
|
61
|
+
return originalReadFile(name);
|
|
62
|
+
};
|
|
63
|
+
return ts.createProgram(originalProgram.getRootFileNames(), options, originalHost, originalProgram);
|
|
64
|
+
}
|
|
46
65
|
function hasPattern(code, patterns) {
|
|
47
66
|
for (let i = 0, n = patterns.length; i < n; i++) {
|
|
48
67
|
if (code.indexOf(patterns[i]) !== -1) {
|
|
@@ -117,34 +136,42 @@ const transform = (plugins, code, file, program, shared) => {
|
|
|
117
136
|
if (plugins.length === 0) {
|
|
118
137
|
return { changed: false, code, sourceFile: file };
|
|
119
138
|
}
|
|
120
|
-
let currentCode = code, currentFile = file;
|
|
139
|
+
let currentCode = code, currentFile = file, currentProgram = program, fileName = file.fileName, transformed = false;
|
|
121
140
|
for (let i = 0, n = plugins.length; i < n; i++) {
|
|
122
141
|
let plugin = plugins[i];
|
|
123
142
|
if (plugin.patterns && !hasPattern(currentCode, plugin.patterns)) {
|
|
124
143
|
continue;
|
|
125
144
|
}
|
|
126
145
|
let { imports, prepend, replacements } = plugin.transform({
|
|
127
|
-
checker:
|
|
146
|
+
checker: currentProgram.getTypeChecker(),
|
|
128
147
|
code: currentCode,
|
|
129
|
-
program,
|
|
148
|
+
program: currentProgram,
|
|
130
149
|
shared,
|
|
131
150
|
sourceFile: currentFile
|
|
132
151
|
});
|
|
152
|
+
let pluginChanged = false;
|
|
133
153
|
if (replacements?.length) {
|
|
134
154
|
currentCode = applyIntents(currentCode, currentFile, replacements);
|
|
135
|
-
currentFile = ts.createSourceFile(
|
|
155
|
+
currentFile = ts.createSourceFile(fileName, currentCode, currentFile.languageVersion, true);
|
|
156
|
+
pluginChanged = true;
|
|
136
157
|
}
|
|
137
158
|
if (prepend?.length) {
|
|
138
159
|
currentCode = applyPrepend(currentCode, currentFile, prepend);
|
|
139
|
-
currentFile = ts.createSourceFile(
|
|
160
|
+
currentFile = ts.createSourceFile(fileName, currentCode, currentFile.languageVersion, true);
|
|
161
|
+
pluginChanged = true;
|
|
140
162
|
}
|
|
141
163
|
if (imports?.length) {
|
|
142
164
|
currentCode = applyImports(currentCode, currentFile, imports);
|
|
143
|
-
currentFile = ts.createSourceFile(
|
|
165
|
+
currentFile = ts.createSourceFile(fileName, currentCode, currentFile.languageVersion, true);
|
|
166
|
+
pluginChanged = true;
|
|
167
|
+
}
|
|
168
|
+
if (pluginChanged) {
|
|
169
|
+
transformed = true;
|
|
170
|
+
currentProgram = createUpdatedProgram(currentProgram, fileName, currentCode);
|
|
144
171
|
}
|
|
145
172
|
}
|
|
146
173
|
return {
|
|
147
|
-
changed:
|
|
174
|
+
changed: transformed,
|
|
148
175
|
code: currentCode,
|
|
149
176
|
sourceFile: currentFile
|
|
150
177
|
};
|
|
@@ -46,7 +46,7 @@ const includes = (checker, node, pkg, symbolName) => {
|
|
|
46
46
|
imports.set(pkg, names);
|
|
47
47
|
}
|
|
48
48
|
if (names.has(node.text)) {
|
|
49
|
-
let symbol = checker
|
|
49
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
50
50
|
if (symbol) {
|
|
51
51
|
let declarations = symbol.getDeclarations();
|
|
52
52
|
if (declarations && declarations.length > 0) {
|
|
@@ -68,7 +68,7 @@ const includes = (checker, node, pkg, symbolName) => {
|
|
|
68
68
|
}
|
|
69
69
|
return true;
|
|
70
70
|
}
|
|
71
|
-
let symbol = checker
|
|
71
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
72
72
|
if (!symbol) {
|
|
73
73
|
return false;
|
|
74
74
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "ICJR",
|
|
3
3
|
"bin": {
|
|
4
|
+
"esportsplus-tsc": "./bin/tsc",
|
|
5
|
+
"esportsplus-tsc-alias": "./bin/tsc-alias",
|
|
4
6
|
"tsc": "./bin/tsc",
|
|
5
7
|
"tsc-alias": "./bin/tsc-alias"
|
|
6
8
|
},
|
|
@@ -37,7 +39,7 @@
|
|
|
37
39
|
},
|
|
38
40
|
"type": "module",
|
|
39
41
|
"types": "build/index.d.ts",
|
|
40
|
-
"version": "0.
|
|
42
|
+
"version": "0.28.1",
|
|
41
43
|
"scripts": {
|
|
42
44
|
"build": "tsc && tsc-alias",
|
|
43
45
|
"-": "-"
|
|
@@ -10,6 +10,9 @@ type CoordinatorResult = {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
const DIRECTORY_SEPARATOR = /\\/g;
|
|
14
|
+
|
|
15
|
+
|
|
13
16
|
function applyImports(code: string, file: ts.SourceFile, intents: ImportIntent[]): string {
|
|
14
17
|
for (let i = 0, n = intents.length; i < n; i++) {
|
|
15
18
|
let intent = intents[i];
|
|
@@ -73,6 +76,51 @@ function applyPrepend(code: string, file: ts.SourceFile, prepend: string[]): str
|
|
|
73
76
|
return code.slice(0, position) + prepend.join('\n') + code.slice(position);
|
|
74
77
|
}
|
|
75
78
|
|
|
79
|
+
function createUpdatedProgram(
|
|
80
|
+
originalProgram: ts.Program,
|
|
81
|
+
fileName: string,
|
|
82
|
+
newCode: string
|
|
83
|
+
): ts.Program {
|
|
84
|
+
let options = originalProgram.getCompilerOptions(),
|
|
85
|
+
originalHost = ts.createCompilerHost(options),
|
|
86
|
+
originalGetSourceFile = originalHost.getSourceFile.bind(originalHost),
|
|
87
|
+
originalReadFile = originalHost.readFile.bind(originalHost);
|
|
88
|
+
|
|
89
|
+
originalHost.getSourceFile = (
|
|
90
|
+
name: string,
|
|
91
|
+
languageVersion: ts.ScriptTarget,
|
|
92
|
+
onError?: (message: string) => void,
|
|
93
|
+
shouldCreateNewSourceFile?: boolean
|
|
94
|
+
): ts.SourceFile | undefined => {
|
|
95
|
+
if (
|
|
96
|
+
name === fileName ||
|
|
97
|
+
name.replace(DIRECTORY_SEPARATOR, '/') === fileName.replace(DIRECTORY_SEPARATOR, '/')
|
|
98
|
+
) {
|
|
99
|
+
return ts.createSourceFile(name, newCode, languageVersion, true);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return originalGetSourceFile(name, languageVersion, onError, shouldCreateNewSourceFile);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
originalHost.readFile = (name: string): string | undefined => {
|
|
106
|
+
if (
|
|
107
|
+
name === fileName ||
|
|
108
|
+
name.replace(DIRECTORY_SEPARATOR, '/') === fileName.replace(DIRECTORY_SEPARATOR, '/')
|
|
109
|
+
) {
|
|
110
|
+
return newCode;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return originalReadFile(name);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
return ts.createProgram(
|
|
117
|
+
originalProgram.getRootFileNames(),
|
|
118
|
+
options,
|
|
119
|
+
originalHost,
|
|
120
|
+
originalProgram
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
76
124
|
function hasPattern(code: string, patterns: string[]): boolean {
|
|
77
125
|
for (let i = 0, n = patterns.length; i < n; i++) {
|
|
78
126
|
if (code.indexOf(patterns[i]) !== -1) {
|
|
@@ -174,7 +222,7 @@ function replaceReverse(code: string, replacements: Replacement[]): string {
|
|
|
174
222
|
|
|
175
223
|
/**
|
|
176
224
|
* Transform source through all plugins sequentially.
|
|
177
|
-
* Each plugin receives fresh AST with accurate positions.
|
|
225
|
+
* Each plugin receives fresh AST and TypeChecker with accurate positions.
|
|
178
226
|
*/
|
|
179
227
|
const transform = (
|
|
180
228
|
plugins: Plugin[],
|
|
@@ -188,7 +236,10 @@ const transform = (
|
|
|
188
236
|
}
|
|
189
237
|
|
|
190
238
|
let currentCode = code,
|
|
191
|
-
currentFile = file
|
|
239
|
+
currentFile = file,
|
|
240
|
+
currentProgram = program,
|
|
241
|
+
fileName = file.fileName,
|
|
242
|
+
transformed = false;
|
|
192
243
|
|
|
193
244
|
for (let i = 0, n = plugins.length; i < n; i++) {
|
|
194
245
|
let plugin = plugins[i];
|
|
@@ -198,46 +249,57 @@ const transform = (
|
|
|
198
249
|
}
|
|
199
250
|
|
|
200
251
|
let { imports, prepend, replacements } = plugin.transform({
|
|
201
|
-
checker:
|
|
252
|
+
checker: currentProgram.getTypeChecker(),
|
|
202
253
|
code: currentCode,
|
|
203
|
-
program,
|
|
254
|
+
program: currentProgram,
|
|
204
255
|
shared,
|
|
205
256
|
sourceFile: currentFile
|
|
206
257
|
});
|
|
207
258
|
|
|
259
|
+
let pluginChanged = false;
|
|
260
|
+
|
|
208
261
|
if (replacements?.length) {
|
|
209
262
|
currentCode = applyIntents(currentCode, currentFile, replacements);
|
|
210
263
|
currentFile = ts.createSourceFile(
|
|
211
|
-
|
|
264
|
+
fileName,
|
|
212
265
|
currentCode,
|
|
213
266
|
currentFile.languageVersion,
|
|
214
267
|
true
|
|
215
268
|
);
|
|
269
|
+
pluginChanged = true;
|
|
216
270
|
}
|
|
217
271
|
|
|
218
272
|
if (prepend?.length) {
|
|
219
273
|
currentCode = applyPrepend(currentCode, currentFile, prepend);
|
|
220
274
|
currentFile = ts.createSourceFile(
|
|
221
|
-
|
|
275
|
+
fileName,
|
|
222
276
|
currentCode,
|
|
223
277
|
currentFile.languageVersion,
|
|
224
278
|
true
|
|
225
279
|
);
|
|
280
|
+
pluginChanged = true;
|
|
226
281
|
}
|
|
227
282
|
|
|
228
283
|
if (imports?.length) {
|
|
229
284
|
currentCode = applyImports(currentCode, currentFile, imports);
|
|
230
285
|
currentFile = ts.createSourceFile(
|
|
231
|
-
|
|
286
|
+
fileName,
|
|
232
287
|
currentCode,
|
|
233
288
|
currentFile.languageVersion,
|
|
234
289
|
true
|
|
235
290
|
);
|
|
291
|
+
pluginChanged = true;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Rebuild program with updated source so next plugin gets valid checker
|
|
295
|
+
if (pluginChanged) {
|
|
296
|
+
transformed = true;
|
|
297
|
+
currentProgram = createUpdatedProgram(currentProgram, fileName, currentCode);
|
|
236
298
|
}
|
|
237
299
|
}
|
|
238
300
|
|
|
239
301
|
return {
|
|
240
|
-
changed:
|
|
302
|
+
changed: transformed,
|
|
241
303
|
code: currentCode,
|
|
242
304
|
sourceFile: currentFile
|
|
243
305
|
};
|
package/src/compiler/imports.ts
CHANGED
|
@@ -89,7 +89,7 @@ const includes = (checker: ts.TypeChecker, node: ts.Node, pkg: string, symbolNam
|
|
|
89
89
|
|
|
90
90
|
// Fast path: direct import from package
|
|
91
91
|
if (names.has(node.text)) {
|
|
92
|
-
let symbol = checker
|
|
92
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
93
93
|
|
|
94
94
|
if (symbol) {
|
|
95
95
|
let declarations = symbol.getDeclarations();
|
|
@@ -120,7 +120,7 @@ const includes = (checker: ts.TypeChecker, node: ts.Node, pkg: string, symbolNam
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
// Slow path: check for re-exports via aliased symbol
|
|
123
|
-
let symbol = checker
|
|
123
|
+
let symbol = checker.getSymbolAtLocation(node);
|
|
124
124
|
|
|
125
125
|
if (!symbol) {
|
|
126
126
|
return false;
|