Skip to content

Commit 6445a5f

Browse files
Fix svelte plugin diagnostic mapping for context="module" (#587)
#584
1 parent 35c2a9f commit 6445a5f

File tree

8 files changed

+70
-9
lines changed

8 files changed

+70
-9
lines changed

packages/language-server/src/plugins/svelte/SvelteDocument.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,16 @@ export class SvelteFragmentMapper {
175175
}
176176

177177
static async createScript(originalDoc: Document, transpiled: string, processed: Processed[]) {
178+
const scriptInfo = originalDoc.scriptInfo || originalDoc.moduleScriptInfo;
179+
const maybeScriptTag = extractScriptTags(transpiled);
180+
const maybeScriptTagInfo =
181+
maybeScriptTag && (maybeScriptTag.script || maybeScriptTag.moduleScript);
182+
178183
return SvelteFragmentMapper.create(
179184
originalDoc,
180185
transpiled,
181-
originalDoc.scriptInfo,
182-
extractScriptTags(transpiled)?.script || null,
186+
scriptInfo,
187+
maybeScriptTagInfo || null,
183188
processed,
184189
);
185190
}

packages/language-server/src/plugins/svelte/features/getDiagnostics.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ async function createParserErrorDiagnostic(error: any, document: Document) {
7878

7979
if (diagnostic.message.includes('expected')) {
8080
const isInStyle = isInTag(diagnostic.range.start, document.styleInfo);
81-
const isInScript = isInTag(diagnostic.range.start, document.scriptInfo);
81+
const isInScript = isInTag(
82+
diagnostic.range.start,
83+
document.scriptInfo || document.moduleScriptInfo,
84+
);
8285

8386
if (isInStyle || isInScript) {
8487
diagnostic.message +=

packages/language-server/src/plugins/typescript/DocumentSnapshot.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ function preprocessSvelteFile(document: Document, options: SvelteSnapshotOptions
151151
if (tsxMap) {
152152
tsxMap.sources = [document.uri];
153153

154-
const tsCheck = getTsCheckComment(document.scriptInfo?.content);
154+
const scriptInfo = document.scriptInfo || document.moduleScriptInfo;
155+
const tsCheck = getTsCheckComment(scriptInfo?.content);
155156
if (tsCheck) {
156157
text = tsCheck + text;
157158
nrPrependedLines = 1;
@@ -172,7 +173,8 @@ function preprocessSvelteFile(document: Document, options: SvelteSnapshotOptions
172173
};
173174

174175
// fall back to extracted script, if any
175-
text = document.scriptInfo ? document.scriptInfo.content : '';
176+
const scriptInfo = document.scriptInfo || document.moduleScriptInfo;
177+
text = scriptInfo ? scriptInfo.content : '';
176178
}
177179

178180
return {
@@ -330,7 +332,7 @@ export class SvelteSnapshotFragment implements SnapshotFragment {
330332
) {}
331333

332334
get scriptInfo() {
333-
return this.parent.scriptInfo;
335+
return this.parent.scriptInfo || this.parent.moduleScriptInfo;
334336
}
335337

336338
getOriginalPosition(pos: Position): Position {

packages/language-server/src/plugins/typescript/features/CodeActionsProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export class CodeActionsProviderImpl implements CodeActionsProvider {
5555
}
5656

5757
private async organizeImports(document: Document): Promise<CodeAction[]> {
58-
if (!document.scriptInfo) {
58+
if (!document.scriptInfo && !document.moduleScriptInfo) {
5959
return [];
6060
}
6161

packages/language-server/src/plugins/typescript/features/CompletionProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export interface CompletionEntryWithIdentifer extends ts.CompletionEntry, TextDo
3434
type validTriggerCharacter = '.' | '"' | "'" | '`' | '/' | '@' | '<' | '#';
3535

3636
export class CompletionsProviderImpl implements CompletionsProvider<CompletionEntryWithIdentifer> {
37-
constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) { }
37+
constructor(private readonly lsAndTsDocResolver: LSAndTSDocResolver) {}
3838

3939
/**
4040
* The language service throws an error if the character is not a valid trigger character.

packages/language-server/test/plugins/svelte/features/getDiagnostics.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import * as assert from 'assert';
2+
import * as path from 'path';
3+
import * as fs from 'fs';
24
import { Diagnostic, DiagnosticSeverity, Position } from 'vscode-languageserver';
35
import { Document } from '../../../../src/lib/documents';
46
import { getDiagnostics } from '../../../../src/plugins/svelte/features/getDiagnostics';
@@ -7,7 +9,9 @@ import {
79
TranspileErrorSource,
810
} from '../../../../src/plugins/svelte/SvelteDocument';
911
import { SvelteConfig } from '../../../../src/lib/documents/configLoader';
10-
import { CompilerWarningsSettings } from '../../../../src/ls-config';
12+
import { CompilerWarningsSettings, LSConfigManager } from '../../../../src/ls-config';
13+
import { pathToUrl } from '../../../../src/utils';
14+
import { SveltePlugin } from '../../../../src/plugins';
1115

1216
describe('SveltePlugin#getDiagnostics', () => {
1317
async function expectDiagnosticsFor({
@@ -31,6 +35,15 @@ describe('SveltePlugin#getDiagnostics', () => {
3135
};
3236
}
3337

38+
function setupFromFile(filename: string) {
39+
const testDir = path.join(__dirname, '..');
40+
const filePath = path.join(testDir, 'testfiles', filename);
41+
const document = new Document(pathToUrl(filePath), fs.readFileSync(filePath, 'utf-8'));
42+
const pluginManager = new LSConfigManager();
43+
const plugin = new SveltePlugin(pluginManager);
44+
return { plugin, document };
45+
}
46+
3447
it('expect svelte.config.js error', async () => {
3548
(
3649
await expectDiagnosticsFor({
@@ -369,4 +382,36 @@ describe('SveltePlugin#getDiagnostics', () => {
369382
},
370383
]);
371384
});
385+
386+
it('should correctly determine diagnostic position', async () => {
387+
const { plugin, document } = setupFromFile('diagnostics.svelte');
388+
const diagnostics = await plugin.getDiagnostics(document);
389+
390+
assert.deepStrictEqual(diagnostics, [
391+
{
392+
range: { start: { line: 1, character: 15 }, end: { line: 1, character: 27 } },
393+
message:
394+
"Component has unused export property 'name'. If it is for external reference only, please consider using `export const name`",
395+
severity: 2,
396+
source: 'svelte',
397+
code: 'unused-export-let',
398+
},
399+
]);
400+
});
401+
402+
it('should correctly determine diagnostic position for context="module"', async () => {
403+
const { plugin, document } = setupFromFile('diagnostics-module.svelte');
404+
const diagnostics = await plugin.getDiagnostics(document);
405+
406+
assert.deepStrictEqual(diagnostics, [
407+
{
408+
range: { start: { line: 1, character: 15 }, end: { line: 1, character: 27 } },
409+
message:
410+
"Component has unused export property 'name'. If it is for external reference only, please consider using `export const name`",
411+
severity: 2,
412+
source: 'svelte',
413+
code: 'unused-export-let',
414+
},
415+
]);
416+
});
372417
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script context="module" lang="typescript">
2+
export let name: string;
3+
</script>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script lang="typescript">
2+
export let name: string;
3+
</script>

0 commit comments

Comments
 (0)