Skip to content

Commit d3cee82

Browse files
committed
feat(gopls): add includes/excludes filter for implementation/reference api
1 parent 089bcb4 commit d3cee82

File tree

4 files changed

+192
-0
lines changed

4 files changed

+192
-0
lines changed

extension/package.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,30 @@
26152615
"type": "boolean",
26162616
"markdownDescription": "`\"rangeVariableTypes\"` controls inlay hints for variable types in range statements:\n```go\n\tfor k/* int*/, v/* string*/ := range []string{} {\n\t\tfmt.Println(k, v)\n\t}\n```\n",
26172617
"default": false
2618+
},
2619+
"go.implementation": {
2620+
"filesInclude": {
2621+
"type": "string",
2622+
"description": "files want to include in the implementation search.\n",
2623+
"scope": "resource"
2624+
},
2625+
"filesExclude": {
2626+
"type": "string",
2627+
"description": "files not want to include in the implementation search.\n",
2628+
"scope": "resource"
2629+
}
2630+
},
2631+
"go.reference": {
2632+
"filesInclude": {
2633+
"type": "string",
2634+
"description": "files want to include in the implementation search.\n",
2635+
"scope": "resource"
2636+
},
2637+
"filesExclude": {
2638+
"type": "string",
2639+
"description": "files not want to include in the implementation search.\n",
2640+
"scope": "resource"
2641+
}
26182642
}
26192643
}
26202644
},

extension/src/goImplementation.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*---------------------------------------------------------
2+
* Copyright 2022 The Go Authors. All rights reserved.
3+
* Licensed under the MIT License. See LICENSE in the project root for license information.
4+
*--------------------------------------------------------*/
5+
6+
import vscode = require('vscode');
7+
import { ImplementationRequest } from 'vscode-languageserver-protocol';
8+
import { GoExtensionContext } from './context';
9+
import { getGoConfig } from './config';
10+
import * as glob from './common/glob.js';
11+
12+
13+
14+
export function GoImplementationProvider(
15+
goCtx: GoExtensionContext,
16+
includeImports?: boolean
17+
): GoplsImplementationProvider {
18+
return new GoplsImplementationProvider(goCtx, includeImports);
19+
}
20+
21+
export class GoplsImplementationProvider implements vscode.ImplementationProvider {
22+
constructor(private readonly goCtx: GoExtensionContext, private includeImports?: boolean) { }
23+
public async provideImplementation(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken):
24+
Promise<vscode.Definition | vscode.LocationLink[] | null | undefined> {
25+
const { languageClient, serverInfo } = this.goCtx;
26+
if (!languageClient) {
27+
return [];
28+
}
29+
const params = languageClient.code2ProtocolConverter.asTextDocumentPositionParams(document, position);
30+
return languageClient.sendRequest(ImplementationRequest.type, params, token).then((result) => {
31+
if (token.isCancellationRequested) {
32+
return null;
33+
}
34+
const ret = languageClient.protocol2CodeConverter.asDefinitionResult(result, token);
35+
const implementationConfig = getGoConfig()['implementation'];
36+
let include = "";
37+
let exclude = "";
38+
if (implementationConfig) {
39+
include = implementationConfig["filesInclude"] as string;
40+
exclude = implementationConfig["filesExclude"] as string;
41+
}
42+
return ret.then((data) => {
43+
if (data) {
44+
const rawLinks = data as vscode.Location[];
45+
return filter(rawLinks, include, exclude);
46+
}
47+
});
48+
}, (error) => {
49+
return languageClient.handleFailedRequest(ImplementationRequest.type, token, error, null);
50+
});
51+
52+
53+
54+
function filter(links: vscode.Location[], include: string, exclude: string,): vscode.Location[] {
55+
const ret = links.filter(item => {
56+
let matches = true;
57+
if (include && include !== '') {
58+
matches = glob.match(include, item.uri.toString());
59+
}
60+
61+
let doesNotMatch = true;
62+
if (exclude && exclude !== '') {
63+
doesNotMatch = !glob.match(exclude, item.uri.toString());
64+
}
65+
return matches && doesNotMatch;
66+
});
67+
68+
return ret;
69+
}
70+
}
71+
72+
static activate(ctx: vscode.ExtensionContext, goCtx: GoExtensionContext) {
73+
let languageClient = goCtx.languageClient;
74+
if (languageClient) {
75+
languageClient.middleware.provideImplementation = new GoplsImplementationProvider(goCtx, true).provideImplementation;
76+
}
77+
vscode.languages.registerImplementationProvider('go', new GoplsImplementationProvider(goCtx, true))
78+
}
79+
80+
}

extension/src/goMain.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ import { toggleVulncheckCommandFactory } from './goVulncheck';
7474
import { GoTaskProvider } from './goTaskProvider';
7575
import { setTelemetryEnvVars, telemetryReporter } from './goTelemetry';
7676
import { experiments } from './experimental';
77+
import { GoplsImplementationProvider } from './goImplementation';
78+
import { GoplsReferenceProvider } from './goReference';
7779

7880
const goCtx: GoExtensionContext = {};
7981

@@ -149,6 +151,9 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<ExtensionA
149151
GoDebugConfigurationProvider.activate(ctx, goCtx);
150152
GoDebugFactory.activate(ctx, goCtx);
151153
experiments.activate(ctx);
154+
GoplsImplementationProvider.activate(ctx, goCtx);
155+
GoplsReferenceProvider.activate(ctx, goCtx);
156+
152157
GoTestExplorer.setup(ctx, goCtx);
153158
GoExplorerProvider.setup(ctx);
154159

extension/src/goReference.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*---------------------------------------------------------
2+
* Copyright 2022 The Go Authors. All rights reserved.
3+
* Licensed under the MIT License. See LICENSE in the project root for license information.
4+
*--------------------------------------------------------*/
5+
6+
import vscode = require('vscode');
7+
import { ReferencesRequest } from 'vscode-languageserver-protocol';
8+
import { GoExtensionContext } from './context';
9+
import { getGoConfig } from './config';
10+
import * as glob from './common/glob.js';
11+
12+
13+
export function GoImplementationProvider(
14+
goCtx: GoExtensionContext,
15+
includeImports?: boolean
16+
): GoplsReferenceProvider {
17+
return new GoplsReferenceProvider(goCtx, includeImports);
18+
}
19+
20+
export class GoplsReferenceProvider implements vscode.ReferenceProvider {
21+
constructor(private readonly goCtx: GoExtensionContext, private includeImports?: boolean) { }
22+
23+
public provideReferences(document: vscode.TextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): vscode.ProviderResult<vscode.Location[]> {
24+
{
25+
const { languageClient, serverInfo } = this.goCtx;
26+
if (!languageClient) {
27+
return [];
28+
}
29+
30+
const params = languageClient.code2ProtocolConverter.asReferenceParams(document, position,context);
31+
return languageClient.sendRequest(ReferencesRequest.type, params, token).then((result) => {
32+
if (token.isCancellationRequested) {
33+
return null;
34+
}
35+
const ret = languageClient.protocol2CodeConverter.asDefinitionResult(result, token);
36+
const referenceConfig = getGoConfig()['reference'];
37+
let include = "";
38+
let exclude = "";
39+
if (referenceConfig){
40+
include = referenceConfig["filesInclude"] as string;
41+
exclude = referenceConfig["filesExclude"] as string;
42+
}
43+
44+
return ret.then((data) => {
45+
if (data) {
46+
const rawLinks = data as vscode.Location[];
47+
return filter(rawLinks, include, exclude);
48+
}
49+
});
50+
}, (error) => {
51+
return languageClient.handleFailedRequest(ReferencesRequest.type, token, error, null);
52+
});
53+
54+
55+
56+
function filter(links: vscode.Location[], include: string, exclude: string,): vscode.Location[] {
57+
const ret = links.filter(item => {
58+
let matches = true;
59+
if (include && include !== '') {
60+
matches = glob.match(include, item.uri.toString());
61+
}
62+
63+
let doesNotMatch = true;
64+
if (exclude && exclude !== '') {
65+
doesNotMatch = !glob.match(exclude, item.uri.toString());
66+
}
67+
return matches && doesNotMatch;
68+
});
69+
70+
return ret;
71+
}
72+
}
73+
74+
}
75+
static activate(ctx: vscode.ExtensionContext, goCtx: GoExtensionContext) {
76+
let languageClient = goCtx.languageClient;
77+
if (languageClient) {
78+
languageClient.middleware.provideReferences = new GoplsReferenceProvider(goCtx, true).provideReferences;
79+
}
80+
vscode.languages.registerReferenceProvider('go', new GoplsReferenceProvider(goCtx, true))
81+
}
82+
83+
}

0 commit comments

Comments
 (0)