From e53590e984c55a3be19c6eff63aca749c007aa40 Mon Sep 17 00:00:00 2001 From: ilaif Date: Mon, 12 May 2025 19:37:01 +0300 Subject: [PATCH 1/3] feat: enhance VS Code integration with new launch and task configurations, add linting fix script, and update .gitignore --- .gitignore | 3 +-- .vscode/launch.json | 17 +++++++++++++++ .vscode/tasks.json | 12 +++++++++++ package.json | 4 +++- src/AnnotateLensProvider.ts | 42 ++++++++++++++++++++++++++++++++----- src/SymbolInfo.ts | 11 +++++----- 6 files changed, 76 insertions(+), 13 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json diff --git a/.gitignore b/.gitignore index e14af20..ff3b7ba 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,4 @@ node_modules .vscode-test/ *.vsix -.vscode -.idea \ No newline at end of file +.idea diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..72c7609 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ], + "preLaunchTask": "npm: compile" + } + ] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..8df9478 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,12 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "npm: compile", + "type": "npm", + "script": "compile", + "group": "build", + "problemMatcher": ["$tsc"] + } + ] +} diff --git a/package.json b/package.json index dfd0d70..e189a80 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,12 @@ ], "scripts": { "vscode:prepublish": "npm run package", + "vscode:publish": "npx vsce package", "compile": "webpack", "watch": "webpack --watch", "package": "webpack --mode production --devtool hidden-source-map", - "lint": "eslint src --ext ts" + "lint": "eslint src --ext ts", + "lint:fix": "eslint src --ext ts --fix" }, "devDependencies": { "@types/glob": "^8.0.0", diff --git a/src/AnnotateLensProvider.ts b/src/AnnotateLensProvider.ts index d0c19e2..c492e2e 100644 --- a/src/AnnotateLensProvider.ts +++ b/src/AnnotateLensProvider.ts @@ -9,15 +9,16 @@ export class AnnotationLensProvider public async provideCodeLenses( document: vscode.TextDocument ): Promise { + const activeEditor = vscode.window.activeTextEditor; + if (!activeEditor) { + return []; + } + const goSymbols = await this.getGoSymbols(document); const results: AnnotationLens[] = []; for (const goSymbol of goSymbols) { const symbolInfo = await SymbolInfo.create(goSymbol); - const activeEditor = vscode.window.activeTextEditor; - if (!activeEditor) { - return []; - } const locations = await this.getSymbolLocations(activeEditor, symbolInfo) ?? []; const symbols = await Promise.all(locations.map(SymbolInfo.getSymbol)); @@ -27,6 +28,36 @@ export class AnnotationLensProvider const annotation = new Annotation(symbolInfo.symbol, symbols); results.push(new AnnotationLens(annotation)); + + for (const child of symbolInfo.symbol.children ?? []) { + if (child.kind !== vscode.SymbolKind.Method) { + continue; + } + + // For methods, get implementation locations directly + const methodLocations = await vscode.commands.executeCommand( + "vscode.executeImplementationProvider", + activeEditor.document.uri, + child.range.start + ) ?? []; + + if (methodLocations.length > 0) { + const methodSymbols = await Promise.all(methodLocations.map(SymbolInfo.getSymbol)); + + // Create location from document and child range + const location = new vscode.Location(activeEditor.document.uri, child.range); + + // Convert the child into the combined type needed for Annotation + const combinedSymbol = { + ...child, + location, + containerName: symbolInfo.symbol.name + } as vscode.SymbolInformation & vscode.DocumentSymbol; + + const methodAnnotation = new Annotation(combinedSymbol, methodSymbols); + results.push(new AnnotationLens(methodAnnotation)); + } + } } return results; @@ -47,7 +78,8 @@ export class AnnotationLensProvider (symbol) => symbol.kind === vscode.SymbolKind.Class || symbol.kind === vscode.SymbolKind.Struct || - symbol.kind === vscode.SymbolKind.Interface + symbol.kind === vscode.SymbolKind.Interface || + symbol.kind === vscode.SymbolKind.Method ); return symbols; } diff --git a/src/SymbolInfo.ts b/src/SymbolInfo.ts index 162837a..a21321e 100644 --- a/src/SymbolInfo.ts +++ b/src/SymbolInfo.ts @@ -1,4 +1,4 @@ -import * as vscode from "vscode"; +import * as vscode from 'vscode'; export class SymbolInfo { public readonly symbol: vscode.SymbolInformation & vscode.DocumentSymbol; @@ -15,9 +15,9 @@ export class SymbolInfo { ): Promise { const documentSymbols = (await vscode.commands.executeCommand< (vscode.SymbolInformation & vscode.DocumentSymbol)[] - >("vscode.executeDocumentSymbolProvider", location.uri))!; + >('vscode.executeDocumentSymbolProvider', location.uri))!; return documentSymbols.find((documentSymbol) => - documentSymbol.range.start.isEqual(location.range.start) + documentSymbol.range.contains(location.range) ) as vscode.SymbolInformation & vscode.DocumentSymbol; } @@ -29,9 +29,10 @@ export class SymbolInfo { if ( this.symbol.kind !== vscode.SymbolKind.Class && this.symbol.kind !== vscode.SymbolKind.Struct && - this.symbol.kind !== vscode.SymbolKind.Interface + this.symbol.kind !== vscode.SymbolKind.Interface && + this.symbol.kind !== vscode.SymbolKind.Method ) { - throw new Error("Expected struct or interface"); + throw new Error('Expected struct or interface'); } } } From 68c3357e975e7e6db3222ff78c1f46bdcf4e4d03 Mon Sep 17 00:00:00 2001 From: Elran Shefer Date: Mon, 12 May 2025 23:55:45 +0300 Subject: [PATCH 2/3] fixup: fixes methods implementation --- resources/implement.svg | 6 ++++++ resources/override.svg | 6 ++++++ src/AnnotateLensProvider.ts | 26 +++++++++++++++++++++++++- src/decorations.ts | 19 +++++++++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 resources/implement.svg create mode 100644 resources/override.svg create mode 100644 src/decorations.ts diff --git a/resources/implement.svg b/resources/implement.svg new file mode 100644 index 0000000..fcae3db --- /dev/null +++ b/resources/implement.svg @@ -0,0 +1,6 @@ + + + + I + + \ No newline at end of file diff --git a/resources/override.svg b/resources/override.svg new file mode 100644 index 0000000..9ea70eb --- /dev/null +++ b/resources/override.svg @@ -0,0 +1,6 @@ + + + + O + + \ No newline at end of file diff --git a/src/AnnotateLensProvider.ts b/src/AnnotateLensProvider.ts index c492e2e..6095233 100644 --- a/src/AnnotateLensProvider.ts +++ b/src/AnnotateLensProvider.ts @@ -2,6 +2,7 @@ import * as vscode from "vscode"; import { Annotation } from "./Annotation"; import { AnnotationLens } from "./AnnotationLens"; import { SymbolInfo } from "./SymbolInfo"; +import { getImplementDecoration, getOverrideDecoration } from "./decorations"; export class AnnotationLensProvider implements vscode.CodeLensProvider @@ -16,6 +17,8 @@ export class AnnotationLensProvider const goSymbols = await this.getGoSymbols(document); + const decorationLocations: vscode.Range[] = []; + const results: AnnotationLens[] = []; for (const goSymbol of goSymbols) { const symbolInfo = await SymbolInfo.create(goSymbol); @@ -29,6 +32,14 @@ export class AnnotationLensProvider const annotation = new Annotation(symbolInfo.symbol, symbols); results.push(new AnnotationLens(annotation)); + const decorationRange = new vscode.Range( + symbolInfo.symbol.location.range.start, + symbolInfo.symbol.location.range.start, + ); + decorationLocations.push( + decorationRange, + ); + for (const child of symbolInfo.symbol.children ?? []) { if (child.kind !== vscode.SymbolKind.Method) { continue; @@ -60,14 +71,27 @@ export class AnnotationLensProvider } } + activeEditor.setDecorations( + getImplementDecoration(), + decorationLocations, + ); + + return results; } private async getSymbolLocations(te: vscode.TextEditor, si: SymbolInfo): Promise { + let position = si.symbol.location.range.start; + if (si.symbol.kind === vscode.SymbolKind.Method) { + position = new vscode.Position( + si.symbol.selectionRange.start.line, + si.symbol.selectionRange.start.character + 1, + ); + } return vscode.commands.executeCommand( "vscode.executeImplementationProvider", te.document.uri, - si.symbol.location.range.start + position, ); } diff --git a/src/decorations.ts b/src/decorations.ts new file mode 100644 index 0000000..77acec9 --- /dev/null +++ b/src/decorations.ts @@ -0,0 +1,19 @@ + +import * as vscode from "vscode"; + +let overrideDecoration = vscode.window.createTextEditorDecorationType({ + gutterIconPath: __dirname + "/../resources/override.svg", + fontWeight: "bold", +}); +let implementDecoration = vscode.window.createTextEditorDecorationType({ + gutterIconPath: __dirname + "/../resources/implement.svg", + fontWeight: "bold", +}); + +export function getOverrideDecoration() { + return overrideDecoration; +} + +export function getImplementDecoration() { + return implementDecoration; +} \ No newline at end of file From 458fc74edaf5542489e2f617b9f90d614d811be5 Mon Sep 17 00:00:00 2001 From: Elran Shefer Date: Tue, 13 May 2025 08:05:15 +0300 Subject: [PATCH 3/3] fixup: remove redundent code --- resources/override.svg | 6 ------ src/AnnotateLensProvider.ts | 2 +- src/decorations.ts | 8 -------- 3 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 resources/override.svg diff --git a/resources/override.svg b/resources/override.svg deleted file mode 100644 index 9ea70eb..0000000 --- a/resources/override.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - O - - \ No newline at end of file diff --git a/src/AnnotateLensProvider.ts b/src/AnnotateLensProvider.ts index 6095233..e0d624c 100644 --- a/src/AnnotateLensProvider.ts +++ b/src/AnnotateLensProvider.ts @@ -2,7 +2,7 @@ import * as vscode from "vscode"; import { Annotation } from "./Annotation"; import { AnnotationLens } from "./AnnotationLens"; import { SymbolInfo } from "./SymbolInfo"; -import { getImplementDecoration, getOverrideDecoration } from "./decorations"; +import { getImplementDecoration } from "./decorations"; export class AnnotationLensProvider implements vscode.CodeLensProvider diff --git a/src/decorations.ts b/src/decorations.ts index 77acec9..3feeeb8 100644 --- a/src/decorations.ts +++ b/src/decorations.ts @@ -1,19 +1,11 @@ import * as vscode from "vscode"; -let overrideDecoration = vscode.window.createTextEditorDecorationType({ - gutterIconPath: __dirname + "/../resources/override.svg", - fontWeight: "bold", -}); let implementDecoration = vscode.window.createTextEditorDecorationType({ gutterIconPath: __dirname + "/../resources/implement.svg", fontWeight: "bold", }); -export function getOverrideDecoration() { - return overrideDecoration; -} - export function getImplementDecoration() { return implementDecoration; } \ No newline at end of file