Skip to content

Commit

Permalink
Using Structured Documentation for Signature Help and improving Param…
Browse files Browse the repository at this point in the history
…eter 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
  • Loading branch information
akshita31 authored Feb 21, 2018
1 parent 2bb822d commit 7f62855
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 7 deletions.
23 changes: 17 additions & 6 deletions src/features/signatureHelpProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

import AbstractSupport from './abstractProvider';
import * as serverUtils from '../omnisharp/utils';
import {extractSummaryText} from './documentation';
import {createRequest} from '../omnisharp/typeConvertion';
import {SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, CancellationToken, TextDocument, Position} from 'vscode';
import { createRequest } from '../omnisharp/typeConvertion';
import { SignatureHelpProvider, SignatureHelp, SignatureInformation, ParameterInformation, CancellationToken, TextDocument, Position } from 'vscode';
import { MarkdownString } from 'vscode';
import { SignatureHelpParameter } from '../omnisharp/protocol';

export default class OmniSharpSignatureHelpProvider extends AbstractSupport implements SignatureHelpProvider {

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

return serverUtils.signatureHelp(this._server, req, token).then(res => {

if (!res) {
return undefined;
}
Expand All @@ -29,13 +30,13 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl

for (let signature of res.Signatures) {

let signatureInfo = new SignatureInformation(signature.Label, extractSummaryText(signature.Documentation));
let signatureInfo = new SignatureInformation(signature.Label, signature.StructuredDocumentation.SummaryText);
ret.signatures.push(signatureInfo);

for (let parameter of signature.Parameters) {
let parameterInfo = new ParameterInformation(
parameter.Label,
extractSummaryText(parameter.Documentation));
this.GetParameterDocumentation(parameter));

signatureInfo.parameters.push(parameterInfo);
}
Expand All @@ -44,4 +45,14 @@ export default class OmniSharpSignatureHelpProvider extends AbstractSupport impl
return ret;
});
}

private GetParameterDocumentation(parameter: SignatureHelpParameter) {
let summary = parameter.Documentation;
if (summary.length > 0) {
let paramText = `**${parameter.Name}**: ${summary}`;
return new MarkdownString(paramText);
}

return "";
}
}
1 change: 1 addition & 0 deletions src/omnisharp/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ export interface SignatureHelpItem {
Label: string;
Documentation: string;
Parameters: SignatureHelpParameter[];
StructuredDocumentation: DocumentationComment;
}

export interface SignatureHelpParameter {
Expand Down
93 changes: 93 additions & 0 deletions test/integrationTests/signatureHelp.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as path from 'path';

import poll from './poll';
import { should, expect } from 'chai';
import testAssetWorkspace from './testAssets/testAssetWorkspace';
import { omnisharp } from '../../src/omnisharp/extension';

const chai = require('chai');
chai.use(require('chai-arrays'));
chai.use(require('chai-fs'));

suite(`SignatureHelp: ${testAssetWorkspace.description}`, function () {
let fileUri: vscode.Uri;
suiteSetup(async function () {
should();

let csharpExtension = vscode.extensions.getExtension("ms-vscode.csharp");
if (!csharpExtension.isActive) {
await csharpExtension.activate();
}

await csharpExtension.exports.initializationFinished;

let fileName = 'sigHelp.cs';
let dir = path.dirname(testAssetWorkspace.projects[0].projectDirectoryPath);
let loc = path.join(dir, fileName);
fileUri = vscode.Uri.file(loc);
await omnisharp.waitForEmptyEventQueue();
await vscode.commands.executeCommand("vscode.open", fileUri);
});


test("Returns response with documentation as undefined when method does not have documentation", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(19, 23));
expect(c.signatures[0].documentation).to.be.undefined;
});

test("Returns label when method does not have documentation", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(19, 23));
let answer = `void sigHelp.noDocMethod()`;
expect(c.signatures[0].label).to.equal(answer);
});

test("Returns summary as documentation for the method", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
let answer = `DoWork is some method.`;
expect(c.signatures[0].documentation).to.equal(answer);
});

test("Returns label for the method", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
let answer = `void sigHelp.DoWork(int Int1, float Float1)`;
expect(c.signatures[0].label).to.equal(answer);
});

test("Returns label for the parameters", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
let param1 = `int Int1`;
let param2 = `float Float1`;
expect(c.signatures[0].parameters[0].label).to.equal(param1);
expect(c.signatures[0].parameters[1].label).to.equal(param2);
});

test("Returns documentation for the parameters", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
let param1 = `**Int1**: Used to indicate status.`;
let param2 = `**Float1**: Used to specify context.`;
expect((<vscode.MarkdownString> c.signatures[0].parameters[0].documentation).value).to.equal(param1);
expect((<vscode.MarkdownString> c.signatures[0].parameters[1].documentation).value).to.equal(param2);
});

test("Signature Help identifies active parameter if there is no comma", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 18));
let answer = `int Int1`;
expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(answer);
});

test("Signature Help identifies active parameter based on comma", async function () {
let c = <vscode.SignatureHelp>await vscode.commands.executeCommand("vscode.executeSignatureHelpProvider", fileUri, new vscode.Position(18, 20));
let answer = `float Float1`;
expect(c.signatures[0].parameters[c.activeParameter].label).to.equal(answer);
});

suiteTeardown(async () => {
await testAssetWorkspace.cleanupWorkspace();
});
});
Original file line number Diff line number Diff line change
@@ -1 +1 @@
fe2f654e9c48e6a308b6a264aa38a2b3defe5730
a42255fc669f86623d73c2e9ad48ccb8310c65c0
23 changes: 23 additions & 0 deletions test/integrationTests/testAssets/singleCsproj/sigHelp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
namespace Test
{
class sigHelp
{
///<summary>DoWork is some method.</summary>
/// <param name="Int1">Used to indicate status.</param>
/// <param name="Float1">Used to specify context.</param>
public static void DoWork(int Int1, float Float1)
{
}

public static void noDocMethod()
{
}

public static void main()
{
DoWork(4, 4.0f);
noDocMethod();
}
}
}
23 changes: 23 additions & 0 deletions test/integrationTests/testAssets/slnWithCsproj/src/app/sigHelp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
namespace Test
{
class sigHelp
{
///<summary>DoWork is some method.</summary>
/// <param name="Int1">Used to indicate status.</param>
/// <param name="Float1">Used to specify context.</param>
public static void DoWork(int Int1, float Float1)
{
}

public static void noDocMethod()
{
}

public static void main()
{
DoWork(4, 4.0f);
noDocMethod();
}
}
}

0 comments on commit 7f62855

Please sign in to comment.