token-goat 2.9.29 → 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 +53 -42
- package/SECURITY.md +37 -11
- package/THIRD_PARTY_NOTICES.md +41 -4
- 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/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/{token-goat-chunk-SE6E4BKJ.mjs → token-goat-chunk-25TRAWET.mjs} +23 -6
- package/dist/token-goat-chunk-2KXO6V2B.mjs +203 -0
- package/dist/{token-goat-chunk-UXSXQQIY.mjs → token-goat-chunk-2M7E4PF7.mjs} +43 -14
- package/dist/token-goat-chunk-2UPZGKKY.mjs +188 -0
- 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-2WOUYWLM.mjs → token-goat-chunk-4GILLLWY.mjs} +34 -7
- package/dist/token-goat-chunk-4NAPX7BA.mjs +90 -0
- package/dist/{token-goat-chunk-NMBWLRHW.mjs → token-goat-chunk-4SC7UJYV.mjs} +9981 -11563
- package/dist/token-goat-chunk-4SMRO4TO.mjs +366 -0
- package/dist/{token-goat-chunk-O6I2XU4P.mjs → token-goat-chunk-4ZBFWLXF.mjs} +310 -441
- package/dist/token-goat-chunk-57BIAXJL.mjs +286 -0
- package/dist/token-goat-chunk-5AC66HNP.mjs +115 -0
- package/dist/token-goat-chunk-5IMLKSOP.mjs +145 -0
- package/dist/token-goat-chunk-5RG5SBL6.mjs +221 -0
- package/dist/{token-goat-chunk-RRNZMM3A.mjs → token-goat-chunk-5Y6ZYL6U.mjs} +21 -2
- package/dist/token-goat-chunk-646E6U44.mjs +398 -0
- package/dist/token-goat-chunk-65N4RHP4.mjs +33 -0
- package/dist/{token-goat-chunk-6AK46ZT7.mjs → token-goat-chunk-6DG6HWP3.mjs} +13 -3
- package/dist/token-goat-chunk-6ENQSNRZ.mjs +573 -0
- package/dist/token-goat-chunk-6ZY4GNF2.mjs +91 -0
- package/dist/{token-goat-chunk-E5TK5DNO.mjs → token-goat-chunk-76FGDLRO.mjs} +574 -340
- package/dist/{token-goat-chunk-TGOXNAHW.mjs → token-goat-chunk-7EZTZOMC.mjs} +780 -767
- package/dist/token-goat-chunk-7MAOA6X4.mjs +3647 -0
- package/dist/token-goat-chunk-7R2ZVVAX.mjs +218 -0
- package/dist/{token-goat-chunk-TCQANXYC.mjs → token-goat-chunk-AM5V6GSX.mjs} +18 -2
- package/dist/token-goat-chunk-AUNGYYQX.mjs +184 -0
- package/dist/token-goat-chunk-AUQYRMMH.mjs +2985 -0
- package/dist/token-goat-chunk-B3PEKBYG.mjs +128 -0
- package/dist/{token-goat-chunk-KOPIR3KZ.mjs → token-goat-chunk-BA4HI6BW.mjs} +1910 -165
- package/dist/{token-goat-chunk-52NSDWYY.mjs → token-goat-chunk-BFCWY73P.mjs} +58 -20
- package/dist/token-goat-chunk-BPGCUMR7.mjs +30 -0
- package/dist/token-goat-chunk-BWGFUZZE.mjs +25 -0
- package/dist/token-goat-chunk-C75NA7PL.mjs +322 -0
- package/dist/token-goat-chunk-CBIQ7WTD.mjs +87 -0
- package/dist/token-goat-chunk-CETM74KC.mjs +307 -0
- package/dist/token-goat-chunk-CIMQ2BB3.mjs +233 -0
- package/dist/{token-goat-chunk-DNSPXQXQ.mjs → token-goat-chunk-CJLS3CDL.mjs} +70 -18
- package/dist/{token-goat-chunk-MELOKFDJ.mjs → token-goat-chunk-CO3UYX6G.mjs} +7 -1
- package/dist/token-goat-chunk-COPNXRJM.mjs +154 -0
- package/dist/token-goat-chunk-CSJ5L3NL.mjs +479 -0
- package/dist/token-goat-chunk-CVCEVUGK.mjs +315 -0
- package/dist/token-goat-chunk-CXHOFN7R.mjs +371 -0
- package/dist/token-goat-chunk-D735C4QM.mjs +603 -0
- package/dist/{token-goat-chunk-E4ZOJIZK.mjs → token-goat-chunk-DGS2LVNA.mjs} +70 -160
- package/dist/{token-goat-chunk-L7H3U27L.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-EELTBKDM.mjs +613 -0
- package/dist/token-goat-chunk-EVMZJ27Z.mjs +147 -0
- package/dist/token-goat-chunk-EXKGNHEG.mjs +2096 -0
- package/dist/{token-goat-chunk-YOOVFPTP.mjs → token-goat-chunk-F4HYL64R.mjs} +12 -2
- package/dist/token-goat-chunk-F6PAUIEK.mjs +624 -0
- package/dist/token-goat-chunk-FDSREWLX.mjs +692 -0
- package/dist/{token-goat-chunk-NMTKNYGF.mjs → token-goat-chunk-FNFBKLRD.mjs} +74 -9
- package/dist/token-goat-chunk-G5PJ7AGM.mjs +36 -0
- package/dist/token-goat-chunk-GGGG7RWB.mjs +236 -0
- package/dist/{token-goat-chunk-TDUT2CL6.mjs → token-goat-chunk-GL3ETKSC.mjs} +276 -19
- package/dist/{token-goat-chunk-7CPMDFGB.mjs → token-goat-chunk-GVB2MUST.mjs} +265 -1567
- package/dist/token-goat-chunk-GWFLAUMQ.mjs +307 -0
- package/dist/token-goat-chunk-HAVAOB3S.mjs +87 -0
- package/dist/token-goat-chunk-HLPW63A7.mjs +48 -0
- package/dist/token-goat-chunk-HU4TORC5.mjs +1377 -0
- package/dist/token-goat-chunk-I7VKZZAW.mjs +35 -0
- package/dist/token-goat-chunk-IA6XSPE3.mjs +218 -0
- package/dist/token-goat-chunk-IAGXMHIK.mjs +863 -0
- package/dist/{token-goat-chunk-435UQTKD.mjs → token-goat-chunk-IK2DRMFX.mjs} +129 -74
- package/dist/{token-goat-chunk-ZER6EAXZ.mjs → token-goat-chunk-INNPTRUX.mjs} +2954 -2783
- package/dist/token-goat-chunk-JJ5BX4F4.mjs +129 -0
- package/dist/token-goat-chunk-JVFSHVFJ.mjs +129 -0
- package/dist/token-goat-chunk-KGEFFSHD.mjs +50 -0
- package/dist/token-goat-chunk-KKUFXAPD.mjs +25 -0
- package/dist/token-goat-chunk-KQBLRPBN.mjs +433 -0
- package/dist/token-goat-chunk-LCNQ2CNN.mjs +497 -0
- 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-2AWQ2R5X.mjs → token-goat-chunk-MHX7XCC3.mjs} +3 -2
- package/dist/token-goat-chunk-MNWKPRAL.mjs +13 -0
- package/dist/token-goat-chunk-N5LSOVSU.mjs +137 -0
- package/dist/{token-goat-chunk-DPNLUJWB.mjs → token-goat-chunk-N5MMR2IW.mjs} +30 -8
- package/dist/token-goat-chunk-N7B3JQ2C.mjs +160 -0
- package/dist/{token-goat-chunk-VMFWNHGR.mjs → token-goat-chunk-NISNMD7T.mjs} +2545 -2953
- package/dist/token-goat-chunk-NMD42SFQ.mjs +434 -0
- package/dist/token-goat-chunk-NOSS5VWY.mjs +174 -0
- package/dist/token-goat-chunk-NSNSPPBG.mjs +69 -0
- package/dist/token-goat-chunk-OBOFIHKN.mjs +38 -0
- package/dist/token-goat-chunk-OBRFJ5O5.mjs +76 -0
- package/dist/token-goat-chunk-ODBT2USM.mjs +800 -0
- 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-ASLWOQ3I.mjs → token-goat-chunk-OYIYKDDT.mjs} +2 -1
- package/dist/{token-goat-chunk-67BNIKKO.mjs → token-goat-chunk-P6HQSWQ3.mjs} +55 -47
- package/dist/token-goat-chunk-P6VGNTQT.mjs +71 -0
- package/dist/token-goat-chunk-PFWIMH2E.mjs +261 -0
- package/dist/token-goat-chunk-PJZXIS3G.mjs +39 -0
- package/dist/token-goat-chunk-PUO5INXP.mjs +606 -0
- package/dist/token-goat-chunk-PX5PQWTY.mjs +462 -0
- package/dist/token-goat-chunk-Q5QDBC6O.mjs +111 -0
- package/dist/token-goat-chunk-QFNQXSDT.mjs +40 -0
- package/dist/token-goat-chunk-QH7YVYOY.mjs +3957 -0
- package/dist/token-goat-chunk-QLMUHEPB.mjs +43 -0
- package/dist/{token-goat-chunk-PYSUADX4.mjs → token-goat-chunk-QQOJIHL3.mjs} +50 -14
- package/dist/token-goat-chunk-QQTWJY2O.mjs +85 -0
- package/dist/token-goat-chunk-QYHO5CPH.mjs +93 -0
- package/dist/token-goat-chunk-RELAVWAD.mjs +27 -0
- package/dist/token-goat-chunk-RSLPOBKQ.mjs +339 -0
- package/dist/token-goat-chunk-SAMFDIS2.mjs +712 -0
- package/dist/token-goat-chunk-SDELXLDM.mjs +48 -0
- package/dist/{token-goat-chunk-PGTH2U4C.mjs → token-goat-chunk-SOAFZNNZ.mjs} +164 -40
- package/dist/{token-goat-chunk-G23DWHV4.mjs → token-goat-chunk-SRTHT7KV.mjs} +33 -15
- package/dist/token-goat-chunk-T5P5ACNQ.mjs +212 -0
- package/dist/token-goat-chunk-T5YGG4V3.mjs +45 -0
- package/dist/token-goat-chunk-TAUZ4OFS.mjs +110 -0
- package/dist/token-goat-chunk-TM6MC754.mjs +40 -0
- package/dist/token-goat-chunk-TWUKBOMP.mjs +72 -0
- package/dist/token-goat-chunk-U2KSB4SG.mjs +56 -0
- package/dist/token-goat-chunk-U4WHMG6Y.mjs +898 -0
- package/dist/token-goat-chunk-UA5V6P3P.mjs +122 -0
- package/dist/token-goat-chunk-UGJHGR5A.mjs +52 -0
- package/dist/{token-goat-chunk-RQGGMPCR.mjs → token-goat-chunk-UOUDVA5U.mjs} +76 -16
- package/dist/{token-goat-chunk-HNFZZHFW.mjs → token-goat-chunk-URRJ33GR.mjs} +22 -4
- package/dist/token-goat-chunk-UZOROKIS.mjs +165 -0
- package/dist/token-goat-chunk-VIHGGGEI.mjs +4234 -0
- package/dist/token-goat-chunk-VTJLAA7P.mjs +21 -0
- package/dist/token-goat-chunk-VWDXLT4F.mjs +678 -0
- package/dist/token-goat-chunk-VWZA2H4P.mjs +368 -0
- package/dist/{token-goat-chunk-QO3LXVVR.mjs → token-goat-chunk-VXEXMJDL.mjs} +2964 -3153
- package/dist/token-goat-chunk-WBA5SKT4.mjs +547 -0
- package/dist/{token-goat-chunk-ONXH6NZ5.mjs → token-goat-chunk-WDH44VAU.mjs} +19 -22
- package/dist/token-goat-chunk-X2SUP3EI.mjs +107 -0
- package/dist/token-goat-chunk-X3BELZSJ.mjs +125 -0
- package/dist/{token-goat-chunk-RLP6J7WR.mjs → token-goat-chunk-XLRBNZCC.mjs} +40 -21
- package/dist/{token-goat-chunk-S4VSXURL.mjs → token-goat-chunk-XRKUX6CM.mjs} +4 -0
- package/dist/token-goat-chunk-XX6O25RN.mjs +82 -0
- package/dist/token-goat-chunk-XZSUHBVS.mjs +65 -0
- package/dist/token-goat-chunk-Y2ZTQOCL.mjs +35 -0
- package/dist/{token-goat-chunk-UA5BKWWQ.mjs → token-goat-chunk-YB4VMGK2.mjs} +15 -4
- package/dist/token-goat-chunk-YBIIY3HR.mjs +51 -0
- package/dist/{token-goat-chunk-PKRWMHVP.mjs → token-goat-chunk-YHVDKQBR.mjs} +389 -221
- package/dist/token-goat-chunk-YJB5XLWI.mjs +26 -0
- package/dist/{token-goat-chunk-PQ53BSCF.mjs → token-goat-chunk-YKB6AQG3.mjs} +53 -31
- package/dist/token-goat-chunk-YMTG2YA5.mjs +35 -0
- package/dist/token-goat-chunk-YPBZYQRV.mjs +40 -0
- package/dist/{token-goat-chunk-HUYUHODZ.mjs → token-goat-chunk-YY6AVUFL.mjs} +13246 -12247
- package/dist/token-goat-chunk-Z7N5OMMP.mjs +98 -0
- package/dist/{token-goat-chunk-BGHSSJUA.mjs → token-goat-chunk-ZFOBKUWH.mjs} +1 -1
- package/dist/token-goat-chunk-ZMBL6UVV.mjs +110 -0
- package/dist/token-goat-chunk-ZNMNUPAZ.mjs +938 -0
- package/dist/token-goat-hook-client.cjs +87 -23
- package/dist/token-goat-hook-client.mjs +3 -3
- package/dist/token-goat-hook.mjs +76 -31
- package/dist/token-goat.core.mjs +6 -6
- package/docs/C4_RUNTIME_ARCHITECTURE.md +2 -2
- package/docs/cli.md +113 -60
- package/docs/install.md +63 -20
- package/docs/security.md +10 -8
- package/package.json +18 -7
- package/scripts/verify-native-dist.mjs +386 -0
- package/dist/token-goat-chunk-2NNUA2LR.mjs +0 -143
- package/dist/token-goat-chunk-44BM7DDQ.mjs +0 -294
- package/dist/token-goat-chunk-BGYOZ6DO.mjs +0 -24
- package/dist/token-goat-chunk-C5YPNZKQ.mjs +0 -318
- package/dist/token-goat-chunk-CIQ2FTY3.mjs +0 -1990
- package/dist/token-goat-chunk-D4ETHJD6.mjs +0 -246
- package/dist/token-goat-chunk-DNRPXHYH.mjs +0 -1062
- package/dist/token-goat-chunk-EUSDXRXU.mjs +0 -1429
- package/dist/token-goat-chunk-FTP4U4QA.mjs +0 -64
- package/dist/token-goat-chunk-G7IWXCFF.mjs +0 -456
- package/dist/token-goat-chunk-GLXRTTLE.mjs +0 -36
- package/dist/token-goat-chunk-H5J3C56Q.mjs +0 -1511
- package/dist/token-goat-chunk-IVWI2OCK.mjs +0 -368
- package/dist/token-goat-chunk-JTKCQMQA.mjs +0 -418
- package/dist/token-goat-chunk-LZNBQTDK.mjs +0 -26
- package/dist/token-goat-chunk-ORNFMIER.mjs +0 -295
- package/dist/token-goat-chunk-RTMVLHWX.mjs +0 -7113
- package/dist/token-goat-chunk-VQ6F6T7X.mjs +0 -36
- package/dist/token-goat-chunk-VZQEWRVH.mjs +0 -312
- package/dist/token-goat-chunk-XYWPOSCN.mjs +0 -807
- package/dist/token-goat-chunk-YAGLESS3.mjs +0 -23
- package/dist/token-goat-chunk-YKSRAWUU.mjs +0 -33
- package/dist/token-goat-chunk-Z6KBMOBI.mjs +0 -53
|
@@ -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,21 +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-
|
|
32
|
-
import "./token-goat-chunk-
|
|
38
|
+
} from "./token-goat-chunk-OXFMP75N.mjs";
|
|
39
|
+
import "./token-goat-chunk-NISNMD7T.mjs";
|
|
40
|
+
import "./token-goat-chunk-EVMZJ27Z.mjs";
|
|
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";
|
|
33
47
|
import {
|
|
34
48
|
GENERIC_CLAUSE,
|
|
35
|
-
assignBraceBlockSpans,
|
|
36
49
|
assignFlatEndLines,
|
|
37
50
|
buildLineIndex,
|
|
38
|
-
|
|
39
|
-
extractIni,
|
|
51
|
+
closingQuoteRunEnd,
|
|
40
52
|
findHtmlHeadingMatches,
|
|
41
|
-
findMatchingBraceEndLine,
|
|
42
53
|
isInsideStringLiteral,
|
|
43
54
|
lineTextAt,
|
|
44
55
|
makeLineSymbol,
|
|
@@ -50,6 +61,7 @@ import {
|
|
|
50
61
|
offsetToLine,
|
|
51
62
|
precedingDocComment,
|
|
52
63
|
propagateEndLinesToSymbols,
|
|
64
|
+
scalaCharLiteralLength,
|
|
53
65
|
scanQuotedStringEnd,
|
|
54
66
|
stripBlockCommentSpan,
|
|
55
67
|
stripCstyleComments,
|
|
@@ -59,21 +71,27 @@ import {
|
|
|
59
71
|
stripMultilineStringSpan,
|
|
60
72
|
stripStringLiterals,
|
|
61
73
|
stripXmlComments
|
|
62
|
-
} from "./token-goat-chunk-
|
|
63
|
-
import "./token-goat-chunk-
|
|
64
|
-
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";
|
|
65
78
|
import "./token-goat-chunk-YZAAZU2S.mjs";
|
|
66
79
|
import "./token-goat-chunk-IVE6U7KV.mjs";
|
|
80
|
+
import {
|
|
81
|
+
elementCursor,
|
|
82
|
+
findElements,
|
|
83
|
+
gtFinder
|
|
84
|
+
} from "./token-goat-chunk-E45INMY3.mjs";
|
|
85
|
+
import "./token-goat-chunk-Y4AFKTHK.mjs";
|
|
67
86
|
import {
|
|
68
87
|
countContentLines,
|
|
69
88
|
escapeRegExp,
|
|
70
89
|
pushAll
|
|
71
|
-
} from "./token-goat-chunk-
|
|
72
|
-
import "./token-goat-chunk-
|
|
73
|
-
import "./token-goat-chunk-
|
|
74
|
-
import "./token-goat-chunk-
|
|
75
|
-
import "./token-goat-chunk-
|
|
76
|
-
import "./token-goat-chunk-JTKCQMQA.mjs";
|
|
90
|
+
} from "./token-goat-chunk-HU4TORC5.mjs";
|
|
91
|
+
import "./token-goat-chunk-GGGG7RWB.mjs";
|
|
92
|
+
import "./token-goat-chunk-AM5V6GSX.mjs";
|
|
93
|
+
import "./token-goat-chunk-FNFBKLRD.mjs";
|
|
94
|
+
import "./token-goat-chunk-CO3UYX6G.mjs";
|
|
77
95
|
import {
|
|
78
96
|
init_define_import_meta_env
|
|
79
97
|
} from "./token-goat-chunk-A37V4PBF.mjs";
|
|
@@ -81,6 +99,682 @@ import {
|
|
|
81
99
|
// src/languages/registry.ts
|
|
82
100
|
init_define_import_meta_env();
|
|
83
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
|
+
|
|
84
778
|
// src/languages/csharp.ts
|
|
85
779
|
init_define_import_meta_env();
|
|
86
780
|
var IDENT = "@?[A-Za-z_][A-Za-z0-9_]*";
|
|
@@ -144,6 +838,13 @@ var PROPERTY_ARROW_RE = new RegExp(
|
|
|
144
838
|
var CONSTRUCTOR_RE = new RegExp(
|
|
145
839
|
`${MEMBER_INDENT}(?:(?:public|protected|private|internal|static)\\s+)*(${IDENT})\\s*\\(`
|
|
146
840
|
);
|
|
841
|
+
var FINALIZER_RE = new RegExp(`${MEMBER_INDENT}(?:(?:extern|unsafe)\\s+)*~\\s*(${IDENT})\\s*\\(`);
|
|
842
|
+
var OPERATOR_RE = /\b(?:implicit|explicit)\s+operator\s([^(]+)\(|\boperator(\s+checked)?\s*([-+!~*/%&|^<>=]+|true|false)\s*\(/;
|
|
843
|
+
var INDEXER_RE = /\bthis\s*\[/;
|
|
844
|
+
var DECLARATION_PREFIX_RE = /^[\w@.<>,?[\]()\s]*$/;
|
|
845
|
+
function isDeclarationPrefix(prefix) {
|
|
846
|
+
return DECLARATION_PREFIX_RE.test(prefix) && /\w/.test(prefix);
|
|
847
|
+
}
|
|
147
848
|
var CLASS_HEADER_RE = new RegExp(
|
|
148
849
|
`^(?:(?:public|protected|private|internal|abstract|sealed|static|partial|readonly|ref|unsafe|file|new)\\s+)*(class|struct|interface|enum|record)(?:\\s+(?:class|struct))?\\s+(${IDENT})`
|
|
149
850
|
);
|
|
@@ -159,9 +860,162 @@ function nextCodeLines(lines, from, count) {
|
|
|
159
860
|
}
|
|
160
861
|
return out;
|
|
161
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
|
+
}
|
|
923
|
+
var CS_REF_NOISE = /* @__PURE__ */ new Set([
|
|
924
|
+
"if",
|
|
925
|
+
"else",
|
|
926
|
+
"while",
|
|
927
|
+
"for",
|
|
928
|
+
"foreach",
|
|
929
|
+
"switch",
|
|
930
|
+
"case",
|
|
931
|
+
"catch",
|
|
932
|
+
"finally",
|
|
933
|
+
"using",
|
|
934
|
+
"lock",
|
|
935
|
+
"fixed",
|
|
936
|
+
"sizeof",
|
|
937
|
+
"typeof",
|
|
938
|
+
"nameof",
|
|
939
|
+
"default",
|
|
940
|
+
"checked",
|
|
941
|
+
"unchecked",
|
|
942
|
+
"delegate",
|
|
943
|
+
"return",
|
|
944
|
+
"throw",
|
|
945
|
+
"yield",
|
|
946
|
+
"base",
|
|
947
|
+
"this",
|
|
948
|
+
"new",
|
|
949
|
+
"var",
|
|
950
|
+
"async",
|
|
951
|
+
"await",
|
|
952
|
+
"get",
|
|
953
|
+
"set",
|
|
954
|
+
"init",
|
|
955
|
+
"add",
|
|
956
|
+
"remove",
|
|
957
|
+
"where",
|
|
958
|
+
"when",
|
|
959
|
+
"select",
|
|
960
|
+
"from",
|
|
961
|
+
"join",
|
|
962
|
+
"into",
|
|
963
|
+
"let",
|
|
964
|
+
"orderby",
|
|
965
|
+
"group",
|
|
966
|
+
"by",
|
|
967
|
+
"equals",
|
|
968
|
+
"on",
|
|
969
|
+
"ascending",
|
|
970
|
+
"descending",
|
|
971
|
+
"true",
|
|
972
|
+
"false",
|
|
973
|
+
"null",
|
|
974
|
+
"void",
|
|
975
|
+
"bool",
|
|
976
|
+
"byte",
|
|
977
|
+
"sbyte",
|
|
978
|
+
"short",
|
|
979
|
+
"ushort",
|
|
980
|
+
"int",
|
|
981
|
+
"uint",
|
|
982
|
+
"long",
|
|
983
|
+
"ulong",
|
|
984
|
+
"float",
|
|
985
|
+
"double",
|
|
986
|
+
"decimal",
|
|
987
|
+
"char",
|
|
988
|
+
"string",
|
|
989
|
+
"object",
|
|
990
|
+
"dynamic",
|
|
991
|
+
"public",
|
|
992
|
+
"private",
|
|
993
|
+
"protected",
|
|
994
|
+
"internal",
|
|
995
|
+
"static",
|
|
996
|
+
"readonly",
|
|
997
|
+
"volatile",
|
|
998
|
+
"virtual",
|
|
999
|
+
"override",
|
|
1000
|
+
"abstract",
|
|
1001
|
+
"sealed",
|
|
1002
|
+
"extern",
|
|
1003
|
+
"unsafe",
|
|
1004
|
+
"partial",
|
|
1005
|
+
"class",
|
|
1006
|
+
"struct",
|
|
1007
|
+
"interface",
|
|
1008
|
+
"enum",
|
|
1009
|
+
"record"
|
|
1010
|
+
]);
|
|
1011
|
+
var CS_NEW_CALL_RE = /\bnew\s+([A-Za-z_][A-Za-z0-9_.]*)(?:<[^>()]+>)?\s*(?:\(|(?=\{))/g;
|
|
1012
|
+
var CS_INVOCATION_RE = /(?:\b([A-Za-z_][A-Za-z0-9_]*)\s*(?:\.|\?\.)\s*|(?:\.|\?\.)\s*)?\b([A-Za-z_][A-Za-z0-9_]*)(?:\s*<[^>()\n]+>)?\s*\(/g;
|
|
1013
|
+
var CS_MULTILINE_INVOCATION_RE = /(?:\b([A-Za-z_][A-Za-z0-9_]*)\s*(?:\.|\?\.)\s*|(?:\.|\?\.)\s*)?\b([A-Za-z_][A-Za-z0-9_]*)(?:\s*<[^>()\n]+>)?\s*$/;
|
|
162
1014
|
function extractCsharp(content, filePath) {
|
|
163
1015
|
const symbols = [];
|
|
1016
|
+
const refs = [];
|
|
164
1017
|
const imports = [];
|
|
1018
|
+
const seenRefs = /* @__PURE__ */ new Set();
|
|
165
1019
|
const lines = content.split(/\r?\n/);
|
|
166
1020
|
const classStack = [];
|
|
167
1021
|
let braceDepth = 0;
|
|
@@ -169,6 +1023,10 @@ function extractCsharp(content, filePath) {
|
|
|
169
1023
|
let mlState = null;
|
|
170
1024
|
let inFalseBlock = false;
|
|
171
1025
|
let falseNesting = 0;
|
|
1026
|
+
let currentMember;
|
|
1027
|
+
let memberBodyEntered = false;
|
|
1028
|
+
const settled = /* @__PURE__ */ new Set();
|
|
1029
|
+
let openMembers = [];
|
|
172
1030
|
for (let i = 0; i < lines.length; i++) {
|
|
173
1031
|
const rawLine = lines[i] ?? "";
|
|
174
1032
|
const lineNum = i + 1;
|
|
@@ -210,25 +1068,31 @@ function extractCsharp(content, filePath) {
|
|
|
210
1068
|
const delegateParent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
211
1069
|
symbols.push(makeLineSymbol(filePath, stripVerbatim(delM[1] ?? ""), "type", lineNum, stripped.slice(0, 200), delegateParent, lines, "c"));
|
|
212
1070
|
}
|
|
1071
|
+
const outerFrame = classStack.length > 0 ? classStack[classStack.length - 1] : null;
|
|
213
1072
|
const cm = CLASS_HEADER_RE.exec(stripLeadingAttributes(stripped));
|
|
214
1073
|
if (cm) {
|
|
215
|
-
const keyword = cm[1] ?? "class";
|
|
216
1074
|
const cname = stripVerbatim(cm[2] ?? "");
|
|
217
|
-
|
|
218
|
-
const parent = classStack.length > 0 ? classStack[classStack.length - 1].name : void 0;
|
|
219
|
-
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"));
|
|
220
1076
|
classStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false });
|
|
221
1077
|
}
|
|
1078
|
+
let ctorM = null;
|
|
1079
|
+
let finM = null;
|
|
1080
|
+
let methM = null;
|
|
1081
|
+
let propM = null;
|
|
1082
|
+
let headerM = null;
|
|
1083
|
+
let arrowM = null;
|
|
222
1084
|
const frame = classStack.length > 0 ? classStack[classStack.length - 1] : null;
|
|
223
1085
|
if (frame !== null) {
|
|
224
1086
|
const depthInClass = braceDepth - frame.startDepth;
|
|
225
1087
|
if (depthInClass === 1) {
|
|
226
1088
|
const lineNoAttr = stripLeadingAttributes(line);
|
|
227
|
-
|
|
1089
|
+
ctorM = CONSTRUCTOR_RE.exec(lineNoAttr);
|
|
228
1090
|
if (ctorM && stripVerbatim(ctorM[1] ?? "") === frame.name) {
|
|
229
1091
|
const sigEnd = line.indexOf("{");
|
|
230
1092
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
|
|
231
1093
|
symbols.push(makeLineSymbol(filePath, frame.name, "method", lineNum, sig.slice(0, 200), frame.name, lines, "c"));
|
|
1094
|
+
currentMember = frame.name;
|
|
1095
|
+
memberBodyEntered = line.includes("{");
|
|
232
1096
|
}
|
|
233
1097
|
let isPropertyLine = false;
|
|
234
1098
|
const eventM = EVENT_RE.exec(lineNoAttr);
|
|
@@ -240,41 +1104,217 @@ function extractCsharp(content, filePath) {
|
|
|
240
1104
|
if (declM) symbols.push(makeLineSymbol(filePath, stripVerbatim(declM[1] ?? ""), "var", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
|
|
241
1105
|
}
|
|
242
1106
|
}
|
|
243
|
-
|
|
1107
|
+
propM = isPropertyLine ? null : PROPERTY_RE.exec(lineNoAttr);
|
|
244
1108
|
if (propM) {
|
|
245
1109
|
isPropertyLine = true;
|
|
246
|
-
|
|
1110
|
+
const propName = stripVerbatim(propM[1] ?? "");
|
|
1111
|
+
symbols.push(makeLineSymbol(filePath, propName, "var", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
|
|
1112
|
+
currentMember = propName;
|
|
1113
|
+
memberBodyEntered = line.includes("{");
|
|
247
1114
|
} else {
|
|
248
|
-
|
|
1115
|
+
headerM = PROPERTY_HEADER_RE.exec(lineNoAttr);
|
|
249
1116
|
if (headerM) {
|
|
250
1117
|
const [braceLineNext = "", accessorLine = ""] = nextCodeLines(lines, i, 2);
|
|
251
1118
|
if (braceLineNext === "{" && (ALLMAN_ACCESSOR_RE.test(accessorLine) || ALLMAN_ACCESSOR_BODY_RE.test(accessorLine))) {
|
|
252
1119
|
isPropertyLine = true;
|
|
253
|
-
|
|
1120
|
+
const propName = stripVerbatim(headerM[1] ?? "");
|
|
1121
|
+
symbols.push(makeLineSymbol(filePath, propName, "var", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
|
|
1122
|
+
currentMember = propName;
|
|
1123
|
+
memberBodyEntered = false;
|
|
254
1124
|
}
|
|
255
1125
|
} else {
|
|
256
|
-
|
|
1126
|
+
arrowM = PROPERTY_ARROW_RE.exec(lineNoAttr);
|
|
257
1127
|
if (arrowM) {
|
|
258
1128
|
isPropertyLine = true;
|
|
259
|
-
|
|
1129
|
+
const propName = stripVerbatim(arrowM[1] ?? "");
|
|
1130
|
+
symbols.push(makeLineSymbol(filePath, propName, "var", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
|
|
1131
|
+
currentMember = propName;
|
|
1132
|
+
memberBodyEntered = false;
|
|
260
1133
|
}
|
|
261
1134
|
}
|
|
262
1135
|
}
|
|
263
|
-
|
|
1136
|
+
let specialName = null;
|
|
1137
|
+
let specialKind = "method";
|
|
1138
|
+
finM = FINALIZER_RE.exec(lineNoAttr);
|
|
1139
|
+
if (finM && stripVerbatim(finM[1] ?? "") === frame.name) specialName = `~${frame.name}`;
|
|
1140
|
+
else finM = null;
|
|
1141
|
+
const opM = specialName === null && !isPropertyLine ? OPERATOR_RE.exec(lineNoAttr) : null;
|
|
1142
|
+
if (opM && isDeclarationPrefix(lineNoAttr.slice(0, opM.index))) specialName = operatorName(opM);
|
|
1143
|
+
const ixM = specialName === null && !isPropertyLine ? INDEXER_RE.exec(lineNoAttr) : null;
|
|
1144
|
+
if (ixM && isDeclarationPrefix(lineNoAttr.slice(0, ixM.index))) {
|
|
1145
|
+
specialName = "this[]";
|
|
1146
|
+
specialKind = "var";
|
|
1147
|
+
}
|
|
1148
|
+
if (specialName !== null) {
|
|
1149
|
+
isPropertyLine = true;
|
|
1150
|
+
const sigEnd = line.indexOf("{");
|
|
1151
|
+
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
|
|
1152
|
+
symbols.push(makeLineSymbol(filePath, specialName, specialKind, lineNum, sig.slice(0, 200), frame.name, lines, "c"));
|
|
1153
|
+
currentMember = specialName;
|
|
1154
|
+
memberBodyEntered = line.includes("{");
|
|
1155
|
+
}
|
|
1156
|
+
methM = isPropertyLine ? null : METHOD_RE.exec(lineNoAttr);
|
|
264
1157
|
if (methM) {
|
|
265
1158
|
const mname = stripVerbatim(methM[1] ?? "");
|
|
266
1159
|
if (mname && mname !== frame.name) {
|
|
267
1160
|
const sigEnd = line.indexOf("{");
|
|
268
1161
|
const sig = sigEnd >= 0 ? line.slice(0, sigEnd).trimEnd() : line.trimEnd();
|
|
269
1162
|
symbols.push(makeLineSymbol(filePath, mname, "method", lineNum, sig.slice(0, 200), frame.name, lines, "c"));
|
|
1163
|
+
currentMember = mname;
|
|
1164
|
+
memberBodyEntered = line.includes("{");
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
const isInterpolatedLine = rawLine.includes('$"') || rawLine.includes('$@"') || rawLine.includes('@$"');
|
|
1170
|
+
const baseLine = isInterpolatedLine ? stripLineComment(rawLine) : stripLineComment(line);
|
|
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
|
+
}
|
|
1196
|
+
if (!inFalseBlock && !stripped.startsWith("#")) {
|
|
1197
|
+
const declSpans = [];
|
|
1198
|
+
if (cm) {
|
|
1199
|
+
const name = stripVerbatim(cm[2] ?? "");
|
|
1200
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1201
|
+
}
|
|
1202
|
+
if (ctorM) {
|
|
1203
|
+
const name = stripVerbatim(ctorM[1] ?? "");
|
|
1204
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1205
|
+
}
|
|
1206
|
+
if (methM) {
|
|
1207
|
+
const name = stripVerbatim(methM[1] ?? "");
|
|
1208
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1209
|
+
}
|
|
1210
|
+
if (delM) {
|
|
1211
|
+
const name = stripVerbatim(delM[1] ?? "");
|
|
1212
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1213
|
+
}
|
|
1214
|
+
if (propM) {
|
|
1215
|
+
const name = stripVerbatim(propM[1] ?? "");
|
|
1216
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1217
|
+
}
|
|
1218
|
+
if (headerM) {
|
|
1219
|
+
const name = stripVerbatim(headerM[1] ?? "");
|
|
1220
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1221
|
+
}
|
|
1222
|
+
if (finM) declSpans.push({ name: stripVerbatim(finM[1] ?? ""), col: line.indexOf("~") + 1 });
|
|
1223
|
+
if (arrowM) {
|
|
1224
|
+
const name = stripVerbatim(arrowM[1] ?? "");
|
|
1225
|
+
declSpans.push({ name, col: line.indexOf(name) });
|
|
1226
|
+
}
|
|
1227
|
+
const isDeclaration = (name, col) => declSpans.some((d) => d.name === name && Math.abs(d.col - col) <= 2);
|
|
1228
|
+
const context = currentMember ?? (frame !== null ? frame.name : "");
|
|
1229
|
+
for (const m of braceLine.matchAll(CS_NEW_CALL_RE)) {
|
|
1230
|
+
const rawName = stripVerbatim(m[1] ?? "");
|
|
1231
|
+
const name = rawName.includes(".") ? rawName.slice(rawName.lastIndexOf(".") + 1) : rawName;
|
|
1232
|
+
if (name.length < 1 || CS_REF_NOISE.has(name)) continue;
|
|
1233
|
+
const nameOffset = m[0].lastIndexOf(name);
|
|
1234
|
+
const col = m.index !== void 0 ? m.index + (nameOffset >= 0 ? nameOffset : 0) : 0;
|
|
1235
|
+
if (isDeclaration(name, col)) continue;
|
|
1236
|
+
const key = `${name}\0${lineNum}`;
|
|
1237
|
+
if (!seenRefs.has(key)) {
|
|
1238
|
+
seenRefs.add(key);
|
|
1239
|
+
refs.push({ filePath, name, line: lineNum, col, context });
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
for (const m of braceLine.matchAll(CS_INVOCATION_RE)) {
|
|
1243
|
+
const callee = stripVerbatim(m[2] ?? "");
|
|
1244
|
+
if (callee.length >= 1 && !CS_REF_NOISE.has(callee)) {
|
|
1245
|
+
const dotIdx = m[0].indexOf(".");
|
|
1246
|
+
const searchStart = dotIdx >= 0 ? m[0].lastIndexOf(".") + 1 : 0;
|
|
1247
|
+
const calleeOffset = m[0].indexOf(callee, searchStart);
|
|
1248
|
+
const col = m.index !== void 0 ? m.index + (calleeOffset >= 0 ? calleeOffset : 0) : 0;
|
|
1249
|
+
if (!isDeclaration(callee, col)) {
|
|
1250
|
+
const key = `${callee}\0${lineNum}`;
|
|
1251
|
+
if (!seenRefs.has(key)) {
|
|
1252
|
+
seenRefs.add(key);
|
|
1253
|
+
refs.push({ filePath, name: callee, line: lineNum, col, context });
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
const receiver = m[1] !== void 0 ? stripVerbatim(m[1]) : "";
|
|
1258
|
+
if (receiver.length > 1 && !CS_REF_NOISE.has(receiver)) {
|
|
1259
|
+
const col = m.index !== void 0 ? m.index + m[0].indexOf(receiver) : 0;
|
|
1260
|
+
if (!isDeclaration(receiver, col)) {
|
|
1261
|
+
const key = `${receiver}\0${lineNum}`;
|
|
1262
|
+
if (!seenRefs.has(key)) {
|
|
1263
|
+
seenRefs.add(key);
|
|
1264
|
+
refs.push({ filePath, name: receiver, line: lineNum, col, context });
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
const nextCode = nextCodeLines(lines, i, 1)[0];
|
|
1270
|
+
if (nextCode?.startsWith("(")) {
|
|
1271
|
+
const mlMatch = CS_MULTILINE_INVOCATION_RE.exec(braceLine);
|
|
1272
|
+
if (mlMatch) {
|
|
1273
|
+
const callee = stripVerbatim(mlMatch[2] ?? "");
|
|
1274
|
+
if (callee.length >= 1 && !CS_REF_NOISE.has(callee)) {
|
|
1275
|
+
const dotIdx = mlMatch[0].indexOf(".");
|
|
1276
|
+
const searchStart = dotIdx >= 0 ? mlMatch[0].lastIndexOf(".") + 1 : 0;
|
|
1277
|
+
const calleeOffset = mlMatch[0].indexOf(callee, searchStart);
|
|
1278
|
+
const col = mlMatch.index !== void 0 ? mlMatch.index + (calleeOffset >= 0 ? calleeOffset : 0) : 0;
|
|
1279
|
+
if (!isDeclaration(callee, col)) {
|
|
1280
|
+
const key = `${callee}\0${lineNum}`;
|
|
1281
|
+
if (!seenRefs.has(key)) {
|
|
1282
|
+
seenRefs.add(key);
|
|
1283
|
+
refs.push({ filePath, name: callee, line: lineNum, col, context });
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
const receiver = mlMatch[1] !== void 0 ? stripVerbatim(mlMatch[1]) : "";
|
|
1288
|
+
if (receiver.length > 1 && !CS_REF_NOISE.has(receiver)) {
|
|
1289
|
+
const col = mlMatch.index !== void 0 ? mlMatch.index + mlMatch[0].indexOf(receiver) : 0;
|
|
1290
|
+
if (!isDeclaration(receiver, col)) {
|
|
1291
|
+
const key = `${receiver}\0${lineNum}`;
|
|
1292
|
+
if (!seenRefs.has(key)) {
|
|
1293
|
+
seenRefs.add(key);
|
|
1294
|
+
refs.push({ filePath, name: receiver, line: lineNum, col, context });
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
270
1297
|
}
|
|
271
1298
|
}
|
|
272
1299
|
}
|
|
273
1300
|
}
|
|
274
|
-
const braceLine = stripStringLiterals(stripLineComment(line));
|
|
275
1301
|
const openBraces = (braceLine.match(/\{/g) ?? []).length;
|
|
276
1302
|
const closeBraces = (braceLine.match(/\}/g) ?? []).length;
|
|
277
1303
|
braceDepth += openBraces - closeBraces;
|
|
1304
|
+
openMembers = endOpenMembers(symbols, settled, openMembers, braceDepth, lineNum, lines);
|
|
1305
|
+
openMembers.push(...lineOpens);
|
|
1306
|
+
if (currentMember !== void 0) {
|
|
1307
|
+
if (!memberBodyEntered) {
|
|
1308
|
+
if (openBraces > 0 && braceDepth > (frame?.startDepth ?? 0) + 1) {
|
|
1309
|
+
memberBodyEntered = true;
|
|
1310
|
+
} else if (stripped.endsWith(";")) {
|
|
1311
|
+
currentMember = void 0;
|
|
1312
|
+
}
|
|
1313
|
+
} else if (frame === null || braceDepth <= frame.startDepth + 1) {
|
|
1314
|
+
currentMember = void 0;
|
|
1315
|
+
memberBodyEntered = false;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
278
1318
|
const bracelessTop = classStack.length > 0 ? classStack[classStack.length - 1] : null;
|
|
279
1319
|
if (bracelessTop !== null && !bracelessTop.bodyEntered && braceDepth === bracelessTop.startDepth && (openBraces > 0 && openBraces === closeBraces || openBraces === 0 && closeBraces === 0 && stripped.endsWith(";"))) {
|
|
280
1320
|
classStack.pop();
|
|
@@ -293,7 +1333,7 @@ function extractCsharp(content, filePath) {
|
|
|
293
1333
|
}
|
|
294
1334
|
}
|
|
295
1335
|
}
|
|
296
|
-
return { symbols, imports };
|
|
1336
|
+
return { symbols, refs, imports, settled };
|
|
297
1337
|
}
|
|
298
1338
|
|
|
299
1339
|
// src/languages/php.ts
|
|
@@ -321,6 +1361,18 @@ var USE_RE = /^use\s+(?:function\s+|const\s+)?([\w\\]+)(?:\s+as\s+\w+)?\s*;/i;
|
|
|
321
1361
|
var GROUP_USE_RE = /^use\s+(?:function\s+|const\s+)?([\w\\]+)\\\{([^}]*)\}/i;
|
|
322
1362
|
var REQUIRE_RE = /^(?:require|include)(?:_once)?\s+['"]([^'"]+)['"]/i;
|
|
323
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
|
+
}
|
|
324
1376
|
function maskPhpInlineHtml(content) {
|
|
325
1377
|
const opener = /<\?(?:php\b|=)/i;
|
|
326
1378
|
if (!opener.test(content)) return content;
|
|
@@ -351,12 +1403,34 @@ function extractPhp(content, filePath) {
|
|
|
351
1403
|
const symbols = [];
|
|
352
1404
|
const imports = [];
|
|
353
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
|
+
};
|
|
354
1427
|
const contextStack = [];
|
|
355
1428
|
let braceDepth = 0;
|
|
356
1429
|
let parenDepth = 0;
|
|
357
1430
|
let inComment = false;
|
|
358
1431
|
let mlState = null;
|
|
359
1432
|
for (let i = 0; i < lines.length; i++) {
|
|
1433
|
+
flushMembers();
|
|
360
1434
|
const rawLine = lines[i] ?? "";
|
|
361
1435
|
const lineNum = i + 1;
|
|
362
1436
|
let mlLine = rawLine;
|
|
@@ -384,6 +1458,23 @@ function extractPhp(content, filePath) {
|
|
|
384
1458
|
if (topFrame !== void 0 && braceDepth > topFrame[1]) {
|
|
385
1459
|
topFrame[2] = true;
|
|
386
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
|
+
}
|
|
387
1478
|
while (contextStack.length > 0) {
|
|
388
1479
|
const top = contextStack[contextStack.length - 1];
|
|
389
1480
|
if (top !== void 0 && top[2] && braceDepth <= top[1]) {
|
|
@@ -430,6 +1521,8 @@ function extractPhp(content, filePath) {
|
|
|
430
1521
|
const parent = topFrame2 !== void 0 && preLineDepth === topFrame2[1] + 1 ? topFrame2[0] : null;
|
|
431
1522
|
symbols.push(makeLineSymbol(filePath, name, kind, lineNum, stripped.slice(0, 200), parent ?? void 0, lines, "c"));
|
|
432
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;
|
|
433
1526
|
if (openB > 0 && openB === closeB) {
|
|
434
1527
|
contextStack.pop();
|
|
435
1528
|
}
|
|
@@ -481,7 +1574,8 @@ function extractPhp(content, filePath) {
|
|
|
481
1574
|
symbols.push(makeLineSymbol(filePath, defineM[1] ?? "", "const", lineNum, stripped.slice(0, 200), void 0, lines, "c"));
|
|
482
1575
|
}
|
|
483
1576
|
}
|
|
484
|
-
|
|
1577
|
+
flushMembers();
|
|
1578
|
+
return { symbols, imports, settled };
|
|
485
1579
|
}
|
|
486
1580
|
|
|
487
1581
|
// src/languages/html.ts
|
|
@@ -530,20 +1624,66 @@ function isNoise(name) {
|
|
|
530
1624
|
}
|
|
531
1625
|
var MAX_SYMBOLS = 1e4;
|
|
532
1626
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
|
|
533
|
-
|
|
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
|
+
}
|
|
534
1672
|
var ELEMENT_SPAN_SCAN_CAP = 2e6;
|
|
535
1673
|
function buildElementSpans(code) {
|
|
536
1674
|
const spans = /* @__PURE__ */ new Map();
|
|
537
1675
|
const openTagRanges = [];
|
|
538
1676
|
const stack = [];
|
|
539
|
-
|
|
1677
|
+
const nextTag = makeTagScanner(code);
|
|
1678
|
+
const styleClose = /<\/style\s*>/gi;
|
|
1679
|
+
let styleCloseMissing = false;
|
|
1680
|
+
let from = 0;
|
|
540
1681
|
let m;
|
|
541
|
-
while ((m =
|
|
542
|
-
if (m.
|
|
543
|
-
const isClose = m
|
|
544
|
-
const
|
|
545
|
-
|
|
546
|
-
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;
|
|
547
1687
|
if (isClose) {
|
|
548
1688
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
549
1689
|
if (stack[i].name === name) {
|
|
@@ -554,14 +1694,17 @@ function buildElementSpans(code) {
|
|
|
554
1694
|
}
|
|
555
1695
|
continue;
|
|
556
1696
|
}
|
|
557
|
-
openTagRanges.push({ start: m.
|
|
1697
|
+
openTagRanges.push({ start: m.start, end: tagEnd });
|
|
558
1698
|
if (selfClosing || VOID_ELEMENTS.has(name)) continue;
|
|
559
1699
|
if (name === "style") {
|
|
560
|
-
|
|
561
|
-
|
|
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;
|
|
562
1705
|
continue;
|
|
563
1706
|
}
|
|
564
|
-
stack.push({ name, start: m.
|
|
1707
|
+
stack.push({ name, start: m.start });
|
|
565
1708
|
}
|
|
566
1709
|
return { spans, openTagRanges };
|
|
567
1710
|
}
|
|
@@ -754,12 +1897,47 @@ var TYPEALIAS_RE = new RegExp(
|
|
|
754
1897
|
var TOP_FUN_RE = new RegExp(
|
|
755
1898
|
"^(?:(?:public|internal|private|suspend|inline|infix|operator|external|actual|expect|tailrec)\\s+)*fun\\s+(?:" + GENERIC_CLAUSE + "\\s*)?" + RECEIVER_RE + "(" + NAME_RE + ")\\s*[(<]"
|
|
756
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
|
+
}
|
|
757
1933
|
function extractKotlin(content, filePath) {
|
|
758
1934
|
const symbols = [];
|
|
759
1935
|
const imports = [];
|
|
760
1936
|
const lines = content.split(/\r?\n/);
|
|
761
1937
|
const classStack = [];
|
|
762
1938
|
let braceDepth = 0;
|
|
1939
|
+
const settled = /* @__PURE__ */ new Set();
|
|
1940
|
+
let openMembers = [];
|
|
763
1941
|
let inComment = false;
|
|
764
1942
|
let mlState = null;
|
|
765
1943
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -850,6 +2028,23 @@ function extractKotlin(content, filePath) {
|
|
|
850
2028
|
}
|
|
851
2029
|
}
|
|
852
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);
|
|
853
2048
|
for (const ch of braceLine) {
|
|
854
2049
|
if (ch === "{") {
|
|
855
2050
|
braceDepth++;
|
|
@@ -864,6 +2059,8 @@ function extractKotlin(content, filePath) {
|
|
|
864
2059
|
frame.parenBalance--;
|
|
865
2060
|
}
|
|
866
2061
|
}
|
|
2062
|
+
openMembers = endOpenMembers(symbols, settled, openMembers, braceDepth, lineNum, lines);
|
|
2063
|
+
openMembers.push(...lineOpens);
|
|
867
2064
|
if (frame !== null && !frame.bodyEntered && frame.parenBalance <= 0) {
|
|
868
2065
|
frame.pendingPop = !(stripped.endsWith(":") || stripped.endsWith(","));
|
|
869
2066
|
}
|
|
@@ -876,12 +2073,28 @@ function extractKotlin(content, filePath) {
|
|
|
876
2073
|
}
|
|
877
2074
|
}
|
|
878
2075
|
}
|
|
879
|
-
return { symbols, imports };
|
|
2076
|
+
return { symbols, imports, settled };
|
|
880
2077
|
}
|
|
881
2078
|
|
|
882
2079
|
// src/languages/scala.ts
|
|
883
2080
|
init_define_import_meta_env();
|
|
884
|
-
var SCALA_STRIP = { symbolLiterals: true };
|
|
2081
|
+
var SCALA_STRIP = { symbolLiterals: true, interpolatorPrefix: true };
|
|
2082
|
+
var MEMBER_KINDS = /* @__PURE__ */ new Set(["function", "val", "var"]);
|
|
2083
|
+
function withSpanEnd(sym, endLine, lines) {
|
|
2084
|
+
if (endLine <= sym.lineStart) return sym;
|
|
2085
|
+
return { ...sym, lineEnd: endLine, body: lines.slice(sym.lineStart - 1, endLine).join("\n") };
|
|
2086
|
+
}
|
|
2087
|
+
function indentedBodyEnd(lines, startLine, declIndent) {
|
|
2088
|
+
let end = startLine;
|
|
2089
|
+
for (let j = startLine; j < lines.length; j++) {
|
|
2090
|
+
const text = lines[j] ?? "";
|
|
2091
|
+
const trimmed = text.trim();
|
|
2092
|
+
if (trimmed === "" || trimmed.startsWith("//")) continue;
|
|
2093
|
+
if (indentOf(text) <= declIndent) break;
|
|
2094
|
+
end = j + 1;
|
|
2095
|
+
}
|
|
2096
|
+
return end;
|
|
2097
|
+
}
|
|
885
2098
|
function indentOf(line) {
|
|
886
2099
|
return line.length - line.trimStart().length;
|
|
887
2100
|
}
|
|
@@ -897,11 +2110,151 @@ var OBJECT_RE = new RegExp("^\\s*(?:package\\s+)?" + MODS + "object\\s+(" + NAME
|
|
|
897
2110
|
var TRAIT_RE = new RegExp("^\\s*" + MODS + "trait\\s+(" + NAME + ")(?:\\s|\\[|:|$)");
|
|
898
2111
|
var ENUM_RE = new RegExp("^\\s*(?:private|protected)?\\s*enum\\s+(" + NAME + ")(?:\\s|\\[|\\(|:|$)");
|
|
899
2112
|
var DEF_NAME = "(?:`[^`\\r\\n]+`|[A-Za-z_][A-Za-z0-9_]*_[+\\-*/%=!<>&|^~:]+|[+\\-*/%=!<>&|^~:]+|[A-Za-z_][A-Za-z0-9_]*)";
|
|
900
|
-
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*=(?!=))");
|
|
901
2114
|
var VAL_RE = new RegExp("^\\s*" + MODS + "val\\s+(" + NAME + ")");
|
|
902
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
|
+
}
|
|
903
2209
|
function startsDeclaration(stripped) {
|
|
904
|
-
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 };
|
|
905
2258
|
}
|
|
906
2259
|
function extractScala(content, filePath) {
|
|
907
2260
|
const symbols = [];
|
|
@@ -909,8 +2262,16 @@ function extractScala(content, filePath) {
|
|
|
909
2262
|
const lines = content.split(/\r?\n/);
|
|
910
2263
|
const typeStack = [];
|
|
911
2264
|
let braceDepth = 0;
|
|
2265
|
+
const settled = /* @__PURE__ */ new Set();
|
|
2266
|
+
let openMembers = [];
|
|
912
2267
|
let inComment = false;
|
|
913
2268
|
let mlState = null;
|
|
2269
|
+
let lastCodeLine = 0;
|
|
2270
|
+
let extBlock = null;
|
|
2271
|
+
const closeColonFrame = (frame, endLine) => {
|
|
2272
|
+
const open = symbols[frame.symbolIndex];
|
|
2273
|
+
if (open !== void 0) symbols[frame.symbolIndex] = withSpanEnd(open, endLine, lines);
|
|
2274
|
+
};
|
|
914
2275
|
for (let i = 0; i < lines.length; i++) {
|
|
915
2276
|
const rawLine = lines[i] ?? "";
|
|
916
2277
|
const lineNum = i + 1;
|
|
@@ -920,7 +2281,7 @@ function extractScala(content, filePath) {
|
|
|
920
2281
|
mlLine = masked.code;
|
|
921
2282
|
mlState = masked.state;
|
|
922
2283
|
}
|
|
923
|
-
const { code: blockStripped, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment);
|
|
2284
|
+
const { code: blockStripped, inComment: nextInComment } = stripBlockCommentSpan(mlLine, inComment, SCALA_STRIP);
|
|
924
2285
|
inComment = nextInComment;
|
|
925
2286
|
const line = stripLineComment(blockStripped, ["//"], SCALA_STRIP).trimEnd();
|
|
926
2287
|
const stripped = line.trim();
|
|
@@ -933,9 +2294,13 @@ function extractScala(content, filePath) {
|
|
|
933
2294
|
const indent = indentOf(line);
|
|
934
2295
|
while (typeStack.length > 0) {
|
|
935
2296
|
const top = typeStack[typeStack.length - 1];
|
|
936
|
-
if (top.colonBody
|
|
937
|
-
|
|
2297
|
+
if (!top.colonBody || indent > top.declIndent) break;
|
|
2298
|
+
typeStack.pop();
|
|
2299
|
+
const closesWithMarker = indent === top.declIndent && stripped === (top.endMarker ?? `end ${top.name}`);
|
|
2300
|
+
closeColonFrame(top, closesWithMarker ? lineNum : lastCodeLine);
|
|
2301
|
+
if (closesWithMarker) lastCodeLine = lineNum;
|
|
938
2302
|
}
|
|
2303
|
+
lastCodeLine = lineNum;
|
|
939
2304
|
const colonTop = typeStack.length > 0 && typeStack[typeStack.length - 1].colonBody ? typeStack[typeStack.length - 1] : null;
|
|
940
2305
|
if (colonTop !== null && colonTop.bodyIndent === null) {
|
|
941
2306
|
colonTop.bodyIndent = indent;
|
|
@@ -974,7 +2339,7 @@ function extractScala(content, filePath) {
|
|
|
974
2339
|
const cname = unquoteName2(cm[1] ?? "");
|
|
975
2340
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
976
2341
|
symbols.push(makeLineSymbol(filePath, cname, "class", lineNum, stripped.slice(0, 200), parent, lines, "c"));
|
|
977
|
-
typeStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null });
|
|
2342
|
+
typeStack.push({ name: cname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null, symbolIndex: symbols.length - 1 });
|
|
978
2343
|
matched = true;
|
|
979
2344
|
}
|
|
980
2345
|
const om = !matched && typeDetectionGateOk && (!isIndented || typeStack.length > 0) ? OBJECT_RE.exec(stripped) : null;
|
|
@@ -982,7 +2347,7 @@ function extractScala(content, filePath) {
|
|
|
982
2347
|
const oname = unquoteName2(om[1] ?? "");
|
|
983
2348
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
984
2349
|
symbols.push(makeLineSymbol(filePath, oname, "object", lineNum, stripped.slice(0, 200), parent, lines, "c"));
|
|
985
|
-
typeStack.push({ name: oname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null });
|
|
2350
|
+
typeStack.push({ name: oname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null, symbolIndex: symbols.length - 1 });
|
|
986
2351
|
matched = true;
|
|
987
2352
|
}
|
|
988
2353
|
const tm = !matched && typeDetectionGateOk && (!isIndented || typeStack.length > 0) ? TRAIT_RE.exec(stripped) : null;
|
|
@@ -990,7 +2355,7 @@ function extractScala(content, filePath) {
|
|
|
990
2355
|
const tname = unquoteName2(tm[1] ?? "");
|
|
991
2356
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
992
2357
|
symbols.push(makeLineSymbol(filePath, tname, "trait", lineNum, stripped.slice(0, 200), parent, lines, "c"));
|
|
993
|
-
typeStack.push({ name: tname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null });
|
|
2358
|
+
typeStack.push({ name: tname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null, symbolIndex: symbols.length - 1 });
|
|
994
2359
|
matched = true;
|
|
995
2360
|
}
|
|
996
2361
|
const enm = !matched && typeDetectionGateOk && (!isIndented || typeStack.length > 0) ? ENUM_RE.exec(stripped) : null;
|
|
@@ -998,10 +2363,37 @@ function extractScala(content, filePath) {
|
|
|
998
2363
|
const enname = unquoteName2(enm[1] ?? "");
|
|
999
2364
|
const parent = typeStack.length > 0 ? typeStack[typeStack.length - 1].name : void 0;
|
|
1000
2365
|
symbols.push(makeLineSymbol(filePath, enname, "enum", lineNum, stripped.slice(0, 200), parent, lines, "c"));
|
|
1001
|
-
typeStack.push({ name: enname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null });
|
|
2366
|
+
typeStack.push({ name: enname, startDepth: braceDepth, bodyEntered: false, openParens: 0, declIndent: indent, colonBody: opensColonBody, bodyIndent: null, symbolIndex: symbols.length - 1 });
|
|
2367
|
+
matched = true;
|
|
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
|
+
}
|
|
1002
2376
|
matched = true;
|
|
1003
2377
|
}
|
|
1004
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
|
+
}
|
|
1005
2397
|
if (!matched && frame !== null) {
|
|
1006
2398
|
const depthInType = braceDepth - frame.startDepth;
|
|
1007
2399
|
if (depthInType === 1 || inColonBody && frame === colonTop) {
|
|
@@ -1040,7 +2432,34 @@ function extractScala(content, filePath) {
|
|
|
1040
2432
|
}
|
|
1041
2433
|
}
|
|
1042
2434
|
}
|
|
2435
|
+
const lastSymbol = symbols[symbols.length - 1];
|
|
2436
|
+
if (lastSymbol !== void 0 && lastSymbol.lineStart === lineNum && MEMBER_KINDS.has(lastSymbol.kind) && stripped.endsWith("=") && !stripped.includes("{")) {
|
|
2437
|
+
symbols[symbols.length - 1] = withSpanEnd(lastSymbol, indentedBodyEnd(lines, lineNum, indent), lines);
|
|
2438
|
+
}
|
|
1043
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);
|
|
1044
2463
|
if (frame !== null && !frame.bodyEntered) {
|
|
1045
2464
|
const parenDelta2 = (braceLine.match(/\(/g) ?? []).length - (braceLine.match(/\)/g) ?? []).length;
|
|
1046
2465
|
frame.openParens = Math.max(0, frame.openParens + parenDelta2);
|
|
@@ -1055,6 +2474,8 @@ function extractScala(content, filePath) {
|
|
|
1055
2474
|
braceDepth--;
|
|
1056
2475
|
}
|
|
1057
2476
|
}
|
|
2477
|
+
openMembers = endOpenMembers(symbols, settled, openMembers, braceDepth, lineNum, lines);
|
|
2478
|
+
openMembers.push(...lineOpens);
|
|
1058
2479
|
while (typeStack.length > 0) {
|
|
1059
2480
|
const top = typeStack[typeStack.length - 1];
|
|
1060
2481
|
if (!top.colonBody && top.bodyEntered && braceDepth <= top.startDepth) {
|
|
@@ -1064,11 +2485,19 @@ function extractScala(content, filePath) {
|
|
|
1064
2485
|
}
|
|
1065
2486
|
}
|
|
1066
2487
|
}
|
|
1067
|
-
|
|
2488
|
+
while (typeStack.length > 0) {
|
|
2489
|
+
const top = typeStack.pop();
|
|
2490
|
+
if (top.colonBody) closeColonFrame(top, lastCodeLine);
|
|
2491
|
+
}
|
|
2492
|
+
return { symbols, imports, settled };
|
|
1068
2493
|
}
|
|
1069
2494
|
|
|
1070
2495
|
// src/languages/lua.ts
|
|
1071
2496
|
init_define_import_meta_env();
|
|
2497
|
+
function receiverName(fname) {
|
|
2498
|
+
const parts = fname.split(/[.:]/);
|
|
2499
|
+
return parts.length > 1 ? parts[parts.length - 2] : void 0;
|
|
2500
|
+
}
|
|
1072
2501
|
function nearestFunctionName(stack) {
|
|
1073
2502
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
1074
2503
|
const frame = stack[i];
|
|
@@ -1160,7 +2589,7 @@ function extractLua(content, filePath) {
|
|
|
1160
2589
|
if (fm) {
|
|
1161
2590
|
const fname = fm[1] ?? "";
|
|
1162
2591
|
const baseName = fname.split(/[.:]/).pop() ?? fname;
|
|
1163
|
-
const parent = nearestFunctionName(funcStack);
|
|
2592
|
+
const parent = receiverName(fname) ?? nearestFunctionName(funcStack);
|
|
1164
2593
|
if (parent !== void 0) {
|
|
1165
2594
|
symbols.push(makeLineSymbol(filePath, baseName, "function", lineNum, stripped.slice(0, 200), parent));
|
|
1166
2595
|
} else {
|
|
@@ -1189,7 +2618,7 @@ function extractLua(content, filePath) {
|
|
|
1189
2618
|
if (afm) {
|
|
1190
2619
|
const fname = afm[1] ?? "";
|
|
1191
2620
|
const baseName = fname.split(/[.:]/).pop() ?? fname;
|
|
1192
|
-
const parent = nearestFunctionName(funcStack);
|
|
2621
|
+
const parent = receiverName(fname) ?? nearestFunctionName(funcStack);
|
|
1193
2622
|
if (parent !== void 0) {
|
|
1194
2623
|
symbols.push(makeLineSymbol(filePath, baseName, "function", lineNum, stripped.slice(0, 200), parent));
|
|
1195
2624
|
} else {
|
|
@@ -1249,7 +2678,7 @@ var DECLARE_RE = new RegExp(String.raw`^Declare\s+(?:(?:Ansi|Unicode|Auto|PtrSaf
|
|
|
1249
2678
|
var VB6_PROPERTY_RE = new RegExp(String.raw`^Property\s+(?:Get|Let|Set)\s+(${ID})`, "i");
|
|
1250
2679
|
var PROPERTY_RE2 = new RegExp(String.raw`^Property\s+(${ID})`, "i");
|
|
1251
2680
|
var PROCEDURE_RE = new RegExp(String.raw`^(Sub|Function)\s+(${ID})`, "i");
|
|
1252
|
-
var
|
|
2681
|
+
var OPERATOR_RE2 = /^Operator\s+([^\s(]+)\s*\(/i;
|
|
1253
2682
|
var EVENT_RE2 = new RegExp(String.raw`^Event\s+(${ID})`, "i");
|
|
1254
2683
|
var CONST_RE3 = /^Const\s+(\S.*)$/i;
|
|
1255
2684
|
var DIM_RE = /^Dim\s+(\S.*)$/i;
|
|
@@ -1578,7 +3007,7 @@ function extractVb(content, filePath) {
|
|
|
1578
3007
|
else open(keyword, name, procedureKind(), stmt);
|
|
1579
3008
|
continue;
|
|
1580
3009
|
}
|
|
1581
|
-
if ((m =
|
|
3010
|
+
if ((m = OPERATOR_RE2.exec(rest)) !== null) {
|
|
1582
3011
|
open("operator", m[1], "method", stmt);
|
|
1583
3012
|
continue;
|
|
1584
3013
|
}
|
|
@@ -1803,6 +3232,16 @@ function extractVhdl(content, filePath) {
|
|
|
1803
3232
|
|
|
1804
3233
|
// src/languages/elixir.ts
|
|
1805
3234
|
init_define_import_meta_env();
|
|
3235
|
+
function bracketDelta(line) {
|
|
3236
|
+
const code = line.replace(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g, "");
|
|
3237
|
+
return (code.match(/[([{]/g)?.length ?? 0) - (code.match(/[)\]}]/g)?.length ?? 0);
|
|
3238
|
+
}
|
|
3239
|
+
var DANGLING_RE = /(?:,|\bwhen|\band|\bor|\bin|&&|\|\||[+\-*/<>=!|&])\s*$/;
|
|
3240
|
+
var DO_KEYWORD_RE = /(?:^|[\s,)])do:/;
|
|
3241
|
+
var DO_KEYWORD_AT_EOL_RE = /(?:^|[\s,)])do:$/;
|
|
3242
|
+
function indentOf2(line) {
|
|
3243
|
+
return line.length - line.trimStart().length;
|
|
3244
|
+
}
|
|
1806
3245
|
function nearestDefName(stack) {
|
|
1807
3246
|
for (let i = stack.length - 1; i >= 0; i--) {
|
|
1808
3247
|
const frame = stack[i];
|
|
@@ -1822,6 +3261,30 @@ function extractElixir(content, filePath) {
|
|
|
1822
3261
|
const lines = content.split(/\r?\n/);
|
|
1823
3262
|
const moduleStack = [];
|
|
1824
3263
|
let mlState = null;
|
|
3264
|
+
let pending;
|
|
3265
|
+
let keywordBody;
|
|
3266
|
+
const extendDefSpan = (symbolIndex, lineEnd) => {
|
|
3267
|
+
const open = symbols[symbolIndex];
|
|
3268
|
+
if (open !== void 0 && lineEnd > open.lineStart) {
|
|
3269
|
+
symbols[symbolIndex] = { ...open, lineEnd, body: lines.slice(open.lineStart - 1, lineEnd).join("\n") };
|
|
3270
|
+
}
|
|
3271
|
+
};
|
|
3272
|
+
const trackKeywordBody = (symbolIndex, stripped) => {
|
|
3273
|
+
const open = symbols[symbolIndex];
|
|
3274
|
+
if (open !== void 0 && DO_KEYWORD_AT_EOL_RE.test(stripped)) {
|
|
3275
|
+
keywordBody = { symbolIndex, headIndent: indentOf2(lines[open.lineStart - 1] ?? "") };
|
|
3276
|
+
}
|
|
3277
|
+
};
|
|
3278
|
+
const settleDefHead = (name, stripped) => {
|
|
3279
|
+
const symbolIndex = symbols.length - 1;
|
|
3280
|
+
if (/\bdo\s*$/.test(stripped)) {
|
|
3281
|
+
moduleStack.push({ name, endKeywordNeeded: true, isBlock: false, symbolIndex });
|
|
3282
|
+
} else if (!DO_KEYWORD_RE.test(stripped)) {
|
|
3283
|
+
pending = { name, symbolIndex, depth: bracketDelta(stripped), dangling: DANGLING_RE.test(stripped) };
|
|
3284
|
+
} else {
|
|
3285
|
+
trackKeywordBody(symbolIndex, stripped);
|
|
3286
|
+
}
|
|
3287
|
+
};
|
|
1825
3288
|
for (let i = 0; i < lines.length; i++) {
|
|
1826
3289
|
const rawLine = lines[i] ?? "";
|
|
1827
3290
|
const lineNum = i + 1;
|
|
@@ -1829,9 +3292,37 @@ function extractElixir(content, filePath) {
|
|
|
1829
3292
|
mlState = nextMlState;
|
|
1830
3293
|
const line = stripLineComment(masked, ["#"]).trimEnd();
|
|
1831
3294
|
const stripped = line.trim();
|
|
3295
|
+
if (keywordBody !== void 0) {
|
|
3296
|
+
if (rawLine.trim() === "") {
|
|
3297
|
+
keywordBody = void 0;
|
|
3298
|
+
} else if (stripped && indentOf2(masked) <= keywordBody.headIndent) {
|
|
3299
|
+
keywordBody = void 0;
|
|
3300
|
+
} else {
|
|
3301
|
+
if (stripped) extendDefSpan(keywordBody.symbolIndex, lineNum);
|
|
3302
|
+
continue;
|
|
3303
|
+
}
|
|
3304
|
+
}
|
|
1832
3305
|
if (!stripped) {
|
|
1833
3306
|
continue;
|
|
1834
3307
|
}
|
|
3308
|
+
if (pending !== void 0) {
|
|
3309
|
+
const startsContinuation = /^(?:when\b|do\b|,|\|)/.test(stripped);
|
|
3310
|
+
if (pending.depth <= 0 && !pending.dangling && !startsContinuation) {
|
|
3311
|
+
pending = void 0;
|
|
3312
|
+
} else {
|
|
3313
|
+
pending.depth += bracketDelta(stripped);
|
|
3314
|
+
pending.dangling = DANGLING_RE.test(stripped);
|
|
3315
|
+
if (pending.depth <= 0 && /\bdo\s*$/.test(stripped)) {
|
|
3316
|
+
moduleStack.push({ name: pending.name, endKeywordNeeded: true, isBlock: false, symbolIndex: pending.symbolIndex });
|
|
3317
|
+
pending = void 0;
|
|
3318
|
+
} else if (pending.depth <= 0 && DO_KEYWORD_RE.test(stripped)) {
|
|
3319
|
+
extendDefSpan(pending.symbolIndex, lineNum);
|
|
3320
|
+
trackKeywordBody(pending.symbolIndex, stripped);
|
|
3321
|
+
pending = void 0;
|
|
3322
|
+
}
|
|
3323
|
+
continue;
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
1835
3326
|
const opensDoBlock = /\bdo\s*$/.test(stripped);
|
|
1836
3327
|
const opensFnBlock = /\bfn\b/.test(stripped) && !/\bend\b/.test(stripped) && /(?:fn|->)\s*$/.test(stripped);
|
|
1837
3328
|
const modM = MODULE_RE.exec(stripped);
|
|
@@ -1868,9 +3359,7 @@ function extractElixir(content, filePath) {
|
|
|
1868
3359
|
} else {
|
|
1869
3360
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines, "hash"));
|
|
1870
3361
|
}
|
|
1871
|
-
|
|
1872
|
-
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
1873
|
-
}
|
|
3362
|
+
settleDefHead(fname, stripped);
|
|
1874
3363
|
continue;
|
|
1875
3364
|
}
|
|
1876
3365
|
const pfm = PRIVATE_FUNC_RE.exec(stripped);
|
|
@@ -1882,9 +3371,7 @@ function extractElixir(content, filePath) {
|
|
|
1882
3371
|
} else {
|
|
1883
3372
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines, "hash"));
|
|
1884
3373
|
}
|
|
1885
|
-
|
|
1886
|
-
moduleStack.push({ name: fname, endKeywordNeeded: true, isBlock: false, symbolIndex: symbols.length - 1 });
|
|
1887
|
-
}
|
|
3374
|
+
settleDefHead(fname, stripped);
|
|
1888
3375
|
continue;
|
|
1889
3376
|
}
|
|
1890
3377
|
if (STRUCT_RE.test(stripped)) {
|
|
@@ -1915,12 +3402,14 @@ function extractElixir(content, filePath) {
|
|
|
1915
3402
|
|
|
1916
3403
|
// src/languages/dart.ts
|
|
1917
3404
|
init_define_import_meta_env();
|
|
3405
|
+
var DART_STRIP = { tripleQuotes: true, singleQuoteHoles: true };
|
|
1918
3406
|
var CLASS_RE4 = /^(?:(?:abstract|base|interface|final|sealed|mixin)\s+)*class\s+([A-Za-z_][A-Za-z0-9_]*)/;
|
|
1919
3407
|
var ENUM_RE2 = /^enum\s+([A-Za-z_][A-Za-z0-9_]*)/;
|
|
1920
3408
|
var MIXIN_RE = /^(?:base\s+)?mixin\s+([A-Za-z_][A-Za-z0-9_]*)/;
|
|
1921
3409
|
var EXTENSION_RE = new RegExp("^extension\\s+(?:([A-Za-z_][A-Za-z0-9_]*)\\s*(?:" + GENERIC_CLAUSE + ")?\\s+)?on\\s+");
|
|
1922
3410
|
var EXTENSION_TYPE_RE = /^extension\s+type\s+([A-Za-z_][A-Za-z0-9_]*)/;
|
|
1923
3411
|
var FUNC_RE5 = new RegExp("(?:^|\\s)(?:static\\s+)?(?:(?:void|Future|Stream|async|external)\\s+|[A-Za-z_][A-Za-z0-9_<>?]*(?:\\s*\\?)?\\s+)([A-Za-z_][A-Za-z0-9_]*)\\s*(?:" + GENERIC_CLAUSE + ")?\\s*\\(");
|
|
3412
|
+
var OPERATOR_RE3 = /(?:^|\s)(?:(?:external|abstract)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>?,]*(?:\s*\?)?\s+)?operator\s*(\[\]=|\[\]|>>>|<<|>>|<=|>=|==|~\/|[-+*/%<>&|^~])\s*\(/;
|
|
1924
3413
|
var GETTER_RE = /^(?:(?:static|external|abstract|covariant)\s+)*(?:[A-Za-z_][A-Za-z0-9_<>,?\s]*(?:\s*\?)?\s+)?get\s+([A-Za-z_][A-Za-z0-9_]*)/;
|
|
1925
3414
|
var NAMED_CTOR_RE = /^(?:(?:const|factory|external)\s+)*([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)\s*\(/;
|
|
1926
3415
|
var UNNAMED_CTOR_RE = /^(?:(?:const|factory|external)\s+)*([A-Za-z_][A-Za-z0-9_]*)\s*\(/;
|
|
@@ -1950,11 +3439,11 @@ function extractDart(content, filePath) {
|
|
|
1950
3439
|
const line = stripLineComment(blockStripped).trimEnd();
|
|
1951
3440
|
const stripped = line.trim();
|
|
1952
3441
|
if (!stripped) {
|
|
1953
|
-
const braceLine2 = stripStringLiterals(line,
|
|
3442
|
+
const braceLine2 = stripStringLiterals(line, DART_STRIP);
|
|
1954
3443
|
braceDepth += (braceLine2.match(/\{/g) ?? []).length - (braceLine2.match(/\}/g) ?? []).length;
|
|
1955
3444
|
continue;
|
|
1956
3445
|
}
|
|
1957
|
-
const structural = stripStringLiterals(stripped,
|
|
3446
|
+
const structural = stripStringLiterals(stripped, DART_STRIP);
|
|
1958
3447
|
const isIndented = line[0] === " " || line[0] === " ";
|
|
1959
3448
|
const outerFrame = typeStack.length > 0 ? typeStack[typeStack.length - 1] : null;
|
|
1960
3449
|
const outerDepthInType = outerFrame !== null ? braceDepth - outerFrame.startDepth : 0;
|
|
@@ -2029,6 +3518,11 @@ function extractDart(content, filePath) {
|
|
|
2029
3518
|
if (!member && FIELD_START_RE.test(stripped)) {
|
|
2030
3519
|
member = true;
|
|
2031
3520
|
}
|
|
3521
|
+
const om = !member ? OPERATOR_RE3.exec(structural) : null;
|
|
3522
|
+
if (om) {
|
|
3523
|
+
symbols.push(makeLineSymbol(filePath, om[1] ?? "", "function", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
|
|
3524
|
+
member = true;
|
|
3525
|
+
}
|
|
2032
3526
|
const gm = !member ? GETTER_RE.exec(stripped) : null;
|
|
2033
3527
|
if (gm) {
|
|
2034
3528
|
symbols.push(makeLineSymbol(filePath, gm[1] ?? "", "function", lineNum, stripped.slice(0, 200), frame.name, lines, "c"));
|
|
@@ -2053,7 +3547,7 @@ function extractDart(content, filePath) {
|
|
|
2053
3547
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines, "c"));
|
|
2054
3548
|
}
|
|
2055
3549
|
}
|
|
2056
|
-
const braceLine = stripStringLiterals(line,
|
|
3550
|
+
const braceLine = stripStringLiterals(line, DART_STRIP);
|
|
2057
3551
|
for (const ch of braceLine) {
|
|
2058
3552
|
if (ch === "{") {
|
|
2059
3553
|
braceDepth++;
|
|
@@ -2470,7 +3964,7 @@ var DOMAIN_RE = makeCreateRe("DOMAIN");
|
|
|
2470
3964
|
var AGGREGATE_RE = makeCreateRe("AGGREGATE", OR_REPLACE);
|
|
2471
3965
|
var POLICY_RE = makeCreateRe("POLICY");
|
|
2472
3966
|
var RULE_RE = makeCreateRe("RULE", OR_REPLACE);
|
|
2473
|
-
var
|
|
3967
|
+
var OPERATOR_RE4 = makeCreateRe("OPERATOR(?!\\s+(?:CLASS|FAMILY)\\b)", OR_REPLACE);
|
|
2474
3968
|
var SYNONYM_RE = makeCreateRe("SYNONYM", `${OR_REPLACE}(?:PUBLIC\\s+)?`);
|
|
2475
3969
|
var DATABASE_LINK_RE = makeCreateRe("DATABASE\\s+LINK", "(?:PUBLIC\\s+)?");
|
|
2476
3970
|
var CLUSTER_RE = makeCreateRe("CLUSTER");
|
|
@@ -2496,7 +3990,7 @@ var PATTERNS = [
|
|
|
2496
3990
|
[AGGREGATE_RE, "sql_aggregate"],
|
|
2497
3991
|
[POLICY_RE, "sql_policy"],
|
|
2498
3992
|
[RULE_RE, "sql_rule"],
|
|
2499
|
-
[
|
|
3993
|
+
[OPERATOR_RE4, "sql_operator"],
|
|
2500
3994
|
[SYNONYM_RE, "sql_synonym"],
|
|
2501
3995
|
[DATABASE_LINK_RE, "sql_database_link"],
|
|
2502
3996
|
[CLUSTER_RE, "sql_cluster"],
|
|
@@ -2788,6 +4282,26 @@ function plsqlStructure(noStrings, lineIndex, units, createStarts, filePath, roo
|
|
|
2788
4282
|
}
|
|
2789
4283
|
return { ends, children };
|
|
2790
4284
|
}
|
|
4285
|
+
var BODY_KINDS = /* @__PURE__ */ new Set([
|
|
4286
|
+
"sql_function",
|
|
4287
|
+
"sql_procedure",
|
|
4288
|
+
"sql_trigger",
|
|
4289
|
+
"sql_type",
|
|
4290
|
+
"sql_type_body",
|
|
4291
|
+
"sql_package",
|
|
4292
|
+
"sql_package_body",
|
|
4293
|
+
"sql_rule"
|
|
4294
|
+
]);
|
|
4295
|
+
var BODY_OPENER_RE = /\b(?:BEGIN|DECLARE)\b|\$\w*\$|\bRETURN\s+[\w$#.%]+(?:\s+[\w$#.%=]+|\s*\([^()]*\)){0,16}?\s+(?:IS|AS)\b(?!\s+(?:NOT|NULL|TRUE|FALSE|DISTINCT|UNKNOWN)\b)/i;
|
|
4296
|
+
var QUOTED_IDENTIFIER_RE = /"[^"]*"|`[^`]*`|\[[^\]]*\]/g;
|
|
4297
|
+
function isBodylessFunction(kind, header) {
|
|
4298
|
+
return kind === "sql_function" && !BODY_OPENER_RE.test(header.replace(QUOTED_IDENTIFIER_RE, " "));
|
|
4299
|
+
}
|
|
4300
|
+
function trimBlankTail(lines, start, end) {
|
|
4301
|
+
let e = end;
|
|
4302
|
+
while (e > start && (lines[e - 1] ?? "").trim() === "") e--;
|
|
4303
|
+
return e;
|
|
4304
|
+
}
|
|
2791
4305
|
function extractSql(content, filePath) {
|
|
2792
4306
|
const symbols = [];
|
|
2793
4307
|
const sections = [];
|
|
@@ -2809,8 +4323,8 @@ function extractSql(content, filePath) {
|
|
|
2809
4323
|
const line = offsetToLine(lineIndex, m.index ?? 0);
|
|
2810
4324
|
createStarts.push(m.index ?? 0);
|
|
2811
4325
|
const semiIdx = findStatementTerminator(noStrings, m.index ?? 0);
|
|
2812
|
-
if (semiIdx !== -1 && offsetToLine(lineIndex, semiIdx) === line) {
|
|
2813
|
-
singleLineEndLines.set(`${name}\0${kind}\0${line}`,
|
|
4326
|
+
if (semiIdx !== -1 && (offsetToLine(lineIndex, semiIdx) === line || !BODY_KINDS.has(kind) || isBodylessFunction(kind, noStrings.slice(m.index ?? 0, semiIdx)))) {
|
|
4327
|
+
singleLineEndLines.set(`${name}\0${kind}\0${line}`, offsetToLine(lineIndex, semiIdx));
|
|
2814
4328
|
} else if (PLSQL_UNIT_KINDS.has(kind)) {
|
|
2815
4329
|
units.push({ name, kind, index: m.index ?? 0, matchEnd: (m.index ?? 0) + m[0].length, line });
|
|
2816
4330
|
}
|
|
@@ -2824,10 +4338,13 @@ function extractSql(content, filePath) {
|
|
|
2824
4338
|
sections.sort((a, b) => a.line - b.line);
|
|
2825
4339
|
symbols.sort((a, b) => a.lineStart - b.lineStart);
|
|
2826
4340
|
assignFlatEndLines(sections, totalLines);
|
|
4341
|
+
const noLines = noStrings.split("\n");
|
|
2827
4342
|
const pinned = propagateEndLinesToSymbols(symbols, sections).map((sym) => {
|
|
2828
4343
|
const key = `${sym.name}\0${sym.kind}\0${sym.lineStart}`;
|
|
2829
|
-
const
|
|
2830
|
-
|
|
4344
|
+
const semiEnd = singleLineEndLines.get(key);
|
|
4345
|
+
const pinnedEndLine = semiEnd !== void 0 ? Math.min(semiEnd, sym.lineEnd) : plsql.ends.get(key);
|
|
4346
|
+
const end = pinnedEndLine ?? trimBlankTail(noLines, sym.lineStart, sym.lineEnd);
|
|
4347
|
+
return end !== sym.lineEnd ? { ...sym, lineEnd: end } : sym;
|
|
2831
4348
|
});
|
|
2832
4349
|
if (plsql.children.length === 0) return pinned;
|
|
2833
4350
|
return [...pinned, ...plsql.children].sort((a, b) => a.lineStart - b.lineStart);
|
|
@@ -3055,6 +4572,103 @@ var FUNC_NAME = "[A-Za-z_][A-Za-z0-9_.+:-]*";
|
|
|
3055
4572
|
var FUNC_KEYWORD_RE = new RegExp(`^function\\s+(${FUNC_NAME})\\s*(?:\\(\\s*\\))?`);
|
|
3056
4573
|
var FUNC_POSIX_RE = new RegExp(`^(${FUNC_NAME})\\s*\\(\\s*\\)`);
|
|
3057
4574
|
var VAR_RE3 = /^(?:(?:export|declare|readonly)\s+(?:-\w+\s+)*)?([A-Za-z_]\w*)=/;
|
|
4575
|
+
var COMPOUND_OPENERS = /* @__PURE__ */ new Set(["if", "for", "while", "until", "select", "case"]);
|
|
4576
|
+
var COMPOUND_CLOSERS = /* @__PURE__ */ new Set(["fi", "done", "esac"]);
|
|
4577
|
+
var COMPOUND_PREFIX_WORDS = /* @__PURE__ */ new Set(["then", "do", "else", "!", "time"]);
|
|
4578
|
+
var COMPOUND_BODY_START_RE = /^(?:if|for|while|until|select|case)\b/;
|
|
4579
|
+
var COMPOUND_SEGMENT_SPLIT_RE = /;|&&|\|\||\||&|\(|\{|\)|\}/;
|
|
4580
|
+
function cleanForScan(line) {
|
|
4581
|
+
return stripStringLiterals(stripBashComment(line)).trim();
|
|
4582
|
+
}
|
|
4583
|
+
function compoundDelta(text) {
|
|
4584
|
+
let delta = 0;
|
|
4585
|
+
for (const segment of text.split(COMPOUND_SEGMENT_SPLIT_RE)) {
|
|
4586
|
+
const words = segment.trim().split(/\s+/);
|
|
4587
|
+
let w = 0;
|
|
4588
|
+
while (w < words.length && COMPOUND_PREFIX_WORDS.has(words[w] ?? "")) w++;
|
|
4589
|
+
const first = words[w] ?? "";
|
|
4590
|
+
if (COMPOUND_OPENERS.has(first)) delta++;
|
|
4591
|
+
else if (COMPOUND_CLOSERS.has(first)) delta--;
|
|
4592
|
+
}
|
|
4593
|
+
return delta;
|
|
4594
|
+
}
|
|
4595
|
+
var SUBSHELL_TOKEN_RE = /;;&|;;|;&|\|\||&&|[()]|[;&|]|[^\s()&;|]+/g;
|
|
4596
|
+
var CASE_ARM_ENDS = /* @__PURE__ */ new Set([";;", ";&", ";;&"]);
|
|
4597
|
+
var COMMAND_POSITION_WORDS = /* @__PURE__ */ new Set(["then", "do", "else", "elif", "!", "time", "{"]);
|
|
4598
|
+
var SubshellParenScanner = class {
|
|
4599
|
+
depth = 0;
|
|
4600
|
+
// One entry per open `case`: 'subject' until `in`, 'pattern' while reading an arm's pattern, 'body' inside an arm.
|
|
4601
|
+
cases = [];
|
|
4602
|
+
commandPosition = true;
|
|
4603
|
+
// Feeds one cleaned line; true once the body's opening `(` has been closed.
|
|
4604
|
+
closes(text) {
|
|
4605
|
+
for (const tok of text.match(SUBSHELL_TOKEN_RE) ?? []) {
|
|
4606
|
+
const top = this.cases.length - 1;
|
|
4607
|
+
const state = this.cases[top];
|
|
4608
|
+
if (state === "subject") {
|
|
4609
|
+
if (tok === "in") this.cases[top] = "pattern";
|
|
4610
|
+
continue;
|
|
4611
|
+
}
|
|
4612
|
+
if (state === "pattern") {
|
|
4613
|
+
if (tok === "esac") {
|
|
4614
|
+
this.cases.pop();
|
|
4615
|
+
this.commandPosition = false;
|
|
4616
|
+
} else if (tok === ")") {
|
|
4617
|
+
this.cases[top] = "body";
|
|
4618
|
+
this.commandPosition = true;
|
|
4619
|
+
}
|
|
4620
|
+
continue;
|
|
4621
|
+
}
|
|
4622
|
+
if (state === "body" && CASE_ARM_ENDS.has(tok)) {
|
|
4623
|
+
this.cases[top] = "pattern";
|
|
4624
|
+
continue;
|
|
4625
|
+
}
|
|
4626
|
+
if (tok === "(") {
|
|
4627
|
+
this.depth++;
|
|
4628
|
+
this.commandPosition = true;
|
|
4629
|
+
continue;
|
|
4630
|
+
}
|
|
4631
|
+
if (tok === ")") {
|
|
4632
|
+
this.depth--;
|
|
4633
|
+
if (this.depth <= 0) return true;
|
|
4634
|
+
this.commandPosition = false;
|
|
4635
|
+
continue;
|
|
4636
|
+
}
|
|
4637
|
+
if (this.commandPosition && tok === "case") this.cases.push("subject");
|
|
4638
|
+
else if (this.commandPosition && tok === "esac" && state === "body") this.cases.pop();
|
|
4639
|
+
this.commandPosition = /^[;&|]/.test(tok) || COMMAND_POSITION_WORDS.has(tok);
|
|
4640
|
+
}
|
|
4641
|
+
this.commandPosition = true;
|
|
4642
|
+
return false;
|
|
4643
|
+
}
|
|
4644
|
+
};
|
|
4645
|
+
function findCompoundBodyEnd(lines, headerIdx, rest) {
|
|
4646
|
+
let startIdx = headerIdx;
|
|
4647
|
+
let text = rest;
|
|
4648
|
+
if (text === "") {
|
|
4649
|
+
let j = headerIdx + 1;
|
|
4650
|
+
while (j < lines.length && cleanForScan(lines[j] ?? "") === "") j++;
|
|
4651
|
+
if (j >= lines.length) return null;
|
|
4652
|
+
startIdx = j;
|
|
4653
|
+
text = cleanForScan(lines[j] ?? "");
|
|
4654
|
+
}
|
|
4655
|
+
const kind = text.startsWith("(") ? "paren" : text.startsWith("[[") ? "test" : COMPOUND_BODY_START_RE.test(text) ? "keyword" : null;
|
|
4656
|
+
if (kind === null) return null;
|
|
4657
|
+
let depth = 0;
|
|
4658
|
+
const parens = kind === "paren" ? new SubshellParenScanner() : null;
|
|
4659
|
+
for (let k = startIdx; k < lines.length; k++) {
|
|
4660
|
+
const cur = k === startIdx ? text : cleanForScan(lines[k] ?? "");
|
|
4661
|
+
if (parens !== null) {
|
|
4662
|
+
if (parens.closes(cur)) return k + 1;
|
|
4663
|
+
} else if (kind === "test") {
|
|
4664
|
+
if (cur.includes("]]")) return k + 1;
|
|
4665
|
+
} else {
|
|
4666
|
+
depth += compoundDelta(cur);
|
|
4667
|
+
if (depth <= 0) return k + 1;
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
return null;
|
|
4671
|
+
}
|
|
3058
4672
|
function stripBashComment(line) {
|
|
3059
4673
|
for (let i = 0; i < line.length; i++) {
|
|
3060
4674
|
if (line[i] !== "#") continue;
|
|
@@ -3113,6 +4727,7 @@ function extractBash(content, filePath) {
|
|
|
3113
4727
|
let awaitingFunctionBrace = false;
|
|
3114
4728
|
let openFunctionIndex = null;
|
|
3115
4729
|
let openHeadingIndex = null;
|
|
4730
|
+
let skipUntil = 0;
|
|
3116
4731
|
for (let i = 0; i < lines.length; i++) {
|
|
3117
4732
|
const rawLine = lines[i] ?? "";
|
|
3118
4733
|
const lineNum = i + 1;
|
|
@@ -3120,7 +4735,7 @@ function extractBash(content, filePath) {
|
|
|
3120
4735
|
if (rawLine.trim() === heredocs[0]) heredocs.shift();
|
|
3121
4736
|
continue;
|
|
3122
4737
|
}
|
|
3123
|
-
if (!inFunction && braceDepth === 0) {
|
|
4738
|
+
if (!inFunction && braceDepth === 0 && lineNum > skipUntil) {
|
|
3124
4739
|
const banner = extractShellBannerHeading(rawLine);
|
|
3125
4740
|
if (banner !== null) {
|
|
3126
4741
|
if (openHeadingIndex !== null) {
|
|
@@ -3155,6 +4770,7 @@ function extractBash(content, filePath) {
|
|
|
3155
4770
|
const opened = findHeredocOpeners(noComment, arithmeticDepth);
|
|
3156
4771
|
arithmeticDepth = opened.depth;
|
|
3157
4772
|
heredocs.push(...opened.terminators);
|
|
4773
|
+
if (lineNum <= skipUntil) continue;
|
|
3158
4774
|
if (!stripped) continue;
|
|
3159
4775
|
if (!inFunction && !awaitingFunctionBrace && braceDepth === 0) {
|
|
3160
4776
|
const kwMatch = FUNC_KEYWORD_RE.exec(stripped);
|
|
@@ -3178,7 +4794,18 @@ function extractBash(content, filePath) {
|
|
|
3178
4794
|
pushedIndex = symbols.length;
|
|
3179
4795
|
symbols.push(makeLineSymbol(filePath, fname, "function", lineNum, stripped.slice(0, 200), void 0, lines, "hash"));
|
|
3180
4796
|
}
|
|
3181
|
-
|
|
4797
|
+
const rest = stripped.slice(funcMatch[0].length).trim();
|
|
4798
|
+
const compoundEnd = fname && !rest.startsWith("{") ? findCompoundBodyEnd(lines, i, rest) : null;
|
|
4799
|
+
if (compoundEnd !== null) {
|
|
4800
|
+
if (pushedIndex !== null) {
|
|
4801
|
+
const open = symbols[pushedIndex];
|
|
4802
|
+
if (open !== void 0 && compoundEnd > lineNum) {
|
|
4803
|
+
symbols[pushedIndex] = { ...open, lineEnd: compoundEnd, body: lines.slice(lineNum - 1, compoundEnd).join("\n") };
|
|
4804
|
+
}
|
|
4805
|
+
}
|
|
4806
|
+
skipUntil = compoundEnd;
|
|
4807
|
+
continue;
|
|
4808
|
+
} else if (fname) {
|
|
3182
4809
|
if (stripped.includes("{")) {
|
|
3183
4810
|
const braceLine2 = stripStringLiterals(stripped);
|
|
3184
4811
|
const openCount = (braceLine2.match(/\{/g) ?? []).length;
|
|
@@ -3292,7 +4919,7 @@ function maskContinuationAndDefines(text) {
|
|
|
3292
4919
|
}
|
|
3293
4920
|
return { noContinuation: contLines.join("\n"), forTargets: targetLines.join("\n") };
|
|
3294
4921
|
}
|
|
3295
|
-
var TARGET_RE = /^((?:[^\t\n#:=]|:(?=[\\/])|\\#)(?:[^:\n#=]|:(?=[\\/])|\\#)*):{1,2}(?![:=])\s*(?:[^=\n]|$)/gm;
|
|
4922
|
+
var TARGET_RE = /^((?:[^\t\n#:=]|:(?=[\\/])|\\#)(?:[^:\n#=]|:(?=[\\/])|\\#)*):{1,2}(?![:=])(?![ \t]*(?:(?:override|export|private)[ \t]+)*[^\s:=#]+[ \t]*(?:[?+!]|:{0,3})=)\s*(?:[^=\n]|$)/gm;
|
|
3296
4923
|
var DEFINE_RE2 = /^ *(?:(?:override|export|private)\s+)*define\s+([\w./%$()-]+)/gm;
|
|
3297
4924
|
var SPECIAL_TARGETS = /* @__PURE__ */ new Set([
|
|
3298
4925
|
".PHONY",
|
|
@@ -4028,12 +5655,12 @@ function extractApex(content, filePath) {
|
|
|
4028
5655
|
}
|
|
4029
5656
|
const typeNamesLower = /* @__PURE__ */ new Set();
|
|
4030
5657
|
for (const match of code.matchAll(TYPE_DECL_RE)) {
|
|
4031
|
-
const
|
|
5658
|
+
const typeKind2 = match[1] ?? "";
|
|
4032
5659
|
const name = match[2] ?? "";
|
|
4033
5660
|
const startOffset = match.index ?? 0;
|
|
4034
5661
|
const line = offsetToLine(lineIndex, startOffset);
|
|
4035
5662
|
const bodyStartLine = annotationStartLine(codeLines, line);
|
|
4036
|
-
const typeKindLower =
|
|
5663
|
+
const typeKindLower = typeKind2.toLowerCase();
|
|
4037
5664
|
const kind = typeKindLower === "class" ? "apex_class" : `apex_${typeKindLower}`;
|
|
4038
5665
|
typeNamesLower.add(name.toLowerCase());
|
|
4039
5666
|
emit2(name, kind, spanForMatch(content, code, lineIndex, startOffset, bodyStartLine, match[0]));
|
|
@@ -4090,36 +5717,52 @@ var FLOW_TAG_KIND = {
|
|
|
4090
5717
|
variables: "sf_flow_variable"
|
|
4091
5718
|
};
|
|
4092
5719
|
function xmlText(content, tag) {
|
|
4093
|
-
const
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
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);
|
|
4100
5729
|
}
|
|
4101
5730
|
function directChildText(content, tag) {
|
|
4102
|
-
const
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
)
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
const idx = cand.index ?? 0;
|
|
4109
|
-
let depth = 0;
|
|
4110
|
-
tagRe.lastIndex = 0;
|
|
4111
|
-
let t;
|
|
4112
|
-
while ((t = tagRe.exec(content)) !== null) {
|
|
4113
|
-
if (t.index >= idx) break;
|
|
4114
|
-
const closing = t[1] === "/";
|
|
4115
|
-
const selfClosing = t[3] === "/";
|
|
4116
|
-
if (selfClosing) continue;
|
|
4117
|
-
depth += closing ? -1 : 1;
|
|
4118
|
-
}
|
|
4119
|
-
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());
|
|
4120
5737
|
}
|
|
4121
5738
|
return null;
|
|
4122
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
|
+
}
|
|
4123
5766
|
function decodeXml(value) {
|
|
4124
5767
|
return value.replace(/'/g, "'").replace(/"/g, '"').replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&");
|
|
4125
5768
|
}
|
|
@@ -4139,8 +5782,7 @@ function wholeFileSpan(content) {
|
|
|
4139
5782
|
return {
|
|
4140
5783
|
startLine: 1,
|
|
4141
5784
|
endLine: lines.length > 1 && lines[lines.length - 1] === "" ? lines.length - 1 : lines.length,
|
|
4142
|
-
// File-level metadata symbols can be several megabytes (profiles are a common case).
|
|
4143
|
-
// 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.
|
|
4144
5786
|
body: ""
|
|
4145
5787
|
};
|
|
4146
5788
|
}
|
|
@@ -4154,11 +5796,13 @@ function spanFromOffsets(content, lineIndex, startOffset, endOffset) {
|
|
|
4154
5796
|
};
|
|
4155
5797
|
}
|
|
4156
5798
|
function rootElement(content) {
|
|
4157
|
-
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);
|
|
4158
5800
|
if (match === null) return null;
|
|
4159
5801
|
const root = match[1];
|
|
4160
5802
|
if (root === void 0) return null;
|
|
4161
|
-
|
|
5803
|
+
const gt = content.indexOf(">", match.index + match[0].length);
|
|
5804
|
+
if (gt < 0) return null;
|
|
5805
|
+
if (content[gt - 1] === "/") return root;
|
|
4162
5806
|
const close = new RegExp(`</(?:[A-Za-z_][\\w.-]*:)?${escapeRegExp(root)}\\s*>`, "i");
|
|
4163
5807
|
return close.test(content) ? root : null;
|
|
4164
5808
|
}
|
|
@@ -4176,14 +5820,10 @@ function metadataArtifactName(filePath) {
|
|
|
4176
5820
|
return match?.[1] ?? basenameWithout(filePath, "-meta.xml");
|
|
4177
5821
|
}
|
|
4178
5822
|
function elementBlocks(content, tag) {
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
return [...content.matchAll(re)].map((match) => ({
|
|
4184
|
-
inner: match[1] ?? "",
|
|
4185
|
-
offset: match.index ?? 0,
|
|
4186
|
-
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)
|
|
4187
5827
|
}));
|
|
4188
5828
|
}
|
|
4189
5829
|
function attributeValue(attributes, name) {
|
|
@@ -4191,11 +5831,33 @@ function attributeValue(attributes, name) {
|
|
|
4191
5831
|
return match?.[2] === void 0 ? null : decodeXml(match[2]);
|
|
4192
5832
|
}
|
|
4193
5833
|
function propertyElements(content) {
|
|
4194
|
-
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);
|
|
4195
5837
|
const out = [];
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
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;
|
|
4199
5861
|
}
|
|
4200
5862
|
return out;
|
|
4201
5863
|
}
|
|
@@ -4227,15 +5889,35 @@ function metadataName(filePath, content, suffix) {
|
|
|
4227
5889
|
function addFlowElements(symbols, seen, content, filePath, flowName) {
|
|
4228
5890
|
const lineIndex = buildLineIndex(content);
|
|
4229
5891
|
const tagAlternation = Object.keys(FLOW_TAG_KIND).join("|");
|
|
4230
|
-
const
|
|
4231
|
-
|
|
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) {
|
|
4232
5898
|
if (symbols.length >= MAX_SYMBOLS11) return;
|
|
4233
|
-
const tag =
|
|
4234
|
-
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();
|
|
4235
5919
|
const name = directChildText(inner, "name");
|
|
4236
5920
|
if (name === null || name === "") continue;
|
|
4237
|
-
const startOffset = match.index ?? 0;
|
|
4238
|
-
const endOffset = startOffset + match[0].length;
|
|
4239
5921
|
const span = spanFromOffsets(content, lineIndex, startOffset, endOffset);
|
|
4240
5922
|
const kind = FLOW_TAG_KIND[tag] ?? "sf_flow_element";
|
|
4241
5923
|
emit(symbols, seen, makeSpanSymbol(filePath, name, kind, span, flowName));
|
|
@@ -4446,11 +6128,33 @@ function blankJsStringLiterals(content) {
|
|
|
4446
6128
|
}
|
|
4447
6129
|
var FUNC_DECL_RE = /^(?:export\s+)?(?:default\s+)?(?:async\s+)?function\s*\*?\s+([A-Za-z_$][\w$]*)/;
|
|
4448
6130
|
var CONST_DECL_RE = /^(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*[:=]/;
|
|
4449
|
-
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*\()/;
|
|
6134
|
+
function declarationEndIdx(blanked, startIdx) {
|
|
6135
|
+
let depth = 0;
|
|
6136
|
+
for (let j = startIdx; j < blanked.length; j++) {
|
|
6137
|
+
const line = blanked[j] ?? "";
|
|
6138
|
+
for (const ch of line) {
|
|
6139
|
+
if (ch === "(" || ch === "[" || ch === "{") depth++;
|
|
6140
|
+
else if (ch === ")" || ch === "]" || ch === "}") depth--;
|
|
6141
|
+
}
|
|
6142
|
+
if (depth > 0) continue;
|
|
6143
|
+
let k = j + 1;
|
|
6144
|
+
while (k < blanked.length && (blanked[k] ?? "").trim() === "") k++;
|
|
6145
|
+
if (j === startIdx && (blanked[k] ?? "").trimStart().startsWith("{")) {
|
|
6146
|
+
j = k - 1;
|
|
6147
|
+
continue;
|
|
6148
|
+
}
|
|
6149
|
+
return j;
|
|
6150
|
+
}
|
|
6151
|
+
return startIdx;
|
|
6152
|
+
}
|
|
4450
6153
|
function extractTopLevelDeclarations(scriptContent, filePath, startLine) {
|
|
4451
6154
|
const symbols = [];
|
|
4452
6155
|
const commentFree = stripJsComments(scriptContent);
|
|
4453
6156
|
const lines = blankJsStringLiterals(commentFree).split("\n");
|
|
6157
|
+
const rawLines = scriptContent.split("\n");
|
|
4454
6158
|
let depth = 0;
|
|
4455
6159
|
for (let i = 0; i < lines.length; i++) {
|
|
4456
6160
|
const rawLine = lines[i] ?? "";
|
|
@@ -4458,16 +6162,16 @@ function extractTopLevelDeclarations(scriptContent, filePath, startLine) {
|
|
|
4458
6162
|
if (depth === 0 && trimmed) {
|
|
4459
6163
|
const line = startLine + i;
|
|
4460
6164
|
const fm = FUNC_DECL_RE.exec(trimmed);
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
}
|
|
6165
|
+
const cm = fm ? null : CONST_DECL_RE.exec(trimmed);
|
|
6166
|
+
const clm = fm || cm ? null : CLASS_DECL_RE.exec(trimmed);
|
|
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);
|
|
6170
|
+
if (name) {
|
|
6171
|
+
const kind = fm || am && am[1] === void 0 ? "sfc_script_function" : cm || dm ? "sfc_script_const" : "sfc_script_class";
|
|
6172
|
+
const sym = makeLineSymbol(filePath, name, kind, line);
|
|
6173
|
+
const endIdx = declarationEndIdx(lines, i);
|
|
6174
|
+
symbols.push(endIdx > i ? { ...sym, lineEnd: startLine + endIdx, body: rawLines.slice(i, endIdx + 1).join("\n") } : sym);
|
|
4471
6175
|
}
|
|
4472
6176
|
}
|
|
4473
6177
|
depth += (rawLine.match(/\{/g) ?? []).length - (rawLine.match(/\}/g) ?? []).length;
|
|
@@ -4495,19 +6199,14 @@ function extractComponentRefs(markup, filePath, startLine, allowKebab) {
|
|
|
4495
6199
|
}
|
|
4496
6200
|
function extractTagBlocks(content, lineIndex, tag) {
|
|
4497
6201
|
const masked = blankJsStringLiterals(content);
|
|
4498
|
-
const re = new RegExp(`<${tag}\\b([^>]*)>([\\s\\S]*?)<\\/${tag}\\s*>`, "gi");
|
|
4499
6202
|
const blocks = [];
|
|
4500
|
-
for (const
|
|
4501
|
-
const
|
|
4502
|
-
const attrs = m[1] ?? "";
|
|
4503
|
-
const innerLen = (m[2] ?? "").length;
|
|
4504
|
-
const openTagLen = 1 + tag.length + attrs.length + 1;
|
|
4505
|
-
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;
|
|
4506
6205
|
blocks.push({
|
|
4507
|
-
content: content.slice(innerStart,
|
|
6206
|
+
content: content.slice(innerStart, el.bodyEnd),
|
|
4508
6207
|
contentStartLine: offsetToLine(lineIndex, innerStart),
|
|
4509
|
-
matchStart,
|
|
4510
|
-
matchEnd:
|
|
6208
|
+
matchStart: el.start,
|
|
6209
|
+
matchEnd: el.end
|
|
4511
6210
|
});
|
|
4512
6211
|
}
|
|
4513
6212
|
return blocks;
|
|
@@ -5401,6 +7100,16 @@ function readToken4(masked, i) {
|
|
|
5401
7100
|
if (p === start) return void 0;
|
|
5402
7101
|
return { word: masked.slice(start, p), start, end: p };
|
|
5403
7102
|
}
|
|
7103
|
+
function readNameToken(masked, i) {
|
|
7104
|
+
let p = i;
|
|
7105
|
+
for (; ; ) {
|
|
7106
|
+
while (isSpace4(masked[p])) p++;
|
|
7107
|
+
if (masked[p] === "#" && masked[p + 1] === "^") p++;
|
|
7108
|
+
if (masked[p] !== "^") break;
|
|
7109
|
+
p = datumEnd2(masked, p + 1);
|
|
7110
|
+
}
|
|
7111
|
+
return readToken4(masked, p);
|
|
7112
|
+
}
|
|
5404
7113
|
function extractClojure(content, filePath) {
|
|
5405
7114
|
if (content.includes("\0")) return { symbols: [], imports: [] };
|
|
5406
7115
|
const rawLines = content.split(/\r?\n/);
|
|
@@ -5421,7 +7130,7 @@ function extractClojure(content, filePath) {
|
|
|
5421
7130
|
if (tok !== void 0) {
|
|
5422
7131
|
const kind = DEFINERS4.get(tok.word.toLowerCase());
|
|
5423
7132
|
if (kind !== void 0) {
|
|
5424
|
-
const nameTok =
|
|
7133
|
+
const nameTok = readNameToken(masked, tok.end);
|
|
5425
7134
|
const name = nameTok?.word.replace(/^:+/, "") ?? "";
|
|
5426
7135
|
const idx = spans.open(name, kind, lineOf(i), owner());
|
|
5427
7136
|
stack.push({ index: idx, depth });
|
|
@@ -5728,7 +7437,7 @@ function afterContext(rest) {
|
|
|
5728
7437
|
const arrow = rest.indexOf("=>");
|
|
5729
7438
|
return (arrow >= 0 ? rest.slice(arrow + 2) : rest).trimStart();
|
|
5730
7439
|
}
|
|
5731
|
-
function classify(line) {
|
|
7440
|
+
function classify(line, continued = false) {
|
|
5732
7441
|
let m;
|
|
5733
7442
|
if (m = /^module\s+([A-Za-z_][A-Za-z0-9_.']*)/.exec(line)) return [{ kind: "module", name: m[1] }];
|
|
5734
7443
|
if (m = /^(?:data|newtype)\s+(?:instance\s+)?([A-Z][A-Za-z0-9_']*)/.exec(line)) return [{ kind: "type", name: m[1] }];
|
|
@@ -5748,11 +7457,11 @@ function classify(line) {
|
|
|
5748
7457
|
if (m = /^\(([^()]+)\)\s*::/.exec(line)) return [{ kind: "function", name: m[1].trim() }];
|
|
5749
7458
|
if (m = /^([a-z_][A-Za-z0-9_']*)\b/.exec(line)) {
|
|
5750
7459
|
const name = m[1];
|
|
5751
|
-
if (!RESERVED_TOP.has(name) && hasTopLevelEquals(line)) return [{ kind: "function", name }];
|
|
7460
|
+
if (!RESERVED_TOP.has(name) && (continued || hasTopLevelEquals(line))) return [{ kind: "function", name }];
|
|
5752
7461
|
return void 0;
|
|
5753
7462
|
}
|
|
5754
7463
|
if (m = /^\(([^()]+)\)/.exec(line)) {
|
|
5755
|
-
if (hasTopLevelEquals(line)) return [{ kind: "function", name: m[1].trim() }];
|
|
7464
|
+
if (continued || hasTopLevelEquals(line)) return [{ kind: "function", name: m[1].trim() }];
|
|
5756
7465
|
}
|
|
5757
7466
|
return void 0;
|
|
5758
7467
|
}
|
|
@@ -5761,7 +7470,15 @@ function extractHaskell(content, filePath) {
|
|
|
5761
7470
|
const rawLines = content.split(/\r?\n/);
|
|
5762
7471
|
const masked = maskHaskell(content);
|
|
5763
7472
|
const maskedLines = masked.split(/\r?\n/);
|
|
5764
|
-
const n = rawLines.length;
|
|
7473
|
+
const n = rawLines.length > 1 && rawLines[rawLines.length - 1] === "" ? rawLines.length - 1 : rawLines.length;
|
|
7474
|
+
const headContinues = (idx) => {
|
|
7475
|
+
for (let j = idx + 1; j < n; j++) {
|
|
7476
|
+
if ((maskedLines[j] ?? "").trim() === "") continue;
|
|
7477
|
+
if (!/^\s/.test(rawLines[j] ?? "")) return false;
|
|
7478
|
+
return /^(?:\|(?!\|)|=(?![=>])|::)/.test((maskedLines[j] ?? "").trim());
|
|
7479
|
+
}
|
|
7480
|
+
return false;
|
|
7481
|
+
};
|
|
5765
7482
|
const boundaries = [];
|
|
5766
7483
|
for (let idx = 0; idx < n; idx++) {
|
|
5767
7484
|
const raw = rawLines[idx] ?? "";
|
|
@@ -5769,7 +7486,7 @@ function extractHaskell(content, filePath) {
|
|
|
5769
7486
|
const maskedLine = maskedLines[idx] ?? "";
|
|
5770
7487
|
const trimmed = maskedLine.trim();
|
|
5771
7488
|
if (trimmed === "") continue;
|
|
5772
|
-
const defs = classify(trimmed);
|
|
7489
|
+
const defs = classify(trimmed) ?? classify(trimmed, headContinues(idx));
|
|
5773
7490
|
if (defs === void 0) {
|
|
5774
7491
|
boundaries.push({ num: idx + 1, consumed: false });
|
|
5775
7492
|
continue;
|
|
@@ -5786,6 +7503,17 @@ function extractHaskell(content, filePath) {
|
|
|
5786
7503
|
boundaries[endIdx + 1].consumed = true;
|
|
5787
7504
|
endIdx++;
|
|
5788
7505
|
}
|
|
7506
|
+
if (boundaries.some((o, k) => k !== i && o.num === b.num && o.def?.kind === "function")) {
|
|
7507
|
+
let k = endIdx + 1;
|
|
7508
|
+
while (k < boundaries.length && boundaries[k].def?.kind === "function" && boundaries[k].def?.name !== b.def.name) k++;
|
|
7509
|
+
if (k < boundaries.length && boundaries[k].def?.kind === "function" && !boundaries[k].consumed) {
|
|
7510
|
+
while (k < boundaries.length && boundaries[k].def?.kind === "function" && boundaries[k].def?.name === b.def.name) {
|
|
7511
|
+
boundaries[k].consumed = true;
|
|
7512
|
+
endIdx = k;
|
|
7513
|
+
k++;
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
}
|
|
5789
7517
|
}
|
|
5790
7518
|
const next = boundaries[endIdx + 1];
|
|
5791
7519
|
const lineEnd = Math.max(b.num, next !== void 0 ? next.num - 1 : n);
|
|
@@ -5935,7 +7663,7 @@ function extractOcaml(content, filePath) {
|
|
|
5935
7663
|
const rawLines = content.split(/\r?\n/);
|
|
5936
7664
|
const masked = maskOcaml(content);
|
|
5937
7665
|
const maskedLines = masked.split(/\r?\n/);
|
|
5938
|
-
const n = rawLines.length;
|
|
7666
|
+
const n = rawLines.length > 1 && rawLines[rawLines.length - 1] === "" ? rawLines.length - 1 : rawLines.length;
|
|
5939
7667
|
const boundaries = [];
|
|
5940
7668
|
for (let idx = 0; idx < n; idx++) {
|
|
5941
7669
|
const raw = rawLines[idx] ?? "";
|
|
@@ -5943,6 +7671,7 @@ function extractOcaml(content, filePath) {
|
|
|
5943
7671
|
const maskedLine = maskedLines[idx] ?? "";
|
|
5944
7672
|
const trimmed = maskedLine.trim();
|
|
5945
7673
|
if (trimmed === "") continue;
|
|
7674
|
+
if (/^end\b/.test(trimmed)) continue;
|
|
5946
7675
|
const def = classify2(trimmed);
|
|
5947
7676
|
boundaries.push(def === void 0 ? { num: idx + 1 } : { num: idx + 1, def });
|
|
5948
7677
|
}
|
|
@@ -6296,12 +8025,17 @@ function sectionsToHeadingSymbols(sections, filePath) {
|
|
|
6296
8025
|
parent: ""
|
|
6297
8026
|
}));
|
|
6298
8027
|
}
|
|
8028
|
+
var CSHARP_SPAN_OPTS = { lineComment: "//", stringEscapes: "csharp", rawStringQuotes: true, expressionBodies: true, interpolation: "csharp" };
|
|
6299
8029
|
var ADAPTER_EXTRACTORS = {
|
|
6300
|
-
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
|
+
},
|
|
6301
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.
|
|
6302
8035
|
php: (content, filePath) => {
|
|
6303
8036
|
const code = maskPhpInlineHtml(content);
|
|
6304
|
-
|
|
8037
|
+
const { symbols, settled } = extractPhp(code, filePath);
|
|
8038
|
+
return spanUnsettled(symbols, settled, (rest) => assignBraceBlockSpans(rest, code, { lineComment: ["//", "#"], lineCommentExceptions: ["#["], multilineLang: "php" }));
|
|
6305
8039
|
},
|
|
6306
8040
|
html: (content, filePath) => {
|
|
6307
8041
|
const r = extractHtml(content, filePath);
|
|
@@ -6311,9 +8045,7 @@ var ADAPTER_EXTRACTORS = {
|
|
|
6311
8045
|
const r = extractLiquid(content, filePath);
|
|
6312
8046
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
6313
8047
|
},
|
|
6314
|
-
// The six template dialects mask their own delimiters out and hand off to extractHtml, so they
|
|
6315
|
-
// compose the same way html/liquid do above -- see templates_idx.ts's module doc for why this
|
|
6316
|
-
// 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.
|
|
6317
8049
|
jinja2: (content, filePath) => {
|
|
6318
8050
|
const r = extractJinja2(content, filePath);
|
|
6319
8051
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
@@ -6338,13 +8070,22 @@ var ADAPTER_EXTRACTORS = {
|
|
|
6338
8070
|
const r = extractTwig(content, filePath);
|
|
6339
8071
|
return [...r.symbols, ...sectionsToHeadingSymbols(r.sections, filePath)];
|
|
6340
8072
|
},
|
|
6341
|
-
kotlin: (content, filePath) =>
|
|
6342
|
-
|
|
6343
|
-
|
|
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
|
+
},
|
|
6344
8085
|
lua: (content, filePath) => extractLua(content, filePath).symbols,
|
|
6345
8086
|
vb: (content, filePath) => extractVb(content, filePath).symbols,
|
|
6346
8087
|
elixir: (content, filePath) => extractElixir(content, filePath).symbols,
|
|
6347
|
-
dart: (content, filePath) => assignBraceBlockSpans(extractDart(content, filePath).symbols, content, { lineComment: "//", nestedBlockComments: true, tripleQuote: true, tripleSingleQuote: true, tripleQuoteRunClose: "first" }),
|
|
8088
|
+
dart: (content, filePath) => assignBraceBlockSpans(extractDart(content, filePath).symbols, content, { lineComment: "//", nestedBlockComments: true, tripleQuote: true, tripleSingleQuote: true, tripleQuoteRunClose: "first", interpolation: "dart" }),
|
|
6348
8089
|
zig: (content, filePath) => assignBraceBlockSpans(extractZig(content, filePath).symbols, content, { lineComment: "//", blockComment: null, lineStringPrefix: "\\\\" }),
|
|
6349
8090
|
r: (content, filePath) => extractR(content, filePath).symbols,
|
|
6350
8091
|
graphql: (content, filePath) => extractGraphql(content, filePath).symbols,
|
|
@@ -6396,10 +8137,14 @@ var ADAPTER_EXTRACTORS = {
|
|
|
6396
8137
|
};
|
|
6397
8138
|
export {
|
|
6398
8139
|
ADAPTER_EXTRACTORS,
|
|
8140
|
+
CSHARP_SPAN_OPTS,
|
|
8141
|
+
assignBraceBlockSpans,
|
|
6399
8142
|
extractAstro,
|
|
6400
8143
|
extractCobol,
|
|
8144
|
+
extractCsharp,
|
|
6401
8145
|
extractNatural,
|
|
6402
8146
|
extractSalesforceMetadata,
|
|
6403
8147
|
extractSvelte,
|
|
6404
|
-
extractVue
|
|
8148
|
+
extractVue,
|
|
8149
|
+
spanUnsettled
|
|
6405
8150
|
};
|