Skip to content

Commit

Permalink
Discovered root cause & fixed issue with popups in comments
Browse files Browse the repository at this point in the history
- issue microsoft#2057
- struggling with test framework & signature provider!
  • Loading branch information
d3r3kk committed Jun 29, 2018
1 parent d17f16f commit 997c7b9
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 19 deletions.
15 changes: 4 additions & 11 deletions src/client/providers/completionSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,18 @@ export class CompletionSource {

private async getCompletionResult(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken)
: Promise<proxy.ICompletionResult | undefined> {
if (position.character <= 0) {
return undefined;
}
const filename = document.fileName;
const lineText = document.lineAt(position.line).text;
if (lineText.match(/^\s*\/\//)) {
return undefined;
}
// Suppress completion inside string and comments.
if (isPositionInsideStringOrComment(document, position)) {
if (position.character <= 0 ||
isPositionInsideStringOrComment(document, position)) {
return undefined;
}

const type = proxy.CommandType.Completions;
const columnIndex = position.character;

const source = document.getText();
const cmd: proxy.ICommand<proxy.ICommandResult> = {
command: type,
fileName: filename,
fileName: document.fileName,
columnIndex: columnIndex,
lineIndex: position.line,
source: source
Expand Down
8 changes: 4 additions & 4 deletions src/client/providers/providerUtilities.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import * as vscode from 'vscode';
import { Position, Range, TextDocument } from 'vscode';
import { Tokenizer } from '../language/tokenizer';
import { ITextRangeCollection, IToken, TokenizerMode, TokenType } from '../language/types';

export function getDocumentTokens(document: vscode.TextDocument, tokenizeTo: vscode.Position, mode: TokenizerMode): ITextRangeCollection<IToken> {
const text = document.getText(new vscode.Range(new vscode.Position(0, 0), tokenizeTo));
export function getDocumentTokens(document: TextDocument, tokenizeTo: Position, mode: TokenizerMode): ITextRangeCollection<IToken> {
const text = document.getText(new Range(new Position(0, 0), tokenizeTo));
return new Tokenizer().tokenize(text, 0, text.length, mode);
}

export function isPositionInsideStringOrComment(document: vscode.TextDocument, position: vscode.Position): boolean {
export function isPositionInsideStringOrComment(document: TextDocument, position: Position): boolean {
const tokenizeTo = position.translate(1, 0);
const tokens = getDocumentTokens(document, tokenizeTo, TokenizerMode.CommentsAndStrings);
const offset = document.offsetAt(position);
Expand Down
12 changes: 10 additions & 2 deletions src/client/providers/signatureProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { JediFactory } from '../languageServices/jediProxyFactory';
import { captureTelemetry } from '../telemetry';
import { SIGNATURE } from '../telemetry/constants';
import * as proxy from './jediProxy';
import { isPositionInsideStringOrComment } from './providerUtilities';

const DOCSTRING_PARAM_PATTERNS = [
'\\s*:type\\s*PARAMNAME:\\s*([^\\n, ]+)', // Sphinx
Expand Down Expand Up @@ -71,7 +72,7 @@ export class PythonSignatureProvider implements SignatureHelpProvider {

if (validParamInfo) {
const docLines = def.docstring.splitLines();
label = docLines.shift().trim();
label = docLines.shift()!.trim();
documentation = docLines.join(EOL).trim();
} else {
if (def.params && def.params.length > 0) {
Expand Down Expand Up @@ -110,7 +111,14 @@ export class PythonSignatureProvider implements SignatureHelpProvider {
return new SignatureHelp();
}
@captureTelemetry(SIGNATURE)
public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Thenable<SignatureHelp> {
public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Thenable<SignatureHelp | undefined> {
// early exit if we're in a string or comment (or in an undefined position)
if (position.character <= 0 ||
isPositionInsideStringOrComment(document, position))
{
return Promise.resolve(undefined);
}

const cmd: proxy.ICommand<proxy.IArgumentsResult> = {
command: proxy.CommandType.Arguments,
fileName: document.fileName,
Expand Down
32 changes: 30 additions & 2 deletions src/test/providers/completionSource.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@

// tslint:disable:max-func-body-length no-any

// import { expect, use } from 'chai';
// import * as chaipromise from 'chai-as-promised';
import * as TypeMoq from 'typemoq';
import { CancellationTokenSource, CompletionItemKind, Position, SymbolKind, TextDocument, TextLine } from 'vscode';
import { CancellationTokenSource, CompletionItemKind, // CancellationToken
Position, SymbolKind, TextDocument, TextLine } from 'vscode'; // SignatureHelp
import { IAutoCompleteSettings, IConfigurationService, IPythonSettings } from '../../client/common/types';
import { IServiceContainer } from '../../client/ioc/types';
import { JediFactory } from '../../client/languageServices/jediProxyFactory';
import { CompletionSource } from '../../client/providers/completionSource';
import { IItemInfoSource } from '../../client/providers/itemInfoSource';
import { IAutoCompleteItem, ICompletionResult, JediProxyHandler } from '../../client/providers/jediProxy';
import { IAutoCompleteItem, // IArgumentsResult
ICompletionResult, JediProxyHandler } from '../../client/providers/jediProxy';
//import { PythonSignatureProvider } from '../../client/providers/signatureProvider';

//use(chaipromise);

suite('Completion Provider', () => {
let completionSource: CompletionSource;
//let pySignatureProvider: PythonSignatureProvider;
let jediHandler: TypeMoq.IMock<JediProxyHandler<ICompletionResult>>;
let autoCompleteSettings: TypeMoq.IMock<IAutoCompleteSettings>;
let itemInfoSource: TypeMoq.IMock<IItemInfoSource>;
Expand All @@ -36,6 +44,7 @@ suite('Completion Provider', () => {
pythonSettings.setup(p => p.autoComplete).returns(() => autoCompleteSettings.object);
itemInfoSource = TypeMoq.Mock.ofType<IItemInfoSource>();
completionSource = new CompletionSource(jediFactory.object, serviceContainer.object, itemInfoSource.object);
//pySignatureProvider = new PythonSignatureProvider(jediFactory.object);
});

async function testDocumentation(source: string, addBrackets: boolean) {
Expand Down Expand Up @@ -85,5 +94,24 @@ suite('Completion Provider', () => {
const source = 'if True:\n print("Hello")\n';
await testDocumentation(source, true);
});
// test('Signature provides docs for commands', async () => {
// const source = ' print(\'Python is awesome\',)';
// const position = new Position(1, 27);

// const lineText = TypeMoq.Mock.ofType<TextLine>();
// lineText.setup(l => l.text).returns(() => source);

// const doc = TypeMoq.Mock.ofType<TextDocument>();
// doc.setup(d => d.fileName).returns(() => '');
// doc.setup(d => d.getText(TypeMoq.It.isAny())).returns(() => source);
// doc.setup(d => d.lineAt(TypeMoq.It.isAny())).returns(() => lineText.object);
// doc.setup(d => d.offsetAt(TypeMoq.It.isAny())).returns(() => 0);
// const cancelToken = TypeMoq.Mock.ofType<CancellationToken>();
// jediHandler.setup(j => j.sendCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
// .returns(() => new Promise.resolve(IArgumentsResult));

// const items: SignatureHelp = await pySignatureProvider.provideSignatureHelp(doc.object, position, cancelToken.object);

// expect(items).to.not.equal(null, 'Expected to have a signature generated for this line of code.');
// });
});

0 comments on commit 997c7b9

Please sign in to comment.