gtx-cli 2.5.35 → 2.5.36
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 +9 -0
- package/dist/console/formatting.d.ts +1 -0
- package/dist/console/formatting.js +7 -0
- package/dist/console/index.d.ts +3 -1
- package/dist/console/index.js +5 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/react/jsx/utils/constants.d.ts +3 -1
- package/dist/react/jsx/utils/constants.js +13 -3
- package/dist/react/jsx/utils/getCalleeNameFromExpression.d.ts +9 -0
- package/dist/react/jsx/utils/getCalleeNameFromExpression.js +32 -0
- package/dist/react/jsx/utils/getPathsAndAliases.js +3 -3
- package/dist/react/jsx/utils/jsxParsing/handleChildrenWhitespace.js +0 -2
- package/dist/react/jsx/utils/jsxParsing/parseJsx.d.ts +6 -4
- package/dist/react/jsx/utils/jsxParsing/parseJsx.js +168 -154
- package/dist/react/jsx/utils/parseDeclareStatic.d.ts +15 -0
- package/dist/react/jsx/utils/parseDeclareStatic.js +540 -0
- package/dist/react/jsx/utils/parseString.d.ts +25 -0
- package/dist/react/jsx/utils/parseString.js +539 -0
- package/dist/react/jsx/utils/parseStringFunction.d.ts +10 -0
- package/dist/react/jsx/utils/parseStringFunction.js +63 -10
- package/dist/react/jsx/utils/types.d.ts +14 -0
- package/dist/react/jsx/utils/types.js +1 -0
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@ import * as t from '@babel/types';
|
|
|
5
5
|
import fs from 'node:fs';
|
|
6
6
|
import { parse } from '@babel/parser';
|
|
7
7
|
import addGTIdentifierToSyntaxTree from './addGTIdentifierToSyntaxTree.js';
|
|
8
|
-
import { warnHasUnwrappedExpressionSync, warnNestedTComponent,
|
|
8
|
+
import { warnHasUnwrappedExpressionSync, warnNestedTComponent, warnFunctionNotFoundSync, warnMissingReturnSync, warnDuplicateFunctionDefinitionSync, warnInvalidStaticInitSync, warnRecursiveFunctionCallSync, } from '../../../../console/index.js';
|
|
9
9
|
import { isAcceptedPluralForm } from 'generaltranslation/internal';
|
|
10
10
|
import { isStaticExpression } from '../../evaluateJsx.js';
|
|
11
11
|
import { STATIC_COMPONENT, TRANSLATION_COMPONENT, VARIABLE_COMPONENTS, } from '../constants.js';
|
|
@@ -16,7 +16,7 @@ import { buildImportMap } from '../buildImportMap.js';
|
|
|
16
16
|
import { getPathsAndAliases } from '../getPathsAndAliases.js';
|
|
17
17
|
import { parseTProps } from './parseTProps.js';
|
|
18
18
|
import { handleChildrenWhitespace } from './handleChildrenWhitespace.js';
|
|
19
|
-
import { isElementNode
|
|
19
|
+
import { isElementNode } from './types.js';
|
|
20
20
|
import { multiplyJsxTree } from './multiplication/multiplyJsxTree.js';
|
|
21
21
|
import { removeNullChildrenFields } from './removeNullChildrenFields.js';
|
|
22
22
|
import path from 'node:path';
|
|
@@ -77,14 +77,31 @@ export function parseTranslationComponent({ originalName, importAliases, localNa
|
|
|
77
77
|
* @param insideT - Whether the current node is inside a <T> component
|
|
78
78
|
* @returns The built JSX tree
|
|
79
79
|
*/
|
|
80
|
-
export function buildJSXTree({ importAliases, node, unwrappedExpressions, visited, callStack, updates, errors, warnings, file, insideT, parsingOptions, scopeNode, importedFunctionsMap, pkgs, }) {
|
|
80
|
+
export function buildJSXTree({ importAliases, node, unwrappedExpressions, inStatic, visited, callStack, updates, errors, warnings, file, insideT, parsingOptions, scopeNode, importedFunctionsMap, pkgs, helperPath, }) {
|
|
81
81
|
if (t.isJSXExpressionContainer(node)) {
|
|
82
82
|
// Skip JSX comments
|
|
83
83
|
if (t.isJSXEmptyExpression(node.expression)) {
|
|
84
84
|
return null;
|
|
85
85
|
}
|
|
86
|
+
if (inStatic) {
|
|
87
|
+
return processStaticExpression({
|
|
88
|
+
unwrappedExpressions,
|
|
89
|
+
scopeNode,
|
|
90
|
+
expressionNodePath: helperPath.get('expression'),
|
|
91
|
+
importAliases,
|
|
92
|
+
visited: visited,
|
|
93
|
+
callStack,
|
|
94
|
+
updates,
|
|
95
|
+
errors,
|
|
96
|
+
warnings,
|
|
97
|
+
file,
|
|
98
|
+
parsingOptions,
|
|
99
|
+
importedFunctionsMap,
|
|
100
|
+
pkgs,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
86
103
|
const expr = node.expression;
|
|
87
|
-
if (t.isJSXElement(expr)) {
|
|
104
|
+
if (t.isJSXElement(expr) || t.isJSXFragment(expr)) {
|
|
88
105
|
return buildJSXTree({
|
|
89
106
|
importAliases,
|
|
90
107
|
node: expr,
|
|
@@ -92,14 +109,16 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
92
109
|
visited,
|
|
93
110
|
callStack,
|
|
94
111
|
updates,
|
|
95
|
-
errors
|
|
96
|
-
warnings
|
|
112
|
+
errors,
|
|
113
|
+
warnings,
|
|
97
114
|
file,
|
|
98
115
|
insideT,
|
|
99
116
|
parsingOptions,
|
|
100
117
|
scopeNode,
|
|
101
118
|
importedFunctionsMap,
|
|
102
119
|
pkgs,
|
|
120
|
+
inStatic,
|
|
121
|
+
helperPath: helperPath.get('expression'),
|
|
103
122
|
});
|
|
104
123
|
}
|
|
105
124
|
const staticAnalysis = isStaticExpression(expr, true);
|
|
@@ -145,7 +164,10 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
145
164
|
const props = {};
|
|
146
165
|
const elementIsPlural = componentType === 'Plural';
|
|
147
166
|
const elementIsBranch = componentType === 'Branch';
|
|
148
|
-
element.openingElement.attributes.forEach((attr) => {
|
|
167
|
+
element.openingElement.attributes.forEach((attr, index) => {
|
|
168
|
+
const helperAttribute = helperPath
|
|
169
|
+
.get('openingElement')
|
|
170
|
+
.get('attributes')[index];
|
|
149
171
|
if (t.isJSXAttribute(attr)) {
|
|
150
172
|
const attrName = attr.name.name;
|
|
151
173
|
let attrValue = null;
|
|
@@ -154,34 +176,24 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
154
176
|
attrValue = attr.value.value;
|
|
155
177
|
}
|
|
156
178
|
else if (t.isJSXExpressionContainer(attr.value)) {
|
|
179
|
+
const helperValue = helperAttribute.get('value');
|
|
157
180
|
// Check if this is an HTML content prop (title, placeholder, alt, etc.)
|
|
158
181
|
const isHtmlContentProp = Object.values(HTML_CONTENT_PROPS).includes(attrName);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
182
|
+
// If its a plural or branch prop
|
|
183
|
+
if ((elementIsPlural && isAcceptedPluralForm(attrName)) ||
|
|
184
|
+
(elementIsBranch && attrName !== 'branch')) {
|
|
185
|
+
// Make sure that variable strings like {`I have ${count} book`} are invalid!
|
|
186
|
+
if (t.isTemplateLiteral(attr.value.expression) &&
|
|
187
|
+
!isStaticExpression(attr.value.expression, true).isStatic) {
|
|
188
|
+
unwrappedExpressions.push(generate(attr.value).code);
|
|
165
189
|
}
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// For non-HTML-content props, validate plural/branch then build tree
|
|
170
|
-
if ((elementIsPlural && isAcceptedPluralForm(attrName)) ||
|
|
171
|
-
(elementIsBranch && attrName !== 'branch')) {
|
|
172
|
-
// Make sure that variable strings like {`I have ${count} book`} are invalid!
|
|
173
|
-
if (t.isTemplateLiteral(attr.value.expression) &&
|
|
174
|
-
!isStaticExpression(attr.value.expression, true).isStatic) {
|
|
175
|
-
unwrappedExpressions.push(generate(attr.value).code);
|
|
176
|
-
}
|
|
177
|
-
// If it's an array, flag as an unwrapped expression
|
|
178
|
-
if (t.isArrayExpression(attr.value.expression)) {
|
|
179
|
-
unwrappedExpressions.push(generate(attr.value.expression).code);
|
|
180
|
-
}
|
|
190
|
+
// If it's an array, flag as an unwrapped expression
|
|
191
|
+
if (t.isArrayExpression(attr.value.expression)) {
|
|
192
|
+
unwrappedExpressions.push(generate(attr.value.expression).code);
|
|
181
193
|
}
|
|
182
194
|
attrValue = buildJSXTree({
|
|
183
195
|
importAliases,
|
|
184
|
-
node: attr.value
|
|
196
|
+
node: attr.value,
|
|
185
197
|
unwrappedExpressions,
|
|
186
198
|
visited,
|
|
187
199
|
callStack,
|
|
@@ -194,8 +206,19 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
194
206
|
scopeNode,
|
|
195
207
|
importedFunctionsMap,
|
|
196
208
|
pkgs,
|
|
209
|
+
inStatic,
|
|
210
|
+
helperPath: helperValue,
|
|
197
211
|
});
|
|
198
212
|
}
|
|
213
|
+
// For HTML content props, only accept static string expressions
|
|
214
|
+
else if (isHtmlContentProp) {
|
|
215
|
+
const staticAnalysis = isStaticExpression(attr.value.expression, true);
|
|
216
|
+
if (staticAnalysis.isStatic &&
|
|
217
|
+
staticAnalysis.value !== undefined) {
|
|
218
|
+
attrValue = staticAnalysis.value;
|
|
219
|
+
}
|
|
220
|
+
// Otherwise attrValue stays null and won't be included
|
|
221
|
+
}
|
|
199
222
|
}
|
|
200
223
|
}
|
|
201
224
|
props[attrName] = attrValue;
|
|
@@ -203,36 +226,43 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
203
226
|
});
|
|
204
227
|
if (elementIsVariable) {
|
|
205
228
|
if (componentType === STATIC_COMPONENT) {
|
|
229
|
+
const helperElement = helperPath.get('children');
|
|
230
|
+
const results = {
|
|
231
|
+
nodeType: 'element',
|
|
232
|
+
type: STATIC_COMPONENT,
|
|
233
|
+
props,
|
|
234
|
+
};
|
|
235
|
+
// Create children array if necessary
|
|
236
|
+
if (element.children.length) {
|
|
237
|
+
results.props.children = [];
|
|
238
|
+
}
|
|
206
239
|
if (visited === null) {
|
|
207
240
|
visited = new Set();
|
|
208
241
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
242
|
+
for (let index = 0; index < element.children.length; index++) {
|
|
243
|
+
const helperChild = helperElement[index];
|
|
244
|
+
const result = buildJSXTree({
|
|
245
|
+
importAliases,
|
|
246
|
+
node: helperChild.node,
|
|
247
|
+
unwrappedExpressions,
|
|
248
|
+
visited,
|
|
249
|
+
callStack,
|
|
250
|
+
updates,
|
|
251
|
+
errors,
|
|
252
|
+
warnings,
|
|
253
|
+
file,
|
|
254
|
+
insideT: true,
|
|
255
|
+
parsingOptions,
|
|
256
|
+
scopeNode,
|
|
257
|
+
importedFunctionsMap,
|
|
258
|
+
pkgs,
|
|
259
|
+
inStatic: true,
|
|
260
|
+
helperPath: helperChild,
|
|
261
|
+
});
|
|
262
|
+
results.props.children.push(result);
|
|
263
|
+
}
|
|
264
|
+
return results;
|
|
225
265
|
}
|
|
226
|
-
// I do not see why this is being called, i am disabling this for now:
|
|
227
|
-
// parseJSXElement({
|
|
228
|
-
// importAliases,
|
|
229
|
-
// node: element,
|
|
230
|
-
// updates,
|
|
231
|
-
// errors,
|
|
232
|
-
// warnings,
|
|
233
|
-
// file,
|
|
234
|
-
// parsingOptions,
|
|
235
|
-
// });
|
|
236
266
|
return {
|
|
237
267
|
nodeType: 'element',
|
|
238
268
|
// if componentType is undefined, use typeName
|
|
@@ -242,7 +272,7 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
242
272
|
};
|
|
243
273
|
}
|
|
244
274
|
const children = element.children
|
|
245
|
-
.map((child) => buildJSXTree({
|
|
275
|
+
.map((child, index) => buildJSXTree({
|
|
246
276
|
importAliases,
|
|
247
277
|
node: child,
|
|
248
278
|
unwrappedExpressions,
|
|
@@ -257,6 +287,8 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
257
287
|
scopeNode,
|
|
258
288
|
importedFunctionsMap,
|
|
259
289
|
pkgs,
|
|
290
|
+
inStatic,
|
|
291
|
+
helperPath: helperPath.get('children')[index],
|
|
260
292
|
}))
|
|
261
293
|
.filter((child) => child !== null && child !== '');
|
|
262
294
|
if (children.length === 1) {
|
|
@@ -276,7 +308,7 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
276
308
|
// If it's a JSX fragment
|
|
277
309
|
else if (t.isJSXFragment(node)) {
|
|
278
310
|
const children = node.children
|
|
279
|
-
.map((child) => buildJSXTree({
|
|
311
|
+
.map((child, index) => buildJSXTree({
|
|
280
312
|
importAliases,
|
|
281
313
|
node: child,
|
|
282
314
|
unwrappedExpressions,
|
|
@@ -291,6 +323,8 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
291
323
|
scopeNode,
|
|
292
324
|
importedFunctionsMap,
|
|
293
325
|
pkgs,
|
|
326
|
+
inStatic,
|
|
327
|
+
helperPath: helperPath.get('children')[index],
|
|
294
328
|
}))
|
|
295
329
|
.filter((child) => child !== null && child !== '');
|
|
296
330
|
const props = {};
|
|
@@ -340,6 +374,59 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
340
374
|
}
|
|
341
375
|
return generate(node).code;
|
|
342
376
|
}
|
|
377
|
+
else if ((t.isCallExpression(node) && t.isIdentifier(node.callee)) ||
|
|
378
|
+
(t.isAwaitExpression(node) &&
|
|
379
|
+
t.isCallExpression(node.argument) &&
|
|
380
|
+
t.isIdentifier(node.argument.callee))) {
|
|
381
|
+
if (inStatic) {
|
|
382
|
+
const callExpression = (node.type === 'AwaitExpression' ? node.argument : node);
|
|
383
|
+
const callee = callExpression.callee;
|
|
384
|
+
const calleeBinding = scopeNode.scope.getBinding(callee.name);
|
|
385
|
+
if (!calleeBinding) {
|
|
386
|
+
warnings.add(warnFunctionNotFoundSync(file, callee.name, `${callee.loc?.start?.line}:${callee.loc?.start?.column}`));
|
|
387
|
+
return null;
|
|
388
|
+
}
|
|
389
|
+
return resolveStaticFunctionInvocationFromBinding({
|
|
390
|
+
importAliases,
|
|
391
|
+
calleeBinding,
|
|
392
|
+
callee,
|
|
393
|
+
visited: visited, // we know this is true bc of inStatic
|
|
394
|
+
callStack,
|
|
395
|
+
file,
|
|
396
|
+
updates,
|
|
397
|
+
errors,
|
|
398
|
+
warnings,
|
|
399
|
+
unwrappedExpressions,
|
|
400
|
+
pkgs,
|
|
401
|
+
parsingOptions,
|
|
402
|
+
importedFunctionsMap,
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
unwrappedExpressions.push(generate(node).code);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else if (t.isParenthesizedExpression(node)) {
|
|
410
|
+
const child = node.expression;
|
|
411
|
+
return buildJSXTree({
|
|
412
|
+
importAliases,
|
|
413
|
+
node: child,
|
|
414
|
+
unwrappedExpressions,
|
|
415
|
+
visited,
|
|
416
|
+
callStack,
|
|
417
|
+
updates,
|
|
418
|
+
errors,
|
|
419
|
+
warnings,
|
|
420
|
+
file,
|
|
421
|
+
insideT,
|
|
422
|
+
parsingOptions,
|
|
423
|
+
scopeNode,
|
|
424
|
+
importedFunctionsMap,
|
|
425
|
+
pkgs,
|
|
426
|
+
inStatic,
|
|
427
|
+
helperPath: helperPath.get('expression'),
|
|
428
|
+
});
|
|
429
|
+
}
|
|
343
430
|
// If it's some other JS expression
|
|
344
431
|
else if (t.isIdentifier(node) ||
|
|
345
432
|
t.isMemberExpression(node) ||
|
|
@@ -347,11 +434,17 @@ export function buildJSXTree({ importAliases, node, unwrappedExpressions, visite
|
|
|
347
434
|
t.isBinaryExpression(node) ||
|
|
348
435
|
t.isLogicalExpression(node) ||
|
|
349
436
|
t.isConditionalExpression(node)) {
|
|
350
|
-
|
|
437
|
+
unwrappedExpressions.push(generate(node).code);
|
|
351
438
|
}
|
|
352
439
|
else {
|
|
353
|
-
|
|
440
|
+
if (node === undefined) {
|
|
441
|
+
unwrappedExpressions.push(node);
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
unwrappedExpressions.push(generate(node).code);
|
|
445
|
+
}
|
|
354
446
|
}
|
|
447
|
+
return null;
|
|
355
448
|
}
|
|
356
449
|
// end buildJSXTree
|
|
357
450
|
// Parses a JSX element and adds it to the updates array
|
|
@@ -393,6 +486,8 @@ export function parseJSXElement({ importAliases, node, originalName, pkgs, updat
|
|
|
393
486
|
insideT: false,
|
|
394
487
|
parsingOptions,
|
|
395
488
|
importedFunctionsMap,
|
|
489
|
+
inStatic: false,
|
|
490
|
+
helperPath: scopeNode,
|
|
396
491
|
});
|
|
397
492
|
// Strip the outer <T> component if necessary
|
|
398
493
|
const jsxTree = isElementNode(treeResult) && treeResult.props?.children
|
|
@@ -438,86 +533,6 @@ export function parseJSXElement({ importAliases, node, originalName, pkgs, updat
|
|
|
438
533
|
});
|
|
439
534
|
}
|
|
440
535
|
}
|
|
441
|
-
/**
|
|
442
|
-
* Resolves an invocation inside of a <Static> component. It will resolve the function, and build
|
|
443
|
-
* a jsx tree for each return inside of the function definition.
|
|
444
|
-
*
|
|
445
|
-
* function getOtherSubject() {
|
|
446
|
-
* return <div>Jane</div>;
|
|
447
|
-
* }
|
|
448
|
-
*
|
|
449
|
-
* function getSubject() {
|
|
450
|
-
* if (condition) return getOtherSubject();
|
|
451
|
-
* return <div>John</div>;
|
|
452
|
-
* }
|
|
453
|
-
* ...
|
|
454
|
-
* <Static>
|
|
455
|
-
* {getSubject()}
|
|
456
|
-
* </Static>
|
|
457
|
-
*/
|
|
458
|
-
function resolveStaticComponentChildren({ importAliases, scopeNode, children, unwrappedExpressions, visited, updates, errors, warnings, file, callStack, parsingOptions, importedFunctionsMap, pkgs, props, }) {
|
|
459
|
-
const result = {
|
|
460
|
-
nodeType: 'element',
|
|
461
|
-
type: STATIC_COMPONENT,
|
|
462
|
-
props,
|
|
463
|
-
};
|
|
464
|
-
let found = false;
|
|
465
|
-
// Create children array if necessary
|
|
466
|
-
if (children.length) {
|
|
467
|
-
result.props.children = [];
|
|
468
|
-
}
|
|
469
|
-
for (const child of children) {
|
|
470
|
-
// Ignore whitespace outside of jsx container
|
|
471
|
-
if (t.isJSXText(child) && child.value.trim() === '') {
|
|
472
|
-
result.props.children.push(child.value);
|
|
473
|
-
continue;
|
|
474
|
-
}
|
|
475
|
-
// Must be an expression container with a function invocation
|
|
476
|
-
if (!t.isJSXExpressionContainer(child) ||
|
|
477
|
-
!((t.isCallExpression(child.expression) &&
|
|
478
|
-
t.isIdentifier(child.expression.callee)) ||
|
|
479
|
-
(t.isAwaitExpression(child.expression) &&
|
|
480
|
-
t.isCallExpression(child.expression.argument) &&
|
|
481
|
-
t.isIdentifier(child.expression.argument.callee))) ||
|
|
482
|
-
found // There can only be one invocation inside of a <Static> component
|
|
483
|
-
) {
|
|
484
|
-
errors.push(warnInvalidStaticChildSync(file, `${child.loc?.start?.line}:${child.loc?.start?.column}`));
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
// Set found to true
|
|
488
|
-
found = true;
|
|
489
|
-
// Get callee and binding from scope
|
|
490
|
-
const callee = (t.isAwaitExpression(child.expression)
|
|
491
|
-
? child.expression.argument.callee
|
|
492
|
-
: child.expression.callee);
|
|
493
|
-
const calleeBinding = scopeNode.scope.getBinding(callee.name);
|
|
494
|
-
if (!calleeBinding) {
|
|
495
|
-
warnings.add(warnFunctionNotFoundSync(file, callee.name, `${callee.loc?.start?.line}:${callee.loc?.start?.column}`));
|
|
496
|
-
continue;
|
|
497
|
-
}
|
|
498
|
-
// Function is found locally, return wrapped in an expression
|
|
499
|
-
const staticFunctionInvocation = resolveStaticFunctionInvocationFromBinding({
|
|
500
|
-
importAliases,
|
|
501
|
-
calleeBinding,
|
|
502
|
-
callee,
|
|
503
|
-
visited,
|
|
504
|
-
callStack,
|
|
505
|
-
file,
|
|
506
|
-
updates,
|
|
507
|
-
errors,
|
|
508
|
-
warnings,
|
|
509
|
-
unwrappedExpressions,
|
|
510
|
-
pkgs,
|
|
511
|
-
parsingOptions,
|
|
512
|
-
importedFunctionsMap,
|
|
513
|
-
});
|
|
514
|
-
result.props.children.push({
|
|
515
|
-
nodeType: 'expression',
|
|
516
|
-
result: staticFunctionInvocation,
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
return result;
|
|
520
|
-
}
|
|
521
536
|
function resolveStaticFunctionInvocationFromBinding({ importAliases, calleeBinding, callee, unwrappedExpressions, visited, callStack, file, updates, errors, warnings, parsingOptions, importedFunctionsMap, pkgs, }) {
|
|
522
537
|
function withRecusionGuard({ cb, filename, functionName, }) {
|
|
523
538
|
const cacheKey = `${filename}::${functionName}`;
|
|
@@ -657,7 +672,7 @@ function processFunctionInFile({ filePath, functionName, visited, callStack, par
|
|
|
657
672
|
});
|
|
658
673
|
const { importAliases } = getPathsAndAliases(ast, pkgs);
|
|
659
674
|
// Collect all imports in this file to track cross-file function calls
|
|
660
|
-
let importedFunctionsMap;
|
|
675
|
+
let importedFunctionsMap = new Map();
|
|
661
676
|
traverse(ast, {
|
|
662
677
|
Program(path) {
|
|
663
678
|
importedFunctionsMap = buildImportMap(path);
|
|
@@ -794,9 +809,8 @@ function processFunctionDeclarationNodePath({ functionName, path, importAliases,
|
|
|
794
809
|
if (!returnNodePath.isExpression()) {
|
|
795
810
|
return;
|
|
796
811
|
}
|
|
797
|
-
result.branches.push(
|
|
812
|
+
result.branches.push(processStaticExpression({
|
|
798
813
|
unwrappedExpressions,
|
|
799
|
-
functionName,
|
|
800
814
|
pkgs,
|
|
801
815
|
callStack,
|
|
802
816
|
scopeNode: returnNodePath,
|
|
@@ -837,9 +851,8 @@ function processVariableDeclarationNodePath({ functionName, path, importAliases,
|
|
|
837
851
|
const bodyNodePath = arrowFunctionPath.get('body');
|
|
838
852
|
if (bodyNodePath.isExpression()) {
|
|
839
853
|
// process expression return
|
|
840
|
-
result.branches.push(
|
|
854
|
+
result.branches.push(processStaticExpression({
|
|
841
855
|
unwrappedExpressions,
|
|
842
|
-
functionName,
|
|
843
856
|
pkgs,
|
|
844
857
|
scopeNode: arrowFunctionPath,
|
|
845
858
|
expressionNodePath: bodyNodePath,
|
|
@@ -865,9 +878,8 @@ function processVariableDeclarationNodePath({ functionName, path, importAliases,
|
|
|
865
878
|
if (!returnNodePath.isExpression()) {
|
|
866
879
|
return;
|
|
867
880
|
}
|
|
868
|
-
result.branches.push(
|
|
881
|
+
result.branches.push(processStaticExpression({
|
|
869
882
|
unwrappedExpressions,
|
|
870
|
-
functionName,
|
|
871
883
|
pkgs,
|
|
872
884
|
scopeNode: returnPath,
|
|
873
885
|
expressionNodePath: returnNodePath,
|
|
@@ -891,15 +903,15 @@ function processVariableDeclarationNodePath({ functionName, path, importAliases,
|
|
|
891
903
|
return result;
|
|
892
904
|
}
|
|
893
905
|
/**
|
|
894
|
-
* Process a expression
|
|
906
|
+
* Process a <Static> expression
|
|
895
907
|
*/
|
|
896
|
-
function
|
|
908
|
+
function processStaticExpression({ unwrappedExpressions, scopeNode, expressionNodePath, importAliases, visited, callStack, updates, errors, warnings, file, parsingOptions, importedFunctionsMap, pkgs, }) {
|
|
897
909
|
// // If the node is null, return
|
|
898
910
|
// if (expressionNodePath == null) return null;
|
|
899
911
|
// Remove parentheses if they exist
|
|
900
912
|
if (t.isParenthesizedExpression(expressionNodePath.node)) {
|
|
901
913
|
// ex: return (value)
|
|
902
|
-
return
|
|
914
|
+
return processStaticExpression({
|
|
903
915
|
unwrappedExpressions,
|
|
904
916
|
importAliases,
|
|
905
917
|
scopeNode,
|
|
@@ -911,7 +923,6 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
911
923
|
warnings,
|
|
912
924
|
file,
|
|
913
925
|
parsingOptions,
|
|
914
|
-
functionName,
|
|
915
926
|
importedFunctionsMap,
|
|
916
927
|
pkgs,
|
|
917
928
|
});
|
|
@@ -925,7 +936,7 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
925
936
|
warnings.add(warnFunctionNotFoundSync(file, callee.name, `${callee.loc?.start?.line}:${callee.loc?.start?.column}`));
|
|
926
937
|
return null;
|
|
927
938
|
}
|
|
928
|
-
// Function is found
|
|
939
|
+
// Function is found
|
|
929
940
|
return resolveStaticFunctionInvocationFromBinding({
|
|
930
941
|
importAliases,
|
|
931
942
|
calleeBinding,
|
|
@@ -952,7 +963,7 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
952
963
|
warnings.add(warnFunctionNotFoundSync(file, callee.name, `${callee.loc?.start?.line}:${callee.loc?.start?.column}`));
|
|
953
964
|
return null;
|
|
954
965
|
}
|
|
955
|
-
// Function is found
|
|
966
|
+
// Function is found
|
|
956
967
|
return resolveStaticFunctionInvocationFromBinding({
|
|
957
968
|
importAliases,
|
|
958
969
|
calleeBinding,
|
|
@@ -987,6 +998,8 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
987
998
|
scopeNode,
|
|
988
999
|
importedFunctionsMap,
|
|
989
1000
|
pkgs,
|
|
1001
|
+
inStatic: true,
|
|
1002
|
+
helperPath: expressionNodePath,
|
|
990
1003
|
});
|
|
991
1004
|
}
|
|
992
1005
|
else if (t.isConditionalExpression(expressionNodePath.node)) {
|
|
@@ -996,7 +1009,7 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
996
1009
|
const alternateNodePath = expressionNodePath.get('alternate');
|
|
997
1010
|
const result = {
|
|
998
1011
|
nodeType: 'multiplication',
|
|
999
|
-
branches: [consequentNodePath, alternateNodePath].map((expressionNodePath) =>
|
|
1012
|
+
branches: [consequentNodePath, alternateNodePath].map((expressionNodePath) => processStaticExpression({
|
|
1000
1013
|
unwrappedExpressions,
|
|
1001
1014
|
importAliases,
|
|
1002
1015
|
scopeNode,
|
|
@@ -1008,7 +1021,6 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
1008
1021
|
warnings,
|
|
1009
1022
|
file,
|
|
1010
1023
|
parsingOptions,
|
|
1011
|
-
functionName,
|
|
1012
1024
|
importedFunctionsMap,
|
|
1013
1025
|
pkgs,
|
|
1014
1026
|
})),
|
|
@@ -1031,6 +1043,8 @@ function processReturnExpression({ unwrappedExpressions, scopeNode, expressionNo
|
|
|
1031
1043
|
scopeNode,
|
|
1032
1044
|
importedFunctionsMap,
|
|
1033
1045
|
pkgs,
|
|
1046
|
+
inStatic: true,
|
|
1047
|
+
helperPath: expressionNodePath,
|
|
1034
1048
|
});
|
|
1035
1049
|
}
|
|
1036
1050
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { NodePath } from '@babel/traverse';
|
|
3
|
+
import { ParsingConfigOptions } from '../../../types/parsing.js';
|
|
4
|
+
import { StringNode } from './types.js';
|
|
5
|
+
export type StringTree = (string | StringTree)[];
|
|
6
|
+
/**
|
|
7
|
+
* Checks if an expression is static or uses declareStatic
|
|
8
|
+
* Returns a Node representing the parsed expression
|
|
9
|
+
* @param expr - The expression to check
|
|
10
|
+
* @param tPath - NodePath for scope resolution
|
|
11
|
+
* @param file - Current file path
|
|
12
|
+
* @param parsingOptions - Parsing configuration
|
|
13
|
+
* @returns Node | null - The parsed node, or null if invalid
|
|
14
|
+
*/
|
|
15
|
+
export declare function handleStaticExpression(expr: t.Expression, tPath: NodePath, file: string, parsingOptions: ParsingConfigOptions, errors: string[]): StringNode | null;
|