@esportsplus/typescript 0.26.4 → 0.27.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/build/compiler/ast.d.ts +17 -0
- package/build/compiler/ast.js +42 -0
- package/build/compiler/coordinator.js +18 -21
- package/build/compiler/imports.d.ts +2 -2
- package/build/compiler/imports.js +28 -14
- package/build/compiler/index.d.ts +1 -1
- package/build/compiler/index.js +1 -1
- package/build/compiler/uid.d.ts +1 -1
- package/build/compiler/uid.js +4 -12
- package/package.json +1 -1
- package/src/compiler/ast.ts +65 -0
- package/src/compiler/coordinator.ts +25 -32
- package/src/compiler/imports.ts +38 -21
- package/src/compiler/index.ts +2 -2
- package/src/compiler/uid.ts +5 -16
- package/build/compiler/ast/expression.d.ts +0 -4
- package/build/compiler/ast/expression.js +0 -23
- package/build/compiler/ast/index.d.ts +0 -3
- package/build/compiler/ast/index.js +0 -3
- package/build/compiler/ast/range.d.ts +0 -7
- package/build/compiler/ast/range.js +0 -10
- package/build/compiler/ast/visitor.d.ts +0 -3
- package/build/compiler/ast/visitor.js +0 -8
- package/src/compiler/ast/expression.ts +0 -34
- package/src/compiler/ast/index.ts +0 -3
- package/src/compiler/ast/range.ts +0 -21
- package/src/compiler/ast/visitor.ts +0 -13
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
type Range = {
|
|
3
|
+
end: number;
|
|
4
|
+
start: number;
|
|
5
|
+
};
|
|
6
|
+
declare const _default: {
|
|
7
|
+
expression: {
|
|
8
|
+
name: (node: ts.Expression) => string | null;
|
|
9
|
+
};
|
|
10
|
+
inRange: (ranges: Range[], start: number, end: number) => boolean;
|
|
11
|
+
property: {
|
|
12
|
+
path: (node: ts.Expression) => string | null;
|
|
13
|
+
};
|
|
14
|
+
test: (node: ts.Node, fn: (n: ts.Node) => boolean) => boolean;
|
|
15
|
+
};
|
|
16
|
+
export default _default;
|
|
17
|
+
export type { Range };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
const expression = {
|
|
3
|
+
name: (node) => {
|
|
4
|
+
if (ts.isIdentifier(node)) {
|
|
5
|
+
return node.text;
|
|
6
|
+
}
|
|
7
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
8
|
+
return property.path(node);
|
|
9
|
+
}
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const inRange = (ranges, start, end) => {
|
|
14
|
+
for (let i = 0, n = ranges.length; i < n; i++) {
|
|
15
|
+
let r = ranges[i];
|
|
16
|
+
if (start >= r.start && end <= r.end) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return false;
|
|
21
|
+
};
|
|
22
|
+
const property = {
|
|
23
|
+
path: (node) => {
|
|
24
|
+
let current = node, parts = [];
|
|
25
|
+
while (ts.isPropertyAccessExpression(current)) {
|
|
26
|
+
parts.push(current.name.text);
|
|
27
|
+
current = current.expression;
|
|
28
|
+
}
|
|
29
|
+
if (ts.isIdentifier(current)) {
|
|
30
|
+
parts.push(current.text);
|
|
31
|
+
return parts.reverse().join('.');
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const test = (node, fn) => {
|
|
37
|
+
if (fn(node)) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return !!ts.forEachChild(node, child => test(child, fn) || undefined);
|
|
41
|
+
};
|
|
42
|
+
export default { expression, inRange, property, test };
|
|
@@ -55,7 +55,7 @@ function modify(code, file, pkg, options) {
|
|
|
55
55
|
if (!options.add && !options.namespace && !options.remove) {
|
|
56
56
|
return code;
|
|
57
57
|
}
|
|
58
|
-
let { namespace } = options, add = options.add ? new Set(options.add) : null, found = imports.
|
|
58
|
+
let { namespace } = options, add = options.add ? new Set(options.add) : null, found = imports.all(file, pkg);
|
|
59
59
|
if (found.length === 0) {
|
|
60
60
|
let statements = [];
|
|
61
61
|
if (namespace) {
|
|
@@ -117,39 +117,36 @@ const transform = (plugins, code, file, program, shared) => {
|
|
|
117
117
|
if (plugins.length === 0) {
|
|
118
118
|
return { changed: false, code, sourceFile: file };
|
|
119
119
|
}
|
|
120
|
-
let
|
|
120
|
+
let currentCode = code, currentFile = file;
|
|
121
121
|
for (let i = 0, n = plugins.length; i < n; i++) {
|
|
122
122
|
let plugin = plugins[i];
|
|
123
123
|
if (plugin.patterns && !hasPattern(currentCode, plugin.patterns)) {
|
|
124
124
|
continue;
|
|
125
125
|
}
|
|
126
|
-
let
|
|
126
|
+
let { imports, prepend, replacements } = plugin.transform({
|
|
127
127
|
checker: program.getTypeChecker(),
|
|
128
128
|
code: currentCode,
|
|
129
129
|
program,
|
|
130
130
|
shared,
|
|
131
|
-
sourceFile:
|
|
131
|
+
sourceFile: currentFile
|
|
132
132
|
});
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
(
|
|
136
|
-
if (!hasChanges) {
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
changed = true;
|
|
140
|
-
if (result.replacements && result.replacements.length > 0) {
|
|
141
|
-
currentCode = applyIntents(currentCode, currentSourceFile, result.replacements);
|
|
142
|
-
currentSourceFile = ts.createSourceFile(currentSourceFile.fileName, currentCode, currentSourceFile.languageVersion, true);
|
|
133
|
+
if (replacements?.length) {
|
|
134
|
+
currentCode = applyIntents(currentCode, currentFile, replacements);
|
|
135
|
+
currentFile = ts.createSourceFile(currentFile.fileName, currentCode, currentFile.languageVersion, true);
|
|
143
136
|
}
|
|
144
|
-
if (
|
|
145
|
-
currentCode = applyPrepend(currentCode,
|
|
146
|
-
|
|
137
|
+
if (prepend?.length) {
|
|
138
|
+
currentCode = applyPrepend(currentCode, currentFile, prepend);
|
|
139
|
+
currentFile = ts.createSourceFile(currentFile.fileName, currentCode, currentFile.languageVersion, true);
|
|
147
140
|
}
|
|
148
|
-
if (
|
|
149
|
-
currentCode = applyImports(currentCode,
|
|
150
|
-
|
|
141
|
+
if (imports?.length) {
|
|
142
|
+
currentCode = applyImports(currentCode, currentFile, imports);
|
|
143
|
+
currentFile = ts.createSourceFile(currentFile.fileName, currentCode, currentFile.languageVersion, true);
|
|
151
144
|
}
|
|
152
145
|
}
|
|
153
|
-
return {
|
|
146
|
+
return {
|
|
147
|
+
changed: currentCode !== code,
|
|
148
|
+
code: currentCode,
|
|
149
|
+
sourceFile: currentFile
|
|
150
|
+
};
|
|
154
151
|
};
|
|
155
152
|
export default { transform };
|
|
@@ -10,8 +10,8 @@ type ModifyOptions = {
|
|
|
10
10
|
remove?: Iterable<string>;
|
|
11
11
|
};
|
|
12
12
|
declare const _default: {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
all: (file: ts.SourceFile, pkg: string) => ImportInfo[];
|
|
14
|
+
includes: (checker: ts.TypeChecker, node: ts.Node, pkg: string, symbolName?: string) => boolean;
|
|
15
15
|
};
|
|
16
16
|
export default _default;
|
|
17
17
|
export type { ImportInfo, ModifyOptions };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ts } from '../index.js';
|
|
2
|
-
|
|
2
|
+
let cache = new WeakMap();
|
|
3
|
+
const all = (file, pkg) => {
|
|
3
4
|
let imports = [];
|
|
4
|
-
for (let i = 0, n =
|
|
5
|
-
let stmt =
|
|
5
|
+
for (let i = 0, n = file.statements.length; i < n; i++) {
|
|
6
|
+
let stmt = file.statements[i];
|
|
6
7
|
if (!ts.isImportDeclaration(stmt)) {
|
|
7
8
|
continue;
|
|
8
9
|
}
|
|
9
10
|
let moduleSpecifier = stmt.moduleSpecifier;
|
|
10
|
-
if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !==
|
|
11
|
+
if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== pkg) {
|
|
11
12
|
continue;
|
|
12
13
|
}
|
|
13
14
|
let bindings = stmt.importClause?.namedBindings, specifiers = new Map();
|
|
@@ -17,19 +18,32 @@ const find = (sourceFile, packageName) => {
|
|
|
17
18
|
specifiers.set(propertyName, name);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
|
-
imports.push({ end: stmt.end, specifiers, start: stmt.getStart(
|
|
21
|
+
imports.push({ end: stmt.end, specifiers, start: stmt.getStart(file) });
|
|
21
22
|
}
|
|
22
23
|
return imports;
|
|
23
24
|
};
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
const includes = (checker, node, pkg, symbolName) => {
|
|
26
|
+
let file = node.getSourceFile(), imports = cache.get(file);
|
|
27
|
+
if (!imports) {
|
|
28
|
+
imports = new Map();
|
|
29
|
+
cache.set(file, imports);
|
|
30
|
+
}
|
|
31
|
+
let varnames = imports.get(pkg);
|
|
32
|
+
if (!varnames) {
|
|
33
|
+
varnames = new Set();
|
|
34
|
+
for (let info of all(file, pkg)) {
|
|
35
|
+
for (let [, varname] of info.specifiers) {
|
|
36
|
+
varnames.add(varname);
|
|
37
|
+
}
|
|
28
38
|
}
|
|
39
|
+
imports.set(pkg, varnames);
|
|
40
|
+
}
|
|
41
|
+
if (ts.isIdentifier(node) && varnames.has(node.text) && (!symbolName || node.text === symbolName)) {
|
|
42
|
+
return true;
|
|
29
43
|
}
|
|
30
44
|
let symbol = checker.getSymbolAtLocation(node);
|
|
31
45
|
if (!symbol) {
|
|
32
|
-
if (
|
|
46
|
+
if (ts.isIdentifier(node) && varnames.has(node.text)) {
|
|
33
47
|
return true;
|
|
34
48
|
}
|
|
35
49
|
return false;
|
|
@@ -38,17 +52,17 @@ const inPackage = (checker, node, pkg, symbolName, packageImports) => {
|
|
|
38
52
|
symbol = checker.getAliasedSymbol(symbol);
|
|
39
53
|
}
|
|
40
54
|
if (symbolName && symbol.name !== symbolName) {
|
|
41
|
-
return
|
|
55
|
+
return ts.isIdentifier(node) && varnames.has(node.text);
|
|
42
56
|
}
|
|
43
57
|
let declarations = symbol.getDeclarations();
|
|
44
58
|
if (!declarations || declarations.length === 0) {
|
|
45
|
-
return
|
|
59
|
+
return ts.isIdentifier(node) && varnames.has(node.text);
|
|
46
60
|
}
|
|
47
61
|
for (let i = 0, n = declarations.length; i < n; i++) {
|
|
48
62
|
if (declarations[i].getSourceFile().fileName.includes(pkg)) {
|
|
49
63
|
return true;
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
|
-
return
|
|
66
|
+
return ts.isIdentifier(node) && varnames.has(node.text);
|
|
53
67
|
};
|
|
54
|
-
export default {
|
|
68
|
+
export default { all, includes };
|
package/build/compiler/index.js
CHANGED
package/build/compiler/uid.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: (
|
|
1
|
+
declare const _default: (name: string) => string;
|
|
2
2
|
export default _default;
|
package/build/compiler/uid.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
let
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
for (let i = 0, n = str.length; i < n; i++) {
|
|
6
|
-
h ^= str.charCodeAt(i);
|
|
7
|
-
h = Math.imul(h, 0x01000193);
|
|
8
|
-
}
|
|
9
|
-
return ((h >>> 0).toString(36) + Math.abs(h).toString(36)).replace(INVALID_CHARS, '');
|
|
10
|
-
}
|
|
11
|
-
export default (prefix) => {
|
|
12
|
-
return prefix + '_' + hash(prefix) + (counter++).toString(36);
|
|
1
|
+
import { uuid } from '@esportsplus/utilities';
|
|
2
|
+
let i = 0, namespace = uuid().replace(/[^A-Za-z0-9]/g, '');
|
|
3
|
+
export default (name) => {
|
|
4
|
+
return name + '_' + namespace + (i++).toString(36);
|
|
13
5
|
};
|
package/package.json
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
type Range = {
|
|
5
|
+
end: number;
|
|
6
|
+
start: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const expression = {
|
|
11
|
+
name: (node: ts.Expression): string | null => {
|
|
12
|
+
if (ts.isIdentifier(node)) {
|
|
13
|
+
return node.text;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
17
|
+
return property.path(node);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const inRange = (ranges: Range[], start: number, end: number): boolean => {
|
|
25
|
+
for (let i = 0, n = ranges.length; i < n; i++) {
|
|
26
|
+
let r = ranges[i];
|
|
27
|
+
|
|
28
|
+
if (start >= r.start && end <= r.end) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return false;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const property = {
|
|
37
|
+
path: (node: ts.Expression): string | null => {
|
|
38
|
+
let current: ts.Node = node,
|
|
39
|
+
parts: string[] = [];
|
|
40
|
+
|
|
41
|
+
while (ts.isPropertyAccessExpression(current)) {
|
|
42
|
+
parts.push(current.name.text);
|
|
43
|
+
current = current.expression;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (ts.isIdentifier(current)) {
|
|
47
|
+
parts.push(current.text);
|
|
48
|
+
return parts.reverse().join('.');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const test = (node: ts.Node, fn: (n: ts.Node) => boolean): boolean => {
|
|
56
|
+
if (fn(node)) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return !!ts.forEachChild(node, child => test(child, fn) || undefined);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
export default { expression, inRange, property, test };
|
|
65
|
+
export type { Range };
|
|
@@ -90,7 +90,7 @@ function modify(code: string, file: ts.SourceFile, pkg: string, options: ModifyO
|
|
|
90
90
|
|
|
91
91
|
let { namespace } = options,
|
|
92
92
|
add = options.add ? new Set(options.add) : null,
|
|
93
|
-
found = imports.
|
|
93
|
+
found = imports.all(file, pkg);
|
|
94
94
|
|
|
95
95
|
if (found.length === 0) {
|
|
96
96
|
let statements: string[] = [];
|
|
@@ -187,9 +187,8 @@ const transform = (
|
|
|
187
187
|
return { changed: false, code, sourceFile: file };
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
let
|
|
191
|
-
|
|
192
|
-
currentSourceFile = file;
|
|
190
|
+
let currentCode = code,
|
|
191
|
+
currentFile = file;
|
|
193
192
|
|
|
194
193
|
for (let i = 0, n = plugins.length; i < n; i++) {
|
|
195
194
|
let plugin = plugins[i];
|
|
@@ -198,56 +197,50 @@ const transform = (
|
|
|
198
197
|
continue;
|
|
199
198
|
}
|
|
200
199
|
|
|
201
|
-
let
|
|
200
|
+
let { imports, prepend, replacements } = plugin.transform({
|
|
202
201
|
checker: program.getTypeChecker(),
|
|
203
202
|
code: currentCode,
|
|
204
203
|
program,
|
|
205
204
|
shared,
|
|
206
|
-
sourceFile:
|
|
205
|
+
sourceFile: currentFile
|
|
207
206
|
});
|
|
208
207
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (!hasChanges) {
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
changed = true;
|
|
218
|
-
|
|
219
|
-
if (result.replacements && result.replacements.length > 0) {
|
|
220
|
-
currentCode = applyIntents(currentCode, currentSourceFile, result.replacements);
|
|
221
|
-
currentSourceFile = ts.createSourceFile(
|
|
222
|
-
currentSourceFile.fileName,
|
|
208
|
+
if (replacements?.length) {
|
|
209
|
+
currentCode = applyIntents(currentCode, currentFile, replacements);
|
|
210
|
+
currentFile = ts.createSourceFile(
|
|
211
|
+
currentFile.fileName,
|
|
223
212
|
currentCode,
|
|
224
|
-
|
|
213
|
+
currentFile.languageVersion,
|
|
225
214
|
true
|
|
226
215
|
);
|
|
227
216
|
}
|
|
228
217
|
|
|
229
|
-
if (
|
|
230
|
-
currentCode = applyPrepend(currentCode,
|
|
231
|
-
|
|
232
|
-
|
|
218
|
+
if (prepend?.length) {
|
|
219
|
+
currentCode = applyPrepend(currentCode, currentFile, prepend);
|
|
220
|
+
currentFile = ts.createSourceFile(
|
|
221
|
+
currentFile.fileName,
|
|
233
222
|
currentCode,
|
|
234
|
-
|
|
223
|
+
currentFile.languageVersion,
|
|
235
224
|
true
|
|
236
225
|
);
|
|
237
226
|
}
|
|
238
227
|
|
|
239
|
-
if (
|
|
240
|
-
currentCode = applyImports(currentCode,
|
|
241
|
-
|
|
242
|
-
|
|
228
|
+
if (imports?.length) {
|
|
229
|
+
currentCode = applyImports(currentCode, currentFile, imports);
|
|
230
|
+
currentFile = ts.createSourceFile(
|
|
231
|
+
currentFile.fileName,
|
|
243
232
|
currentCode,
|
|
244
|
-
|
|
233
|
+
currentFile.languageVersion,
|
|
245
234
|
true
|
|
246
235
|
);
|
|
247
236
|
}
|
|
248
237
|
}
|
|
249
238
|
|
|
250
|
-
return {
|
|
239
|
+
return {
|
|
240
|
+
changed: currentCode !== code,
|
|
241
|
+
code: currentCode,
|
|
242
|
+
sourceFile: currentFile
|
|
243
|
+
};
|
|
251
244
|
};
|
|
252
245
|
|
|
253
246
|
|
package/src/compiler/imports.ts
CHANGED
|
@@ -14,12 +14,15 @@ type ModifyOptions = {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
|
|
17
|
+
let cache = new WeakMap<ts.SourceFile, Map<string, Set<string>>>();
|
|
18
|
+
|
|
19
|
+
|
|
17
20
|
// Find all named imports from a specific package
|
|
18
|
-
const
|
|
21
|
+
const all = (file: ts.SourceFile, pkg: string): ImportInfo[] => {
|
|
19
22
|
let imports: ImportInfo[] = [];
|
|
20
23
|
|
|
21
|
-
for (let i = 0, n =
|
|
22
|
-
let stmt =
|
|
24
|
+
for (let i = 0, n = file.statements.length; i < n; i++) {
|
|
25
|
+
let stmt = file.statements[i];
|
|
23
26
|
|
|
24
27
|
if (!ts.isImportDeclaration(stmt)) {
|
|
25
28
|
continue;
|
|
@@ -27,7 +30,7 @@ const find = (sourceFile: ts.SourceFile, packageName: string): ImportInfo[] => {
|
|
|
27
30
|
|
|
28
31
|
let moduleSpecifier = stmt.moduleSpecifier;
|
|
29
32
|
|
|
30
|
-
if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !==
|
|
33
|
+
if (!ts.isStringLiteral(moduleSpecifier) || moduleSpecifier.text !== pkg) {
|
|
31
34
|
continue;
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -44,32 +47,46 @@ const find = (sourceFile: ts.SourceFile, packageName: string): ImportInfo[] => {
|
|
|
44
47
|
}
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
imports.push({ end: stmt.end, specifiers, start: stmt.getStart(
|
|
50
|
+
imports.push({ end: stmt.end, specifiers, start: stmt.getStart(file) });
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
return imports;
|
|
51
54
|
};
|
|
52
55
|
|
|
53
56
|
// Check if node's symbol originates from a specific package (with optional symbol name validation)
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
const includes = (checker: ts.TypeChecker, node: ts.Node, pkg: string, symbolName?: string): boolean => {
|
|
58
|
+
let file = node.getSourceFile(),
|
|
59
|
+
imports = cache.get(file);
|
|
60
|
+
|
|
61
|
+
if (!imports) {
|
|
62
|
+
imports = new Map();
|
|
63
|
+
cache.set(file, imports);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let varnames = imports.get(pkg);
|
|
67
|
+
|
|
68
|
+
if (!varnames) {
|
|
69
|
+
varnames = new Set();
|
|
70
|
+
|
|
71
|
+
for (let info of all(file, pkg)) {
|
|
72
|
+
for (let [, varname] of info.specifiers) {
|
|
73
|
+
varnames.add(varname);
|
|
74
|
+
}
|
|
65
75
|
}
|
|
76
|
+
|
|
77
|
+
imports.set(pkg, varnames);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Fast path: identifier matches known import and expected name
|
|
81
|
+
if (ts.isIdentifier(node) && varnames.has(node.text) && (!symbolName || node.text === symbolName)) {
|
|
82
|
+
return true;
|
|
66
83
|
}
|
|
67
84
|
|
|
68
85
|
let symbol = checker.getSymbolAtLocation(node);
|
|
69
86
|
|
|
70
87
|
if (!symbol) {
|
|
71
88
|
// Fallback: aliased import - check if local name is in imports
|
|
72
|
-
if (
|
|
89
|
+
if (ts.isIdentifier(node) && varnames.has(node.text)) {
|
|
73
90
|
return true;
|
|
74
91
|
}
|
|
75
92
|
|
|
@@ -83,13 +100,13 @@ const inPackage = (
|
|
|
83
100
|
|
|
84
101
|
// Check symbol name if specified
|
|
85
102
|
if (symbolName && symbol.name !== symbolName) {
|
|
86
|
-
return
|
|
103
|
+
return ts.isIdentifier(node) && varnames.has(node.text);
|
|
87
104
|
}
|
|
88
105
|
|
|
89
106
|
let declarations = symbol.getDeclarations();
|
|
90
107
|
|
|
91
108
|
if (!declarations || declarations.length === 0) {
|
|
92
|
-
return
|
|
109
|
+
return ts.isIdentifier(node) && varnames.has(node.text);
|
|
93
110
|
}
|
|
94
111
|
|
|
95
112
|
// Check if any declaration is from the expected package
|
|
@@ -99,9 +116,9 @@ const inPackage = (
|
|
|
99
116
|
}
|
|
100
117
|
}
|
|
101
118
|
|
|
102
|
-
return
|
|
119
|
+
return ts.isIdentifier(node) && varnames.has(node.text);
|
|
103
120
|
};
|
|
104
121
|
|
|
105
122
|
|
|
106
|
-
export default {
|
|
123
|
+
export default { all, includes };
|
|
107
124
|
export type { ImportInfo, ModifyOptions };
|
package/src/compiler/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { default as ast } from './ast';
|
|
2
2
|
export { default as code } from './code';
|
|
3
3
|
export { default as coordinator } from './coordinator';
|
|
4
4
|
export { default as imports } from './imports';
|
|
5
|
-
export { default as plugin } from './plugins
|
|
5
|
+
export { default as plugin } from './plugins';
|
|
6
6
|
export { default as uid } from './uid';
|
|
7
7
|
export type * from './types';
|
package/src/compiler/uid.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { uuid } from '@esportsplus/utilities';
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
let
|
|
4
|
+
let i = 0,
|
|
5
|
+
namespace = uuid().replace(/[^A-Za-z0-9]/g, '');
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
for (let i = 0, n = str.length; i < n; i++) {
|
|
11
|
-
h ^= str.charCodeAt(i);
|
|
12
|
-
h = Math.imul(h, 0x01000193);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return ((h >>> 0).toString(36) + Math.abs(h).toString(36)).replace(INVALID_CHARS, '');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export default (prefix: string): string => {
|
|
20
|
-
return prefix + '_' + hash(prefix) + (counter++).toString(36);
|
|
8
|
+
export default (name: string): string => {
|
|
9
|
+
return name + '_' + namespace + (i++).toString(36);
|
|
21
10
|
};
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
const getExpressionName = (node) => {
|
|
3
|
-
if (ts.isIdentifier(node)) {
|
|
4
|
-
return node.text;
|
|
5
|
-
}
|
|
6
|
-
if (ts.isPropertyAccessExpression(node)) {
|
|
7
|
-
return getPropertyPath(node);
|
|
8
|
-
}
|
|
9
|
-
return null;
|
|
10
|
-
};
|
|
11
|
-
const getPropertyPath = (node) => {
|
|
12
|
-
let current = node, parts = [];
|
|
13
|
-
while (ts.isPropertyAccessExpression(current)) {
|
|
14
|
-
parts.push(current.name.text);
|
|
15
|
-
current = current.expression;
|
|
16
|
-
}
|
|
17
|
-
if (ts.isIdentifier(current)) {
|
|
18
|
-
parts.push(current.text);
|
|
19
|
-
return parts.reverse().join('.');
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
};
|
|
23
|
-
export { getExpressionName, getPropertyPath };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const getExpressionName = (node: ts.Expression): string | null => {
|
|
5
|
-
if (ts.isIdentifier(node)) {
|
|
6
|
-
return node.text;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
if (ts.isPropertyAccessExpression(node)) {
|
|
10
|
-
return getPropertyPath(node);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
const getPropertyPath = (node: ts.Expression): string | null => {
|
|
17
|
-
let current: ts.Node = node,
|
|
18
|
-
parts: string[] = [];
|
|
19
|
-
|
|
20
|
-
while (ts.isPropertyAccessExpression(current)) {
|
|
21
|
-
parts.push(current.name.text);
|
|
22
|
-
current = current.expression;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (ts.isIdentifier(current)) {
|
|
26
|
-
parts.push(current.text);
|
|
27
|
-
return parts.reverse().join('.');
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return null;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export { getExpressionName, getPropertyPath };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
type Range = {
|
|
2
|
-
end: number;
|
|
3
|
-
start: number;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const inRange = (ranges: Range[], start: number, end: number): boolean => {
|
|
8
|
-
for (let i = 0, n = ranges.length; i < n; i++) {
|
|
9
|
-
let r = ranges[i];
|
|
10
|
-
|
|
11
|
-
if (start >= r.start && end <= r.end) {
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return false;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export { inRange };
|
|
21
|
-
export type { Range };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const hasMatch = (node: ts.Node, predicate: (n: ts.Node) => boolean): boolean => {
|
|
5
|
-
if (predicate(node)) {
|
|
6
|
-
return true;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
return !!ts.forEachChild(node, child => hasMatch(child, predicate) || undefined);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export { hasMatch };
|