Skip to content

Commit

Permalink
Merge pull request #72 from nicoespeon/extract-interface
Browse files Browse the repository at this point in the history
New Refactoring: Extract Interface
  • Loading branch information
nicoespeon authored Jan 31, 2020
2 parents d29f256 + a2fa984 commit c303bc8
Show file tree
Hide file tree
Showing 14 changed files with 514 additions and 8 deletions.
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"peacock.color": "#34223A",
"workbench.colorCustomizations": {
"activityBar.background": "#51355a",
"activityBar.activeBorder": "#000000",
"activityBar.foreground": "#e7e7e7",
"activityBar.inactiveForeground": "#e7e7e799",
"activityBarBadge.background": "#000000",
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- **[New Refactoring]** Add Braces to JSX Attribute
- **[New Refactoring]** Remove Braces from JSX Attribute
- **[New Refactoring]** Extract Interfaces _(TS specific)_

## [3.1.0] - 2020-01-14 - Keep 'em simple 🌱

Expand All @@ -28,7 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **[New Refactoring]** Convert to Pure Component (React specific)
- **[New Refactoring]** Convert to Pure Component _(React specific)_

### Changed

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ Related projects:
1. [Convert to Template Literal](#convert-to-template-literal)
1. [Replace Binary with Assignment](#replace-binary-with-assignment)
1. [Convert For-Loop to Foreach](#convert-for-loop-to-foreach)
- TS specific:
1. [Extract Interface](#extract-interface)
- React specific:
1. [Convert to Pure Component](#convert-to-pure-component)
1. [Add braces to JSX attribute](#add-braces-to-jsx-attribute)
Expand Down Expand Up @@ -348,6 +350,16 @@ When it's possible, it converts an old-school for-loop into a `forEach()` call.

![][demo-convert-for-to-foreach]

### Extract Interface

> 💡 Available as Quick Fix (`Alt ↵`)
Extract the interface from a class.

This is very useful when you need to invert a dependency: create an interface from an existing class, so you can provide a different implementation of this interface.

![][demo-extract-interface]

### Convert to Pure Component

> 💡 Available as Quick Fix (`Alt ↵`)
Expand Down Expand Up @@ -563,6 +575,7 @@ When we'll have more experience, we'll probably ping the authors of other extens
[demo-add-braces-to-if-statement]: https://github.com/nicoespeon/abracadabra/blob/master/docs/demo/add-braces-to-if-statement.gif?raw=true
[demo-add-braces-to-jsx-attribute]: https://github.com/nicoespeon/abracadabra/blob/master/docs/demo/add-braces-to-jsx-attribute.gif?raw=true
[demo-remove-braces-from-jsx-attribute]: https://github.com/nicoespeon/abracadabra/blob/master/docs/demo/remove-braces-from-jsx-attribute.gif?raw=true
[demo-extract-interface]: https://github.com/nicoespeon/abracadabra/blob/master/docs/demo/extract-interface.gif?raw=true

<!-- Logo -->

Expand Down
Binary file added docs/demo/extract-interface.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
"onCommand:abracadabra.convertIfElseToSwitch",
"onCommand:abracadabra.convertTernaryToIfElse",
"onCommand:abracadabra.convertToTemplateLiteral",
"onCommand:abracadabra.extractInterface",
"onCommand:abracadabra.extractVariable",
"onCommand:abracadabra.flipIfElse",
"onCommand:abracadabra.flipTernary",
Expand Down Expand Up @@ -160,6 +161,11 @@
"title": "Extract Variable",
"category": "Abracadabra"
},
{
"command": "abracadabra.extractInterface",
"title": "Extract Interface",
"category": "Abracadabra"
},
{
"command": "abracadabra.flipIfElse",
"title": "Flip If/Else",
Expand Down Expand Up @@ -421,6 +427,14 @@
"command": "abracadabra.extractVariable",
"when": "editorLangId == typescriptreact"
},
{
"command": "abracadabra.extractInterface",
"when": "editorLangId == typescript"
},
{
"command": "abracadabra.extractInterface",
"when": "editorLangId == typescriptreact"
},
{
"command": "abracadabra.flipIfElse",
"when": "editorLangId == javascript"
Expand Down
4 changes: 4 additions & 0 deletions src/editor/adapters/in-memory-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class InMemoryEditor implements Editor {
return Promise.resolve(choices[0]);
}

moveCursorTo(_position: Position) {
return Promise.resolve();
}

private setCodeMatrix(code: Code) {
this.codeMatrix = code
.split(LINE_SEPARATOR)
Expand Down
5 changes: 5 additions & 0 deletions src/editor/adapters/vscode-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ class VSCodeEditor implements Editor {
async askUser<T>(choices: Choice<T>[]) {
return await vscode.window.showQuickPick(choices);
}

moveCursorTo(position: Position) {
this.editor.selection = toVSCodeCursor(position);
return Promise.resolve();
}
}

function createSelectionFromVSCode(
Expand Down
1 change: 1 addition & 0 deletions src/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface Editor {
delegate(command: Command): Promise<void>;
showError(reason: ErrorReason): Promise<void>;
askUser<T>(choices: Choice<T>[]): Promise<Choice<T> | undefined>;
moveCursorTo(position: Position): Promise<void>;
}

type Modification = {
Expand Down
4 changes: 4 additions & 0 deletions src/editor/error-reason.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { ErrorReason, toString };
enum ErrorReason {
DidNotFoundJsxAttributeToAddBracesTo,
DidNotFoundBracesToRemove,
DidNotFoundClassToExtractInterface,
DidNotFoundReactComponent,
DidNotFoundIfStatementToAddBraces,
DidNotFoundDeadCode,
Expand Down Expand Up @@ -47,6 +48,9 @@ function toString(reason: ErrorReason): string {
case ErrorReason.DidNotFoundBracesToRemove:
return didNotFound("braces to remove from jsx attribute");

case ErrorReason.DidNotFoundClassToExtractInterface:
return didNotFound("a class to extract the interface");

case ErrorReason.DidNotFoundReactComponent:
return didNotFound("a React component to convert");

Expand Down
4 changes: 4 additions & 0 deletions src/editor/position.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ class Position {
return new Position(this.line + lines, this.character);
}

addCharacters(characters: number): Position {
return new Position(this.line, this.character + characters);
}

putAtSameCharacter(position: Position): Position {
return new Position(this.line, position.character);
}
Expand Down
22 changes: 15 additions & 7 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import convertIfElseToSwitch from "./refactorings/convert-if-else-to-switch";
import convertIfElseToTernary from "./refactorings/convert-if-else-to-ternary";
import convertTernaryToIfElse from "./refactorings/convert-ternary-to-if-else";
import convertToTemplateLiteral from "./refactorings/convert-to-template-literal";
import extractInterface from "./refactorings/extract-interface";
import extractVariable from "./refactorings/extract-variable";
import flipIfElse from "./refactorings/flip-if-else";
import flipTernary from "./refactorings/flip-ternary";
Expand All @@ -32,12 +33,8 @@ import splitDeclarationAndInitialization from "./refactorings/split-declaration-
import splitIfStatement from "./refactorings/split-if-statement";
import simplifyTernary from "./refactorings/simplify-ternary";

const SUPPORTED_LANGUAGES = [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
];
const TS_LANGUAGES = ["typescript", "typescriptreact"];
const ALL_LANGUAGES = ["javascript", "javascriptreact", ...TS_LANGUAGES];

export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
Expand All @@ -55,6 +52,7 @@ export function activate(context: vscode.ExtensionContext) {
convertIfElseToTernary,
convertTernaryToIfElse,
convertToTemplateLiteral,
extractInterface,
extractVariable,
flipIfElse,
flipTernary,
Expand Down Expand Up @@ -84,7 +82,17 @@ export function activate(context: vscode.ExtensionContext) {
)
);

SUPPORTED_LANGUAGES.forEach(language => {
TS_LANGUAGES.forEach(language => {
vscode.languages.registerCodeActionsProvider(
language,
new RefactoringActionProvider([extractInterface]),
{
providedCodeActionKinds: [vscode.CodeActionKind.RefactorRewrite]
}
);
});

ALL_LANGUAGES.forEach(language => {
vscode.languages.registerCodeActionsProvider(
language,
new RefactoringActionProvider([
Expand Down
Loading

0 comments on commit c303bc8

Please sign in to comment.