@boristype/bt-cli 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +66 -0
- package/build/builder/config.js +88 -0
- package/build/cli/commands/artifact.js +14 -0
- package/build/cli/commands/build.js +25 -0
- package/build/cli/commands/dev.js +190 -0
- package/build/cli/commands/index.js +18 -0
- package/build/cli/commands/init.js +15 -0
- package/build/cli/commands/link.js +18 -0
- package/build/cli/commands/push.js +28 -0
- package/build/cli/index.js +14 -0
- package/build/cli/types.js +2 -0
- package/build/core/artifacting/context.js +54 -0
- package/build/core/artifacting/index.js +37 -0
- package/build/core/artifacting/stages/index.js +10 -0
- package/build/core/artifacting/stages/main-archive.js +72 -0
- package/build/core/artifacting/stages/validate.js +70 -0
- package/build/core/artifacting/types.js +6 -0
- package/build/core/artifacting/utils/index.js +10 -0
- package/build/core/artifacting/utils/zip.js +94 -0
- package/build/core/babel.js +96 -0
- package/build/core/btconfig.types.js +6 -0
- package/build/core/build.js +280 -0
- package/build/core/building/compile-mode.js +146 -0
- package/build/core/building/compiler.js +281 -0
- package/build/core/building/coordinator.js +71 -0
- package/build/core/building/files.js +290 -0
- package/build/core/building/index.js +102 -0
- package/build/core/building/output.js +92 -0
- package/build/core/building/transformers.js +110 -0
- package/build/core/building/types.js +19 -0
- package/build/core/config.js +157 -0
- package/build/core/dependencies.js +223 -0
- package/build/core/linking/cache.js +260 -0
- package/build/core/linking/context.js +149 -0
- package/build/core/linking/dependencies.js +240 -0
- package/build/core/linking/executables.js +61 -0
- package/build/core/linking/generators/api-ext.js +57 -0
- package/build/core/linking/generators/component.js +83 -0
- package/build/core/linking/generators/filemap.js +53 -0
- package/build/core/linking/generators/index.js +21 -0
- package/build/core/linking/generators/init-xml.js +37 -0
- package/build/core/linking/generators/package-json.js +50 -0
- package/build/core/linking/index.js +213 -0
- package/build/core/linking/linkers/component.js +175 -0
- package/build/core/linking/linkers/index.js +69 -0
- package/build/core/linking/linkers/standalone.js +144 -0
- package/build/core/linking/linkers/system.js +86 -0
- package/build/core/linking/parsers.js +278 -0
- package/build/core/linking/types.js +6 -0
- package/build/core/linking/utils/copy.js +101 -0
- package/build/core/linking/utils/index.js +26 -0
- package/build/core/linking/utils/node-modules.js +226 -0
- package/build/core/linking/utils/package-type.js +101 -0
- package/build/core/linking/utils/url.js +73 -0
- package/build/core/linking/utils/write.js +91 -0
- package/build/core/logger.js +10 -0
- package/build/core/pushing/config.js +90 -0
- package/build/core/pushing/index.js +96 -0
- package/build/core/pushing/init-scripts.js +173 -0
- package/build/core/pushing/queue.js +95 -0
- package/build/core/pushing/reinit.js +61 -0
- package/build/core/pushing/session.js +167 -0
- package/build/core/pushing/types.js +6 -0
- package/build/core/pushing/upload.js +35 -0
- package/build/core/tsconfig.js +78 -0
- package/build/core/utils/index.js +17 -0
- package/build/core/utils/logger.js +46 -0
- package/build/core/utils/properties.js +81 -0
- package/build/core/utils/xml.js +44 -0
- package/build/core/utils.js +59 -0
- package/build/index.js +76 -0
- package/build/plugins/destructuring.js +83 -0
- package/build/plugins/forOfToForIn.js +14 -0
- package/build/plugins/loopHoistVariables.js +160 -0
- package/build/plugins/precedence.js +172 -0
- package/build/plugins/removeImportExport.js +42 -0
- package/build/plugins/replaceDollar.js +16 -0
- package/build/plugins/spreadArray.js +42 -0
- package/build/plugins/spreadObject.js +91 -0
- package/build/transformers/arrayFunctional.js +467 -0
- package/build/transformers/arrayGeneral.js +222 -0
- package/build/transformers/blockScoping.js +212 -0
- package/build/transformers/destructuring.js +133 -0
- package/build/transformers/dirname.js +79 -0
- package/build/transformers/enumsToObjects.js +25 -0
- package/build/transformers/execObj.js +220 -0
- package/build/transformers/forOfToForIn.js +45 -0
- package/build/transformers/funcSemantic.js +113 -0
- package/build/transformers/functions.js +270 -0
- package/build/transformers/globalCache.js +34 -0
- package/build/transformers/loopHoistVariables.js +352 -0
- package/build/transformers/math.js +39 -0
- package/build/transformers/namespaces.js +22 -0
- package/build/transformers/numericSeparator.js +46 -0
- package/build/transformers/objectProperties.js +54 -0
- package/build/transformers/precedence.js +192 -0
- package/build/transformers/propSemantic.js +467 -0
- package/build/transformers/remodule.js +620 -0
- package/build/transformers/removeImportExport.js +135 -0
- package/build/transformers/replaceDollar.js +46 -0
- package/build/transformers/shorthandProperties.js +34 -0
- package/build/transformers/spreadArray.js +68 -0
- package/build/transformers/spreadObject.js +134 -0
- package/build/transformers/string.js +138 -0
- package/build/transformers/templateLiterals.js +104 -0
- package/build/transformers/tocodelibrary.js +178 -0
- package/build/transformers/utils.js +202 -0
- package/build/wshcm/client.js +193 -0
- package/build/wshcm/evaluator.js +111 -0
- package/build/wshcm/exceptions.js +25 -0
- package/build/wshcm/index.js +20 -0
- package/build/wshcm/soap-utils.js +228 -0
- package/build/wshcm/types.js +2 -0
- package/build/wshcm/uploader.js +320 -0
- package/package.json +51 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.templateLiteralsTransformer = templateLiteralsTransformer;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
8
|
+
/**
|
|
9
|
+
* Трансформер для преобразования шаблонных строк в конкатенацию.
|
|
10
|
+
* Использует режим "loose" — все части приводятся к строкам через конкатенацию с "".
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Вход:
|
|
14
|
+
* const msg = `Hello, ${name}!`;
|
|
15
|
+
* const multi = `a${b}c${d}e`;
|
|
16
|
+
*
|
|
17
|
+
* // Выход:
|
|
18
|
+
* const msg = "Hello, " + name + "!";
|
|
19
|
+
* const multi = "a" + b + "c" + d + "e";
|
|
20
|
+
*
|
|
21
|
+
* @returns TypeScript transformer factory
|
|
22
|
+
*/
|
|
23
|
+
function templateLiteralsTransformer() {
|
|
24
|
+
return (context) => {
|
|
25
|
+
return (sourceFile) => {
|
|
26
|
+
const visitor = (node) => {
|
|
27
|
+
// Обрабатываем шаблонные литералы (template literals)
|
|
28
|
+
if (typescript_1.default.isTemplateExpression(node)) {
|
|
29
|
+
return transformTemplateExpression(node, context);
|
|
30
|
+
}
|
|
31
|
+
// Обрабатываем tagged template expressions (например: tag`hello`)
|
|
32
|
+
if (typescript_1.default.isTaggedTemplateExpression(node)) {
|
|
33
|
+
// Tagged templates требуют особой обработки, пока пропускаем
|
|
34
|
+
// TODO: поддержка tagged templates если нужно
|
|
35
|
+
return typescript_1.default.visitEachChild(node, visitor, context);
|
|
36
|
+
}
|
|
37
|
+
// Обрабатываем простые шаблонные строки без выражений (`hello`)
|
|
38
|
+
if (typescript_1.default.isNoSubstitutionTemplateLiteral(node)) {
|
|
39
|
+
// Просто превращаем в обычную строку
|
|
40
|
+
return typescript_1.default.factory.createStringLiteral(node.text);
|
|
41
|
+
}
|
|
42
|
+
return typescript_1.default.visitEachChild(node, visitor, context);
|
|
43
|
+
};
|
|
44
|
+
return typescript_1.default.visitNode(sourceFile, visitor);
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Преобразует TemplateExpression в конкатенацию строк.
|
|
50
|
+
*
|
|
51
|
+
* @param node - узел TemplateExpression
|
|
52
|
+
* @param context - контекст трансформации
|
|
53
|
+
* @returns выражение конкатенации строк
|
|
54
|
+
*/
|
|
55
|
+
function transformTemplateExpression(node, context) {
|
|
56
|
+
const parts = [];
|
|
57
|
+
// Добавляем начальную часть (head)
|
|
58
|
+
if (node.head.text.length > 0) {
|
|
59
|
+
parts.push(typescript_1.default.factory.createStringLiteral(node.head.text));
|
|
60
|
+
}
|
|
61
|
+
// Обрабатываем каждый span (выражение + следующий текст)
|
|
62
|
+
for (const span of node.templateSpans) {
|
|
63
|
+
// Добавляем выражение (рекурсивно обрабатываем на случай вложенных шаблонов)
|
|
64
|
+
const visitedExpression = typescript_1.default.visitNode(span.expression, (n) => {
|
|
65
|
+
if (typescript_1.default.isTemplateExpression(n)) {
|
|
66
|
+
return transformTemplateExpression(n, context);
|
|
67
|
+
}
|
|
68
|
+
if (typescript_1.default.isNoSubstitutionTemplateLiteral(n)) {
|
|
69
|
+
return typescript_1.default.factory.createStringLiteral(n.text);
|
|
70
|
+
}
|
|
71
|
+
return n;
|
|
72
|
+
});
|
|
73
|
+
parts.push(visitedExpression);
|
|
74
|
+
// Добавляем текстовую часть после выражения
|
|
75
|
+
const literal = span.literal;
|
|
76
|
+
if (literal.text.length > 0) {
|
|
77
|
+
parts.push(typescript_1.default.factory.createStringLiteral(literal.text));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Если нет частей, возвращаем пустую строку
|
|
81
|
+
if (parts.length === 0) {
|
|
82
|
+
return typescript_1.default.factory.createStringLiteral('');
|
|
83
|
+
}
|
|
84
|
+
// Если только одна часть — возвращаем её
|
|
85
|
+
if (parts.length === 1) {
|
|
86
|
+
// Если это не строка, нужно привести к строке через конкатенацию с ""
|
|
87
|
+
const part = parts[0];
|
|
88
|
+
if (typescript_1.default.isStringLiteral(part)) {
|
|
89
|
+
return part;
|
|
90
|
+
}
|
|
91
|
+
// "" + expr для приведения к строке
|
|
92
|
+
return typescript_1.default.factory.createBinaryExpression(typescript_1.default.factory.createStringLiteral(''), typescript_1.default.SyntaxKind.PlusToken, part);
|
|
93
|
+
}
|
|
94
|
+
// Строим цепочку конкатенации слева направо
|
|
95
|
+
let result = parts[0];
|
|
96
|
+
// Если первая часть не строка, начинаем с "" + для приведения к строке
|
|
97
|
+
if (!typescript_1.default.isStringLiteral(result)) {
|
|
98
|
+
result = typescript_1.default.factory.createBinaryExpression(typescript_1.default.factory.createStringLiteral(''), typescript_1.default.SyntaxKind.PlusToken, result);
|
|
99
|
+
}
|
|
100
|
+
for (let i = 1; i < parts.length; i++) {
|
|
101
|
+
result = typescript_1.default.factory.createBinaryExpression(result, typescript_1.default.SyntaxKind.PlusToken, parts[i]);
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.tocodelibraryTransformer = tocodelibraryTransformer;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
function tocodelibraryTransformer() {
|
|
10
|
+
return (context) => {
|
|
11
|
+
return (sourceFile) => {
|
|
12
|
+
if (sourceFile.fileName.endsWith(".test.ts")) {
|
|
13
|
+
return sourceFile;
|
|
14
|
+
}
|
|
15
|
+
// Пропускаем трансформацию для executable objects
|
|
16
|
+
if ((0, utils_1.isExecutableObject)(sourceFile)) {
|
|
17
|
+
return sourceFile;
|
|
18
|
+
}
|
|
19
|
+
const hoistedFunctions = [];
|
|
20
|
+
let functionCounter = 0;
|
|
21
|
+
const functionNameMap = new Map();
|
|
22
|
+
const nameToHoistedName = new Map(); // Маппинг имени -> hoisted имя
|
|
23
|
+
const functionDepthMap = new Map(); // Маппинг функции -> уровень вложенности
|
|
24
|
+
let currentDepth = 0;
|
|
25
|
+
// Генерация уникального имени для функции
|
|
26
|
+
function generateUniqueName(originalName, node, depth) {
|
|
27
|
+
const baseName = originalName || "anonymous";
|
|
28
|
+
// Top-level функции (depth === 0) сохраняют оригинальное имя
|
|
29
|
+
let uniqueName;
|
|
30
|
+
if (depth === 0 && originalName) {
|
|
31
|
+
uniqueName = originalName;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
// Вложенные функции получают префикс __hoisted_
|
|
35
|
+
uniqueName = `__hoisted_${baseName}_${functionCounter++}`;
|
|
36
|
+
}
|
|
37
|
+
functionNameMap.set(node, uniqueName);
|
|
38
|
+
functionDepthMap.set(node, depth);
|
|
39
|
+
if (originalName) {
|
|
40
|
+
// Маппинг для всех функций (и top-level и вложенных)
|
|
41
|
+
nameToHoistedName.set(originalName, uniqueName);
|
|
42
|
+
}
|
|
43
|
+
return uniqueName;
|
|
44
|
+
}
|
|
45
|
+
// Генерация пути к __codelibrary через цепочку __parent
|
|
46
|
+
function generateCodelibaryPath(depth) {
|
|
47
|
+
if (depth === 0) {
|
|
48
|
+
return context.factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(context.factory.createIdentifier("__module_env")), "__codelibrary");
|
|
49
|
+
}
|
|
50
|
+
let expr = context.factory.createIdentifier("__env");
|
|
51
|
+
for (let i = 0; i < depth; i++) {
|
|
52
|
+
expr = context.factory.createPropertyAccessExpression(expr, "__parent");
|
|
53
|
+
}
|
|
54
|
+
return context.factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(expr), "__codelibrary");
|
|
55
|
+
}
|
|
56
|
+
// Первый проход: собираем все функции и даем им уникальные имена
|
|
57
|
+
function collectFunctions(node) {
|
|
58
|
+
if (typescript_1.default.isFunctionDeclaration(node)) {
|
|
59
|
+
const originalName = node.name?.text;
|
|
60
|
+
const uniqueName = generateUniqueName(originalName, node, currentDepth);
|
|
61
|
+
const hoistedFunction = context.factory.createFunctionDeclaration(node.modifiers, node.asteriskToken, context.factory.createIdentifier(uniqueName), node.typeParameters, node.parameters, node.type, node.body);
|
|
62
|
+
hoistedFunctions.push(hoistedFunction);
|
|
63
|
+
// Увеличиваем глубину для вложенных функций
|
|
64
|
+
currentDepth++;
|
|
65
|
+
typescript_1.default.forEachChild(node, collectFunctions);
|
|
66
|
+
currentDepth--;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
typescript_1.default.forEachChild(node, collectFunctions);
|
|
70
|
+
}
|
|
71
|
+
// Второй проход: заменяем объявления функций и callable на ref, добавляем lib
|
|
72
|
+
function visitor(node, depth = 0) {
|
|
73
|
+
if (typescript_1.default.isFunctionDeclaration(node)) {
|
|
74
|
+
const originalName = node.name?.text;
|
|
75
|
+
const uniqueName = functionNameMap.get(node);
|
|
76
|
+
if (!uniqueName) {
|
|
77
|
+
return node;
|
|
78
|
+
}
|
|
79
|
+
// Увеличиваем глубину для обработки тела функции
|
|
80
|
+
const newDepth = depth + 1;
|
|
81
|
+
// Обрабатываем тело функции для замены вложенных функций
|
|
82
|
+
const transformedBody = node.body
|
|
83
|
+
? typescript_1.default.visitNode(node.body, (n) => visitor(n, newDepth))
|
|
84
|
+
: undefined;
|
|
85
|
+
// Обновляем hoisted функцию с трансформированным телом
|
|
86
|
+
const hoistedIndex = hoistedFunctions.findIndex(f => f.name?.text === uniqueName);
|
|
87
|
+
if (hoistedIndex !== -1 && transformedBody) {
|
|
88
|
+
hoistedFunctions[hoistedIndex] = context.factory.createFunctionDeclaration(hoistedFunctions[hoistedIndex].modifiers, hoistedFunctions[hoistedIndex].asteriskToken, hoistedFunctions[hoistedIndex].name, hoistedFunctions[hoistedIndex].typeParameters, hoistedFunctions[hoistedIndex].parameters, hoistedFunctions[hoistedIndex].type, transformedBody);
|
|
89
|
+
}
|
|
90
|
+
// Удаляем объявление функции из кода
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
// Обрабатываем дескрипторы функций
|
|
94
|
+
if (typescript_1.default.isObjectLiteralExpression(node)) {
|
|
95
|
+
const hasDescriptor = node.properties.some(prop => typescript_1.default.isPropertyAssignment(prop) &&
|
|
96
|
+
((typescript_1.default.isIdentifier(prop.name) && prop.name.text === "@descriptor") ||
|
|
97
|
+
(typescript_1.default.isStringLiteral(prop.name) && prop.name.text === "@descriptor")));
|
|
98
|
+
if (hasDescriptor) {
|
|
99
|
+
// Это дескриптор, добавляем свойство lib
|
|
100
|
+
const codelibPath = generateCodelibaryPath(depth);
|
|
101
|
+
const newProperties = node.properties.map(prop => {
|
|
102
|
+
// Заменяем callable на ref
|
|
103
|
+
if (typescript_1.default.isPropertyAssignment(prop)) {
|
|
104
|
+
const propertyName = typescript_1.default.isIdentifier(prop.name)
|
|
105
|
+
? prop.name.text
|
|
106
|
+
: typescript_1.default.isStringLiteral(prop.name)
|
|
107
|
+
? prop.name.text
|
|
108
|
+
: undefined;
|
|
109
|
+
if (propertyName === "callable") {
|
|
110
|
+
if (typescript_1.default.isIdentifier(prop.initializer)) {
|
|
111
|
+
const functionName = prop.initializer.text;
|
|
112
|
+
const hoistedName = nameToHoistedName.get(functionName);
|
|
113
|
+
if (hoistedName) {
|
|
114
|
+
return context.factory.createPropertyAssignment(context.factory.createStringLiteral("ref"), context.factory.createStringLiteral(hoistedName));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return context.factory.createPropertyAssignment(context.factory.createStringLiteral("ref"), typescript_1.default.visitNode(prop.initializer, (n) => visitor(n, depth)));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return prop;
|
|
121
|
+
});
|
|
122
|
+
// Добавляем свойство lib
|
|
123
|
+
const propertiesWithLib = [
|
|
124
|
+
...newProperties,
|
|
125
|
+
context.factory.createPropertyAssignment(context.factory.createStringLiteral("lib"), codelibPath)
|
|
126
|
+
];
|
|
127
|
+
return context.factory.updateObjectLiteralExpression(node, propertiesWithLib);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return typescript_1.default.visitEachChild(node, (n) => visitor(n, depth), context);
|
|
131
|
+
}
|
|
132
|
+
// Собираем все функции
|
|
133
|
+
collectFunctions(sourceFile);
|
|
134
|
+
// Трансформируем исходный файл
|
|
135
|
+
const transformedStatements = sourceFile.statements.map(statement => typescript_1.default.visitNode(statement, visitor)).flat().filter((s) => s !== undefined);
|
|
136
|
+
// Разделяем statements на export декларации и остальной код
|
|
137
|
+
const exportStatements = [];
|
|
138
|
+
const initStatements = [];
|
|
139
|
+
transformedStatements.forEach(statement => {
|
|
140
|
+
// Проверяем, содержит ли statement модификатор export или является export декларацией
|
|
141
|
+
const hasExportModifier = typescript_1.default.canHaveModifiers(statement) &&
|
|
142
|
+
typescript_1.default.getModifiers(statement)?.some((m) => m.kind === typescript_1.default.SyntaxKind.ExportKeyword);
|
|
143
|
+
const isExportDeclaration = typescript_1.default.isExportDeclaration(statement) || typescript_1.default.isExportAssignment(statement);
|
|
144
|
+
// Все что содержит export остается на top-level
|
|
145
|
+
// Это включает: export type, export interface, export {}, export default, export function, export const и т.д.
|
|
146
|
+
if (hasExportModifier || isExportDeclaration) {
|
|
147
|
+
exportStatements.push(statement);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
initStatements.push(statement);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
// Ищем var __module_env = {} и добавляем __codelibrary
|
|
154
|
+
const statementsWithCodelibrary = initStatements.flatMap(statement => {
|
|
155
|
+
// Проверяем, является ли это var __module_env = {}
|
|
156
|
+
if (typescript_1.default.isVariableStatement(statement)) {
|
|
157
|
+
const decl = statement.declarationList.declarations[0];
|
|
158
|
+
if (decl && typescript_1.default.isIdentifier(decl.name) && decl.name.text === "__module_env") {
|
|
159
|
+
// Нашли __module_env, добавляем после него __module_env.__codelibrary = __codelibrary
|
|
160
|
+
const codelibAssignment = context.factory.createExpressionStatement(context.factory.createBinaryExpression(context.factory.createPropertyAccessExpression((0, utils_1.markUntouchable)(context.factory.createIdentifier("__module_env")), "__codelibrary"), typescript_1.default.SyntaxKind.EqualsToken, context.factory.createIdentifier("__codelibrary")));
|
|
161
|
+
return [statement, codelibAssignment];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return [statement];
|
|
165
|
+
});
|
|
166
|
+
// Создаем функцию __init с оставшимися statements (без export деклараций)
|
|
167
|
+
const initFunction = context.factory.createFunctionDeclaration(undefined, undefined, context.factory.createIdentifier("__init"), undefined, [
|
|
168
|
+
context.factory.createParameterDeclaration(undefined, undefined, context.factory.createIdentifier("__codelibrary")),
|
|
169
|
+
context.factory.createParameterDeclaration(undefined, undefined, context.factory.createIdentifier("__module"))
|
|
170
|
+
], undefined, context.factory.createBlock(statementsWithCodelibrary, true));
|
|
171
|
+
// Объединяем: hoisted функции, __init, и export декларации в конце
|
|
172
|
+
const newStatements = [...hoistedFunctions, initFunction, ...exportStatements];
|
|
173
|
+
newStatements.forEach(stmt => (0, utils_1.setParentNodes)(stmt, sourceFile));
|
|
174
|
+
// Возвращаем новый файл с hoisted функциями, __init и export декларациями
|
|
175
|
+
return context.factory.updateSourceFile(sourceFile, newStatements);
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.printAstNode = printAstNode;
|
|
37
|
+
exports.markUntouchable = markUntouchable;
|
|
38
|
+
exports.isUntouchable = isUntouchable;
|
|
39
|
+
exports.markExecutableObject = markExecutableObject;
|
|
40
|
+
exports.isExecutableObject = isExecutableObject;
|
|
41
|
+
exports.setExecutableObjectKey = setExecutableObjectKey;
|
|
42
|
+
exports.getExecutableObjectKey = getExecutableObjectKey;
|
|
43
|
+
exports.preserveSymbolsFrom = preserveSymbolsFrom;
|
|
44
|
+
exports.setParentNodes = setParentNodes;
|
|
45
|
+
exports.visitNodeWithParents = visitNodeWithParents;
|
|
46
|
+
exports.visitEachChildWithParents = visitEachChildWithParents;
|
|
47
|
+
const ts = __importStar(require("typescript"));
|
|
48
|
+
/**
|
|
49
|
+
* Utility functions for TypeScript AST transformers.
|
|
50
|
+
*
|
|
51
|
+
* Эти функции обеспечивают корректную работу последовательных трансформеров,
|
|
52
|
+
* устанавливая parent ссылки для узлов, созданных через factory методы.
|
|
53
|
+
*
|
|
54
|
+
* Проблема: Когда трансформер создает новые узлы через ts.factory.create*(),
|
|
55
|
+
* у этих узлов нет parent ссылок. Последующие трансформеры, которые полагаются
|
|
56
|
+
* на node.parent для определения контекста, не могут корректно обработать такие узлы.
|
|
57
|
+
*
|
|
58
|
+
* Решение: Использовать setParentNodes() после создания новых узлов.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // Создание новых узлов без parent:
|
|
62
|
+
* const newNode = ts.factory.createObjectLiteralExpression(properties, true);
|
|
63
|
+
* return setParentNodes(newNode); // Устанавливаем parent для всех детей
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Замена узла в visitor с сохранением parent из оригинальной ноды:
|
|
67
|
+
* if (ts.isArrowFunction(node)) {
|
|
68
|
+
* const newFunc = ts.factory.createFunctionExpression(...);
|
|
69
|
+
* return setParentNodes(newFunc, node.parent); // Parent от оригинального узла
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* // Использование wrapper для visitNode:
|
|
74
|
+
* const transformed = visitNodeWithParents(node, visitor); // Автоматически сохраняет parent
|
|
75
|
+
*/
|
|
76
|
+
function printAstNode(node, sourceCode) {
|
|
77
|
+
const printer = ts.createPrinter({
|
|
78
|
+
newLine: ts.NewLineKind.LineFeed,
|
|
79
|
+
});
|
|
80
|
+
let sourceFile;
|
|
81
|
+
if (sourceCode) {
|
|
82
|
+
// Используем существующий исходный код
|
|
83
|
+
sourceFile = ts.createSourceFile('temp.ts', sourceCode, ts.ScriptTarget.Latest, true);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Создаем минимальный sourceFile для контекста
|
|
87
|
+
sourceFile = ts.createSourceFile('temp.ts', '', ts.ScriptTarget.Latest);
|
|
88
|
+
}
|
|
89
|
+
const result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
|
|
90
|
+
// console.log(result);
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
const untouchable = Symbol('untouchable');
|
|
94
|
+
function markUntouchable(obj) {
|
|
95
|
+
obj[untouchable] = true;
|
|
96
|
+
return obj;
|
|
97
|
+
}
|
|
98
|
+
function isUntouchable(obj) {
|
|
99
|
+
return obj && obj[untouchable] === true;
|
|
100
|
+
}
|
|
101
|
+
const executableObject = Symbol('executableObject');
|
|
102
|
+
function markExecutableObject(obj) {
|
|
103
|
+
obj[executableObject] = true;
|
|
104
|
+
return obj;
|
|
105
|
+
}
|
|
106
|
+
function isExecutableObject(obj) {
|
|
107
|
+
return obj && obj[executableObject] === true;
|
|
108
|
+
}
|
|
109
|
+
const executableObjectKey = Symbol('executableObjectKey');
|
|
110
|
+
function setExecutableObjectKey(obj, key) {
|
|
111
|
+
obj[executableObjectKey] = key;
|
|
112
|
+
return obj;
|
|
113
|
+
}
|
|
114
|
+
function getExecutableObjectKey(obj) {
|
|
115
|
+
return obj && obj[executableObjectKey];
|
|
116
|
+
}
|
|
117
|
+
function preserveSymbolsFrom(target, source) {
|
|
118
|
+
if (isUntouchable(source)) {
|
|
119
|
+
markUntouchable(target);
|
|
120
|
+
}
|
|
121
|
+
if (isExecutableObject(source)) {
|
|
122
|
+
markExecutableObject(target);
|
|
123
|
+
}
|
|
124
|
+
if (getExecutableObjectKey(source) !== undefined) {
|
|
125
|
+
setExecutableObjectKey(target, getExecutableObjectKey(source));
|
|
126
|
+
}
|
|
127
|
+
return target;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Устанавливает parent ссылки для всех дочерних узлов в AST.
|
|
131
|
+
* Используется после создания новых узлов через factory методы,
|
|
132
|
+
* чтобы последующие трансформеры могли корректно работать с node.parent.
|
|
133
|
+
*
|
|
134
|
+
* @param node - Корневой узел, для которого нужно установить parent ссылки
|
|
135
|
+
* @param parentNode - Опциональный parent для корневого узла (полезно при замене узлов в visitor)
|
|
136
|
+
* @returns Тот же узел с установленными parent ссылками
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* // Замена узла в visitor с сохранением parent:
|
|
140
|
+
* if (ts.isArrowFunction(node)) {
|
|
141
|
+
* const newNode = ts.factory.createFunctionExpression(...);
|
|
142
|
+
* return setParentNodes(newNode, node.parent); // Сохраняем parent из оригинальной ноды
|
|
143
|
+
* }
|
|
144
|
+
*/
|
|
145
|
+
function setParentNodes(node, parentNode) {
|
|
146
|
+
function visit(currentNode, parent) {
|
|
147
|
+
// Устанавливаем parent для текущего узла
|
|
148
|
+
if (parent && currentNode !== parent && currentNode.kind !== 308) {
|
|
149
|
+
currentNode.parent = parent;
|
|
150
|
+
}
|
|
151
|
+
// Рекурсивно обходим всех детей
|
|
152
|
+
ts.forEachChild(currentNode, child => {
|
|
153
|
+
visit(child, currentNode);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (!node)
|
|
157
|
+
return node;
|
|
158
|
+
// Устанавливаем parent для корневого узла, если указан
|
|
159
|
+
if (parentNode && node !== parentNode && node.kind !== 308) {
|
|
160
|
+
node.parent = parentNode;
|
|
161
|
+
}
|
|
162
|
+
// Обходим детей корневого узла
|
|
163
|
+
ts.forEachChild(node, child => {
|
|
164
|
+
visit(child, node);
|
|
165
|
+
});
|
|
166
|
+
return node;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Wrapper для ts.visitNode, который автоматически устанавливает parent ссылки
|
|
170
|
+
* для результата трансформации.
|
|
171
|
+
*
|
|
172
|
+
* @param node - Узел для трансформации
|
|
173
|
+
* @param visitor - Visitor функция
|
|
174
|
+
* @param preserveParent - Если true, сохраняет parent из оригинального узла
|
|
175
|
+
* @returns Трансформированный узел с установленными parent ссылками
|
|
176
|
+
*/
|
|
177
|
+
function visitNodeWithParents(node, visitor, preserveParent = true) {
|
|
178
|
+
if (!node)
|
|
179
|
+
return undefined;
|
|
180
|
+
const originalParent = node.parent;
|
|
181
|
+
const result = ts.visitNode(node, visitor);
|
|
182
|
+
if (result) {
|
|
183
|
+
setParentNodes(result, preserveParent ? originalParent : undefined);
|
|
184
|
+
}
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Wrapper для ts.visitEachChild, который автоматически устанавливает parent ссылки
|
|
189
|
+
* для результата трансформации.
|
|
190
|
+
*
|
|
191
|
+
* @param node - Узел для трансформации
|
|
192
|
+
* @param visitor - Visitor функция
|
|
193
|
+
* @param context - Контекст трансформации
|
|
194
|
+
* @param preserveParent - Если true, сохраняет parent из оригинального узла
|
|
195
|
+
* @returns Трансформированный узел с установленными parent ссылками
|
|
196
|
+
*/
|
|
197
|
+
function visitEachChildWithParents(node, visitor, context, preserveParent = true) {
|
|
198
|
+
const originalParent = node.parent;
|
|
199
|
+
const result = ts.visitEachChild(node, visitor, context);
|
|
200
|
+
setParentNodes(result, preserveParent ? originalParent : undefined);
|
|
201
|
+
return result;
|
|
202
|
+
}
|