scancscode 1.0.35 → 1.0.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/.trae/specs/fix-string-expression-capture-range/checklist.md +7 -0
- package/.trae/specs/fix-string-expression-capture-range/spec.md +96 -0
- package/.trae/specs/fix-string-expression-capture-range/tasks.md +25 -0
- package/.trae/specs/handle-null-value/checklist.md +10 -0
- package/.trae/specs/handle-null-value/spec.md +57 -0
- package/.trae/specs/handle-null-value/tasks.md +40 -0
- package/.trae/specs/handle-right-value-expression/checklist.md +9 -0
- package/.trae/specs/handle-right-value-expression/spec.md +72 -0
- package/.trae/specs/handle-right-value-expression/tasks.md +53 -0
- package/.trae/specs/process-function-call-interpolated-strings/checklist.md +12 -0
- package/.trae/specs/process-function-call-interpolated-strings/spec.md +80 -0
- package/.trae/specs/process-function-call-interpolated-strings/tasks.md +73 -0
- package/dist/src/CSharpStringExtractor.js +547 -117
- package/dist/test/CSharpStringExtractor.test.js +174 -0
- package/package.json +1 -1
- package/src/CSharpStringExtractor.ts +581 -116
- package/test/CSharpStringExtractor.test.ts +185 -0
- package/dist/debug-arg.js +0 -30
- package/dist/debug-args.js +0 -34
- package/dist/debug-comment-5.js +0 -25
- package/dist/debug-comment-strings.js +0 -24
- package/dist/debug-full.js +0 -14
- package/dist/debug-template-issue.js +0 -33
- package/dist/debug-test-5.js +0 -23
- package/dist/debug-test.js +0 -21
- package/dist/debug.js +0 -15
- package/dist/simple-debug.js +0 -27
- package/dist/simple-test.js +0 -61
- package/dist/temp-original-source.js +0 -1
- package/dist/test-logic.js +0 -79
- package/dist/test-regex.js +0 -13
|
@@ -181,15 +181,22 @@ class CSharpStringExtractor {
|
|
|
181
181
|
const trimmedStatement = statement.trim();
|
|
182
182
|
const isStringFormatCall = trimmedStatement.startsWith('string.Format(');
|
|
183
183
|
const isTextAssignment = /\w+\.text\s*=/.test(trimmedStatement);
|
|
184
|
-
const isRegularAssignment =
|
|
184
|
+
const isRegularAssignment = /^[\s\S]*?=/.test(trimmedStatement);
|
|
185
185
|
const isCaseOrDefault = trimmedStatement.startsWith('case ') || trimmedStatement.startsWith('default:');
|
|
186
186
|
const isFunctionCall = /^\s*[\w\.<>]+[\s\w\.<>]*\(/.test(trimmedStatement) && !isStringFormatCall && !isCaseOrDefault;
|
|
187
|
+
if ((isRegularAssignment && !isTextAssignment) && !isFunctionCall) {
|
|
188
|
+
const assignmentIndex = statement.indexOf('=');
|
|
189
|
+
if (assignmentIndex !== -1) {
|
|
190
|
+
this.processAllFunctionCallsInRange(originalIndex, originalIndex + assignmentIndex, code, snippets, trClass, trFormatMethod, trMethod);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
187
193
|
if (isFunctionCall && !isStringFormatCall) {
|
|
188
194
|
this.processFunctionCallArguments(statement, originalIndex, code, snippets, trClass, trFormatMethod, trMethod);
|
|
189
195
|
}
|
|
190
196
|
else {
|
|
191
197
|
const extractionResult = this.extractValueExpression(statement, originalIndex, code);
|
|
192
198
|
const { valueExpression, valueExpressionIndex } = extractionResult;
|
|
199
|
+
const hasStringInValue = /"(?:[^"\\]|\\.)*"|'[^']*'|\$"[\s\S]*?"|\$@"[\s\S]*?"|@\$"[\s\S]*?"/.test(valueExpression);
|
|
193
200
|
let alreadyExists = false;
|
|
194
201
|
for (const snippet of snippets) {
|
|
195
202
|
if (snippet.originalIndex === valueExpressionIndex) {
|
|
@@ -197,13 +204,18 @@ class CSharpStringExtractor {
|
|
|
197
204
|
break;
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
|
-
if (!alreadyExists) {
|
|
207
|
+
if (!alreadyExists && (hasStringInValue || isTextAssignment)) {
|
|
201
208
|
const snippet = new CodeSnippet();
|
|
202
209
|
snippet.originalIndex = valueExpressionIndex;
|
|
203
210
|
snippet.originalCode = valueExpression;
|
|
204
211
|
snippet.originalContext = valueExpression;
|
|
205
212
|
this.variableIndex = 0;
|
|
206
|
-
|
|
213
|
+
if (isCaseOrDefault) {
|
|
214
|
+
this.processSingleArgument(snippet, valueExpression, trClass, trFormatMethod, trMethod);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
this.processStatementAndExtractValue(snippet, statement, valueExpression, trClass, trFormatMethod, trMethod);
|
|
218
|
+
}
|
|
207
219
|
snippets.push(snippet);
|
|
208
220
|
}
|
|
209
221
|
}
|
|
@@ -243,6 +255,8 @@ class CSharpStringExtractor {
|
|
|
243
255
|
let inClassBody = true;
|
|
244
256
|
let inComment = false;
|
|
245
257
|
let commentType = '';
|
|
258
|
+
let isInterpolatedString = false;
|
|
259
|
+
let interpolatedBraceDepth = 0;
|
|
246
260
|
for (j = braceOpenIndex + 1; j < code.length; j++) {
|
|
247
261
|
const char = code[j];
|
|
248
262
|
const nextChar = j + 1 < code.length ? code[j + 1] : '';
|
|
@@ -288,9 +302,11 @@ class CSharpStringExtractor {
|
|
|
288
302
|
continue;
|
|
289
303
|
}
|
|
290
304
|
if (inString) {
|
|
291
|
-
if (char === stringDelimiter) {
|
|
305
|
+
if (char === stringDelimiter && (!isInterpolatedString || interpolatedBraceDepth === 0)) {
|
|
292
306
|
inString = false;
|
|
293
307
|
stringDelimiter = '';
|
|
308
|
+
isInterpolatedString = false;
|
|
309
|
+
interpolatedBraceDepth = 0;
|
|
294
310
|
if (afterEqual && braceDepth === 1) {
|
|
295
311
|
const stringLiteral = code.substring(stringStartPos, j + 1);
|
|
296
312
|
let alreadyExists = false;
|
|
@@ -311,11 +327,20 @@ class CSharpStringExtractor {
|
|
|
311
327
|
}
|
|
312
328
|
}
|
|
313
329
|
}
|
|
330
|
+
else if (isInterpolatedString) {
|
|
331
|
+
if (char === '{' && !escapeNext) {
|
|
332
|
+
interpolatedBraceDepth++;
|
|
333
|
+
}
|
|
334
|
+
else if (char === '}' && !escapeNext && interpolatedBraceDepth > 0) {
|
|
335
|
+
interpolatedBraceDepth--;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
314
338
|
continue;
|
|
315
339
|
}
|
|
316
340
|
if (!inString && afterEqual && braceDepth === 1 && j + 1 < code.length && char === '$') {
|
|
317
341
|
if (code[j + 1] === '"') {
|
|
318
342
|
inString = true;
|
|
343
|
+
isInterpolatedString = true;
|
|
319
344
|
stringDelimiter = '"';
|
|
320
345
|
stringStartPos = j;
|
|
321
346
|
j++;
|
|
@@ -323,6 +348,7 @@ class CSharpStringExtractor {
|
|
|
323
348
|
}
|
|
324
349
|
else if (code[j + 1] === '@' && j + 2 < code.length && code[j + 2] === '"') {
|
|
325
350
|
inString = true;
|
|
351
|
+
isInterpolatedString = true;
|
|
326
352
|
stringDelimiter = '"';
|
|
327
353
|
stringStartPos = j;
|
|
328
354
|
j += 2;
|
|
@@ -331,14 +357,16 @@ class CSharpStringExtractor {
|
|
|
331
357
|
}
|
|
332
358
|
else if (!inString && afterEqual && braceDepth === 1 && j + 1 < code.length && char === '@' && code[j + 1] === '$' && j + 2 < code.length && code[j + 2] === '"') {
|
|
333
359
|
inString = true;
|
|
360
|
+
isInterpolatedString = true;
|
|
334
361
|
stringDelimiter = '"';
|
|
335
362
|
stringStartPos = j;
|
|
336
363
|
j += 2;
|
|
337
364
|
continue;
|
|
338
365
|
}
|
|
339
|
-
else if (!inString &&
|
|
366
|
+
else if (!inString && char === '"') {
|
|
340
367
|
if (afterEqual && braceDepth === 1) {
|
|
341
368
|
inString = true;
|
|
369
|
+
isInterpolatedString = false;
|
|
342
370
|
stringDelimiter = char;
|
|
343
371
|
stringStartPos = j;
|
|
344
372
|
}
|
|
@@ -406,6 +434,8 @@ class CSharpStringExtractor {
|
|
|
406
434
|
let commentType = '';
|
|
407
435
|
let inAnonymousFunction = false;
|
|
408
436
|
let anonymousFunctionBraceDepth = 0;
|
|
437
|
+
let isInterpolatedString = false;
|
|
438
|
+
let interpolatedBraceDepth = 0;
|
|
409
439
|
for (j = braceOpenIndex + 1; j < code.length; j++) {
|
|
410
440
|
const char = code[j];
|
|
411
441
|
const nextChar = j + 1 < code.length ? code[j + 1] : '';
|
|
@@ -457,9 +487,11 @@ class CSharpStringExtractor {
|
|
|
457
487
|
continue;
|
|
458
488
|
}
|
|
459
489
|
if (inString) {
|
|
460
|
-
if (char === stringDelimiter) {
|
|
490
|
+
if (char === stringDelimiter && (!isInterpolatedString || interpolatedBraceDepth === 0)) {
|
|
461
491
|
inString = false;
|
|
462
492
|
stringDelimiter = '';
|
|
493
|
+
isInterpolatedString = false;
|
|
494
|
+
interpolatedBraceDepth = 0;
|
|
463
495
|
if (afterEqual || inAnonymousFunction) {
|
|
464
496
|
const stringLiteral = code.substring(stringStartPos, j + 1);
|
|
465
497
|
let alreadyExists = false;
|
|
@@ -480,11 +512,20 @@ class CSharpStringExtractor {
|
|
|
480
512
|
}
|
|
481
513
|
}
|
|
482
514
|
}
|
|
515
|
+
else if (isInterpolatedString) {
|
|
516
|
+
if (char === '{' && !escapeNext) {
|
|
517
|
+
interpolatedBraceDepth++;
|
|
518
|
+
}
|
|
519
|
+
else if (char === '}' && !escapeNext && interpolatedBraceDepth > 0) {
|
|
520
|
+
interpolatedBraceDepth--;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
483
523
|
continue;
|
|
484
524
|
}
|
|
485
525
|
if (!inString && (afterEqual || inAnonymousFunction) && j + 1 < code.length && char === '$') {
|
|
486
526
|
if (code[j + 1] === '"') {
|
|
487
527
|
inString = true;
|
|
528
|
+
isInterpolatedString = true;
|
|
488
529
|
stringDelimiter = '"';
|
|
489
530
|
stringStartPos = j;
|
|
490
531
|
j++;
|
|
@@ -492,6 +533,7 @@ class CSharpStringExtractor {
|
|
|
492
533
|
}
|
|
493
534
|
else if (code[j + 1] === '@' && j + 2 < code.length && code[j + 2] === '"') {
|
|
494
535
|
inString = true;
|
|
536
|
+
isInterpolatedString = true;
|
|
495
537
|
stringDelimiter = '"';
|
|
496
538
|
stringStartPos = j;
|
|
497
539
|
j += 2;
|
|
@@ -500,14 +542,16 @@ class CSharpStringExtractor {
|
|
|
500
542
|
}
|
|
501
543
|
else if (!inString && (afterEqual || inAnonymousFunction) && j + 1 < code.length && char === '@' && code[j + 1] === '$' && j + 2 < code.length && code[j + 2] === '"') {
|
|
502
544
|
inString = true;
|
|
545
|
+
isInterpolatedString = true;
|
|
503
546
|
stringDelimiter = '"';
|
|
504
547
|
stringStartPos = j;
|
|
505
548
|
j += 2;
|
|
506
549
|
continue;
|
|
507
550
|
}
|
|
508
|
-
else if (!inString &&
|
|
551
|
+
else if (!inString && char === '"') {
|
|
509
552
|
if (afterEqual || inAnonymousFunction) {
|
|
510
553
|
inString = true;
|
|
554
|
+
isInterpolatedString = false;
|
|
511
555
|
stringDelimiter = char;
|
|
512
556
|
stringStartPos = j;
|
|
513
557
|
}
|
|
@@ -555,13 +599,11 @@ class CSharpStringExtractor {
|
|
|
555
599
|
if (i + 1 < code.length && code[i] === '/' && code[i + 1] === '/') {
|
|
556
600
|
commentType = '//';
|
|
557
601
|
if (i + 2 < code.length && code[i + 2] === '/') {
|
|
558
|
-
// 这是文档注释(三个或更多连续 /),跳过它
|
|
559
602
|
isDocComment = true;
|
|
560
603
|
inComment = true;
|
|
561
604
|
i += 3;
|
|
562
605
|
}
|
|
563
606
|
else {
|
|
564
|
-
// 普通注释,正常处理
|
|
565
607
|
inComment = true;
|
|
566
608
|
i += 2;
|
|
567
609
|
}
|
|
@@ -576,7 +618,6 @@ class CSharpStringExtractor {
|
|
|
576
618
|
continue;
|
|
577
619
|
}
|
|
578
620
|
if (isDocComment) {
|
|
579
|
-
// 对于文档注释,我们只需要跳过,不处理任何内容!
|
|
580
621
|
while (i < code.length && inComment) {
|
|
581
622
|
const char = code[i];
|
|
582
623
|
if (char === '\n') {
|
|
@@ -592,9 +633,11 @@ class CSharpStringExtractor {
|
|
|
592
633
|
let stringDelimiter = '';
|
|
593
634
|
let stringStartPos = -1;
|
|
594
635
|
let interpolatedBraceDepth = 0;
|
|
636
|
+
let isInterpolatedString = false;
|
|
595
637
|
while (i < code.length && inComment) {
|
|
596
638
|
const char = code[i];
|
|
597
639
|
const nextChar = i + 1 < code.length ? code[i + 1] : '';
|
|
640
|
+
const nextNextChar = i + 2 < code.length ? code[i + 2] : '';
|
|
598
641
|
if (commentType === '//') {
|
|
599
642
|
if (char === '\n') {
|
|
600
643
|
inComment = false;
|
|
@@ -619,9 +662,11 @@ class CSharpStringExtractor {
|
|
|
619
662
|
continue;
|
|
620
663
|
}
|
|
621
664
|
if (inString) {
|
|
622
|
-
if (char === stringDelimiter) {
|
|
665
|
+
if (char === stringDelimiter && (!isInterpolatedString || interpolatedBraceDepth === 0)) {
|
|
623
666
|
inString = false;
|
|
624
667
|
stringDelimiter = '';
|
|
668
|
+
isInterpolatedString = false;
|
|
669
|
+
interpolatedBraceDepth = 0;
|
|
625
670
|
let alreadyExists = false;
|
|
626
671
|
for (const snippet of snippets) {
|
|
627
672
|
if (snippet.originalIndex === stringStartPos) {
|
|
@@ -640,12 +685,21 @@ class CSharpStringExtractor {
|
|
|
640
685
|
snippets.push(snippet);
|
|
641
686
|
}
|
|
642
687
|
}
|
|
688
|
+
else if (isInterpolatedString) {
|
|
689
|
+
if (char === '{' && !escapeNext) {
|
|
690
|
+
interpolatedBraceDepth++;
|
|
691
|
+
}
|
|
692
|
+
else if (char === '}' && !escapeNext && interpolatedBraceDepth > 0) {
|
|
693
|
+
interpolatedBraceDepth--;
|
|
694
|
+
}
|
|
695
|
+
}
|
|
643
696
|
i++;
|
|
644
697
|
continue;
|
|
645
698
|
}
|
|
646
699
|
if (!inString && i + 1 < code.length && char === '$') {
|
|
647
700
|
if (code[i + 1] === '"') {
|
|
648
701
|
inString = true;
|
|
702
|
+
isInterpolatedString = true;
|
|
649
703
|
stringDelimiter = '"';
|
|
650
704
|
stringStartPos = i;
|
|
651
705
|
i += 2;
|
|
@@ -653,6 +707,7 @@ class CSharpStringExtractor {
|
|
|
653
707
|
}
|
|
654
708
|
else if (code[i + 1] === '@' && i + 2 < code.length && code[i + 2] === '"') {
|
|
655
709
|
inString = true;
|
|
710
|
+
isInterpolatedString = true;
|
|
656
711
|
stringDelimiter = '"';
|
|
657
712
|
stringStartPos = i;
|
|
658
713
|
i += 3;
|
|
@@ -661,13 +716,15 @@ class CSharpStringExtractor {
|
|
|
661
716
|
}
|
|
662
717
|
else if (!inString && i + 1 < code.length && char === '@' && code[i + 1] === '$' && i + 2 < code.length && code[i + 2] === '"') {
|
|
663
718
|
inString = true;
|
|
719
|
+
isInterpolatedString = true;
|
|
664
720
|
stringDelimiter = '"';
|
|
665
721
|
stringStartPos = i;
|
|
666
722
|
i += 3;
|
|
667
723
|
continue;
|
|
668
724
|
}
|
|
669
|
-
else if (!inString &&
|
|
725
|
+
else if (!inString && char === '"') {
|
|
670
726
|
inString = true;
|
|
727
|
+
isInterpolatedString = false;
|
|
671
728
|
stringDelimiter = char;
|
|
672
729
|
stringStartPos = i;
|
|
673
730
|
i++;
|
|
@@ -1684,11 +1741,15 @@ class CSharpStringExtractor {
|
|
|
1684
1741
|
processTextAssignments(statement, snippet, trClass, trFormatMethod, trMethod) {
|
|
1685
1742
|
const textAssignmentRegex = /([\s\S]*?\.text\s*=\s*)([\s\S]*?)(?=;|$)/;
|
|
1686
1743
|
const match = textAssignmentRegex.exec(statement);
|
|
1687
|
-
|
|
1688
|
-
|
|
1744
|
+
let prefix = null;
|
|
1745
|
+
let value;
|
|
1746
|
+
if (match) {
|
|
1747
|
+
prefix = match[1];
|
|
1748
|
+
value = match[2];
|
|
1749
|
+
}
|
|
1750
|
+
else {
|
|
1751
|
+
value = statement;
|
|
1689
1752
|
}
|
|
1690
|
-
const prefix = match[1];
|
|
1691
|
-
const value = match[2];
|
|
1692
1753
|
let processedValue = value;
|
|
1693
1754
|
if (value.includes('?') && value.includes(':')) {
|
|
1694
1755
|
const trueBranchMatch = value.match(/\?\s*([^:]+)\s*:/);
|
|
@@ -1734,7 +1795,7 @@ class CSharpStringExtractor {
|
|
|
1734
1795
|
else {
|
|
1735
1796
|
const trimmedValue = value.trim();
|
|
1736
1797
|
if (!trimmedValue.includes(`${trClass}.${trFormatMethod}(`) && !trimmedValue.endsWith(`.${trMethod}()`)) {
|
|
1737
|
-
if (trimmedValue.startsWith('"') || /^\w+/.test(trimmedValue) || trimmedValue.startsWith('(')) {
|
|
1798
|
+
if (trimmedValue !== 'null' && (trimmedValue.startsWith('"') || /^\w+/.test(trimmedValue) || trimmedValue.startsWith('('))) {
|
|
1738
1799
|
const whitespaceBefore = value.substring(0, value.search(/\S/));
|
|
1739
1800
|
const actualValue = value.substring(value.search(/\S/));
|
|
1740
1801
|
const whitespaceAfter = actualValue.search(/\s*$/) === 0 ? actualValue : actualValue.substring(actualValue.search(/\S/) + trimmedValue.length);
|
|
@@ -1742,12 +1803,17 @@ class CSharpStringExtractor {
|
|
|
1742
1803
|
}
|
|
1743
1804
|
}
|
|
1744
1805
|
}
|
|
1745
|
-
if (
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1806
|
+
if (prefix) {
|
|
1807
|
+
if (processedValue !== value) {
|
|
1808
|
+
const hasSemicolon = statement.trim().endsWith(';');
|
|
1809
|
+
const result = prefix + processedValue;
|
|
1810
|
+
return hasSemicolon ? result + ';' : result;
|
|
1811
|
+
}
|
|
1812
|
+
return statement;
|
|
1813
|
+
}
|
|
1814
|
+
else {
|
|
1815
|
+
return processedValue;
|
|
1749
1816
|
}
|
|
1750
|
-
return statement;
|
|
1751
1817
|
}
|
|
1752
1818
|
processStringConcatenation(statement, snippet, trClass, trFormatMethod, trMethod) {
|
|
1753
1819
|
if (!statement.includes('+')) {
|
|
@@ -1801,10 +1867,66 @@ class CSharpStringExtractor {
|
|
|
1801
1867
|
}
|
|
1802
1868
|
const hasSemicolon = statement.endsWith(';');
|
|
1803
1869
|
let statementWithoutSemicolon = hasSemicolon ? statement.slice(0, -1) : statement;
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1870
|
+
// Find actual assignment operator = that's not inside string, parentheses, etc.
|
|
1871
|
+
let assignmentIndex = -1;
|
|
1872
|
+
let tempInString = false;
|
|
1873
|
+
let tempEscapeNext = false;
|
|
1874
|
+
let tempStringDelimiter = '';
|
|
1875
|
+
let parenDepth = 0;
|
|
1876
|
+
let braceDepth = 0;
|
|
1877
|
+
let bracketDepth = 0;
|
|
1878
|
+
for (let i = 0; i < statementWithoutSemicolon.length; i++) {
|
|
1879
|
+
const char = statementWithoutSemicolon[i];
|
|
1880
|
+
if (tempEscapeNext) {
|
|
1881
|
+
tempEscapeNext = false;
|
|
1882
|
+
continue;
|
|
1883
|
+
}
|
|
1884
|
+
if (char === '\\') {
|
|
1885
|
+
tempEscapeNext = true;
|
|
1886
|
+
continue;
|
|
1887
|
+
}
|
|
1888
|
+
if (tempInString) {
|
|
1889
|
+
if (char === tempStringDelimiter) {
|
|
1890
|
+
tempInString = false;
|
|
1891
|
+
tempStringDelimiter = '';
|
|
1892
|
+
}
|
|
1893
|
+
continue;
|
|
1894
|
+
}
|
|
1895
|
+
if (char === '"' || char === "'") {
|
|
1896
|
+
tempInString = true;
|
|
1897
|
+
tempStringDelimiter = char;
|
|
1898
|
+
continue;
|
|
1899
|
+
}
|
|
1900
|
+
if (char === '(') {
|
|
1901
|
+
parenDepth++;
|
|
1902
|
+
}
|
|
1903
|
+
else if (char === ')') {
|
|
1904
|
+
parenDepth--;
|
|
1905
|
+
}
|
|
1906
|
+
else if (char === '{') {
|
|
1907
|
+
braceDepth++;
|
|
1908
|
+
}
|
|
1909
|
+
else if (char === '}') {
|
|
1910
|
+
braceDepth--;
|
|
1911
|
+
}
|
|
1912
|
+
else if (char === '[') {
|
|
1913
|
+
bracketDepth++;
|
|
1914
|
+
}
|
|
1915
|
+
else if (char === ']') {
|
|
1916
|
+
bracketDepth--;
|
|
1917
|
+
}
|
|
1918
|
+
else if (char === '=' && parenDepth === 0 && braceDepth === 0 && bracketDepth === 0) {
|
|
1919
|
+
assignmentIndex = i;
|
|
1920
|
+
break;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
let leftSide = '';
|
|
1924
|
+
let rightSide = '';
|
|
1925
|
+
if (assignmentIndex !== -1) {
|
|
1926
|
+
leftSide = statementWithoutSemicolon.substring(0, assignmentIndex + 1); // Include =
|
|
1927
|
+
rightSide = statementWithoutSemicolon.substring(assignmentIndex + 1);
|
|
1928
|
+
}
|
|
1929
|
+
if (assignmentIndex !== -1) {
|
|
1808
1930
|
const parts = this.splitExpression(rightSide);
|
|
1809
1931
|
const processedParts = [];
|
|
1810
1932
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -1840,7 +1962,7 @@ class CSharpStringExtractor {
|
|
|
1840
1962
|
const whitespaceAfter = actualPart.search(/\s*$/) === 0 ? actualPart : actualPart.substring(actualPart.search(/\S/) + trimmedPart.length);
|
|
1841
1963
|
processedParts.push(whitespaceBefore + trimmedPart + `.${trMethod}()` + whitespaceAfter);
|
|
1842
1964
|
}
|
|
1843
|
-
else if (trimmedPart && !trimmedPart.match(/^\s*$/) && !trimmedPart.match(/^\d+$/)) {
|
|
1965
|
+
else if (trimmedPart !== 'null' && trimmedPart && !trimmedPart.match(/^\s*$/) && !trimmedPart.match(/^\d+$/)) {
|
|
1844
1966
|
const whitespaceBefore = part.substring(0, part.search(/\S/));
|
|
1845
1967
|
const actualPart = part.substring(part.search(/\S/));
|
|
1846
1968
|
const whitespaceAfter = actualPart.search(/\s*$/) === 0 ? actualPart : actualPart.substring(actualPart.search(/\S/) + trimmedPart.length);
|
|
@@ -1886,7 +2008,7 @@ class CSharpStringExtractor {
|
|
|
1886
2008
|
const whitespaceAfter = actualPart.search(/\s*$/) === 0 ? actualPart : actualPart.substring(actualPart.search(/\S/) + trimmedPart.length);
|
|
1887
2009
|
processedParts.push(whitespaceBefore + trimmedPart + `.${trMethod}()` + whitespaceAfter);
|
|
1888
2010
|
}
|
|
1889
|
-
else if (trimmedPart && !trimmedPart.match(/^\s*$/) && !trimmedPart.match(/^\d+$/)) {
|
|
2011
|
+
else if (trimmedPart !== 'null' && trimmedPart && !trimmedPart.match(/^\s*$/) && !trimmedPart.match(/^\d+$/)) {
|
|
1890
2012
|
if (trimmedPart.includes(`${trClass}.${trFormatMethod}(`)) {
|
|
1891
2013
|
processedParts.push(part);
|
|
1892
2014
|
continue;
|
|
@@ -2172,6 +2294,87 @@ class CSharpStringExtractor {
|
|
|
2172
2294
|
}
|
|
2173
2295
|
}
|
|
2174
2296
|
}
|
|
2297
|
+
let startInStatement = -1;
|
|
2298
|
+
for (let i = 0; i < statement.length - 1; i++) {
|
|
2299
|
+
const char = statement[i];
|
|
2300
|
+
const nextChar = i + 1 < statement.length ? statement[i + 1] : '';
|
|
2301
|
+
const nextNextChar = i + 2 < statement.length ? statement[i + 2] : '';
|
|
2302
|
+
if ((char === '$' && nextChar === '"') ||
|
|
2303
|
+
(char === '$' && nextChar === '@' && nextNextChar === '"') ||
|
|
2304
|
+
(char === '@' && nextChar === '$' && nextNextChar === '"')) {
|
|
2305
|
+
startInStatement = i;
|
|
2306
|
+
break;
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
if (startInStatement === -1) {
|
|
2310
|
+
for (let i = 0; i < statement.length; i++) {
|
|
2311
|
+
if (statement[i] === '"' || statement[i] === "'") {
|
|
2312
|
+
startInStatement = i;
|
|
2313
|
+
break;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
if (startInStatement !== -1) {
|
|
2318
|
+
const finalIndex = statementIndex + startInStatement;
|
|
2319
|
+
let stringEnd = startInStatement;
|
|
2320
|
+
let inString = false;
|
|
2321
|
+
let escapeNext = false;
|
|
2322
|
+
let stringDelimiter = '';
|
|
2323
|
+
let interpolatedBraceDepth = 0;
|
|
2324
|
+
let j = startInStatement;
|
|
2325
|
+
const char = statement[j];
|
|
2326
|
+
const nextChar = j + 1 < statement.length ? statement[j + 1] : '';
|
|
2327
|
+
const nextNextChar = j + 2 < statement.length ? statement[j + 2] : '';
|
|
2328
|
+
if ((char === '$' && nextChar === '"')) {
|
|
2329
|
+
inString = true;
|
|
2330
|
+
stringDelimiter = '"';
|
|
2331
|
+
j += 2;
|
|
2332
|
+
}
|
|
2333
|
+
else if (char === '$' && nextChar === '@' && nextNextChar === '"') {
|
|
2334
|
+
inString = true;
|
|
2335
|
+
stringDelimiter = '"';
|
|
2336
|
+
j += 3;
|
|
2337
|
+
}
|
|
2338
|
+
else if (char === '@' && nextChar === '$' && nextNextChar === '"') {
|
|
2339
|
+
inString = true;
|
|
2340
|
+
stringDelimiter = '"';
|
|
2341
|
+
j += 3;
|
|
2342
|
+
}
|
|
2343
|
+
else if (char === '"' || char === "'") {
|
|
2344
|
+
inString = true;
|
|
2345
|
+
stringDelimiter = char;
|
|
2346
|
+
j++;
|
|
2347
|
+
}
|
|
2348
|
+
while (j < statement.length && inString) {
|
|
2349
|
+
const currentChar = statement[j];
|
|
2350
|
+
if (escapeNext) {
|
|
2351
|
+
escapeNext = false;
|
|
2352
|
+
}
|
|
2353
|
+
else if (currentChar === '\\') {
|
|
2354
|
+
escapeNext = true;
|
|
2355
|
+
}
|
|
2356
|
+
else if (currentChar === stringDelimiter && interpolatedBraceDepth === 0) {
|
|
2357
|
+
inString = false;
|
|
2358
|
+
j++;
|
|
2359
|
+
stringEnd = j;
|
|
2360
|
+
break;
|
|
2361
|
+
}
|
|
2362
|
+
else if (currentChar === '{' && !escapeNext) {
|
|
2363
|
+
interpolatedBraceDepth++;
|
|
2364
|
+
}
|
|
2365
|
+
else if (currentChar === '}' && !escapeNext && interpolatedBraceDepth > 0) {
|
|
2366
|
+
interpolatedBraceDepth--;
|
|
2367
|
+
}
|
|
2368
|
+
j++;
|
|
2369
|
+
}
|
|
2370
|
+
if (!inString) {
|
|
2371
|
+
const valueExpression = statement.substring(startInStatement, stringEnd).trim();
|
|
2372
|
+
return {
|
|
2373
|
+
valueExpression,
|
|
2374
|
+
valueExpressionIndex: finalIndex
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2175
2378
|
return {
|
|
2176
2379
|
valueExpression: trimmedStatement,
|
|
2177
2380
|
valueExpressionIndex: statementIndex
|
|
@@ -2238,121 +2441,348 @@ class CSharpStringExtractor {
|
|
|
2238
2441
|
return result;
|
|
2239
2442
|
}
|
|
2240
2443
|
processStatementAndExtractValue(snippet, fullStatement, valueExpression, trClass, trFormatMethod, trMethod) {
|
|
2241
|
-
let
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2444
|
+
let processedValueExpression = valueExpression;
|
|
2445
|
+
const isTextAssignment = /\w+\.text\s*=/.test(fullStatement.trim());
|
|
2446
|
+
this.extractTrFormatStrings(processedValueExpression, snippet, trClass, trFormatMethod);
|
|
2447
|
+
processedValueExpression = this.processStringTemplates(processedValueExpression, snippet, trClass, trFormatMethod);
|
|
2448
|
+
processedValueExpression = this.processStringFormat(processedValueExpression, snippet, trClass, trFormatMethod);
|
|
2449
|
+
processedValueExpression = this.processStringConcatenation(processedValueExpression, snippet, trClass, trFormatMethod, trMethod);
|
|
2450
|
+
if (isTextAssignment) {
|
|
2451
|
+
processedValueExpression = this.processTextAssignments(processedValueExpression, snippet, trClass, trFormatMethod, trMethod);
|
|
2452
|
+
}
|
|
2453
|
+
this.extractPlainStrings(processedValueExpression, snippet, trClass, trFormatMethod);
|
|
2248
2454
|
const regex = new RegExp(`${trClass}\\.${trFormatMethod}\\(([^)]*)\\)\\.${trMethod}\\(\\)`, 'g');
|
|
2249
|
-
|
|
2455
|
+
processedValueExpression = processedValueExpression.replace(regex, `${trClass}.${trFormatMethod}($1)`);
|
|
2250
2456
|
snippet.finalizeLiterals();
|
|
2251
|
-
let convertedValueExpression =
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
const isCaseOrDefault = trimmedFullStatement.startsWith('case ') || trimmedFullStatement.startsWith('default:');
|
|
2255
|
-
if (/^return\s/.test(trimmedFullStatement)) {
|
|
2256
|
-
// 检查 processedFullStatement 是否真的被修改过
|
|
2257
|
-
// 如果没有被修改过,直接使用原始 valueExpression 即可
|
|
2258
|
-
if (fullStatement === processedFullStatement) {
|
|
2259
|
-
convertedValueExpression = valueExpression;
|
|
2260
|
-
}
|
|
2261
|
-
else {
|
|
2262
|
-
// 对于 return 语句,我们不需要复杂地使用 extractValueUntilSemicolon 来重新解析!
|
|
2263
|
-
// 我们已经处理完整个语句了,直接截取 return 后面的所有内容,然后去掉末尾的分号即可!
|
|
2264
|
-
let returnIndex = trimmedProcessedStatement.indexOf('return');
|
|
2265
|
-
let valuePart = trimmedProcessedStatement.substring(returnIndex + 'return'.length);
|
|
2266
|
-
valuePart = valuePart.trim();
|
|
2267
|
-
if (valuePart.endsWith(';')) {
|
|
2268
|
-
valuePart = valuePart.slice(0, -1).trim();
|
|
2269
|
-
}
|
|
2270
|
-
convertedValueExpression = valuePart;
|
|
2271
|
-
}
|
|
2457
|
+
let convertedValueExpression = processedValueExpression;
|
|
2458
|
+
if (convertedValueExpression.endsWith(';')) {
|
|
2459
|
+
convertedValueExpression = convertedValueExpression.slice(0, -1).trim();
|
|
2272
2460
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2461
|
+
snippet.convertedCode = convertedValueExpression;
|
|
2462
|
+
}
|
|
2463
|
+
processAllFunctionCallsInRange(startIndex, endIndex, fullCode, snippets, trClass, trFormatMethod, trMethod) {
|
|
2464
|
+
let i = startIndex;
|
|
2465
|
+
while (i < endIndex) {
|
|
2466
|
+
let actualParenOpenIndex = -1;
|
|
2467
|
+
let tempDepth = 0;
|
|
2468
|
+
let tempInString = false;
|
|
2469
|
+
let tempEscapeNext = false;
|
|
2470
|
+
let tempStringDelimiter = '';
|
|
2471
|
+
let isStringFormat = false;
|
|
2472
|
+
let functionNameStart = -1;
|
|
2473
|
+
for (let j = i; j < endIndex; j++) {
|
|
2474
|
+
const char = fullCode[j];
|
|
2475
|
+
const nextChar = j + 1 < fullCode.length ? fullCode[j + 1] : '';
|
|
2476
|
+
const nextNextChar = j + 2 < fullCode.length ? fullCode[j + 2] : '';
|
|
2477
|
+
if (tempEscapeNext) {
|
|
2478
|
+
tempEscapeNext = false;
|
|
2479
|
+
continue;
|
|
2278
2480
|
}
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
const value = this.extractValueUntilSemicolon(valuePart);
|
|
2283
|
-
convertedValueExpression = value.trim();
|
|
2481
|
+
if (char === '\\') {
|
|
2482
|
+
tempEscapeNext = true;
|
|
2483
|
+
continue;
|
|
2284
2484
|
}
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2485
|
+
if (tempInString) {
|
|
2486
|
+
if (char === tempStringDelimiter) {
|
|
2487
|
+
tempInString = false;
|
|
2488
|
+
tempStringDelimiter = '';
|
|
2489
|
+
}
|
|
2490
|
+
continue;
|
|
2491
|
+
}
|
|
2492
|
+
if ((char === '$' && nextChar === '"') ||
|
|
2493
|
+
(char === '$' && nextChar === '@' && nextNextChar === '"') ||
|
|
2494
|
+
(char === '@' && nextChar === '$' && nextNextChar === '"')) {
|
|
2495
|
+
tempInString = true;
|
|
2496
|
+
tempStringDelimiter = '"';
|
|
2497
|
+
if (nextChar === '@') {
|
|
2498
|
+
j += 2;
|
|
2291
2499
|
}
|
|
2292
2500
|
else {
|
|
2293
|
-
|
|
2294
|
-
const valuePart = trimmedProcessedStatement.substring(assignmentIndex + 1);
|
|
2295
|
-
const value = this.extractValueUntilSemicolon(valuePart);
|
|
2296
|
-
convertedValueExpression = value.trim();
|
|
2501
|
+
j += 1;
|
|
2297
2502
|
}
|
|
2503
|
+
continue;
|
|
2298
2504
|
}
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
}
|
|
2505
|
+
if (char === '"' || char === "'") {
|
|
2506
|
+
tempInString = true;
|
|
2507
|
+
tempStringDelimiter = char;
|
|
2508
|
+
continue;
|
|
2304
2509
|
}
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2510
|
+
if (char === '(') {
|
|
2511
|
+
tempDepth++;
|
|
2512
|
+
if (actualParenOpenIndex === -1) {
|
|
2513
|
+
actualParenOpenIndex = j;
|
|
2514
|
+
if (functionNameStart !== -1) {
|
|
2515
|
+
const funcName = fullCode.substring(functionNameStart, j).trim();
|
|
2516
|
+
isStringFormat = funcName === 'string.Format';
|
|
2517
|
+
}
|
|
2308
2518
|
}
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2519
|
+
}
|
|
2520
|
+
else if (char === ')') {
|
|
2521
|
+
tempDepth--;
|
|
2522
|
+
if (tempDepth === 0 && actualParenOpenIndex !== -1 && !isStringFormat) {
|
|
2523
|
+
const actualParenCloseIndex = j;
|
|
2524
|
+
let currentSnippetCount = 0;
|
|
2525
|
+
const stringLiteralPositions = [];
|
|
2526
|
+
let k = actualParenOpenIndex;
|
|
2527
|
+
let inString3 = false;
|
|
2528
|
+
let escapeNext3 = false;
|
|
2529
|
+
let stringDelimiter3 = '';
|
|
2530
|
+
let stringStart = -1;
|
|
2531
|
+
while (k < fullCode.length && k <= actualParenCloseIndex) {
|
|
2532
|
+
const char = fullCode[k];
|
|
2533
|
+
const nextChar = k + 1 < fullCode.length ? fullCode[k + 1] : '';
|
|
2534
|
+
const nextNextChar = k + 2 < fullCode.length ? fullCode[k + 2] : '';
|
|
2535
|
+
if (escapeNext3) {
|
|
2536
|
+
escapeNext3 = false;
|
|
2537
|
+
k++;
|
|
2538
|
+
continue;
|
|
2316
2539
|
}
|
|
2317
|
-
|
|
2318
|
-
|
|
2540
|
+
if (char === '\\') {
|
|
2541
|
+
escapeNext3 = true;
|
|
2542
|
+
k++;
|
|
2543
|
+
continue;
|
|
2319
2544
|
}
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2545
|
+
if (inString3) {
|
|
2546
|
+
if (char === stringDelimiter3) {
|
|
2547
|
+
stringLiteralPositions.push(stringStart);
|
|
2548
|
+
inString3 = false;
|
|
2549
|
+
stringDelimiter3 = '';
|
|
2550
|
+
}
|
|
2551
|
+
k++;
|
|
2552
|
+
continue;
|
|
2553
|
+
}
|
|
2554
|
+
if ((char === '$' && nextChar === '"') ||
|
|
2555
|
+
(char === '$' && nextChar === '@' && nextNextChar === '"') ||
|
|
2556
|
+
(char === '@' && nextChar === '$' && nextNextChar === '"')) {
|
|
2557
|
+
inString3 = true;
|
|
2558
|
+
stringDelimiter3 = '"';
|
|
2559
|
+
stringStart = k;
|
|
2560
|
+
if (nextChar === '@') {
|
|
2561
|
+
k += 2;
|
|
2327
2562
|
}
|
|
2328
2563
|
else {
|
|
2329
|
-
|
|
2564
|
+
k += 1;
|
|
2330
2565
|
}
|
|
2566
|
+
continue;
|
|
2567
|
+
}
|
|
2568
|
+
if (char === '"' || char === "'") {
|
|
2569
|
+
inString3 = true;
|
|
2570
|
+
stringDelimiter3 = char;
|
|
2571
|
+
stringStart = k;
|
|
2572
|
+
k++;
|
|
2573
|
+
continue;
|
|
2574
|
+
}
|
|
2575
|
+
if (char === ')' && k === actualParenCloseIndex) {
|
|
2576
|
+
break;
|
|
2577
|
+
}
|
|
2578
|
+
k++;
|
|
2579
|
+
}
|
|
2580
|
+
let argStartPos = actualParenOpenIndex + 1;
|
|
2581
|
+
const trimmedCode = fullCode.substring(actualParenOpenIndex + 1, actualParenCloseIndex);
|
|
2582
|
+
const args = this.splitArguments(trimmedCode);
|
|
2583
|
+
for (const arg of args) {
|
|
2584
|
+
const trimmedArg = arg.trim();
|
|
2585
|
+
if (!trimmedArg) {
|
|
2586
|
+
argStartPos = this.updateArgStartPos(argStartPos, fullCode, actualParenCloseIndex);
|
|
2587
|
+
continue;
|
|
2588
|
+
}
|
|
2589
|
+
const hasStringLiteral = /"(?:[^"\\]|\\.)*"/.test(trimmedArg) ||
|
|
2590
|
+
/\$"[\s\S]*?"/.test(trimmedArg) ||
|
|
2591
|
+
/\$@"[\s\S]*?"/.test(trimmedArg) ||
|
|
2592
|
+
/@\$"[\s\S]*?"/.test(trimmedArg);
|
|
2593
|
+
while (argStartPos < fullCode.length && /\s/.test(fullCode[argStartPos])) {
|
|
2594
|
+
argStartPos++;
|
|
2595
|
+
}
|
|
2596
|
+
let foundArgEnd = argStartPos;
|
|
2597
|
+
let inString4 = false;
|
|
2598
|
+
let escapeNext4 = false;
|
|
2599
|
+
let stringDelimiter4 = '';
|
|
2600
|
+
let parenthesesDepth = 0;
|
|
2601
|
+
let braceDepth = 0;
|
|
2602
|
+
let bracketDepth = 0;
|
|
2603
|
+
while (foundArgEnd < fullCode.length && foundArgEnd <= actualParenCloseIndex) {
|
|
2604
|
+
const char = fullCode[foundArgEnd];
|
|
2605
|
+
const nextChar = foundArgEnd + 1 < fullCode.length ? fullCode[foundArgEnd + 1] : '';
|
|
2606
|
+
const nextNextChar = foundArgEnd + 2 < fullCode.length ? fullCode[foundArgEnd + 2] : '';
|
|
2607
|
+
if (escapeNext4) {
|
|
2608
|
+
escapeNext4 = false;
|
|
2609
|
+
foundArgEnd++;
|
|
2610
|
+
continue;
|
|
2611
|
+
}
|
|
2612
|
+
if (char === '\\') {
|
|
2613
|
+
escapeNext4 = true;
|
|
2614
|
+
foundArgEnd++;
|
|
2615
|
+
continue;
|
|
2616
|
+
}
|
|
2617
|
+
if (inString4) {
|
|
2618
|
+
if (char === stringDelimiter4) {
|
|
2619
|
+
inString4 = false;
|
|
2620
|
+
stringDelimiter4 = '';
|
|
2621
|
+
}
|
|
2622
|
+
foundArgEnd++;
|
|
2623
|
+
continue;
|
|
2624
|
+
}
|
|
2625
|
+
if ((char === '$' && nextChar === '"') ||
|
|
2626
|
+
(char === '$' && nextChar === '@' && nextNextChar === '"') ||
|
|
2627
|
+
(char === '@' && nextChar === '$' && nextNextChar === '"')) {
|
|
2628
|
+
inString4 = true;
|
|
2629
|
+
stringDelimiter4 = '"';
|
|
2630
|
+
if (nextChar === '@') {
|
|
2631
|
+
foundArgEnd += 2;
|
|
2632
|
+
}
|
|
2633
|
+
else {
|
|
2634
|
+
foundArgEnd += 1;
|
|
2635
|
+
}
|
|
2636
|
+
continue;
|
|
2637
|
+
}
|
|
2638
|
+
if (char === '"' || char === "'") {
|
|
2639
|
+
inString4 = true;
|
|
2640
|
+
stringDelimiter4 = char;
|
|
2641
|
+
foundArgEnd++;
|
|
2642
|
+
continue;
|
|
2643
|
+
}
|
|
2644
|
+
if (char === '(') {
|
|
2645
|
+
parenthesesDepth++;
|
|
2646
|
+
}
|
|
2647
|
+
else if (char === ')') {
|
|
2648
|
+
if (foundArgEnd === actualParenCloseIndex) {
|
|
2649
|
+
break;
|
|
2650
|
+
}
|
|
2651
|
+
parenthesesDepth--;
|
|
2652
|
+
}
|
|
2653
|
+
else if (char === '{') {
|
|
2654
|
+
braceDepth++;
|
|
2655
|
+
}
|
|
2656
|
+
else if (char === '}') {
|
|
2657
|
+
braceDepth--;
|
|
2658
|
+
}
|
|
2659
|
+
else if (char === '[') {
|
|
2660
|
+
bracketDepth++;
|
|
2661
|
+
}
|
|
2662
|
+
else if (char === ']') {
|
|
2663
|
+
bracketDepth--;
|
|
2664
|
+
}
|
|
2665
|
+
else if (char === ',' && parenthesesDepth === 0 && braceDepth === 0 && bracketDepth === 0) {
|
|
2666
|
+
break;
|
|
2667
|
+
}
|
|
2668
|
+
foundArgEnd++;
|
|
2669
|
+
}
|
|
2670
|
+
if (!hasStringLiteral) {
|
|
2671
|
+
argStartPos = foundArgEnd + 1;
|
|
2672
|
+
continue;
|
|
2673
|
+
}
|
|
2674
|
+
const actualArg = fullCode.substring(argStartPos, foundArgEnd).trim();
|
|
2675
|
+
const isObjectInitializer = actualArg.startsWith('new ') && actualArg.includes('{') && actualArg.includes('}');
|
|
2676
|
+
if (isObjectInitializer) {
|
|
2677
|
+
this.processObjectInitializerStringsOnly(argStartPos, fullCode, snippets, trClass, trFormatMethod, trMethod);
|
|
2331
2678
|
}
|
|
2332
2679
|
else {
|
|
2333
|
-
|
|
2680
|
+
let finalOriginalIndex = argStartPos;
|
|
2681
|
+
if (currentSnippetCount < stringLiteralPositions.length) {
|
|
2682
|
+
finalOriginalIndex = stringLiteralPositions[currentSnippetCount];
|
|
2683
|
+
}
|
|
2684
|
+
let alreadyExists = false;
|
|
2685
|
+
for (const snippet of snippets) {
|
|
2686
|
+
if (snippet.originalIndex === finalOriginalIndex) {
|
|
2687
|
+
alreadyExists = true;
|
|
2688
|
+
break;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
if (!alreadyExists) {
|
|
2692
|
+
let finalArg = actualArg;
|
|
2693
|
+
if (currentSnippetCount < stringLiteralPositions.length) {
|
|
2694
|
+
const stringStart = stringLiteralPositions[currentSnippetCount];
|
|
2695
|
+
let stringEnd = stringStart;
|
|
2696
|
+
let j = stringStart;
|
|
2697
|
+
let inString = false;
|
|
2698
|
+
let escapeNext = false;
|
|
2699
|
+
let stringDelimiter = '';
|
|
2700
|
+
let braceDepth = 0;
|
|
2701
|
+
let interpolatedBraceDepth = 0;
|
|
2702
|
+
const char = fullCode[j];
|
|
2703
|
+
const nextChar = j + 1 < fullCode.length ? fullCode[j + 1] : '';
|
|
2704
|
+
const nextNextChar = j + 2 < fullCode.length ? fullCode[j + 2] : '';
|
|
2705
|
+
if ((char === '$' && nextChar === '"')) {
|
|
2706
|
+
inString = true;
|
|
2707
|
+
stringDelimiter = '"';
|
|
2708
|
+
j += 2;
|
|
2709
|
+
}
|
|
2710
|
+
else if (char === '$' && nextChar === '@' && j + 2 < fullCode.length && fullCode[j + 2] === '"') {
|
|
2711
|
+
inString = true;
|
|
2712
|
+
stringDelimiter = '"';
|
|
2713
|
+
j += 3;
|
|
2714
|
+
}
|
|
2715
|
+
else if (char === '@' && nextChar === '$' && j + 2 < fullCode.length && fullCode[j + 2] === '"') {
|
|
2716
|
+
inString = true;
|
|
2717
|
+
stringDelimiter = '"';
|
|
2718
|
+
j += 3;
|
|
2719
|
+
}
|
|
2720
|
+
else if (char === '"' || char === "'") {
|
|
2721
|
+
inString = true;
|
|
2722
|
+
stringDelimiter = char;
|
|
2723
|
+
j++;
|
|
2724
|
+
}
|
|
2725
|
+
while (j < fullCode.length && inString) {
|
|
2726
|
+
const currentChar = fullCode[j];
|
|
2727
|
+
if (escapeNext) {
|
|
2728
|
+
escapeNext = false;
|
|
2729
|
+
}
|
|
2730
|
+
else if (currentChar === '\\') {
|
|
2731
|
+
escapeNext = true;
|
|
2732
|
+
}
|
|
2733
|
+
else if (currentChar === stringDelimiter && interpolatedBraceDepth === 0) {
|
|
2734
|
+
inString = false;
|
|
2735
|
+
j++;
|
|
2736
|
+
stringEnd = j;
|
|
2737
|
+
break;
|
|
2738
|
+
}
|
|
2739
|
+
else if (currentChar === '{' && !escapeNext) {
|
|
2740
|
+
interpolatedBraceDepth++;
|
|
2741
|
+
}
|
|
2742
|
+
else if (currentChar === '}' && !escapeNext && interpolatedBraceDepth > 0) {
|
|
2743
|
+
interpolatedBraceDepth--;
|
|
2744
|
+
}
|
|
2745
|
+
j++;
|
|
2746
|
+
}
|
|
2747
|
+
if (!inString) {
|
|
2748
|
+
finalArg = fullCode.substring(stringStart, stringEnd);
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
const snippet = new CodeSnippet();
|
|
2752
|
+
snippet.originalIndex = finalOriginalIndex;
|
|
2753
|
+
snippet.originalCode = finalArg;
|
|
2754
|
+
snippet.originalContext = finalArg;
|
|
2755
|
+
this.variableIndex = 0;
|
|
2756
|
+
this.processSingleArgument(snippet, finalArg, trClass, trFormatMethod, trMethod);
|
|
2757
|
+
snippets.push(snippet);
|
|
2758
|
+
currentSnippetCount++;
|
|
2759
|
+
}
|
|
2334
2760
|
}
|
|
2761
|
+
argStartPos = foundArgEnd + 1;
|
|
2335
2762
|
}
|
|
2763
|
+
i = actualParenCloseIndex + 1;
|
|
2764
|
+
actualParenOpenIndex = -1;
|
|
2765
|
+
isStringFormat = false;
|
|
2766
|
+
functionNameStart = -1;
|
|
2336
2767
|
}
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
if (parenCloseIndex !== -1) {
|
|
2343
|
-
convertedValueExpression = trimmedProcessedStatement.substring(parenOpenIndex + 1, parenCloseIndex).trim();
|
|
2344
|
-
}
|
|
2768
|
+
else if (tempDepth === 0 && actualParenOpenIndex !== -1 && isStringFormat) {
|
|
2769
|
+
i = j + 1;
|
|
2770
|
+
actualParenOpenIndex = -1;
|
|
2771
|
+
isStringFormat = false;
|
|
2772
|
+
functionNameStart = -1;
|
|
2345
2773
|
}
|
|
2346
2774
|
}
|
|
2347
|
-
else {
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2775
|
+
else if (!tempInString && char === '.' && tempDepth === 0) {
|
|
2776
|
+
functionNameStart = -1;
|
|
2777
|
+
}
|
|
2778
|
+
else if (!tempInString && /[a-zA-Z_]/.test(char) && tempDepth === 0 && functionNameStart === -1) {
|
|
2779
|
+
functionNameStart = j;
|
|
2352
2780
|
}
|
|
2353
2781
|
}
|
|
2782
|
+
if (actualParenOpenIndex === -1) {
|
|
2783
|
+
break;
|
|
2784
|
+
}
|
|
2354
2785
|
}
|
|
2355
|
-
snippet.convertedCode = convertedValueExpression;
|
|
2356
2786
|
}
|
|
2357
2787
|
}
|
|
2358
2788
|
exports.CSharpStringExtractor = CSharpStringExtractor;
|