From 752b478a8d8c835e8ee4763220610d7ee5bc4e02 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Thu, 20 Jun 2019 17:05:23 -0700 Subject: [PATCH 1/3] Fix addBrackets --- .../Impl/Completion/CompletionItemSource.cs | 8 ++++--- .../Impl/Completion/CompletionSource.cs | 5 +++++ .../Impl/Completion/ExpressionCompletion.cs | 5 +++-- .../Impl/Implementation/Server.cs | 1 + src/LanguageServer/Test/CompletionTests.cs | 21 +++++++++++++++++++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/LanguageServer/Impl/Completion/CompletionItemSource.cs b/src/LanguageServer/Impl/Completion/CompletionItemSource.cs index f202be5c4..60e43e7a2 100644 --- a/src/LanguageServer/Impl/Completion/CompletionItemSource.cs +++ b/src/LanguageServer/Impl/Completion/CompletionItemSource.cs @@ -28,13 +28,14 @@ internal class CompletionItemSource { public static readonly CompletionItem Star = CreateCompletionItem("*", CompletionItemKind.Keyword); private readonly IDocumentationSource _docSource; - private readonly ServerSettings.PythonCompletionOptions _options; public CompletionItemSource(IDocumentationSource docSource, ServerSettings.PythonCompletionOptions options) { _docSource = docSource; - _options = options; + Options = options; } + public ServerSettings.PythonCompletionOptions Options { get; set; } + public CompletionItem CreateCompletionItem(string text, IMember member, IPythonType self = null, string label = null) => CreateCompletionItem(text, ToCompletionItemKind(member?.MemberType ?? PythonMemberType.Class), member, self, label); @@ -42,7 +43,8 @@ public CompletionItemEx CreateCompletionItem(string text, CompletionItemKind kin var t = member?.GetPythonType(); var docFormat = _docSource.DocumentationFormat; - if (_options.addBrackets && (kind == CompletionItemKind.Constructor || kind == CompletionItemKind.Function || kind == CompletionItemKind.Method)) { + if (Options.addBrackets && (kind == CompletionItemKind.Constructor || kind == CompletionItemKind.Function || kind == CompletionItemKind.Method)) { + label = text; text += "($0)"; docFormat = InsertTextFormat.Snippet; } diff --git a/src/LanguageServer/Impl/Completion/CompletionSource.cs b/src/LanguageServer/Impl/Completion/CompletionSource.cs index 7f635c5c3..7b9d51cf4 100644 --- a/src/LanguageServer/Impl/Completion/CompletionSource.cs +++ b/src/LanguageServer/Impl/Completion/CompletionSource.cs @@ -29,6 +29,11 @@ public CompletionSource(IDocumentationSource docSource, ServerSettings.PythonCom _itemSource = new CompletionItemSource(docSource, completionSettings); } + public ServerSettings.PythonCompletionOptions Options { + get => _itemSource.Options; + set => _itemSource.Options = value; + } + public CompletionResult GetCompletions(IDocumentAnalysis analysis, SourceLocation location) { if(analysis.Document.ModuleType != ModuleType.User) { return CompletionResult.Empty; diff --git a/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs b/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs index d95d8366d..b23841e22 100644 --- a/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs +++ b/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs @@ -44,7 +44,7 @@ private static IEnumerable GetItemsFromExpression(Expression e, var type = value.GetPythonType(); if(type is IPythonClassType cls) { - return GetClassItems(cls, e, context); + return GetClassItems(cls, e, value is IPythonInstance, context); } var items = new List(); @@ -60,7 +60,7 @@ private static IEnumerable GetItemsFromExpression(Expression e, return Enumerable.Empty(); } - private static IEnumerable GetClassItems(IPythonClassType cls, Expression e, CompletionContext context) { + private static IEnumerable GetClassItems(IPythonClassType cls, Expression e, bool isInstance, CompletionContext context) { var eval = context.Analysis.ExpressionEvaluator; // See if we are completing on self. Note that we may be inside inner function // that does not necessarily have 'self' argument so we are looking beyond local @@ -76,6 +76,7 @@ private static IEnumerable GetClassItems(IPythonClassType cls, E if (m is IVariable v && v.Source != VariableSource.Declaration) { continue; } + // If this is class member completion, unmangle private member names. var unmangledName = cls.UnmangleMemberName(t); if (!string.IsNullOrEmpty(unmangledName)) { diff --git a/src/LanguageServer/Impl/Implementation/Server.cs b/src/LanguageServer/Impl/Implementation/Server.cs index 39b1720d4..61324ece6 100644 --- a/src/LanguageServer/Impl/Implementation/Server.cs +++ b/src/LanguageServer/Impl/Implementation/Server.cs @@ -209,6 +209,7 @@ private bool HandleConfigurationChanges(ServerSettings newSettings) { Settings = newSettings; _symbolHierarchyMaxSymbols = Settings.analysis.symbolsHierarchyMaxSymbols; + _completionSource.Options = Settings.completion; if (oldSettings == null) { return true; diff --git a/src/LanguageServer/Test/CompletionTests.cs b/src/LanguageServer/Test/CompletionTests.cs index 93eb1e189..16e3ffe7c 100644 --- a/src/LanguageServer/Test/CompletionTests.cs +++ b/src/LanguageServer/Test/CompletionTests.cs @@ -32,6 +32,7 @@ using Microsoft.Python.Parsing; using Microsoft.Python.Parsing.Tests; using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; using TestUtilities; namespace Microsoft.Python.LanguageServer.Tests { @@ -1194,5 +1195,25 @@ def test(x: Foo = func()): var comps = cs.GetCompletions(analysis, new SourceLocation(13, 7)); comps.Should().HaveLabels("name", "z"); } + + [TestMethod, Priority(0)] + public async Task AddBrackets() { + const string code = @"prin"; + var analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X); + + ServerSettings.completion.addBrackets = true; + var cs = new CompletionSource(new PlainTextDocumentationSource(), ServerSettings.completion); + + var comps = cs.GetCompletions(analysis, new SourceLocation(1, 5)); + var print = comps.Completions.FirstOrDefault(x => x.label == "print"); + print.Should().NotBeNull(); + print.insertText.Should().Be("print($0)"); + + cs.Options.addBrackets = false; + comps = cs.GetCompletions(analysis, new SourceLocation(1, 5)); + print = comps.Completions.FirstOrDefault(x => x.label == "print"); + print.Should().NotBeNull(); + print.insertText.Should().Be("print"); + } } } From 369e86f20f05ac64975407621f21045246b67e16 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Thu, 20 Jun 2019 17:08:45 -0700 Subject: [PATCH 2/3] Remove unrelated change --- src/LanguageServer/Impl/Completion/ExpressionCompletion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs b/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs index b23841e22..a199acae7 100644 --- a/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs +++ b/src/LanguageServer/Impl/Completion/ExpressionCompletion.cs @@ -44,7 +44,7 @@ private static IEnumerable GetItemsFromExpression(Expression e, var type = value.GetPythonType(); if(type is IPythonClassType cls) { - return GetClassItems(cls, e, value is IPythonInstance, context); + return GetClassItems(cls, e, context); } var items = new List(); @@ -60,7 +60,7 @@ private static IEnumerable GetItemsFromExpression(Expression e, return Enumerable.Empty(); } - private static IEnumerable GetClassItems(IPythonClassType cls, Expression e, bool isInstance, CompletionContext context) { + private static IEnumerable GetClassItems(IPythonClassType cls, Expression e, CompletionContext context) { var eval = context.Analysis.ExpressionEvaluator; // See if we are completing on self. Note that we may be inside inner function // that does not necessarily have 'self' argument so we are looking beyond local From cb0ae894e4dc60c820d0e42505a1f9b5ec3a67c9 Mon Sep 17 00:00:00 2001 From: Mikhail Arkhipov Date: Fri, 21 Jun 2019 08:55:37 -0700 Subject: [PATCH 3/3] Usings --- src/LanguageServer/Test/CompletionTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/LanguageServer/Test/CompletionTests.cs b/src/LanguageServer/Test/CompletionTests.cs index 16e3ffe7c..8b0416bb2 100644 --- a/src/LanguageServer/Test/CompletionTests.cs +++ b/src/LanguageServer/Test/CompletionTests.cs @@ -32,7 +32,6 @@ using Microsoft.Python.Parsing; using Microsoft.Python.Parsing.Tests; using Microsoft.VisualStudio.TestTools.UnitTesting; -using NSubstitute; using TestUtilities; namespace Microsoft.Python.LanguageServer.Tests {