Skip to content

Commit e81abcc

Browse files
authored
fix(instrumenter): parse svelte template expressions as TS when file uses lang="ts" (#6024)
1 parent 2677072 commit e81abcc

5 files changed

Lines changed: 40 additions & 14 deletions

File tree

e2e/test/svelte-ts-vitest/src/App.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@ describe("App.svelte", () => {
3333
let result = 0;
3434
loop(5, (n: any) => (result += n));
3535
expect(result).toEqual(15);
36-
});
37-
36+
});
3837
})
3938

4039

e2e/test/svelte-ts-vitest/src/App.svelte

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@
2222
}
2323
</script>
2424

25-
<script>
25+
<script lang="ts">
26+
interface User { name: string; age: number }
2627
let hits = 0;
28+
let user: User | null = { name: 'world', age: 18 };
2729
</script>
2830

2931
<main>
30-
<p>Hello world!</p>
32+
<p>Hello {user!.name}!</p>
3133
<p>1 + 2 = {sum(1, 2)}</p>
32-
<p>Over legal drinking age: {isOldEnough(18)}</p>
34+
<p>Over legal drinking age: {isOldEnough(user!.age)}</p>
3335
<button on:click={() => hits++}>Hits {hits}</button>
3436
<button on:click={() => (hits += 10)}>Add 10 ({hits + 10})</button>
3537
</main>

e2e/test/svelte-ts-vitest/verify/verify.js.snap

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ exports[`Verify stryker has ran correctly should report correct score 1`] = `
44
Object {
55
"compileErrors": 0,
66
"ignored": 0,
7-
"killed": 13,
8-
"mutationScore": 64,
9-
"mutationScoreBasedOnCoveredCode": 84.21052631578947,
7+
"killed": 15,
8+
"mutationScore": 66.66666666666666,
9+
"mutationScoreBasedOnCoveredCode": 85.71428571428571,
1010
"noCoverage": 6,
1111
"pending": 0,
1212
"runtimeErrors": 0,
1313
"survived": 3,
1414
"timeout": 3,
15-
"totalCovered": 19,
16-
"totalDetected": 16,
15+
"totalCovered": 21,
16+
"totalDetected": 18,
1717
"totalInvalid": 0,
18-
"totalMutants": 25,
18+
"totalMutants": 27,
1919
"totalUndetected": 9,
20-
"totalValid": 25,
20+
"totalValid": 27,
2121
}
2222
`;

packages/instrumenter/src/parsers/svelte-parser.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ function remapScriptLocations(
198198
const scriptRanges = [moduleScriptRange, ...templateRanges]
199199
.filter(notEmpty)
200200
.sort((a, b) => a.start - b.start);
201+
const expressionFormat = [...scriptMap.values()].some(
202+
(s) => s.attributes.lang === 'ts',
203+
)
204+
? AstFormat.TS
205+
: AstFormat.JS;
201206
let offset = 0;
202207
let newModuleScriptRange: TemplateScriptRange | undefined;
203208
const newScriptRanges: TemplateScriptRange[] = scriptRanges.map((range) => {
@@ -218,12 +223,12 @@ function remapScriptLocations(
218223
}
219224
return scriptRange;
220225
} else {
221-
// Template script is always JS
226+
// Template expressions use the same format as the file's script lang
222227
return {
223228
start,
224229
end: start + script.length,
225230
isExpression: range.isExpression,
226-
format: AstFormat.JS,
231+
format: range.isExpression ? expressionFormat : AstFormat.JS,
227232
};
228233
}
229234
});

packages/instrumenter/test/unit/parsers/svelte-parser.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,5 +508,25 @@ describe('svelte-parser', () => {
508508
expect(ast.root.additionalScripts).lengthOf(1);
509509
expect(ast.root.additionalScripts[0].ast.root).eq(eventHandlerAst.root);
510510
});
511+
512+
it('should parse a typescript expression as TS when the svelte file has a lang="ts" script', async () => {
513+
// Arrange
514+
const tsExpression = '"test" as string';
515+
const tsAst = createTSAst({ rawContent: tsExpression });
516+
const svelte = `<script lang="ts"></script><div>{${tsExpression}}</div>`;
517+
contextStub.parse.resolves(tsAst);
518+
519+
// Act
520+
const ast = await parse(svelte, 'index.svelte', contextStub);
521+
522+
// Assert
523+
sinon.assert.calledWithExactly(
524+
contextStub.parse,
525+
tsExpression,
526+
'index.svelte',
527+
AstFormat.TS,
528+
);
529+
expect(ast.root.additionalScripts[0].ast.root).eq(tsAst.root);
530+
});
511531
});
512532
});

0 commit comments

Comments
 (0)