1- import ts from 'typescript' ;
1+ import ts , { flattenDiagnosticMessageText } from 'typescript' ;
22import { CancellationToken , Diagnostic , DiagnosticSeverity , Range } from 'vscode-languageserver' ;
33import {
44 Document ,
@@ -101,8 +101,25 @@ export class DiagnosticsProviderImpl implements DiagnosticsProvider {
101101 diagnostics . push ( ...checker . call ( lang , tsDoc . filePath ) ) ;
102102 }
103103
104+ return mapAndFilterDiagnostics ( diagnostics , document , tsDoc , isTypescript , lang ) ;
105+ }
106+
107+ private async getLSAndTSDoc ( document : Document ) {
108+ return this . lsAndTsDocResolver . getLSAndTSDoc ( document ) ;
109+ }
110+ }
111+
112+ export function mapAndFilterDiagnostics (
113+ diagnostics : ts . Diagnostic [ ] ,
114+ document : Document ,
115+ tsDoc : SvelteDocumentSnapshot ,
116+ isTypescript : boolean ,
117+ lang ?: ts . LanguageService
118+ ) : Diagnostic [ ] {
119+ const notGenerated = isNotGenerated ( tsDoc . getFullText ( ) ) ;
120+
121+ if ( lang ) {
104122 const additionalStoreDiagnostics : ts . Diagnostic [ ] = [ ] ;
105- const notGenerated = isNotGenerated ( tsDoc . getFullText ( ) ) ;
106123 for ( const diagnostic of diagnostics ) {
107124 if (
108125 ( diagnostic . code === DiagnosticCode . NO_OVERLOAD_MATCHES_CALL ||
@@ -132,46 +149,44 @@ export class DiagnosticsProviderImpl implements DiagnosticsProvider {
132149 }
133150 }
134151 diagnostics . push ( ...additionalStoreDiagnostics ) ;
152+ }
135153
136- diagnostics = diagnostics
137- . filter ( notGenerated )
138- . filter ( not ( isUnusedReactiveStatementLabel ) )
139- . filter ( ( diagnostics ) => ! expectedTransitionThirdArgument ( diagnostics , tsDoc , lang ) ) ;
154+ diagnostics = diagnostics
155+ . filter ( notGenerated )
156+ . filter ( not ( isUnusedReactiveStatementLabel ) )
157+ . filter ( ( diagnostic ) => ! expectedTransitionThirdArgument ( diagnostic , tsDoc , lang ) ) ;
140158
159+ if ( lang ) {
141160 diagnostics = resolveNoopsInReactiveStatements ( lang , diagnostics ) ;
161+ }
142162
143- const mapRange = rangeMapper ( tsDoc , document , lang ) ;
144- const noFalsePositive = isNoFalsePositive ( document , tsDoc ) ;
145- const converted : Diagnostic [ ] = [ ] ;
146-
147- for ( const tsDiag of diagnostics ) {
148- let diagnostic : Diagnostic = {
149- range : convertRange ( tsDoc , tsDiag ) ,
150- severity : mapSeverity ( tsDiag . category ) ,
151- source : isTypescript ? 'ts' : 'js' ,
152- message : ts . flattenDiagnosticMessageText ( tsDiag . messageText , '\n' ) ,
153- code : tsDiag . code ,
154- tags : getDiagnosticTag ( tsDiag )
155- } ;
156- diagnostic = mapRange ( diagnostic ) ;
157-
158- moveBindingErrorMessage ( tsDiag , tsDoc , diagnostic , document ) ;
163+ const mapRange = rangeMapper ( tsDoc , document , lang ) ;
164+ const noFalsePositive = isNoFalsePositive ( document , tsDoc ) ;
165+ const converted : Diagnostic [ ] = [ ] ;
166+
167+ for ( const tsDiag of diagnostics ) {
168+ let diagnostic : Diagnostic = {
169+ range : convertRange ( tsDoc , tsDiag ) ,
170+ severity : mapSeverity ( tsDiag . category ) ,
171+ source : isTypescript ? 'ts' : 'js' ,
172+ message : ts . flattenDiagnosticMessageText ( tsDiag . messageText , '\n' ) ,
173+ code : tsDiag . code ,
174+ tags : getDiagnosticTag ( tsDiag )
175+ } ;
176+ diagnostic = mapRange ( diagnostic ) ;
159177
160- if ( ! hasNoNegativeLines ( diagnostic ) || ! noFalsePositive ( diagnostic ) ) {
161- continue ;
162- }
178+ moveBindingErrorMessage ( tsDiag , tsDoc , diagnostic , document ) ;
163179
164- diagnostic = adjustIfNecessary ( diagnostic , tsDoc . isSvelte5Plus ) ;
165- diagnostic = swapDiagRangeStartEndIfNecessary ( diagnostic ) ;
166- converted . push ( diagnostic ) ;
180+ if ( ! hasNoNegativeLines ( diagnostic ) || ! noFalsePositive ( diagnostic ) ) {
181+ continue ;
167182 }
168183
169- return converted ;
184+ diagnostic = adjustIfNecessary ( diagnostic , tsDoc . isSvelte5Plus ) ;
185+ diagnostic = swapDiagRangeStartEndIfNecessary ( diagnostic ) ;
186+ converted . push ( diagnostic ) ;
170187 }
171188
172- private async getLSAndTSDoc ( document : Document ) {
173- return this . lsAndTsDocResolver . getLSAndTSDoc ( document ) ;
174- }
189+ return converted ;
175190}
176191
177192function moveBindingErrorMessage (
@@ -231,17 +246,21 @@ function moveBindingErrorMessage(
231246function rangeMapper (
232247 snapshot : SvelteDocumentSnapshot ,
233248 document : Document ,
234- lang : ts . LanguageService
249+ lang ? : ts . LanguageService
235250) : ( value : Diagnostic ) => Diagnostic {
236- const get$$PropsDefWithCache = memoize ( ( ) => get$$PropsDef ( lang , snapshot ) ) ;
251+ const get$$PropsDefWithCache = memoize ( ( ) =>
252+ lang ? get$$PropsDef ( lang , snapshot ) : undefined
253+ ) ;
237254 const get$$PropsAliasInfoWithCache = memoize ( ( ) =>
238- get$$PropsAliasForInfo ( get$$PropsDefWithCache , lang , document )
255+ lang ? get$$PropsAliasForInfo ( get$$PropsDefWithCache , lang , document ) : undefined
239256 ) ;
240257
241258 return ( diagnostic ) => {
242259 let range = mapRangeToOriginal ( snapshot , diagnostic . range ) ;
243260
244- if ( range . start . line < 0 ) {
261+ // When lang is unavailable (incremental CLI path), we can't remap negative-line
262+ // diagnostics. This only affects deprecated $$Props syntax, so it's acceptable.
263+ if ( range . start . line < 0 && lang ) {
245264 range =
246265 movePropsErrorRangeBackIfNecessary (
247266 diagnostic ,
@@ -605,7 +624,7 @@ function movePropsErrorRangeBackIfNecessary(
605624function expectedTransitionThirdArgument (
606625 diagnostic : ts . Diagnostic ,
607626 tsDoc : SvelteDocumentSnapshot ,
608- lang : ts . LanguageService
627+ lang ? : ts . LanguageService
609628) {
610629 if (
611630 diagnostic . code !== DiagnosticCode . EXPECTED_N_ARGUMENTS ||
@@ -631,6 +650,13 @@ function expectedTransitionThirdArgument(
631650 ts . isCallExpression
632651 ) ;
633652
653+ if ( ! lang ) {
654+ // Without a language service we can't resolve the signature to check parameter count.
655+ // Fall back to checking the message text for " 3" (i.e. "Expected 3 arguments").
656+ // This is only for the __sveltets_2_ensureTransition wrapper and unlikely to false-positive.
657+ return flattenDiagnosticMessageText ( diagnostic . messageText , '\n' ) . includes ( ' 3' ) ;
658+ }
659+
634660 const signature =
635661 callExpression && lang . getProgram ( ) ?. getTypeChecker ( ) . getResolvedSignature ( callExpression ) ;
636662
0 commit comments