Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export class RenameProviderImpl implements RenameProvider {
const docs = new Map<string, SnapshotFragment>([[tsDoc.filePath, fragment]]);
let convertedRenameLocations: (ts.RenameLocation & {
range: Range;
})[] = await this.mapRenameLocationsToParent(renameLocations, docs);
})[] = await this.mapAndFilterRenameLocations(renameLocations, docs);
// eslint-disable-next-line max-len
const additionalRenameForPropRenameInsideComponentWithProp = await this.getAdditionLocationsForRenameOfPropInsideComponentWithProp(
document,
Expand Down Expand Up @@ -127,7 +127,7 @@ export class RenameProviderImpl implements RenameProvider {
if (
!renameInfo.canRename ||
renameInfo.kind === ts.ScriptElementKind.jsxAttribute ||
renameInfo.fullDisplayName?.includes("JSX.IntrinsicElements")
renameInfo.fullDisplayName?.includes('JSX.IntrinsicElements')
) {
return null;
}
Expand Down Expand Up @@ -189,7 +189,7 @@ export class RenameProviderImpl implements RenameProvider {
rename.fileName !== updatePropLocation.fileName ||
this.isInSvelte2TsxPropLine(fragment, rename),
);
return await this.mapRenameLocationsToParent(replacementsForProp, fragments);
return await this.mapAndFilterRenameLocations(replacementsForProp, fragments);
}

/**
Expand Down Expand Up @@ -222,7 +222,7 @@ export class RenameProviderImpl implements RenameProvider {
const idx = (match.index || 0) + match[0].lastIndexOf(match[1]);
const replacementsForProp =
lang.findRenameLocations(updatePropLocation.fileName, idx, false, false) || [];
return await this.mapRenameLocationsToParent(replacementsForProp, fragments);
return await this.mapAndFilterRenameLocations(replacementsForProp, fragments);
}

// --------> svelte2tsx?
Expand Down Expand Up @@ -278,12 +278,13 @@ export class RenameProviderImpl implements RenameProvider {
* The rename locations the ts language services hands back are relative to the
* svelte2tsx generated code -> map it back to the original document positions.
* Some of those positions could be unmapped (line=-1), these are handled elsewhere.
* Also filter out wrong renames.
*/
private async mapRenameLocationsToParent(
private async mapAndFilterRenameLocations(
renameLocations: readonly ts.RenameLocation[],
fragments: Map<string, SnapshotFragment>,
): Promise<(ts.RenameLocation & { range: Range })[]> {
return Promise.all(
const mappedLocations = await Promise.all(
renameLocations.map(async (loc) => {
let doc = fragments.get(loc.fileName);
if (!doc) {
Expand All @@ -297,6 +298,27 @@ export class RenameProviderImpl implements RenameProvider {
};
}),
);
return this.filterWrongRenameLocations(mappedLocations);
}

private filterWrongRenameLocations(
mappedLocations: (ts.RenameLocation & { range: Range })[],
): (ts.RenameLocation & { range: Range })[] {
return mappedLocations.filter((loc) => {
const snapshot = this.getSnapshot(loc.fileName);
if (!(snapshot instanceof SvelteDocumentSnapshot)) {
return true;
}

const content = snapshot.getText(0, snapshot.getLength());
const svelteInstanceOfFn = '__sveltets_instanceOf(';
// When the user renames a Svelte component, ts will also want to rename
// `__sveltets_instanceOf(TheComponentToRename)`. Prevent that.
return (
content.lastIndexOf(svelteInstanceOfFn, loc.textSpan.start) !==
loc.textSpan.start - svelteInstanceOfFn.length
);
});
}

private mapRangeToOriginal(doc: SnapshotFragment, textSpan: ts.TextSpan): Range {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ describe('RenameProvider', () => {
const renameDoc1 = await openDoc('rename.svelte');
const renameDoc2 = await openDoc('rename2.svelte');
const renameDoc3 = await openDoc('rename3.svelte');
return { provider, renameDoc1, renameDoc2, renameDoc3, docManager };
const renameDoc4 = await openDoc('rename4.svelte');
return { provider, renameDoc1, renameDoc2, renameDoc3, renameDoc4, docManager };

async function openDoc(filename: string) {
const filePath = getFullPath(filename);
Expand Down Expand Up @@ -234,6 +235,57 @@ describe('RenameProvider', () => {
});
});

it('should do rename of svelte component', async () => {
const { provider, renameDoc4 } = await setup();
const result = await provider.rename(renameDoc4, Position.create(1, 12), 'ChildNew');

assert.deepStrictEqual(result, {
changes: {
[getUri('rename4.svelte')]: [
{
newText: 'ChildNew',
range: {
start: {
line: 1,
character: 11,
},
end: {
line: 1,
character: 16,
},
},
},
{
newText: 'ChildNew',
range: {
start: {
line: 7,
character: 5,
},
end: {
line: 7,
character: 10,
},
},
},
{
newText: 'ChildNew',
range: {
start: {
line: 8,
character: 5,
},
end: {
line: 8,
character: 10,
},
},
},
],
},
});
});

it('should allow rename of variable', async () => {
const { provider, renameDoc1 } = await setup();
const result = await provider.prepareRename(renameDoc1, Position.create(1, 25));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script>
import Child from './rename3.svelte';

let componentRef;
</script>

<main>
<Child bind:this={componentRef} />
<Child />
</main>