token-goat 2.9.30 → 2.9.31
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/README.md +24 -7
- package/SECURITY.md +10 -2
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/native/linux-arm64/tg-hook +0 -0
- package/dist/native/linux-x64/tg-hook +0 -0
- package/dist/native/win32-arm64/tg-hook.exe +0 -0
- package/dist/native/win32-x64/tg-hook.exe +0 -0
- package/dist/{token-goat-chunk-QSBRTGM2.mjs → token-goat-chunk-25TRAWET.mjs} +17 -7
- package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
- package/dist/{token-goat-chunk-IVKIZWAB.mjs → token-goat-chunk-2M7E4PF7.mjs} +41 -12
- package/dist/{token-goat-chunk-SMVRN2HU.mjs → token-goat-chunk-2UPZGKKY.mjs} +2 -2
- package/dist/token-goat-chunk-2WLPWKHV.mjs +135 -0
- package/dist/token-goat-chunk-2XBMMDBD.mjs +126 -0
- package/dist/token-goat-chunk-32ZOY4N5.mjs +23 -0
- package/dist/token-goat-chunk-3EZRNKTK.mjs +188 -0
- package/dist/token-goat-chunk-4ADZHI7J.mjs +63 -0
- package/dist/token-goat-chunk-4GBVPH3D.mjs +242 -0
- package/dist/{token-goat-chunk-KWPNJBDH.mjs → token-goat-chunk-4GILLLWY.mjs} +7 -4
- package/dist/{token-goat-chunk-67TQJ76B.mjs → token-goat-chunk-4NAPX7BA.mjs} +36 -3
- package/dist/{token-goat-chunk-PU7V3FD6.mjs → token-goat-chunk-4SC7UJYV.mjs} +3354 -2553
- package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
- package/dist/{token-goat-chunk-AFLYLHDH.mjs → token-goat-chunk-4ZBFWLXF.mjs} +283 -427
- package/dist/{token-goat-chunk-JDWCRD6M.mjs → token-goat-chunk-57BIAXJL.mjs} +73 -40
- package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
- package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
- package/dist/token-goat-chunk-646E6U44.mjs +398 -0
- package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
- package/dist/{token-goat-chunk-JN4XMLSD.mjs → token-goat-chunk-6DG6HWP3.mjs} +8 -2
- package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
- package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
- package/dist/{token-goat-chunk-VPBBTSJR.mjs → token-goat-chunk-76FGDLRO.mjs} +262 -255
- package/dist/{token-goat-chunk-7IN2MKDS.mjs → token-goat-chunk-7EZTZOMC.mjs} +121 -289
- package/dist/{token-goat-chunk-OJBNYTJP.mjs → token-goat-chunk-7MAOA6X4.mjs} +640 -80
- package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
- package/dist/{token-goat-chunk-PD5VKH46.mjs → token-goat-chunk-AUNGYYQX.mjs} +2 -2
- package/dist/{token-goat-chunk-HG45AF2B.mjs → token-goat-chunk-AUQYRMMH.mjs} +794 -37
- package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
- package/dist/{token-goat-chunk-A3CK6N5Z.mjs → token-goat-chunk-BA4HI6BW.mjs} +1309 -110
- package/dist/{token-goat-chunk-JB6QN6VF.mjs → token-goat-chunk-BFCWY73P.mjs} +59 -23
- package/dist/{token-goat-chunk-B45VMIIH.mjs → token-goat-chunk-BWGFUZZE.mjs} +7 -5
- package/dist/{token-goat-chunk-P4QMM4WK.mjs → token-goat-chunk-C75NA7PL.mjs} +50 -23
- package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
- package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
- package/dist/{token-goat-chunk-H2PHHGM5.mjs → token-goat-chunk-CIMQ2BB3.mjs} +57 -12
- package/dist/{token-goat-chunk-N2NMER56.mjs → token-goat-chunk-CJLS3CDL.mjs} +46 -4
- package/dist/{token-goat-chunk-VES7EL7O.mjs → token-goat-chunk-CO3UYX6G.mjs} +1 -1
- package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
- package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
- package/dist/{token-goat-chunk-4LCCNRTG.mjs → token-goat-chunk-CVCEVUGK.mjs} +8 -6
- package/dist/{token-goat-chunk-B2RZZCSS.mjs → token-goat-chunk-CXHOFN7R.mjs} +37 -20
- package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
- package/dist/{token-goat-chunk-APGZXSPS.mjs → token-goat-chunk-DGS2LVNA.mjs} +47 -30
- package/dist/{token-goat-chunk-54K3EUV3.mjs → token-goat-chunk-DOWRSMWO.mjs} +1 -1
- package/dist/token-goat-chunk-E45INMY3.mjs +71 -0
- package/dist/token-goat-chunk-EC5F37F4.mjs +244 -0
- package/dist/{token-goat-chunk-XTQAOTSO.mjs → token-goat-chunk-EDBDRVH5.mjs} +4 -1
- package/dist/{token-goat-chunk-5BCIJXMO.mjs → token-goat-chunk-EELTBKDM.mjs} +14 -10
- package/dist/{token-goat-chunk-W3QCJS6G.mjs → token-goat-chunk-F4HYL64R.mjs} +8 -6
- package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
- package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
- package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
- package/dist/{token-goat-chunk-C63JQV5K.mjs → token-goat-chunk-GL3ETKSC.mjs} +233 -15
- package/dist/token-goat-chunk-GVB2MUST.mjs +1298 -0
- package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
- package/dist/{token-goat-chunk-ZEJVMUQH.mjs → token-goat-chunk-HLPW63A7.mjs} +2 -2
- package/dist/{token-goat-chunk-GOLEOXZP.mjs → token-goat-chunk-HU4TORC5.mjs} +44 -26
- package/dist/{token-goat-chunk-Z57YODA2.mjs → token-goat-chunk-I7VKZZAW.mjs} +2 -2
- package/dist/{token-goat-chunk-NYKZLXMK.mjs → token-goat-chunk-IA6XSPE3.mjs} +6 -6
- package/dist/{token-goat-chunk-E3OQX2XT.mjs → token-goat-chunk-IAGXMHIK.mjs} +81 -42
- package/dist/{token-goat-chunk-HYBFA5X3.mjs → token-goat-chunk-IK2DRMFX.mjs} +24 -68
- package/dist/{token-goat-chunk-COBQGL5S.mjs → token-goat-chunk-INNPTRUX.mjs} +249 -299
- package/dist/{token-goat-chunk-7NADEDKJ.mjs → token-goat-chunk-JJ5BX4F4.mjs} +6 -1
- package/dist/{token-goat-chunk-PEPTHRFF.mjs → token-goat-chunk-JVFSHVFJ.mjs} +6 -6
- package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
- package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
- package/dist/{token-goat-chunk-Q5VTGRH7.mjs → token-goat-chunk-LCNQ2CNN.mjs} +55 -319
- package/dist/token-goat-chunk-M3LFJDPU.mjs +58 -0
- package/dist/token-goat-chunk-M52KPT3C.mjs +87 -0
- package/dist/token-goat-chunk-MBEG42H7.mjs +150 -0
- package/dist/{token-goat-chunk-EVC4TOLE.mjs → token-goat-chunk-METECDOH.mjs} +3 -12
- package/dist/{token-goat-chunk-T4FK7VOV.mjs → token-goat-chunk-MHX7XCC3.mjs} +2 -1
- package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
- package/dist/{token-goat-chunk-LOBGHXPB.mjs → token-goat-chunk-N5MMR2IW.mjs} +1 -1
- package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
- package/dist/{token-goat-chunk-RHXKCZX3.mjs → token-goat-chunk-NISNMD7T.mjs} +2182 -2959
- package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
- package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
- package/dist/{token-goat-chunk-KQNZDCBD.mjs → token-goat-chunk-NSNSPPBG.mjs} +25 -3
- package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
- package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
- package/dist/{token-goat-chunk-JTQQGXZH.mjs → token-goat-chunk-ODBT2USM.mjs} +124 -57
- package/dist/token-goat-chunk-OS5EM5PP.mjs +107 -0
- package/dist/token-goat-chunk-OUKDTVNU.mjs +1178 -0
- package/dist/token-goat-chunk-OXFMP75N.mjs +566 -0
- package/dist/{token-goat-chunk-DZX2YDPT.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -2
- package/dist/{token-goat-chunk-QCLDAQTS.mjs → token-goat-chunk-P6HQSWQ3.mjs} +50 -53
- package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
- package/dist/{token-goat-chunk-7BXSNBY5.mjs → token-goat-chunk-PFWIMH2E.mjs} +23 -15
- package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
- package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
- package/dist/{token-goat-chunk-GFBSN7BD.mjs → token-goat-chunk-PX5PQWTY.mjs} +22 -250
- package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
- package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
- package/dist/{token-goat-chunk-FBNQNSJK.mjs → token-goat-chunk-QH7YVYOY.mjs} +2198 -2782
- package/dist/{token-goat-chunk-64FBPDTK.mjs → token-goat-chunk-QLMUHEPB.mjs} +12 -9
- package/dist/{token-goat-chunk-RZRTDST7.mjs → token-goat-chunk-QQOJIHL3.mjs} +37 -11
- package/dist/{token-goat-chunk-XKI4SEMX.mjs → token-goat-chunk-QQTWJY2O.mjs} +19 -0
- package/dist/{token-goat-chunk-U4N3BN2W.mjs → token-goat-chunk-QYHO5CPH.mjs} +3 -2
- package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
- package/dist/{token-goat-chunk-ETBHVDB6.mjs → token-goat-chunk-RSLPOBKQ.mjs} +22 -11
- package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
- package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
- package/dist/{token-goat-chunk-4JJS54TR.mjs → token-goat-chunk-SOAFZNNZ.mjs} +161 -38
- package/dist/{token-goat-chunk-664RTTUV.mjs → token-goat-chunk-SRTHT7KV.mjs} +21 -16
- package/dist/{token-goat-chunk-4FVIAHSI.mjs → token-goat-chunk-T5P5ACNQ.mjs} +7 -6
- package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
- package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
- package/dist/{token-goat-chunk-COTXZHTS.mjs → token-goat-chunk-TM6MC754.mjs} +4 -3
- package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
- package/dist/{token-goat-chunk-3CHUNJ2O.mjs → token-goat-chunk-U2KSB4SG.mjs} +8 -5
- package/dist/{token-goat-chunk-3Z5S4KGM.mjs → token-goat-chunk-U4WHMG6Y.mjs} +29 -49
- package/dist/{token-goat-chunk-PY533T7F.mjs → token-goat-chunk-UGJHGR5A.mjs} +21 -15
- package/dist/{token-goat-chunk-CYCEYAEO.mjs → token-goat-chunk-UOUDVA5U.mjs} +1 -1
- package/dist/{token-goat-chunk-JDHE26RP.mjs → token-goat-chunk-URRJ33GR.mjs} +16 -5
- package/dist/{token-goat-chunk-56EIMS3E.mjs → token-goat-chunk-UZOROKIS.mjs} +23 -17
- package/dist/{token-goat-chunk-CZ3LUXYZ.mjs → token-goat-chunk-VIHGGGEI.mjs} +427 -308
- package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
- package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
- package/dist/{token-goat-chunk-YARZFCZS.mjs → token-goat-chunk-VWZA2H4P.mjs} +62 -53
- package/dist/{token-goat-chunk-SQSSNQPE.mjs → token-goat-chunk-VXEXMJDL.mjs} +3979 -4745
- package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
- package/dist/{token-goat-chunk-SJHWVNDQ.mjs → token-goat-chunk-WDH44VAU.mjs} +7 -4
- package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
- package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
- package/dist/{token-goat-chunk-FZ3NEW5O.mjs → token-goat-chunk-XLRBNZCC.mjs} +13 -8
- package/dist/{token-goat-chunk-Z44YO3QZ.mjs → token-goat-chunk-XRKUX6CM.mjs} +1 -1
- package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
- package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
- package/dist/{token-goat-chunk-WY3L4DVT.mjs → token-goat-chunk-Y2ZTQOCL.mjs} +13 -8
- package/dist/{token-goat-chunk-UQ5UK2T7.mjs → token-goat-chunk-YB4VMGK2.mjs} +1 -1
- package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
- package/dist/{token-goat-chunk-ZQSJMO2R.mjs → token-goat-chunk-YHVDKQBR.mjs} +105 -105
- package/dist/{token-goat-chunk-H2K3QP6H.mjs → token-goat-chunk-YJB5XLWI.mjs} +8 -6
- package/dist/{token-goat-chunk-ZCDTCVIS.mjs → token-goat-chunk-YKB6AQG3.mjs} +5 -2
- package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
- package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
- package/dist/{token-goat-chunk-HOJLCGDP.mjs → token-goat-chunk-YY6AVUFL.mjs} +2033 -2251
- package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
- package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
- package/dist/token-goat-hook-client.cjs +1 -1
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +67 -38
- package/dist/token-goat.core.mjs +4 -4
- package/docs/C4_RUNTIME_ARCHITECTURE.md +1 -1
- package/docs/cli.md +40 -21
- package/docs/install.md +19 -9
- package/docs/security.md +5 -3
- package/package.json +2 -1
- package/dist/token-goat-chunk-5KDMCMF2.mjs +0 -362
- package/dist/token-goat-chunk-6QMAS7AB.mjs +0 -42
- package/dist/token-goat-chunk-7F2UBPD3.mjs +0 -397
- package/dist/token-goat-chunk-ARDNEC2U.mjs +0 -248
- package/dist/token-goat-chunk-ATCPY7EQ.mjs +0 -134
- package/dist/token-goat-chunk-EFHMMIGP.mjs +0 -68
- package/dist/token-goat-chunk-IVALLT3S.mjs +0 -48
- package/dist/token-goat-chunk-JDU3EXSU.mjs +0 -65
- package/dist/token-goat-chunk-MKPF4CL5.mjs +0 -37
- package/dist/token-goat-chunk-RC35RBUL.mjs +0 -312
- package/dist/token-goat-chunk-USILZ3T3.mjs +0 -53
- package/dist/token-goat-chunk-VL3YIFHZ.mjs +0 -2975
- package/dist/token-goat-chunk-XU4P6Z24.mjs +0 -133
- package/dist/token-goat-chunk-Y776AENC.mjs +0 -1597
|
@@ -2,6 +2,11 @@ import { createRequire as __cjsRequire } from 'node:module';
|
|
|
2
2
|
const require = __cjsRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
SpanCollector,
|
|
5
|
+
bodyBraceAt,
|
|
6
|
+
bodyResumeAt,
|
|
7
|
+
bodySegments,
|
|
8
|
+
endOpenMember,
|
|
9
|
+
endOpenMembers,
|
|
5
10
|
extractAbap,
|
|
6
11
|
extractAbl,
|
|
7
12
|
extractAsm,
|
|
@@ -24,22 +29,27 @@ import {
|
|
|
24
29
|
extractSolidity,
|
|
25
30
|
extractSwift,
|
|
26
31
|
extractThrift,
|
|
27
|
-
extractWgsl
|
|
28
|
-
|
|
32
|
+
extractWgsl,
|
|
33
|
+
openMembersOf,
|
|
34
|
+
spanUnsettled
|
|
35
|
+
} from "./token-goat-chunk-SOAFZNNZ.mjs";
|
|
29
36
|
import {
|
|
30
37
|
extractShellBannerHeading
|
|
31
|
-
} from "./token-goat-chunk-
|
|
38
|
+
} from "./token-goat-chunk-OXFMP75N.mjs";
|
|
39
|
+
import "./token-goat-chunk-NISNMD7T.mjs";
|
|
32
40
|
import "./token-goat-chunk-EVMZJ27Z.mjs";
|
|
33
|
-
import "./token-goat-chunk-
|
|
41
|
+
import "./token-goat-chunk-IK2DRMFX.mjs";
|
|
42
|
+
import {
|
|
43
|
+
extractEnv,
|
|
44
|
+
extractIni
|
|
45
|
+
} from "./token-goat-chunk-GVB2MUST.mjs";
|
|
46
|
+
import "./token-goat-chunk-XB5KKOCG.mjs";
|
|
34
47
|
import {
|
|
35
48
|
GENERIC_CLAUSE,
|
|
36
|
-
assignBraceBlockSpans,
|
|
37
49
|
assignFlatEndLines,
|
|
38
50
|
buildLineIndex,
|
|
39
|
-
|
|
40
|
-
extractIni,
|
|
51
|
+
closingQuoteRunEnd,
|
|
41
52
|
findHtmlHeadingMatches,
|
|
42
|
-
findMatchingBraceEndLine,
|
|
43
53
|
isInsideStringLiteral,
|
|
44
54
|
lineTextAt,
|
|
45
55
|
makeLineSymbol,
|
|
@@ -51,6 +61,7 @@ import {
|
|
|
51
61
|
offsetToLine,
|
|
52
62
|
precedingDocComment,
|
|
53
63
|
propagateEndLinesToSymbols,
|
|
64
|
+
scalaCharLiteralLength,
|
|
54
65
|
scanQuotedStringEnd,
|
|
55
66
|
stripBlockCommentSpan,
|
|
56
67
|
stripCstyleComments,
|
|
@@ -60,21 +71,27 @@ import {
|
|
|
60
71
|
stripMultilineStringSpan,
|
|
61
72
|
stripStringLiterals,
|
|
62
73
|
stripXmlComments
|
|
63
|
-
} from "./token-goat-chunk-
|
|
64
|
-
import "./token-goat-chunk-
|
|
65
|
-
import "./token-goat-chunk-
|
|
66
|
-
import "./token-goat-chunk-
|
|
74
|
+
} from "./token-goat-chunk-OUKDTVNU.mjs";
|
|
75
|
+
import "./token-goat-chunk-7EZTZOMC.mjs";
|
|
76
|
+
import "./token-goat-chunk-QYHO5CPH.mjs";
|
|
77
|
+
import "./token-goat-chunk-4GBVPH3D.mjs";
|
|
67
78
|
import "./token-goat-chunk-YZAAZU2S.mjs";
|
|
68
79
|
import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
80
|
+
import {
|
|
81
|
+
elementCursor,
|
|
82
|
+
findElements,
|
|
83
|
+
gtFinder
|
|
84
|
+
} from "./token-goat-chunk-E45INMY3.mjs";
|
|
69
85
|
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
70
86
|
import {
|
|
71
87
|
countContentLines,
|
|
72
88
|
escapeRegExp,
|
|
73
89
|
pushAll
|
|
74
|
-
} from "./token-goat-chunk-
|
|
90
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
91
|
+
import "./token-goat-chunk-GGGG7RWB.mjs";
|
|
75
92
|
import "./token-goat-chunk-AM5V6GSX.mjs";
|
|
76
93
|
import "./token-goat-chunk-FNFBKLRD.mjs";
|
|
77
|
-
import "./token-goat-chunk-
|
|
94
|
+
import "./token-goat-chunk-CO3UYX6G.mjs";
|
|
78
95
|
import {
|
|
79
96
|
init_define_import_meta_env
|
|
80
97
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -82,6 +99,682 @@ import {
|
|
|
82
99
|
// src/languages/registry.ts
|
|
83
100
|
init_define_import_meta_env();
|
|
84
101
|
|
|
102
|
+
// src/languages/brace_spans.ts
|
|
103
|
+
init_define_import_meta_env();
|
|
104
|
+
function tripleQuoteDelimiters(opts) {
|
|
105
|
+
const delims = [];
|
|
106
|
+
if (opts?.tripleQuote === true) delims.push('"""');
|
|
107
|
+
if (opts?.tripleSingleQuote === true) delims.push("'''");
|
|
108
|
+
return delims;
|
|
109
|
+
}
|
|
110
|
+
function quoteRunLength(content, i) {
|
|
111
|
+
let n = 0;
|
|
112
|
+
while (content[i + n] === '"') n++;
|
|
113
|
+
return n;
|
|
114
|
+
}
|
|
115
|
+
function skipRawStringQuotes(content, from, min) {
|
|
116
|
+
return closingQuoteRunEnd(content, from, '"', min, "last");
|
|
117
|
+
}
|
|
118
|
+
function stepPowershellString(content, i, quote) {
|
|
119
|
+
const ch = content[i];
|
|
120
|
+
if (quote === '"' && ch === "`") return { next: i + 1, open: true };
|
|
121
|
+
return { next: i, open: ch !== quote };
|
|
122
|
+
}
|
|
123
|
+
function opensCsharpVerbatimString(content, i) {
|
|
124
|
+
const prev = content[i - 1];
|
|
125
|
+
return prev === "@" || prev === "$" && content[i - 2] === "@";
|
|
126
|
+
}
|
|
127
|
+
function toLineCommentPrefixes(prefix) {
|
|
128
|
+
if (prefix === void 0) return [];
|
|
129
|
+
return typeof prefix === "string" ? [prefix] : prefix;
|
|
130
|
+
}
|
|
131
|
+
function atLineComment(content, i, prefixes, exceptions) {
|
|
132
|
+
if (exceptions.some((e) => content.startsWith(e, i))) return false;
|
|
133
|
+
return prefixes.some((prefix) => content.startsWith(prefix, i));
|
|
134
|
+
}
|
|
135
|
+
function skipBlockComment(content, start, block, nested) {
|
|
136
|
+
let i = start + block[0].length;
|
|
137
|
+
let depth = 1;
|
|
138
|
+
while (i < content.length) {
|
|
139
|
+
if (nested && content.startsWith(block[0], i)) {
|
|
140
|
+
depth++;
|
|
141
|
+
i += block[0].length;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (content.startsWith(block[1], i)) {
|
|
145
|
+
depth--;
|
|
146
|
+
i += block[1].length;
|
|
147
|
+
if (depth === 0) return i;
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
i++;
|
|
151
|
+
}
|
|
152
|
+
return -1;
|
|
153
|
+
}
|
|
154
|
+
function findMatchingBraceEndLine(content, openBraceIndex, totalLines, lineIndex, lineCommentPrefix, opts) {
|
|
155
|
+
const linePrefixes = toLineCommentPrefixes(lineCommentPrefix);
|
|
156
|
+
const lineExceptions = opts?.lineCommentExceptions ?? [];
|
|
157
|
+
const block = opts?.blockComment;
|
|
158
|
+
const backtick = opts?.backtickQuote === true;
|
|
159
|
+
const escapes = opts?.stringEscapes ?? "backslash";
|
|
160
|
+
const nestedBlock = opts?.nestedBlockComments === true;
|
|
161
|
+
const rawString = opts?.rawStringQuotes === true;
|
|
162
|
+
const rRaw = opts?.rRawStrings === true;
|
|
163
|
+
const tripleDelims = tripleQuoteDelimiters(opts);
|
|
164
|
+
const lineString = opts?.lineStringPrefix;
|
|
165
|
+
const interpolation = opts?.interpolation;
|
|
166
|
+
let interpolated = false;
|
|
167
|
+
let depth = 0;
|
|
168
|
+
let quote = null;
|
|
169
|
+
let verbatim = false;
|
|
170
|
+
for (let i = openBraceIndex; i < content.length; i++) {
|
|
171
|
+
const ch = content[i];
|
|
172
|
+
if (quote !== null) {
|
|
173
|
+
if (interpolated && interpolation !== void 0) {
|
|
174
|
+
const past = skipInterpolationAt(content, i, content.length, interpolation);
|
|
175
|
+
if (past !== null) {
|
|
176
|
+
i = past - 1;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (verbatim) {
|
|
181
|
+
if (ch === quote) {
|
|
182
|
+
if (content[i + 1] === quote) {
|
|
183
|
+
i++;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
quote = null;
|
|
187
|
+
verbatim = false;
|
|
188
|
+
}
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (escapes === "powershell") {
|
|
192
|
+
const step = stepPowershellString(content, i, quote);
|
|
193
|
+
i = step.next;
|
|
194
|
+
if (!step.open) quote = null;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (ch === "\\") {
|
|
198
|
+
i++;
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (ch === quote) quote = null;
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (block !== void 0 && content.startsWith(block[0], i)) {
|
|
205
|
+
const end = skipBlockComment(content, i, block, nestedBlock);
|
|
206
|
+
i = end === -1 ? content.length : end - 1;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (atLineComment(content, i, linePrefixes, lineExceptions)) {
|
|
210
|
+
while (i < content.length && content[i] !== "\n") i++;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
if (lineString !== void 0 && content.startsWith(lineString, i)) {
|
|
214
|
+
while (i < content.length && content[i] !== "\n") i++;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
if (rRaw) {
|
|
218
|
+
const rOpen = matchRRawOpener(content, i);
|
|
219
|
+
if (rOpen !== null) {
|
|
220
|
+
const end = content.indexOf(rOpen.closer, rOpen.openerEnd);
|
|
221
|
+
i = end === -1 ? content.length : end + rOpen.closer.length - 1;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (rawString && ch === '"') {
|
|
226
|
+
const run = quoteRunLength(content, i);
|
|
227
|
+
if (run >= 3) {
|
|
228
|
+
const end = skipRawStringQuotes(content, i + run, run);
|
|
229
|
+
i = end === -1 ? content.length : end - 1;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const tripleAt = tripleDelims.find((t) => content.startsWith(t, i));
|
|
234
|
+
if (tripleAt !== void 0) {
|
|
235
|
+
const end = closingQuoteRunEnd(content, i + 3, tripleAt[0] ?? '"', 3, opts?.tripleQuoteRunClose ?? "last");
|
|
236
|
+
i = end === -1 ? content.length : end - 1;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (ch === "'" && opts?.symbolLiterals === true) {
|
|
240
|
+
const charLen = scalaCharLiteralLength(content, i);
|
|
241
|
+
if (charLen > 0) i += charLen - 1;
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (ch === '"' || ch === "'" || backtick && ch === "`") {
|
|
245
|
+
quote = ch;
|
|
246
|
+
verbatim = escapes === "csharp" && ch === '"' && opensCsharpVerbatimString(content, i);
|
|
247
|
+
interpolated = interpolation !== void 0 && opensInterpolatedString(content, i, interpolation);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (ch === "{") depth++;
|
|
251
|
+
else if (ch === "}") {
|
|
252
|
+
depth--;
|
|
253
|
+
if (depth === 0) {
|
|
254
|
+
return offsetToLine(lineIndex, i);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return opts?.noMatchValue ?? totalLines;
|
|
259
|
+
}
|
|
260
|
+
function assignBraceBlockSpans(symbols, content, opts = {}) {
|
|
261
|
+
const lineCommentPrefix = opts.lineComment;
|
|
262
|
+
const stringEscapes = opts.stringEscapes ?? "backslash";
|
|
263
|
+
const nestedBlockComments = opts.nestedBlockComments ?? false;
|
|
264
|
+
const tripleQuote = opts.tripleQuote ?? false;
|
|
265
|
+
const lineStringPrefix = opts.lineStringPrefix;
|
|
266
|
+
const firstLinePrefix = toLineCommentPrefixes(lineCommentPrefix)[0];
|
|
267
|
+
if (symbols.length === 0) return [...symbols];
|
|
268
|
+
const lines = content.split("\n");
|
|
269
|
+
const totalLines = lines.length;
|
|
270
|
+
const lineIndex = buildLineIndex(content);
|
|
271
|
+
const starts = [...new Set(symbols.map((s) => s.lineStart))].sort((a, b) => a - b);
|
|
272
|
+
const scanContent = opts.multilineLang === void 0 ? content : maskMultilineStrings(content, opts.multilineLang);
|
|
273
|
+
const blockComment = opts.blockComment !== void 0 ? opts.blockComment ?? void 0 : firstLinePrefix === "//" ? ["/*", "*/"] : firstLinePrefix === "#" ? ["<#", "#>"] : void 0;
|
|
274
|
+
const scanOpts = {
|
|
275
|
+
noMatchValue: -1,
|
|
276
|
+
stringEscapes,
|
|
277
|
+
tripleQuote,
|
|
278
|
+
rawStringQuotes: opts.rawStringQuotes ?? false,
|
|
279
|
+
tripleSingleQuote: opts.tripleSingleQuote ?? false,
|
|
280
|
+
tripleQuoteRunClose: opts.tripleQuoteRunClose ?? "last",
|
|
281
|
+
...opts.interpolation === void 0 ? {} : { interpolation: opts.interpolation },
|
|
282
|
+
...blockComment === void 0 ? {} : { blockComment, nestedBlockComments },
|
|
283
|
+
...lineStringPrefix === void 0 ? {} : { lineStringPrefix },
|
|
284
|
+
...opts.symbolLiterals === true ? { symbolLiterals: true } : {},
|
|
285
|
+
...opts.lineCommentExceptions === void 0 ? {} : { lineCommentExceptions: opts.lineCommentExceptions }
|
|
286
|
+
};
|
|
287
|
+
return symbols.map((sym) => {
|
|
288
|
+
if (sym.lineEnd !== sym.lineStart) return sym;
|
|
289
|
+
const nextStart = starts.find((s) => s > sym.lineStart);
|
|
290
|
+
if (opts.expressionBodies === true) {
|
|
291
|
+
const arrowLast = Math.min(nextStart !== void 0 ? nextStart - 1 : totalLines, sym.lineStart + BRACE_SEARCH_MAX_LINES);
|
|
292
|
+
const arrowEnd = findArrowBodyEndLine(scanContent, lineIndex, sym.lineStart, arrowLast);
|
|
293
|
+
if (arrowEnd !== null) {
|
|
294
|
+
return arrowEnd <= sym.lineStart ? withWholeLineBody(sym, lines) : { ...sym, lineEnd: arrowEnd, body: lines.slice(sym.lineStart - 1, arrowEnd).join("\n") };
|
|
295
|
+
}
|
|
296
|
+
} else if (opts.expressionBodies === "kotlin") {
|
|
297
|
+
const eqEnd = findKotlinEqualsBodyEndLine(scanContent, lineIndex, sym.lineStart, nextStart !== void 0 ? nextStart - 1 : totalLines, opts.symbolLiterals === true);
|
|
298
|
+
if (eqEnd !== null) {
|
|
299
|
+
return eqEnd <= sym.lineStart ? withWholeLineBody(sym, lines) : { ...sym, lineEnd: eqEnd, body: lines.slice(sym.lineStart - 1, eqEnd).join("\n") };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const lastSearchLine = Math.min(nextStart !== void 0 ? nextStart - 1 : totalLines, sym.lineStart + BRACE_SEARCH_MAX_LINES);
|
|
303
|
+
const openIndex = findBlockOpenBrace(scanContent, lineIndex, sym.lineStart, lastSearchLine, lineCommentPrefix, TYPE_HEADER_KINDS.test(sym.kind) ? { ...scanOpts, typeHeader: true } : scanOpts);
|
|
304
|
+
if (openIndex === null) return sym;
|
|
305
|
+
if (opts.expressionBodies === "kotlin" && isAbstractValueFollowedByBareBlock(sym, scanContent, lineIndex, openIndex)) return sym;
|
|
306
|
+
const endLine = findMatchingBraceEndLine(
|
|
307
|
+
scanContent,
|
|
308
|
+
openIndex,
|
|
309
|
+
totalLines,
|
|
310
|
+
lineIndex,
|
|
311
|
+
lineCommentPrefix,
|
|
312
|
+
scanOpts
|
|
313
|
+
);
|
|
314
|
+
if (endLine === sym.lineStart) return withWholeLineBody(sym, lines);
|
|
315
|
+
if (endLine < sym.lineStart) return sym;
|
|
316
|
+
return { ...sym, lineEnd: endLine, body: lines.slice(sym.lineStart - 1, endLine).join("\n") };
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function withWholeLineBody(sym, lines) {
|
|
320
|
+
const line = lines[sym.lineStart - 1];
|
|
321
|
+
if (line === void 0 || sym.body.includes("{") || !line.includes("{")) return sym;
|
|
322
|
+
return { ...sym, body: line.trimEnd() };
|
|
323
|
+
}
|
|
324
|
+
var BRACE_SEARCH_MAX_LINES = 10;
|
|
325
|
+
function skipCsharpInterpolationHole(content, i, to) {
|
|
326
|
+
let depth = 0;
|
|
327
|
+
for (let k = i; k < to; k++) {
|
|
328
|
+
const lit = skipCsharpLiteral(content, k, to);
|
|
329
|
+
if (lit !== null) {
|
|
330
|
+
k = lit - 1;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const ch = content[k];
|
|
334
|
+
if (ch === "{") depth++;
|
|
335
|
+
else if (ch === "}" && --depth === 0) return k + 1;
|
|
336
|
+
}
|
|
337
|
+
return to;
|
|
338
|
+
}
|
|
339
|
+
function skipCsharpLiteral(content, i, to) {
|
|
340
|
+
const first = content[i];
|
|
341
|
+
if (first === "'") {
|
|
342
|
+
if (content[i + 1] === "\\") {
|
|
343
|
+
const close = content.indexOf("'", i + 3);
|
|
344
|
+
return close === -1 || close >= to ? null : close + 1;
|
|
345
|
+
}
|
|
346
|
+
return content[i + 2] === "'" ? i + 3 : null;
|
|
347
|
+
}
|
|
348
|
+
let j = i;
|
|
349
|
+
while ((content[j] === "$" || content[j] === "@") && j - i < 3) j++;
|
|
350
|
+
if (content[j] !== '"') return null;
|
|
351
|
+
const prefix = content.slice(i, j);
|
|
352
|
+
if (j > i && /[A-Za-z0-9_]/.test(content[i - 1] ?? "")) return null;
|
|
353
|
+
const interpolated = prefix.includes("$");
|
|
354
|
+
const verbatim = prefix.includes("@");
|
|
355
|
+
const run = quoteRunLength(content, j);
|
|
356
|
+
if (run >= 3) {
|
|
357
|
+
const end = skipRawStringQuotes(content, j + run, run);
|
|
358
|
+
return end === -1 ? to : end;
|
|
359
|
+
}
|
|
360
|
+
for (let k = j + 1; k < to; k++) {
|
|
361
|
+
const ch = content[k];
|
|
362
|
+
if (ch === void 0) break;
|
|
363
|
+
if (verbatim) {
|
|
364
|
+
if (ch === '"') {
|
|
365
|
+
if (content[k + 1] === '"') {
|
|
366
|
+
k++;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
return k + 1;
|
|
370
|
+
}
|
|
371
|
+
} else if (ch === "\\") {
|
|
372
|
+
k++;
|
|
373
|
+
continue;
|
|
374
|
+
} else if (ch === '"') return k + 1;
|
|
375
|
+
if (interpolated) {
|
|
376
|
+
if (ch === "{") {
|
|
377
|
+
if (content[k + 1] === "{") {
|
|
378
|
+
k++;
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
k = skipCsharpInterpolationHole(content, k, to) - 1;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return to;
|
|
386
|
+
}
|
|
387
|
+
function findArrowBodyEndLine(content, lineIndex, startLine, lastSearchLine) {
|
|
388
|
+
const from = lineIndex[startLine - 1];
|
|
389
|
+
if (from === void 0) return null;
|
|
390
|
+
const to = lineIndex[lastSearchLine] ?? content.length;
|
|
391
|
+
let depth = 0;
|
|
392
|
+
let seenArrow = false;
|
|
393
|
+
for (let i = from; i < to; i++) {
|
|
394
|
+
const ch = content[i];
|
|
395
|
+
if (ch === void 0) break;
|
|
396
|
+
if (ch === "/" && content[i + 1] === "/") {
|
|
397
|
+
while (i + 1 < to && content[i + 1] !== "\n") i++;
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
if (ch === "/" && content[i + 1] === "*") {
|
|
401
|
+
const end = content.indexOf("*/", i + 2);
|
|
402
|
+
if (end === -1) return null;
|
|
403
|
+
i = end + 1;
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
const lit = skipCsharpLiteral(content, i, to);
|
|
407
|
+
if (lit !== null) {
|
|
408
|
+
i = lit - 1;
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (ch === "(" || ch === "[") depth++;
|
|
412
|
+
else if (ch === ")" || ch === "]") {
|
|
413
|
+
if (depth > 0) depth--;
|
|
414
|
+
} else if (ch === "=" && content[i + 1] === ">" && depth === 0) {
|
|
415
|
+
seenArrow = true;
|
|
416
|
+
i++;
|
|
417
|
+
} else if (ch === "{") {
|
|
418
|
+
if (!seenArrow && depth === 0) return null;
|
|
419
|
+
depth++;
|
|
420
|
+
} else if (ch === "}") {
|
|
421
|
+
if (depth === 0) return null;
|
|
422
|
+
depth--;
|
|
423
|
+
} else if (ch === ";" && depth === 0) {
|
|
424
|
+
if (!seenArrow) return null;
|
|
425
|
+
let line = startLine;
|
|
426
|
+
for (let k = from; k < i; k++) if (content[k] === "\n") line++;
|
|
427
|
+
return line;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
function skipKotlinTemplateHole(content, i, to, symbolLiterals = false) {
|
|
433
|
+
let depth = 0;
|
|
434
|
+
for (let k = i; k < to; k++) {
|
|
435
|
+
const lit = skipKotlinLiteral(content, k, to, symbolLiterals);
|
|
436
|
+
if (lit !== null) {
|
|
437
|
+
k = lit - 1;
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
const ch = content[k];
|
|
441
|
+
if (ch === "{") depth++;
|
|
442
|
+
else if (ch === "}" && --depth === 0) return k + 1;
|
|
443
|
+
}
|
|
444
|
+
return to;
|
|
445
|
+
}
|
|
446
|
+
function skipKotlinLiteral(content, i, to, symbolLiterals = false) {
|
|
447
|
+
const first = content[i];
|
|
448
|
+
if (first === "'" && symbolLiterals) {
|
|
449
|
+
const len = scalaCharLiteralLength(content, i);
|
|
450
|
+
return len > 0 ? i + len : null;
|
|
451
|
+
}
|
|
452
|
+
if (first === "'") {
|
|
453
|
+
for (let k = i + 1; k < to && content[k] !== "\n"; k++) {
|
|
454
|
+
if (content[k] === "\\") {
|
|
455
|
+
k++;
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (content[k] === "'") return k + 1;
|
|
459
|
+
}
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
if (first !== '"') return null;
|
|
463
|
+
const triple = content.startsWith('"""', i);
|
|
464
|
+
for (let k = i + (triple ? 3 : 1); k < to; k++) {
|
|
465
|
+
const ch = content[k];
|
|
466
|
+
if (triple) {
|
|
467
|
+
if (ch === '"' && content.startsWith('"""', k)) {
|
|
468
|
+
k += 3;
|
|
469
|
+
while (content[k] === '"') k++;
|
|
470
|
+
return k;
|
|
471
|
+
}
|
|
472
|
+
} else if (ch === "\\") {
|
|
473
|
+
k++;
|
|
474
|
+
continue;
|
|
475
|
+
} else if (ch === '"') return k + 1;
|
|
476
|
+
else if (ch === "\n") return k;
|
|
477
|
+
if (ch === "$" && content[k + 1] === "{") k = skipKotlinTemplateHole(content, k + 1, to, symbolLiterals) - 1;
|
|
478
|
+
}
|
|
479
|
+
return to;
|
|
480
|
+
}
|
|
481
|
+
function opensInterpolatedString(content, i, lang) {
|
|
482
|
+
const q = content[i];
|
|
483
|
+
const prev = content[i - 1] ?? "";
|
|
484
|
+
if (lang === "csharp") return q === '"' && (prev === "$" || prev === "@" && content[i - 2] === "$");
|
|
485
|
+
if (lang === "scala") return q === '"' && /[A-Za-z0-9_]/.test(prev);
|
|
486
|
+
if (lang === "dart") return !(prev === "r" && !/[A-Za-z0-9_$]/.test(content[i - 2] ?? ""));
|
|
487
|
+
return q === '"';
|
|
488
|
+
}
|
|
489
|
+
function skipInterpolationAt(content, i, to, lang) {
|
|
490
|
+
const ch = content[i];
|
|
491
|
+
if (lang === "swift") return ch === "\\" && content[i + 1] === "(" ? skipInterpolationHole(content, i + 1, to, lang) : null;
|
|
492
|
+
if (lang === "csharp") {
|
|
493
|
+
if (ch !== "{") return null;
|
|
494
|
+
return content[i + 1] === "{" ? i + 2 : skipInterpolationHole(content, i, to, lang);
|
|
495
|
+
}
|
|
496
|
+
return ch === "$" && content[i + 1] === "{" ? skipInterpolationHole(content, i + 1, to, lang) : null;
|
|
497
|
+
}
|
|
498
|
+
function skipInterpolationHole(content, i, to, lang) {
|
|
499
|
+
const open = content[i];
|
|
500
|
+
const close = open === "(" ? ")" : "}";
|
|
501
|
+
let depth = 0;
|
|
502
|
+
for (let k = i; k < to; k++) {
|
|
503
|
+
const lit = skipNestedLiteral(content, k, to, lang);
|
|
504
|
+
if (lit !== null) {
|
|
505
|
+
k = lit - 1;
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
const ch = content[k];
|
|
509
|
+
if (ch === open) depth++;
|
|
510
|
+
else if (ch === close && --depth === 0) return k + 1;
|
|
511
|
+
}
|
|
512
|
+
return to;
|
|
513
|
+
}
|
|
514
|
+
function skipNestedLiteral(content, i, to, lang) {
|
|
515
|
+
const ch = content[i];
|
|
516
|
+
if (lang === "csharp") return skipCsharpLiteral(content, i, to);
|
|
517
|
+
if (lang === "kotlin") return skipKotlinLiteral(content, i, to);
|
|
518
|
+
if (ch === "'" && lang === "scala") {
|
|
519
|
+
const len = scalaCharLiteralLength(content, i);
|
|
520
|
+
return len > 0 ? i + len : null;
|
|
521
|
+
}
|
|
522
|
+
if (ch !== '"' && !(ch === "'" && lang === "dart")) return null;
|
|
523
|
+
return skipInterpolatedString(content, i, to, lang, opensInterpolatedString(content, i, lang));
|
|
524
|
+
}
|
|
525
|
+
function skipInterpolatedString(content, i, to, lang, interpolated) {
|
|
526
|
+
const q = content[i];
|
|
527
|
+
if (content.startsWith(q + q + q, i)) {
|
|
528
|
+
const end = content.indexOf(q + q + q, i + 3);
|
|
529
|
+
return end === -1 || end >= to ? to : end + 3;
|
|
530
|
+
}
|
|
531
|
+
for (let k = i + 1; k < to; k++) {
|
|
532
|
+
const ch = content[k];
|
|
533
|
+
if (ch === "\n") return k;
|
|
534
|
+
if (interpolated) {
|
|
535
|
+
const past = skipInterpolationAt(content, k, to, lang);
|
|
536
|
+
if (past !== null) {
|
|
537
|
+
k = past - 1;
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
if (ch === "\\") {
|
|
542
|
+
k++;
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
if (ch === q) return k + 1;
|
|
546
|
+
}
|
|
547
|
+
return to;
|
|
548
|
+
}
|
|
549
|
+
function kotlinBodyContinues(content, lastSig, ifParenClosedAt, nextLineFrom) {
|
|
550
|
+
const c = content[lastSig];
|
|
551
|
+
const prev = content[lastSig - 1];
|
|
552
|
+
if (lastSig === ifParenClosedAt) return true;
|
|
553
|
+
if (c !== void 0 && "=*/%&|,.:".includes(c)) return true;
|
|
554
|
+
if ((c === "+" || c === "-") && prev !== c) return true;
|
|
555
|
+
if (c === ">" && prev === "-") return true;
|
|
556
|
+
if (/(?:^|[^A-Za-z0-9_])else$/.test(content.slice(Math.max(0, lastSig - 4), lastSig + 1))) return true;
|
|
557
|
+
const rest = content.slice(nextLineFrom);
|
|
558
|
+
const next = /^(?:[ \t\r]*(?:\/\/[^\n]*)?\n)*[ \t]*(\.|\?\.|\?:|&&|\|\||else\b|as\b|catch\b|finally\b)/.exec(rest);
|
|
559
|
+
return next !== null;
|
|
560
|
+
}
|
|
561
|
+
var NEXT_LINE_STARTS_WITH_EQUALS = /^(?:[ \t\r]*(?:\/\/[^\n]*)?\n)*[ \t]*=(?!=)/;
|
|
562
|
+
function findKotlinEqualsBodyEndLine(content, lineIndex, startLine, lastLine, symbolLiterals = false) {
|
|
563
|
+
const from = lineIndex[startLine - 1];
|
|
564
|
+
if (from === void 0) return null;
|
|
565
|
+
const to = lineIndex[lastLine] ?? content.length;
|
|
566
|
+
let depth = 0;
|
|
567
|
+
let seenEq = false;
|
|
568
|
+
let line = startLine;
|
|
569
|
+
let lastSig = -1;
|
|
570
|
+
let ifParenClosedAt = -1;
|
|
571
|
+
const ifParens = [];
|
|
572
|
+
for (let i = from; i < to; i++) {
|
|
573
|
+
const ch = content[i];
|
|
574
|
+
if (ch === void 0) break;
|
|
575
|
+
if (ch === "\n") {
|
|
576
|
+
if (depth === 0) {
|
|
577
|
+
if (!seenEq && !NEXT_LINE_STARTS_WITH_EQUALS.test(content.slice(i + 1, to))) return null;
|
|
578
|
+
if (seenEq && !kotlinBodyContinues(content, lastSig, ifParenClosedAt, i + 1)) return line;
|
|
579
|
+
}
|
|
580
|
+
line++;
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
if (ch === " " || ch === " " || ch === "\r") continue;
|
|
584
|
+
if (ch === "/" && content[i + 1] === "/") {
|
|
585
|
+
while (i + 1 < to && content[i + 1] !== "\n") i++;
|
|
586
|
+
continue;
|
|
587
|
+
}
|
|
588
|
+
if (ch === "/" && content[i + 1] === "*") {
|
|
589
|
+
const end = content.indexOf("*/", i + 2);
|
|
590
|
+
if (end === -1) return null;
|
|
591
|
+
for (let k = i; k < end; k++) if (content[k] === "\n") line++;
|
|
592
|
+
i = end + 1;
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
const lit = skipKotlinLiteral(content, i, to, symbolLiterals);
|
|
596
|
+
if (lit !== null) {
|
|
597
|
+
for (let k = i; k < lit; k++) if (content[k] === "\n") line++;
|
|
598
|
+
lastSig = lit - 1;
|
|
599
|
+
i = lit - 1;
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
lastSig = i;
|
|
603
|
+
if (ch === "(" || ch === "[" || ch === "{") {
|
|
604
|
+
if (ch === "{" && !seenEq && depth === 0) return null;
|
|
605
|
+
ifParens.push(ch === "(" && /\bif\s*$/.test(content.slice(Math.max(from, i - 8), i)));
|
|
606
|
+
depth++;
|
|
607
|
+
} else if (ch === ")" || ch === "]" || ch === "}") {
|
|
608
|
+
if (depth === 0) return null;
|
|
609
|
+
depth--;
|
|
610
|
+
if (ifParens.pop() === true) ifParenClosedAt = i;
|
|
611
|
+
} else if (ch === "=" && !seenEq && depth === 0 && !"=!<>".includes(content[i - 1] ?? " ") && content[i + 1] !== "=") {
|
|
612
|
+
seenEq = true;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return seenEq && depth === 0 ? line : null;
|
|
616
|
+
}
|
|
617
|
+
function maskMultilineStrings(content, lang) {
|
|
618
|
+
let state = null;
|
|
619
|
+
const parts = [];
|
|
620
|
+
let pos = 0;
|
|
621
|
+
for (; ; ) {
|
|
622
|
+
const nl = content.indexOf("\n", pos);
|
|
623
|
+
const end = nl === -1 ? content.length : nl;
|
|
624
|
+
const lineEnd = end > pos && content[end - 1] === "\r" ? end - 1 : end;
|
|
625
|
+
const masked = stripMultilineStringSpan(content.slice(pos, lineEnd), state, lang);
|
|
626
|
+
state = masked.state;
|
|
627
|
+
parts.push(masked.code, content.slice(lineEnd, end));
|
|
628
|
+
if (nl === -1) break;
|
|
629
|
+
parts.push("\n");
|
|
630
|
+
pos = nl + 1;
|
|
631
|
+
}
|
|
632
|
+
return parts.join("");
|
|
633
|
+
}
|
|
634
|
+
function findBlockOpenBrace(content, lineIndex, startLine, lastSearchLine, lineCommentPrefix, opts) {
|
|
635
|
+
const blockComment = opts?.blockComment;
|
|
636
|
+
const stringEscapes = opts?.stringEscapes ?? "backslash";
|
|
637
|
+
const nestedBlockComments = opts?.nestedBlockComments === true;
|
|
638
|
+
const rawString = opts?.rawStringQuotes === true;
|
|
639
|
+
const tripleDelims = tripleQuoteDelimiters(opts);
|
|
640
|
+
const lineString = opts?.lineStringPrefix;
|
|
641
|
+
const linePrefixes = toLineCommentPrefixes(lineCommentPrefix);
|
|
642
|
+
const lineExceptions = opts?.lineCommentExceptions ?? [];
|
|
643
|
+
const from = lineIndex[startLine - 1];
|
|
644
|
+
if (from === void 0) return null;
|
|
645
|
+
const to = lineIndex[lastSearchLine] ?? content.length;
|
|
646
|
+
const interpolation = opts?.interpolation;
|
|
647
|
+
let interpolated = false;
|
|
648
|
+
let quote = null;
|
|
649
|
+
let parenDepth = 0;
|
|
650
|
+
let linesSeen = 0;
|
|
651
|
+
let atLineStart = false;
|
|
652
|
+
let verbatim = false;
|
|
653
|
+
for (let i = from; i < to; i++) {
|
|
654
|
+
const ch = content[i];
|
|
655
|
+
if (ch === void 0) break;
|
|
656
|
+
if (quote !== null) {
|
|
657
|
+
if (interpolated && interpolation !== void 0) {
|
|
658
|
+
const past = skipInterpolationAt(content, i, to, interpolation);
|
|
659
|
+
if (past !== null) {
|
|
660
|
+
i = past - 1;
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (verbatim) {
|
|
665
|
+
if (ch === quote) {
|
|
666
|
+
if (content[i + 1] === quote) {
|
|
667
|
+
i++;
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
quote = null;
|
|
671
|
+
verbatim = false;
|
|
672
|
+
}
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (stringEscapes === "powershell") {
|
|
676
|
+
const step = stepPowershellString(content, i, quote);
|
|
677
|
+
i = step.next;
|
|
678
|
+
if (!step.open) quote = null;
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
if (ch === "\\") {
|
|
682
|
+
i++;
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
if (ch === quote) quote = null;
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
if (ch === "\n") {
|
|
689
|
+
linesSeen++;
|
|
690
|
+
atLineStart = true;
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
if (blockComment !== void 0 && content.startsWith(blockComment[0], i)) {
|
|
694
|
+
const end = skipBlockComment(content, i, blockComment, nestedBlockComments);
|
|
695
|
+
if (end === -1) return null;
|
|
696
|
+
i = end - 1;
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
if (atLineComment(content, i, linePrefixes, lineExceptions)) {
|
|
700
|
+
while (i + 1 < to && content[i + 1] !== "\n") i++;
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
if (atLineStart && !/\s/.test(ch)) {
|
|
704
|
+
atLineStart = false;
|
|
705
|
+
if (parenDepth === 0 && linesSeen >= 1 && startsWithBlockKeyword(content, i, to, opts?.typeHeader !== true)) return null;
|
|
706
|
+
}
|
|
707
|
+
if (lineString !== void 0 && content.startsWith(lineString, i)) {
|
|
708
|
+
while (i + 1 < to && content[i + 1] !== "\n") i++;
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
if (rawString && ch === '"') {
|
|
712
|
+
const run = quoteRunLength(content, i);
|
|
713
|
+
if (run >= 3) {
|
|
714
|
+
const end = skipRawStringQuotes(content, i + run, run);
|
|
715
|
+
if (end === -1) return null;
|
|
716
|
+
i = end - 1;
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
const tripleAt = tripleDelims.find((t) => content.startsWith(t, i));
|
|
721
|
+
if (tripleAt !== void 0) {
|
|
722
|
+
const end = closingQuoteRunEnd(content, i + 3, tripleAt[0] ?? '"', 3, opts?.tripleQuoteRunClose ?? "last");
|
|
723
|
+
if (end === -1) return null;
|
|
724
|
+
i = end - 1;
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
if (ch === "'" && opts?.symbolLiterals === true) {
|
|
728
|
+
const charLen = scalaCharLiteralLength(content, i);
|
|
729
|
+
if (charLen > 0) i += charLen - 1;
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
if (ch === '"' || ch === "'") {
|
|
733
|
+
quote = ch;
|
|
734
|
+
verbatim = stringEscapes === "csharp" && ch === '"' && opensCsharpVerbatimString(content, i);
|
|
735
|
+
interpolated = interpolation !== void 0 && opensInterpolatedString(content, i, interpolation);
|
|
736
|
+
continue;
|
|
737
|
+
}
|
|
738
|
+
if (ch === "(" || ch === "[") parenDepth++;
|
|
739
|
+
else if (ch === ")" || ch === "]") {
|
|
740
|
+
if (parenDepth > 0) parenDepth--;
|
|
741
|
+
} else if (ch === ";") return null;
|
|
742
|
+
else if (ch === "}" && parenDepth === 0) return null;
|
|
743
|
+
else if (ch === "{") return i;
|
|
744
|
+
}
|
|
745
|
+
return null;
|
|
746
|
+
}
|
|
747
|
+
var BLOCK_OPENING_KEYWORDS = /* @__PURE__ */ new Set([
|
|
748
|
+
"if",
|
|
749
|
+
"for",
|
|
750
|
+
"while",
|
|
751
|
+
"do",
|
|
752
|
+
"switch",
|
|
753
|
+
"when",
|
|
754
|
+
"match",
|
|
755
|
+
"try",
|
|
756
|
+
"foreach",
|
|
757
|
+
"loop",
|
|
758
|
+
"guard",
|
|
759
|
+
"repeat",
|
|
760
|
+
"unless",
|
|
761
|
+
"until"
|
|
762
|
+
]);
|
|
763
|
+
function isAbstractValueFollowedByBareBlock(sym, content, lineIndex, openIndex) {
|
|
764
|
+
const openLine = offsetToLine(lineIndex, openIndex);
|
|
765
|
+
return /^va[lr]$/.test(sym.kind) && openLine > sym.lineStart && lineTextAt(content, lineIndex, openLine) === "{" && !lineTextAt(content, lineIndex, sym.lineStart).includes("=");
|
|
766
|
+
}
|
|
767
|
+
var TYPE_HEADER_KINDS = /^(?:class|object|interface|trait|enum|struct|protocol|record|extension)$/;
|
|
768
|
+
var MEMBER_START_WORDS = /* @__PURE__ */ new Set(["init", "locally", "constructor", "companion"]);
|
|
769
|
+
function startsWithBlockKeyword(content, i, to, members) {
|
|
770
|
+
const first = content[i];
|
|
771
|
+
if (first === void 0 || !/[A-Za-z_]/.test(first)) return false;
|
|
772
|
+
let j = i + 1;
|
|
773
|
+
while (j < to && /[A-Za-z0-9_]/.test(content[j])) j++;
|
|
774
|
+
const word = content.slice(i, j);
|
|
775
|
+
return BLOCK_OPENING_KEYWORDS.has(word) || members && MEMBER_START_WORDS.has(word);
|
|
776
|
+
}
|
|
777
|
+
|
|
85
778
|
// src/languages/csharp.ts
|
|
86
779
|
init_define_import_meta_env();
|
|
87
780
|
var IDENT = "@?[A-Za-z_][A-Za-z0-9_]*";
|
|
@@ -167,6 +860,66 @@ function nextCodeLines(lines, from, count) {
|
|
|
167
860
|
}
|
|
168
861
|
return out;
|
|
169
862
|
}
|
|
863
|
+
function typeKind(keyword) {
|
|
864
|
+
return keyword === "struct" ? "struct" : keyword === "interface" ? "interface" : keyword === "enum" ? "enum" : "class";
|
|
865
|
+
}
|
|
866
|
+
function operatorName(opM) {
|
|
867
|
+
return opM[1] !== void 0 ? `operator ${opM[1].replace(/\s+/g, " ").trim()}` : `operator${opM[2] !== void 0 ? " checked " : ""}${opM[3] ?? ""}`;
|
|
868
|
+
}
|
|
869
|
+
function memberDecls(decl, parent) {
|
|
870
|
+
const delM = DELEGATE_RE.exec(decl);
|
|
871
|
+
if (delM) return [[stripVerbatim(delM[1] ?? ""), "type"]];
|
|
872
|
+
const eventM = EVENT_RE.exec(decl);
|
|
873
|
+
if (eventM) {
|
|
874
|
+
const out = [];
|
|
875
|
+
for (const part of splitEventDeclarators(decl.slice(eventM[0].length).split(/[;{]/)[0] ?? "")) {
|
|
876
|
+
const declM = EVENT_NAME_RE.exec(part.split("=")[0]?.trim() ?? "");
|
|
877
|
+
if (declM) out.push([stripVerbatim(declM[1] ?? ""), "var"]);
|
|
878
|
+
}
|
|
879
|
+
return out;
|
|
880
|
+
}
|
|
881
|
+
const ctorM = CONSTRUCTOR_RE.exec(decl);
|
|
882
|
+
if (ctorM && stripVerbatim(ctorM[1] ?? "") === parent) return [[parent, "method"]];
|
|
883
|
+
const propM = PROPERTY_RE.exec(decl) ?? PROPERTY_ARROW_RE.exec(decl);
|
|
884
|
+
if (propM) return [[stripVerbatim(propM[1] ?? ""), "var"]];
|
|
885
|
+
const finM = FINALIZER_RE.exec(decl);
|
|
886
|
+
if (finM && stripVerbatim(finM[1] ?? "") === parent) return [[`~${parent}`, "method"]];
|
|
887
|
+
const opM = OPERATOR_RE.exec(decl);
|
|
888
|
+
if (opM && isDeclarationPrefix(decl.slice(0, opM.index))) return [[operatorName(opM), "method"]];
|
|
889
|
+
const ixM = INDEXER_RE.exec(decl);
|
|
890
|
+
if (ixM && isDeclarationPrefix(decl.slice(0, ixM.index))) return [["this[]", "var"]];
|
|
891
|
+
const methM = METHOD_RE.exec(decl);
|
|
892
|
+
const mname = methM ? stripVerbatim(methM[1] ?? "") : "";
|
|
893
|
+
return mname && mname !== parent ? [[mname, "method"]] : [];
|
|
894
|
+
}
|
|
895
|
+
function inlineCsharpMembers(line, code, segs, parent, filePath, lineNum, level = 0) {
|
|
896
|
+
const members = [];
|
|
897
|
+
const opens = [];
|
|
898
|
+
for (const seg of segs) {
|
|
899
|
+
const text = line.slice(seg.start, seg.end).trim();
|
|
900
|
+
const decl = stripLeadingAttributes(text);
|
|
901
|
+
const classM = CLASS_HEADER_RE.exec(decl);
|
|
902
|
+
if (classM) {
|
|
903
|
+
const brace = bodyBraceAt(code, seg.start, seg.end);
|
|
904
|
+
if (seg.open && brace === -1) continue;
|
|
905
|
+
const name = stripVerbatim(classM[2] ?? "");
|
|
906
|
+
const typeSym = makeLineSymbol(filePath, name, typeKind(classM[1] ?? "class"), lineNum, text, parent);
|
|
907
|
+
members.push(typeSym);
|
|
908
|
+
if (brace !== -1) {
|
|
909
|
+
const inner = inlineCsharpMembers(line, code, bodySegments(code, brace + 1), name, filePath, lineNum, level + 1);
|
|
910
|
+
members.push(...inner.members);
|
|
911
|
+
if (seg.open) opens.push({ sym: typeSym, level, isType: true }, ...inner.opens);
|
|
912
|
+
}
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
for (const [name, kind] of memberDecls(decl, parent)) {
|
|
916
|
+
const sym = makeLineSymbol(filePath, name, kind, lineNum, text, parent);
|
|
917
|
+
members.push(sym);
|
|
918
|
+
if (seg.open) opens.push({ sym, level, isType: false });
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return { members, opens };
|
|
922
|
+
}
|
|
170
923
|
var CS_REF_NOISE = /* @__PURE__ */ new Set([
|
|
171
924
|
"if",
|
|
172
925
|
"else",
|
|
@@ -272,6 +1025,8 @@ function extractCsharp(content, filePath) {
|
|
|
272
1025
|
let falseNesting = 0;
|
|
273
1026
|
let currentMember;
|
|
274
1027
|
let memberBodyEntered = false;
|
|
1028
|
+
const settled = /* @__PURE__ */ new Set();
|
|
1029
|
+
let openMembers = [];
|
|
275
1030
|
for (let i = 0; i < lines.length; i++) {
|
|
276
1031
|
const rawLine = lines[i] ?? "";
|
|
277
1032
|
const lineNum = i + 1;
|
|
@@ -313,13 +1068,11 @@ function extractCsharp(content, filePath) {
|
|
|
313
1068
|
const delegateParent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
314
1069
|
symbols.push(makeLineSymbol(filePath, stripVerbatim(delM[1] ?? ""), "type", lineNum, stripped.slice(0, 200), delegateParent, lines, "c"));
|
|
315
1070
|
}
|
|
1071
|
+
const outerFrame = classStack.length > 0 ? classStack[classStack.length - 1] : null;
|
|
316
1072
|
const cm = CLASS_HEADER_RE.exec(stripLeadingAttributes(stripped));
|
|
317
1073
|
if (cm) {
|
|
318
|
-
const keyword = cm[1] ?? "class";
|
|
319
1074
|
const cname = stripVerbatim(cm[2] ?? "");
|
|
320
|
-
|
|
321
|
-
const parent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
322
|
-
symbols.push(makeLineSymbol(filePath, cname, kind, lineNum, stripped.slice(0, 200), parent, lines, "c"));
|
|
1075
|
+
symbols.push(makeLineSymbol(filePath, cname, typeKind(cm[1] ?? "class"), lineNum, stripped.slice(0, 200), outerFrame?.name, lines, "c"));
|
|
323
1076
|
classStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false });
|
|
324
1077
|
}
|
|
325
1078
|
let ctorM = null;
|
|
@@ -386,7 +1139,7 @@ function extractCsharp(content, filePath) {
|
|
|
386
1139
|
if (finM && stripVerbatim(finM[1] ?? "") === frame.name) specialName = `~${frame.name}`;
|
|
387
1140
|
else finM = null;
|
|
388
1141
|
const opM = specialName === null && !isPropertyLine ? OPERATOR_RE.exec(lineNoAttr) : null;
|
|
389
|
-
if (opM && isDeclarationPrefix(lineNoAttr.slice(0, opM.index))) specialName = opM
|
|
1142
|
+
if (opM && isDeclarationPrefix(lineNoAttr.slice(0, opM.index))) specialName = operatorName(opM);
|
|
390
1143
|
const ixM = specialName === null && !isPropertyLine ? INDEXER_RE.exec(lineNoAttr) : null;
|
|
391
1144
|
if (ixM && isDeclarationPrefix(lineNoAttr.slice(0, ixM.index))) {
|
|
392
1145
|
specialName = "this[]";
|
|
@@ -416,6 +1169,30 @@ function extractCsharp(content, filePath) {
|
|
|
416
1169
|
const isInterpolatedLine = rawLine.includes('$"') || rawLine.includes('$@"') || rawLine.includes('@$"');
|
|
417
1170
|
const baseLine = isInterpolatedLine ? stripLineComment(rawLine) : stripLineComment(line);
|
|
418
1171
|
const braceLine = stripStringLiterals(baseLine, { tripleQuotes: true });
|
|
1172
|
+
const segCode = stripStringLiterals(line, { tripleQuotes: true });
|
|
1173
|
+
const lineOpens = [];
|
|
1174
|
+
const queueMembers = (segs, parent, bodyDepth) => {
|
|
1175
|
+
const { members, opens } = inlineCsharpMembers(line, segCode, segs, parent, filePath, lineNum);
|
|
1176
|
+
symbols.push(...members);
|
|
1177
|
+
for (const m of members) settled.add(m);
|
|
1178
|
+
lineOpens.push(...openMembersOf(opens, bodyDepth));
|
|
1179
|
+
for (const o of opens) {
|
|
1180
|
+
if (!o.isType) continue;
|
|
1181
|
+
const enclosing = classStack[classStack.length - 1];
|
|
1182
|
+
if (enclosing !== void 0) enclosing.bodyEntered = true;
|
|
1183
|
+
classStack.push({ name: o.sym.name, startDepth: bodyDepth + o.level, bodyEntered: true });
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1186
|
+
const lineSegs = bodySegments(segCode, 0);
|
|
1187
|
+
if (frame !== null && frame !== outerFrame && lineSegs[0] !== void 0) {
|
|
1188
|
+
const brace = bodyBraceAt(segCode, lineSegs[0].start, lineSegs[0].end);
|
|
1189
|
+
if (brace !== -1) queueMembers(bodySegments(segCode, brace + 1), frame.name, braceDepth + 1);
|
|
1190
|
+
}
|
|
1191
|
+
const insideMember = outerFrame === null ? -1 : braceDepth - outerFrame.startDepth - 1;
|
|
1192
|
+
if (outerFrame !== null && insideMember >= 0) {
|
|
1193
|
+
const resume = bodyResumeAt(segCode, insideMember);
|
|
1194
|
+
if (resume >= 0) queueMembers(insideMember === 0 ? lineSegs.slice(1) : bodySegments(segCode, resume), outerFrame.name, outerFrame.startDepth + 1);
|
|
1195
|
+
}
|
|
419
1196
|
if (!inFalseBlock && !stripped.startsWith("#")) {
|
|
420
1197
|
const declSpans = [];
|
|
421
1198
|
if (cm) {
|
|
@@ -524,6 +1301,8 @@ function extractCsharp(content, filePath) {
|
|
|
524
1301
|
const openBraces = (braceLine.match(/\{/g) ?? []).length;
|
|
525
1302
|
const closeBraces = (braceLine.match(/\}/g) ?? []).length;
|
|
526
1303
|
braceDepth += openBraces - closeBraces;
|
|
1304
|
+
openMembers = endOpenMembers(symbols, settled, openMembers, braceDepth, lineNum, lines);
|
|
1305
|
+
openMembers.push(...lineOpens);
|
|
527
1306
|
if (currentMember !== void 0) {
|
|
528
1307
|
if (!memberBodyEntered) {
|
|
529
1308
|
if (openBraces > 0 && braceDepth > (frame?.startDepth ?? 0) + 1) {
|
|
@@ -554,7 +1333,7 @@ function extractCsharp(content, filePath) {
|
|
|
554
1333
|
}
|
|
555
1334
|
}
|
|
556
1335
|
}
|
|
557
|
-
return { symbols, refs, imports };
|
|
1336
|
+
return { symbols, refs, imports, settled };
|
|
558
1337
|
}
|
|
559
1338
|
|
|
560
1339
|
// src/languages/php.ts
|
|
@@ -582,6 +1361,18 @@ var USE_RE = /^use\s+(?:function\s+|const\s+)?([\w\\]+)(?:\s+as\s+\w+)?\s*;/i;
|
|
|
582
1361
|
var GROUP_USE_RE = /^use\s+(?:function\s+|const\s+)?([\w\\]+)\\\{([^}]*)\}/i;
|
|
583
1362
|
var REQUIRE_RE = /^(?:require|include)(?:_once)?\s+['"]([^'"]+)['"]/i;
|
|
584
1363
|
var ENUM_CASE_RE = /^case\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:=|;)/i;
|
|
1364
|
+
function inlinePhpMember(text, kind, parent, filePath, lineNum) {
|
|
1365
|
+
const enumCaseM = kind === "enum" && parent !== void 0 ? ENUM_CASE_RE.exec(text) : null;
|
|
1366
|
+
if (enumCaseM) return makeLineSymbol(filePath, enumCaseM[1] ?? "", "const", lineNum, text, parent);
|
|
1367
|
+
if (ANON_FN_RE.test(text)) return null;
|
|
1368
|
+
const methM = METHOD_RE2.exec(text);
|
|
1369
|
+
if (methM) return makeLineSymbol(filePath, methM[1] ?? "", parent === void 0 ? "function" : "method", lineNum, text, parent);
|
|
1370
|
+
const propM = parent === void 0 ? null : PROP_RE.exec(text);
|
|
1371
|
+
if (propM) return makeLineSymbol(filePath, propM[1] ?? "", "var", lineNum, text, parent);
|
|
1372
|
+
const constM = CONST_RE.exec(text);
|
|
1373
|
+
if (constM) return makeLineSymbol(filePath, constM[1] ?? "", "const", lineNum, text, parent);
|
|
1374
|
+
return null;
|
|
1375
|
+
}
|
|
585
1376
|
function maskPhpInlineHtml(content) {
|
|
586
1377
|
const opener = /<\?(?:php\b|=)/i;
|
|
587
1378
|
if (!opener.test(content)) return content;
|
|
@@ -612,12 +1403,34 @@ function extractPhp(content, filePath) {
|
|
|
612
1403
|
const symbols = [];
|
|
613
1404
|
const imports = [];
|
|
614
1405
|
const lines = maskPhpInlineHtml(content).split(/\r?\n/);
|
|
1406
|
+
const settled = /* @__PURE__ */ new Set();
|
|
1407
|
+
let lineMembers = [];
|
|
1408
|
+
let openMember = null;
|
|
1409
|
+
let pendingBrace = null;
|
|
1410
|
+
const queueMembers = (segs, line, kind, parent, lineNum, bodyDepth) => {
|
|
1411
|
+
let open = null;
|
|
1412
|
+
for (const seg of segs) {
|
|
1413
|
+
const text = line.slice(seg.start, seg.end).trim();
|
|
1414
|
+
const sym = inlinePhpMember(text, kind, parent, filePath, lineNum);
|
|
1415
|
+
if (sym === null) continue;
|
|
1416
|
+
lineMembers.push(sym);
|
|
1417
|
+
settled.add(sym);
|
|
1418
|
+
if (seg.open) open = { sym, depth: bodyDepth + 1 };
|
|
1419
|
+
else if (seg === segs[segs.length - 1] && sym.kind !== "const" && sym.kind !== "var" && !/[;}]$/.test(text) && stripStringLiterals(text).split("(").length === stripStringLiterals(text).split(")").length) pendingBrace = { sym, depth: bodyDepth + 1 };
|
|
1420
|
+
}
|
|
1421
|
+
return open;
|
|
1422
|
+
};
|
|
1423
|
+
const flushMembers = () => {
|
|
1424
|
+
symbols.push(...lineMembers);
|
|
1425
|
+
lineMembers = [];
|
|
1426
|
+
};
|
|
615
1427
|
const contextStack = [];
|
|
616
1428
|
let braceDepth = 0;
|
|
617
1429
|
let parenDepth = 0;
|
|
618
1430
|
let inComment = false;
|
|
619
1431
|
let mlState = null;
|
|
620
1432
|
for (let i = 0; i < lines.length; i++) {
|
|
1433
|
+
flushMembers();
|
|
621
1434
|
const rawLine = lines[i] ?? "";
|
|
622
1435
|
const lineNum = i + 1;
|
|
623
1436
|
let mlLine = rawLine;
|
|
@@ -645,6 +1458,23 @@ function extractPhp(content, filePath) {
|
|
|
645
1458
|
if (topFrame !== void 0 && braceDepth > topFrame[1]) {
|
|
646
1459
|
topFrame[2] = true;
|
|
647
1460
|
}
|
|
1461
|
+
if (pendingBrace !== null) {
|
|
1462
|
+
if (stripped.startsWith("{")) openMember = pendingBrace;
|
|
1463
|
+
pendingBrace = null;
|
|
1464
|
+
}
|
|
1465
|
+
if (openMember !== null && braceDepth < openMember.depth) {
|
|
1466
|
+
endOpenMember(symbols, settled, openMember, lineNum, lines);
|
|
1467
|
+
openMember = null;
|
|
1468
|
+
}
|
|
1469
|
+
const bodyBase = topFrame === void 0 ? 0 : topFrame[1] + 1;
|
|
1470
|
+
const preDepth = braceDepth - openB + closeB;
|
|
1471
|
+
if ((topFrame === void 0 || topFrame[2]) && preDepth >= bodyBase && preLineParenDepth === 0) {
|
|
1472
|
+
const resume = bodyResumeAt(braceLine, preDepth - bodyBase);
|
|
1473
|
+
if (resume >= 0 && (preDepth > bodyBase || topFrame !== void 0)) {
|
|
1474
|
+
const segs = bodySegments(braceLine, resume);
|
|
1475
|
+
openMember = queueMembers(preDepth === bodyBase ? segs.slice(1) : segs, line, topFrame?.[3] ?? "file", topFrame?.[0], lineNum, bodyBase) ?? openMember;
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
648
1478
|
while (contextStack.length > 0) {
|
|
649
1479
|
const top = contextStack[contextStack.length - 1];
|
|
650
1480
|
if (top !== void 0 && top[2] && braceDepth <= top[1]) {
|
|
@@ -691,6 +1521,8 @@ function extractPhp(content, filePath) {
|
|
|
691
1521
|
const parent = topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1 ? topFrame2[0] : null;
|
|
692
1522
|
symbols.push(makeLineSymbol(filePath, name, kind, lineNum, stripped.slice(0, 200), parent ?? void 0, lines, "c"));
|
|
693
1523
|
contextStack.push([name, braceDepth - openB + closeB, false, kind]);
|
|
1524
|
+
const bodyOpen = braceLine.indexOf("{");
|
|
1525
|
+
if (bodyOpen !== -1) openMember = queueMembers(bodySegments(braceLine, bodyOpen + 1), line, kind, name, lineNum, preLineDepth + 1) ?? openMember;
|
|
694
1526
|
if (openB > 0 && openB === closeB) {
|
|
695
1527
|
contextStack.pop();
|
|
696
1528
|
}
|
|
@@ -742,7 +1574,8 @@ function extractPhp(content, filePath) {
|
|
|
742
1574
|
symbols.push(makeLineSymbol(filePath, defineM[1] ?? "", "const", lineNum, stripped.slice(0, 200), void 0, lines, "c"));
|
|
743
1575
|
}
|
|
744
1576
|
}
|
|
745
|
-
|
|
1577
|
+
flushMembers();
|
|
1578
|
+
return { symbols, imports, settled };
|
|
746
1579
|
}
|
|
747
1580
|
|
|
748
1581
|
// src/languages/html.ts
|
|
@@ -791,20 +1624,66 @@ function isNoise(name) {
|
|
|
791
1624
|
}
|
|
792
1625
|
var MAX_SYMBOLS = 1e4;
|
|
793
1626
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
794
|
-
|
|
1627
|
+
function makeTagScanner(code) {
|
|
1628
|
+
const head = /<(\/?)([a-zA-Z][a-zA-Z0-9:-]*)/g;
|
|
1629
|
+
const stop = /[>"']/g;
|
|
1630
|
+
let dead = null;
|
|
1631
|
+
return (from) => {
|
|
1632
|
+
head.lastIndex = from;
|
|
1633
|
+
let m;
|
|
1634
|
+
while ((m = head.exec(code)) !== null) {
|
|
1635
|
+
const nameEnd = m.index + m[0].length;
|
|
1636
|
+
let end = -1;
|
|
1637
|
+
if (code[nameEnd] === ">") {
|
|
1638
|
+
end = nameEnd + 1;
|
|
1639
|
+
} else if (nameEnd < code.length && /\s/.test(code[nameEnd])) {
|
|
1640
|
+
let i = nameEnd + 1;
|
|
1641
|
+
const outside = [];
|
|
1642
|
+
for (; ; ) {
|
|
1643
|
+
if (dead !== null && dead[i] === 1) break;
|
|
1644
|
+
stop.lastIndex = i;
|
|
1645
|
+
const h = stop.exec(code);
|
|
1646
|
+
if (h === null) {
|
|
1647
|
+
outside.push(i, code.length + 1);
|
|
1648
|
+
break;
|
|
1649
|
+
}
|
|
1650
|
+
if (h[0] === ">") {
|
|
1651
|
+
end = h.index + 1;
|
|
1652
|
+
break;
|
|
1653
|
+
}
|
|
1654
|
+
outside.push(i, h.index + 1);
|
|
1655
|
+
const closeQuote = code.indexOf(h[0], h.index + 1);
|
|
1656
|
+
if (closeQuote < 0) break;
|
|
1657
|
+
i = closeQuote + 1;
|
|
1658
|
+
}
|
|
1659
|
+
if (end < 0 && outside.length > 0) {
|
|
1660
|
+
dead ??= new Uint8Array(code.length + 2);
|
|
1661
|
+
for (let k = 0; k < outside.length; k += 2) dead.fill(1, outside[k], outside[k + 1]);
|
|
1662
|
+
}
|
|
1663
|
+
}
|
|
1664
|
+
if (end >= 0) {
|
|
1665
|
+
return { start: m.index, end, isClose: m[1] === "/", name: (m[2] ?? "").toLowerCase(), selfClosing: code[end - 2] === "/" };
|
|
1666
|
+
}
|
|
1667
|
+
head.lastIndex = m.index + 1;
|
|
1668
|
+
}
|
|
1669
|
+
return null;
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
795
1672
|
var ELEMENT_SPAN_SCAN_CAP = 2e6;
|
|
796
1673
|
function buildElementSpans(code) {
|
|
797
1674
|
const spans = /* @__PURE__ */ new Map();
|
|
798
1675
|
const openTagRanges = [];
|
|
799
1676
|
const stack = [];
|
|
800
|
-
|
|
1677
|
+
const nextTag = makeTagScanner(code);
|
|
1678
|
+
const styleClose = /<\/style\s*>/gi;
|
|
1679
|
+
let styleCloseMissing = false;
|
|
1680
|
+
let from = 0;
|
|
801
1681
|
let m;
|
|
802
|
-
while ((m =
|
|
803
|
-
if (m.
|
|
804
|
-
const isClose = m
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
const tagEnd = m.index + m[0].length;
|
|
1682
|
+
while ((m = nextTag(from)) !== null) {
|
|
1683
|
+
if (m.start > ELEMENT_SPAN_SCAN_CAP) break;
|
|
1684
|
+
const { isClose, name, selfClosing } = m;
|
|
1685
|
+
const tagEnd = m.end;
|
|
1686
|
+
from = tagEnd;
|
|
808
1687
|
if (isClose) {
|
|
809
1688
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
810
1689
|
if (stack[i].name === name) {
|
|
@@ -815,14 +1694,17 @@ function buildElementSpans(code) {
|
|
|
815
1694
|
}
|
|
816
1695
|
continue;
|
|
817
1696
|
}
|
|
818
|
-
openTagRanges.push({ start: m.
|
|
1697
|
+
openTagRanges.push({ start: m.start, end: tagEnd });
|
|
819
1698
|
if (selfClosing || VOID_ELEMENTS.has(name)) continue;
|
|
820
1699
|
if (name === "style") {
|
|
821
|
-
|
|
822
|
-
|
|
1700
|
+
if (styleCloseMissing) continue;
|
|
1701
|
+
styleClose.lastIndex = tagEnd;
|
|
1702
|
+
const closeMatch = styleClose.exec(code);
|
|
1703
|
+
if (closeMatch === null) styleCloseMissing = true;
|
|
1704
|
+
else from = closeMatch.index + closeMatch[0].length;
|
|
823
1705
|
continue;
|
|
824
1706
|
}
|
|
825
|
-
stack.push({ name, start: m.
|
|
1707
|
+
stack.push({ name, start: m.start });
|
|
826
1708
|
}
|
|
827
1709
|
return { spans, openTagRanges };
|
|
828
1710
|
}
|
|
@@ -1015,12 +1897,47 @@ var TYPEALIAS_RE = new RegExp(
|
|
|
1015
1897
|
var TOP_FUN_RE = new RegExp(
|
|
1016
1898
|
"^(?:(?:public|internal|private|suspend|inline|infix|operator|external|actual|expect|tailrec)\\s+)*fun\\s+(?:" + GENERIC_CLAUSE + "\\s*)?" + RECEIVER_RE + "(" + NAME_RE + ")\\s*[(<]"
|
|
1017
1899
|
);
|
|
1900
|
+
function inlineKotlinMembers(line, code, segs, parent, filePath, lineNum, level = 0) {
|
|
1901
|
+
const members = [];
|
|
1902
|
+
const opens = [];
|
|
1903
|
+
for (const seg of segs) {
|
|
1904
|
+
const text = line.slice(seg.start, seg.end).trim();
|
|
1905
|
+
const noAnn = stripLeadingAnnotations(text);
|
|
1906
|
+
const fm = (parent === void 0 ? TOP_FUN_RE : FUN_RE).exec(noAnn);
|
|
1907
|
+
const constM = fm === null ? CONST_RE2.exec(noAnn) : null;
|
|
1908
|
+
const companionM = fm === null && constM === null && parent !== void 0 ? COMPANION_RE.exec(noAnn) : null;
|
|
1909
|
+
const classM = fm === null && constM === null && companionM === null ? CLASS_HEADER_RE2.exec(noAnn) : null;
|
|
1910
|
+
let sym = null;
|
|
1911
|
+
if (fm) sym = makeLineSymbol(filePath, unquoteName(fm[1] ?? ""), parent === void 0 ? "function" : "method", lineNum, text, parent);
|
|
1912
|
+
else if (constM) sym = makeLineSymbol(filePath, constM[1] ?? "", "const", lineNum, text, parent);
|
|
1913
|
+
else if (companionM !== null || classM !== null) {
|
|
1914
|
+
const brace = bodyBraceAt(code, seg.start, seg.end);
|
|
1915
|
+
if (seg.open && brace === -1) continue;
|
|
1916
|
+
const name = unquoteName((companionM !== null ? companionM[1] : classM?.[2]) ?? "Companion");
|
|
1917
|
+
const keyword = companionM !== null ? "object" : classM?.[1] ?? "class";
|
|
1918
|
+
const typeSym = makeLineSymbol(filePath, name, keyword === "interface" ? "interface" : keyword === "object" ? "object" : "class", lineNum, text, parent);
|
|
1919
|
+
members.push(typeSym);
|
|
1920
|
+
if (brace !== -1) {
|
|
1921
|
+
const inner = inlineKotlinMembers(line, code, bodySegments(code, brace + 1), name, filePath, lineNum, level + 1);
|
|
1922
|
+
members.push(...inner.members);
|
|
1923
|
+
if (seg.open) opens.push({ sym: typeSym, level, isType: true }, ...inner.opens);
|
|
1924
|
+
}
|
|
1925
|
+
continue;
|
|
1926
|
+
}
|
|
1927
|
+
if (sym === null) continue;
|
|
1928
|
+
members.push(sym);
|
|
1929
|
+
if (seg.open) opens.push({ sym, level, isType: false });
|
|
1930
|
+
}
|
|
1931
|
+
return { members, opens };
|
|
1932
|
+
}
|
|
1018
1933
|
function extractKotlin(content, filePath) {
|
|
1019
1934
|
const symbols = [];
|
|
1020
1935
|
const imports = [];
|
|
1021
1936
|
const lines = content.split(/\r?\n/);
|
|
1022
1937
|
const classStack = [];
|
|
1023
1938
|
let braceDepth = 0;
|
|
1939
|
+
const settled = /* @__PURE__ */ new Set();
|
|
1940
|
+
let openMembers = [];
|
|
1024
1941
|
let inComment = false;
|
|
1025
1942
|
let mlState = null;
|
|
1026
1943
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -1111,6 +2028,23 @@ function extractKotlin(content, filePath) {
|
|
|
1111
2028
|
}
|
|
1112
2029
|
}
|
|
1113
2030
|
const braceLine = stripStringLiterals(line);
|
|
2031
|
+
const lineOpens = [];
|
|
2032
|
+
const queueMembers = (segs, parent, bodyDepth) => {
|
|
2033
|
+
const { members, opens } = inlineKotlinMembers(line, braceLine, segs, parent, filePath, lineNum);
|
|
2034
|
+
symbols.push(...members);
|
|
2035
|
+
for (const m of members) settled.add(m);
|
|
2036
|
+
lineOpens.push(...openMembersOf(opens, bodyDepth));
|
|
2037
|
+
for (const o of opens) if (o.isType) classStack.push({ name: o.sym.name, braceDepth: bodyDepth + o.level, bodyEntered: true, parenBalance: 0, pendingPop: false });
|
|
2038
|
+
};
|
|
2039
|
+
const lineSegs = bodySegments(braceLine, 0);
|
|
2040
|
+
if (frame !== null && frame !== outerFrame && lineSegs[0] !== void 0) {
|
|
2041
|
+
const brace = bodyBraceAt(braceLine, lineSegs[0].start, lineSegs[0].end);
|
|
2042
|
+
if (brace !== -1) queueMembers(bodySegments(braceLine, brace + 1), frame.name, braceDepth + 1);
|
|
2043
|
+
}
|
|
2044
|
+
if (outerFrame !== null && outerDepthInClass >= 1) {
|
|
2045
|
+
const resume = bodyResumeAt(braceLine, outerDepthInClass - 1);
|
|
2046
|
+
if (resume >= 0) queueMembers(outerDepthInClass === 1 ? lineSegs.slice(1) : bodySegments(braceLine, resume), outerFrame.name, outerFrame.braceDepth + 1);
|
|
2047
|
+
} else if (outerFrame === null && !isIndented) queueMembers(lineSegs.slice(1), void 0, braceDepth);
|
|
1114
2048
|
for (const ch of braceLine) {
|
|
1115
2049
|
if (ch === "{") {
|
|
1116
2050
|
braceDepth++;
|
|
@@ -1125,6 +2059,8 @@ function extractKotlin(content, filePath) {
|
|
|
1125
2059
|
frame.parenBalance--;
|
|
1126
2060
|
}
|
|
1127
2061
|
}
|
|
2062
|
+
openMembers = endOpenMembers(symbols, settled, openMembers, braceDepth, lineNum, lines);
|
|
2063
|
+
openMembers.push(...lineOpens);
|
|
1128
2064
|
if (frame !== null && !frame.bodyEntered && frame.parenBalance <= 0) {
|
|
1129
2065
|
frame.pendingPop = !(stripped.endsWith(":") || stripped.endsWith(","));
|
|
1130
2066
|
}
|
|
@@ -1137,7 +2073,7 @@ function extractKotlin(content, filePath) {
|
|
|
1137
2073
|
}
|
|
1138
2074
|
}
|
|
1139
2075
|
}
|
|
1140
|
-
return { symbols, imports };
|
|
2076
|
+
return { symbols, imports, settled };
|
|
1141
2077
|
}
|
|
1142
2078
|
|
|
1143
2079
|
// src/languages/scala.ts
|
|
@@ -1174,11 +2110,151 @@ var OBJECT_RE = new RegExp("^\\s*(?:package\\s+)?" + MODS + "object\\s+(" + NAME
|
|
|
1174
2110
|
var TRAIT_RE = new RegExp("^\\s*" + MODS + "trait\\s+(" + NAME + ")(?:\\s|\\[|:|$)");
|
|
1175
2111
|
var ENUM_RE = new RegExp("^\\s*(?:private|protected)?\\s*enum\\s+(" + NAME + ")(?:\\s|\\[|\\(|:|$)");
|
|
1176
2112
|
var DEF_NAME = "(?:`[^`\\r\\n]+`|[A-Za-z_][A-Za-z0-9_]*_[+\\-*/%=!<>&|^~:]+|[+\\-*/%=!<>&|^~:]+|[A-Za-z_][A-Za-z0-9_]*)";
|
|
1177
|
-
var FUNC_RE = new RegExp("^\\s*" + MODS + "def\\s+(" + DEF_NAME + ")(?:\\s*\\[|\\s*\\(|\\s
|
|
2113
|
+
var FUNC_RE = new RegExp("^\\s*" + MODS + "def\\s+(" + DEF_NAME + ")(?:\\s*\\[|\\s*\\(|\\s*:|\\s*=(?!=))");
|
|
1178
2114
|
var VAL_RE = new RegExp("^\\s*" + MODS + "val\\s+(" + NAME + ")");
|
|
1179
2115
|
var VAR_RE = new RegExp("^\\s*" + MODS + "var\\s+(" + NAME + ")");
|
|
2116
|
+
var GIVEN_RE = /^\s*(?:(?:(?:private|protected)(?:\[[A-Za-z_][A-Za-z0-9_]*\])?|inline|transparent|override|final|implicit|lazy)\s+)*given\s+(?!=(?!>))(\S.*)$/;
|
|
2117
|
+
var SIMPLE_TYPE_HEAD_RE = /^(?:[A-Za-z_][A-Za-z0-9_]*\.)*([A-Za-z_][A-Za-z0-9_]*)\s*/;
|
|
2118
|
+
function splitTopLevel(text) {
|
|
2119
|
+
const parts = [];
|
|
2120
|
+
let depth = 0;
|
|
2121
|
+
let start = 0;
|
|
2122
|
+
for (let i = 0; i < text.length; i++) {
|
|
2123
|
+
const ch = text[i];
|
|
2124
|
+
if (ch === "(" || ch === "[") depth++;
|
|
2125
|
+
else if (ch === ")" || ch === "]") depth--;
|
|
2126
|
+
else if (ch === "," && depth === 0) {
|
|
2127
|
+
parts.push(text.slice(start, i).trim());
|
|
2128
|
+
start = i + 1;
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
parts.push(text.slice(start).trim());
|
|
2132
|
+
return parts;
|
|
2133
|
+
}
|
|
2134
|
+
function anonymousGivenName(typeText) {
|
|
2135
|
+
let text = typeText.trim();
|
|
2136
|
+
while (text.startsWith("[") || text.startsWith("(")) {
|
|
2137
|
+
let depth = 0;
|
|
2138
|
+
let i = 0;
|
|
2139
|
+
for (; i < text.length; i++) {
|
|
2140
|
+
const ch = text[i];
|
|
2141
|
+
if (ch === "(" || ch === "[") depth++;
|
|
2142
|
+
else if (ch === ")" || ch === "]") depth--;
|
|
2143
|
+
if (depth === 0) break;
|
|
2144
|
+
}
|
|
2145
|
+
const after = text.slice(i + 1).trimStart();
|
|
2146
|
+
if (!after.startsWith("=>")) return "given";
|
|
2147
|
+
text = after.slice(2).trim();
|
|
2148
|
+
}
|
|
2149
|
+
const head = SIMPLE_TYPE_HEAD_RE.exec(text);
|
|
2150
|
+
if (!head) return "given";
|
|
2151
|
+
const parts = [head[1]];
|
|
2152
|
+
const tail = text.slice(head[0].length);
|
|
2153
|
+
if (tail !== "") {
|
|
2154
|
+
if (!tail.startsWith("[") || !tail.endsWith("]")) return "given";
|
|
2155
|
+
for (const arg of splitTopLevel(tail.slice(1, -1))) {
|
|
2156
|
+
const members = arg.startsWith("(") && arg.endsWith(")") ? splitTopLevel(arg.slice(1, -1)) : [arg];
|
|
2157
|
+
for (const member of members) {
|
|
2158
|
+
if (member.replace(/\[.*\]/g, "").includes("=>")) {
|
|
2159
|
+
parts.push("Function");
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2162
|
+
const m = SIMPLE_TYPE_HEAD_RE.exec(member);
|
|
2163
|
+
if (!m || !/^(?:\[.*\])?$/.test(member.slice(m[0].length))) return "given";
|
|
2164
|
+
parts.push(m[1]);
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
return `given_${parts.join("_")}`;
|
|
2169
|
+
}
|
|
2170
|
+
function givenHead(stripped) {
|
|
2171
|
+
const m = GIVEN_RE.exec(stripped);
|
|
2172
|
+
if (!m) return null;
|
|
2173
|
+
const rest = m[1];
|
|
2174
|
+
const blanked = stripStringLiterals(rest, SCALA_STRIP);
|
|
2175
|
+
let depth = 0;
|
|
2176
|
+
let sigColon = -1;
|
|
2177
|
+
let end = blanked.length;
|
|
2178
|
+
let body = null;
|
|
2179
|
+
for (let i = 0; i < blanked.length; i++) {
|
|
2180
|
+
const ch = blanked[i];
|
|
2181
|
+
if (ch === "(" || ch === "[") depth++;
|
|
2182
|
+
else if (ch === ")" || ch === "]") depth--;
|
|
2183
|
+
else if (depth !== 0) continue;
|
|
2184
|
+
else if (ch === "{") {
|
|
2185
|
+
end = i;
|
|
2186
|
+
body = "brace";
|
|
2187
|
+
break;
|
|
2188
|
+
} else if (ch === "=" && blanked[i + 1] !== ">") {
|
|
2189
|
+
end = i;
|
|
2190
|
+
break;
|
|
2191
|
+
} else if (ch === ":") {
|
|
2192
|
+
if (blanked.slice(i + 1).trim() === "") {
|
|
2193
|
+
end = i;
|
|
2194
|
+
body = "colon";
|
|
2195
|
+
break;
|
|
2196
|
+
}
|
|
2197
|
+
if (sigColon < 0) sigColon = i;
|
|
2198
|
+
} else if (blanked.startsWith("with", i) && !/[A-Za-z0-9_]/.test(blanked[i - 1] ?? "") && !/[A-Za-z0-9_]/.test(blanked[i + 4] ?? "")) {
|
|
2199
|
+
end = i;
|
|
2200
|
+
body = blanked.slice(i + 4).trim().startsWith("{") ? "brace" : "colon";
|
|
2201
|
+
break;
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
const sig = sigColon >= 0 ? rest.slice(0, sigColon).trim() : "";
|
|
2205
|
+
const named = new RegExp("^(" + NAME + ")\\s*(?:[[(]|$)").exec(sig);
|
|
2206
|
+
if (named) return { name: unquoteName2(named[1]), anonymous: false, body };
|
|
2207
|
+
return { name: anonymousGivenName(sigColon >= 0 ? rest.slice(sigColon + 1, end) : rest.slice(0, end)), anonymous: true, body };
|
|
2208
|
+
}
|
|
1180
2209
|
function startsDeclaration(stripped) {
|
|
1181
|
-
return CLASS_RE3.test(stripped) || OBJECT_RE.test(stripped) || TRAIT_RE.test(stripped) || ENUM_RE.test(stripped) || FUNC_RE.test(stripped) || VAL_RE.test(stripped) || VAR_RE.test(stripped);
|
|
2210
|
+
return CLASS_RE3.test(stripped) || OBJECT_RE.test(stripped) || TRAIT_RE.test(stripped) || ENUM_RE.test(stripped) || FUNC_RE.test(stripped) || VAL_RE.test(stripped) || VAR_RE.test(stripped) || GIVEN_RE.test(stripped) || extensionClauseTail(stripped) !== null;
|
|
2211
|
+
}
|
|
2212
|
+
function extensionClauseTail(stripped) {
|
|
2213
|
+
if (!/^extension\s*[[(]/.test(stripped)) return null;
|
|
2214
|
+
const blanked = stripStringLiterals(stripped, SCALA_STRIP);
|
|
2215
|
+
let i = "extension".length;
|
|
2216
|
+
let depth = 0;
|
|
2217
|
+
for (; i < blanked.length; i++) {
|
|
2218
|
+
const ch = blanked[i];
|
|
2219
|
+
if (ch === "(" || ch === "[") depth++;
|
|
2220
|
+
else if (ch === ")" || ch === "]") depth--;
|
|
2221
|
+
else if (depth === 0 && ch !== " " && ch !== " ") break;
|
|
2222
|
+
}
|
|
2223
|
+
return depth === 0 ? stripped.slice(i).trim() : null;
|
|
2224
|
+
}
|
|
2225
|
+
var INLINE_TYPES = [[CLASS_RE3, "class"], [OBJECT_RE, "object"], [TRAIT_RE, "trait"], [ENUM_RE, "enum"]];
|
|
2226
|
+
function inlineScalaMembers(line, code, segs, parent, filePath, lineNum, level = 0) {
|
|
2227
|
+
const members = [];
|
|
2228
|
+
const opens = [];
|
|
2229
|
+
for (const seg of segs) {
|
|
2230
|
+
const text = line.slice(seg.start, seg.end).trim();
|
|
2231
|
+
const fm = FUNC_RE.exec(text);
|
|
2232
|
+
const vm = fm === null ? VAL_RE.exec(text) : null;
|
|
2233
|
+
const varm = fm === null && vm === null ? VAR_RE.exec(text) : null;
|
|
2234
|
+
const member = fm !== null ? [fm, "function"] : vm !== null ? [vm, "val"] : varm !== null ? [varm, "var"] : null;
|
|
2235
|
+
if (member !== null) {
|
|
2236
|
+
const sym = makeLineSymbol(filePath, unquoteName2(member[0][1] ?? ""), member[1], lineNum, text, parent);
|
|
2237
|
+
members.push(sym);
|
|
2238
|
+
if (seg.open) opens.push({ sym, level, isType: false });
|
|
2239
|
+
continue;
|
|
2240
|
+
}
|
|
2241
|
+
for (const [re, kind] of INLINE_TYPES) {
|
|
2242
|
+
const tm = re.exec(text);
|
|
2243
|
+
if (tm === null) continue;
|
|
2244
|
+
const brace = bodyBraceAt(code, seg.start, seg.end);
|
|
2245
|
+
if (seg.open && brace === -1) break;
|
|
2246
|
+
const name = unquoteName2(tm[1] ?? "");
|
|
2247
|
+
const typeSym = makeLineSymbol(filePath, name, kind, lineNum, text, parent);
|
|
2248
|
+
members.push(typeSym);
|
|
2249
|
+
if (brace !== -1) {
|
|
2250
|
+
const inner = inlineScalaMembers(line, code, bodySegments(code, brace + 1), name, filePath, lineNum, level + 1);
|
|
2251
|
+
members.push(...inner.members);
|
|
2252
|
+
if (seg.open) opens.push({ sym: typeSym, level, isType: true }, ...inner.opens);
|
|
2253
|
+
}
|
|
2254
|
+
break;
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
return { members, opens };
|
|
1182
2258
|
}
|
|
1183
2259
|
function extractScala(content, filePath) {
|
|
1184
2260
|
const symbols = [];
|
|
@@ -1186,9 +2262,12 @@ function extractScala(content, filePath) {
|
|
|
1186
2262
|
const lines = content.split(/\r?\n/);
|
|
1187
2263
|
const typeStack = [];
|
|
1188
2264
|
let braceDepth = 0;
|
|
2265
|
+
const settled = /* @__PURE__ */ new Set();
|
|
2266
|
+
let openMembers = [];
|
|
1189
2267
|
let inComment = false;
|
|
1190
2268
|
let mlState = null;
|
|
1191
2269
|
let lastCodeLine = 0;
|
|
2270
|
+
let extBlock = null;
|
|
1192
2271
|
const closeColonFrame = (frame, endLine) => {
|
|
1193
2272
|
const open = symbols[frame.symbolIndex];
|
|
1194
2273
|
if (open !== void 0) symbols[frame.symbolIndex] = withSpanEnd(open, endLine, lines);
|
|
@@ -1202,7 +2281,7 @@ function extractScala(content, filePath) {
|
|
|
1202
2281
|
mlLine = masked.code;
|
|
1203
2282
|
mlState = masked.state;
|
|
1204
2283
|
}
|
|
1205
|
-
const { code: blockStripped, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment);
|
|
2284
|
+
const { code: blockStripped, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment, SCALA_STRIP);
|
|
1206
2285
|
inComment = nextInComment;
|
|
1207
2286
|
const line = stripLineComment(blockStripped, ["//"], SCALA_STRIP).trimEnd();
|
|
1208
2287
|
const stripped = line.trim();
|
|
@@ -1217,7 +2296,7 @@ function extractScala(content, filePath) {
|
|
|
1217
2296
|
const top = typeStack[typeStack.length - 1];
|
|
1218
2297
|
if (!top.colonBody || indent > top.declIndent) break;
|
|
1219
2298
|
typeStack.pop();
|
|
1220
|
-
const closesWithMarker = indent === top.declIndent && stripped === `end ${top.name}
|
|
2299
|
+
const closesWithMarker = indent === top.declIndent && stripped === (top.endMarker ?? `end ${top.name}`);
|
|
1221
2300
|
closeColonFrame(top, closesWithMarker ? lineNum : lastCodeLine);
|
|
1222
2301
|
if (closesWithMarker) lastCodeLine = lineNum;
|
|
1223
2302
|
}
|
|
@@ -1287,7 +2366,34 @@ function extractScala(content, filePath) {
|
|
|
1287
2366
|
typeStack.push({ name: enname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null, symbolIndex: symbols.length - 1 });
|
|
1288
2367
|
matched = true;
|
|
1289
2368
|
}
|
|
2369
|
+
const gm = !matched && typeDetectionGateOk && (!isIndented || typeStack.length > 0) ? givenHead(stripped) : null;
|
|
2370
|
+
if (gm) {
|
|
2371
|
+
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
2372
|
+
symbols.push(makeLineSymbol(filePath, gm.name, gm.body === null ? "val" : "object", lineNum, stripped.slice(0, 200), parent, lines, "c"));
|
|
2373
|
+
if (gm.body !== null) {
|
|
2374
|
+
typeStack.push({ name: gm.name, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: gm.body === "colon", bodyIndent: null, symbolIndex: symbols.length - 1, ...gm.anonymous ? { endMarker: "end given" } : {} });
|
|
2375
|
+
}
|
|
2376
|
+
matched = true;
|
|
2377
|
+
}
|
|
1290
2378
|
const frame = typeStack.length > 0 ? typeStack[typeStack.length - 1] : null;
|
|
2379
|
+
if (extBlock !== null && braceDepth <= extBlock.depth && indent <= extBlock.indent) extBlock = null;
|
|
2380
|
+
if (!matched && extBlock !== null) {
|
|
2381
|
+
if (extBlock.bodyIndent === null) {
|
|
2382
|
+
extBlock.bodyIndent = indent;
|
|
2383
|
+
extBlock.bodyDepth = braceDepth;
|
|
2384
|
+
}
|
|
2385
|
+
const fm = indent === extBlock.bodyIndent && braceDepth === extBlock.bodyDepth ? FUNC_RE.exec(stripped) : null;
|
|
2386
|
+
if (fm) symbols.push(makeLineSymbol(filePath, unquoteName2(fm[1] ?? ""), "function", lineNum, stripped.slice(0, 200), extBlock.parent, lines, "c"));
|
|
2387
|
+
matched = true;
|
|
2388
|
+
}
|
|
2389
|
+
const memberSlot = frame === null ? !isIndented : braceDepth - frame.startDepth === 1 || inColonBody && frame === colonTop;
|
|
2390
|
+
const extTail = !matched && memberSlot ? extensionClauseTail(stripped) : null;
|
|
2391
|
+
if (extTail !== null) {
|
|
2392
|
+
const fm = FUNC_RE.exec(extTail);
|
|
2393
|
+
if (fm) symbols.push(makeLineSymbol(filePath, unquoteName2(fm[1] ?? ""), "function", lineNum, stripped.slice(0, 200), frame?.name, lines, "c"));
|
|
2394
|
+
else extBlock = { indent, depth: braceDepth, parent: frame?.name, bodyIndent: null, bodyDepth: braceDepth };
|
|
2395
|
+
matched = true;
|
|
2396
|
+
}
|
|
1291
2397
|
if (!matched && frame !== null) {
|
|
1292
2398
|
const depthInType = braceDepth - frame.startDepth;
|
|
1293
2399
|
if (depthInType === 1 || inColonBody && frame === colonTop) {
|
|
@@ -1331,6 +2437,29 @@ function extractScala(content, filePath) {
|
|
|
1331
2437
|
symbols[symbols.length - 1] = withSpanEnd(lastSymbol, indentedBodyEnd(lines, lineNum, indent), lines);
|
|
1332
2438
|
}
|
|
1333
2439
|
const braceLine = stripStringLiterals(line, SCALA_STRIP);
|
|
2440
|
+
const lineOpens = [];
|
|
2441
|
+
const queueMembers = (segs, parent, bodyDepth) => {
|
|
2442
|
+
const { members, opens } = inlineScalaMembers(line, braceLine, segs, parent, filePath, lineNum);
|
|
2443
|
+
symbols.push(...members);
|
|
2444
|
+
for (const m of members) settled.add(m);
|
|
2445
|
+
lineOpens.push(...openMembersOf(opens, bodyDepth));
|
|
2446
|
+
for (const o of opens) {
|
|
2447
|
+
if (!o.isType) continue;
|
|
2448
|
+
const enclosing = typeStack[typeStack.length - 1];
|
|
2449
|
+
if (enclosing !== void 0) enclosing.bodyEntered = true;
|
|
2450
|
+
typeStack.push({ name: o.sym.name, startDepth: bodyDepth + o.level, bodyEntered: true, openParens: 0, declIndent: indent, colonBody: false, bodyIndent: null, symbolIndex: symbols.indexOf(o.sym) });
|
|
2451
|
+
}
|
|
2452
|
+
};
|
|
2453
|
+
const lineSegs = bodySegments(braceLine, 0);
|
|
2454
|
+
if (frame !== null && frame !== outerFrame && lineSegs[0] !== void 0) {
|
|
2455
|
+
const brace = bodyBraceAt(braceLine, lineSegs[0].start, lineSegs[0].end);
|
|
2456
|
+
if (brace !== -1) queueMembers(bodySegments(braceLine, brace + 1), frame.name, braceDepth + 1);
|
|
2457
|
+
}
|
|
2458
|
+
if (outerFrame !== null && (outerDepthInType === 1 || inColonBody && outerFrame === colonTop)) queueMembers(lineSegs.slice(1), outerFrame.name, braceDepth);
|
|
2459
|
+
else if (outerFrame !== null && !outerFrame.colonBody && outerDepthInType > 1) {
|
|
2460
|
+
const resume = bodyResumeAt(braceLine, outerDepthInType - 1);
|
|
2461
|
+
if (resume >= 0) queueMembers(bodySegments(braceLine, resume), outerFrame.name, outerFrame.startDepth + 1);
|
|
2462
|
+
} else if (outerFrame === null && !isIndented) queueMembers(lineSegs.slice(1), void 0, braceDepth);
|
|
1334
2463
|
if (frame !== null && !frame.bodyEntered) {
|
|
1335
2464
|
const parenDelta2 = (braceLine.match(/\(/g) ?? []).length - (braceLine.match(/\)/g) ?? []).length;
|
|
1336
2465
|
frame.openParens = Math.max(0, frame.openParens + parenDelta2);
|
|
@@ -1345,6 +2474,8 @@ function extractScala(content, filePath) {
|
|
|
1345
2474
|
braceDepth--;
|
|
1346
2475
|
}
|
|
1347
2476
|
}
|
|
2477
|
+
openMembers = endOpenMembers(symbols, settled, openMembers, braceDepth, lineNum, lines);
|
|
2478
|
+
openMembers.push(...lineOpens);
|
|
1348
2479
|
while (typeStack.length > 0) {
|
|
1349
2480
|
const top = typeStack[typeStack.length - 1];
|
|
1350
2481
|
if (!top.colonBody && top.bodyEntered && braceDepth <= top.startDepth) {
|
|
@@ -1358,7 +2489,7 @@ function extractScala(content, filePath) {
|
|
|
1358
2489
|
const top = typeStack.pop();
|
|
1359
2490
|
if (top.colonBody) closeColonFrame(top, lastCodeLine);
|
|
1360
2491
|
}
|
|
1361
|
-
return { symbols, imports };
|
|
2492
|
+
return { symbols, imports, settled };
|
|
1362
2493
|
}
|
|
1363
2494
|
|
|
1364
2495
|
// src/languages/lua.ts
|
|
@@ -4524,12 +5655,12 @@ function extractApex(content, filePath) {
|
|
|
4524
5655
|
}
|
|
4525
5656
|
const typeNamesLower = /* @__PURE__ */ new Set();
|
|
4526
5657
|
for (const match of code.matchAll(TYPE_DECL_RE)) {
|
|
4527
|
-
const
|
|
5658
|
+
const typeKind2 = match[1] ?? "";
|
|
4528
5659
|
const name = match[2] ?? "";
|
|
4529
5660
|
const startOffset = match.index ?? 0;
|
|
4530
5661
|
const line = offsetToLine(lineIndex, startOffset);
|
|
4531
5662
|
const bodyStartLine = annotationStartLine(codeLines, line);
|
|
4532
|
-
const typeKindLower =
|
|
5663
|
+
const typeKindLower = typeKind2.toLowerCase();
|
|
4533
5664
|
const kind = typeKindLower === "class" ? "apex_class" : `apex_${typeKindLower}`;
|
|
4534
5665
|
typeNamesLower.add(name.toLowerCase());
|
|
4535
5666
|
emit2(name, kind, spanForMatch(content, code, lineIndex, startOffset, bodyStartLine, match[0]));
|
|
@@ -4586,36 +5717,52 @@ var FLOW_TAG_KIND = {
|
|
|
4586
5717
|
variables: "sf_flow_variable"
|
|
4587
5718
|
};
|
|
4588
5719
|
function xmlText(content, tag) {
|
|
4589
|
-
const
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
5720
|
+
const first = findElements(content, tagOpenRe(tag, "gi"), tagCloseRe(tag, "gi"), 1)[0];
|
|
5721
|
+
if (first === void 0) return null;
|
|
5722
|
+
return decodeXml(first.body.trim());
|
|
5723
|
+
}
|
|
5724
|
+
function tagOpenRe(tag, flags) {
|
|
5725
|
+
return new RegExp(`<(?:[A-Za-z_][\\w.-]*:)?${tag}(?=[\\s>])`, flags);
|
|
5726
|
+
}
|
|
5727
|
+
function tagCloseRe(tag, flags) {
|
|
5728
|
+
return new RegExp(`</(?:[A-Za-z_][\\w.-]*:)?${tag}\\s*>`, flags);
|
|
4596
5729
|
}
|
|
4597
5730
|
function directChildText(content, tag) {
|
|
4598
|
-
const
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
)
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
const idx = cand.index ?? 0;
|
|
4605
|
-
let depth = 0;
|
|
4606
|
-
tagRe.lastIndex = 0;
|
|
4607
|
-
let t;
|
|
4608
|
-
while ((t = tagRe.exec(content)) !== null) {
|
|
4609
|
-
if (t.index >= idx) break;
|
|
4610
|
-
const closing = t[1] === "/";
|
|
4611
|
-
const selfClosing = t[3] === "/";
|
|
4612
|
-
if (selfClosing) continue;
|
|
4613
|
-
depth += closing ? -1 : 1;
|
|
4614
|
-
}
|
|
4615
|
-
if (depth === 0) return decodeXml((cand[1] ?? "").trim());
|
|
5731
|
+
const nextCandidate = elementCursor(content, tagOpenRe(tag, "gi"), tagCloseRe(tag, "gi"));
|
|
5732
|
+
let depthBefore = null;
|
|
5733
|
+
let cand;
|
|
5734
|
+
while ((cand = nextCandidate()) !== null) {
|
|
5735
|
+
depthBefore ??= depthCursor(content);
|
|
5736
|
+
if (depthBefore(cand.start) === 0) return decodeXml(cand.body.trim());
|
|
4616
5737
|
}
|
|
4617
5738
|
return null;
|
|
4618
5739
|
}
|
|
5740
|
+
function depthCursor(content) {
|
|
5741
|
+
const re = /<(\/?)([A-Za-z_:][\w.:-]*)\b/g;
|
|
5742
|
+
let depth = 0;
|
|
5743
|
+
let heldStart = -1;
|
|
5744
|
+
let heldDelta = 0;
|
|
5745
|
+
let done = false;
|
|
5746
|
+
return (pos) => {
|
|
5747
|
+
for (; ; ) {
|
|
5748
|
+
if (heldStart < 0) {
|
|
5749
|
+
const m = done ? null : re.exec(content);
|
|
5750
|
+
const gt = m === null ? -1 : content.indexOf(">", m.index + m[0].length);
|
|
5751
|
+
if (m === null || gt < 0) {
|
|
5752
|
+
done = true;
|
|
5753
|
+
return depth;
|
|
5754
|
+
}
|
|
5755
|
+
const nameEnd = m.index + m[0].length;
|
|
5756
|
+
heldStart = m.index;
|
|
5757
|
+
heldDelta = content[gt - 1] === "/" && gt - 1 >= nameEnd ? 0 : m[1] === "/" ? -1 : 1;
|
|
5758
|
+
re.lastIndex = gt + 1;
|
|
5759
|
+
}
|
|
5760
|
+
if (heldStart >= pos) return depth;
|
|
5761
|
+
depth += heldDelta;
|
|
5762
|
+
heldStart = -1;
|
|
5763
|
+
}
|
|
5764
|
+
};
|
|
5765
|
+
}
|
|
4619
5766
|
function decodeXml(value) {
|
|
4620
5767
|
return value.replace(/'/g, "'").replace(/"/g, '"').replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&");
|
|
4621
5768
|
}
|
|
@@ -4635,8 +5782,7 @@ function wholeFileSpan(content) {
|
|
|
4635
5782
|
return {
|
|
4636
5783
|
startLine: 1,
|
|
4637
5784
|
endLine: lines.length > 1 && lines[lines.length - 1] === "" ? lines.length - 1 : lines.length,
|
|
4638
|
-
// File-level metadata symbols can be several megabytes (profiles are a common case).
|
|
4639
|
-
// Keep only the source span in the index; `read` reconstructs empty bodies from disk.
|
|
5785
|
+
// File-level metadata symbols can be several megabytes (profiles are a common case). Keep only the source span in the index; `read` reconstructs empty bodies from disk.
|
|
4640
5786
|
body: ""
|
|
4641
5787
|
};
|
|
4642
5788
|
}
|
|
@@ -4650,11 +5796,13 @@ function spanFromOffsets(content, lineIndex, startOffset, endOffset) {
|
|
|
4650
5796
|
};
|
|
4651
5797
|
}
|
|
4652
5798
|
function rootElement(content) {
|
|
4653
|
-
const match = /<(?!\?|!)(?:[A-Za-z_][\w.-]*:)?([A-Za-z_][\w.-]*)\b
|
|
5799
|
+
const match = /<(?!\?|!)(?:[A-Za-z_][\w.-]*:)?([A-Za-z_][\w.-]*)\b/.exec(content);
|
|
4654
5800
|
if (match === null) return null;
|
|
4655
5801
|
const root = match[1];
|
|
4656
5802
|
if (root === void 0) return null;
|
|
4657
|
-
|
|
5803
|
+
const gt = content.indexOf(">", match.index + match[0].length);
|
|
5804
|
+
if (gt < 0) return null;
|
|
5805
|
+
if (content[gt - 1] === "/") return root;
|
|
4658
5806
|
const close = new RegExp(`</(?:[A-Za-z_][\\w.-]*:)?${escapeRegExp(root)}\\s*>`, "i");
|
|
4659
5807
|
return close.test(content) ? root : null;
|
|
4660
5808
|
}
|
|
@@ -4672,14 +5820,10 @@ function metadataArtifactName(filePath) {
|
|
|
4672
5820
|
return match?.[1] ?? basenameWithout(filePath, "-meta.xml");
|
|
4673
5821
|
}
|
|
4674
5822
|
function elementBlocks(content, tag) {
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
return [...content.matchAll(re)].map((match) => ({
|
|
4680
|
-
inner: match[1] ?? "",
|
|
4681
|
-
offset: match.index ?? 0,
|
|
4682
|
-
text: match[0]
|
|
5823
|
+
return findElements(content, tagOpenRe(tag, "gi"), tagCloseRe(tag, "gi")).map((el) => ({
|
|
5824
|
+
inner: el.body,
|
|
5825
|
+
offset: el.start,
|
|
5826
|
+
text: content.slice(el.start, el.end)
|
|
4683
5827
|
}));
|
|
4684
5828
|
}
|
|
4685
5829
|
function attributeValue(attributes, name) {
|
|
@@ -4687,11 +5831,33 @@ function attributeValue(attributes, name) {
|
|
|
4687
5831
|
return match?.[2] === void 0 ? null : decodeXml(match[2]);
|
|
4688
5832
|
}
|
|
4689
5833
|
function propertyElements(content) {
|
|
4690
|
-
const
|
|
5834
|
+
const open = /<(?:[A-Za-z_][\w.-]*:)?property\b/gi;
|
|
5835
|
+
const close = /<\/(?:[A-Za-z_][\w.-]*:)?property\s*>/gi;
|
|
5836
|
+
const nextGt = gtFinder(content);
|
|
4691
5837
|
const out = [];
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
5838
|
+
let deadFrom = Infinity;
|
|
5839
|
+
let m;
|
|
5840
|
+
while ((m = open.exec(content)) !== null) {
|
|
5841
|
+
const nameEnd = m.index + m[0].length;
|
|
5842
|
+
const gt = nextGt(nameEnd);
|
|
5843
|
+
if (gt < 0) break;
|
|
5844
|
+
let end = gt + 1;
|
|
5845
|
+
let attrs = content.slice(nameEnd, gt);
|
|
5846
|
+
if (content[gt - 1] === "/" && gt - 1 >= nameEnd) {
|
|
5847
|
+
attrs = content.slice(nameEnd, gt - 1);
|
|
5848
|
+
} else {
|
|
5849
|
+
if (gt >= deadFrom) continue;
|
|
5850
|
+
close.lastIndex = gt + 1;
|
|
5851
|
+
const c = close.exec(content);
|
|
5852
|
+
if (c === null) {
|
|
5853
|
+
deadFrom = gt;
|
|
5854
|
+
continue;
|
|
5855
|
+
}
|
|
5856
|
+
end = c.index + c[0].length;
|
|
5857
|
+
}
|
|
5858
|
+
const name = attributeValue(attrs, "name");
|
|
5859
|
+
if (name !== null && name !== "") out.push({ name, offset: m.index, text: content.slice(m.index, end) });
|
|
5860
|
+
open.lastIndex = end;
|
|
4695
5861
|
}
|
|
4696
5862
|
return out;
|
|
4697
5863
|
}
|
|
@@ -4723,15 +5889,35 @@ function metadataName(filePath, content, suffix) {
|
|
|
4723
5889
|
function addFlowElements(symbols, seen, content, filePath, flowName) {
|
|
4724
5890
|
const lineIndex = buildLineIndex(content);
|
|
4725
5891
|
const tagAlternation = Object.keys(FLOW_TAG_KIND).join("|");
|
|
4726
|
-
const
|
|
4727
|
-
|
|
5892
|
+
const open = new RegExp(`<(?:[A-Za-z_][\\w.-]*:)?(${tagAlternation})(?=[\\s>])`, "g");
|
|
5893
|
+
const closeByTag = /* @__PURE__ */ new Map();
|
|
5894
|
+
const deadFromByTag = /* @__PURE__ */ new Map();
|
|
5895
|
+
const nextGt = gtFinder(content);
|
|
5896
|
+
let m;
|
|
5897
|
+
while ((m = open.exec(content)) !== null) {
|
|
4728
5898
|
if (symbols.length >= MAX_SYMBOLS11) return;
|
|
4729
|
-
const tag =
|
|
4730
|
-
const
|
|
5899
|
+
const tag = m[1] ?? "";
|
|
5900
|
+
const nameEnd = m.index + m[0].length;
|
|
5901
|
+
const gt = nextGt(nameEnd);
|
|
5902
|
+
if (gt < 0) break;
|
|
5903
|
+
if (gt >= (deadFromByTag.get(tag) ?? Infinity)) continue;
|
|
5904
|
+
let close = closeByTag.get(tag);
|
|
5905
|
+
if (close === void 0) {
|
|
5906
|
+
close = tagCloseRe(tag, "g");
|
|
5907
|
+
closeByTag.set(tag, close);
|
|
5908
|
+
}
|
|
5909
|
+
close.lastIndex = gt + 1;
|
|
5910
|
+
const c = close.exec(content);
|
|
5911
|
+
if (c === null) {
|
|
5912
|
+
deadFromByTag.set(tag, gt);
|
|
5913
|
+
continue;
|
|
5914
|
+
}
|
|
5915
|
+
const startOffset = m.index;
|
|
5916
|
+
const endOffset = c.index + c[0].length;
|
|
5917
|
+
open.lastIndex = endOffset;
|
|
5918
|
+
const inner = content.slice(gt + 1, c.index).trim();
|
|
4731
5919
|
const name = directChildText(inner, "name");
|
|
4732
5920
|
if (name === null || name === "") continue;
|
|
4733
|
-
const startOffset = match.index ?? 0;
|
|
4734
|
-
const endOffset = startOffset + match[0].length;
|
|
4735
5921
|
const span = spanFromOffsets(content, lineIndex, startOffset, endOffset);
|
|
4736
5922
|
const kind = FLOW_TAG_KIND[tag] ?? "sf_flow_element";
|
|
4737
5923
|
emit(symbols, seen, makeSpanSymbol(filePath, name, kind, span, flowName));
|
|
@@ -4942,7 +6128,9 @@ function blankJsStringLiterals(content) {
|
|
|
4942
6128
|
}
|
|
4943
6129
|
var FUNC_DECL_RE = /^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s+([A-Za-z_$][\w$]*)/;
|
|
4944
6130
|
var CONST_DECL_RE = /^(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*[:=]/;
|
|
4945
|
-
var CLASS_DECL_RE = /^(?:export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+([A-Za-z_$][\w$]*)/;
|
|
6131
|
+
var CLASS_DECL_RE = /^(?:export\s+)?(?:default\s+)?(?:abstract\s+)?class\s+(?!extends\b)([A-Za-z_$][\w$]*)/;
|
|
6132
|
+
var ANONYMOUS_DEFAULT_RE = /^export\s+default\s+(?:async\s+)?(?:function\b|(class)\b|(?:\([^)]*\)|[A-Za-z_$][\w$]*)\s*=>)/;
|
|
6133
|
+
var DEFAULT_VALUE_RE = /^export\s+default\s+(?:\{|[A-Za-z_$][\w$.]*\s*\()/;
|
|
4946
6134
|
function declarationEndIdx(blanked, startIdx) {
|
|
4947
6135
|
let depth = 0;
|
|
4948
6136
|
for (let j = startIdx; j < blanked.length; j++) {
|
|
@@ -4976,9 +6164,11 @@ function extractTopLevelDeclarations(scriptContent, filePath, startLine) {
|
|
|
4976
6164
|
const fm = FUNC_DECL_RE.exec(trimmed);
|
|
4977
6165
|
const cm = fm ? null : CONST_DECL_RE.exec(trimmed);
|
|
4978
6166
|
const clm = fm || cm ? null : CLASS_DECL_RE.exec(trimmed);
|
|
4979
|
-
const
|
|
6167
|
+
const am = fm || cm || clm ? null : ANONYMOUS_DEFAULT_RE.exec(trimmed);
|
|
6168
|
+
const dm = fm || cm || clm || am ? null : DEFAULT_VALUE_RE.exec(trimmed);
|
|
6169
|
+
const name = fm?.[1] ?? cm?.[1] ?? clm?.[1] ?? (am || dm ? "default" : void 0);
|
|
4980
6170
|
if (name) {
|
|
4981
|
-
const kind = fm ? "sfc_script_function" : cm ? "sfc_script_const" : "sfc_script_class";
|
|
6171
|
+
const kind = fm || am && am[1] === void 0 ? "sfc_script_function" : cm || dm ? "sfc_script_const" : "sfc_script_class";
|
|
4982
6172
|
const sym = makeLineSymbol(filePath, name, kind, line);
|
|
4983
6173
|
const endIdx = declarationEndIdx(lines, i);
|
|
4984
6174
|
symbols.push(endIdx > i ? { ...sym, lineEnd: startLine + endIdx, body: rawLines.slice(i, endIdx + 1).join("\n") } : sym);
|
|
@@ -5009,19 +6199,14 @@ function extractComponentRefs(markup, filePath, startLine, allowKebab) {
|
|
|
5009
6199
|
}
|
|
5010
6200
|
function extractTagBlocks(content, lineIndex, tag) {
|
|
5011
6201
|
const masked = blankJsStringLiterals(content);
|
|
5012
|
-
const re = new RegExp(`<${tag}\\b([^>]*)>([\\s\\S]*?)<\\/${tag}\\s*>`, "gi");
|
|
5013
6202
|
const blocks = [];
|
|
5014
|
-
for (const
|
|
5015
|
-
const
|
|
5016
|
-
const attrs = m[1] ?? "";
|
|
5017
|
-
const innerLen = (m[2] ?? "").length;
|
|
5018
|
-
const openTagLen = 1 + tag.length + attrs.length + 1;
|
|
5019
|
-
const innerStart = matchStart + openTagLen;
|
|
6203
|
+
for (const el of findElements(masked, new RegExp(`<${tag}\\b`, "gi"), new RegExp(`<\\/${tag}\\s*>`, "gi"))) {
|
|
6204
|
+
const innerStart = el.bodyEnd - el.body.length;
|
|
5020
6205
|
blocks.push({
|
|
5021
|
-
content: content.slice(innerStart,
|
|
6206
|
+
content: content.slice(innerStart, el.bodyEnd),
|
|
5022
6207
|
contentStartLine: offsetToLine(lineIndex, innerStart),
|
|
5023
|
-
matchStart,
|
|
5024
|
-
matchEnd:
|
|
6208
|
+
matchStart: el.start,
|
|
6209
|
+
matchEnd: el.end
|
|
5025
6210
|
});
|
|
5026
6211
|
}
|
|
5027
6212
|
return blocks;
|
|
@@ -6840,12 +8025,17 @@ function sectionsToHeadingSymbols(sections, filePath) {
|
|
|
6840
8025
|
parent: ""
|
|
6841
8026
|
}));
|
|
6842
8027
|
}
|
|
8028
|
+
var CSHARP_SPAN_OPTS = { lineComment: "//", stringEscapes: "csharp", rawStringQuotes: true, expressionBodies: true, interpolation: "csharp" };
|
|
6843
8029
|
var ADAPTER_EXTRACTORS = {
|
|
6844
|
-
csharp: (content, filePath) =>
|
|
8030
|
+
csharp: (content, filePath) => {
|
|
8031
|
+
const { symbols, settled } = extractCsharp(content, filePath);
|
|
8032
|
+
return spanUnsettled(symbols, settled, (rest) => assignBraceBlockSpans(rest, content, CSHARP_SPAN_OPTS));
|
|
8033
|
+
},
|
|
6845
8034
|
// Both halves walk the SAME masked text: the brace pass used to span raw file content, so it nested on braces in the inline HTML the extractor is no longer reading.
|
|
6846
8035
|
php: (content, filePath) => {
|
|
6847
8036
|
const code = maskPhpInlineHtml(content);
|
|
6848
|
-
|
|
8037
|
+
const { symbols, settled } = extractPhp(code, filePath);
|
|
8038
|
+
return spanUnsettled(symbols, settled, (rest) => assignBraceBlockSpans(rest, code, { lineComment: ["//", "#"], lineCommentExceptions: ["#["], multilineLang: "php" }));
|
|
6849
8039
|
},
|
|
6850
8040
|
html: (content, filePath) => {
|
|
6851
8041
|
const r = extractHtml(content, filePath);
|
|
@@ -6855,9 +8045,7 @@ var ADAPTER_EXTRACTORS = {
|
|
|
6855
8045
|
const r = extractLiquid(content, filePath);
|
|
6856
8046
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
6857
8047
|
},
|
|
6858
|
-
// The six template dialects mask their own delimiters out and hand off to extractHtml, so they
|
|
6859
|
-
// compose the same way html/liquid do above -- see templates_idx.ts's module doc for why this
|
|
6860
|
-
// is the one place in Batch G/F where sharing IS correct.
|
|
8048
|
+
// The six template dialects mask their own delimiters out and hand off to extractHtml, so they compose the same way html/liquid do above -- see templates_idx.ts's module doc for why this is the one place in Batch G/F where sharing IS correct.
|
|
6861
8049
|
jinja2: (content, filePath) => {
|
|
6862
8050
|
const r = extractJinja2(content, filePath);
|
|
6863
8051
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
@@ -6882,9 +8070,18 @@ var ADAPTER_EXTRACTORS = {
|
|
|
6882
8070
|
const r = extractTwig(content, filePath);
|
|
6883
8071
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
6884
8072
|
},
|
|
6885
|
-
kotlin: (content, filePath) =>
|
|
6886
|
-
|
|
6887
|
-
|
|
8073
|
+
kotlin: (content, filePath) => {
|
|
8074
|
+
const { symbols, settled } = extractKotlin(content, filePath);
|
|
8075
|
+
return spanUnsettled(symbols, settled, (rest) => assignBraceBlockSpans(rest, content, { lineComment: "//", nestedBlockComments: true, tripleQuote: true, tripleQuoteRunClose: "last", expressionBodies: "kotlin", interpolation: "kotlin" }));
|
|
8076
|
+
},
|
|
8077
|
+
swift: (content, filePath) => {
|
|
8078
|
+
const { symbols, settled } = extractSwift(content, filePath);
|
|
8079
|
+
return spanUnsettled(symbols, settled, (rest) => assignBraceBlockSpans(rest, content, { lineComment: "//", nestedBlockComments: true, tripleQuote: true, tripleQuoteRunClose: "last", multilineLang: "swift", interpolation: "swift" }));
|
|
8080
|
+
},
|
|
8081
|
+
scala: (content, filePath) => {
|
|
8082
|
+
const { symbols, settled } = extractScala(content, filePath);
|
|
8083
|
+
return spanUnsettled(symbols, settled, (rest) => assignBraceBlockSpans(rest, content, { lineComment: "//", nestedBlockComments: true, tripleQuote: true, tripleQuoteRunClose: "last", expressionBodies: "kotlin", interpolation: "scala", symbolLiterals: true }));
|
|
8084
|
+
},
|
|
6888
8085
|
lua: (content, filePath) => extractLua(content, filePath).symbols,
|
|
6889
8086
|
vb: (content, filePath) => extractVb(content, filePath).symbols,
|
|
6890
8087
|
elixir: (content, filePath) => extractElixir(content, filePath).symbols,
|
|
@@ -6940,6 +8137,7 @@ var ADAPTER_EXTRACTORS = {
|
|
|
6940
8137
|
};
|
|
6941
8138
|
export {
|
|
6942
8139
|
ADAPTER_EXTRACTORS,
|
|
8140
|
+
CSHARP_SPAN_OPTS,
|
|
6943
8141
|
assignBraceBlockSpans,
|
|
6944
8142
|
extractAstro,
|
|
6945
8143
|
extractCobol,
|
|
@@ -6947,5 +8145,6 @@ export {
|
|
|
6947
8145
|
extractNatural,
|
|
6948
8146
|
extractSalesforceMetadata,
|
|
6949
8147
|
extractSvelte,
|
|
6950
|
-
extractVue
|
|
8148
|
+
extractVue,
|
|
8149
|
+
spanUnsettled
|
|
6951
8150
|
};
|