Skip to content

Commit b9b41df

Browse files
authored
(fix) keep comment from being removed in organizes imports (#1320)
#1310 Side effect, this also allows the @ts-ignore comment to silence import diagnostics.
1 parent 50c13f6 commit b9b41df

File tree

6 files changed

+123
-5
lines changed

6 files changed

+123
-5
lines changed

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,70 @@ describe('CodeActionsProvider', () => {
695695
]);
696696
});
697697

698+
it('organizes imports and not remove the leading comment', async () => {
699+
const { provider, document } = setup('organize-imports-leading-comment.svelte');
700+
701+
const codeActions = await provider.getCodeActions(
702+
document,
703+
Range.create(Position.create(1, 4), Position.create(1, 5)), // irrelevant
704+
{
705+
diagnostics: [],
706+
only: [CodeActionKind.SourceOrganizeImports]
707+
}
708+
);
709+
(<TextDocumentEdit>codeActions[0]?.edit?.documentChanges?.[0])?.edits.forEach(
710+
(edit) => (edit.newText = harmonizeNewLines(edit.newText))
711+
);
712+
713+
assert.deepStrictEqual(codeActions, [
714+
{
715+
edit: {
716+
documentChanges: [
717+
{
718+
edits: [
719+
{
720+
newText:
721+
'// @ts-ignore\n' +
722+
" import { } from './somepng.png';\n" +
723+
" import { } from './t.png';\n",
724+
range: {
725+
end: {
726+
character: 4,
727+
line: 2
728+
},
729+
start: {
730+
character: 4,
731+
line: 1
732+
}
733+
}
734+
},
735+
{
736+
newText: '',
737+
range: {
738+
end: {
739+
character: 0,
740+
line: 4
741+
},
742+
start: {
743+
character: 4,
744+
line: 2
745+
}
746+
}
747+
}
748+
],
749+
textDocument: {
750+
uri: getUri('organize-imports-leading-comment.svelte'),
751+
version: null
752+
}
753+
}
754+
]
755+
},
756+
kind: 'source.organizeImports',
757+
title: 'Organize Imports'
758+
}
759+
]);
760+
});
761+
698762
it('should do extract into const refactor', async () => {
699763
const { provider, document } = setup('codeactions.svelte');
700764

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
import { } from './t.png';
3+
// @ts-ignore
4+
import { } from './somepng.png';
5+
</script>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import MagicString from 'magic-string';
2+
import ts from 'typescript';
3+
4+
/**
5+
* move imports to top of script so they appear outside our render function
6+
*/
7+
export function handleImportDeclaration(
8+
node: ts.ImportDeclaration,
9+
str: MagicString,
10+
astOffset: number,
11+
scriptStart: number
12+
) {
13+
const comments = ts.getLeadingCommentRanges(node.getFullText(), 0) ?? [];
14+
for (const comment of comments) {
15+
const commentEnd = node.pos + comment.end + astOffset;
16+
str.move(node.pos + comment.pos + astOffset, commentEnd, scriptStart + 1);
17+
18+
if (comment.hasTrailingNewLine) {
19+
str.overwrite(commentEnd - 1, commentEnd, str.original[commentEnd - 1] + '\n');
20+
}
21+
}
22+
23+
str.move(node.getStart() + astOffset, node.end + astOffset, scriptStart + 1);
24+
//add in a \n
25+
const originalEndChar = str.original[node.end + astOffset - 1];
26+
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
27+
}

packages/svelte2tsx/src/svelte2tsx/processInstanceScriptContent.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { ImplicitStoreValues } from './nodes/ImplicitStoreValues';
1515
import { Generics } from './nodes/Generics';
1616
import { is$$SlotsDeclaration } from './nodes/slot';
1717
import { preprendStr } from '../utils/magic-string';
18+
import { handleImportDeclaration } from './nodes/handleImportDeclaration';
1819

1920
export interface InstanceScriptProcessResult {
2021
exportedNames: ExportedNames;
@@ -283,11 +284,8 @@ export function processInstanceScriptContent(
283284
}
284285

285286
if (ts.isImportDeclaration(node)) {
286-
//move imports to top of script so they appear outside our render function
287-
str.move(node.getStart() + astOffset, node.end + astOffset, script.start + 1);
288-
//add in a \n
289-
const originalEndChar = str.original[node.end + astOffset - 1];
290-
str.overwrite(node.end + astOffset - 1, node.end + astOffset, originalEndChar + '\n');
287+
handleImportDeclaration(node, str, astOffset, script.start);
288+
291289
// Check if import is the event dispatcher
292290
events.checkIfImportIsEventDispatcher(node);
293291
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
///<reference types="svelte" />
2+
<></>;
3+
import A from './a.svelte';
4+
// @ts-ignore
5+
import B from './b.svelte';
6+
/*hi*/import C from './c.svelte';
7+
function render() {
8+
9+
10+
11+
12+
13+
;
14+
() => (<></>);
15+
return { props: {}, slots: {}, getters: {}, events: {} }}
16+
17+
export default class Input__SvelteComponent_ extends __sveltets_1_createSvelte2TsxComponent(__sveltets_1_partial(__sveltets_1_with_any_event(render()))) {
18+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script lang="ts">
2+
import A from './a.svelte';
3+
// @ts-ignore
4+
import B from './b.svelte';
5+
/*hi*/import C from './c.svelte';
6+
</script>

0 commit comments

Comments
 (0)