Skip to content

Commit 6baa94f

Browse files
committed
feat: added support for getMoveToRefactoringFileSuggestions, organizeImports, getEditsForFileRename
1 parent b5473c2 commit 6baa94f

File tree

8 files changed

+223
-0
lines changed

8 files changed

+223
-0
lines changed

src/exp.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,17 @@ for (let file of FILES) {
148148
await tsServer.openFile(file.getEditsForRefactor.filePath);
149149
const getEditsForRefactorResponse = await tsServer.getEditsForRefactor(file.getEditsForRefactor.filePath, file.getEditsForRefactor.refactor, file.getEditsForRefactor.action, file.getEditsForRefactor.startLine, file.getEditsForRefactor.startOffset, file.getEditsForRefactor.endLine, file.getEditsForRefactor.endOffset, file.getEditsForRefactor.interactiveRefactorArguments);
150150
console.log('getEditsForRefactorResponse', JSON.stringify(getEditsForRefactorResponse));
151+
152+
await tsServer.openFile(file.getMoveToRefactoringFileSuggestions.filePath);
153+
const getMoveToRefactoringFileSuggestionsResponse = await tsServer.getMoveToRefactoringFileSuggestions(file.getMoveToRefactoringFileSuggestions.filePath, file.getMoveToRefactoringFileSuggestions.startLine, file.getMoveToRefactoringFileSuggestions.startOffset, file.getMoveToRefactoringFileSuggestions.endLine, file.getMoveToRefactoringFileSuggestions.endOffset/*,file.getMoveToRefactoringFileSuggestions.kind*/);
154+
console.log('getMoveToRefactoringFileSuggestionsResponse', JSON.stringify(getMoveToRefactoringFileSuggestionsResponse));
155+
156+
await tsServer.openFile(file.organizeImports.filePath);
157+
const organizeImportsResponse = await tsServer.organizeImports(file.organizeImports.filePath, file.organizeImports.mode);
158+
console.log('organizeImportsResponse', JSON.stringify(organizeImportsResponse));
159+
160+
await tsServer.openFile(file.getEditsForFileRename.oldFilePath);
161+
const getEditsForFileRenameResponse = await tsServer.getEditsForFileRename(file.getEditsForFileRename.oldFilePath, file.getEditsForFileRename.newFilePath);
162+
console.log('getEditsForFileRenameResponse', JSON.stringify(getEditsForFileRenameResponse));
151163
}
152164
//tsServer.exitServer();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// main.ts
2+
import { greet } from './sample';
3+
4+
console.log(greet('World'));
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// sample.ts
2+
export function greet(name: string): string {
3+
return `Hello, ${name}!`;
4+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es5", // Specify ECMAScript target version
4+
"module": "commonjs", // Specify module code generation
5+
"strict": true, // Enable all strict type-checking options
6+
"esModuleInterop": true, // Enables compatibility with default imports from CommonJS modules
7+
"outDir": "./dist", // Redirect output structure to the directory
8+
"baseUrl": "./", // Base directory to resolve non-relative module names
9+
"paths": { // Specify paths for module names
10+
"*": ["node_modules/*"]
11+
},
12+
"skipLibCheck": true, // Skip type checking of all declaration files (*.d.ts)
13+
"forceConsistentCasingInFileNames": true // Disallow inconsistently-cased references to the same file.
14+
},
15+
"include": [
16+
"./**/*.ts" // Include all TypeScript files in the project
17+
],
18+
"exclude": [
19+
"node_modules", // Exclude the node_modules directory
20+
"**/*.spec.ts" // Exclude test files
21+
]
22+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class MathOperations {
2+
// This method is a good candidate to be moved to a separate utility file
3+
static add(a: number, b: number): number {
4+
return a + b;
5+
}
6+
7+
// This method might stay within this class
8+
static subtract(a: number, b: number): number {
9+
return a - b;
10+
}
11+
}
12+
13+
// Usage of the class methods
14+
console.log(MathOperations.add(5, 3));
15+
console.log(MathOperations.subtract(10, 4));

src/test/sample/organizeImports.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// sample.ts
2+
import { Component } from 'react';
3+
import { useState } from 'react';
4+
import { useEffect } from 'react';
5+
import { render } from 'react-dom';
6+
import { someUnusedFunction } from './utils';
7+
8+
class MyComponent extends Component {
9+
// Component implementation
10+
}
11+
12+
const App = () => {
13+
const [state, setState] = useState(null);
14+
15+
useEffect(() => {
16+
// Effect logic
17+
}, []);
18+
19+
return (
20+
<MyComponent />
21+
);
22+
};
23+
24+
render(<App />, document.getElementById('root'));

src/utils/server.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,111 @@ function createTSServerInstance(inferredProject = true) {
17841784
return sendCommand(command);
17851785
}
17861786

1787+
/**
1788+
* Sends a 'GetMoveToRefactoringFileSuggestions' request to the TypeScript Server. This command retrieves a list of
1789+
* existing file paths as suggestions for moving a specific piece of code as part of a refactoring process.
1790+
* The function handles both single-location requests (FileLocationRequestArgs) and range-based requests (FileRangeRequestArgs).
1791+
*
1792+
* @param {string} filePath - The absolute path to the TypeScript file.
1793+
* @param {number} startLine - The starting line number of the range or location (1-based).
1794+
* @param {number} startOffset - The starting character offset on the start line (1-based).
1795+
* @param {number} [endLine] - The ending line number of the range (1-based). Optional for single location.
1796+
* @param {number} [endOffset] - The ending character offset on the end line (1-based). Optional for single location.
1797+
* @param {string} [kind] - Optional. The kind of refactoring to apply.
1798+
* @returns {Promise<Object>} A promise that resolves with a list of file paths suggested for the refactoring.
1799+
* @example
1800+
* // Example usage for a range in a file
1801+
* getMoveToRefactoringFileSuggestions('/path/to/file.ts', 5, 1, 7, 1)
1802+
* .then(suggestions => {
1803+
* console.log('Refactoring File Suggestions:', suggestions);
1804+
* })
1805+
* .catch(error => {
1806+
* console.error('Error getting file suggestions for refactoring:', error);
1807+
* });
1808+
*/
1809+
function getMoveToRefactoringFileSuggestions(filePath, startLine, startOffset, endLine, endOffset, kind) {
1810+
const args = endLine !== undefined && endOffset !== undefined
1811+
? {startLine, startOffset, endLine, endOffset} // FileRangeRequestArgs
1812+
: {line: startLine, offset: startOffset}; // FileLocationRequestArgs
1813+
1814+
const command = {
1815+
command: "getMoveToRefactoringFileSuggestions",
1816+
arguments: {
1817+
file: filePath,
1818+
...args,
1819+
kind: kind
1820+
}
1821+
};
1822+
return sendCommand(command);
1823+
}
1824+
1825+
/**
1826+
* Sends an 'organizeImports' request to the TypeScript Server. This command organizes the imports in a TypeScript file by:
1827+
* 1) Removing unused imports.
1828+
* 2) Coalescing imports from the same module.
1829+
* 3) Sorting imports.
1830+
* The scope of the request is limited to a single file. The function allows specifying the mode of import organization.
1831+
*
1832+
* @param {string} filePath - The absolute path to the TypeScript file.
1833+
* @param {string} [mode] - The mode of import organization, which can be 'All', 'SortAndCombine', or 'RemoveUnused'. Default is 'All'.
1834+
* @param {string} [projectFileName] - Optional. The name of the project that contains the file (e.g., path to 'tsconfig.json').
1835+
* @returns {Promise<Object>} A promise that resolves with an array of file code edits suggested by the TypeScript server. Each edit includes the file name and an array of text changes.
1836+
* @example
1837+
* // Organizing imports in a file with all modes
1838+
* organizeImports('/path/to/file.ts', 'All', '/path/to/project/tsconfig.json')
1839+
* .then(edits => {
1840+
* console.log('Organize Imports Edits:', edits);
1841+
* })
1842+
* .catch(error => {
1843+
* console.error('Error organizing imports:', error);
1844+
* });
1845+
*/
1846+
function organizeImports(filePath, mode = 'All', projectFileName) {
1847+
const command = {
1848+
command: "organizeImports",
1849+
arguments: {
1850+
scope: {
1851+
type: "file",
1852+
args: {file: filePath, projectFileName: projectFileName}
1853+
},
1854+
mode: mode
1855+
}
1856+
};
1857+
return sendCommand(command);
1858+
}
1859+
1860+
/**
1861+
* Sends a 'getEditsForFileRename' request to the TypeScript Server. This function is used to retrieve
1862+
* the necessary code edits required when a file is renamed. It updates import paths and references in
1863+
* other files within the project to reflect the new file name.
1864+
*
1865+
* @param {string} oldFilePath - The original path of the file before renaming.
1866+
* @param {string} newFilePath - The new path of the file after renaming.
1867+
* @returns {Promise} A promise that resolves with an array of file code edits. Each element in the array
1868+
* is an object containing the file name and an array of text changes. Each text change
1869+
* is an object with 'start', 'end', and 'newText' properties indicating how the text
1870+
* should be modified.
1871+
* @example
1872+
* getEditsForFileRename('/path/to/oldFile.ts', '/path/to/newFile.ts')
1873+
* .then(edits => {
1874+
* console.log('File Rename Edits:', edits);
1875+
* })
1876+
* .catch(error => {
1877+
* console.error('Error getting edits for file rename:', error);
1878+
* });
1879+
*/
1880+
function getEditsForFileRename(oldFilePath, newFilePath) {
1881+
const command = {
1882+
command: "getEditsForFileRename",
1883+
arguments: {
1884+
oldFilePath: oldFilePath,
1885+
newFilePath: newFilePath
1886+
}
1887+
};
1888+
return sendCommand(command);
1889+
}
1890+
1891+
17871892
/**
17881893
* Terminates the TypeScript Server process.
17891894
* Warning: Use this function with caution. Prefer using the exitServer function for a graceful shutdown.
@@ -1848,6 +1953,9 @@ function createTSServerInstance(inferredProject = true) {
18481953
getSupportedCodeFixes,
18491954
getApplicableRefactors,
18501955
getEditsForRefactor,
1956+
getMoveToRefactoringFileSuggestions,
1957+
organizeImports,
1958+
getEditsForFileRename,
18511959
exitServer
18521960
};
18531961
}

src/utils/testconfig.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,23 @@ export const FILES = [{
200200
interactiveRefactorArguments: {
201201
targetFile: '/home/charly/repo/tsIntelligence/src/test/sample/getEditsForRefactor.ts'
202202
}
203+
},
204+
getMoveToRefactoringFileSuggestions: {
205+
filePath: '/home/charly/repo/tsIntelligence/src/test/sample/getMoveToRefactoringFileSuggestions.ts',
206+
startLine: 3,
207+
startOffset: 1,
208+
endLine: 6,
209+
endOffset: 1,
210+
kind: ""
211+
212+
},
213+
organizeImports: {
214+
filePath: '/home/charly/repo/tsIntelligence/src/test/sample/organizeImports.ts',
215+
mode: 'All'
216+
},
217+
getEditsForFileRename: {
218+
oldFilePath: '/home/charly/repo/tsIntelligence/src/test/sample/getEditsForFileRename/sample.ts',
219+
newFilePath: '/home/charly/repo/tsIntelligence/src/test/sample/getEditsForFileRename/greetings.ts'
203220
}
204221
}, {
205222
filepath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/webServer.ts',
@@ -374,6 +391,23 @@ export const FILES = [{
374391
interactiveRefactorArguments: {
375392
targetFile: '/home/charly/repo/tsIntelligence/src/test/sample/getEditsForRefactor.ts'
376393
}
394+
},
395+
getMoveToRefactoringFileSuggestions: {
396+
filePath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/webServer.ts',
397+
startLine: 62,
398+
startOffset: 1,
399+
endLine: 76,
400+
endOffset: 3,
401+
kind: ""
402+
403+
},
404+
organizeImports: {
405+
filePath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/webServer.ts',
406+
mode: 'All'
407+
},
408+
getEditsForFileRename: {
409+
oldFilePath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/fileWatcherManager.ts',
410+
newFilePath: '/home/charly/repo/vscode/extensions/typescript-language-features/web/src/fileWatcherManager1.ts'
377411
}
378412
// TODO: add testcase for update and open
379413
}];

0 commit comments

Comments
 (0)