Skip to content

Commit a74f8d0

Browse files
committed
feat(new-refactoring): Add Split Declaration and Initialization refactoring code action! Activation range is const or let keyword.
fixes #108 also add comparing refactor extensions docs
1 parent 2293b4d commit a74f8d0

File tree

3 files changed

+59
-1
lines changed

3 files changed

+59
-1
lines changed

REFACTOR-EXTENSIONS-COMPARING.MD

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# VS CODE Refactor Extensions Comparing
2+
3+
All of these extensions are free to use and can be used offline.
4+
5+
| Extension | Good number of actions | Actions quality | Performance Optimizations |
6+
| --------------------------------------------------------------------------------------------------------------- | ---------------------- | -------------------------------------------------------------------------- | --------------------------------------------------- |
7+
| [JS Refactor :: JS CodeFormer](https://marketplace.visualstudio.com/items?itemName=cmstead.jsrefactor) || ❌ (Extension abandoned) | ? |
8+
| [Abracadabra, refactor this!](https://marketplace.visualstudio.com/items?itemName=nicoespeon.abracadabra) || ❌ Sometimes buggy, doesn't work with syntax errors, no TS types auto-infer | ❌ (Uses extension host, slow downs other extension) |
9+
| [JS Refactoring Assistant (P42)](https://marketplace.visualstudio.com/items?itemName=p42ai.refactor) || JS - ✅, TS - ❌ (You need to write types yourself) | ✅ (Dedicated language server) |
10+
| [TypeScript Essential Plugins](https://marketplace.visualstudio.com/items?itemName=zardoy.ts-essential-plugins) || ✅? (Auto infers types, but missing a lot of tests) | ✅ (Best possible, reuses TS language server) |
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { getChangesTracker, getIndentFromPos } from '../../utils'
2+
import { CodeAction } from '../getCodeActions'
3+
4+
export default {
5+
name: 'Split Declaration and Initialization',
6+
id: 'splitDeclarationAndInitialization',
7+
kind: 'refactor.rewrite.split-declaration-and-initialization',
8+
tryToApply(sourceFile, position, range, node, formatOptions, languageService, languageServiceHost) {
9+
if (range || !node) return
10+
if (!ts.isVariableDeclarationList(node) || node.declarations.length !== 1) return
11+
const declaration = node.declarations[0]!
12+
if (position > declaration.pos || !declaration.initializer || !ts.isIdentifier(declaration.name)) return
13+
if (!formatOptions) return true
14+
const typeChecker = languageService.getProgram()!.getTypeChecker()!
15+
let typeNode = declaration.type
16+
if (!typeNode) {
17+
let type = typeChecker.getTypeAtLocation(declaration)
18+
if (type.isLiteral()) {
19+
type = typeChecker.getBaseTypeOfLiteralType(type)
20+
}
21+
typeNode = typeChecker.typeToTypeNode(type, node.parent, ts.NodeBuilderFlags.NoTruncation)
22+
}
23+
const changesTracker = getChangesTracker(formatOptions)
24+
const { factory } = ts
25+
const nodeStart = node.pos + node.getLeadingTriviaWidth()
26+
const varName = declaration.name.text
27+
changesTracker.insertNodeAt(
28+
sourceFile,
29+
nodeStart,
30+
factory.createVariableDeclarationList(
31+
[factory.createVariableDeclaration(factory.createIdentifier(varName), undefined, typeNode)],
32+
ts.NodeFlags.Let,
33+
),
34+
)
35+
changesTracker.replaceNode(
36+
sourceFile,
37+
node,
38+
factory.createBinaryExpression(factory.createIdentifier(varName), factory.createToken(ts.SyntaxKind.EqualsToken), declaration.initializer),
39+
{
40+
prefix: `\n${getIndentFromPos(ts, sourceFile, position)}`,
41+
suffix: '\n',
42+
leadingTriviaOption: /*Ignore all*/ 0,
43+
},
44+
)
45+
return changesTracker.getChanges()[0]?.textChanges as ts.TextChange[]
46+
},
47+
} satisfies CodeAction

typescript/src/codeActions/getCodeActions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { compact } from '@zardoy/utils'
22
import { findChildContainingPosition } from '../utils'
33
import objectSwapKeysAndValues from './custom/objectSwapKeysAndValues'
44
import changeStringReplaceToRegex from './custom/changeStringReplaceToRegex'
5+
import splitDeclarationAndInitialization from './custom/splitDeclarationAndInitialization'
56

67
type SimplifiedRefactorInfo =
78
| {
@@ -30,7 +31,7 @@ export type CodeAction = {
3031
tryToApply: ApplyCodeAction
3132
}
3233

33-
const codeActions: CodeAction[] = [/* toggleBraces */ objectSwapKeysAndValues, changeStringReplaceToRegex]
34+
const codeActions: CodeAction[] = [/* toggleBraces */ objectSwapKeysAndValues, changeStringReplaceToRegex, splitDeclarationAndInitialization]
3435

3536
export const REFACTORS_CATEGORY = 'essential-refactors'
3637

0 commit comments

Comments
 (0)