Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper Newlines in Hover #1918

Merged
merged 30 commits into from
Jan 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2f9c784
Added the changes for structured documentation
akshita31 Dec 6, 2017
cc22739
Merge remote-tracking branch 'rchande/testImprovements' into typelook…
akshita31 Dec 6, 2017
0df87fa
Test
akshita31 Dec 6, 2017
27f5dde
First Test Running Properly
akshita31 Dec 6, 2017
50aa8e8
Integration Test Running
akshita31 Dec 8, 2017
007dba8
Test Commit
akshita31 Dec 8, 2017
b66e5f1
Add new test files next to the csproj, not in the root of the workspace
Dec 11, 2017
6873f90
Make it possible for tests to await restore
Dec 11, 2017
882d13b
Enable tests to wait for the omnisharp request queue to be empty
Dec 11, 2017
ccc21a6
Wait for queue empty in hover test
Dec 11, 2017
d0acf84
Removed debug statements
akshita31 Dec 11, 2017
eebb979
Removed Unnecessary space
akshita31 Dec 11, 2017
0207222
Added braces for if-else
akshita31 Dec 11, 2017
66f5b7e
Added conditions for each field individually
akshita31 Dec 11, 2017
2e96efc
Merge branch 'master' into typelookup_changed
Dec 12, 2017
c07a4ca
Aligned parameters
akshita31 Dec 12, 2017
c621872
Merge branch 'typelookup_changed' of https://github.com/akshita31/omn…
akshita31 Dec 12, 2017
05ed4bd
Changes for parameter as an object
akshita31 Dec 13, 2017
47129b7
Add missing line
akshita31 Dec 13, 2017
e289fb1
Changed to DocumentationItem
akshita31 Dec 13, 2017
d7e0f35
Merge remote-tracking branch 'upstream/master' into typelookup_changed
akshita31 Dec 14, 2017
c2a32f7
Extracted Documentation helper as a function in a separate file
akshita31 Jan 11, 2018
9e61bc9
Removed unnecessary using
akshita31 Jan 11, 2018
b57e7a9
Merge remote-tracking branch 'upstream/master' into typelookup_changed
akshita31 Jan 11, 2018
ecec82c
Code Clean up
akshita31 Jan 11, 2018
cbfde53
Clean up
akshita31 Jan 11, 2018
62e6c2e
Fixed spacing
akshita31 Jan 12, 2018
5fe5694
Merge branch 'master' into typelookup_changed
akshita31 Jan 12, 2018
5e69bcb
Removed unused variable
akshita31 Jan 12, 2018
3e4b01a
Merge branch 'typelookup_changed' of https://github.com/akshita31/omn…
akshita31 Jan 12, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/features/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function projectsToCommands(projects: protocol.ProjectDescriptor[]): Promise<Com
});
}

export function dotnetRestoreAllProjects(server: OmniSharpServer) {
export function dotnetRestoreAllProjects(server: OmniSharpServer) : Promise<void> {

if (!server.isRunning()) {
return Promise.reject('OmniSharp server is not running.');
Expand Down
49 changes: 49 additions & 0 deletions src/features/documentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

'use strict';
import * as protocol from '../omnisharp/protocol';

const summaryStartTag = /<summary>/i;
const summaryEndTag = /<\/summary>/i;
Expand All @@ -29,3 +30,51 @@ export function extractSummaryText(xmlDocComment: string): string {

return summary.slice(0, endIndex);
}

export function GetDocumentationString(structDoc: protocol.DocumentationComment) {
let newLine = "\n\n";
let indentSpaces = "\t\t";
let documentation = "";

if (structDoc.SummaryText) {
documentation += structDoc.SummaryText + newLine;
}

if (structDoc.TypeParamElements && structDoc.TypeParamElements.length > 0) {
documentation += "Type Parameters:" + newLine;
documentation += indentSpaces + structDoc.TypeParamElements.map(displayDocumentationObject).join("\n" + indentSpaces) + newLine;
}

if (structDoc.ParamElements && structDoc.ParamElements.length > 0) {
documentation += "Parameters:" + newLine;
documentation += indentSpaces + structDoc.ParamElements.map(displayDocumentationObject).join("\n" + indentSpaces) + newLine;
}

if (structDoc.ReturnsText) {
documentation += structDoc.ReturnsText + newLine;
}

if (structDoc.RemarksText) {
documentation += structDoc.RemarksText + newLine;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth extracting out a little helper method that adds the newline for you.

}

if (structDoc.ExampleText) {
documentation += structDoc.ExampleText + newLine;
}

if (structDoc.ValueText) {
documentation += structDoc.ValueText + newLine;
}

if (structDoc.Exception && structDoc.Exception.length > 0) {
documentation += "Exceptions:" + newLine;
documentation += indentSpaces + structDoc.Exception.map(displayDocumentationObject).join("\n" + indentSpaces) + newLine;
}

documentation = documentation.trim();
return documentation;
}

export function displayDocumentationObject(obj: protocol.DocumentationItem): string {
return obj.Name + ": " + obj.Documentation;
}
11 changes: 6 additions & 5 deletions src/features/hoverProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@

'use strict';

import {extractSummaryText} from './documentation';
import AbstractSupport from './abstractProvider';
import * as protocol from '../omnisharp/protocol';
import * as serverUtils from '../omnisharp/utils';
import {createRequest} from '../omnisharp/typeConvertion';
import {HoverProvider, Hover, TextDocument, CancellationToken, Position} from 'vscode';
import { createRequest } from '../omnisharp/typeConvertion';
import { HoverProvider, Hover, TextDocument, CancellationToken, Position } from 'vscode';
import { GetDocumentationString } from './documentation';

export default class OmniSharpHoverProvider extends AbstractSupport implements HoverProvider {

Expand All @@ -21,9 +21,10 @@ export default class OmniSharpHoverProvider extends AbstractSupport implements H

return serverUtils.typeLookup(this._server, req, token).then(value => {
if (value && value.Type) {
let contents = [extractSummaryText(value.Documentation), { language: 'csharp', value: value.Type }];
let documentation = GetDocumentationString(value.StructuredDocumentation);
let contents = [documentation, { language: 'csharp', value: value.Type }];
return new Hover(contents);
}
});
}
}
}
3 changes: 3 additions & 0 deletions src/omnisharp/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import forwardChanges from '../features/changeForwarding';
import registerCommands from '../features/commands';
import reportStatus from '../features/status';

export let omnisharp: OmniSharpServer;

export function activate(context: vscode.ExtensionContext, reporter: TelemetryReporter, channel: vscode.OutputChannel) {
const documentSelector: vscode.DocumentSelector = {
language: 'csharp',
Expand All @@ -42,6 +44,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe
const options = Options.Read();

const server = new OmniSharpServer(reporter);
omnisharp = server;
const advisor = new Advisor(server); // create before server is started
const disposables: vscode.Disposable[] = [];
const localDisposables: vscode.Disposable[] = [];
Expand Down
24 changes: 20 additions & 4 deletions src/omnisharp/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,30 @@ export interface FindSymbolsResponse {
QuickFixes: SymbolLocation[];
}

export interface DocumentationItem {
Name: string;
Documentation: string;
}

export interface DocumentationComment {
SummaryText: string;
TypeParamElements: DocumentationItem[];
ParamElements: DocumentationItem[];
ReturnsText: string;
RemarksText: string;
ExampleText: string;
ValueText: string;
Exception: DocumentationItem[];
}

export interface TypeLookupRequest extends Request {
IncludeDocumentation: boolean;
}

export interface TypeLookupResponse {
Type: string;
Documentation: string;
StructuredDocumentation: DocumentationComment;
}

export interface RunCodeActionResponse {
Expand Down Expand Up @@ -418,13 +435,12 @@ export interface PackageDependency {
Name: string;
Version: string;
}
export interface FilesChangedRequest extends Request{

export interface FilesChangedRequest extends Request {
ChangeType: FileChangeType;
}

export enum FileChangeType
{
export enum FileChangeType {
Change = "Change",
Create = "Create",
Delete = "Delete"
Expand Down
7 changes: 7 additions & 0 deletions src/omnisharp/requestQueue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ export class RequestQueueCollection {
}
}

public isEmpty()
{
return !this._deferredQueue.hasPending()
&& !this._normalQueue.hasPending()
&& !this._priorityQueue.hasPending();
}

public enqueue(request: Request) {
const queue = this.getQueue(request.command);
queue.enqueue(request);
Expand Down
8 changes: 8 additions & 0 deletions src/omnisharp/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as path from 'path';
import * as protocol from './protocol';
import * as utils from '../common';
import * as vscode from 'vscode';
import { setTimeout } from 'timers';

enum ServerState {
Starting,
Expand Down Expand Up @@ -98,6 +99,13 @@ export class OmniSharpServer {
return this._state === ServerState.Started;
}

public async waitForEmptyEventQueue() : Promise<void> {
while (!this._requestQueue.isEmpty()) {
let p = new Promise((resolve) => setTimeout(resolve, 100));
await p;
}
}

private _getState(): ServerState {
return this._state;
}
Expand Down
83 changes: 83 additions & 0 deletions test/integrationTests/hoverProvider.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as fs from 'async-file';
import * as vscode from 'vscode';

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

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

suite(`Tasks generation: ${testAssetWorkspace.description}`, function() {
suiteSetup(async function() {
should();

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

await testAssetWorkspace.cleanupWorkspace();

await csharpExtension.exports.initializationFinished;

await vscode.commands.executeCommand("dotnet.generateAssets");

await poll(async () => await fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100);

});


test("Hover returns structured documentation with proper newlines", async function () {

let program =
`using System;
namespace Test
{
class testissue
{
///<summary>Checks if object is tagged with the tag.</summary>
/// <param name="gameObject">The game object.</param>
/// <param name="tagName">Name of the tag.</param>
/// <returns>Returns <c> true</c> if object is tagged with tag.</returns>

public static bool Compare(int gameObject,string tagName)
{
return true;
}
}
}`;
let fileUri = await testAssetWorkspace.projects[0].addFileWithContents("test1.cs", program);

await omnisharp.waitForEmptyEventQueue();

await vscode.commands.executeCommand("vscode.open", fileUri);

let c = await vscode.commands.executeCommand("vscode.executeHoverProvider", fileUri,new vscode.Position(10,29));

let answer:string =
`Checks if object is tagged with the tag.

Parameters:

\t\tgameObject: The game object.
\t\ttagName: Name of the tag.

Returns trueif object is tagged with tag.`;
expect(c[0].contents[0].value).to.equal(answer);
});

teardown(async() =>
{
await testAssetWorkspace.cleanupWorkspace();
})
});
36 changes: 18 additions & 18 deletions test/integrationTests/launchConfiguration.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,42 @@ import poll from './poll';
import { should } from 'chai';
import testAssetWorkspace from './testAssets/testAssetWorkspace';

const chai = require('chai');
chai.use(require('chai-arrays'));
chai.use(require('chai-fs'));
suite(`Tasks generation: ${testAssetWorkspace.description}`, function() {
suiteSetup(async function() {
const chai = require('chai');
chai.use(require('chai-arrays'));
chai.use(require('chai-fs'));

suite(`Tasks generation: ${testAssetWorkspace.description}`, function () {
suiteSetup(async function () {
should();

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

await testAssetWorkspace.cleanupWorkspace();

await csharpExtension.exports.initializationFinished;

await vscode.commands.executeCommand("dotnet.generateAssets");

await poll(async () => await fs.exists(testAssetWorkspace.launchJsonPath), 10000, 100);
});

test("Starting .NET Core Launch (console) from the workspace root should create an Active Debug Session", async () => {

});

test("Starting .NET Core Launch (console) from the workspace root should create an Active Debug Session", async () => {
await vscode.debug.startDebugging(vscode.workspace.workspaceFolders[0], ".NET Core Launch (console)");

let debugSessionTerminated = new Promise(resolve => {
vscode.debug.onDidTerminateDebugSession((e) => resolve());
});

vscode.debug.activeDebugSession.type.should.equal("coreclr");

await debugSessionTerminated;
});

teardown(async() =>
{
teardown(async () => {
await testAssetWorkspace.cleanupWorkspace();
})
});
});
});
Loading