pi-lens 4.4.1 → 4.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/config/dependency-cruiser-eager-allowlist.json +3 -1
- package/dist/{chunk-BJF25SUG.js → chunk-23WOO7TX.js} +11 -10
- package/dist/{chunk-WATC3IQR.js → chunk-2B73ZPOK.js} +3 -3
- package/dist/{chunk-N2IRDBZI.js → chunk-2BBLFX75.js} +101 -11
- package/dist/{chunk-TA5L5KWQ.js → chunk-2CD5RS6M.js} +2 -2
- package/dist/{chunk-3TTPKMEF.js → chunk-2VUQMUMT.js} +38 -37
- package/dist/{chunk-5JHXUETW.js → chunk-3EFKIGZN.js} +3 -3
- package/dist/chunk-3JNKMP3B.js +17 -0
- package/dist/{chunk-6P54TMWL.js → chunk-3VPVG5SU.js} +6 -6
- package/dist/{chunk-ZETYB3XG.js → chunk-3W7IEVVL.js} +44 -28
- package/dist/chunk-3YN6V5TV.js +85 -0
- package/dist/chunk-466Z26MG.js +30 -0
- package/dist/{chunk-PCHDGUKT.js → chunk-4UNXBNE2.js} +12 -11
- package/dist/{chunk-J7WJZ6W7.js → chunk-4W4VLAPJ.js} +12 -11
- package/dist/{chunk-F5VLZHUW.js → chunk-52FUZI6K.js} +4 -2
- package/dist/{chunk-H5EV3VMF.js → chunk-5NGR67U5.js} +2 -2
- package/dist/{chunk-CBD2B5CP.js → chunk-5UCAH366.js} +21 -20
- package/dist/{chunk-BHWHXMQ2.js → chunk-67WMNWEE.js} +9 -8
- package/dist/{chunk-USHG4DLH.js → chunk-6C7JWPCP.js} +7 -7
- package/dist/{chunk-VPWKF3GN.js → chunk-6GFRNVYR.js} +11 -10
- package/dist/{chunk-3JL6IFD7.js → chunk-6SDEP3AJ.js} +9 -8
- package/dist/{chunk-NJF2X5XF.js → chunk-6STA6Z7I.js} +19 -17
- package/dist/{chunk-KJCWXUUS.js → chunk-724UL2TJ.js} +6 -4
- package/dist/{chunk-MQA2YBAH.js → chunk-76MWC2K6.js} +3 -3
- package/dist/{chunk-YLN4K6WD.js → chunk-77M37OKR.js} +10 -8
- package/dist/{chunk-XHSCVSOL.js → chunk-7DYBLXYA.js} +3 -3
- package/dist/{chunk-OC7LYAU5.js → chunk-AB3YYG6N.js} +24 -10
- package/dist/{chunk-LD7WFTRX.js → chunk-ACXEQZOU.js} +16 -16
- package/dist/{chunk-VSMJK3ZJ.js → chunk-AOHZU2BM.js} +1 -1
- package/dist/{chunk-T4QZ6FEH.js → chunk-AW7R2GWG.js} +65 -8
- package/dist/{chunk-GAYGGICG.js → chunk-BKE7E7TC.js} +10 -9
- package/dist/{chunk-EUT3B22Y.js → chunk-BRGDSBJE.js} +13 -12
- package/dist/{chunk-T54VJRAD.js → chunk-C34ZXZ7O.js} +55 -11
- package/dist/{chunk-UGSMCQ4D.js → chunk-CHOW74WE.js} +1 -1
- package/dist/{chunk-H2W2AXD3.js → chunk-CMMHNUZ2.js} +66 -58
- package/dist/chunk-CSHFH5IN.js +17 -0
- package/dist/chunk-EC47DWFA.js +56 -0
- package/dist/{chunk-KJN4IOEJ.js → chunk-EJIUXPBX.js} +1 -1
- package/dist/{chunk-IQZXOZ7S.js → chunk-EU63SDCG.js} +720 -334
- package/dist/{chunk-LNOMA3MP.js → chunk-FCSOVF55.js} +107 -3
- package/dist/{chunk-CFYISHUW.js → chunk-FLKWCIZH.js} +8 -5
- package/dist/{chunk-OYTMZXRF.js → chunk-FMSO6RDZ.js} +16 -14
- package/dist/{chunk-IUKPRZER.js → chunk-GAEGEPOC.js} +2 -2
- package/dist/{chunk-6XX5HCLK.js → chunk-GBPP5P7X.js} +4 -4
- package/dist/{chunk-TQFBZVCG.js → chunk-GXW6K4YJ.js} +1 -1
- package/dist/{chunk-ZZUFZUQZ.js → chunk-H6MF6EVN.js} +331 -107
- package/dist/{chunk-3JSEWUWI.js → chunk-IBGIOBEE.js} +3 -3
- package/dist/chunk-IZSHAIJ7.js +26 -0
- package/dist/{chunk-7ELY2CSM.js → chunk-JAU72XNY.js} +16 -14
- package/dist/chunk-JMYYOTQG.js +77 -0
- package/dist/{chunk-ELVWJYRV.js → chunk-JSQFTSC6.js} +12 -11
- package/dist/{chunk-J6DFZDFA.js → chunk-KBG47GHP.js} +4 -4
- package/dist/chunk-KDERNTCQ.js +28 -0
- package/dist/chunk-KSX3TXSZ.js +69 -0
- package/dist/{chunk-XGUL4SLQ.js → chunk-L3BLXZG7.js} +2 -2
- package/dist/chunk-LOP6GRPH.js +31 -0
- package/dist/{chunk-MTDRLSI7.js → chunk-M6HSLBWY.js} +1064 -986
- package/dist/chunk-MQLUAEOC.js +162 -0
- package/dist/{chunk-3MRXIJ6I.js → chunk-MRXKYPCS.js} +2 -2
- package/dist/{chunk-D65GOCJB.js → chunk-MXGY6KPT.js} +19 -16
- package/dist/{chunk-G3RLJYA2.js → chunk-N2H3ZPZY.js} +47 -1
- package/dist/{chunk-HREZQCT3.js → chunk-N3X6Q4YT.js} +3 -3
- package/dist/{chunk-HSIRMK2D.js → chunk-OCAGUNBC.js} +15 -15
- package/dist/{chunk-ZOEYVXSV.js → chunk-OXXKQCSV.js} +6 -6
- package/dist/{chunk-S6AMWKPC.js → chunk-P7266HLM.js} +2 -2
- package/dist/{chunk-64LU2OVH.js → chunk-PHDMFAKM.js} +12 -2
- package/dist/{chunk-IMSQR4WO.js → chunk-PNQDPDRC.js} +1 -1
- package/dist/{chunk-IUR76K6A.js → chunk-Q7DUK4LX.js} +5 -5
- package/dist/{chunk-CULQYFLU.js → chunk-QGQ5CCCG.js} +2 -2
- package/dist/{chunk-UEAHAMEI.js → chunk-QHJ6DQ2R.js} +11 -11
- package/dist/{chunk-BNKLYOOO.js → chunk-QILIYSJF.js} +1 -1
- package/dist/{chunk-VYKKMYVT.js → chunk-QOBUHWHX.js} +11 -6
- package/dist/{chunk-3PNFWVHT.js → chunk-QQNQ7SJW.js} +2 -75
- package/dist/{chunk-7M4T5N3V.js → chunk-R3PCY3YS.js} +14 -13
- package/dist/{chunk-MGIWSROG.js → chunk-RPLINGVB.js} +7 -7
- package/dist/{chunk-CMU4RMJB.js → chunk-RWWYJ623.js} +10 -1
- package/dist/{chunk-3FERWMCH.js → chunk-RXCOMYPY.js} +27 -26
- package/dist/{chunk-7BX5DWSA.js → chunk-SAEFPSB6.js} +11 -11
- package/dist/{chunk-N7YNJE5R.js → chunk-SQ4TVJBR.js} +10 -10
- package/dist/{chunk-DMS52BEP.js → chunk-SS36ZX4J.js} +9 -7
- package/dist/{chunk-JONGANYH.js → chunk-T6CPIZNT.js} +32 -30
- package/dist/{chunk-6UYA642J.js → chunk-TYM6OUIT.js} +13 -12
- package/dist/{chunk-ALQRYH6O.js → chunk-UXGETRP4.js} +13 -12
- package/dist/{chunk-FGALODG3.js → chunk-UZ3TUTRV.js} +1 -1
- package/dist/{chunk-J3FZR3YY.js → chunk-VCHXCQFG.js} +3 -3
- package/dist/{chunk-3P4PF2BX.js → chunk-VCO24T4L.js} +34 -22
- package/dist/{chunk-O7HZX7CA.js → chunk-VRZP76YM.js} +1 -1
- package/dist/{chunk-VZHJS6DR.js → chunk-VSSBEUFT.js} +16 -15
- package/dist/{chunk-U52SAGRM.js → chunk-VWCXW2E7.js} +1 -1
- package/dist/{chunk-WW5BLB74.js → chunk-WOA4LN2R.js} +2 -2
- package/dist/{chunk-ZMOMPX2Z.js → chunk-WU567RSC.js} +11 -10
- package/dist/{chunk-N77WFUL7.js → chunk-XAGLWMJ4.js} +23 -22
- package/dist/{chunk-WSEWKCXU.js → chunk-XCJN5IJU.js} +4 -4
- package/dist/{chunk-IR6XFA5P.js → chunk-XIJZVPD5.js} +16 -14
- package/dist/{chunk-OYOB3ZFG.js → chunk-XMSXXAHW.js} +2 -2
- package/dist/{chunk-34OCDWOS.js → chunk-XTMJ7XDT.js} +1 -1
- package/dist/{chunk-Z6BB4JLQ.js → chunk-XVF2VVXP.js} +5 -3
- package/dist/{chunk-AFZYMAIV.js → chunk-YIUAVF7E.js} +37 -35
- package/dist/{chunk-NFXP47RV.js → chunk-YSZNHOBY.js} +85 -31
- package/dist/{chunk-V5MEBST3.js → chunk-YYOIQFRS.js} +21 -21
- package/dist/chunk-Z527N6YQ.js +28 -0
- package/dist/{chunk-D6YF5HKX.js → chunk-ZANLILYD.js} +22 -2
- package/dist/{chunk-2UMYMRI3.js → chunk-ZGDGW2V3.js} +2 -2
- package/dist/{chunk-6B5I6ICN.js → chunk-ZHFZWTZV.js} +12 -11
- package/dist/{chunk-OEX24ECI.js → chunk-ZWFS3OEF.js} +51 -41
- package/dist/{chunk-AXKPQ6ZI.js → chunk-ZXYDQ3TZ.js} +5 -5
- package/dist/index.js +73783 -71033
- package/dist/mcp/analyze-cli.js +18 -8
- package/dist/mcp/cli.js +48 -37
- package/dist/mcp/server.js +568 -397
- package/dist/mcp/worker.js +67 -55
- package/dist/probes/installer.js +20 -19
- package/docs/astplayground.md +1 -1
- package/docs/configuration.md +29 -0
- package/docs/dependencies.md +3 -0
- package/docs/features.md +2 -2
- package/docs/globalconfig.md +2 -0
- package/docs/language-coverage.md +2 -1
- package/docs/lsp-capability-matrix.md +29 -7
- package/docs/lsp-idle-eviction.md +38 -47
- package/docs/pi-lens-fixer.md +4 -0
- package/docs/pi-lens-merge-policy.md +17 -4
- package/docs/pi-lens-retro.md +2 -1
- package/docs/pi-lens-reviewer.md +18 -0
- package/docs/pi-lens-subagent.md +7 -0
- package/docs/real-harness.md +17 -0
- package/docs/schema/pi-lens-config-v1.json +37 -2
- package/docs/servercapabilities.md +15 -4
- package/docs/settings.md +2 -1
- package/package.json +1 -1
- package/dist/chunk-2FQ62SPM.js +0 -83
- package/dist/chunk-7AXO3ZDF.js +0 -30
- package/dist/chunk-KMGPUKFD.js +0 -25
- package/dist/chunk-OZJINN4O.js +0 -84
- package/dist/chunk-RJFED73B.js +0 -79
- package/dist/chunk-RTQNRM5X.js +0 -27
- package/dist/chunk-VGEVL5EQ.js +0 -29
- package/dist/chunk-WPE5FPGR.js +0 -54
- package/dist/chunk-Z7QQA2KT.js +0 -27
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import { createRequire as __pilensCreateRequire } from "node:module"; const require = __pilensCreateRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
emitBounded
|
|
4
|
-
} from "./chunk-OZJINN4O.js";
|
|
5
2
|
import {
|
|
6
3
|
createReadGuardEditBatchSummary,
|
|
7
4
|
getReadGuardCorrelationId,
|
|
@@ -9,7 +6,7 @@ import {
|
|
|
9
6
|
normalizeMessage,
|
|
10
7
|
sanitizeCorrelationId,
|
|
11
8
|
stableFindingId
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IBGIOBEE.js";
|
|
13
10
|
import {
|
|
14
11
|
mapWithConcurrency
|
|
15
12
|
} from "./chunk-XIMYZ3JA.js";
|
|
@@ -28,42 +25,57 @@ import {
|
|
|
28
25
|
isAuxiliary,
|
|
29
26
|
isDirectLspCommandTemporarilyUnavailable,
|
|
30
27
|
isOutsideAllSessionRoots,
|
|
28
|
+
isSameOrWithin,
|
|
29
|
+
refuseUntrustedLspExecution,
|
|
31
30
|
resetClassicTsRepairGuard,
|
|
32
31
|
resetLspLaunchAvailabilityGeneration,
|
|
32
|
+
resolveAnalysisRoot,
|
|
33
|
+
resolveAnalysisRootPath,
|
|
33
34
|
resolveLspServerCwd,
|
|
34
|
-
serverTraits
|
|
35
|
-
|
|
35
|
+
serverTraits,
|
|
36
|
+
withLspProjectCodePermission
|
|
37
|
+
} from "./chunk-EU63SDCG.js";
|
|
36
38
|
import {
|
|
37
39
|
findLocalOpengrepConfig
|
|
38
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-VWCXW2E7.js";
|
|
41
|
+
import {
|
|
42
|
+
emitBounded
|
|
43
|
+
} from "./chunk-FCSOVF55.js";
|
|
44
|
+
import {
|
|
45
|
+
loadProjectSnapshot,
|
|
46
|
+
readJsonCache
|
|
47
|
+
} from "./chunk-ZXYDQ3TZ.js";
|
|
39
48
|
import {
|
|
40
49
|
getSharedTreeSitterClient,
|
|
41
50
|
loadWebTreeSitter,
|
|
42
51
|
logTreeSitterDiagnostic,
|
|
43
52
|
resolveTreeSitterLanguage,
|
|
44
53
|
wasmQueryInput
|
|
45
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-QHJ6DQ2R.js";
|
|
46
55
|
import {
|
|
47
56
|
EXTENSION_TO_GRAMMAR,
|
|
48
57
|
EXTENSION_TO_LSP_ID,
|
|
49
58
|
KIND_TO_GRAMMAR
|
|
50
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-724UL2TJ.js";
|
|
51
60
|
import {
|
|
52
61
|
js_yaml_default
|
|
53
62
|
} from "./chunk-QOZXJ4NA.js";
|
|
54
63
|
import {
|
|
55
64
|
buildModuleGraph
|
|
56
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-GBPP5P7X.js";
|
|
66
|
+
import {
|
|
67
|
+
acquireWorkspaceSweepHold,
|
|
68
|
+
configureLspServiceLifecycle,
|
|
69
|
+
getOwnedLspService,
|
|
70
|
+
peekOwnedLspService,
|
|
71
|
+
resetOwnedLspService
|
|
72
|
+
} from "./chunk-MQLUAEOC.js";
|
|
57
73
|
import {
|
|
58
74
|
HOOK_WALL_BUDGET_MS,
|
|
59
75
|
bounded,
|
|
60
76
|
withDeadline,
|
|
61
77
|
withTimeout
|
|
62
|
-
} from "./chunk-
|
|
63
|
-
import {
|
|
64
|
-
loadProjectSnapshot,
|
|
65
|
-
readJsonCache
|
|
66
|
-
} from "./chunk-AXKPQ6ZI.js";
|
|
78
|
+
} from "./chunk-52FUZI6K.js";
|
|
67
79
|
import {
|
|
68
80
|
PathKeyedMap
|
|
69
81
|
} from "./chunk-Z3CCVDUB.js";
|
|
@@ -73,19 +85,18 @@ import {
|
|
|
73
85
|
requestWarmCodeActions,
|
|
74
86
|
requestWarmDiagnostics,
|
|
75
87
|
toRunnerDisplayPath
|
|
76
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-L3BLXZG7.js";
|
|
77
89
|
import {
|
|
78
90
|
findLocalZizmorConfig,
|
|
79
91
|
logSessionStart
|
|
80
|
-
} from "./chunk-
|
|
92
|
+
} from "./chunk-ACXEQZOU.js";
|
|
81
93
|
import {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} from "./chunk-D6YF5HKX.js";
|
|
94
|
+
findLocalBinUpwards,
|
|
95
|
+
isProjectLocalBinPath
|
|
96
|
+
} from "./chunk-AW7R2GWG.js";
|
|
86
97
|
import {
|
|
87
98
|
getLspCapableKinds
|
|
88
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-QOBUHWHX.js";
|
|
89
100
|
import {
|
|
90
101
|
createGenerationMap,
|
|
91
102
|
createGenerationSource,
|
|
@@ -104,22 +115,27 @@ import {
|
|
|
104
115
|
removeLspChild,
|
|
105
116
|
sampleProcessTreeCpuPercent,
|
|
106
117
|
selectLivePeerInstances
|
|
107
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-C34ZXZ7O.js";
|
|
108
119
|
import {
|
|
109
120
|
createSingleFlight
|
|
110
121
|
} from "./chunk-BW5KFIQC.js";
|
|
111
122
|
import {
|
|
112
123
|
SPECIAL_FILENAMES,
|
|
113
124
|
getLanguageId
|
|
114
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-PHDMFAKM.js";
|
|
115
126
|
import {
|
|
116
127
|
detectFileRole
|
|
117
|
-
} from "./chunk-
|
|
128
|
+
} from "./chunk-2BBLFX75.js";
|
|
118
129
|
import {
|
|
119
130
|
findGoverningTsconfigDir,
|
|
120
131
|
getDirectoryMarkers,
|
|
121
132
|
registerWorkspaceTopologyReset
|
|
122
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-XVF2VVXP.js";
|
|
134
|
+
import {
|
|
135
|
+
assertInstallAllowed,
|
|
136
|
+
isLspSpawnAllowedByTrust,
|
|
137
|
+
projectTrustDenialReason
|
|
138
|
+
} from "./chunk-ZANLILYD.js";
|
|
123
139
|
import {
|
|
124
140
|
writeFileAtomic
|
|
125
141
|
} from "./chunk-2EECBNC5.js";
|
|
@@ -128,15 +144,15 @@ import {
|
|
|
128
144
|
incrementDegradationCount,
|
|
129
145
|
recordDegradation,
|
|
130
146
|
recordDegradationOnce
|
|
131
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-JAU72XNY.js";
|
|
132
148
|
import {
|
|
133
149
|
logExtension
|
|
134
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-XTMJ7XDT.js";
|
|
135
151
|
import {
|
|
136
152
|
logLatency,
|
|
137
153
|
phaseFinished,
|
|
138
154
|
phaseStarted
|
|
139
|
-
} from "./chunk-
|
|
155
|
+
} from "./chunk-QQNQ7SJW.js";
|
|
140
156
|
import {
|
|
141
157
|
createNdjsonLogger,
|
|
142
158
|
getGlobalPiLensLogDir,
|
|
@@ -145,7 +161,7 @@ import {
|
|
|
145
161
|
isTestMode,
|
|
146
162
|
nextModuleEvaluationOrdinal,
|
|
147
163
|
toPositiveFinite
|
|
148
|
-
} from "./chunk-
|
|
164
|
+
} from "./chunk-AOHZU2BM.js";
|
|
149
165
|
import {
|
|
150
166
|
BoundedFifoMap,
|
|
151
167
|
BoundedLruCache,
|
|
@@ -165,7 +181,7 @@ import {
|
|
|
165
181
|
toProjectRelativePath,
|
|
166
182
|
uriToDiskPath,
|
|
167
183
|
uriToPath
|
|
168
|
-
} from "./chunk-
|
|
184
|
+
} from "./chunk-N2H3ZPZY.js";
|
|
169
185
|
import {
|
|
170
186
|
__commonJS,
|
|
171
187
|
__require,
|
|
@@ -716,7 +732,7 @@ var require_linkedMap = __commonJS({
|
|
|
716
732
|
return item.value;
|
|
717
733
|
}
|
|
718
734
|
forEach(callbackfn, thisArg) {
|
|
719
|
-
const
|
|
735
|
+
const state4 = this._state;
|
|
720
736
|
let current = this._head;
|
|
721
737
|
while (current) {
|
|
722
738
|
if (thisArg) {
|
|
@@ -724,21 +740,21 @@ var require_linkedMap = __commonJS({
|
|
|
724
740
|
} else {
|
|
725
741
|
callbackfn(current.value, current.key, this);
|
|
726
742
|
}
|
|
727
|
-
if (this._state !==
|
|
743
|
+
if (this._state !== state4) {
|
|
728
744
|
throw new Error(`LinkedMap got modified during iteration.`);
|
|
729
745
|
}
|
|
730
746
|
current = current.next;
|
|
731
747
|
}
|
|
732
748
|
}
|
|
733
749
|
keys() {
|
|
734
|
-
const
|
|
750
|
+
const state4 = this._state;
|
|
735
751
|
let current = this._head;
|
|
736
752
|
const iterator = {
|
|
737
753
|
[Symbol.iterator]: () => {
|
|
738
754
|
return iterator;
|
|
739
755
|
},
|
|
740
756
|
next: () => {
|
|
741
|
-
if (this._state !==
|
|
757
|
+
if (this._state !== state4) {
|
|
742
758
|
throw new Error(`LinkedMap got modified during iteration.`);
|
|
743
759
|
}
|
|
744
760
|
if (current) {
|
|
@@ -753,14 +769,14 @@ var require_linkedMap = __commonJS({
|
|
|
753
769
|
return iterator;
|
|
754
770
|
}
|
|
755
771
|
values() {
|
|
756
|
-
const
|
|
772
|
+
const state4 = this._state;
|
|
757
773
|
let current = this._head;
|
|
758
774
|
const iterator = {
|
|
759
775
|
[Symbol.iterator]: () => {
|
|
760
776
|
return iterator;
|
|
761
777
|
},
|
|
762
778
|
next: () => {
|
|
763
|
-
if (this._state !==
|
|
779
|
+
if (this._state !== state4) {
|
|
764
780
|
throw new Error(`LinkedMap got modified during iteration.`);
|
|
765
781
|
}
|
|
766
782
|
if (current) {
|
|
@@ -775,14 +791,14 @@ var require_linkedMap = __commonJS({
|
|
|
775
791
|
return iterator;
|
|
776
792
|
}
|
|
777
793
|
entries() {
|
|
778
|
-
const
|
|
794
|
+
const state4 = this._state;
|
|
779
795
|
let current = this._head;
|
|
780
796
|
const iterator = {
|
|
781
797
|
[Symbol.iterator]: () => {
|
|
782
798
|
return iterator;
|
|
783
799
|
},
|
|
784
800
|
next: () => {
|
|
785
|
-
if (this._state !==
|
|
801
|
+
if (this._state !== state4) {
|
|
786
802
|
throw new Error(`LinkedMap got modified during iteration.`);
|
|
787
803
|
}
|
|
788
804
|
if (current) {
|
|
@@ -1869,7 +1885,7 @@ var require_messageBuffer = __commonJS({
|
|
|
1869
1885
|
if (this._chunks.length === 0) {
|
|
1870
1886
|
return void 0;
|
|
1871
1887
|
}
|
|
1872
|
-
let
|
|
1888
|
+
let state4 = 0;
|
|
1873
1889
|
let chunkIndex = 0;
|
|
1874
1890
|
let offset = 0;
|
|
1875
1891
|
let chunkBytesRead = 0;
|
|
@@ -1880,39 +1896,39 @@ var require_messageBuffer = __commonJS({
|
|
|
1880
1896
|
const value = chunk[offset];
|
|
1881
1897
|
switch (value) {
|
|
1882
1898
|
case CR:
|
|
1883
|
-
switch (
|
|
1899
|
+
switch (state4) {
|
|
1884
1900
|
case 0:
|
|
1885
|
-
|
|
1901
|
+
state4 = 1;
|
|
1886
1902
|
break;
|
|
1887
1903
|
case 2:
|
|
1888
|
-
|
|
1904
|
+
state4 = 3;
|
|
1889
1905
|
break;
|
|
1890
1906
|
default:
|
|
1891
|
-
|
|
1907
|
+
state4 = 0;
|
|
1892
1908
|
}
|
|
1893
1909
|
break;
|
|
1894
1910
|
case LF:
|
|
1895
|
-
switch (
|
|
1911
|
+
switch (state4) {
|
|
1896
1912
|
case 1:
|
|
1897
|
-
|
|
1913
|
+
state4 = 2;
|
|
1898
1914
|
break;
|
|
1899
1915
|
case 3:
|
|
1900
|
-
|
|
1916
|
+
state4 = 4;
|
|
1901
1917
|
offset++;
|
|
1902
1918
|
break row;
|
|
1903
1919
|
default:
|
|
1904
|
-
|
|
1920
|
+
state4 = 0;
|
|
1905
1921
|
}
|
|
1906
1922
|
break;
|
|
1907
1923
|
default:
|
|
1908
|
-
|
|
1924
|
+
state4 = 0;
|
|
1909
1925
|
}
|
|
1910
1926
|
offset++;
|
|
1911
1927
|
}
|
|
1912
1928
|
chunkBytesRead += chunk.byteLength;
|
|
1913
1929
|
chunkIndex++;
|
|
1914
1930
|
}
|
|
1915
|
-
if (
|
|
1931
|
+
if (state4 !== 4) {
|
|
1916
1932
|
return void 0;
|
|
1917
1933
|
}
|
|
1918
1934
|
const buffer = this._read(chunkBytesRead + offset);
|
|
@@ -2286,7 +2302,7 @@ var require_connection = __commonJS({
|
|
|
2286
2302
|
let trace = Trace.Off;
|
|
2287
2303
|
let traceFormat = TraceFormat.Text;
|
|
2288
2304
|
let tracer;
|
|
2289
|
-
let
|
|
2305
|
+
let state4 = ConnectionState.New;
|
|
2290
2306
|
const errorEmitter = new events_1.Emitter();
|
|
2291
2307
|
const closeEmitter = new events_1.Emitter();
|
|
2292
2308
|
const unhandledNotificationEmitter = new events_1.Emitter();
|
|
@@ -2297,17 +2313,17 @@ var require_connection = __commonJS({
|
|
|
2297
2313
|
return void 0;
|
|
2298
2314
|
}
|
|
2299
2315
|
function isListening() {
|
|
2300
|
-
return
|
|
2316
|
+
return state4 === ConnectionState.Listening;
|
|
2301
2317
|
}
|
|
2302
2318
|
function isClosed() {
|
|
2303
|
-
return
|
|
2319
|
+
return state4 === ConnectionState.Closed;
|
|
2304
2320
|
}
|
|
2305
2321
|
function isDisposed() {
|
|
2306
|
-
return
|
|
2322
|
+
return state4 === ConnectionState.Disposed;
|
|
2307
2323
|
}
|
|
2308
2324
|
function closeHandler() {
|
|
2309
|
-
if (
|
|
2310
|
-
|
|
2325
|
+
if (state4 === ConnectionState.New || state4 === ConnectionState.Listening) {
|
|
2326
|
+
state4 = ConnectionState.Closed;
|
|
2311
2327
|
closeEmitter.fire(void 0);
|
|
2312
2328
|
}
|
|
2313
2329
|
}
|
|
@@ -3109,7 +3125,7 @@ ${JSON.stringify(message, null, 4)}`);
|
|
|
3109
3125
|
if (isDisposed()) {
|
|
3110
3126
|
return;
|
|
3111
3127
|
}
|
|
3112
|
-
|
|
3128
|
+
state4 = ConnectionState.Disposed;
|
|
3113
3129
|
disposeEmitter.fire(void 0);
|
|
3114
3130
|
const error = new messages_1.ResponseError(messages_1.ErrorCodes.PendingResponseRejected, "Pending response rejected since connection got disposed");
|
|
3115
3131
|
for (const promise of responsePromises.values()) {
|
|
@@ -3129,7 +3145,7 @@ ${JSON.stringify(message, null, 4)}`);
|
|
|
3129
3145
|
listen: () => {
|
|
3130
3146
|
throwIfClosedOrDisposed();
|
|
3131
3147
|
throwIfListening();
|
|
3132
|
-
|
|
3148
|
+
state4 = ConnectionState.Listening;
|
|
3133
3149
|
messageReader.listen(callback);
|
|
3134
3150
|
},
|
|
3135
3151
|
inspect: () => {
|
|
@@ -3969,13 +3985,11 @@ function demotePastEofDiagnostics(args) {
|
|
|
3969
3985
|
function resyncDocumentOnPastEof(filePath) {
|
|
3970
3986
|
void (async () => {
|
|
3971
3987
|
try {
|
|
3972
|
-
const [{
|
|
3973
|
-
import("./chunk-
|
|
3988
|
+
const [{ getOwnedLspService: getOwnedLspService2 }, content] = await Promise.all([
|
|
3989
|
+
import("./chunk-3JNKMP3B.js"),
|
|
3974
3990
|
fs.promises.readFile(filePath, "utf-8")
|
|
3975
3991
|
]);
|
|
3976
|
-
await
|
|
3977
|
-
preserveDiagnostics: false
|
|
3978
|
-
});
|
|
3992
|
+
await getOwnedLspService2().openFile(filePath, content, { preserveDiagnostics: false });
|
|
3979
3993
|
} catch {
|
|
3980
3994
|
}
|
|
3981
3995
|
})();
|
|
@@ -6118,6 +6132,7 @@ function state() {
|
|
|
6118
6132
|
secondarySessionCount: 0
|
|
6119
6133
|
}));
|
|
6120
6134
|
}
|
|
6135
|
+
var SUCCESSOR_HANDOFF_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
6121
6136
|
function getActiveSessionId() {
|
|
6122
6137
|
return state().activeSessionId;
|
|
6123
6138
|
}
|
|
@@ -6493,9 +6508,9 @@ var Scope = class {
|
|
|
6493
6508
|
}
|
|
6494
6509
|
};
|
|
6495
6510
|
function drawTicket() {
|
|
6496
|
-
const
|
|
6497
|
-
|
|
6498
|
-
return
|
|
6511
|
+
const state4 = registry();
|
|
6512
|
+
state4.nextTicket += 1;
|
|
6513
|
+
return state4.nextTicket;
|
|
6499
6514
|
}
|
|
6500
6515
|
function beginScope(args) {
|
|
6501
6516
|
return new Scope(args);
|
|
@@ -6510,9 +6525,9 @@ function moveBranch(scope) {
|
|
|
6510
6525
|
scope.moveBranch();
|
|
6511
6526
|
}
|
|
6512
6527
|
function nextOrderTurn() {
|
|
6513
|
-
const
|
|
6514
|
-
|
|
6515
|
-
return
|
|
6528
|
+
const state4 = registry();
|
|
6529
|
+
state4.orderTurn += 1;
|
|
6530
|
+
return state4.orderTurn;
|
|
6516
6531
|
}
|
|
6517
6532
|
function logScopeTransition(scope, args) {
|
|
6518
6533
|
logLatency({
|
|
@@ -7694,6 +7709,16 @@ Re-read the relevant section, then retry the edit using the current line range/c
|
|
|
7694
7709
|
this.touchFile(key);
|
|
7695
7710
|
return this.reads.get(key) ?? [];
|
|
7696
7711
|
}
|
|
7712
|
+
/**
|
|
7713
|
+
* Whether the current bytes still match the newest full-content read binding.
|
|
7714
|
+
* Undefined means this file has no full-content binding to compare; callers
|
|
7715
|
+
* must preserve their existing uncertainty wording in that case.
|
|
7716
|
+
*/
|
|
7717
|
+
contentMatchesLastRead(filePath) {
|
|
7718
|
+
const reads = this.getReadHistory(filePath);
|
|
7719
|
+
const binding = [...reads].reverse().find((read) => read.contentBinding?.fullFile)?.contentBinding;
|
|
7720
|
+
return binding === void 0 ? void 0 : currentContentMatchesBinding(filePath, binding);
|
|
7721
|
+
}
|
|
7697
7722
|
/**
|
|
7698
7723
|
* Session-lifetime record-cap trim totals for a file (#1913 review F1).
|
|
7699
7724
|
* `recordRead` only writes ONE `read_cap_trimmed` read-guard.log line per
|
|
@@ -7748,9 +7773,9 @@ Re-read the relevant section, then retry the edit using the current line range/c
|
|
|
7748
7773
|
* `sessionStartMs`) names no write, so it imports nothing. Null-safe on a
|
|
7749
7774
|
* malformed payload; never throws.
|
|
7750
7775
|
*/
|
|
7751
|
-
importAuthorship(
|
|
7776
|
+
importAuthorship(state4, onBranch) {
|
|
7752
7777
|
const result = { imported: 0, dropped: 0 };
|
|
7753
|
-
const authorship =
|
|
7778
|
+
const authorship = state4;
|
|
7754
7779
|
const entries = Array.isArray(authorship?.entries) ? authorship.entries : [];
|
|
7755
7780
|
const withEntry = /* @__PURE__ */ new Set();
|
|
7756
7781
|
for (const entry of entries) {
|
|
@@ -7855,13 +7880,13 @@ Re-read the relevant section, then retry the edit using the current line range/c
|
|
|
7855
7880
|
* payload loads as no reads and never throws — a throw here would abort
|
|
7856
7881
|
* the whole session_start rehydration.
|
|
7857
7882
|
*/
|
|
7858
|
-
importBranch(
|
|
7883
|
+
importBranch(state4, onBranch) {
|
|
7859
7884
|
const result = { imported: 0, dropped: 0 };
|
|
7860
|
-
if (!
|
|
7885
|
+
if (!state4 || state4.version !== READ_GUARD_STATE_VERSION)
|
|
7861
7886
|
return result;
|
|
7862
|
-
if (!Array.isArray(
|
|
7887
|
+
if (!Array.isArray(state4.reads))
|
|
7863
7888
|
return result;
|
|
7864
|
-
for (const entry of
|
|
7889
|
+
for (const entry of state4.reads) {
|
|
7865
7890
|
if (!Array.isArray(entry) || entry.length !== 2)
|
|
7866
7891
|
continue;
|
|
7867
7892
|
const [rawPath, records] = entry;
|
|
@@ -8421,21 +8446,21 @@ function readState(cwd) {
|
|
|
8421
8446
|
if (stateCache && stateCache.path === p && !stateCache.missing && stateCache.mtimeMs === stat2.mtimeMs && stateCache.size === stat2.size) {
|
|
8422
8447
|
return stateCache.state;
|
|
8423
8448
|
}
|
|
8424
|
-
let
|
|
8449
|
+
let state4;
|
|
8425
8450
|
try {
|
|
8426
8451
|
const parsed = JSON.parse(fs8.readFileSync(p, "utf-8"));
|
|
8427
|
-
|
|
8452
|
+
state4 = parsed && typeof parsed === "object" ? parsed : {};
|
|
8428
8453
|
} catch {
|
|
8429
|
-
|
|
8454
|
+
state4 = {};
|
|
8430
8455
|
}
|
|
8431
8456
|
stateCache = {
|
|
8432
8457
|
path: p,
|
|
8433
8458
|
missing: false,
|
|
8434
8459
|
mtimeMs: stat2.mtimeMs,
|
|
8435
8460
|
size: stat2.size,
|
|
8436
|
-
state:
|
|
8461
|
+
state: state4
|
|
8437
8462
|
};
|
|
8438
|
-
return
|
|
8463
|
+
return state4;
|
|
8439
8464
|
}
|
|
8440
8465
|
function getDisposition(cwd, anchor) {
|
|
8441
8466
|
return readState(cwd).dispositions?.[anchor];
|
|
@@ -8673,14 +8698,14 @@ function migrateEntryStamps(entries, recordTouchedAt) {
|
|
|
8673
8698
|
return rest.observedAt == null ? { ...rest, observedAt: recordTouchedAt } : rest;
|
|
8674
8699
|
});
|
|
8675
8700
|
}
|
|
8676
|
-
function importWidgetState(
|
|
8677
|
-
if (!
|
|
8701
|
+
function importWidgetState(state4) {
|
|
8702
|
+
if (!state4 || typeof state4.version !== "number" || state4.version < 1 || state4.version > WIDGET_STATE_VERSION) {
|
|
8678
8703
|
return false;
|
|
8679
8704
|
}
|
|
8680
8705
|
files.clear();
|
|
8681
8706
|
diagnosticsWriteGuard.clear();
|
|
8682
8707
|
runnerWriteGuard.clear();
|
|
8683
|
-
for (const f of
|
|
8708
|
+
for (const f of state4.files ?? []) {
|
|
8684
8709
|
const recordTouchedAt = f.touchedAt ?? Date.now();
|
|
8685
8710
|
const migratedAllDiagnostics = migrateEntryStamps(f.allDiagnostics, recordTouchedAt);
|
|
8686
8711
|
files.set(fileMapKey(f.filePath), {
|
|
@@ -8700,7 +8725,7 @@ function importWidgetState(state5) {
|
|
|
8700
8725
|
});
|
|
8701
8726
|
}
|
|
8702
8727
|
pruneInactiveFileRecords();
|
|
8703
|
-
sessionLanguages =
|
|
8728
|
+
sessionLanguages = state4.sessionLanguages ?? [];
|
|
8704
8729
|
requestRenderFn?.();
|
|
8705
8730
|
return true;
|
|
8706
8731
|
}
|
|
@@ -8716,12 +8741,12 @@ var widgetStore = defineSessionStore({
|
|
|
8716
8741
|
snapshot: () => exportWidgetState(),
|
|
8717
8742
|
restore: async (_scope, payload, ctx) => {
|
|
8718
8743
|
clearWidgetState();
|
|
8719
|
-
const
|
|
8720
|
-
if (!
|
|
8744
|
+
const state4 = payload;
|
|
8745
|
+
if (!state4?.files)
|
|
8721
8746
|
return { itemsIn: 0, itemsKept: 0 };
|
|
8722
|
-
const fresh = await dropStaleFiles(
|
|
8747
|
+
const fresh = await dropStaleFiles(state4, ctx.savedAt);
|
|
8723
8748
|
importWidgetState(fresh);
|
|
8724
|
-
return { itemsIn:
|
|
8749
|
+
return { itemsIn: state4.files.length, itemsKept: fresh.files.length };
|
|
8725
8750
|
},
|
|
8726
8751
|
reset: () => clearWidgetState(),
|
|
8727
8752
|
reason: "the diagnostics a conversation's edits produced, which a resume and a relaunch show again"
|
|
@@ -9662,94 +9687,6 @@ function isDeferredLspWorkArmed() {
|
|
|
9662
9687
|
return deferredController?.signal.aborted === false;
|
|
9663
9688
|
}
|
|
9664
9689
|
|
|
9665
|
-
// dist/clients/lsp/workspace-sweep-hold.js
|
|
9666
|
-
var SWEEP_IDLE_SAFETY_MARGIN_MS = 6e4;
|
|
9667
|
-
var WORKSPACE_SWEEP_HOLD_FAMILY = "lsp.workspace-sweep-hold";
|
|
9668
|
-
var WORKSPACE_SWEEP_HOLD_VERSION = 1;
|
|
9669
|
-
function state2() {
|
|
9670
|
-
return getProcessSingleton(WORKSPACE_SWEEP_HOLD_FAMILY, WORKSPACE_SWEEP_HOLD_VERSION, () => ({ holds: /* @__PURE__ */ new Map(), nextHoldId: 1, idleWaiters: [] }));
|
|
9671
|
-
}
|
|
9672
|
-
function flushIdleWaitersIfEmpty() {
|
|
9673
|
-
const current = state2();
|
|
9674
|
-
if (current.holds.size > 0)
|
|
9675
|
-
return;
|
|
9676
|
-
if (current.idleWaiters.length === 0)
|
|
9677
|
-
return;
|
|
9678
|
-
const waiters = current.idleWaiters;
|
|
9679
|
-
current.idleWaiters = [];
|
|
9680
|
-
for (const waiter of waiters) {
|
|
9681
|
-
try {
|
|
9682
|
-
waiter();
|
|
9683
|
-
} catch {
|
|
9684
|
-
}
|
|
9685
|
-
}
|
|
9686
|
-
}
|
|
9687
|
-
function getWorkspaceSweepMaxHoldAgeMs() {
|
|
9688
|
-
return getFullScanWallClockMs() + SWEEP_IDLE_SAFETY_MARGIN_MS;
|
|
9689
|
-
}
|
|
9690
|
-
function reapStaleHolds() {
|
|
9691
|
-
const current = state2();
|
|
9692
|
-
if (current.holds.size === 0)
|
|
9693
|
-
return;
|
|
9694
|
-
const maxAgeMs = getWorkspaceSweepMaxHoldAgeMs();
|
|
9695
|
-
const now = Date.now();
|
|
9696
|
-
for (const [holdId, acquiredAt] of current.holds) {
|
|
9697
|
-
const ageMs = now - acquiredAt;
|
|
9698
|
-
if (ageMs <= maxAgeMs)
|
|
9699
|
-
continue;
|
|
9700
|
-
current.holds.delete(holdId);
|
|
9701
|
-
logLatency({
|
|
9702
|
-
type: "phase",
|
|
9703
|
-
phase: "lsp_workspace_sweep_hold_force_released",
|
|
9704
|
-
filePath: "",
|
|
9705
|
-
durationMs: ageMs,
|
|
9706
|
-
metadata: { holdId, maxHoldAgeMs: maxAgeMs }
|
|
9707
|
-
});
|
|
9708
|
-
}
|
|
9709
|
-
flushIdleWaitersIfEmpty();
|
|
9710
|
-
}
|
|
9711
|
-
function acquireWorkspaceSweepHold() {
|
|
9712
|
-
const current = state2();
|
|
9713
|
-
const holdId = current.nextHoldId++;
|
|
9714
|
-
current.holds.set(holdId, Date.now());
|
|
9715
|
-
return () => {
|
|
9716
|
-
if (!state2().holds.delete(holdId))
|
|
9717
|
-
return;
|
|
9718
|
-
flushIdleWaitersIfEmpty();
|
|
9719
|
-
};
|
|
9720
|
-
}
|
|
9721
|
-
function isWorkspaceSweepActive() {
|
|
9722
|
-
reapStaleHolds();
|
|
9723
|
-
return state2().holds.size > 0;
|
|
9724
|
-
}
|
|
9725
|
-
function runWhenWorkspaceSweepIdle(cb) {
|
|
9726
|
-
reapStaleHolds();
|
|
9727
|
-
const current = state2();
|
|
9728
|
-
if (current.holds.size === 0) {
|
|
9729
|
-
cb();
|
|
9730
|
-
return;
|
|
9731
|
-
}
|
|
9732
|
-
current.idleWaiters.push(cb);
|
|
9733
|
-
}
|
|
9734
|
-
function clearWorkspaceSweepHoldForSessionStart() {
|
|
9735
|
-
const current = state2();
|
|
9736
|
-
if (current.holds.size === 0)
|
|
9737
|
-
return;
|
|
9738
|
-
logLatency({
|
|
9739
|
-
type: "phase",
|
|
9740
|
-
phase: "lsp_workspace_sweep_hold_session_reset",
|
|
9741
|
-
filePath: "",
|
|
9742
|
-
durationMs: 0,
|
|
9743
|
-
metadata: { clearedHolds: current.holds.size }
|
|
9744
|
-
});
|
|
9745
|
-
current.holds.clear();
|
|
9746
|
-
flushIdleWaitersIfEmpty();
|
|
9747
|
-
}
|
|
9748
|
-
function getFullScanWallClockMs() {
|
|
9749
|
-
const raw = Number(process.env.PI_LENS_LENS_DIAGNOSTICS_FULL_TIMEOUT_MS);
|
|
9750
|
-
return Number.isFinite(raw) && raw > 0 ? raw : 3e5;
|
|
9751
|
-
}
|
|
9752
|
-
|
|
9753
9690
|
// dist/clients/lsp/document-drift.js
|
|
9754
9691
|
import { createHash as createHash5 } from "node:crypto";
|
|
9755
9692
|
import nodeFs from "node:fs";
|
|
@@ -10303,7 +10240,7 @@ var OpaqueBaselineStore = class _OpaqueBaselineStore {
|
|
|
10303
10240
|
* for a call a `tool_call` handler blocked or Escape aborted before it ran,
|
|
10304
10241
|
* and on a non-git project the entry holds a whole-tree stat snapshot.
|
|
10305
10242
|
*/
|
|
10306
|
-
record(slot, callId,
|
|
10243
|
+
record(slot, callId, state4, turn) {
|
|
10307
10244
|
for (const [staleKey, entry] of this.pending.entriesArray())
|
|
10308
10245
|
if (entry.turn && !entry.turn.isLive(entry.turn.key)) {
|
|
10309
10246
|
this.pending.delete(staleKey);
|
|
@@ -10311,7 +10248,7 @@ var OpaqueBaselineStore = class _OpaqueBaselineStore {
|
|
|
10311
10248
|
}
|
|
10312
10249
|
const key = _OpaqueBaselineStore.keyOf(slot, callId);
|
|
10313
10250
|
const overwrote = this.pending.delete(key);
|
|
10314
|
-
const evicted = this.pending.set(key, { state:
|
|
10251
|
+
const evicted = this.pending.set(key, { state: state4, turn });
|
|
10315
10252
|
if (overwrote)
|
|
10316
10253
|
recordBaselineLoss("overwrite");
|
|
10317
10254
|
if (evicted.length > 0)
|
|
@@ -10368,7 +10305,7 @@ var OBSERVED_PENDING_MAX = 32;
|
|
|
10368
10305
|
var OBSERVED_LEDGER_MAX = 1e3;
|
|
10369
10306
|
var OBSERVED_FAMILY = "observed-mutation-net";
|
|
10370
10307
|
var OBSERVED_VERSION = 4;
|
|
10371
|
-
function
|
|
10308
|
+
function state2() {
|
|
10372
10309
|
return getProcessSingleton(OBSERVED_FAMILY, OBSERVED_VERSION, () => ({
|
|
10373
10310
|
pending: new BoundedFifoMap(OBSERVED_PENDING_MAX),
|
|
10374
10311
|
ledger: new BoundedFifoMap(OBSERVED_LEDGER_MAX),
|
|
@@ -10380,7 +10317,7 @@ function state3() {
|
|
|
10380
10317
|
}));
|
|
10381
10318
|
}
|
|
10382
10319
|
function resetObservedMutationNet() {
|
|
10383
|
-
const current =
|
|
10320
|
+
const current = state2();
|
|
10384
10321
|
current.pending.clear();
|
|
10385
10322
|
current.ledger.clear();
|
|
10386
10323
|
current.handled.clear();
|
|
@@ -10391,7 +10328,7 @@ function resetObservedMutationNet() {
|
|
|
10391
10328
|
}
|
|
10392
10329
|
function noteMutationHandled(filePath) {
|
|
10393
10330
|
try {
|
|
10394
|
-
const handled =
|
|
10331
|
+
const handled = state2().handled;
|
|
10395
10332
|
const key = normalizeMapKey(path10.resolve(filePath));
|
|
10396
10333
|
const evicted = handled.add(key);
|
|
10397
10334
|
for (const oldest of evicted) {
|
|
@@ -10410,7 +10347,7 @@ function noteMutationHandled(filePath) {
|
|
|
10410
10347
|
{
|
|
10411
10348
|
ledgerKind: "observed-mutation-budget",
|
|
10412
10349
|
reason: `the handled set is full at ${OBSERVED_HANDLED_MAX}; the oldest pi-lens-authored file lost its mark, so its next drift is reported as third-party`,
|
|
10413
|
-
capPerTurn: { limit: 2, turnIndex:
|
|
10350
|
+
capPerTurn: { limit: 2, turnIndex: state2().turnIndex }
|
|
10414
10351
|
}
|
|
10415
10352
|
);
|
|
10416
10353
|
}
|
|
@@ -10591,6 +10528,9 @@ function bookkeepLspMutation(context, files2, fileDetails) {
|
|
|
10591
10528
|
authorshipUnknown: true
|
|
10592
10529
|
},
|
|
10593
10530
|
...editRanges !== void 0 ? { editRanges } : {},
|
|
10531
|
+
...context.sessionId !== void 0 && {
|
|
10532
|
+
sessionId: context.sessionId
|
|
10533
|
+
},
|
|
10594
10534
|
consumer: context.tool,
|
|
10595
10535
|
provenance: "observed",
|
|
10596
10536
|
// Real value threaded through, not the bridge's own
|
|
@@ -10632,7 +10572,7 @@ function bookkeepLspMutation(context, files2, fileDetails) {
|
|
|
10632
10572
|
detail.range ?? { start: 1, end: 1 },
|
|
10633
10573
|
detail.importsChanged ?? true,
|
|
10634
10574
|
context.cwd,
|
|
10635
|
-
runtime?.telemetrySessionId,
|
|
10575
|
+
context.sessionId ?? runtime?.telemetrySessionId,
|
|
10636
10576
|
void 0,
|
|
10637
10577
|
// #2504 review round 2 (F1). #2504 added a containment
|
|
10638
10578
|
// filter to `addModifiedRange` and gave it `cwd` as the
|
|
@@ -11615,11 +11555,11 @@ async function preflightWorkspaceEdit(planned, cwd, options) {
|
|
|
11615
11555
|
virtual.set(key, value);
|
|
11616
11556
|
return value;
|
|
11617
11557
|
};
|
|
11618
|
-
const contentFor = async (filePath,
|
|
11619
|
-
if (!
|
|
11558
|
+
const contentFor = async (filePath, state4) => {
|
|
11559
|
+
if (!state4.exists || state4.directory)
|
|
11620
11560
|
throw new Error(`text edit target is not a file: ${filePath}`);
|
|
11621
|
-
if (
|
|
11622
|
-
return
|
|
11561
|
+
if (state4.content !== void 0)
|
|
11562
|
+
return state4.content;
|
|
11623
11563
|
const physicalPath = resolveVirtualPath(filePath);
|
|
11624
11564
|
if (!physicalPath)
|
|
11625
11565
|
throw new Error(`text edit target does not exist: ${filePath}`);
|
|
@@ -11628,50 +11568,50 @@ async function preflightWorkspaceEdit(planned, cwd, options) {
|
|
|
11628
11568
|
if (expected !== void 0 && expected !== content) {
|
|
11629
11569
|
refuseStaleWorkspaceEdit(filePath, "the file changed after the edit was computed from it");
|
|
11630
11570
|
}
|
|
11631
|
-
|
|
11571
|
+
state4.content = content;
|
|
11632
11572
|
return content;
|
|
11633
11573
|
};
|
|
11634
11574
|
for (const op of planned) {
|
|
11635
11575
|
if (op.kind === "text") {
|
|
11636
11576
|
const filePath2 = await confine(op.uri);
|
|
11637
|
-
const
|
|
11577
|
+
const state5 = await stateFor(filePath2);
|
|
11638
11578
|
if (op.version !== void 0 && op.version !== null) {
|
|
11639
11579
|
const current = options.documentVersions?.get(normalizeMapKey(filePath2));
|
|
11640
11580
|
if (current === void 0 || current !== op.version)
|
|
11641
11581
|
throw new Error(`stale text document version for ${filePath2}: expected ${op.version}, current ${current ?? "unknown"}`);
|
|
11642
11582
|
}
|
|
11643
|
-
const content = await contentFor(filePath2,
|
|
11583
|
+
const content = await contentFor(filePath2, state5);
|
|
11644
11584
|
const encoding = options.positionEncoding ?? "utf-16";
|
|
11645
11585
|
const normalized = normalizeTextEditsForContent(content, op.edits, encoding);
|
|
11646
11586
|
text.set(op, normalized);
|
|
11647
11587
|
for (const origin of op.origins ?? []) {
|
|
11648
11588
|
textByOrigin.set(textEditOriginKey(origin), normalizeTextEditsForContent(content, origin.edits, encoding));
|
|
11649
11589
|
}
|
|
11650
|
-
|
|
11590
|
+
state5.content = applyTextEditsToString(content, normalized);
|
|
11651
11591
|
continue;
|
|
11652
11592
|
}
|
|
11653
11593
|
if (op.kind === "create") {
|
|
11654
11594
|
const filePath2 = await confine(op.uri);
|
|
11655
|
-
const
|
|
11595
|
+
const state5 = await stateFor(filePath2);
|
|
11656
11596
|
await assertParentIsUsable(filePath2, stateFor);
|
|
11657
|
-
if (
|
|
11597
|
+
if (state5.exists) {
|
|
11658
11598
|
if (op.options?.ignoreIfExists) {
|
|
11659
11599
|
ignored.add(op);
|
|
11660
11600
|
continue;
|
|
11661
11601
|
}
|
|
11662
|
-
if (!op.options?.overwrite ||
|
|
11602
|
+
if (!op.options?.overwrite || state5.directory)
|
|
11663
11603
|
throw new Error(`create target already exists: ${filePath2}`);
|
|
11664
|
-
|
|
11604
|
+
state5.content = "";
|
|
11665
11605
|
} else {
|
|
11666
11606
|
clearTombstonesUnder(filePath2);
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11607
|
+
state5.exists = true;
|
|
11608
|
+
state5.directory = false;
|
|
11609
|
+
state5.content = "";
|
|
11670
11610
|
const physicalPath = resolveVirtualPath(filePath2);
|
|
11671
11611
|
if (physicalPath)
|
|
11672
|
-
virtual.set(normalizeMapKey(physicalPath),
|
|
11612
|
+
virtual.set(normalizeMapKey(physicalPath), state5);
|
|
11673
11613
|
else
|
|
11674
|
-
virtualOverrides.set(normalizeMapKey(filePath2),
|
|
11614
|
+
virtualOverrides.set(normalizeMapKey(filePath2), state5);
|
|
11675
11615
|
}
|
|
11676
11616
|
continue;
|
|
11677
11617
|
}
|
|
@@ -11720,18 +11660,18 @@ async function preflightWorkspaceEdit(planned, cwd, options) {
|
|
|
11720
11660
|
continue;
|
|
11721
11661
|
}
|
|
11722
11662
|
const filePath = await confine(op.uri);
|
|
11723
|
-
const
|
|
11724
|
-
if (!
|
|
11663
|
+
const state4 = await stateFor(filePath);
|
|
11664
|
+
if (!state4.exists) {
|
|
11725
11665
|
if (op.options?.ignoreIfNotExists)
|
|
11726
11666
|
ignored.add(op);
|
|
11727
11667
|
else
|
|
11728
11668
|
throw new Error(`delete target does not exist: ${filePath}`);
|
|
11729
11669
|
} else {
|
|
11730
|
-
if (
|
|
11670
|
+
if (state4.directory && !op.options?.recursive)
|
|
11731
11671
|
throw new Error(`delete directory requires recursive: ${filePath}`);
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
virtualTombstones.push({ path: filePath, directory:
|
|
11672
|
+
state4.exists = false;
|
|
11673
|
+
state4.content = void 0;
|
|
11674
|
+
virtualTombstones.push({ path: filePath, directory: state4.directory });
|
|
11735
11675
|
}
|
|
11736
11676
|
}
|
|
11737
11677
|
return { text, textByOrigin, ignored };
|
|
@@ -12751,16 +12691,16 @@ var ACTIVE_CLIENTS_VERSION = 1;
|
|
|
12751
12691
|
function activeLspClientSet() {
|
|
12752
12692
|
return getProcessSingleton(ACTIVE_CLIENTS_FAMILY, ACTIVE_CLIENTS_VERSION, () => /* @__PURE__ */ new Set());
|
|
12753
12693
|
}
|
|
12754
|
-
function isClientAlive(
|
|
12755
|
-
return
|
|
12694
|
+
function isClientAlive(state4) {
|
|
12695
|
+
return state4.isConnected && !state4.isDestroyed && !state4.lspProcess.process.killed;
|
|
12756
12696
|
}
|
|
12757
|
-
function disposeClientConnection(
|
|
12758
|
-
if (
|
|
12697
|
+
function disposeClientConnection(state4) {
|
|
12698
|
+
if (state4.connectionDisposed)
|
|
12759
12699
|
return;
|
|
12760
|
-
|
|
12761
|
-
activeLspClientSet().delete(
|
|
12700
|
+
state4.connectionDisposed = true;
|
|
12701
|
+
activeLspClientSet().delete(state4);
|
|
12762
12702
|
try {
|
|
12763
|
-
|
|
12703
|
+
state4.connection.dispose();
|
|
12764
12704
|
} catch {
|
|
12765
12705
|
}
|
|
12766
12706
|
}
|
|
@@ -12929,66 +12869,66 @@ function mergeDiagnosticLists(...lists) {
|
|
|
12929
12869
|
}
|
|
12930
12870
|
return merged;
|
|
12931
12871
|
}
|
|
12932
|
-
function getMergedDiagnosticsForPath(
|
|
12933
|
-
const legacy =
|
|
12934
|
-
return mergeDiagnosticLists(
|
|
12872
|
+
function getMergedDiagnosticsForPath(state4, normalizedPath) {
|
|
12873
|
+
const legacy = state4;
|
|
12874
|
+
return mergeDiagnosticLists(state4.pushDiagnostics?.get(normalizedPath) ?? legacy.diagnostics?.get(normalizedPath), state4.documentPullDiagnostics?.get(normalizedPath));
|
|
12935
12875
|
}
|
|
12936
12876
|
var PULL_SOURCE_KEY_SEPARATOR = "\0";
|
|
12937
12877
|
var BARE_PULL_SOURCE = "";
|
|
12938
12878
|
function pullSourceKey(normalizedPath, identifier) {
|
|
12939
12879
|
return identifier === void 0 ? normalizedPath : `${normalizedPath}${PULL_SOURCE_KEY_SEPARATOR}${identifier}`;
|
|
12940
12880
|
}
|
|
12941
|
-
function pullSourceKeysForPath(
|
|
12881
|
+
function pullSourceKeysForPath(state4, normalizedPath) {
|
|
12942
12882
|
const prefix = `${normalizedPath}${PULL_SOURCE_KEY_SEPARATOR}`;
|
|
12943
12883
|
return [
|
|
12944
12884
|
normalizedPath,
|
|
12945
|
-
...[...
|
|
12885
|
+
...[...state4.pullResultIds?.keys() ?? []].filter((key) => key.startsWith(prefix))
|
|
12946
12886
|
];
|
|
12947
12887
|
}
|
|
12948
|
-
function pullSourcesFor(
|
|
12949
|
-
if (!
|
|
12950
|
-
|
|
12888
|
+
function pullSourcesFor(state4, normalizedPath) {
|
|
12889
|
+
if (!state4.documentPullDiagnosticsBySource) {
|
|
12890
|
+
state4.documentPullDiagnosticsBySource = /* @__PURE__ */ new Map();
|
|
12951
12891
|
}
|
|
12952
|
-
let sources =
|
|
12892
|
+
let sources = state4.documentPullDiagnosticsBySource.get(normalizedPath);
|
|
12953
12893
|
if (!sources) {
|
|
12954
12894
|
sources = /* @__PURE__ */ new Map();
|
|
12955
|
-
|
|
12895
|
+
state4.documentPullDiagnosticsBySource.set(normalizedPath, sources);
|
|
12956
12896
|
}
|
|
12957
12897
|
return sources;
|
|
12958
12898
|
}
|
|
12959
|
-
function pullSourceDiagnostics(
|
|
12960
|
-
const sources =
|
|
12899
|
+
function pullSourceDiagnostics(state4, normalizedPath, identifier) {
|
|
12900
|
+
const sources = state4.documentPullDiagnosticsBySource?.get(normalizedPath);
|
|
12961
12901
|
const stored = sources?.get(identifier ?? BARE_PULL_SOURCE);
|
|
12962
12902
|
if (stored)
|
|
12963
12903
|
return stored;
|
|
12964
|
-
return sources && sources.size > 0 ? [] :
|
|
12904
|
+
return sources && sources.size > 0 ? [] : state4.documentPullDiagnostics.get(normalizedPath) ?? [];
|
|
12965
12905
|
}
|
|
12966
|
-
function storePullSourceDiagnostics(
|
|
12967
|
-
const sources = pullSourcesFor(
|
|
12906
|
+
function storePullSourceDiagnostics(state4, normalizedPath, identifier, diagnostics) {
|
|
12907
|
+
const sources = pullSourcesFor(state4, normalizedPath);
|
|
12968
12908
|
sources.set(identifier ?? BARE_PULL_SOURCE, diagnostics);
|
|
12969
|
-
|
|
12909
|
+
state4.documentPullDiagnostics.set(normalizedPath, mergeDiagnosticLists(...sources.values()));
|
|
12970
12910
|
}
|
|
12971
|
-
function pullGenerationFor(
|
|
12972
|
-
return
|
|
12911
|
+
function pullGenerationFor(state4, normalizedPath) {
|
|
12912
|
+
return state4.pullGenerations?.get(normalizedPath) ?? 0;
|
|
12973
12913
|
}
|
|
12974
|
-
function bumpPullGeneration(
|
|
12975
|
-
if (!
|
|
12976
|
-
|
|
12977
|
-
|
|
12914
|
+
function bumpPullGeneration(state4, normalizedPath) {
|
|
12915
|
+
if (!state4.pullGenerations)
|
|
12916
|
+
state4.pullGenerations = /* @__PURE__ */ new Map();
|
|
12917
|
+
state4.pullGenerations.set(normalizedPath, (state4.pullGenerations.get(normalizedPath) ?? 0) + 1);
|
|
12978
12918
|
}
|
|
12979
|
-
function claimPullRequestSequence(
|
|
12980
|
-
if (!
|
|
12981
|
-
|
|
12982
|
-
const next = (
|
|
12983
|
-
|
|
12919
|
+
function claimPullRequestSequence(state4, sourceKey) {
|
|
12920
|
+
if (!state4.pullRequestSequences)
|
|
12921
|
+
state4.pullRequestSequences = /* @__PURE__ */ new Map();
|
|
12922
|
+
const next = (state4.pullRequestSequences.get(sourceKey) ?? 0) + 1;
|
|
12923
|
+
state4.pullRequestSequences.set(sourceKey, next);
|
|
12984
12924
|
return next;
|
|
12985
12925
|
}
|
|
12986
|
-
function isNewestPullRequest(
|
|
12987
|
-
return (
|
|
12926
|
+
function isNewestPullRequest(state4, sourceKey, sequence) {
|
|
12927
|
+
return (state4.pullRequestSequences?.get(sourceKey) ?? 0) === sequence;
|
|
12988
12928
|
}
|
|
12989
|
-
function retirePullSource(
|
|
12929
|
+
function retirePullSource(state4, identifier) {
|
|
12990
12930
|
const suffix = `${PULL_SOURCE_KEY_SEPARATOR}${identifier}`;
|
|
12991
|
-
for (const source of [
|
|
12931
|
+
for (const source of [state4.pullResultIds, state4.pullRequestSequences]) {
|
|
12992
12932
|
if (!source)
|
|
12993
12933
|
continue;
|
|
12994
12934
|
for (const key of source.keys()) {
|
|
@@ -12996,17 +12936,17 @@ function retirePullSource(state5, identifier) {
|
|
|
12996
12936
|
source.delete(key);
|
|
12997
12937
|
}
|
|
12998
12938
|
}
|
|
12999
|
-
for (const [normalizedPath, sources] of
|
|
12939
|
+
for (const [normalizedPath, sources] of state4.documentPullDiagnosticsBySource ?? []) {
|
|
13000
12940
|
if (!sources.delete(identifier))
|
|
13001
12941
|
continue;
|
|
13002
|
-
|
|
13003
|
-
bumpDiagnosticsVersion(
|
|
13004
|
-
|
|
12942
|
+
state4.documentPullDiagnostics.set(normalizedPath, mergeDiagnosticLists(...sources.values()));
|
|
12943
|
+
bumpDiagnosticsVersion(state4, normalizedPath);
|
|
12944
|
+
state4.diagnosticEmitter.emit("diagnostics", normalizedPath);
|
|
13005
12945
|
}
|
|
13006
12946
|
}
|
|
13007
|
-
function pullDiagnosticSources(
|
|
12947
|
+
function pullDiagnosticSources(state4) {
|
|
13008
12948
|
const identifiers = /* @__PURE__ */ new Set();
|
|
13009
|
-
for (const registration of
|
|
12949
|
+
for (const registration of state4.dynamicRegistrations?.values() ?? []) {
|
|
13010
12950
|
if (registration.method !== "textDocument/diagnostic")
|
|
13011
12951
|
continue;
|
|
13012
12952
|
if (registration.identifier)
|
|
@@ -13014,91 +12954,91 @@ function pullDiagnosticSources(state5) {
|
|
|
13014
12954
|
}
|
|
13015
12955
|
return [void 0, ...[...identifiers].sort((a, b) => a.localeCompare(b))];
|
|
13016
12956
|
}
|
|
13017
|
-
function bumpDiagnosticsVersion(
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
countPublication(
|
|
12957
|
+
function bumpDiagnosticsVersion(state4, normalizedPath) {
|
|
12958
|
+
state4.diagnosticsVersion += 1;
|
|
12959
|
+
state4.diagnosticsVersionsByPath?.set(normalizedPath, state4.diagnosticsVersion);
|
|
12960
|
+
countPublication(state4, normalizedPath);
|
|
13021
12961
|
}
|
|
13022
|
-
function countPublication(
|
|
13023
|
-
const counts =
|
|
12962
|
+
function countPublication(state4, normalizedPath) {
|
|
12963
|
+
const counts = state4.publicationStoreCountsByPath;
|
|
13024
12964
|
if (!counts)
|
|
13025
12965
|
return;
|
|
13026
|
-
const { sent } = publicationCountsForPath(
|
|
12966
|
+
const { sent } = publicationCountsForPath(state4, normalizedPath);
|
|
13027
12967
|
if (sent === 0)
|
|
13028
12968
|
return;
|
|
13029
12969
|
counts.set(normalizedPath, Math.min((counts.get(normalizedPath) ?? 0) + 1, sent));
|
|
13030
12970
|
}
|
|
13031
|
-
function rebaselineForRulesRefresh(
|
|
13032
|
-
const counts =
|
|
12971
|
+
function rebaselineForRulesRefresh(state4) {
|
|
12972
|
+
const counts = state4.publicationStoreCountsByPath;
|
|
13033
12973
|
for (const [normalizedPath, published] of counts) {
|
|
13034
12974
|
counts.set(normalizedPath, published - 1);
|
|
13035
12975
|
}
|
|
13036
|
-
for (const normalizedPath of
|
|
13037
|
-
if (counts.has(normalizedPath) || publicationCountsForPath(
|
|
12976
|
+
for (const normalizedPath of state4.pendingDiagnostics.keys()) {
|
|
12977
|
+
if (counts.has(normalizedPath) || publicationCountsForPath(state4, normalizedPath).sent === 0)
|
|
13038
12978
|
continue;
|
|
13039
12979
|
counts.set(normalizedPath, -1);
|
|
13040
12980
|
}
|
|
13041
12981
|
logLatency({
|
|
13042
12982
|
type: "phase",
|
|
13043
12983
|
phase: "lsp_rules_refreshed",
|
|
13044
|
-
filePath:
|
|
12984
|
+
filePath: state4.root,
|
|
13045
12985
|
durationMs: 0,
|
|
13046
|
-
metadata: { serverId:
|
|
12986
|
+
metadata: { serverId: state4.serverId, rebaselinedPaths: counts.size }
|
|
13047
12987
|
});
|
|
13048
12988
|
}
|
|
13049
|
-
function publicationCountsForPath(
|
|
13050
|
-
const lastSent =
|
|
12989
|
+
function publicationCountsForPath(state4, normalizedPath) {
|
|
12990
|
+
const lastSent = state4.documentVersions.get(normalizedPath);
|
|
13051
12991
|
return {
|
|
13052
|
-
sent: (lastSent === void 0 ? 0 : lastSent + 1) + (
|
|
13053
|
-
published:
|
|
12992
|
+
sent: (lastSent === void 0 ? 0 : lastSent + 1) + (state4.expectedPublicationsBeyondSends?.get(normalizedPath) ?? 0),
|
|
12993
|
+
published: state4.publicationStoreCountsByPath?.get(normalizedPath) ?? 0
|
|
13054
12994
|
};
|
|
13055
12995
|
}
|
|
13056
|
-
function diagnosticsVersionForPath(
|
|
13057
|
-
return
|
|
12996
|
+
function diagnosticsVersionForPath(state4, normalizedPath) {
|
|
12997
|
+
return state4.diagnosticsVersionsByPath?.get(normalizedPath) ?? 0;
|
|
13058
12998
|
}
|
|
13059
|
-
function clearDiagnosticsForPath(
|
|
13060
|
-
const legacy =
|
|
13061
|
-
|
|
13062
|
-
const pending2 =
|
|
12999
|
+
function clearDiagnosticsForPath(state4, normalizedPath) {
|
|
13000
|
+
const legacy = state4;
|
|
13001
|
+
state4.pushDiagnostics?.delete(normalizedPath);
|
|
13002
|
+
const pending2 = state4.pendingDiagnostics?.get(normalizedPath);
|
|
13063
13003
|
if (pending2) {
|
|
13064
13004
|
clearTimeout(pending2);
|
|
13065
|
-
countPublication(
|
|
13066
|
-
}
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
|
|
13071
|
-
|
|
13072
|
-
|
|
13073
|
-
|
|
13074
|
-
for (const key of pullSourceKeysForPath(
|
|
13075
|
-
|
|
13076
|
-
}
|
|
13077
|
-
|
|
13078
|
-
bumpPullGeneration(
|
|
13079
|
-
|
|
13005
|
+
countPublication(state4, normalizedPath);
|
|
13006
|
+
}
|
|
13007
|
+
state4.pendingDiagnostics?.delete(normalizedPath);
|
|
13008
|
+
state4.pushDiagnosticTimestamps?.delete(normalizedPath);
|
|
13009
|
+
state4.documentPullDiagnostics?.delete(normalizedPath);
|
|
13010
|
+
state4.documentPullDiagnosticTimestamps?.delete(normalizedPath);
|
|
13011
|
+
state4.diagnosticDocVersions?.delete(normalizedPath);
|
|
13012
|
+
state4.diagnosticBindings?.delete(normalizedPath);
|
|
13013
|
+
state4.diagnosticsVersionsByPath?.delete(normalizedPath);
|
|
13014
|
+
for (const key of pullSourceKeysForPath(state4, normalizedPath)) {
|
|
13015
|
+
state4.pullResultIds?.delete(key);
|
|
13016
|
+
}
|
|
13017
|
+
state4.documentPullDiagnosticsBySource?.delete(normalizedPath);
|
|
13018
|
+
bumpPullGeneration(state4, normalizedPath);
|
|
13019
|
+
state4.workspacePullResultCache?.delete(normalizedPath);
|
|
13080
13020
|
legacy.diagnostics?.delete(normalizedPath);
|
|
13081
13021
|
legacy.diagnosticTimestamps?.delete(normalizedPath);
|
|
13082
13022
|
}
|
|
13083
|
-
function logTypeScriptPullSettle(
|
|
13084
|
-
if (
|
|
13023
|
+
function logTypeScriptPullSettle(state4, normalizedPath, durationMs, pullSettleSource) {
|
|
13024
|
+
if (state4.serverId !== "typescript")
|
|
13085
13025
|
return;
|
|
13086
|
-
const diagnostics =
|
|
13087
|
-
const elapsedSinceDidOpenMs = Math.max(0, Date.now() - (
|
|
13026
|
+
const diagnostics = state4.documentPullDiagnostics.get(normalizedPath) ?? [];
|
|
13027
|
+
const elapsedSinceDidOpenMs = Math.max(0, Date.now() - (state4.documentOpenedAt.get(normalizedPath) ?? Date.now()));
|
|
13088
13028
|
const diagnosticCodes = [
|
|
13089
13029
|
...new Set(diagnostics.map((diagnostic) => diagnostic.code).filter((code) => code !== void 0).map(String))
|
|
13090
13030
|
].slice(0, 8);
|
|
13091
|
-
const trackedVersion =
|
|
13031
|
+
const trackedVersion = state4.diagnosticsVersionsByPath?.get(normalizedPath);
|
|
13092
13032
|
logLatency({
|
|
13093
13033
|
type: "phase",
|
|
13094
13034
|
phase: "lsp_typescript_diagnostic_sequence",
|
|
13095
13035
|
filePath: normalizedPath,
|
|
13096
13036
|
durationMs,
|
|
13097
13037
|
metadata: {
|
|
13098
|
-
serverId:
|
|
13038
|
+
serverId: state4.serverId,
|
|
13099
13039
|
outcome: "settled",
|
|
13100
|
-
launchVariant:
|
|
13101
|
-
publicationIndex:
|
|
13040
|
+
launchVariant: state4.launchVariant ?? "unknown",
|
|
13041
|
+
publicationIndex: state4.diagnosticPublicationCounts.get(normalizedPath) ?? 0,
|
|
13102
13042
|
version: trackedVersion ?? "pull-unversioned",
|
|
13103
13043
|
diagnosticCount: diagnostics.length,
|
|
13104
13044
|
diagnosticCodes,
|
|
@@ -13127,25 +13067,25 @@ function scanSentContent(content) {
|
|
|
13127
13067
|
}
|
|
13128
13068
|
return { lfNewlineCount, lastLine: { index, start } };
|
|
13129
13069
|
}
|
|
13130
|
-
function recordSentContent(
|
|
13070
|
+
function recordSentContent(state4, normalizedPath, version, content, coalescedCount = 0) {
|
|
13131
13071
|
const scan = scanSentContent(content);
|
|
13132
|
-
const previous =
|
|
13072
|
+
const previous = state4.documentContentHashes.get(normalizedPath);
|
|
13133
13073
|
if (previous && previous.version > version) {
|
|
13134
13074
|
incrementDegradationCount({
|
|
13135
13075
|
kind: "lsp-document-send-order",
|
|
13136
|
-
subject: `${
|
|
13076
|
+
subject: `${state4.serverId}:${normalizedPath}`,
|
|
13137
13077
|
reason: `recorded version ${version} after newer version ${previous.version}`
|
|
13138
13078
|
});
|
|
13139
13079
|
return;
|
|
13140
13080
|
}
|
|
13141
13081
|
if (previous?.text !== void 0) {
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13082
|
+
state4.incrementalTextRetainedEntries = Math.max(0, (state4.incrementalTextRetainedEntries ?? 1) - 1);
|
|
13083
|
+
state4.incrementalTextRetainedBytes = Math.max(0, (state4.incrementalTextRetainedBytes ?? previous.text.length * 2) - previous.text.length * 2);
|
|
13084
|
+
state4.incrementalTextBearingPaths?.delete(normalizedPath);
|
|
13145
13085
|
}
|
|
13146
|
-
|
|
13086
|
+
state4.documentContentHashes.delete(normalizedPath);
|
|
13147
13087
|
const hash = hashDiagnosticContent(content);
|
|
13148
|
-
|
|
13088
|
+
state4.documentContentHashes.set(normalizedPath, {
|
|
13149
13089
|
version,
|
|
13150
13090
|
hash,
|
|
13151
13091
|
changedAtMs: previous?.hash === hash ? previous.changedAtMs : Date.now(),
|
|
@@ -13156,35 +13096,35 @@ function recordSentContent(state5, normalizedPath, version, content, coalescedCo
|
|
|
13156
13096
|
// what the server last saw; Full/None never read this field.
|
|
13157
13097
|
// #2066: `lastLine` is that reader's answer, already computed by the
|
|
13158
13098
|
// scan above — it rides along with the text it describes.
|
|
13159
|
-
...
|
|
13099
|
+
...state4.syncKind === TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL && {
|
|
13160
13100
|
text: content,
|
|
13161
13101
|
lastLine: scan.lastLine
|
|
13162
13102
|
}
|
|
13163
13103
|
});
|
|
13164
|
-
if (
|
|
13165
|
-
|
|
13166
|
-
|
|
13167
|
-
if (!
|
|
13168
|
-
|
|
13169
|
-
}
|
|
13170
|
-
|
|
13171
|
-
while ((
|
|
13172
|
-
const oldestPath =
|
|
13104
|
+
if (state4.syncKind === TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL) {
|
|
13105
|
+
state4.incrementalTextRetainedEntries = (state4.incrementalTextRetainedEntries ?? 0) + 1;
|
|
13106
|
+
state4.incrementalTextRetainedBytes = (state4.incrementalTextRetainedBytes ?? 0) + content.length * 2;
|
|
13107
|
+
if (!state4.incrementalTextBearingPaths) {
|
|
13108
|
+
state4.incrementalTextBearingPaths = /* @__PURE__ */ new Set();
|
|
13109
|
+
}
|
|
13110
|
+
state4.incrementalTextBearingPaths.add(normalizedPath);
|
|
13111
|
+
while ((state4.incrementalTextRetainedEntries ?? 0) > MAX_INCREMENTAL_TEXT_RETAINED_ENTRIES || (state4.incrementalTextRetainedBytes ?? 0) > MAX_INCREMENTAL_TEXT_RETAINED_BYTES) {
|
|
13112
|
+
const oldestPath = state4.incrementalTextBearingPaths?.values().next().value;
|
|
13173
13113
|
if (oldestPath === void 0)
|
|
13174
13114
|
break;
|
|
13175
|
-
const binding =
|
|
13176
|
-
|
|
13115
|
+
const binding = state4.documentContentHashes.get(oldestPath);
|
|
13116
|
+
state4.incrementalTextBearingPaths.delete(oldestPath);
|
|
13177
13117
|
if (!binding || binding.text === void 0)
|
|
13178
13118
|
continue;
|
|
13179
|
-
|
|
13119
|
+
state4.documentContentHashes.set(oldestPath, {
|
|
13180
13120
|
version: binding.version,
|
|
13181
13121
|
hash: binding.hash,
|
|
13182
13122
|
changedAtMs: binding.changedAtMs,
|
|
13183
13123
|
openedAtMs: binding.openedAtMs,
|
|
13184
13124
|
openedHash: binding.openedHash
|
|
13185
13125
|
});
|
|
13186
|
-
|
|
13187
|
-
|
|
13126
|
+
state4.incrementalTextRetainedEntries = Math.max(0, (state4.incrementalTextRetainedEntries ?? 1) - 1);
|
|
13127
|
+
state4.incrementalTextRetainedBytes = Math.max(0, (state4.incrementalTextRetainedBytes ?? 0) - binding.text.length * 2);
|
|
13188
13128
|
}
|
|
13189
13129
|
}
|
|
13190
13130
|
logLatency({
|
|
@@ -13200,11 +13140,11 @@ function recordSentContent(state5, normalizedPath, version, content, coalescedCo
|
|
|
13200
13140
|
}
|
|
13201
13141
|
});
|
|
13202
13142
|
}
|
|
13203
|
-
function buildContentChanges(
|
|
13204
|
-
if (
|
|
13143
|
+
function buildContentChanges(state4, normalizedPath, content) {
|
|
13144
|
+
if (state4.syncKind !== TEXT_DOCUMENT_SYNC_KIND_INCREMENTAL) {
|
|
13205
13145
|
return [{ text: content }];
|
|
13206
13146
|
}
|
|
13207
|
-
const previous =
|
|
13147
|
+
const previous = state4.documentContentHashes.get(normalizedPath);
|
|
13208
13148
|
if (previous?.text === void 0) {
|
|
13209
13149
|
return [{ text: content }];
|
|
13210
13150
|
}
|
|
@@ -13217,7 +13157,7 @@ function buildContentChanges(state5, normalizedPath, content) {
|
|
|
13217
13157
|
start: { line: 0, character: 0 },
|
|
13218
13158
|
end: {
|
|
13219
13159
|
line: lastLine.index,
|
|
13220
|
-
character: convertCharacterOffset(
|
|
13160
|
+
character: convertCharacterOffset(state4.positionEncoding, lastLineText, lastLineText.length)
|
|
13221
13161
|
}
|
|
13222
13162
|
},
|
|
13223
13163
|
text: content
|
|
@@ -13238,12 +13178,12 @@ var DYNAMIC_OPERATION_METHOD_MAP = {
|
|
|
13238
13178
|
"textDocument/implementation": "implementation",
|
|
13239
13179
|
"textDocument/prepareCallHierarchy": "callHierarchy"
|
|
13240
13180
|
};
|
|
13241
|
-
function applyDynamicCapabilities(
|
|
13242
|
-
const registrations = [...
|
|
13181
|
+
function applyDynamicCapabilities(state4) {
|
|
13182
|
+
const registrations = [...state4.dynamicRegistrations.values()];
|
|
13243
13183
|
const registeredMethods = new Set(registrations.map((r) => r.method));
|
|
13244
13184
|
const hasDynamicPull = registeredMethods.has("textDocument/diagnostic") || registeredMethods.has("workspace/diagnostic");
|
|
13245
13185
|
if (hasDynamicPull) {
|
|
13246
|
-
|
|
13186
|
+
state4.workspaceDiagnosticsSupport = {
|
|
13247
13187
|
advertised: true,
|
|
13248
13188
|
mode: "pull",
|
|
13249
13189
|
// #1667: workspace-pull support is what the REGISTRATION declares. The
|
|
@@ -13256,8 +13196,8 @@ function applyDynamicCapabilities(state5) {
|
|
|
13256
13196
|
workspaceDiagnostics: registrations.some((r) => r.workspaceDiagnostics === true) || registeredMethods.has("workspace/diagnostic"),
|
|
13257
13197
|
diagnosticProviderKind: "dynamic"
|
|
13258
13198
|
};
|
|
13259
|
-
} else if (
|
|
13260
|
-
|
|
13199
|
+
} else if (state4.staticDiagnosticsMode === "push-only" && state4.workspaceDiagnosticsSupport.diagnosticProviderKind === "dynamic") {
|
|
13200
|
+
state4.workspaceDiagnosticsSupport = {
|
|
13261
13201
|
advertised: false,
|
|
13262
13202
|
mode: "push-only",
|
|
13263
13203
|
workspaceDiagnostics: false,
|
|
@@ -13266,7 +13206,7 @@ function applyDynamicCapabilities(state5) {
|
|
|
13266
13206
|
}
|
|
13267
13207
|
for (const [method, key] of Object.entries(DYNAMIC_OPERATION_METHOD_MAP)) {
|
|
13268
13208
|
if (registeredMethods.has(method)) {
|
|
13269
|
-
|
|
13209
|
+
state4.operationSupport[key] = true;
|
|
13270
13210
|
}
|
|
13271
13211
|
}
|
|
13272
13212
|
}
|
|
@@ -13284,34 +13224,34 @@ function resolveConfigurationSection(initialization, section) {
|
|
|
13284
13224
|
}
|
|
13285
13225
|
return cur;
|
|
13286
13226
|
}
|
|
13287
|
-
function setupIncomingHandlers(
|
|
13288
|
-
|
|
13227
|
+
function setupIncomingHandlers(state4, initialization, onDiagnosticsPublished) {
|
|
13228
|
+
state4.connection.onNotification("textDocument/publishDiagnostics", (params) => {
|
|
13289
13229
|
const publishReceivedAt = Date.now();
|
|
13290
13230
|
const filePath = uriToPath(params.uri);
|
|
13291
13231
|
const normalizedPath = normalizeMapKey(filePath);
|
|
13292
13232
|
const docVersion = params.version;
|
|
13293
|
-
if (docVersion === void 0 && getStrategy(
|
|
13233
|
+
if (docVersion === void 0 && getStrategy(state4.serverId, state4.launchVariant).publishesOnClose) {
|
|
13294
13234
|
return;
|
|
13295
13235
|
}
|
|
13296
|
-
if (
|
|
13297
|
-
countPublication(
|
|
13236
|
+
if (state4.closedDocuments?.has(normalizedPath)) {
|
|
13237
|
+
countPublication(state4, normalizedPath);
|
|
13298
13238
|
return;
|
|
13299
13239
|
}
|
|
13300
|
-
onDiagnosticsPublished?.(
|
|
13240
|
+
onDiagnosticsPublished?.(state4.serverId);
|
|
13301
13241
|
const newDiags = normalizeLspDiagnostics(params.diagnostics || []);
|
|
13302
|
-
const fence =
|
|
13242
|
+
const fence = state4.diagnosticFences.get(normalizedPath);
|
|
13303
13243
|
if (docVersion === void 0 && fence) {
|
|
13304
13244
|
fence.dropped += 1;
|
|
13305
|
-
countPublication(
|
|
13306
|
-
if (getStrategy(
|
|
13307
|
-
|
|
13245
|
+
countPublication(state4, normalizedPath);
|
|
13246
|
+
if (getStrategy(state4.serverId, state4.launchVariant).emptyFirstPublish === "indexing" && !state4.emptyFirstPublishHoldSpent && newDiags.length === 0 && !state4.pushDiagnostics.has(normalizedPath) && !state4.pendingDiagnostics.has(normalizedPath)) {
|
|
13247
|
+
state4.emptyFirstPublishHoldSpent = true;
|
|
13308
13248
|
logLatency({
|
|
13309
13249
|
type: "phase",
|
|
13310
13250
|
phase: "lsp_empty_first_publish_held",
|
|
13311
13251
|
filePath: normalizedPath,
|
|
13312
|
-
durationMs: Math.max(0, publishReceivedAt - (
|
|
13252
|
+
durationMs: Math.max(0, publishReceivedAt - (state4.documentOpenedAt.get(normalizedPath) ?? publishReceivedAt)),
|
|
13313
13253
|
metadata: {
|
|
13314
|
-
serverId:
|
|
13254
|
+
serverId: state4.serverId,
|
|
13315
13255
|
emptyFirstPublish: "indexing",
|
|
13316
13256
|
via: "fence-drop",
|
|
13317
13257
|
pubVersion: "push-unversioned"
|
|
@@ -13324,31 +13264,31 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13324
13264
|
logExtension({
|
|
13325
13265
|
subsystem: "lsp-pub",
|
|
13326
13266
|
level: "debug",
|
|
13327
|
-
message: `server=${
|
|
13267
|
+
message: `server=${state4.serverId} pubVersion=${docVersion} docVersion=${state4.documentVersions?.get(normalizedPath)} diags=${newDiags.length}`
|
|
13328
13268
|
});
|
|
13329
13269
|
}
|
|
13330
|
-
const strategy = getStrategy(
|
|
13331
|
-
const isTypeScriptTelemetry =
|
|
13332
|
-
const publicationIndex = isTypeScriptTelemetry ? (
|
|
13270
|
+
const strategy = getStrategy(state4.serverId, state4.launchVariant);
|
|
13271
|
+
const isTypeScriptTelemetry = state4.serverId === "typescript";
|
|
13272
|
+
const publicationIndex = isTypeScriptTelemetry ? (state4.diagnosticPublicationCounts.get(normalizedPath) ?? 0) + 1 : 0;
|
|
13333
13273
|
if (isTypeScriptTelemetry) {
|
|
13334
|
-
|
|
13274
|
+
state4.diagnosticPublicationCounts.set(normalizedPath, publicationIndex);
|
|
13335
13275
|
}
|
|
13336
13276
|
const diagnosticCodes = isTypeScriptTelemetry ? [
|
|
13337
13277
|
...new Set(newDiags.map((diagnostic) => diagnostic.code).filter((code) => code !== void 0).map(String))
|
|
13338
13278
|
].slice(0, 8) : [];
|
|
13339
13279
|
const logSequence = (settledReturn, settleSource, durationMs) => {
|
|
13340
|
-
if (
|
|
13280
|
+
if (state4.serverId !== "typescript")
|
|
13341
13281
|
return;
|
|
13342
|
-
const elapsedSinceDidOpenMs = Math.max(0, Date.now() - (
|
|
13282
|
+
const elapsedSinceDidOpenMs = Math.max(0, Date.now() - (state4.documentOpenedAt.get(normalizedPath) ?? Date.now()));
|
|
13343
13283
|
logLatency({
|
|
13344
13284
|
type: "phase",
|
|
13345
13285
|
phase: "lsp_typescript_diagnostic_sequence",
|
|
13346
13286
|
filePath: normalizedPath,
|
|
13347
13287
|
durationMs,
|
|
13348
13288
|
metadata: {
|
|
13349
|
-
serverId:
|
|
13289
|
+
serverId: state4.serverId,
|
|
13350
13290
|
outcome: settledReturn ? "settled" : "published",
|
|
13351
|
-
launchVariant:
|
|
13291
|
+
launchVariant: state4.launchVariant ?? "unknown",
|
|
13352
13292
|
publicationIndex,
|
|
13353
13293
|
version: docVersion ?? "push-unversioned",
|
|
13354
13294
|
diagnosticCount: newDiags.length,
|
|
@@ -13361,17 +13301,17 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13361
13301
|
};
|
|
13362
13302
|
const recordDocVersion = () => {
|
|
13363
13303
|
if (docVersion !== void 0) {
|
|
13364
|
-
|
|
13304
|
+
state4.diagnosticDocVersions.set(normalizedPath, docVersion);
|
|
13365
13305
|
}
|
|
13366
13306
|
recordBinding();
|
|
13367
13307
|
};
|
|
13368
13308
|
const recordBinding = () => {
|
|
13369
13309
|
if (docVersion === void 0) {
|
|
13370
|
-
|
|
13310
|
+
state4.diagnosticBindings.delete(normalizedPath);
|
|
13371
13311
|
return;
|
|
13372
13312
|
}
|
|
13373
|
-
const sent =
|
|
13374
|
-
|
|
13313
|
+
const sent = state4.documentContentHashes.get(normalizedPath);
|
|
13314
|
+
state4.diagnosticBindings.set(normalizedPath, {
|
|
13375
13315
|
version: docVersion,
|
|
13376
13316
|
contentHash: sent && sent.version === docVersion ? sent.hash : void 0
|
|
13377
13317
|
});
|
|
@@ -13379,18 +13319,18 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13379
13319
|
const isSupersededPush = () => {
|
|
13380
13320
|
if (docVersion === void 0)
|
|
13381
13321
|
return false;
|
|
13382
|
-
const currentVersion =
|
|
13322
|
+
const currentVersion = state4.documentVersions.get(normalizedPath);
|
|
13383
13323
|
return currentVersion !== void 0 && docVersion < currentVersion;
|
|
13384
13324
|
};
|
|
13385
|
-
if (strategy.emptyFirstPublish === "indexing" && !
|
|
13386
|
-
|
|
13325
|
+
if (strategy.emptyFirstPublish === "indexing" && !state4.emptyFirstPublishHoldSpent && newDiags.length === 0 && !state4.pushDiagnostics.has(normalizedPath) && !state4.pendingDiagnostics.has(normalizedPath)) {
|
|
13326
|
+
state4.emptyFirstPublishHoldSpent = true;
|
|
13387
13327
|
logLatency({
|
|
13388
13328
|
type: "phase",
|
|
13389
13329
|
phase: "lsp_empty_first_publish_held",
|
|
13390
13330
|
filePath: normalizedPath,
|
|
13391
|
-
durationMs: Math.max(0, publishReceivedAt - (
|
|
13331
|
+
durationMs: Math.max(0, publishReceivedAt - (state4.documentOpenedAt.get(normalizedPath) ?? publishReceivedAt)),
|
|
13392
13332
|
metadata: {
|
|
13393
|
-
serverId:
|
|
13333
|
+
serverId: state4.serverId,
|
|
13394
13334
|
emptyFirstPublish: strategy.emptyFirstPublish,
|
|
13395
13335
|
// `pubVersion`, the `[lsp-pub]` trace's own field name for the
|
|
13396
13336
|
// publish's LSP document version — not a lifecycle identity, and
|
|
@@ -13400,49 +13340,49 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13400
13340
|
});
|
|
13401
13341
|
return;
|
|
13402
13342
|
}
|
|
13403
|
-
if (strategy.seedFirstPush && !
|
|
13343
|
+
if (strategy.seedFirstPush && !state4.pushDiagnostics.has(normalizedPath)) {
|
|
13404
13344
|
if (isSupersededPush()) {
|
|
13405
|
-
countPublication(
|
|
13345
|
+
countPublication(state4, normalizedPath);
|
|
13406
13346
|
return;
|
|
13407
13347
|
}
|
|
13408
|
-
|
|
13409
|
-
|
|
13348
|
+
state4.pushDiagnostics.set(normalizedPath, newDiags);
|
|
13349
|
+
state4.pushDiagnosticTimestamps.set(normalizedPath, Date.now());
|
|
13410
13350
|
recordDocVersion();
|
|
13411
|
-
bumpDiagnosticsVersion(
|
|
13412
|
-
|
|
13351
|
+
bumpDiagnosticsVersion(state4, normalizedPath);
|
|
13352
|
+
state4.diagnosticEmitter.emit("diagnostics", normalizedPath);
|
|
13413
13353
|
logSequence(true, "first-push", 0);
|
|
13414
13354
|
return;
|
|
13415
13355
|
}
|
|
13416
13356
|
logSequence(false, "publication", 0);
|
|
13417
|
-
const existingTimer =
|
|
13357
|
+
const existingTimer = state4.pendingDiagnostics.get(normalizedPath);
|
|
13418
13358
|
if (existingTimer) {
|
|
13419
13359
|
clearTimeout(existingTimer);
|
|
13420
|
-
countPublication(
|
|
13360
|
+
countPublication(state4, normalizedPath);
|
|
13421
13361
|
}
|
|
13422
13362
|
const timer = setTimeout(() => {
|
|
13423
|
-
|
|
13363
|
+
state4.pendingDiagnostics.delete(normalizedPath);
|
|
13424
13364
|
if (isSupersededPush()) {
|
|
13425
|
-
countPublication(
|
|
13365
|
+
countPublication(state4, normalizedPath);
|
|
13426
13366
|
return;
|
|
13427
13367
|
}
|
|
13428
|
-
|
|
13429
|
-
|
|
13368
|
+
state4.pushDiagnostics.set(normalizedPath, newDiags);
|
|
13369
|
+
state4.pushDiagnosticTimestamps.set(normalizedPath, Date.now());
|
|
13430
13370
|
recordDocVersion();
|
|
13431
|
-
bumpDiagnosticsVersion(
|
|
13432
|
-
|
|
13371
|
+
bumpDiagnosticsVersion(state4, normalizedPath);
|
|
13372
|
+
state4.diagnosticEmitter.emit("diagnostics", normalizedPath);
|
|
13433
13373
|
logSequence(true, "quiet-window", Date.now() - publishReceivedAt);
|
|
13434
13374
|
}, strategy.debounceMs);
|
|
13435
|
-
|
|
13375
|
+
state4.pendingDiagnostics.set(normalizedPath, timer);
|
|
13436
13376
|
});
|
|
13437
|
-
|
|
13438
|
-
{ name: "workspace", uri: pathToFileURL2(
|
|
13377
|
+
state4.connection.onRequest("workspace/workspaceFolders", () => [
|
|
13378
|
+
{ name: "workspace", uri: pathToFileURL2(state4.root).href }
|
|
13439
13379
|
]);
|
|
13440
|
-
|
|
13380
|
+
state4.connection.onRequest("client/registerCapability", async (params) => {
|
|
13441
13381
|
for (const reg of params?.registrations ?? []) {
|
|
13442
13382
|
const options = reg.registerOptions;
|
|
13443
13383
|
const commands = Array.isArray(options?.commands) ? options.commands.filter((cmd) => typeof cmd === "string") : void 0;
|
|
13444
13384
|
if (reg.id && reg.method) {
|
|
13445
|
-
|
|
13385
|
+
state4.dynamicRegistrations.set(reg.id, {
|
|
13446
13386
|
method: reg.method,
|
|
13447
13387
|
...typeof options?.identifier === "string" && options.identifier ? { identifier: options.identifier } : {},
|
|
13448
13388
|
...typeof options?.workspaceDiagnostics === "boolean" ? { workspaceDiagnostics: options.workspaceDiagnostics } : {},
|
|
@@ -13451,45 +13391,45 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13451
13391
|
}
|
|
13452
13392
|
if (reg.method === "workspace/executeCommand" && commands) {
|
|
13453
13393
|
for (const cmd of commands)
|
|
13454
|
-
|
|
13394
|
+
state4.advertisedCommands.add(cmd);
|
|
13455
13395
|
}
|
|
13456
13396
|
}
|
|
13457
|
-
applyDynamicCapabilities(
|
|
13397
|
+
applyDynamicCapabilities(state4);
|
|
13458
13398
|
});
|
|
13459
|
-
|
|
13399
|
+
state4.connection.onRequest("client/unregisterCapability", async (params) => {
|
|
13460
13400
|
const retiredIdentifiers = /* @__PURE__ */ new Set();
|
|
13461
13401
|
for (const unreg of params?.unregisterations ?? []) {
|
|
13462
13402
|
if (!unreg.id)
|
|
13463
13403
|
continue;
|
|
13464
|
-
const registration =
|
|
13465
|
-
|
|
13404
|
+
const registration = state4.dynamicRegistrations.get(unreg.id);
|
|
13405
|
+
state4.dynamicRegistrations.delete(unreg.id);
|
|
13466
13406
|
if (registration?.method === "textDocument/diagnostic" && registration.identifier) {
|
|
13467
13407
|
retiredIdentifiers.add(registration.identifier);
|
|
13468
13408
|
}
|
|
13469
13409
|
}
|
|
13470
|
-
const stillRegistered = new Set([...
|
|
13410
|
+
const stillRegistered = new Set([...state4.dynamicRegistrations.values()].filter((r) => r.method === "textDocument/diagnostic").map((r) => r.identifier));
|
|
13471
13411
|
for (const identifier of retiredIdentifiers) {
|
|
13472
13412
|
if (!stillRegistered.has(identifier)) {
|
|
13473
|
-
retirePullSource(
|
|
13413
|
+
retirePullSource(state4, identifier);
|
|
13474
13414
|
}
|
|
13475
13415
|
}
|
|
13476
|
-
applyDynamicCapabilities(
|
|
13416
|
+
applyDynamicCapabilities(state4);
|
|
13477
13417
|
});
|
|
13478
|
-
|
|
13479
|
-
if (
|
|
13418
|
+
state4.connection.onRequest("workspace/applyEdit", async (params) => {
|
|
13419
|
+
if (state4.serverEditsAllowed <= 0 || !params?.edit) {
|
|
13480
13420
|
return { applied: false, failureReason: "edit not solicited" };
|
|
13481
13421
|
}
|
|
13482
|
-
const context =
|
|
13422
|
+
const context = state4.activeMutationContext;
|
|
13483
13423
|
const telemetryContext = context ?? {
|
|
13484
|
-
cwd:
|
|
13424
|
+
cwd: state4.root,
|
|
13485
13425
|
correlationId: newLspMutationCorrelationId(),
|
|
13486
13426
|
tool: "lsp-workspace-applyEdit",
|
|
13487
13427
|
source: "lsp-execute-command"
|
|
13488
13428
|
};
|
|
13489
13429
|
try {
|
|
13490
|
-
await applyWorkspaceEdit(params.edit,
|
|
13491
|
-
positionEncoding:
|
|
13492
|
-
documentVersions:
|
|
13430
|
+
await applyWorkspaceEdit(params.edit, state4.root, {
|
|
13431
|
+
positionEncoding: state4.positionEncoding,
|
|
13432
|
+
documentVersions: state4.documentVersions,
|
|
13493
13433
|
mutationContext: telemetryContext
|
|
13494
13434
|
});
|
|
13495
13435
|
return { applied: true };
|
|
@@ -13500,30 +13440,30 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13500
13440
|
};
|
|
13501
13441
|
}
|
|
13502
13442
|
});
|
|
13503
|
-
|
|
13443
|
+
state4.connection.onRequest("workspace/configuration", async (params) => {
|
|
13504
13444
|
const items = params?.items ?? [];
|
|
13505
13445
|
return items.map((item) => resolveConfigurationSection(initialization, item?.section));
|
|
13506
13446
|
});
|
|
13507
|
-
|
|
13447
|
+
state4.connection.onRequest("window/workDoneProgress/create", async () => {
|
|
13508
13448
|
});
|
|
13509
|
-
|
|
13449
|
+
state4.connection.onNotification("semgrep/rulesRefreshed", () => rebaselineForRulesRefresh(state4));
|
|
13510
13450
|
let refreshRepullRunning = false;
|
|
13511
13451
|
let refreshRepullRerunRequested = false;
|
|
13512
13452
|
const runRefreshRepullPool = async () => {
|
|
13513
13453
|
do {
|
|
13514
13454
|
refreshRepullRerunRequested = false;
|
|
13515
|
-
const toRepull =
|
|
13455
|
+
const toRepull = state4.workspaceDiagnosticsSupport.mode === "pull" ? [...state4.openDocuments] : [];
|
|
13516
13456
|
if (toRepull.length > 0) {
|
|
13517
13457
|
try {
|
|
13518
13458
|
await mapWithConcurrency(toRepull, REFRESH_REPULL_CONCURRENCY, async (normalizedPath) => {
|
|
13519
|
-
const uri =
|
|
13459
|
+
const uri = state4.openDocumentUris?.get(normalizedPath);
|
|
13520
13460
|
const filePath = uri ? uriToPath(uri) : normalizedPath;
|
|
13521
|
-
await clientRequestPullDiagnostics(
|
|
13461
|
+
await clientRequestPullDiagnostics(state4, filePath);
|
|
13522
13462
|
});
|
|
13523
13463
|
} catch (err) {
|
|
13524
13464
|
incrementDegradationCount({
|
|
13525
13465
|
kind: "lsp-pull-unconfirmed",
|
|
13526
|
-
subject:
|
|
13466
|
+
subject: state4.serverId,
|
|
13527
13467
|
reason: `refresh re-pull threw: ${err instanceof Error ? err.message : String(err)}`
|
|
13528
13468
|
});
|
|
13529
13469
|
}
|
|
@@ -13531,14 +13471,14 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13531
13471
|
} while (refreshRepullRerunRequested);
|
|
13532
13472
|
refreshRepullRunning = false;
|
|
13533
13473
|
};
|
|
13534
|
-
|
|
13535
|
-
|
|
13474
|
+
state4.connection.onRequest("workspace/diagnostic/refresh", async () => {
|
|
13475
|
+
state4.workspacePullResultCache.clear();
|
|
13536
13476
|
clearAllWorkspaceDiagnosticsCaches();
|
|
13537
|
-
clearWorkspaceDiagnosticsCacheAtAndAbove(
|
|
13538
|
-
for (const normalizedPath of
|
|
13539
|
-
clearDiagnosticsForPath(
|
|
13477
|
+
clearWorkspaceDiagnosticsCacheAtAndAbove(state4.root);
|
|
13478
|
+
for (const normalizedPath of state4.openDocuments) {
|
|
13479
|
+
clearDiagnosticsForPath(state4, normalizedPath);
|
|
13540
13480
|
}
|
|
13541
|
-
if (
|
|
13481
|
+
if (state4.workspaceDiagnosticsSupport.mode === "pull" && state4.openDocuments.size > 0) {
|
|
13542
13482
|
if (refreshRepullRunning) {
|
|
13543
13483
|
refreshRepullRerunRequested = true;
|
|
13544
13484
|
} else {
|
|
@@ -13551,40 +13491,40 @@ function setupIncomingHandlers(state5, initialization, onDiagnosticsPublished) {
|
|
|
13551
13491
|
return null;
|
|
13552
13492
|
});
|
|
13553
13493
|
}
|
|
13554
|
-
function markExitedIfUnset(
|
|
13555
|
-
if (
|
|
13556
|
-
|
|
13494
|
+
function markExitedIfUnset(state4) {
|
|
13495
|
+
if (state4.exitedAt === void 0) {
|
|
13496
|
+
state4.exitedAt = Date.now();
|
|
13557
13497
|
}
|
|
13558
13498
|
}
|
|
13559
|
-
function setupConnectionLifecycle(
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
markExitedIfUnset(
|
|
13565
|
-
disposeClientConnection(
|
|
13499
|
+
function setupConnectionLifecycle(state4, recentStderr) {
|
|
13500
|
+
state4.connection.onError(([error]) => {
|
|
13501
|
+
state4.lastError = error instanceof Error ? error : new Error(String(error));
|
|
13502
|
+
state4.isConnected = false;
|
|
13503
|
+
state4.isDestroyed = true;
|
|
13504
|
+
markExitedIfUnset(state4);
|
|
13505
|
+
disposeClientConnection(state4);
|
|
13566
13506
|
});
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
|
|
13570
|
-
markExitedIfUnset(
|
|
13571
|
-
disposeClientConnection(
|
|
13507
|
+
state4.connection.onClose(() => {
|
|
13508
|
+
state4.isConnected = false;
|
|
13509
|
+
state4.isDestroyed = true;
|
|
13510
|
+
markExitedIfUnset(state4);
|
|
13511
|
+
disposeClientConnection(state4);
|
|
13572
13512
|
});
|
|
13573
|
-
|
|
13574
|
-
const wasIntentional =
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
markExitedIfUnset(
|
|
13578
|
-
disposeClientConnection(
|
|
13513
|
+
state4.lspProcess.process.on("exit", (code, signal) => {
|
|
13514
|
+
const wasIntentional = state4.shutdownRequested;
|
|
13515
|
+
state4.isConnected = false;
|
|
13516
|
+
state4.isDestroyed = true;
|
|
13517
|
+
markExitedIfUnset(state4);
|
|
13518
|
+
disposeClientConnection(state4);
|
|
13579
13519
|
if (!wasIntentional) {
|
|
13580
13520
|
logLatency({
|
|
13581
13521
|
type: "phase",
|
|
13582
13522
|
phase: "lsp_server_unexpected_exit",
|
|
13583
|
-
filePath:
|
|
13523
|
+
filePath: state4.root,
|
|
13584
13524
|
durationMs: 0,
|
|
13585
13525
|
metadata: {
|
|
13586
|
-
serverId:
|
|
13587
|
-
pid:
|
|
13526
|
+
serverId: state4.serverId,
|
|
13527
|
+
pid: state4.lspProcess.pid,
|
|
13588
13528
|
exitCode: code ?? null,
|
|
13589
13529
|
exitSignal: signal ?? null,
|
|
13590
13530
|
stderrTail: recentStderr(20)
|
|
@@ -13592,44 +13532,44 @@ function setupConnectionLifecycle(state5, recentStderr) {
|
|
|
13592
13532
|
});
|
|
13593
13533
|
}
|
|
13594
13534
|
});
|
|
13595
|
-
|
|
13596
|
-
if (
|
|
13535
|
+
state4.lspProcess.process.on("close", (code, signal) => {
|
|
13536
|
+
if (state4.shutdownRequested)
|
|
13597
13537
|
return;
|
|
13598
13538
|
try {
|
|
13599
13539
|
const stderrTail = recentStderr(20);
|
|
13600
13540
|
incrementDegradationCount({
|
|
13601
13541
|
kind: "lsp-server-unexpected-close",
|
|
13602
|
-
subject:
|
|
13603
|
-
reason: `closed unprompted: code=${code ?? "none"} signal=${signal ?? "none"} stderr=${stderrTail.length > 0 ? `present(${stderrTail.length}b)` : "empty"} root=${
|
|
13542
|
+
subject: state4.serverId,
|
|
13543
|
+
reason: `closed unprompted: code=${code ?? "none"} signal=${signal ?? "none"} stderr=${stderrTail.length > 0 ? `present(${stderrTail.length}b)` : "empty"} root=${state4.root}`
|
|
13604
13544
|
});
|
|
13605
13545
|
} catch {
|
|
13606
13546
|
}
|
|
13607
13547
|
});
|
|
13608
13548
|
}
|
|
13609
13549
|
var PULL_RACE_BACKSTOP_MARGIN_MS = 25;
|
|
13610
|
-
async function clientRequestPullDiagnostics(
|
|
13611
|
-
if (!isClientAlive(
|
|
13550
|
+
async function clientRequestPullDiagnostics(state4, filePath, budgetMs = PULL_REQUEST_TIMEOUT_MS) {
|
|
13551
|
+
if (!isClientAlive(state4))
|
|
13612
13552
|
return { status: "unavailable" };
|
|
13613
|
-
const sources = pullDiagnosticSources(
|
|
13553
|
+
const sources = pullDiagnosticSources(state4);
|
|
13614
13554
|
if (sources.length === 1) {
|
|
13615
|
-
return aggregatePullOutcomes(
|
|
13616
|
-
await pullDiagnosticSource(
|
|
13555
|
+
return aggregatePullOutcomes(state4, filePath, [
|
|
13556
|
+
await pullDiagnosticSource(state4, filePath, budgetMs, void 0)
|
|
13617
13557
|
]);
|
|
13618
13558
|
}
|
|
13619
|
-
const attempts = sources.map((identifier) => pullDiagnosticSource(
|
|
13559
|
+
const attempts = sources.map((identifier) => pullDiagnosticSource(state4, filePath, budgetMs, identifier));
|
|
13620
13560
|
const settled = await raceToCompletion(attempts, (results) => results.some((r) => r.status === "found" && r.primaryCount > 0), {
|
|
13621
13561
|
// No graceMs: finalize the instant a source answers for this file.
|
|
13622
13562
|
// The per-request `withTimeout` inside each attempt is the real bound;
|
|
13623
13563
|
// this deadline is only a backstop, so it sits just past it.
|
|
13624
13564
|
timeoutMs: Math.max(1, Math.min(PULL_REQUEST_TIMEOUT_MS, budgetMs)) + PULL_RACE_BACKSTOP_MARGIN_MS
|
|
13625
13565
|
});
|
|
13626
|
-
return aggregatePullOutcomes(
|
|
13566
|
+
return aggregatePullOutcomes(state4, filePath, settled);
|
|
13627
13567
|
}
|
|
13628
|
-
function aggregatePullOutcomes(
|
|
13568
|
+
function aggregatePullOutcomes(state4, filePath, outcomes) {
|
|
13629
13569
|
const found = outcomes.filter((o) => o.status === "found");
|
|
13630
13570
|
if (found.length > 0) {
|
|
13631
13571
|
const normalizedPath = normalizeMapKey(filePath);
|
|
13632
|
-
const unionCount =
|
|
13572
|
+
const unionCount = state4.documentPullDiagnostics.get(normalizedPath)?.length ?? 0;
|
|
13633
13573
|
return {
|
|
13634
13574
|
status: "found",
|
|
13635
13575
|
count: Math.max(unionCount, ...found.map((o) => o.count))
|
|
@@ -13640,39 +13580,39 @@ function aggregatePullOutcomes(state5, filePath, outcomes) {
|
|
|
13640
13580
|
}
|
|
13641
13581
|
return outcomes.some((o) => o.status === "clean") ? { status: "clean" } : { status: "unavailable" };
|
|
13642
13582
|
}
|
|
13643
|
-
async function pullDiagnosticSource(
|
|
13644
|
-
if (!isClientAlive(
|
|
13583
|
+
async function pullDiagnosticSource(state4, filePath, budgetMs, identifier) {
|
|
13584
|
+
if (!isClientAlive(state4))
|
|
13645
13585
|
return { status: "unavailable" };
|
|
13646
13586
|
const normalizedPath = normalizeMapKey(filePath);
|
|
13647
13587
|
if (budgetMs < PULL_MIN_USABLE_BUDGET_MS) {
|
|
13648
|
-
emitBounded("lsp_pull_skipped_budget_exhausted", `${
|
|
13588
|
+
emitBounded("lsp_pull_skipped_budget_exhausted", `${state4.serverId}::${pullSourceKey(normalizedPath, identifier)}`, {
|
|
13649
13589
|
type: "phase",
|
|
13650
13590
|
filePath: normalizedPath,
|
|
13651
13591
|
durationMs: 0,
|
|
13652
13592
|
metadata: {
|
|
13653
13593
|
identifier: identifier ?? "bare",
|
|
13654
13594
|
remainingBudgetMs: budgetMs,
|
|
13655
|
-
server:
|
|
13595
|
+
server: state4.serverId
|
|
13656
13596
|
}
|
|
13657
13597
|
}, {
|
|
13658
13598
|
ledgerKind: "lsp-pull-skipped-budget-exhausted",
|
|
13659
|
-
reason: `pull skipped on ${
|
|
13599
|
+
reason: `pull skipped on ${state4.serverId}: budget already exhausted (${budgetMs}ms remaining)`
|
|
13660
13600
|
});
|
|
13661
13601
|
return { status: "unavailable" };
|
|
13662
13602
|
}
|
|
13663
13603
|
const uri = pathToFileURL2(filePath).href;
|
|
13664
13604
|
const sourceKey = pullSourceKey(normalizedPath, identifier);
|
|
13665
|
-
if (
|
|
13605
|
+
if (state4.abandonedPullRequests?.has(sourceKey)) {
|
|
13666
13606
|
return { status: "unavailable" };
|
|
13667
13607
|
}
|
|
13668
|
-
const previousResultId =
|
|
13669
|
-
const generation = pullGenerationFor(
|
|
13670
|
-
const requestSequence = claimPullRequestSequence(
|
|
13608
|
+
const previousResultId = state4.pullResultIds.get(sourceKey);
|
|
13609
|
+
const generation = pullGenerationFor(state4, normalizedPath);
|
|
13610
|
+
const requestSequence = claimPullRequestSequence(state4, sourceKey);
|
|
13671
13611
|
const requestStartedAt = Date.now();
|
|
13672
13612
|
const effectiveTimeoutMs = Math.max(1, Math.min(PULL_REQUEST_TIMEOUT_MS, budgetMs));
|
|
13673
13613
|
const pullAbort = new AbortController();
|
|
13674
13614
|
const pullSettlement = { cancelled: false };
|
|
13675
|
-
const requestPromise = safeSendRequest(
|
|
13615
|
+
const requestPromise = safeSendRequest(state4.connection, "textDocument/diagnostic", {
|
|
13676
13616
|
textDocument: { uri },
|
|
13677
13617
|
// #1667: name the source this request is for, so the server answers
|
|
13678
13618
|
// from that source instead of its default one.
|
|
@@ -13682,56 +13622,56 @@ async function pullDiagnosticSource(state5, filePath, budgetMs, identifier) {
|
|
|
13682
13622
|
try {
|
|
13683
13623
|
const report = await withTimeout(requestPromise, effectiveTimeoutMs);
|
|
13684
13624
|
if (!report) {
|
|
13685
|
-
recordPullFailure(
|
|
13625
|
+
recordPullFailure(state4, "textDocument/diagnostic", new Error("empty response"));
|
|
13686
13626
|
return { status: "unavailable" };
|
|
13687
13627
|
}
|
|
13688
13628
|
const now = Date.now();
|
|
13689
|
-
const sentHash =
|
|
13690
|
-
if (pullGenerationFor(
|
|
13629
|
+
const sentHash = state4.documentContentHashes.get(normalizedPath)?.hash;
|
|
13630
|
+
if (pullGenerationFor(state4, normalizedPath) !== generation || !isNewestPullRequest(state4, sourceKey, requestSequence)) {
|
|
13691
13631
|
return { status: "unavailable" };
|
|
13692
13632
|
}
|
|
13693
13633
|
let primaryCount;
|
|
13694
13634
|
if (report.kind === "unchanged") {
|
|
13695
|
-
primaryCount = pullSourceDiagnostics(
|
|
13696
|
-
|
|
13635
|
+
primaryCount = pullSourceDiagnostics(state4, normalizedPath, identifier).length;
|
|
13636
|
+
state4.documentPullDiagnosticTimestamps.set(normalizedPath, now);
|
|
13697
13637
|
} else {
|
|
13698
13638
|
const primaryItems = normalizeLspDiagnostics(report.items ?? []);
|
|
13699
|
-
storePullSourceDiagnostics(
|
|
13700
|
-
|
|
13701
|
-
bumpDiagnosticsVersion(
|
|
13702
|
-
|
|
13639
|
+
storePullSourceDiagnostics(state4, normalizedPath, identifier, primaryItems);
|
|
13640
|
+
state4.documentPullDiagnosticTimestamps.set(normalizedPath, now);
|
|
13641
|
+
bumpDiagnosticsVersion(state4, normalizedPath);
|
|
13642
|
+
state4.diagnosticBindings.set(normalizedPath, { contentHash: sentHash });
|
|
13703
13643
|
primaryCount = primaryItems.length;
|
|
13704
13644
|
}
|
|
13705
13645
|
let totalCount = primaryCount;
|
|
13706
13646
|
if (report.resultId !== void 0) {
|
|
13707
|
-
|
|
13647
|
+
state4.pullResultIds.set(sourceKey, report.resultId);
|
|
13708
13648
|
} else {
|
|
13709
|
-
|
|
13649
|
+
state4.pullResultIds.delete(sourceKey);
|
|
13710
13650
|
}
|
|
13711
13651
|
if (report.relatedDocuments) {
|
|
13712
13652
|
for (const [relatedUri, related] of Object.entries(report.relatedDocuments)) {
|
|
13713
13653
|
const relatedPath = uriToPath(relatedUri);
|
|
13714
13654
|
const relatedNormalized = normalizeMapKey(relatedPath);
|
|
13715
13655
|
if (related?.kind === "unchanged") {
|
|
13716
|
-
totalCount += pullSourceDiagnostics(
|
|
13717
|
-
|
|
13656
|
+
totalCount += pullSourceDiagnostics(state4, relatedNormalized, identifier).length;
|
|
13657
|
+
state4.documentPullDiagnosticTimestamps.set(relatedNormalized, now);
|
|
13718
13658
|
} else {
|
|
13719
13659
|
const relatedItems = normalizeLspDiagnostics(related?.items ?? []);
|
|
13720
|
-
storePullSourceDiagnostics(
|
|
13721
|
-
|
|
13722
|
-
|
|
13660
|
+
storePullSourceDiagnostics(state4, relatedNormalized, identifier, relatedItems);
|
|
13661
|
+
state4.documentPullDiagnosticTimestamps.set(relatedNormalized, now);
|
|
13662
|
+
state4.diagnosticBindings.delete(relatedNormalized);
|
|
13723
13663
|
totalCount += relatedItems.length;
|
|
13724
13664
|
}
|
|
13725
13665
|
if (related?.resultId !== void 0) {
|
|
13726
|
-
|
|
13666
|
+
state4.pullResultIds.set(pullSourceKey(relatedNormalized, identifier), related.resultId);
|
|
13727
13667
|
}
|
|
13728
13668
|
}
|
|
13729
13669
|
}
|
|
13730
|
-
|
|
13670
|
+
state4.diagnosticEmitter.emit("diagnostics", normalizedPath);
|
|
13731
13671
|
return totalCount > 0 ? { status: "found", count: totalCount, primaryCount } : { status: "clean" };
|
|
13732
13672
|
} catch (err) {
|
|
13733
13673
|
if (isPullTimeoutError(err, effectiveTimeoutMs)) {
|
|
13734
|
-
trackAbandonedPullRequest(
|
|
13674
|
+
trackAbandonedPullRequest(state4, sourceKey, requestPromise);
|
|
13735
13675
|
pullAbort.abort();
|
|
13736
13676
|
recordPullTimeoutTelemetry({
|
|
13737
13677
|
scope: normalizedPath,
|
|
@@ -13739,7 +13679,7 @@ async function pullDiagnosticSource(state5, filePath, budgetMs, identifier) {
|
|
|
13739
13679
|
effectiveBudgetMs: effectiveTimeoutMs,
|
|
13740
13680
|
hadPreviousResultId: previousResultId !== void 0,
|
|
13741
13681
|
elapsedMs: Date.now() - requestStartedAt,
|
|
13742
|
-
server:
|
|
13682
|
+
server: state4.serverId
|
|
13743
13683
|
});
|
|
13744
13684
|
armLateAnswerTelemetry({
|
|
13745
13685
|
requestPromise,
|
|
@@ -13747,21 +13687,21 @@ async function pullDiagnosticSource(state5, filePath, budgetMs, identifier) {
|
|
|
13747
13687
|
identifier,
|
|
13748
13688
|
subject: sourceKey,
|
|
13749
13689
|
requestStartedAt,
|
|
13750
|
-
server:
|
|
13690
|
+
server: state4.serverId,
|
|
13751
13691
|
settlement: pullSettlement
|
|
13752
13692
|
});
|
|
13753
13693
|
}
|
|
13754
|
-
recordPullFailure(
|
|
13694
|
+
recordPullFailure(state4, "textDocument/diagnostic", err);
|
|
13755
13695
|
return { status: "unavailable" };
|
|
13756
13696
|
}
|
|
13757
13697
|
}
|
|
13758
|
-
function trackAbandonedPullRequest(
|
|
13759
|
-
if (!
|
|
13760
|
-
|
|
13761
|
-
|
|
13698
|
+
function trackAbandonedPullRequest(state4, sourceKey, requestPromise) {
|
|
13699
|
+
if (!state4.abandonedPullRequests)
|
|
13700
|
+
state4.abandonedPullRequests = /* @__PURE__ */ new Map();
|
|
13701
|
+
state4.abandonedPullRequests.set(sourceKey, requestPromise);
|
|
13762
13702
|
const release = () => {
|
|
13763
|
-
if (
|
|
13764
|
-
|
|
13703
|
+
if (state4.abandonedPullRequests?.get(sourceKey) === requestPromise) {
|
|
13704
|
+
state4.abandonedPullRequests.delete(sourceKey);
|
|
13765
13705
|
}
|
|
13766
13706
|
};
|
|
13767
13707
|
requestPromise.then(release, release);
|
|
@@ -13835,43 +13775,43 @@ function armLateAnswerTelemetry(args) {
|
|
|
13835
13775
|
});
|
|
13836
13776
|
}
|
|
13837
13777
|
var PULL_FAILURE_HISTORY_LIMIT = 10;
|
|
13838
|
-
function recordPullFailure(
|
|
13778
|
+
function recordPullFailure(state4, method, error) {
|
|
13839
13779
|
const candidate = error;
|
|
13840
13780
|
const message = typeof candidate.message === "string" ? candidate.message : "";
|
|
13841
13781
|
const unsupportedMessage = /^(?:method not found|unknown method|unsupported method)(?::|$)/i;
|
|
13842
13782
|
if (candidate.code === -32601 || candidate.code === "-32601" || unsupportedMessage.test(message.trim()))
|
|
13843
13783
|
return;
|
|
13844
|
-
|
|
13784
|
+
state4.pullFailureHistory.push({
|
|
13845
13785
|
timestamp: Date.now(),
|
|
13846
13786
|
method,
|
|
13847
13787
|
...typeof candidate.code === "number" || typeof candidate.code === "string" ? { code: candidate.code } : {},
|
|
13848
13788
|
message: typeof candidate.message === "string" ? candidate.message : String(error)
|
|
13849
13789
|
});
|
|
13850
|
-
if (
|
|
13851
|
-
|
|
13790
|
+
if (state4.pullFailureHistory.length > PULL_FAILURE_HISTORY_LIMIT) {
|
|
13791
|
+
state4.pullFailureHistory.splice(0, state4.pullFailureHistory.length - PULL_FAILURE_HISTORY_LIMIT);
|
|
13852
13792
|
}
|
|
13853
13793
|
}
|
|
13854
|
-
async function clientRequestWorkspaceDiagnostics(
|
|
13855
|
-
if (!isClientAlive(
|
|
13794
|
+
async function clientRequestWorkspaceDiagnostics(state4, budgetMs) {
|
|
13795
|
+
if (!isClientAlive(state4))
|
|
13856
13796
|
return void 0;
|
|
13857
|
-
if (!
|
|
13797
|
+
if (!state4.workspaceDiagnosticsSupport.workspaceDiagnostics)
|
|
13858
13798
|
return void 0;
|
|
13859
|
-
if (
|
|
13799
|
+
if (state4.abandonedPullRequests?.has(WORKSPACE_PULL_SCOPE))
|
|
13860
13800
|
return void 0;
|
|
13861
|
-
const previousResultIds = Array.from(
|
|
13801
|
+
const previousResultIds = Array.from(state4.workspacePullResultCache.values()).map((entry) => ({ uri: entry.uri, value: entry.resultId }));
|
|
13862
13802
|
if (budgetMs < PULL_MIN_USABLE_BUDGET_MS) {
|
|
13863
|
-
emitBounded("lsp_pull_skipped_budget_exhausted", `${
|
|
13803
|
+
emitBounded("lsp_pull_skipped_budget_exhausted", `${state4.serverId}::${WORKSPACE_PULL_SCOPE}`, {
|
|
13864
13804
|
type: "phase",
|
|
13865
13805
|
filePath: WORKSPACE_PULL_SCOPE,
|
|
13866
13806
|
durationMs: 0,
|
|
13867
13807
|
metadata: {
|
|
13868
13808
|
identifier: "bare",
|
|
13869
13809
|
remainingBudgetMs: budgetMs,
|
|
13870
|
-
server:
|
|
13810
|
+
server: state4.serverId
|
|
13871
13811
|
}
|
|
13872
13812
|
}, {
|
|
13873
13813
|
ledgerKind: "lsp-pull-skipped-budget-exhausted",
|
|
13874
|
-
reason: `workspace pull skipped on ${
|
|
13814
|
+
reason: `workspace pull skipped on ${state4.serverId}: budget already exhausted (${budgetMs}ms remaining)`
|
|
13875
13815
|
});
|
|
13876
13816
|
return void 0;
|
|
13877
13817
|
}
|
|
@@ -13879,7 +13819,7 @@ async function clientRequestWorkspaceDiagnostics(state5, budgetMs) {
|
|
|
13879
13819
|
const workspacePullTimeoutMs = Math.max(1, budgetMs);
|
|
13880
13820
|
const workspacePullAbort = new AbortController();
|
|
13881
13821
|
const workspacePullSettlement = { cancelled: false };
|
|
13882
|
-
const workspaceRequestPromise = safeSendRequest(
|
|
13822
|
+
const workspaceRequestPromise = safeSendRequest(state4.connection, "workspace/diagnostic", { previousResultIds }, workspacePullAbort.signal, workspacePullSettlement);
|
|
13883
13823
|
try {
|
|
13884
13824
|
const report = await withTimeout(workspaceRequestPromise, workspacePullTimeoutMs);
|
|
13885
13825
|
if (!report || !Array.isArray(report.items))
|
|
@@ -13892,35 +13832,35 @@ async function clientRequestWorkspaceDiagnostics(state5, budgetMs) {
|
|
|
13892
13832
|
const filePath = uriToPath(item.uri);
|
|
13893
13833
|
const normalizedPath = normalizeMapKey(filePath);
|
|
13894
13834
|
if (item.kind === "unchanged") {
|
|
13895
|
-
const prior =
|
|
13835
|
+
const prior = state4.workspacePullResultCache.get(normalizedPath);
|
|
13896
13836
|
if (!prior) {
|
|
13897
13837
|
const remainingMs = fallbackPullDeadline - Date.now();
|
|
13898
13838
|
if (remainingMs <= 0) {
|
|
13899
13839
|
incrementDegradationCount({
|
|
13900
13840
|
kind: "lsp-pull-unconfirmed",
|
|
13901
|
-
subject:
|
|
13841
|
+
subject: state4.serverId,
|
|
13902
13842
|
reason: "unchanged report with no workspacePullResultCache basis; the shared fallback-pull deadline was already exhausted by earlier files this sweep"
|
|
13903
13843
|
});
|
|
13904
13844
|
continue;
|
|
13905
13845
|
}
|
|
13906
|
-
const outcome = await clientRequestPullDiagnostics(
|
|
13846
|
+
const outcome = await clientRequestPullDiagnostics(state4, filePath, remainingMs);
|
|
13907
13847
|
if (outcome.status === "found") {
|
|
13908
13848
|
out.push({
|
|
13909
13849
|
filePath,
|
|
13910
|
-
diagnostics:
|
|
13911
|
-
contentHash:
|
|
13850
|
+
diagnostics: state4.documentPullDiagnostics.get(normalizedPath) ?? [],
|
|
13851
|
+
contentHash: state4.diagnosticBindings.get(normalizedPath)?.contentHash
|
|
13912
13852
|
});
|
|
13913
13853
|
} else if (outcome.status === "unavailable") {
|
|
13914
13854
|
incrementDegradationCount({
|
|
13915
13855
|
kind: "lsp-pull-unconfirmed",
|
|
13916
|
-
subject:
|
|
13856
|
+
subject: state4.serverId,
|
|
13917
13857
|
reason: "unchanged report with no workspacePullResultCache basis, and the per-file fallback pull was unavailable"
|
|
13918
13858
|
});
|
|
13919
13859
|
}
|
|
13920
13860
|
continue;
|
|
13921
13861
|
}
|
|
13922
13862
|
if (item.resultId !== void 0) {
|
|
13923
|
-
|
|
13863
|
+
state4.workspacePullResultCache.set(normalizedPath, {
|
|
13924
13864
|
...prior,
|
|
13925
13865
|
resultId: item.resultId
|
|
13926
13866
|
});
|
|
@@ -13933,27 +13873,27 @@ async function clientRequestWorkspaceDiagnostics(state5, budgetMs) {
|
|
|
13933
13873
|
continue;
|
|
13934
13874
|
}
|
|
13935
13875
|
const diagnostics = normalizeLspDiagnostics(item.items ?? []);
|
|
13936
|
-
const sent =
|
|
13876
|
+
const sent = state4.openDocuments.has(normalizedPath) ? state4.documentContentHashes.get(normalizedPath) : void 0;
|
|
13937
13877
|
const contentHash2 = sent !== void 0 && sent.version === item.version ? sent.hash : void 0;
|
|
13938
13878
|
if (item.resultId !== void 0) {
|
|
13939
|
-
if (
|
|
13940
|
-
|
|
13879
|
+
if (state4.workspacePullResultCache.size >= WORKSPACE_PULL_RESULT_CACHE_MAX) {
|
|
13880
|
+
state4.workspacePullResultCache.clear();
|
|
13941
13881
|
}
|
|
13942
|
-
|
|
13882
|
+
state4.workspacePullResultCache.set(normalizedPath, {
|
|
13943
13883
|
uri: item.uri,
|
|
13944
13884
|
resultId: item.resultId,
|
|
13945
13885
|
diagnostics,
|
|
13946
13886
|
contentHash: contentHash2
|
|
13947
13887
|
});
|
|
13948
13888
|
} else {
|
|
13949
|
-
|
|
13889
|
+
state4.workspacePullResultCache.delete(normalizedPath);
|
|
13950
13890
|
}
|
|
13951
13891
|
out.push({ filePath, diagnostics, contentHash: contentHash2 });
|
|
13952
13892
|
}
|
|
13953
13893
|
return out;
|
|
13954
13894
|
} catch (err) {
|
|
13955
13895
|
if (isPullTimeoutError(err, workspacePullTimeoutMs)) {
|
|
13956
|
-
trackAbandonedPullRequest(
|
|
13896
|
+
trackAbandonedPullRequest(state4, WORKSPACE_PULL_SCOPE, workspaceRequestPromise);
|
|
13957
13897
|
workspacePullAbort.abort();
|
|
13958
13898
|
recordPullTimeoutTelemetry({
|
|
13959
13899
|
scope: WORKSPACE_PULL_SCOPE,
|
|
@@ -13961,7 +13901,7 @@ async function clientRequestWorkspaceDiagnostics(state5, budgetMs) {
|
|
|
13961
13901
|
effectiveBudgetMs: workspacePullTimeoutMs,
|
|
13962
13902
|
hadPreviousResultId: previousResultIds.length > 0,
|
|
13963
13903
|
elapsedMs: Date.now() - workspacePullStartedAt,
|
|
13964
|
-
server:
|
|
13904
|
+
server: state4.serverId
|
|
13965
13905
|
});
|
|
13966
13906
|
armLateAnswerTelemetry({
|
|
13967
13907
|
requestPromise: workspaceRequestPromise,
|
|
@@ -13969,55 +13909,55 @@ async function clientRequestWorkspaceDiagnostics(state5, budgetMs) {
|
|
|
13969
13909
|
identifier: void 0,
|
|
13970
13910
|
subject: WORKSPACE_PULL_SCOPE,
|
|
13971
13911
|
requestStartedAt: workspacePullStartedAt,
|
|
13972
|
-
server:
|
|
13912
|
+
server: state4.serverId,
|
|
13973
13913
|
settlement: workspacePullSettlement
|
|
13974
13914
|
});
|
|
13975
13915
|
}
|
|
13976
|
-
recordPullFailure(
|
|
13916
|
+
recordPullFailure(state4, "workspace/diagnostic", err);
|
|
13977
13917
|
return void 0;
|
|
13978
13918
|
}
|
|
13979
13919
|
}
|
|
13980
|
-
async function clientWaitForDiagnostics(
|
|
13920
|
+
async function clientWaitForDiagnostics(state4, filePath, timeoutMs, options = {}) {
|
|
13981
13921
|
const normalizedPath = normalizeMapKey(filePath);
|
|
13982
13922
|
const minVersion = options.minVersion;
|
|
13983
13923
|
const pullSettleSource = options.pullSettleSource ?? "pull";
|
|
13984
|
-
const hasFreshDiagnostics = () => minVersion === void 0 || diagnosticsVersionForPath(
|
|
13924
|
+
const hasFreshDiagnostics = () => minVersion === void 0 || diagnosticsVersionForPath(state4, normalizedPath) > minVersion;
|
|
13985
13925
|
const isVersionStale = () => {
|
|
13986
|
-
const cachedVersion =
|
|
13926
|
+
const cachedVersion = state4.diagnosticDocVersions?.get(normalizedPath);
|
|
13987
13927
|
if (cachedVersion === void 0)
|
|
13988
13928
|
return false;
|
|
13989
|
-
const currentVersion =
|
|
13929
|
+
const currentVersion = state4.documentVersions?.get(normalizedPath);
|
|
13990
13930
|
return currentVersion !== void 0 && cachedVersion < currentVersion;
|
|
13991
13931
|
};
|
|
13992
|
-
if (
|
|
13932
|
+
if (state4.workspaceDiagnosticsSupport.mode === "pull") {
|
|
13993
13933
|
const pullSettleStartedAt = Date.now();
|
|
13994
|
-
let outcome = await clientRequestPullDiagnostics(
|
|
13934
|
+
let outcome = await clientRequestPullDiagnostics(state4, filePath, timeoutMs);
|
|
13995
13935
|
if (outcome.status === "found") {
|
|
13996
|
-
logTypeScriptPullSettle(
|
|
13936
|
+
logTypeScriptPullSettle(state4, normalizedPath, Date.now() - pullSettleStartedAt, pullSettleSource);
|
|
13997
13937
|
return;
|
|
13998
13938
|
}
|
|
13999
13939
|
let sawClean = outcome.status === "clean";
|
|
14000
|
-
const strategy = getStrategy(
|
|
13940
|
+
const strategy = getStrategy(state4.serverId, state4.launchVariant);
|
|
14001
13941
|
const retryBudgetMs = strategy.pullRetryBudgetMs > 0 ? Math.min(timeoutMs, strategy.pullRetryBudgetMs) : 0;
|
|
14002
13942
|
const startedAt = Date.now();
|
|
14003
13943
|
while (outcome.status !== "found" && Date.now() - startedAt < retryBudgetMs) {
|
|
14004
13944
|
await new Promise((resolve9) => setTimeout(resolve9, PULL_DIAGNOSTICS_RETRY_INTERVAL_MS));
|
|
14005
|
-
outcome = await clientRequestPullDiagnostics(
|
|
13945
|
+
outcome = await clientRequestPullDiagnostics(state4, filePath, Math.max(0, retryBudgetMs - (Date.now() - startedAt)));
|
|
14006
13946
|
if (outcome.status === "clean")
|
|
14007
13947
|
sawClean = true;
|
|
14008
13948
|
}
|
|
14009
13949
|
if (options.pullOnly) {
|
|
14010
13950
|
if (outcome.status === "found" || sawClean) {
|
|
14011
|
-
logTypeScriptPullSettle(
|
|
13951
|
+
logTypeScriptPullSettle(state4, normalizedPath, Date.now() - pullSettleStartedAt, pullSettleSource);
|
|
14012
13952
|
}
|
|
14013
13953
|
return;
|
|
14014
13954
|
}
|
|
14015
13955
|
if (outcome.status === "found" || sawClean) {
|
|
14016
|
-
logTypeScriptPullSettle(
|
|
13956
|
+
logTypeScriptPullSettle(state4, normalizedPath, Date.now() - pullSettleStartedAt, pullSettleSource);
|
|
14017
13957
|
return;
|
|
14018
13958
|
}
|
|
14019
13959
|
}
|
|
14020
|
-
if (hasFreshDiagnostics() && !isVersionStale() && getMergedDiagnosticsForPath(
|
|
13960
|
+
if (hasFreshDiagnostics() && !isVersionStale() && getMergedDiagnosticsForPath(state4, normalizedPath).length > 0) {
|
|
14021
13961
|
return;
|
|
14022
13962
|
}
|
|
14023
13963
|
return new Promise((resolve9) => {
|
|
@@ -14029,124 +13969,124 @@ async function clientWaitForDiagnostics(state5, filePath, timeoutMs, options = {
|
|
|
14029
13969
|
return;
|
|
14030
13970
|
if (debounceTimer)
|
|
14031
13971
|
clearTimeout(debounceTimer);
|
|
14032
|
-
const strategy = getStrategy(
|
|
14033
|
-
const hit =
|
|
13972
|
+
const strategy = getStrategy(state4.serverId, state4.launchVariant);
|
|
13973
|
+
const hit = state4.pushDiagnosticTimestamps.get(normalizedPath);
|
|
14034
13974
|
const timeSincePush = hit ? Date.now() - hit : Infinity;
|
|
14035
13975
|
const remaining = Math.max(0, strategy.debounceMs - timeSincePush);
|
|
14036
13976
|
debounceTimer = setTimeout(() => {
|
|
14037
|
-
|
|
13977
|
+
state4.diagnosticEmitter.off("diagnostics", onDiagnostics);
|
|
14038
13978
|
clearTimeout(timeout);
|
|
14039
13979
|
resolve9();
|
|
14040
13980
|
}, remaining);
|
|
14041
13981
|
};
|
|
14042
|
-
|
|
13982
|
+
state4.diagnosticEmitter.on("diagnostics", onDiagnostics);
|
|
14043
13983
|
const timeout = setTimeout(() => {
|
|
14044
13984
|
if (debounceTimer)
|
|
14045
13985
|
clearTimeout(debounceTimer);
|
|
14046
|
-
|
|
13986
|
+
state4.diagnosticEmitter.off("diagnostics", onDiagnostics);
|
|
14047
13987
|
resolve9();
|
|
14048
13988
|
}, timeoutMs);
|
|
14049
13989
|
});
|
|
14050
13990
|
}
|
|
14051
|
-
function handleNotifyExternalChange(
|
|
14052
|
-
if (!isClientAlive(
|
|
13991
|
+
function handleNotifyExternalChange(state4, filePath, type) {
|
|
13992
|
+
if (!isClientAlive(state4))
|
|
14053
13993
|
return;
|
|
14054
13994
|
const normalizedPath = normalizeMapKey(filePath);
|
|
14055
|
-
const uri =
|
|
14056
|
-
|
|
13995
|
+
const uri = state4.openDocumentUris?.get(normalizedPath) ?? pathToFileURL2(filePath).href;
|
|
13996
|
+
state4.watchQueue.enqueue(uri, type);
|
|
14057
13997
|
}
|
|
14058
|
-
function expectSaveRescan(
|
|
14059
|
-
if (!getStrategy(
|
|
13998
|
+
function expectSaveRescan(state4, normalizedPath) {
|
|
13999
|
+
if (!getStrategy(state4.serverId, state4.launchVariant).rescansOnSave)
|
|
14060
14000
|
return;
|
|
14061
|
-
const beyond =
|
|
14001
|
+
const beyond = state4.expectedPublicationsBeyondSends;
|
|
14062
14002
|
beyond?.set(normalizedPath, (beyond.get(normalizedPath) ?? 0) + 1);
|
|
14063
14003
|
}
|
|
14064
|
-
async function sendDidSave(
|
|
14065
|
-
const save =
|
|
14004
|
+
async function sendDidSave(state4, normalizedPath, uri, content) {
|
|
14005
|
+
const save = state4.saveOptions;
|
|
14066
14006
|
if (!save)
|
|
14067
14007
|
return;
|
|
14068
|
-
if (!isClientAlive(
|
|
14008
|
+
if (!isClientAlive(state4))
|
|
14069
14009
|
return;
|
|
14070
|
-
expectSaveRescan(
|
|
14010
|
+
expectSaveRescan(state4, normalizedPath);
|
|
14071
14011
|
const limit = save.includeText ? exceedsLspSyncLimits(content) : { tooLarge: false, reason: "" };
|
|
14072
14012
|
if (limit.tooLarge) {
|
|
14073
14013
|
recordDegradationOnce({
|
|
14074
14014
|
kind: "lsp-did-save-text-omitted",
|
|
14075
|
-
subject:
|
|
14015
|
+
subject: state4.serverId,
|
|
14076
14016
|
reason: limit.reason
|
|
14077
14017
|
});
|
|
14078
14018
|
}
|
|
14079
|
-
await safeSendNotification(
|
|
14019
|
+
await safeSendNotification(state4.connection, "textDocument/didSave", {
|
|
14080
14020
|
textDocument: { uri },
|
|
14081
14021
|
...save.includeText && !limit.tooLarge ? { text: content } : {}
|
|
14082
14022
|
});
|
|
14083
14023
|
}
|
|
14084
|
-
async function sendDidSaveForHeldDocument(
|
|
14085
|
-
if (!
|
|
14024
|
+
async function sendDidSaveForHeldDocument(state4, normalizedPath) {
|
|
14025
|
+
if (!state4.saveOptions || !isClientAlive(state4))
|
|
14086
14026
|
return;
|
|
14087
|
-
if (!
|
|
14027
|
+
if (!state4.openDocuments.has(normalizedPath))
|
|
14088
14028
|
return;
|
|
14089
|
-
const uri =
|
|
14029
|
+
const uri = state4.openDocumentUris?.get(normalizedPath);
|
|
14090
14030
|
if (uri === void 0)
|
|
14091
14031
|
return;
|
|
14092
|
-
expectSaveRescan(
|
|
14032
|
+
expectSaveRescan(state4, normalizedPath);
|
|
14093
14033
|
try {
|
|
14094
|
-
await safeSendNotification(
|
|
14034
|
+
await safeSendNotification(state4.connection, "textDocument/didSave", {
|
|
14095
14035
|
textDocument: { uri }
|
|
14096
14036
|
});
|
|
14097
14037
|
} catch {
|
|
14098
14038
|
}
|
|
14099
14039
|
}
|
|
14100
|
-
async function handleNotifyOpenOnce(
|
|
14101
|
-
if (!isClientAlive(
|
|
14040
|
+
async function handleNotifyOpenOnce(state4, filePath, content, languageId, preserveDiagnostics = false, silent = false, coalescedCount = 0, saved = false) {
|
|
14041
|
+
if (!isClientAlive(state4))
|
|
14102
14042
|
return false;
|
|
14103
14043
|
const normalizedPath = normalizeMapKey(filePath);
|
|
14104
|
-
const uri =
|
|
14105
|
-
if (
|
|
14106
|
-
const version = (
|
|
14107
|
-
|
|
14044
|
+
const uri = state4.openDocumentUris?.get(normalizedPath) ?? pathToFileURL2(filePath).href;
|
|
14045
|
+
if (state4.openDocuments.has(normalizedPath) || state4.pendingOpens.has(normalizedPath)) {
|
|
14046
|
+
const version = (state4.documentVersions.get(normalizedPath) ?? 0) + 1;
|
|
14047
|
+
state4.documentVersions.set(normalizedPath, version);
|
|
14108
14048
|
if (!preserveDiagnostics) {
|
|
14109
|
-
clearDiagnosticsForPath(
|
|
14049
|
+
clearDiagnosticsForPath(state4, normalizedPath);
|
|
14110
14050
|
}
|
|
14111
|
-
if (getStrategy(
|
|
14112
|
-
await safeSendNotification(
|
|
14051
|
+
if (getStrategy(state4.serverId, state4.launchVariant).reopenOnResync) {
|
|
14052
|
+
await safeSendNotification(state4.connection, "textDocument/didClose", {
|
|
14113
14053
|
textDocument: { uri }
|
|
14114
14054
|
});
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14118
|
-
|
|
14119
|
-
|
|
14120
|
-
if (!isClientAlive(
|
|
14055
|
+
state4.openDocuments.delete(normalizedPath);
|
|
14056
|
+
state4.openDocumentUris?.delete(normalizedPath);
|
|
14057
|
+
state4.documentVersions.set(normalizedPath, version);
|
|
14058
|
+
state4.documentOpenedAt.set(normalizedPath, Date.now());
|
|
14059
|
+
state4.diagnosticPublicationCounts.set(normalizedPath, 0);
|
|
14060
|
+
if (!isClientAlive(state4))
|
|
14121
14061
|
return false;
|
|
14122
|
-
const reopenSent = await safeSendNotification(
|
|
14062
|
+
const reopenSent = await safeSendNotification(state4.connection, "textDocument/didOpen", { textDocument: { uri, languageId, version, text: content } });
|
|
14123
14063
|
if (reopenSent)
|
|
14124
|
-
recordSentContent(
|
|
14125
|
-
|
|
14126
|
-
|
|
14064
|
+
recordSentContent(state4, normalizedPath, version, content, coalescedCount);
|
|
14065
|
+
state4.openDocuments.add(normalizedPath);
|
|
14066
|
+
state4.openDocumentUris?.set(normalizedPath, uri);
|
|
14127
14067
|
if (saved && reopenSent)
|
|
14128
|
-
await sendDidSave(
|
|
14068
|
+
await sendDidSave(state4, normalizedPath, uri, content);
|
|
14129
14069
|
return reopenSent;
|
|
14130
14070
|
}
|
|
14131
|
-
const changeSent = await sendFenced(
|
|
14071
|
+
const changeSent = await sendFenced(state4, normalizedPath, uri, "textDocument/didChange", {
|
|
14132
14072
|
textDocument: { uri, version },
|
|
14133
|
-
contentChanges: buildContentChanges(
|
|
14073
|
+
contentChanges: buildContentChanges(state4, normalizedPath, content)
|
|
14134
14074
|
});
|
|
14135
14075
|
if (changeSent)
|
|
14136
|
-
recordSentContent(
|
|
14076
|
+
recordSentContent(state4, normalizedPath, version, content, coalescedCount);
|
|
14137
14077
|
if (saved && changeSent)
|
|
14138
|
-
await sendDidSave(
|
|
14078
|
+
await sendDidSave(state4, normalizedPath, uri, content);
|
|
14139
14079
|
return changeSent;
|
|
14140
14080
|
}
|
|
14141
|
-
if (await closedAndGone(
|
|
14081
|
+
if (await closedAndGone(state4, filePath, normalizedPath))
|
|
14142
14082
|
return false;
|
|
14143
|
-
|
|
14144
|
-
|
|
14145
|
-
|
|
14146
|
-
|
|
14147
|
-
clearDiagnosticsForPath(
|
|
14148
|
-
if (!
|
|
14149
|
-
|
|
14083
|
+
state4.pendingOpens.add(normalizedPath);
|
|
14084
|
+
state4.documentVersions.set(normalizedPath, 0);
|
|
14085
|
+
state4.documentOpenedAt.set(normalizedPath, Date.now());
|
|
14086
|
+
state4.diagnosticPublicationCounts.set(normalizedPath, 0);
|
|
14087
|
+
clearDiagnosticsForPath(state4, normalizedPath);
|
|
14088
|
+
if (!state4.expectedPublicationsBeyondSends?.has(normalizedPath))
|
|
14089
|
+
state4.publicationStoreCountsByPath?.delete(normalizedPath);
|
|
14150
14090
|
if (!silent) {
|
|
14151
14091
|
let fileExists = true;
|
|
14152
14092
|
try {
|
|
@@ -14154,37 +14094,37 @@ async function handleNotifyOpenOnce(state5, filePath, content, languageId, prese
|
|
|
14154
14094
|
} catch {
|
|
14155
14095
|
fileExists = false;
|
|
14156
14096
|
}
|
|
14157
|
-
|
|
14097
|
+
state4.watchQueue.enqueue(uri, fileExists ? 2 : 1);
|
|
14158
14098
|
}
|
|
14159
|
-
if (!isClientAlive(
|
|
14099
|
+
if (!isClientAlive(state4))
|
|
14160
14100
|
return false;
|
|
14161
|
-
const openSent = await sendFenced(
|
|
14101
|
+
const openSent = await sendFenced(state4, normalizedPath, uri, "textDocument/didOpen", { textDocument: { uri, languageId, version: 0, text: content } });
|
|
14162
14102
|
if (openSent)
|
|
14163
|
-
recordSentContent(
|
|
14164
|
-
|
|
14165
|
-
|
|
14166
|
-
|
|
14167
|
-
|
|
14103
|
+
recordSentContent(state4, normalizedPath, 0, content, coalescedCount);
|
|
14104
|
+
state4.pendingOpens.delete(normalizedPath);
|
|
14105
|
+
state4.openDocuments.add(normalizedPath);
|
|
14106
|
+
state4.closedDocuments?.delete(normalizedPath);
|
|
14107
|
+
state4.openDocumentUris?.set(normalizedPath, uri);
|
|
14168
14108
|
if (saved && openSent)
|
|
14169
|
-
await sendDidSave(
|
|
14109
|
+
await sendDidSave(state4, normalizedPath, uri, content);
|
|
14170
14110
|
void probeTsserverProjectIdentity({
|
|
14171
|
-
serverId:
|
|
14172
|
-
launchVariant:
|
|
14173
|
-
clientRoot:
|
|
14111
|
+
serverId: state4.serverId,
|
|
14112
|
+
launchVariant: state4.launchVariant,
|
|
14113
|
+
clientRoot: state4.root,
|
|
14174
14114
|
file: filePath,
|
|
14175
14115
|
normalizedFile: normalizedPath,
|
|
14176
|
-
probedFiles:
|
|
14116
|
+
probedFiles: state4.projectIdentityProbedFiles ?? (state4.projectIdentityProbedFiles = /* @__PURE__ */ new Set()),
|
|
14177
14117
|
commandChannel: {
|
|
14178
|
-
executeCommand: (command, args) => runReadOnlyServerCommand(
|
|
14118
|
+
executeCommand: (command, args) => runReadOnlyServerCommand(state4, command, args)
|
|
14179
14119
|
}
|
|
14180
14120
|
});
|
|
14181
14121
|
return openSent;
|
|
14182
14122
|
}
|
|
14183
|
-
function enqueueDocumentNotify(
|
|
14184
|
-
let queue =
|
|
14123
|
+
function enqueueDocumentNotify(state4, normalizedPath, run, saved = false, readStamp, close = false) {
|
|
14124
|
+
let queue = state4.notifyChangeQueues.get(normalizedPath);
|
|
14185
14125
|
if (!queue) {
|
|
14186
14126
|
queue = { running: false };
|
|
14187
|
-
|
|
14127
|
+
state4.notifyChangeQueues.set(normalizedPath, queue);
|
|
14188
14128
|
}
|
|
14189
14129
|
return new Promise((resolve9, reject) => {
|
|
14190
14130
|
if (queue.closing && !close) {
|
|
@@ -14198,7 +14138,7 @@ function enqueueDocumentNotify(state5, normalizedPath, run, saved = false, readS
|
|
|
14198
14138
|
waiter.stale = true;
|
|
14199
14139
|
queue.closing = true;
|
|
14200
14140
|
}
|
|
14201
|
-
const lastSent =
|
|
14141
|
+
const lastSent = state4.sentReadStamps.get(normalizedPath);
|
|
14202
14142
|
const before = (a, b) => a !== void 0 && b !== void 0 && a < b;
|
|
14203
14143
|
const stale = previous !== void 0 && (before(readStamp, previous.readStamp) || before(readStamp, lastSent));
|
|
14204
14144
|
const heldStamp = before(previous?.readStamp, lastSent) ? void 0 : previous?.readStamp;
|
|
@@ -14224,16 +14164,16 @@ function enqueueDocumentNotify(state5, normalizedPath, run, saved = false, readS
|
|
|
14224
14164
|
if (!next)
|
|
14225
14165
|
break;
|
|
14226
14166
|
queue.pending = void 0;
|
|
14227
|
-
const lastSent2 =
|
|
14167
|
+
const lastSent2 = state4.sentReadStamps.get(normalizedPath);
|
|
14228
14168
|
if (next.readStamp !== void 0 && lastSent2 !== void 0 && next.readStamp < lastSent2) {
|
|
14229
14169
|
if (next.saved)
|
|
14230
|
-
await sendDidSaveForHeldDocument(
|
|
14170
|
+
await sendDidSaveForHeldDocument(state4, normalizedPath);
|
|
14231
14171
|
for (const waiter of next.waiters)
|
|
14232
14172
|
waiter.resolve(false);
|
|
14233
14173
|
continue;
|
|
14234
14174
|
}
|
|
14235
14175
|
if (next.readStamp !== void 0)
|
|
14236
|
-
|
|
14176
|
+
state4.sentReadStamps.set(normalizedPath, next.readStamp);
|
|
14237
14177
|
try {
|
|
14238
14178
|
const sent = await next.run(next.coalescedCount, next.saved);
|
|
14239
14179
|
for (const waiter of next.waiters)
|
|
@@ -14245,33 +14185,33 @@ function enqueueDocumentNotify(state5, normalizedPath, run, saved = false, readS
|
|
|
14245
14185
|
}
|
|
14246
14186
|
} finally {
|
|
14247
14187
|
queue.running = false;
|
|
14248
|
-
if (!queue.pending &&
|
|
14249
|
-
|
|
14188
|
+
if (!queue.pending && state4.notifyChangeQueues.get(normalizedPath) === queue) {
|
|
14189
|
+
state4.notifyChangeQueues.delete(normalizedPath);
|
|
14250
14190
|
}
|
|
14251
14191
|
}
|
|
14252
14192
|
});
|
|
14253
14193
|
});
|
|
14254
14194
|
}
|
|
14255
|
-
function cancelDocumentNotifyQueues(
|
|
14256
|
-
for (const queue of
|
|
14195
|
+
function cancelDocumentNotifyQueues(state4) {
|
|
14196
|
+
for (const queue of state4.notifyChangeQueues.values()) {
|
|
14257
14197
|
for (const waiter of queue.pending?.waiters ?? [])
|
|
14258
14198
|
waiter.resolve(false);
|
|
14259
14199
|
queue.pending = void 0;
|
|
14260
14200
|
}
|
|
14261
|
-
|
|
14201
|
+
state4.notifyChangeQueues.clear();
|
|
14262
14202
|
}
|
|
14263
|
-
function handleNotifyOpen(
|
|
14203
|
+
function handleNotifyOpen(state4, filePath, content, languageId, preserveDiagnostics = false, silent = false, saved = false, readStamp) {
|
|
14264
14204
|
const normalizedPath = normalizeMapKey(filePath);
|
|
14265
|
-
return enqueueDocumentNotify(
|
|
14205
|
+
return enqueueDocumentNotify(state4, normalizedPath, (coalescedCount, queuedSaved) => handleNotifyOpenOnce(state4, filePath, content, languageId, preserveDiagnostics, silent, coalescedCount, queuedSaved), saved, readStamp);
|
|
14266
14206
|
}
|
|
14267
|
-
async function handleNotifyChangeOnce(
|
|
14268
|
-
if (!isClientAlive(
|
|
14207
|
+
async function handleNotifyChangeOnce(state4, filePath, content, normalizedPath, coalescedCount = 0, saved = false) {
|
|
14208
|
+
if (!isClientAlive(state4))
|
|
14269
14209
|
return false;
|
|
14270
|
-
const uri =
|
|
14271
|
-
if (!
|
|
14272
|
-
if (await closedAndGone(
|
|
14210
|
+
const uri = state4.openDocumentUris?.get(normalizedPath) ?? pathToFileURL2(filePath).href;
|
|
14211
|
+
if (!state4.openDocuments.has(normalizedPath)) {
|
|
14212
|
+
if (await closedAndGone(state4, filePath, normalizedPath))
|
|
14273
14213
|
return false;
|
|
14274
|
-
const fallbackOpenSent = await sendFenced(
|
|
14214
|
+
const fallbackOpenSent = await sendFenced(state4, normalizedPath, uri, "textDocument/didOpen", {
|
|
14275
14215
|
textDocument: {
|
|
14276
14216
|
uri,
|
|
14277
14217
|
languageId: "plaintext",
|
|
@@ -14279,37 +14219,37 @@ async function handleNotifyChangeOnce(state5, filePath, content, normalizedPath,
|
|
|
14279
14219
|
text: content
|
|
14280
14220
|
}
|
|
14281
14221
|
});
|
|
14282
|
-
|
|
14283
|
-
|
|
14284
|
-
|
|
14222
|
+
state4.documentVersions.set(normalizedPath, 0);
|
|
14223
|
+
state4.documentOpenedAt.set(normalizedPath, Date.now());
|
|
14224
|
+
state4.diagnosticPublicationCounts.set(normalizedPath, 0);
|
|
14285
14225
|
if (fallbackOpenSent)
|
|
14286
|
-
recordSentContent(
|
|
14287
|
-
|
|
14288
|
-
|
|
14289
|
-
|
|
14226
|
+
recordSentContent(state4, normalizedPath, 0, content, coalescedCount);
|
|
14227
|
+
state4.openDocuments.add(normalizedPath);
|
|
14228
|
+
state4.closedDocuments?.delete(normalizedPath);
|
|
14229
|
+
state4.openDocumentUris?.set(normalizedPath, uri);
|
|
14290
14230
|
if (saved && fallbackOpenSent)
|
|
14291
|
-
await sendDidSave(
|
|
14231
|
+
await sendDidSave(state4, normalizedPath, uri, content);
|
|
14292
14232
|
return fallbackOpenSent;
|
|
14293
14233
|
}
|
|
14294
|
-
const version = (
|
|
14295
|
-
|
|
14296
|
-
clearDiagnosticsForPath(
|
|
14297
|
-
const changeSent = await sendFenced(
|
|
14234
|
+
const version = (state4.documentVersions.get(normalizedPath) ?? 0) + 1;
|
|
14235
|
+
state4.documentVersions.set(normalizedPath, version);
|
|
14236
|
+
clearDiagnosticsForPath(state4, normalizedPath);
|
|
14237
|
+
const changeSent = await sendFenced(state4, normalizedPath, uri, "textDocument/didChange", {
|
|
14298
14238
|
textDocument: { uri, version },
|
|
14299
|
-
contentChanges: buildContentChanges(
|
|
14239
|
+
contentChanges: buildContentChanges(state4, normalizedPath, content)
|
|
14300
14240
|
});
|
|
14301
14241
|
if (changeSent)
|
|
14302
|
-
recordSentContent(
|
|
14242
|
+
recordSentContent(state4, normalizedPath, version, content, coalescedCount);
|
|
14303
14243
|
if (saved && changeSent)
|
|
14304
|
-
await sendDidSave(
|
|
14244
|
+
await sendDidSave(state4, normalizedPath, uri, content);
|
|
14305
14245
|
return changeSent;
|
|
14306
14246
|
}
|
|
14307
|
-
function handleNotifyChange(
|
|
14247
|
+
function handleNotifyChange(state4, filePath, content) {
|
|
14308
14248
|
const normalizedPath = normalizeMapKey(filePath);
|
|
14309
|
-
return enqueueDocumentNotify(
|
|
14249
|
+
return enqueueDocumentNotify(state4, normalizedPath, (coalescedCount, queuedSaved) => handleNotifyChangeOnce(state4, filePath, content, normalizedPath, coalescedCount, queuedSaved));
|
|
14310
14250
|
}
|
|
14311
|
-
async function closedAndGone(
|
|
14312
|
-
if (!
|
|
14251
|
+
async function closedAndGone(state4, filePath, normalizedPath) {
|
|
14252
|
+
if (!state4.closedDocuments?.has(normalizedPath))
|
|
14313
14253
|
return false;
|
|
14314
14254
|
try {
|
|
14315
14255
|
await access(filePath);
|
|
@@ -14318,76 +14258,76 @@ async function closedAndGone(state5, filePath, normalizedPath) {
|
|
|
14318
14258
|
return true;
|
|
14319
14259
|
}
|
|
14320
14260
|
}
|
|
14321
|
-
async function closeDocument(
|
|
14322
|
-
if (!isClientAlive(
|
|
14261
|
+
async function closeDocument(state4, filePath) {
|
|
14262
|
+
if (!isClientAlive(state4))
|
|
14323
14263
|
return;
|
|
14324
14264
|
const normalizedPath = normalizeMapKey(filePath);
|
|
14325
|
-
await enqueueDocumentNotify(
|
|
14265
|
+
await enqueueDocumentNotify(state4, normalizedPath, () => closeDocumentOnce(state4, filePath, normalizedPath), false, void 0, true);
|
|
14326
14266
|
}
|
|
14327
|
-
async function closeDocumentOnce(
|
|
14328
|
-
if (!isClientAlive(
|
|
14267
|
+
async function closeDocumentOnce(state4, filePath, normalizedPath) {
|
|
14268
|
+
if (!isClientAlive(state4))
|
|
14329
14269
|
return;
|
|
14330
|
-
if (!
|
|
14331
|
-
|
|
14270
|
+
if (!state4.openDocuments.has(normalizedPath)) {
|
|
14271
|
+
state4.closedDocuments?.add(normalizedPath);
|
|
14332
14272
|
return;
|
|
14333
14273
|
}
|
|
14334
|
-
await safeSendNotification(
|
|
14274
|
+
await safeSendNotification(state4.connection, "textDocument/didClose", {
|
|
14335
14275
|
textDocument: {
|
|
14336
|
-
uri:
|
|
14276
|
+
uri: state4.openDocumentUris?.get(normalizedPath) ?? pathToFileURL2(filePath).href
|
|
14337
14277
|
}
|
|
14338
14278
|
});
|
|
14339
|
-
|
|
14340
|
-
|
|
14341
|
-
|
|
14342
|
-
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
|
|
14346
|
-
|
|
14347
|
-
|
|
14348
|
-
const retained =
|
|
14279
|
+
state4.openDocuments.delete(normalizedPath);
|
|
14280
|
+
state4.closedDocuments?.add(normalizedPath);
|
|
14281
|
+
state4.openDocumentUris?.delete(normalizedPath);
|
|
14282
|
+
state4.expectedPublicationsBeyondSends?.set(normalizedPath, publicationCountsForPath(state4, normalizedPath).sent);
|
|
14283
|
+
state4.documentVersions.delete(normalizedPath);
|
|
14284
|
+
state4.sentReadStamps.delete(normalizedPath);
|
|
14285
|
+
state4.documentOpenedAt.delete(normalizedPath);
|
|
14286
|
+
state4.diagnosticPublicationCounts.delete(normalizedPath);
|
|
14287
|
+
state4.projectIdentityProbedFiles?.delete(normalizedPath);
|
|
14288
|
+
const retained = state4.documentContentHashes.get(normalizedPath);
|
|
14349
14289
|
if (retained?.text !== void 0) {
|
|
14350
|
-
|
|
14351
|
-
|
|
14352
|
-
|
|
14290
|
+
state4.incrementalTextRetainedEntries = Math.max(0, (state4.incrementalTextRetainedEntries ?? 1) - 1);
|
|
14291
|
+
state4.incrementalTextRetainedBytes = Math.max(0, (state4.incrementalTextRetainedBytes ?? retained.text.length * 2) - retained.text.length * 2);
|
|
14292
|
+
state4.incrementalTextBearingPaths?.delete(normalizedPath);
|
|
14353
14293
|
}
|
|
14354
|
-
|
|
14355
|
-
clearDiagnosticsForPath(
|
|
14294
|
+
state4.documentContentHashes.delete(normalizedPath);
|
|
14295
|
+
clearDiagnosticsForPath(state4, normalizedPath);
|
|
14356
14296
|
}
|
|
14357
14297
|
function isAtLeastAsAggressiveShutdown(existing, requested) {
|
|
14358
14298
|
return !!existing.fast >= !!requested.fast && !!existing.processExiting >= !!requested.processExiting;
|
|
14359
14299
|
}
|
|
14360
|
-
function clientShutdown(
|
|
14361
|
-
if (
|
|
14362
|
-
return
|
|
14300
|
+
function clientShutdown(state4, options = {}) {
|
|
14301
|
+
if (state4.shutdownPromise && state4.shutdownOptions && isAtLeastAsAggressiveShutdown(state4.shutdownOptions, options)) {
|
|
14302
|
+
return state4.shutdownPromise;
|
|
14363
14303
|
}
|
|
14364
|
-
|
|
14365
|
-
const attempt = clientShutdownOnce(
|
|
14366
|
-
|
|
14304
|
+
state4.shutdownOptions = options;
|
|
14305
|
+
const attempt = clientShutdownOnce(state4, options);
|
|
14306
|
+
state4.shutdownPromise = attempt;
|
|
14367
14307
|
attempt.catch(() => {
|
|
14368
|
-
if (
|
|
14369
|
-
|
|
14370
|
-
|
|
14308
|
+
if (state4.shutdownPromise === attempt) {
|
|
14309
|
+
state4.shutdownPromise = void 0;
|
|
14310
|
+
state4.shutdownOptions = void 0;
|
|
14371
14311
|
}
|
|
14372
14312
|
});
|
|
14373
14313
|
return attempt;
|
|
14374
14314
|
}
|
|
14375
|
-
async function clientShutdownOnce(
|
|
14315
|
+
async function clientShutdownOnce(state4, options) {
|
|
14376
14316
|
const shutdownStart = Date.now();
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
for (const timer of
|
|
14317
|
+
state4.shutdownRequested = true;
|
|
14318
|
+
state4.isConnected = false;
|
|
14319
|
+
state4.isDestroyed = true;
|
|
14320
|
+
for (const timer of state4.pendingDiagnostics.values()) {
|
|
14381
14321
|
clearTimeout(timer);
|
|
14382
14322
|
}
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
|
|
14386
|
-
|
|
14387
|
-
cancelDocumentNotifyQueues(
|
|
14388
|
-
|
|
14389
|
-
|
|
14390
|
-
|
|
14323
|
+
state4.pendingDiagnostics.clear();
|
|
14324
|
+
state4.pendingOpens.clear();
|
|
14325
|
+
state4.openDocuments.clear();
|
|
14326
|
+
state4.openDocumentUris?.clear();
|
|
14327
|
+
cancelDocumentNotifyQueues(state4);
|
|
14328
|
+
state4.projectIdentityProbedFiles?.clear();
|
|
14329
|
+
state4.watchQueue?.cancel();
|
|
14330
|
+
state4.diagnosticEmitter.removeAllListeners();
|
|
14391
14331
|
let shutdownRequestTimedOut = false;
|
|
14392
14332
|
let exitNotifyTimedOut = false;
|
|
14393
14333
|
let shutdownRequestUndelivered = false;
|
|
@@ -14395,7 +14335,7 @@ async function clientShutdownOnce(state5, options) {
|
|
|
14395
14335
|
try {
|
|
14396
14336
|
if (!options.fast) {
|
|
14397
14337
|
try {
|
|
14398
|
-
const shutdownAck = await withTimeout(safeSendRequest(
|
|
14338
|
+
const shutdownAck = await withTimeout(safeSendRequest(state4.connection, "shutdown", {}), SHUTDOWN_REQUEST_TIMEOUT_MS);
|
|
14399
14339
|
if (shutdownAck === void 0)
|
|
14400
14340
|
shutdownRequestUndelivered = true;
|
|
14401
14341
|
} catch (err) {
|
|
@@ -14406,7 +14346,7 @@ async function clientShutdownOnce(state5, options) {
|
|
|
14406
14346
|
}
|
|
14407
14347
|
}
|
|
14408
14348
|
try {
|
|
14409
|
-
const exitSent = await withTimeout(safeSendNotification(
|
|
14349
|
+
const exitSent = await withTimeout(safeSendNotification(state4.connection, "exit", {}), EXIT_NOTIFY_TIMEOUT_MS);
|
|
14410
14350
|
if (exitSent === false)
|
|
14411
14351
|
exitNotifyUndelivered = true;
|
|
14412
14352
|
} catch (err) {
|
|
@@ -14418,15 +14358,15 @@ async function clientShutdownOnce(state5, options) {
|
|
|
14418
14358
|
}
|
|
14419
14359
|
}
|
|
14420
14360
|
} finally {
|
|
14421
|
-
disposeClientConnection(
|
|
14422
|
-
const pid =
|
|
14361
|
+
disposeClientConnection(state4);
|
|
14362
|
+
const pid = state4.lspProcess.pid;
|
|
14423
14363
|
logLatency({
|
|
14424
14364
|
type: "phase",
|
|
14425
14365
|
phase: "lsp_client_shutdown",
|
|
14426
|
-
filePath:
|
|
14366
|
+
filePath: state4.root,
|
|
14427
14367
|
durationMs: Date.now() - shutdownStart,
|
|
14428
14368
|
metadata: {
|
|
14429
|
-
serverId:
|
|
14369
|
+
serverId: state4.serverId,
|
|
14430
14370
|
pid,
|
|
14431
14371
|
fast: !!options.fast,
|
|
14432
14372
|
processExiting: !!options.processExiting,
|
|
@@ -14448,7 +14388,7 @@ async function clientShutdownOnce(state5, options) {
|
|
|
14448
14388
|
shutdownOutcome: options.fast ? "fast" : shutdownRequestTimedOut || exitNotifyTimedOut || shutdownRequestUndelivered || exitNotifyUndelivered ? "forced" : "graceful"
|
|
14449
14389
|
}
|
|
14450
14390
|
});
|
|
14451
|
-
void removeLspChild(pid, extractSpawnMarker(
|
|
14391
|
+
void removeLspChild(pid, extractSpawnMarker(state4.lspProcess.args)).catch((err) => {
|
|
14452
14392
|
logLatency({
|
|
14453
14393
|
type: "phase",
|
|
14454
14394
|
phase: "lsp_registry_write_failed",
|
|
@@ -14457,17 +14397,17 @@ async function clientShutdownOnce(state5, options) {
|
|
|
14457
14397
|
metadata: { op: "remove", pid, error: String(err) }
|
|
14458
14398
|
});
|
|
14459
14399
|
});
|
|
14460
|
-
await killProcessTree(
|
|
14400
|
+
await killProcessTree(state4.lspProcess.process, pid, options);
|
|
14461
14401
|
}
|
|
14462
14402
|
}
|
|
14463
|
-
async function toWirePosition(
|
|
14464
|
-
if (
|
|
14403
|
+
async function toWirePosition(state4, filePath, line, character) {
|
|
14404
|
+
if (state4.positionEncoding === "utf-16")
|
|
14465
14405
|
return { line, character };
|
|
14466
14406
|
try {
|
|
14467
14407
|
const content = await readFile(filePath, "utf8");
|
|
14468
14408
|
return {
|
|
14469
14409
|
line,
|
|
14470
|
-
character: convertCharacterOffset(
|
|
14410
|
+
character: convertCharacterOffset(state4.positionEncoding, lineTextAt(content, line), character)
|
|
14471
14411
|
};
|
|
14472
14412
|
} catch {
|
|
14473
14413
|
return { line, character };
|
|
@@ -14476,13 +14416,13 @@ async function toWirePosition(state5, filePath, line, character) {
|
|
|
14476
14416
|
function navStaleDropEnabled() {
|
|
14477
14417
|
return process.env.PI_LENS_LSP_NAV_STALE_DROP !== "0";
|
|
14478
14418
|
}
|
|
14479
|
-
async function navRequest(
|
|
14480
|
-
if (!isClientAlive(
|
|
14419
|
+
async function navRequest(state4, method, params, staleCheckPath, timeoutMs = NAV_REQUEST_TIMEOUT_MS, signal = getAmbientAbortSignal()) {
|
|
14420
|
+
if (!isClientAlive(state4))
|
|
14481
14421
|
return null;
|
|
14482
14422
|
const normalizedPath = staleCheckPath !== void 0 ? normalizeMapKey(staleCheckPath) : void 0;
|
|
14483
|
-
const requestVersion = normalizedPath !== void 0 ?
|
|
14423
|
+
const requestVersion = normalizedPath !== void 0 ? state4.documentVersions.get(normalizedPath) : void 0;
|
|
14484
14424
|
const requestStartedAt = Date.now();
|
|
14485
|
-
const requestPromise = safeSendRequest(
|
|
14425
|
+
const requestPromise = safeSendRequest(state4.connection, method, params, signal);
|
|
14486
14426
|
const result = await withTimeout(requestPromise, timeoutMs).catch((err) => {
|
|
14487
14427
|
if (isNavTimeoutError(err, timeoutMs)) {
|
|
14488
14428
|
recordNavTimeoutTelemetry({
|
|
@@ -14505,7 +14445,7 @@ async function navRequest(state5, method, params, staleCheckPath, timeoutMs = NA
|
|
|
14505
14445
|
throw err;
|
|
14506
14446
|
});
|
|
14507
14447
|
if (normalizedPath !== void 0 && requestVersion !== void 0 && navStaleDropEnabled()) {
|
|
14508
|
-
const currentVersion =
|
|
14448
|
+
const currentVersion = state4.documentVersions.get(normalizedPath);
|
|
14509
14449
|
if (currentVersion !== void 0 && currentVersion > requestVersion) {
|
|
14510
14450
|
return void 0;
|
|
14511
14451
|
}
|
|
@@ -14550,23 +14490,23 @@ function armNavLateAnswerTelemetry(args) {
|
|
|
14550
14490
|
}, () => {
|
|
14551
14491
|
});
|
|
14552
14492
|
}
|
|
14553
|
-
function chooseLivenessProbe(
|
|
14554
|
-
if (
|
|
14493
|
+
function chooseLivenessProbe(state4) {
|
|
14494
|
+
if (state4.operationSupport?.workspaceSymbol === true) {
|
|
14555
14495
|
return {
|
|
14556
14496
|
method: "workspace/symbol",
|
|
14557
14497
|
params: { query: LIVENESS_PING_QUERY }
|
|
14558
14498
|
};
|
|
14559
14499
|
}
|
|
14560
|
-
const openUri = firstOpenDocumentUri(
|
|
14500
|
+
const openUri = firstOpenDocumentUri(state4);
|
|
14561
14501
|
if (openUri === void 0)
|
|
14562
14502
|
return void 0;
|
|
14563
|
-
if (
|
|
14503
|
+
if (state4.operationSupport?.documentSymbol === true) {
|
|
14564
14504
|
return {
|
|
14565
14505
|
method: "textDocument/documentSymbol",
|
|
14566
14506
|
params: { textDocument: { uri: openUri } }
|
|
14567
14507
|
};
|
|
14568
14508
|
}
|
|
14569
|
-
if (
|
|
14509
|
+
if (state4.operationSupport?.hover === true) {
|
|
14570
14510
|
return {
|
|
14571
14511
|
method: "textDocument/hover",
|
|
14572
14512
|
params: {
|
|
@@ -14577,62 +14517,62 @@ function chooseLivenessProbe(state5) {
|
|
|
14577
14517
|
}
|
|
14578
14518
|
return void 0;
|
|
14579
14519
|
}
|
|
14580
|
-
function firstOpenDocumentUri(
|
|
14581
|
-
for (const normalizedPath of
|
|
14582
|
-
const uri =
|
|
14520
|
+
function firstOpenDocumentUri(state4) {
|
|
14521
|
+
for (const normalizedPath of state4.openDocuments) {
|
|
14522
|
+
const uri = state4.openDocumentUris?.get(normalizedPath);
|
|
14583
14523
|
if (uri !== void 0)
|
|
14584
14524
|
return uri;
|
|
14585
14525
|
}
|
|
14586
14526
|
return void 0;
|
|
14587
14527
|
}
|
|
14588
|
-
async function clientPingLiveness(
|
|
14589
|
-
if (!isClientAlive(
|
|
14528
|
+
async function clientPingLiveness(state4, timeoutMs = LIVENESS_PING_TIMEOUT_MS) {
|
|
14529
|
+
if (!isClientAlive(state4))
|
|
14590
14530
|
return false;
|
|
14591
|
-
const probe = chooseLivenessProbe(
|
|
14531
|
+
const probe = chooseLivenessProbe(state4);
|
|
14592
14532
|
if (probe === void 0) {
|
|
14593
14533
|
try {
|
|
14594
14534
|
incrementDegradationCount({
|
|
14595
14535
|
kind: "lsp-liveness-probe-unsupported",
|
|
14596
|
-
subject:
|
|
14536
|
+
subject: state4.serverId,
|
|
14597
14537
|
reason: "no advertised request method to probe with (no workspaceSymbolProvider, and no open document with documentSymbolProvider or hoverProvider); liveness from process and connection state only"
|
|
14598
14538
|
});
|
|
14599
14539
|
} catch {
|
|
14600
14540
|
}
|
|
14601
|
-
return isClientAlive(
|
|
14541
|
+
return isClientAlive(state4);
|
|
14602
14542
|
}
|
|
14603
14543
|
try {
|
|
14604
|
-
await withTimeout(safeSendRequest(
|
|
14544
|
+
await withTimeout(safeSendRequest(state4.connection, probe.method, probe.params), timeoutMs);
|
|
14605
14545
|
} catch (err) {
|
|
14606
14546
|
if (err instanceof Error && err.message.startsWith("Timeout after")) {
|
|
14607
14547
|
return false;
|
|
14608
14548
|
}
|
|
14609
14549
|
}
|
|
14610
|
-
return isClientAlive(
|
|
14550
|
+
return isClientAlive(state4);
|
|
14611
14551
|
}
|
|
14612
|
-
function syncMutationContextSlot(
|
|
14613
|
-
|
|
14552
|
+
function syncMutationContextSlot(state4) {
|
|
14553
|
+
state4.activeMutationContext = state4.activeMutationDepth === 1 ? state4.mutationContextOwner : void 0;
|
|
14614
14554
|
}
|
|
14615
|
-
async function runServerCommand(
|
|
14616
|
-
if (!isClientAlive(
|
|
14555
|
+
async function runServerCommand(state4, command, args, timeoutMs = EXECUTE_COMMAND_TIMEOUT_MS, mutationContext) {
|
|
14556
|
+
if (!isClientAlive(state4)) {
|
|
14617
14557
|
return { executed: false, reason: "lsp client not alive" };
|
|
14618
14558
|
}
|
|
14619
|
-
if (!
|
|
14559
|
+
if (!state4.advertisedCommands.has(command)) {
|
|
14620
14560
|
return {
|
|
14621
14561
|
executed: false,
|
|
14622
|
-
reason: `command "${command}" is not advertised by the ${
|
|
14562
|
+
reason: `command "${command}" is not advertised by the ${state4.serverId} server`
|
|
14623
14563
|
};
|
|
14624
14564
|
}
|
|
14625
|
-
|
|
14626
|
-
|
|
14627
|
-
const isMutationContextOwner =
|
|
14565
|
+
state4.serverEditsAllowed += 1;
|
|
14566
|
+
state4.activeMutationDepth = (state4.activeMutationDepth ?? 0) + 1;
|
|
14567
|
+
const isMutationContextOwner = state4.activeMutationDepth === 1;
|
|
14628
14568
|
if (isMutationContextOwner) {
|
|
14629
|
-
|
|
14569
|
+
state4.mutationContextOwner = mutationContext;
|
|
14630
14570
|
}
|
|
14631
|
-
syncMutationContextSlot(
|
|
14571
|
+
syncMutationContextSlot(state4);
|
|
14632
14572
|
try {
|
|
14633
14573
|
let result;
|
|
14634
14574
|
try {
|
|
14635
|
-
result = await withTimeout(safeSendRequest(
|
|
14575
|
+
result = await withTimeout(safeSendRequest(state4.connection, "workspace/executeCommand", {
|
|
14636
14576
|
command,
|
|
14637
14577
|
arguments: args ?? []
|
|
14638
14578
|
}), timeoutMs);
|
|
@@ -14647,26 +14587,26 @@ async function runServerCommand(state5, command, args, timeoutMs = EXECUTE_COMMA
|
|
|
14647
14587
|
}
|
|
14648
14588
|
return { executed: true, result };
|
|
14649
14589
|
} finally {
|
|
14650
|
-
|
|
14651
|
-
|
|
14590
|
+
state4.serverEditsAllowed -= 1;
|
|
14591
|
+
state4.activeMutationDepth = Math.max(0, (state4.activeMutationDepth ?? 0) - 1);
|
|
14652
14592
|
if (isMutationContextOwner) {
|
|
14653
|
-
|
|
14593
|
+
state4.mutationContextOwner = void 0;
|
|
14654
14594
|
}
|
|
14655
|
-
syncMutationContextSlot(
|
|
14595
|
+
syncMutationContextSlot(state4);
|
|
14656
14596
|
}
|
|
14657
14597
|
}
|
|
14658
|
-
async function runReadOnlyServerCommand(
|
|
14659
|
-
if (!isClientAlive(
|
|
14598
|
+
async function runReadOnlyServerCommand(state4, command, args, timeoutMs = PROBE_COMMAND_TIMEOUT_MS) {
|
|
14599
|
+
if (!isClientAlive(state4)) {
|
|
14660
14600
|
return { executed: false, reason: "lsp client not alive" };
|
|
14661
14601
|
}
|
|
14662
|
-
if (!
|
|
14602
|
+
if (!state4.advertisedCommands.has(command)) {
|
|
14663
14603
|
return {
|
|
14664
14604
|
executed: false,
|
|
14665
|
-
reason: `command "${command}" is not advertised by the ${
|
|
14605
|
+
reason: `command "${command}" is not advertised by the ${state4.serverId} server`
|
|
14666
14606
|
};
|
|
14667
14607
|
}
|
|
14668
14608
|
try {
|
|
14669
|
-
const result = await withTimeout(safeSendRequest(
|
|
14609
|
+
const result = await withTimeout(safeSendRequest(state4.connection, "workspace/executeCommand", {
|
|
14670
14610
|
command,
|
|
14671
14611
|
arguments: args ?? []
|
|
14672
14612
|
}), timeoutMs);
|
|
@@ -14681,14 +14621,14 @@ async function runReadOnlyServerCommand(state5, command, args, timeoutMs = PROBE
|
|
|
14681
14621
|
throw err;
|
|
14682
14622
|
}
|
|
14683
14623
|
}
|
|
14684
|
-
function validateWorkspaceEditVersions(
|
|
14624
|
+
function validateWorkspaceEditVersions(state4, edit) {
|
|
14685
14625
|
for (const change of edit.documentChanges ?? []) {
|
|
14686
14626
|
if (typeof change !== "object" || change === null || !("textDocument" in change))
|
|
14687
14627
|
continue;
|
|
14688
14628
|
const textDocument = change.textDocument;
|
|
14689
14629
|
if (!textDocument || typeof textDocument.uri !== "string" || textDocument.version == null)
|
|
14690
14630
|
continue;
|
|
14691
|
-
const current =
|
|
14631
|
+
const current = state4.documentVersions.get(normalizeMapKey(uriToPath(textDocument.uri)));
|
|
14692
14632
|
if (current === void 0 || current !== textDocument.version) {
|
|
14693
14633
|
throw new Error(`stale workspace edit document version for ${textDocument.uri}`);
|
|
14694
14634
|
}
|
|
@@ -14711,31 +14651,31 @@ function stripDocumentVersions(edit) {
|
|
|
14711
14651
|
});
|
|
14712
14652
|
return { ...edit, documentChanges };
|
|
14713
14653
|
}
|
|
14714
|
-
async function normalizeClientWorkspaceEdit(
|
|
14715
|
-
validateWorkspaceEditVersions(
|
|
14716
|
-
const normalized = await normalizeWorkspaceEditToUtf16(edit,
|
|
14654
|
+
async function normalizeClientWorkspaceEdit(state4, edit) {
|
|
14655
|
+
validateWorkspaceEditVersions(state4, edit);
|
|
14656
|
+
const normalized = await normalizeWorkspaceEditToUtf16(edit, state4.positionEncoding, state4.root);
|
|
14717
14657
|
return stripDocumentVersions(normalized);
|
|
14718
14658
|
}
|
|
14719
|
-
async function resolveCodeActionBestEffort(
|
|
14720
|
-
if (!isClientAlive(
|
|
14659
|
+
async function resolveCodeActionBestEffort(state4, action) {
|
|
14660
|
+
if (!isClientAlive(state4))
|
|
14721
14661
|
return action;
|
|
14722
14662
|
if (action.edit) {
|
|
14723
14663
|
return {
|
|
14724
14664
|
...action,
|
|
14725
|
-
edit: await normalizeClientWorkspaceEdit(
|
|
14665
|
+
edit: await normalizeClientWorkspaceEdit(state4, action.edit)
|
|
14726
14666
|
};
|
|
14727
14667
|
}
|
|
14728
|
-
if (!
|
|
14668
|
+
if (!state4.operationSupport.codeActionResolve) {
|
|
14729
14669
|
recordDegradationOnce({
|
|
14730
14670
|
kind: "lsp-capability-skip",
|
|
14731
|
-
subject: `${
|
|
14671
|
+
subject: `${state4.serverId}:codeAction/resolve`,
|
|
14732
14672
|
reason: "server did not advertise codeActionProvider.resolveProvider"
|
|
14733
14673
|
});
|
|
14734
14674
|
return action;
|
|
14735
14675
|
}
|
|
14736
14676
|
let resolved2;
|
|
14737
14677
|
try {
|
|
14738
|
-
resolved2 = await withTimeout(safeSendRequest(
|
|
14678
|
+
resolved2 = await withTimeout(safeSendRequest(state4.connection, "codeAction/resolve", action), NAV_REQUEST_TIMEOUT_MS);
|
|
14739
14679
|
} catch {
|
|
14740
14680
|
return action;
|
|
14741
14681
|
}
|
|
@@ -14744,7 +14684,7 @@ async function resolveCodeActionBestEffort(state5, action) {
|
|
|
14744
14684
|
const merged = { ...action, ...resolved2 };
|
|
14745
14685
|
return merged.edit ? {
|
|
14746
14686
|
...merged,
|
|
14747
|
-
edit: await normalizeClientWorkspaceEdit(
|
|
14687
|
+
edit: await normalizeClientWorkspaceEdit(state4, merged.edit)
|
|
14748
14688
|
} : merged;
|
|
14749
14689
|
}
|
|
14750
14690
|
async function createLSPClient(options) {
|
|
@@ -14819,7 +14759,7 @@ async function createLSPClient(options) {
|
|
|
14819
14759
|
const connection = (0, import_node.createMessageConnection)(new import_node.StreamMessageReader(lspProcess.stdout), new import_node.StreamMessageWriter(lspProcess.stdin));
|
|
14820
14760
|
const diagnosticEmitter = new EventEmitter();
|
|
14821
14761
|
diagnosticEmitter.setMaxListeners(50);
|
|
14822
|
-
const
|
|
14762
|
+
const state4 = {
|
|
14823
14763
|
isConnected: true,
|
|
14824
14764
|
isDestroyed: false,
|
|
14825
14765
|
startedAtMs: Date.now(),
|
|
@@ -14887,15 +14827,15 @@ async function createLSPClient(options) {
|
|
|
14887
14827
|
// SAFETY: state construction completes before the flush closure can run.
|
|
14888
14828
|
watchQueue: void 0
|
|
14889
14829
|
};
|
|
14890
|
-
activeLspClientSet().add(
|
|
14891
|
-
|
|
14892
|
-
if (!isClientAlive(
|
|
14830
|
+
activeLspClientSet().add(state4);
|
|
14831
|
+
state4.watchQueue = new WatchedFilesQueue((changes) => {
|
|
14832
|
+
if (!isClientAlive(state4))
|
|
14893
14833
|
return;
|
|
14894
|
-
void safeSendNotification(
|
|
14834
|
+
void safeSendNotification(state4.connection, "workspace/didChangeWatchedFiles", { changes });
|
|
14895
14835
|
});
|
|
14896
|
-
setupIncomingHandlers(
|
|
14836
|
+
setupIncomingHandlers(state4, initialization, onDiagnosticsPublished);
|
|
14897
14837
|
connection.listen();
|
|
14898
|
-
setupConnectionLifecycle(
|
|
14838
|
+
setupConnectionLifecycle(state4, recentStderr);
|
|
14899
14839
|
let initResult;
|
|
14900
14840
|
try {
|
|
14901
14841
|
initResult = await withTimeout(safeSendRequest(connection, "initialize", {
|
|
@@ -14908,7 +14848,7 @@ async function createLSPClient(options) {
|
|
|
14908
14848
|
initializationOptions: initialization
|
|
14909
14849
|
}), initializeTimeoutMs);
|
|
14910
14850
|
} catch (err) {
|
|
14911
|
-
|
|
14851
|
+
state4.shutdownRequested = true;
|
|
14912
14852
|
const pid = lspProcess.pid;
|
|
14913
14853
|
void killProcessTree(lspProcess.process, pid);
|
|
14914
14854
|
void removeLspChild(pid, extractSpawnMarker(lspProcess.args)).catch((err2) => {
|
|
@@ -14943,8 +14883,8 @@ async function createLSPClient(options) {
|
|
|
14943
14883
|
].join(" ");
|
|
14944
14884
|
throw new Error(`[lsp] ${serverId} failed to initialize - stream may have been destroyed. The server binary may be missing or crashed immediately. ${reinstallHint} telemetry: ${telemetry}`);
|
|
14945
14885
|
}
|
|
14946
|
-
|
|
14947
|
-
|
|
14886
|
+
state4.workspaceDiagnosticsSupport = detectWorkspaceDiagnosticsSupport(initResult);
|
|
14887
|
+
state4.operationSupport = detectOperationSupport(initResult);
|
|
14948
14888
|
const capabilities = initResult?.capabilities ?? {};
|
|
14949
14889
|
const workspace = isCapabilityRecord(capabilities.workspace) ? capabilities.workspace : void 0;
|
|
14950
14890
|
const fileOperations = isCapabilityRecord(workspace) ? workspace.fileOperations : void 0;
|
|
@@ -14956,21 +14896,21 @@ async function createLSPClient(options) {
|
|
|
14956
14896
|
}
|
|
14957
14897
|
}
|
|
14958
14898
|
}
|
|
14959
|
-
|
|
14899
|
+
state4.fileOperationMalformedRegistrations = malformedFileOperationRegistrations;
|
|
14960
14900
|
if (isCapabilityRecord(fileOperations)) {
|
|
14961
|
-
|
|
14901
|
+
state4.fileOperationFilters = {
|
|
14962
14902
|
willRename: parseFileOperationFilters(fileOperations.willRename),
|
|
14963
14903
|
didRename: parseFileOperationFilters(fileOperations.didRename)
|
|
14964
14904
|
};
|
|
14965
14905
|
}
|
|
14966
|
-
|
|
14967
|
-
|
|
14968
|
-
|
|
14969
|
-
|
|
14906
|
+
state4.positionEncoding = negotiatePositionEncoding(initResult?.capabilities);
|
|
14907
|
+
state4.syncKind = negotiateSyncKind(initResult?.capabilities);
|
|
14908
|
+
state4.saveOptions = negotiateSaveOptions(initResult?.capabilities);
|
|
14909
|
+
state4.rawCapabilityKeys = Object.keys(initResult?.capabilities ?? {}).sort((a, b) => a.localeCompare(b));
|
|
14970
14910
|
for (const cmd of detectExecuteCommands(initResult)) {
|
|
14971
|
-
|
|
14911
|
+
state4.advertisedCommands.add(cmd);
|
|
14972
14912
|
}
|
|
14973
|
-
|
|
14913
|
+
state4.staticDiagnosticsMode = state4.workspaceDiagnosticsSupport.mode;
|
|
14974
14914
|
await safeSendNotification(connection, "initialized", {});
|
|
14975
14915
|
if (initialization) {
|
|
14976
14916
|
await safeSendNotification(connection, "workspace/didChangeConfiguration", {
|
|
@@ -14981,59 +14921,59 @@ async function createLSPClient(options) {
|
|
|
14981
14921
|
serverId,
|
|
14982
14922
|
root,
|
|
14983
14923
|
connection,
|
|
14984
|
-
isAlive: () => isClientAlive(
|
|
14924
|
+
isAlive: () => isClientAlive(state4),
|
|
14985
14925
|
/** True if the server process has exited or been killed. */
|
|
14986
14926
|
processExited: () => lspProcess.process.exitCode !== null || lspProcess.process.killed === true,
|
|
14987
14927
|
/** #1127: mirrors `state.shutdownRequested` — see interface doc. */
|
|
14988
|
-
wasShutdownIntentional: () =>
|
|
14928
|
+
wasShutdownIntentional: () => state4.shutdownRequested,
|
|
14989
14929
|
/** #1127: mirrors `state.exitedAt` — see interface doc. */
|
|
14990
|
-
getExitedAt: () =>
|
|
14930
|
+
getExitedAt: () => state4.exitedAt,
|
|
14991
14931
|
/** Last N lines of server stderr for diagnostics. */
|
|
14992
14932
|
recentStderr: (lines) => recentStderr(lines),
|
|
14993
|
-
getPullFailureHistory: () =>
|
|
14933
|
+
getPullFailureHistory: () => state4.pullFailureHistory.map((entry) => ({
|
|
14994
14934
|
...entry,
|
|
14995
14935
|
message: entry.message.slice(0, 200)
|
|
14996
14936
|
})),
|
|
14997
14937
|
/** Pre-request health check — returns error string if dead. */
|
|
14998
14938
|
checkAlive: () => checkProcessAlive(),
|
|
14999
14939
|
/** #1277: cheap request round-trip proving the server still responds. */
|
|
15000
|
-
pingLiveness: (timeoutMs) => clientPingLiveness(
|
|
14940
|
+
pingLiveness: (timeoutMs) => clientPingLiveness(state4, timeoutMs),
|
|
15001
14941
|
/** #2358: the OS pid of the live server process (see interface doc). */
|
|
15002
14942
|
getProcessPid: () => lspProcess.pid,
|
|
15003
14943
|
notify: {
|
|
15004
14944
|
async open(filePath, content, languageId, preserveDiagnostics, silent, saved, readStamp) {
|
|
15005
|
-
return handleNotifyOpen(
|
|
14945
|
+
return handleNotifyOpen(state4, filePath, content, languageId, preserveDiagnostics, silent, saved, readStamp);
|
|
15006
14946
|
},
|
|
15007
14947
|
async change(filePath, content) {
|
|
15008
|
-
return handleNotifyChange(
|
|
14948
|
+
return handleNotifyChange(state4, filePath, content);
|
|
15009
14949
|
},
|
|
15010
14950
|
watchedFileChange(filePath, type) {
|
|
15011
|
-
handleNotifyExternalChange(
|
|
14951
|
+
handleNotifyExternalChange(state4, filePath, type);
|
|
15012
14952
|
}
|
|
15013
14953
|
},
|
|
15014
14954
|
getDiagnostics(filePath) {
|
|
15015
|
-
return getMergedDiagnosticsForPath(
|
|
14955
|
+
return getMergedDiagnosticsForPath(state4, normalizeMapKey(filePath));
|
|
15016
14956
|
},
|
|
15017
14957
|
getDiagnosticBinding(filePath) {
|
|
15018
|
-
return
|
|
14958
|
+
return state4.diagnosticBindings.get(normalizeMapKey(filePath));
|
|
15019
14959
|
},
|
|
15020
14960
|
getDiagnosticsVersionForPath(filePath) {
|
|
15021
|
-
return diagnosticsVersionForPath(
|
|
14961
|
+
return diagnosticsVersionForPath(state4, normalizeMapKey(filePath));
|
|
15022
14962
|
},
|
|
15023
14963
|
getPublicationCountsForPath(filePath) {
|
|
15024
|
-
return publicationCountsForPath(
|
|
14964
|
+
return publicationCountsForPath(state4, normalizeMapKey(filePath));
|
|
15025
14965
|
},
|
|
15026
14966
|
getAllDiagnostics() {
|
|
15027
14967
|
const result = /* @__PURE__ */ new Map();
|
|
15028
14968
|
const keys = /* @__PURE__ */ new Set([
|
|
15029
|
-
...
|
|
15030
|
-
...
|
|
14969
|
+
...state4.pushDiagnostics.keys(),
|
|
14970
|
+
...state4.documentPullDiagnostics.keys()
|
|
15031
14971
|
]);
|
|
15032
14972
|
for (const key of keys) {
|
|
15033
14973
|
result.set(key, {
|
|
15034
|
-
diags: getMergedDiagnosticsForPath(
|
|
15035
|
-
ts: Math.max(
|
|
15036
|
-
binding:
|
|
14974
|
+
diags: getMergedDiagnosticsForPath(state4, key),
|
|
14975
|
+
ts: Math.max(state4.pushDiagnosticTimestamps.get(key) ?? 0, state4.documentPullDiagnosticTimestamps.get(key) ?? 0),
|
|
14976
|
+
binding: state4.diagnosticBindings.get(key)
|
|
15037
14977
|
});
|
|
15038
14978
|
}
|
|
15039
14979
|
return result;
|
|
@@ -15041,188 +14981,188 @@ async function createLSPClient(options) {
|
|
|
15041
14981
|
getTrackedDiagnosticPaths() {
|
|
15042
14982
|
return [
|
|
15043
14983
|
.../* @__PURE__ */ new Set([
|
|
15044
|
-
...
|
|
15045
|
-
...
|
|
14984
|
+
...state4.pushDiagnostics.keys(),
|
|
14985
|
+
...state4.documentPullDiagnostics.keys()
|
|
15046
14986
|
])
|
|
15047
14987
|
].map((filePath) => process.platform === "win32" ? filePath.replace(/\//g, "\\") : filePath);
|
|
15048
14988
|
},
|
|
15049
14989
|
pruneDiagnostics(predicate) {
|
|
15050
14990
|
let removed = 0;
|
|
15051
14991
|
const keys = /* @__PURE__ */ new Set([
|
|
15052
|
-
...
|
|
15053
|
-
...
|
|
14992
|
+
...state4.pushDiagnostics.keys(),
|
|
14993
|
+
...state4.documentPullDiagnostics.keys()
|
|
15054
14994
|
]);
|
|
15055
14995
|
for (const key of keys) {
|
|
15056
|
-
const diags = getMergedDiagnosticsForPath(
|
|
15057
|
-
const ts = Math.max(
|
|
14996
|
+
const diags = getMergedDiagnosticsForPath(state4, key);
|
|
14997
|
+
const ts = Math.max(state4.pushDiagnosticTimestamps.get(key) ?? 0, state4.documentPullDiagnosticTimestamps.get(key) ?? 0);
|
|
15058
14998
|
if (!predicate(key, ts, diags))
|
|
15059
14999
|
continue;
|
|
15060
|
-
clearDiagnosticsForPath(
|
|
15000
|
+
clearDiagnosticsForPath(state4, key);
|
|
15061
15001
|
removed++;
|
|
15062
15002
|
}
|
|
15063
15003
|
return removed;
|
|
15064
15004
|
},
|
|
15065
15005
|
getWorkspaceDiagnosticsSupport() {
|
|
15066
|
-
return
|
|
15006
|
+
return state4.workspaceDiagnosticsSupport;
|
|
15067
15007
|
},
|
|
15068
15008
|
requestWorkspaceDiagnostics(budgetMs) {
|
|
15069
|
-
return clientRequestWorkspaceDiagnostics(
|
|
15009
|
+
return clientRequestWorkspaceDiagnostics(state4, budgetMs);
|
|
15070
15010
|
},
|
|
15071
15011
|
getOperationSupport() {
|
|
15072
|
-
return
|
|
15012
|
+
return state4.operationSupport;
|
|
15073
15013
|
},
|
|
15074
15014
|
getMalformedFileOperationRegistrations() {
|
|
15075
|
-
return
|
|
15015
|
+
return state4.fileOperationMalformedRegistrations ?? /* @__PURE__ */ new Set();
|
|
15076
15016
|
},
|
|
15077
15017
|
getAdvertisedCommands() {
|
|
15078
|
-
return [...
|
|
15018
|
+
return [...state4.advertisedCommands];
|
|
15079
15019
|
},
|
|
15080
15020
|
getRawCapabilityKeys() {
|
|
15081
|
-
return
|
|
15021
|
+
return state4.rawCapabilityKeys ?? [];
|
|
15082
15022
|
},
|
|
15083
15023
|
getSaveOptions() {
|
|
15084
|
-
return
|
|
15024
|
+
return state4.saveOptions ? { ...state4.saveOptions } : void 0;
|
|
15085
15025
|
},
|
|
15086
15026
|
getLaunchVariant() {
|
|
15087
|
-
return
|
|
15027
|
+
return state4.launchVariant;
|
|
15088
15028
|
},
|
|
15089
15029
|
async executeCommand(command, args, mutationContext) {
|
|
15090
|
-
return runServerCommand(
|
|
15030
|
+
return runServerCommand(state4, command, args, EXECUTE_COMMAND_TIMEOUT_MS, mutationContext);
|
|
15091
15031
|
},
|
|
15092
15032
|
async executeReadOnlyCommand(command, args) {
|
|
15093
|
-
return runReadOnlyServerCommand(
|
|
15033
|
+
return runReadOnlyServerCommand(state4, command, args);
|
|
15094
15034
|
},
|
|
15095
15035
|
get diagnosticsVersion() {
|
|
15096
|
-
return
|
|
15036
|
+
return state4.diagnosticsVersion;
|
|
15097
15037
|
},
|
|
15098
15038
|
async waitForDiagnostics(filePath, timeoutMs = DIAGNOSTICS_WAIT_TIMEOUT_MS, options2) {
|
|
15099
|
-
return clientWaitForDiagnostics(
|
|
15039
|
+
return clientWaitForDiagnostics(state4, filePath, timeoutMs, options2);
|
|
15100
15040
|
},
|
|
15101
15041
|
async definition(filePath, line, character) {
|
|
15102
|
-
const result = await navRequest(
|
|
15042
|
+
const result = await navRequest(state4, "textDocument/definition", {
|
|
15103
15043
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15104
|
-
position: await toWirePosition(
|
|
15044
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15105
15045
|
}, filePath);
|
|
15106
15046
|
if (!result)
|
|
15107
15047
|
return [];
|
|
15108
15048
|
return Array.isArray(result) ? result : [result];
|
|
15109
15049
|
},
|
|
15110
15050
|
async typeDefinition(filePath, line, character) {
|
|
15111
|
-
const result = await navRequest(
|
|
15051
|
+
const result = await navRequest(state4, "textDocument/typeDefinition", {
|
|
15112
15052
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15113
|
-
position: await toWirePosition(
|
|
15053
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15114
15054
|
}, filePath);
|
|
15115
15055
|
if (!result)
|
|
15116
15056
|
return [];
|
|
15117
15057
|
return Array.isArray(result) ? result : [result];
|
|
15118
15058
|
},
|
|
15119
15059
|
async declaration(filePath, line, character) {
|
|
15120
|
-
const result = await navRequest(
|
|
15060
|
+
const result = await navRequest(state4, "textDocument/declaration", {
|
|
15121
15061
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15122
|
-
position: await toWirePosition(
|
|
15062
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15123
15063
|
}, filePath);
|
|
15124
15064
|
if (!result)
|
|
15125
15065
|
return [];
|
|
15126
15066
|
return Array.isArray(result) ? result : [result];
|
|
15127
15067
|
},
|
|
15128
15068
|
async references(filePath, line, character, includeDeclaration = true) {
|
|
15129
|
-
const result = await navRequest(
|
|
15069
|
+
const result = await navRequest(state4, "textDocument/references", {
|
|
15130
15070
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15131
|
-
position: await toWirePosition(
|
|
15071
|
+
position: await toWirePosition(state4, filePath, line, character),
|
|
15132
15072
|
context: { includeDeclaration }
|
|
15133
15073
|
}, filePath);
|
|
15134
15074
|
return result ?? [];
|
|
15135
15075
|
},
|
|
15136
15076
|
async hover(filePath, line, character) {
|
|
15137
|
-
const result = await navRequest(
|
|
15077
|
+
const result = await navRequest(state4, "textDocument/hover", {
|
|
15138
15078
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15139
|
-
position: await toWirePosition(
|
|
15079
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15140
15080
|
}, filePath);
|
|
15141
15081
|
return result ?? null;
|
|
15142
15082
|
},
|
|
15143
15083
|
async signatureHelp(filePath, line, character) {
|
|
15144
|
-
const result = await navRequest(
|
|
15084
|
+
const result = await navRequest(state4, "textDocument/signatureHelp", {
|
|
15145
15085
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15146
|
-
position: await toWirePosition(
|
|
15086
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15147
15087
|
}, filePath);
|
|
15148
15088
|
return result ?? null;
|
|
15149
15089
|
},
|
|
15150
15090
|
async documentSymbol(filePath) {
|
|
15151
|
-
const result = await navRequest(
|
|
15091
|
+
const result = await navRequest(state4, "textDocument/documentSymbol", { textDocument: { uri: pathToFileURL2(filePath).href } }, filePath);
|
|
15152
15092
|
return result ?? [];
|
|
15153
15093
|
},
|
|
15154
15094
|
isDocumentOpen(filePath) {
|
|
15155
|
-
return
|
|
15095
|
+
return state4.openDocuments.has(normalizeMapKey(filePath));
|
|
15156
15096
|
},
|
|
15157
15097
|
openDocumentPaths() {
|
|
15158
|
-
return [...
|
|
15098
|
+
return [...state4.openDocuments];
|
|
15159
15099
|
},
|
|
15160
15100
|
getSentContent(filePath) {
|
|
15161
|
-
const sent =
|
|
15101
|
+
const sent = state4.documentContentHashes.get(normalizeMapKey(filePath));
|
|
15162
15102
|
return sent && {
|
|
15163
15103
|
hash: sent.hash,
|
|
15164
15104
|
changedAtMs: sent.changedAtMs,
|
|
15165
15105
|
openedAtMs: sent.openedAtMs,
|
|
15166
15106
|
openedHash: sent.openedHash,
|
|
15167
|
-
clientStartedAtMs:
|
|
15107
|
+
clientStartedAtMs: state4.startedAtMs
|
|
15168
15108
|
};
|
|
15169
15109
|
},
|
|
15170
15110
|
isBusy() {
|
|
15171
15111
|
return isConnectionBusy(connection);
|
|
15172
15112
|
},
|
|
15173
15113
|
getDocumentUri(filePath) {
|
|
15174
|
-
return
|
|
15114
|
+
return state4.openDocumentUris?.get(normalizeMapKey(filePath));
|
|
15175
15115
|
},
|
|
15176
15116
|
async workspaceSymbol(query) {
|
|
15177
|
-
if (!isClientAlive(
|
|
15117
|
+
if (!isClientAlive(state4))
|
|
15178
15118
|
return [];
|
|
15179
|
-
const result = await navRequest(
|
|
15119
|
+
const result = await navRequest(state4, "workspace/symbol", {
|
|
15180
15120
|
query
|
|
15181
15121
|
});
|
|
15182
15122
|
return result ?? [];
|
|
15183
15123
|
},
|
|
15184
15124
|
async codeAction(filePath, line, character, endLine, endCharacter) {
|
|
15185
|
-
if (!isClientAlive(
|
|
15125
|
+
if (!isClientAlive(state4))
|
|
15186
15126
|
return [];
|
|
15187
15127
|
const uri = pathToFileURL2(filePath).href;
|
|
15188
|
-
const result = await navRequest(
|
|
15128
|
+
const result = await navRequest(state4, "textDocument/codeAction", {
|
|
15189
15129
|
textDocument: { uri },
|
|
15190
15130
|
range: {
|
|
15191
|
-
start: await toWirePosition(
|
|
15192
|
-
end: await toWirePosition(
|
|
15131
|
+
start: await toWirePosition(state4, filePath, line, character),
|
|
15132
|
+
end: await toWirePosition(state4, filePath, endLine, endCharacter)
|
|
15193
15133
|
},
|
|
15194
15134
|
context: {
|
|
15195
|
-
diagnostics: getMergedDiagnosticsForPath(
|
|
15135
|
+
diagnostics: getMergedDiagnosticsForPath(state4, normalizeMapKey(filePath))
|
|
15196
15136
|
}
|
|
15197
15137
|
}, filePath);
|
|
15198
15138
|
if (!result || !Array.isArray(result))
|
|
15199
15139
|
return [];
|
|
15200
15140
|
const actions = result.filter((item) => typeof item === "object" && item !== null && "title" in item);
|
|
15201
|
-
return Promise.all(actions.map((action) => resolveCodeActionBestEffort(
|
|
15141
|
+
return Promise.all(actions.map((action) => resolveCodeActionBestEffort(state4, action)));
|
|
15202
15142
|
},
|
|
15203
15143
|
async rename(filePath, line, character, newName) {
|
|
15204
|
-
const result = await navRequest(
|
|
15144
|
+
const result = await navRequest(state4, "textDocument/rename", {
|
|
15205
15145
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15206
|
-
position: await toWirePosition(
|
|
15146
|
+
position: await toWirePosition(state4, filePath, line, character),
|
|
15207
15147
|
newName
|
|
15208
15148
|
}, filePath);
|
|
15209
|
-
return result ? await normalizeClientWorkspaceEdit(
|
|
15149
|
+
return result ? await normalizeClientWorkspaceEdit(state4, result) : null;
|
|
15210
15150
|
},
|
|
15211
|
-
closeDocument: (filePath) => closeDocument(
|
|
15151
|
+
closeDocument: (filePath) => closeDocument(state4, filePath),
|
|
15212
15152
|
async willRenameFiles(oldFilePath, newFilePath) {
|
|
15213
|
-
if (!isClientAlive(
|
|
15153
|
+
if (!isClientAlive(state4))
|
|
15214
15154
|
return null;
|
|
15215
15155
|
const oldUri = pathToFileURL2(oldFilePath).href;
|
|
15216
15156
|
const newUri = pathToFileURL2(newFilePath).href;
|
|
15217
|
-
if (!await fileOperationFiltersMatch(
|
|
15157
|
+
if (!await fileOperationFiltersMatch(state4.fileOperationFilters?.willRename, oldUri, newUri, oldFilePath, newFilePath)) {
|
|
15218
15158
|
recordDegradationOnce({
|
|
15219
15159
|
kind: "lsp-capability-skip",
|
|
15220
|
-
subject: `${
|
|
15160
|
+
subject: `${state4.serverId}:workspace/willRenameFiles:filter`,
|
|
15221
15161
|
reason: "filter-mismatch"
|
|
15222
15162
|
});
|
|
15223
15163
|
return null;
|
|
15224
15164
|
}
|
|
15225
|
-
const result = await navRequest(
|
|
15165
|
+
const result = await navRequest(state4, "workspace/willRenameFiles", {
|
|
15226
15166
|
files: [
|
|
15227
15167
|
{
|
|
15228
15168
|
oldUri,
|
|
@@ -15230,22 +15170,22 @@ async function createLSPClient(options) {
|
|
|
15230
15170
|
}
|
|
15231
15171
|
]
|
|
15232
15172
|
});
|
|
15233
|
-
return result ? await normalizeClientWorkspaceEdit(
|
|
15173
|
+
return result ? await normalizeClientWorkspaceEdit(state4, result) : null;
|
|
15234
15174
|
},
|
|
15235
15175
|
async didRenameFiles(oldFilePath, newFilePath, oldUri, newUri) {
|
|
15236
|
-
if (!isClientAlive(
|
|
15176
|
+
if (!isClientAlive(state4))
|
|
15237
15177
|
return;
|
|
15238
15178
|
const wireOldUri = oldUri ?? pathToFileURL2(oldFilePath).href;
|
|
15239
15179
|
const wireNewUri = newUri ?? pathToFileURL2(newFilePath).href;
|
|
15240
|
-
if (!await fileOperationFiltersMatch(
|
|
15180
|
+
if (!await fileOperationFiltersMatch(state4.fileOperationFilters?.didRename, wireOldUri, wireNewUri, oldFilePath, newFilePath)) {
|
|
15241
15181
|
recordDegradationOnce({
|
|
15242
15182
|
kind: "lsp-capability-skip",
|
|
15243
|
-
subject: `${
|
|
15183
|
+
subject: `${state4.serverId}:workspace/didRenameFiles:filter`,
|
|
15244
15184
|
reason: "filter-mismatch"
|
|
15245
15185
|
});
|
|
15246
15186
|
return;
|
|
15247
15187
|
}
|
|
15248
|
-
await safeSendNotification(
|
|
15188
|
+
await safeSendNotification(state4.connection, "workspace/didRenameFiles", {
|
|
15249
15189
|
files: [
|
|
15250
15190
|
{
|
|
15251
15191
|
oldUri: wireOldUri,
|
|
@@ -15255,54 +15195,54 @@ async function createLSPClient(options) {
|
|
|
15255
15195
|
});
|
|
15256
15196
|
},
|
|
15257
15197
|
async implementation(filePath, line, character) {
|
|
15258
|
-
const result = await navRequest(
|
|
15198
|
+
const result = await navRequest(state4, "textDocument/implementation", {
|
|
15259
15199
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15260
|
-
position: await toWirePosition(
|
|
15200
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15261
15201
|
}, filePath);
|
|
15262
15202
|
if (!result)
|
|
15263
15203
|
return [];
|
|
15264
15204
|
return Array.isArray(result) ? result : [result];
|
|
15265
15205
|
},
|
|
15266
15206
|
async prepareCallHierarchy(filePath, line, character) {
|
|
15267
|
-
const result = await navRequest(
|
|
15207
|
+
const result = await navRequest(state4, "textDocument/prepareCallHierarchy", {
|
|
15268
15208
|
textDocument: { uri: pathToFileURL2(filePath).href },
|
|
15269
|
-
position: await toWirePosition(
|
|
15209
|
+
position: await toWirePosition(state4, filePath, line, character)
|
|
15270
15210
|
}, filePath);
|
|
15271
15211
|
if (!result)
|
|
15272
15212
|
return [];
|
|
15273
15213
|
return Array.isArray(result) ? result : [result];
|
|
15274
15214
|
},
|
|
15275
15215
|
async incomingCalls(item) {
|
|
15276
|
-
const result = await navRequest(
|
|
15216
|
+
const result = await navRequest(state4, "callHierarchy/incomingCalls", { item });
|
|
15277
15217
|
return result ?? [];
|
|
15278
15218
|
},
|
|
15279
15219
|
async outgoingCalls(item) {
|
|
15280
|
-
const result = await navRequest(
|
|
15220
|
+
const result = await navRequest(state4, "callHierarchy/outgoingCalls", { item });
|
|
15281
15221
|
return result ?? [];
|
|
15282
15222
|
},
|
|
15283
15223
|
async shutdown(options2) {
|
|
15284
|
-
return clientShutdown(
|
|
15224
|
+
return clientShutdown(state4, options2);
|
|
15285
15225
|
}
|
|
15286
15226
|
};
|
|
15287
15227
|
}
|
|
15288
|
-
function sendFenced(
|
|
15289
|
-
const sent = safeSendNotification(
|
|
15290
|
-
armDiagnosticsFence(
|
|
15228
|
+
function sendFenced(state4, normalizedPath, uri, method, params) {
|
|
15229
|
+
const sent = safeSendNotification(state4.connection, method, params);
|
|
15230
|
+
armDiagnosticsFence(state4, normalizedPath, uri);
|
|
15291
15231
|
return sent;
|
|
15292
15232
|
}
|
|
15293
|
-
function armDiagnosticsFence(
|
|
15294
|
-
if (getStrategy(
|
|
15233
|
+
function armDiagnosticsFence(state4, normalizedPath, uri) {
|
|
15234
|
+
if (getStrategy(state4.serverId, state4.launchVariant).diagnosticsFence !== "reply-first") {
|
|
15295
15235
|
return;
|
|
15296
15236
|
}
|
|
15297
|
-
if (
|
|
15298
|
-
if (!
|
|
15299
|
-
|
|
15237
|
+
if (state4.operationSupport?.documentSymbol !== true) {
|
|
15238
|
+
if (!state4.fenceSkipRecorded) {
|
|
15239
|
+
state4.fenceSkipRecorded = true;
|
|
15300
15240
|
logLatency({
|
|
15301
15241
|
type: "phase",
|
|
15302
15242
|
phase: "lsp_diagnostics_fence",
|
|
15303
15243
|
filePath: normalizedPath,
|
|
15304
15244
|
durationMs: 0,
|
|
15305
|
-
metadata: { serverId:
|
|
15245
|
+
metadata: { serverId: state4.serverId, outcome: "no-request" }
|
|
15306
15246
|
});
|
|
15307
15247
|
}
|
|
15308
15248
|
return;
|
|
@@ -15314,7 +15254,7 @@ function armDiagnosticsFence(state5, normalizedPath, uri) {
|
|
|
15314
15254
|
return;
|
|
15315
15255
|
ended = true;
|
|
15316
15256
|
clearTimeout(bound);
|
|
15317
|
-
|
|
15257
|
+
state4.diagnosticFences.delete(normalizedPath);
|
|
15318
15258
|
cancellation.cancel();
|
|
15319
15259
|
cancellation.dispose();
|
|
15320
15260
|
if (outcome === "timeout" || fence.dropped > 0) {
|
|
@@ -15324,7 +15264,7 @@ function armDiagnosticsFence(state5, normalizedPath, uri) {
|
|
|
15324
15264
|
filePath: normalizedPath,
|
|
15325
15265
|
durationMs: Date.now() - armedAt,
|
|
15326
15266
|
metadata: {
|
|
15327
|
-
serverId:
|
|
15267
|
+
serverId: state4.serverId,
|
|
15328
15268
|
outcome,
|
|
15329
15269
|
droppedPublishes: fence.dropped
|
|
15330
15270
|
}
|
|
@@ -15336,13 +15276,13 @@ function armDiagnosticsFence(state5, normalizedPath, uri) {
|
|
|
15336
15276
|
dropped: 0,
|
|
15337
15277
|
supersede: () => end("superseded")
|
|
15338
15278
|
};
|
|
15339
|
-
|
|
15340
|
-
|
|
15279
|
+
state4.diagnosticFences.get(normalizedPath)?.supersede();
|
|
15280
|
+
state4.diagnosticFences.set(normalizedPath, fence);
|
|
15341
15281
|
const bound = setTimeout(() => end("timeout"), DIAGNOSTICS_WAIT_TIMEOUT_MS);
|
|
15342
15282
|
bound.unref?.();
|
|
15343
15283
|
let reply;
|
|
15344
15284
|
try {
|
|
15345
|
-
reply = Promise.resolve(
|
|
15285
|
+
reply = Promise.resolve(state4.connection.sendRequest("textDocument/documentSymbol", { textDocument: { uri } }, cancellation.token));
|
|
15346
15286
|
} catch (thrown) {
|
|
15347
15287
|
reply = Promise.reject(thrown);
|
|
15348
15288
|
}
|
|
@@ -15599,6 +15539,45 @@ async function probeRenameEntityKind(oldFilePath, newFilePath) {
|
|
|
15599
15539
|
return void 0;
|
|
15600
15540
|
}
|
|
15601
15541
|
|
|
15542
|
+
// dist/clients/lsp/grouping.js
|
|
15543
|
+
function groupFilesByPrimaryServer(files2) {
|
|
15544
|
+
const byServer = /* @__PURE__ */ new Map();
|
|
15545
|
+
for (const filePath of files2) {
|
|
15546
|
+
const servers = getServersForFileWithConfig(filePath);
|
|
15547
|
+
const primary = servers[0]?.id ?? "none";
|
|
15548
|
+
const group = byServer.get(primary);
|
|
15549
|
+
const fallbackFamilyHeads = /* @__PURE__ */ new Map();
|
|
15550
|
+
const familyHeads = servers.map((server) => {
|
|
15551
|
+
const head = server.fallbackFor ? fallbackFamilyHeads.get(server.fallbackFor) ?? server.fallbackFor : server.id;
|
|
15552
|
+
fallbackFamilyHeads.set(server.id, head);
|
|
15553
|
+
return head;
|
|
15554
|
+
});
|
|
15555
|
+
const multiServer = new Set(familyHeads).size > 1;
|
|
15556
|
+
if (group) {
|
|
15557
|
+
group.files.push(filePath);
|
|
15558
|
+
if (multiServer)
|
|
15559
|
+
group.multiServer = true;
|
|
15560
|
+
} else {
|
|
15561
|
+
byServer.set(primary, { files: [filePath], multiServer });
|
|
15562
|
+
}
|
|
15563
|
+
}
|
|
15564
|
+
return [...byServer.values()];
|
|
15565
|
+
}
|
|
15566
|
+
async function runPerServerGroups(groups, concurrency, processGroup, signal) {
|
|
15567
|
+
let nextGroup = 0;
|
|
15568
|
+
const workers = Math.min(Math.max(1, concurrency), groups.length);
|
|
15569
|
+
await Promise.all(Array.from({ length: workers }, async () => {
|
|
15570
|
+
while (!signal?.aborted) {
|
|
15571
|
+
const gi = nextGroup;
|
|
15572
|
+
nextGroup += 1;
|
|
15573
|
+
if (gi >= groups.length)
|
|
15574
|
+
break;
|
|
15575
|
+
await processGroup(groups[gi]);
|
|
15576
|
+
}
|
|
15577
|
+
return true;
|
|
15578
|
+
}));
|
|
15579
|
+
}
|
|
15580
|
+
|
|
15602
15581
|
// dist/clients/lsp/language.js
|
|
15603
15582
|
import path15 from "node:path";
|
|
15604
15583
|
var LANGUAGE_EXTENSIONS = EXTENSION_TO_LSP_ID;
|
|
@@ -15675,7 +15654,7 @@ function createLazyImport(load) {
|
|
|
15675
15654
|
}
|
|
15676
15655
|
|
|
15677
15656
|
// dist/clients/lsp-lazy.js
|
|
15678
|
-
var lazyLsp = createLazyImport(() => import("./chunk-
|
|
15657
|
+
var lazyLsp = createLazyImport(() => import("./chunk-KSX3TXSZ.js"));
|
|
15679
15658
|
function warmLspService() {
|
|
15680
15659
|
return lazyLsp.get();
|
|
15681
15660
|
}
|
|
@@ -15684,7 +15663,7 @@ function loadLspService() {
|
|
|
15684
15663
|
}
|
|
15685
15664
|
|
|
15686
15665
|
// dist/clients/warm-attach.js
|
|
15687
|
-
var
|
|
15666
|
+
var state3 = { local: true, servedDiagnosticHashes: /* @__PURE__ */ new Map() };
|
|
15688
15667
|
function record(event, cwd, reason, pid, source) {
|
|
15689
15668
|
logLatency({
|
|
15690
15669
|
type: "phase",
|
|
@@ -15698,50 +15677,50 @@ function selectWarmAttachIncumbent(entries, cwd, now = Date.now(), isPidAlive =
|
|
|
15698
15677
|
return selectLivePeerInstances(entries, cwd, now, isPidAlive)[0];
|
|
15699
15678
|
}
|
|
15700
15679
|
async function tryWarmAttachedDiagnostics(file, content, timeoutMs, source = "per-edit") {
|
|
15701
|
-
if (
|
|
15680
|
+
if (state3.local || !state3.cwd || !state3.incumbentPid)
|
|
15702
15681
|
return void 0;
|
|
15703
15682
|
const entries = await readInstanceRegistry();
|
|
15704
|
-
const incumbent = selectWarmAttachIncumbent(entries,
|
|
15705
|
-
if (incumbent?.pid !==
|
|
15683
|
+
const incumbent = selectWarmAttachIncumbent(entries, state3.cwd);
|
|
15684
|
+
if (incumbent?.pid !== state3.incumbentPid) {
|
|
15706
15685
|
promoteToLocal("incumbent-stale-or-exited");
|
|
15707
15686
|
return void 0;
|
|
15708
15687
|
}
|
|
15709
|
-
const result = await requestWarmDiagnostics(
|
|
15688
|
+
const result = await requestWarmDiagnostics(state3.cwd, state3.incumbentPid, file, content, timeoutMs);
|
|
15710
15689
|
if (!result.available) {
|
|
15711
15690
|
if (result.reason === "no-listener") {
|
|
15712
15691
|
recordDegradationOnce({
|
|
15713
15692
|
kind: "warm-ipc-endpoint-missing",
|
|
15714
|
-
subject: diagnosticsIpcPathForCwd(
|
|
15693
|
+
subject: diagnosticsIpcPathForCwd(state3.cwd, state3.incumbentPid),
|
|
15715
15694
|
reason: "the registry confirms this incumbent is alive but nothing is listening on its derived endpoint \u2014 if pi-lens was upgraded while it was running, restart it"
|
|
15716
15695
|
});
|
|
15717
15696
|
}
|
|
15718
15697
|
promoteToLocal(result.reason);
|
|
15719
15698
|
} else {
|
|
15720
|
-
record("diagnostics-served", file, void 0,
|
|
15699
|
+
record("diagnostics-served", file, void 0, state3.incumbentPid, source);
|
|
15721
15700
|
}
|
|
15722
15701
|
return result;
|
|
15723
15702
|
}
|
|
15724
15703
|
async function tryWarmAttachedCodeActions(file, expectedContentHash, ranges, timeoutMs) {
|
|
15725
|
-
if (
|
|
15704
|
+
if (state3.local || !state3.cwd || !state3.incumbentPid)
|
|
15726
15705
|
return void 0;
|
|
15727
|
-
const result = await requestWarmCodeActions(
|
|
15706
|
+
const result = await requestWarmCodeActions(state3.cwd, state3.incumbentPid, file, expectedContentHash, ranges, timeoutMs);
|
|
15728
15707
|
if (result.available) {
|
|
15729
|
-
record("code-actions-served", file, void 0,
|
|
15708
|
+
record("code-actions-served", file, void 0, state3.incumbentPid);
|
|
15730
15709
|
} else {
|
|
15731
|
-
record("code-actions-skipped", file, result.reason,
|
|
15710
|
+
record("code-actions-skipped", file, result.reason, state3.incumbentPid);
|
|
15732
15711
|
}
|
|
15733
15712
|
return result;
|
|
15734
15713
|
}
|
|
15735
15714
|
function isWarmAttached() {
|
|
15736
|
-
return !
|
|
15715
|
+
return !state3.local && state3.incumbentPid !== void 0;
|
|
15737
15716
|
}
|
|
15738
15717
|
function promoteToLocal(reason) {
|
|
15739
|
-
if (
|
|
15718
|
+
if (state3.local)
|
|
15740
15719
|
return;
|
|
15741
|
-
const pid =
|
|
15742
|
-
|
|
15743
|
-
|
|
15744
|
-
record("takeover",
|
|
15720
|
+
const pid = state3.incumbentPid;
|
|
15721
|
+
state3.local = true;
|
|
15722
|
+
state3.incumbentPid = void 0;
|
|
15723
|
+
record("takeover", state3.cwd ?? process.cwd(), reason, pid);
|
|
15745
15724
|
}
|
|
15746
15725
|
|
|
15747
15726
|
// dist/clients/lsp/index.js
|
|
@@ -15758,6 +15737,8 @@ var AUX_WAIT_DEMOTION_THRESHOLD = 5;
|
|
|
15758
15737
|
var AUX_WAIT_DEMOTION_RATIO = 0.9;
|
|
15759
15738
|
var AUX_WAIT_REPROMOTION_THRESHOLD = 5;
|
|
15760
15739
|
var AUX_WAIT_REPROMOTION_RATIO = 0.5;
|
|
15740
|
+
var ADOPTED_ROOT_CAP = 2;
|
|
15741
|
+
var ADOPTED_ROOT_IDLE_EVICT_MS = 6e4;
|
|
15761
15742
|
function destinationUriPreservingSpelling(oldUri, oldFilePath, newFilePath) {
|
|
15762
15743
|
const canonical = pathToFileURL3(newFilePath);
|
|
15763
15744
|
try {
|
|
@@ -15927,32 +15908,6 @@ function mergeLspDiagnostics(diagnostics) {
|
|
|
15927
15908
|
function attributeDiagnostics(serverId, diagnostics) {
|
|
15928
15909
|
return diagnostics.map((diagnostic) => ({ ...diagnostic, serverId }));
|
|
15929
15910
|
}
|
|
15930
|
-
function groupFilesByPrimaryServer(files2) {
|
|
15931
|
-
const byServer = /* @__PURE__ */ new Map();
|
|
15932
|
-
for (const filePath of files2) {
|
|
15933
|
-
const servers = getServersForFileWithConfig(filePath);
|
|
15934
|
-
const primary = servers[0]?.id ?? "none";
|
|
15935
|
-
const group = byServer.get(primary);
|
|
15936
|
-
const fallbackFamilyHeads = /* @__PURE__ */ new Map();
|
|
15937
|
-
const familyHeads = servers.map((server) => {
|
|
15938
|
-
const head = server.fallbackFor ? fallbackFamilyHeads.get(server.fallbackFor) ?? server.fallbackFor : server.id;
|
|
15939
|
-
fallbackFamilyHeads.set(server.id, head);
|
|
15940
|
-
return head;
|
|
15941
|
-
});
|
|
15942
|
-
const multiServer = new Set(familyHeads).size > 1;
|
|
15943
|
-
if (group) {
|
|
15944
|
-
group.files.push(filePath);
|
|
15945
|
-
if (multiServer)
|
|
15946
|
-
group.multiServer = true;
|
|
15947
|
-
} else {
|
|
15948
|
-
byServer.set(primary, {
|
|
15949
|
-
files: [filePath],
|
|
15950
|
-
multiServer
|
|
15951
|
-
});
|
|
15952
|
-
}
|
|
15953
|
-
}
|
|
15954
|
-
return [...byServer.values()];
|
|
15955
|
-
}
|
|
15956
15911
|
function createSweepIndexGate() {
|
|
15957
15912
|
const seen = /* @__PURE__ */ new Set();
|
|
15958
15913
|
return {
|
|
@@ -15964,20 +15919,6 @@ function createSweepIndexGate() {
|
|
|
15964
15919
|
}
|
|
15965
15920
|
};
|
|
15966
15921
|
}
|
|
15967
|
-
async function runPerServerGroups(groups, concurrency, processGroup, signal) {
|
|
15968
|
-
let nextGroup = 0;
|
|
15969
|
-
const workers = Math.min(Math.max(1, concurrency), groups.length);
|
|
15970
|
-
await Promise.all(Array.from({ length: workers }, async () => {
|
|
15971
|
-
while (!signal?.aborted) {
|
|
15972
|
-
const gi = nextGroup;
|
|
15973
|
-
nextGroup += 1;
|
|
15974
|
-
if (gi >= groups.length)
|
|
15975
|
-
break;
|
|
15976
|
-
await processGroup(groups[gi]);
|
|
15977
|
-
}
|
|
15978
|
-
return true;
|
|
15979
|
-
}));
|
|
15980
|
-
}
|
|
15981
15922
|
var WORKSPACE_DIAGNOSTICS_CONCURRENCY = 8;
|
|
15982
15923
|
var WORKSPACE_SWEEP_PREOPEN_CHUNK_SIZE = (() => {
|
|
15983
15924
|
const raw = Number(process.env.PI_LENS_LSP_WORKSPACE_PREOPEN_CHUNK);
|
|
@@ -16265,6 +16206,9 @@ var LSPService = class _LSPService {
|
|
|
16265
16206
|
notifyStallDemotions = new BoundedFifoMap(_LSPService.MAX_NOTIFY_STALL_DEMOTIONS);
|
|
16266
16207
|
/** LRU clock for capacity eviction, keyed by the canonical server/root key. */
|
|
16267
16208
|
clientLastUsedAt = /* @__PURE__ */ new Map();
|
|
16209
|
+
/** LRU of foreign project roots; kept apart from the session-root registry. */
|
|
16210
|
+
adoptedRootLastUsedAt = /* @__PURE__ */ new Map();
|
|
16211
|
+
adoptedClientKeys = /* @__PURE__ */ new Set();
|
|
16268
16212
|
/**
|
|
16269
16213
|
* Manager-owned use leases close the acquisition/use gap that `isBusy()`
|
|
16270
16214
|
* cannot see: a caller may hold a selected client before its first request has
|
|
@@ -16354,6 +16298,67 @@ var LSPService = class _LSPService {
|
|
|
16354
16298
|
reason: "auxiliary produced five consecutive late answers below half its declared wait budget"
|
|
16355
16299
|
});
|
|
16356
16300
|
}
|
|
16301
|
+
analysisRootModeForFile(filePath) {
|
|
16302
|
+
const roots = getSessionRootsForTelemetry(128);
|
|
16303
|
+
if (this.sessionCwd)
|
|
16304
|
+
roots.push(this.sessionCwd);
|
|
16305
|
+
let adopted = false;
|
|
16306
|
+
for (const root of new Set(roots)) {
|
|
16307
|
+
const mode = resolveAnalysisRoot(filePath, root);
|
|
16308
|
+
if (mode === "session" || mode === "linked-worktree")
|
|
16309
|
+
return mode;
|
|
16310
|
+
adopted ||= mode === "adopted";
|
|
16311
|
+
}
|
|
16312
|
+
return adopted ? "adopted" : "none";
|
|
16313
|
+
}
|
|
16314
|
+
fileIsOutsideRegisteredRoots(filePath) {
|
|
16315
|
+
const roots = getSessionRootsForTelemetry(128);
|
|
16316
|
+
if (roots.length === 0)
|
|
16317
|
+
return isOutsideAllSessionRoots(filePath);
|
|
16318
|
+
return !roots.some((root) => isSameOrWithin(root, filePath));
|
|
16319
|
+
}
|
|
16320
|
+
admitAdoptedRoot(root, filePath) {
|
|
16321
|
+
if (this.analysisRootModeForFile(filePath) !== "adopted")
|
|
16322
|
+
return false;
|
|
16323
|
+
const normalized = normalizeMapKey(root);
|
|
16324
|
+
const liveRoots = /* @__PURE__ */ new Set();
|
|
16325
|
+
for (const key of this.state.clients.keys()) {
|
|
16326
|
+
if (this.adoptedClientKeys.has(key))
|
|
16327
|
+
liveRoots.add(key.slice(key.indexOf(":") + 1));
|
|
16328
|
+
}
|
|
16329
|
+
for (const root2 of this.adoptedRootLastUsedAt.keys()) {
|
|
16330
|
+
if (!liveRoots.has(root2))
|
|
16331
|
+
this.adoptedRootLastUsedAt.delete(root2);
|
|
16332
|
+
}
|
|
16333
|
+
if (liveRoots.has(normalized)) {
|
|
16334
|
+
this.adoptedRootLastUsedAt.set(normalized, Date.now());
|
|
16335
|
+
return true;
|
|
16336
|
+
}
|
|
16337
|
+
if (this.adoptedRootLastUsedAt.size < ADOPTED_ROOT_CAP) {
|
|
16338
|
+
this.adoptedRootLastUsedAt.set(normalized, Date.now());
|
|
16339
|
+
return true;
|
|
16340
|
+
}
|
|
16341
|
+
this.adoptedRootLastUsedAt.set(normalized, Date.now());
|
|
16342
|
+
const victim = [...this.adoptedRootLastUsedAt.keys()].sort((a, b) => (this.adoptedRootLastUsedAt.get(a) ?? 0) - (this.adoptedRootLastUsedAt.get(b) ?? 0)).find((candidate) => candidate !== normalized);
|
|
16343
|
+
if (!victim)
|
|
16344
|
+
return true;
|
|
16345
|
+
this.adoptedRootLastUsedAt.delete(victim);
|
|
16346
|
+
for (const [key, client] of this.state.clients) {
|
|
16347
|
+
if (!this.adoptedClientKeys.has(key) || !key.endsWith(`:${victim}`))
|
|
16348
|
+
continue;
|
|
16349
|
+
if ((this.clientLeases.get(key) ?? 0) > 0)
|
|
16350
|
+
continue;
|
|
16351
|
+
this.retireClient(key);
|
|
16352
|
+
void client.shutdown({ reason: "adopted-root-lru" }).catch(() => {
|
|
16353
|
+
});
|
|
16354
|
+
}
|
|
16355
|
+
incrementDegradationCount({
|
|
16356
|
+
kind: "lsp-adopted-root-evicted",
|
|
16357
|
+
subject: victim,
|
|
16358
|
+
reason: `adopted root cap ${ADOPTED_ROOT_CAP} evicted ${victim}`
|
|
16359
|
+
});
|
|
16360
|
+
return true;
|
|
16361
|
+
}
|
|
16357
16362
|
/**
|
|
16358
16363
|
* Resolve one server's client identity root. Root selection is hard-bounded
|
|
16359
16364
|
* by the session cwd, then config-only nested roots reuse an already-hosted
|
|
@@ -16363,7 +16368,13 @@ var LSPService = class _LSPService {
|
|
|
16363
16368
|
const candidate = await resolveLspServerCwd(server, filePath, this.sessionCwd ?? process.cwd(), onRootFailure);
|
|
16364
16369
|
if (!candidate)
|
|
16365
16370
|
return void 0;
|
|
16366
|
-
|
|
16371
|
+
const mode = this.analysisRootModeForFile(filePath);
|
|
16372
|
+
if (mode === "adopted") {
|
|
16373
|
+
const classifierRoot = resolveAnalysisRootPath(filePath, this.sessionCwd ?? process.cwd());
|
|
16374
|
+
if (!classifierRoot || normalizeMapKey(classifierRoot) !== normalizeMapKey(candidate))
|
|
16375
|
+
return void 0;
|
|
16376
|
+
}
|
|
16377
|
+
if (this.fileIsOutsideRegisteredRoots(filePath) && this.analysisRootModeForFile(filePath) !== "adopted")
|
|
16367
16378
|
return void 0;
|
|
16368
16379
|
const root = enforceLspRootCeiling(candidate, process.cwd(), filePath);
|
|
16369
16380
|
if (normalizeMapKey(root) === normalizeMapKey(process.cwd()))
|
|
@@ -16551,6 +16562,11 @@ var LSPService = class _LSPService {
|
|
|
16551
16562
|
this.state.clientSpawnedAt.delete(key);
|
|
16552
16563
|
this.forgetReadiness(key);
|
|
16553
16564
|
this.clientLastUsedAt.delete(key);
|
|
16565
|
+
if (this.adoptedClientKeys.delete(key)) {
|
|
16566
|
+
const root = key.slice(key.indexOf(":") + 1);
|
|
16567
|
+
if (![...this.adoptedClientKeys].some((candidate) => candidate.endsWith(`:${root}`)))
|
|
16568
|
+
this.adoptedRootLastUsedAt.delete(root);
|
|
16569
|
+
}
|
|
16554
16570
|
this.clearIdleEvictionTimer(key);
|
|
16555
16571
|
this.auxNotifyInflight.delete(key);
|
|
16556
16572
|
this.auxNotifyDrainLatencyEwma.delete(key);
|
|
@@ -16565,12 +16581,12 @@ var LSPService = class _LSPService {
|
|
|
16565
16581
|
current.resolveSettled();
|
|
16566
16582
|
}
|
|
16567
16583
|
scheduleIdleEviction(key, server) {
|
|
16568
|
-
if (server.idleEviction !== "transparent")
|
|
16584
|
+
if (server.idleEviction !== "transparent" && !this.adoptedClientKeys.has(key))
|
|
16569
16585
|
return;
|
|
16570
16586
|
this.clearIdleEvictionTimer(key);
|
|
16571
16587
|
const lastUsedAt = this.clientLastUsedAt.get(key) ?? Date.now();
|
|
16572
16588
|
const root = key.slice(key.indexOf(":") + 1);
|
|
16573
|
-
const idleMs = getLspIdleEvictMsForRoot(root);
|
|
16589
|
+
const idleMs = this.adoptedClientKeys.has(key) ? ADOPTED_ROOT_IDLE_EVICT_MS : getLspIdleEvictMsForRoot(root);
|
|
16574
16590
|
const timer = setTimeout(() => {
|
|
16575
16591
|
this.idleEvictionTimers.delete(key);
|
|
16576
16592
|
void this.withClientSpawnGate(async () => {
|
|
@@ -18025,6 +18041,22 @@ var LSPService = class _LSPService {
|
|
|
18025
18041
|
const allowInstall = this.shouldAllowInstall(server.id);
|
|
18026
18042
|
const normalizedRoot = normalizeMapKey(root);
|
|
18027
18043
|
const key = `${server.id}:${normalizedRoot}`;
|
|
18044
|
+
const adopted = this.analysisRootModeForFile(filePath) === "adopted";
|
|
18045
|
+
if (adopted) {
|
|
18046
|
+
const localCommand = server.command ?? server.projectLocalCommand ?? server.availabilityKey;
|
|
18047
|
+
const localBinary = localCommand ? path16.isAbsolute(localCommand) ? isProjectLocalBinPath(localCommand, root) ? localCommand : void 0 : findLocalBinUpwards(localCommand, root) : void 0;
|
|
18048
|
+
if (localBinary) {
|
|
18049
|
+
recordDegradationOnce({
|
|
18050
|
+
kind: "lsp-registry-decision",
|
|
18051
|
+
subject: `${server.id}:${normalizeMapKey(root)}`,
|
|
18052
|
+
reason: "project-local LSP binary refused for adopted root"
|
|
18053
|
+
});
|
|
18054
|
+
return void 0;
|
|
18055
|
+
}
|
|
18056
|
+
this.adoptedClientKeys.add(key);
|
|
18057
|
+
if (!this.admitAdoptedRoot(root, filePath))
|
|
18058
|
+
return void 0;
|
|
18059
|
+
}
|
|
18028
18060
|
const isOptionalServer = OPTIONAL_LSP_SERVER_IDS.has(server.id);
|
|
18029
18061
|
if (server.availabilityKey && isDirectLspCommandTemporarilyUnavailable(server.availabilityKey)) {
|
|
18030
18062
|
emitBounded("lsp_client_skipped_unavailable_command", `${server.availabilityKey}:${normalizeMapKey(filePath)}`, {
|
|
@@ -18198,7 +18230,20 @@ var LSPService = class _LSPService {
|
|
|
18198
18230
|
* Internal: spawn a client for a server/root combination
|
|
18199
18231
|
*/
|
|
18200
18232
|
async spawnClient(server, root, key, filePath, allowInstall) {
|
|
18201
|
-
|
|
18233
|
+
try {
|
|
18234
|
+
if (server.executesProjectCode === true) {
|
|
18235
|
+
refuseUntrustedLspExecution({
|
|
18236
|
+
kind: "project-code-server",
|
|
18237
|
+
serverId: server.id,
|
|
18238
|
+
root
|
|
18239
|
+
});
|
|
18240
|
+
}
|
|
18241
|
+
} catch (error) {
|
|
18242
|
+
logSessionStart(`lsp spawn ${server.id}: refused \u2014 ${error instanceof Error ? error.message : String(error)}`);
|
|
18243
|
+
this.noteSpawnVerdict(key, "failed");
|
|
18244
|
+
return void 0;
|
|
18245
|
+
}
|
|
18246
|
+
if (server.trustAllowed !== true && !isLspSpawnAllowedByTrust()) {
|
|
18202
18247
|
logSessionStart(`lsp spawn ${server.id}: refused \u2014 ${projectTrustDenialReason()}`);
|
|
18203
18248
|
this.noteSpawnVerdict(key, "declined");
|
|
18204
18249
|
return void 0;
|
|
@@ -18208,7 +18253,12 @@ var LSPService = class _LSPService {
|
|
|
18208
18253
|
logSessionStart(`lsp spawn ${server.id}: start root=${root} install=${allowInstall ? "enabled" : "disabled"} file=${filePath}`);
|
|
18209
18254
|
recordLsp(server.id, root, "spawn_start");
|
|
18210
18255
|
try {
|
|
18211
|
-
const
|
|
18256
|
+
const projectCodeAllowed = this.analysisRootModeForFile(filePath) !== "adopted";
|
|
18257
|
+
const spawned = await withLspProjectCodePermission(projectCodeAllowed, () => server.spawn(root, {
|
|
18258
|
+
allowInstall,
|
|
18259
|
+
projectCodeAllowed,
|
|
18260
|
+
sessionRoot: this.sessionCwd ?? process.cwd()
|
|
18261
|
+
}));
|
|
18212
18262
|
if (this.isDestroyed) {
|
|
18213
18263
|
try {
|
|
18214
18264
|
spawned?.process?.process?.kill();
|
|
@@ -18240,7 +18290,7 @@ var LSPService = class _LSPService {
|
|
|
18240
18290
|
return void 0;
|
|
18241
18291
|
}
|
|
18242
18292
|
const override = getServerInitOverride(server.id, filePath);
|
|
18243
|
-
const mergedInit = mergeInitializationOptions(spawned.initialization, override?.initializationOptions);
|
|
18293
|
+
const mergedInit = spawned.launchVariant === "classic" ? mergeInitializationOptions(override?.initializationOptions, spawned.initialization) : mergeInitializationOptions(spawned.initialization, override?.initializationOptions);
|
|
18244
18294
|
this.state.diagnosticsPublished.delete(server.id);
|
|
18245
18295
|
this.state.diagnosticsUnsupported.delete(server.id);
|
|
18246
18296
|
this.firstContactWaits.delete(server.id);
|
|
@@ -19487,7 +19537,9 @@ var LSPService = class _LSPService {
|
|
|
19487
19537
|
* pays one bounded map walk and never the `server.root()` filesystem walks.
|
|
19488
19538
|
*/
|
|
19489
19539
|
async findOutsideProjectRoot(filePath) {
|
|
19490
|
-
if (!
|
|
19540
|
+
if (!this.fileIsOutsideRegisteredRoots(filePath))
|
|
19541
|
+
return void 0;
|
|
19542
|
+
if (this.analysisRootModeForFile(filePath) === "adopted")
|
|
19491
19543
|
return void 0;
|
|
19492
19544
|
const candidates = await Promise.all(getServersForFileWithConfig(filePath).map((server) => server.root(filePath)));
|
|
19493
19545
|
return candidates.find((candidate) => Boolean(candidate));
|
|
@@ -21522,71 +21574,107 @@ var LSPService = class _LSPService {
|
|
|
21522
21574
|
return [...primary, ...aux];
|
|
21523
21575
|
}
|
|
21524
21576
|
};
|
|
21525
|
-
|
|
21526
|
-
|
|
21527
|
-
|
|
21528
|
-
|
|
21529
|
-
|
|
21530
|
-
if (
|
|
21531
|
-
|
|
21532
|
-
|
|
21533
|
-
|
|
21534
|
-
|
|
21535
|
-
|
|
21536
|
-
|
|
21537
|
-
|
|
21538
|
-
|
|
21539
|
-
|
|
21540
|
-
|
|
21541
|
-
|
|
21577
|
+
configureLspServiceLifecycle({
|
|
21578
|
+
create: (generationHandoff) => new LSPService(generationHandoff, process.cwd()),
|
|
21579
|
+
beforeReset: (options) => {
|
|
21580
|
+
abortDeferredLspWork(`lsp service reset: ${options.reason ?? "unspecified"}`);
|
|
21581
|
+
resetLspLaunchAvailabilityGeneration();
|
|
21582
|
+
if (options.reason === "session_start") {
|
|
21583
|
+
resetClassicTsRepairGuard();
|
|
21584
|
+
}
|
|
21585
|
+
},
|
|
21586
|
+
destroy: (service, options) => service.shutdown(options)
|
|
21587
|
+
});
|
|
21588
|
+
|
|
21589
|
+
// dist/clients/lsp/capabilities.js
|
|
21590
|
+
var adaptedServices = /* @__PURE__ */ new WeakMap();
|
|
21591
|
+
function bindGroup(service, keys) {
|
|
21592
|
+
return new Proxy({}, {
|
|
21593
|
+
get(_target, key) {
|
|
21594
|
+
if (!keys.includes(key))
|
|
21595
|
+
return void 0;
|
|
21596
|
+
const value = service[key];
|
|
21597
|
+
return typeof value === "function" ? value.bind(service) : value;
|
|
21542
21598
|
}
|
|
21543
21599
|
});
|
|
21544
21600
|
}
|
|
21545
|
-
function
|
|
21546
|
-
const
|
|
21547
|
-
if (
|
|
21548
|
-
|
|
21549
|
-
|
|
21601
|
+
function adaptLspService(service) {
|
|
21602
|
+
const existing = adaptedServices.get(service);
|
|
21603
|
+
if (existing)
|
|
21604
|
+
return existing;
|
|
21605
|
+
const groups = {
|
|
21606
|
+
clients: bindGroup(service, [
|
|
21607
|
+
"checkDestroyed",
|
|
21608
|
+
"getAliveClientCount",
|
|
21609
|
+
"getAliveServerIds",
|
|
21610
|
+
"getBrokenStatus",
|
|
21611
|
+
"getStatus",
|
|
21612
|
+
"isSpawnInFlight",
|
|
21613
|
+
"shutdown"
|
|
21614
|
+
]),
|
|
21615
|
+
documents: bindGroup(service, [
|
|
21616
|
+
"getOpenDocumentPaths",
|
|
21617
|
+
"openFile",
|
|
21618
|
+
"touchFile"
|
|
21619
|
+
]),
|
|
21620
|
+
diagnostics: bindGroup(service, [
|
|
21621
|
+
"getAllDiagnostics",
|
|
21622
|
+
"getDiagnostics",
|
|
21623
|
+
"getDiagnosticsHealth",
|
|
21624
|
+
"getLastKnownDiagnostics",
|
|
21625
|
+
"readCachedDiagnosticsForServers",
|
|
21626
|
+
"runWorkspaceDiagnostics"
|
|
21627
|
+
]),
|
|
21628
|
+
navigation: bindGroup(service, [
|
|
21629
|
+
"codeAction",
|
|
21630
|
+
"documentSymbol",
|
|
21631
|
+
"definition",
|
|
21632
|
+
"hover",
|
|
21633
|
+
"implementation",
|
|
21634
|
+
"incomingCalls",
|
|
21635
|
+
"outgoingCalls",
|
|
21636
|
+
"prepareCallHierarchy",
|
|
21637
|
+
"references",
|
|
21638
|
+
"rename",
|
|
21639
|
+
"typeDefinition"
|
|
21640
|
+
]),
|
|
21641
|
+
workspace: bindGroup(service, [
|
|
21642
|
+
"getAdvertisedCommands",
|
|
21643
|
+
"getCapabilitySnapshots",
|
|
21644
|
+
"getClientForFile",
|
|
21645
|
+
"getOperationSupport",
|
|
21646
|
+
"getWarmClientForFile",
|
|
21647
|
+
"hasServerPublishedForFileRoot",
|
|
21648
|
+
"supportsLSP"
|
|
21649
|
+
])
|
|
21650
|
+
};
|
|
21651
|
+
const adapted = new Proxy(service, {
|
|
21652
|
+
get(target, key, receiver) {
|
|
21653
|
+
if (key in groups)
|
|
21654
|
+
return groups[key];
|
|
21655
|
+
const value = Reflect.get(target, key, receiver);
|
|
21656
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
21657
|
+
}
|
|
21658
|
+
});
|
|
21659
|
+
adaptedServices.set(service, adapted);
|
|
21660
|
+
return adapted;
|
|
21550
21661
|
}
|
|
21551
21662
|
function getLSPService() {
|
|
21552
|
-
return
|
|
21663
|
+
return adaptLspService(getOwnedLspService());
|
|
21553
21664
|
}
|
|
21554
21665
|
function peekLSPService() {
|
|
21555
|
-
|
|
21556
|
-
|
|
21557
|
-
async function hasAuxiliaryLspPublishedForRoot(serverId, filePath) {
|
|
21558
|
-
return getLSPService().hasServerPublishedForFileRoot(serverId, filePath);
|
|
21666
|
+
const service = peekOwnedLspService();
|
|
21667
|
+
return service ? adaptLspService(service) : void 0;
|
|
21559
21668
|
}
|
|
21669
|
+
var resetLSPService = (options = {}) => resetOwnedLspService(options);
|
|
21560
21670
|
async function notifyExternalFileChange(filePath, type) {
|
|
21561
21671
|
return getLSPService().notifyExternalFileChange(filePath, type);
|
|
21562
21672
|
}
|
|
21563
21673
|
async function resyncGitChangedFiles(changedPaths) {
|
|
21564
21674
|
return getLSPService().resyncGitChangedFiles(changedPaths);
|
|
21565
21675
|
}
|
|
21566
|
-
function
|
|
21567
|
-
|
|
21568
|
-
resetLspLaunchAvailabilityGeneration();
|
|
21569
|
-
if (options.reason === "session_start") {
|
|
21570
|
-
resetClassicTsRepairGuard();
|
|
21571
|
-
clearWorkspaceSweepHoldForSessionStart();
|
|
21572
|
-
}
|
|
21573
|
-
const state5 = lspProcessState();
|
|
21574
|
-
const retiringService = state5.service;
|
|
21575
|
-
state5.service = null;
|
|
21576
|
-
if (!retiringService)
|
|
21577
|
-
return;
|
|
21578
|
-
const teardown = retiringService.shutdown(options);
|
|
21579
|
-
const pending2 = state5.generationHandoff ? [state5.generationHandoff, teardown] : [teardown];
|
|
21580
|
-
const handoff = Promise.allSettled(pending2).then(() => void 0);
|
|
21581
|
-
state5.generationHandoff = handoff;
|
|
21582
|
-
void handoff.then(() => {
|
|
21583
|
-
if (state5.generationHandoff === handoff) {
|
|
21584
|
-
state5.generationHandoff = void 0;
|
|
21585
|
-
}
|
|
21586
|
-
});
|
|
21587
|
-
}
|
|
21588
|
-
function __collectWorkspaceDiagnosticFilesForTest(root, maxFiles, signal, homeDir) {
|
|
21589
|
-
return collectWorkspaceDiagnosticFiles(path16.resolve(root), maxFiles ?? getMaxWorkspaceDiagnosticFiles(), signal, homeDir);
|
|
21676
|
+
async function hasAuxiliaryLspPublishedForRoot(serverId, filePath) {
|
|
21677
|
+
return getLSPService().hasServerPublishedForFileRoot(serverId, filePath);
|
|
21590
21678
|
}
|
|
21591
21679
|
|
|
21592
21680
|
export {
|
|
@@ -21661,10 +21749,6 @@ export {
|
|
|
21661
21749
|
retagAuxiliaryDiagnostics,
|
|
21662
21750
|
armDeferredLspWork,
|
|
21663
21751
|
registerDeferredLspWork,
|
|
21664
|
-
SWEEP_IDLE_SAFETY_MARGIN_MS,
|
|
21665
|
-
isWorkspaceSweepActive,
|
|
21666
|
-
runWhenWorkspaceSweepIdle,
|
|
21667
|
-
getFullScanWallClockMs,
|
|
21668
21752
|
MAX_LATE_AUX_REARMS,
|
|
21669
21753
|
isAuxBacklogPublished,
|
|
21670
21754
|
isPendingAuxiliaryPastRearmTtl,
|
|
@@ -21697,24 +21781,18 @@ export {
|
|
|
21697
21781
|
buildReverseDependencyIndexFromGraph,
|
|
21698
21782
|
buildScopeKey,
|
|
21699
21783
|
createWorkspaceDiagnosticsCacheContext,
|
|
21784
|
+
groupFilesByPrimaryServer,
|
|
21785
|
+
runPerServerGroups,
|
|
21700
21786
|
createLazyImport,
|
|
21701
21787
|
loadLspService,
|
|
21702
21788
|
tryWarmAttachedDiagnostics,
|
|
21703
21789
|
tryWarmAttachedCodeActions,
|
|
21704
21790
|
isWarmAttached,
|
|
21705
|
-
|
|
21706
|
-
getLspIdleEvictMs,
|
|
21707
|
-
getLspIdleEvictMsForRoot,
|
|
21708
|
-
getLspClientCeiling,
|
|
21709
|
-
groupFilesByPrimaryServer,
|
|
21710
|
-
createSweepIndexGate,
|
|
21711
|
-
runPerServerGroups,
|
|
21712
|
-
LSPService,
|
|
21791
|
+
adaptLspService,
|
|
21713
21792
|
getLSPService,
|
|
21714
21793
|
peekLSPService,
|
|
21715
|
-
|
|
21794
|
+
resetLSPService,
|
|
21716
21795
|
notifyExternalFileChange,
|
|
21717
21796
|
resyncGitChangedFiles,
|
|
21718
|
-
|
|
21719
|
-
__collectWorkspaceDiagnosticFilesForTest
|
|
21797
|
+
hasAuxiliaryLspPublishedForRoot
|
|
21720
21798
|
};
|