Skip to content

Commit 7f62855

Browse files
authored
Using Structured Documentation for Signature Help and improving Parameter Documentation (#1958)
* Structured Documentation in Signature Help * Code clean up * Using only summary of the documentation * Code clean up * Documentation for parameters showing in signature help * Removing unnecesaary import * Using interploated string and fixed spacing * Parameter Documentation using interpolated text * Added tests
1 parent 2bb822d commit 7f62855

File tree

6 files changed

+158
-7
lines changed

6 files changed

+158
-7
lines changed

src/features/signatureHelpProvider.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
import AbstractSupport from './abstractProvider';
99
import * as serverUtils from '../omnisharp/utils';
10-
import {extractSummaryText} from './documentation';
11-
import {createRequest} from '../omnisharp/typeConvertion';
12-
import {SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, CancellationToken, TextDocument, Position} from 'vscode';
10+
import { createRequest } from '../omnisharp/typeConvertion';
11+
import { SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, CancellationToken, TextDocument, Position } from 'vscode';
12+
import { MarkdownString } from 'vscode';
13+
import { SignatureHelpParameter } from '../omnisharp/protocol';
1314

1415
export default class OmniSharpSignatureHelpProvider extends AbstractSupport implements SignatureHelpProvider {
1516

@@ -18,7 +19,7 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl
1819
let req = createRequest(document, position);
1920

2021
return serverUtils.signatureHelp(this._server, req, token).then(res => {
21-
22+
2223
if (!res) {
2324
return undefined;
2425
}
@@ -29,13 +30,13 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl
2930

3031
for (let signature of res.Signatures) {
3132

32-
let signatureInfo = new SignatureInformation(signature.Label, extractSummaryText(signature.Documentation));
33+
let signatureInfo = new SignatureInformation(signature.Label, signature.StructuredDocumentation.SummaryText);
3334
ret.signatures.push(signatureInfo);
3435

3536
for (let parameter of signature.Parameters) {
3637
let parameterInfo = new ParameterInformation(
3738
parameter.Label,
38-
extractSummaryText(parameter.Documentation));
39+
this.GetParameterDocumentation(parameter));
3940

4041
signatureInfo.parameters.push(parameterInfo);
4142
}
@@ -44,4 +45,14 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl
4445
return ret;
4546
});
4647
}
48+
49+
private GetParameterDocumentation(parameter: SignatureHelpParameter) {
50+
let summary = parameter.Documentation;
51+
if (summary.length > 0) {
52+
let paramText = `**${parameter.Name}**: ${summary}`;
53+
return new MarkdownString(paramText);
54+
}
55+
56+
return "";
57+
}
4758
}

src/omnisharp/protocol.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ export interface SignatureHelpItem {
398398
Label: string;
399399
Documentation: string;
400400
Parameters: SignatureHelpParameter[];
401+
StructuredDocumentation: DocumentationComment;
401402
}
402403

403404
export interface SignatureHelpParameter {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import * as path from 'path';
8+
9+
import poll from './poll';
10+
import { should, expect } from 'chai';
11+
import testAssetWorkspace from './testAssets/testAssetWorkspace';
12+
import { omnisharp } from '../../src/omnisharp/extension';
13+
14+
const chai = require('chai');
15+
chai.use(require('chai-arrays'));
16+
chai.use(require('chai-fs'));
17+
18+
suite(`SignatureHelp: ${testAssetWorkspace.description}`, function () {
19+
let fileUri: vscode.Uri;
20+
suiteSetup(async function () {
21+
should();
22+
23+
let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp");
24+
if (!csharpExtension.isActive) {
25+
await csharpExtension.activate();
26+
}
27+
28+
await csharpExtension.exports.initializationFinished;
29+
30+
let fileName = 'sigHelp.cs';
31+
let dir = path.dirname(testAssetWorkspace.projects[0].projectDirectoryPath);
32+
let loc = path.join(dir, fileName);
33+
fileUri = vscode.Uri.file(loc);
34+
await omnisharp.waitForEmptyEventQueue();
35+
await vscode.commands.executeCommand("vscode.open", fileUri);
36+
});
37+
38+
39+
test("Returns response with documentation as undefined when method does not have documentation", async function () {
40+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(19, 23));
41+
expect(c.signatures[0].documentation).to.be.undefined;
42+
});
43+
44+
test("Returns label when method does not have documentation", async function () {
45+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(19, 23));
46+
let answer = `void sigHelp.noDocMethod()`;
47+
expect(c.signatures[0].label).to.equal(answer);
48+
});
49+
50+
test("Returns summary as documentation for the method", async function () {
51+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
52+
let answer = `DoWork is some method.`;
53+
expect(c.signatures[0].documentation).to.equal(answer);
54+
});
55+
56+
test("Returns label for the method", async function () {
57+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
58+
let answer = `void sigHelp.DoWork(int Int1, float Float1)`;
59+
expect(c.signatures[0].label).to.equal(answer);
60+
});
61+
62+
test("Returns label for the parameters", async function () {
63+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
64+
let param1 = `int Int1`;
65+
let param2 = `float Float1`;
66+
expect(c.signatures[0].parameters[0].label).to.equal(param1);
67+
expect(c.signatures[0].parameters[1].label).to.equal(param2);
68+
});
69+
70+
test("Returns documentation for the parameters", async function () {
71+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
72+
let param1 = `**Int1**: Used to indicate status.`;
73+
let param2 = `**Float1**: Used to specify context.`;
74+
expect((<vscode.MarkdownString> c.signatures[0].parameters[0].documentation).value).to.equal(param1);
75+
expect((<vscode.MarkdownString> c.signatures[0].parameters[1].documentation).value).to.equal(param2);
76+
});
77+
78+
test("Signature Help identifies active parameter if there is no comma", async function () {
79+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
80+
let answer = `int Int1`;
81+
expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(answer);
82+
});
83+
84+
test("Signature Help identifies active parameter based on comma", async function () {
85+
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 20));
86+
let answer = `float Float1`;
87+
expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(answer);
88+
});
89+
90+
suiteTeardown(async () => {
91+
await testAssetWorkspace.cleanupWorkspace();
92+
});
93+
});
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fe2f654e9c48e6a308b6a264aa38a2b3defe5730
1+
a42255fc669f86623d73c2e9ad48ccb8310c65c0
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
namespace Test
3+
{
4+
class sigHelp
5+
{
6+
///<summary>DoWork is some method.</summary>
7+
/// <param name="Int1">Used to indicate status.</param>
8+
/// <param name="Float1">Used to specify context.</param>
9+
public static void DoWork(int Int1, float Float1)
10+
{
11+
}
12+
13+
public static void noDocMethod()
14+
{
15+
}
16+
17+
public static void main()
18+
{
19+
DoWork(4, 4.0f);
20+
noDocMethod();
21+
}
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
namespace Test
3+
{
4+
class sigHelp
5+
{
6+
///<summary>DoWork is some method.</summary>
7+
/// <param name="Int1">Used to indicate status.</param>
8+
/// <param name="Float1">Used to specify context.</param>
9+
public static void DoWork(int Int1, float Float1)
10+
{
11+
}
12+
13+
public static void noDocMethod()
14+
{
15+
}
16+
17+
public static void main()
18+
{
19+
DoWork(4, 4.0f);
20+
noDocMethod();
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)