From 30c5092314fbbf4209e67ea3d8de50142b9af8e9 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 22 Nov 2017 17:07:10 -0800 Subject: [PATCH 01/15] Added code to check for the methods in the base classes --- .../Services/Signatures/SignatureHelpService.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index 8dc8a593e2..acb4ae5f63 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -133,7 +133,15 @@ private IEnumerable GetMethodOverloads(SemanticModel semanticMode return new IMethodSymbol[] { }; } - return symbol.ContainingType.GetMembers(symbol.Name).OfType(); + var MethodOverloads = symbol.ContainingType.GetMembers(symbol.Name).OfType(); + var BaseType = symbol.ContainingType.BaseType; + while(BaseType!=null) + { + MethodOverloads = MethodOverloads.Concat(BaseType.GetMembers(symbol.Name).OfType()); + BaseType = BaseType.BaseType; + } + + return MethodOverloads; } private int InvocationScore(IMethodSymbol symbol, IEnumerable types) From de3de6a3f38c4b52375ca62e0ee0339ca67eec0d Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 22 Nov 2017 18:09:36 -0800 Subject: [PATCH 02/15] Made changes to avoid the classes in System Namespace and added test --- .../Signatures/SignatureHelpService.cs | 2 +- .../SignatureHelpFacts.cs | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index acb4ae5f63..0356795929 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -135,7 +135,7 @@ private IEnumerable GetMethodOverloads(SemanticModel semanticMode var MethodOverloads = symbol.ContainingType.GetMembers(symbol.Name).OfType(); var BaseType = symbol.ContainingType.BaseType; - while(BaseType!=null) + while(BaseType!=null && BaseType.ContainingNamespace.Name!= "System") { MethodOverloads = MethodOverloads.Concat(BaseType.GetMembers(symbol.Name).OfType()); BaseType = BaseType.BaseType; diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index 031b25d44c..55a0800a3a 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -474,13 +474,40 @@ public Program(Program p, int n) { } }"; - var actual = await GetSignatureHelp(source); Assert.Equal(3, actual.Signatures.Count()); Assert.Equal(1, actual.ActiveParameter); Assert.Contains("ctor2", actual.Signatures.ElementAt(actual.ActiveSignature).Documentation); } + [Fact] + public async Task SignatureHelpForOverloadedMethodsInheritance() + { + const string source = +@"public class MyBase +{ + public void MyMethod(int a) { } + public void MyMethod(int a, int b) { } +} + +public class Class1 : MyBase +{ + public void MyMethod(int a, int b, int c) { } + public void MyMethod(int a, int b, int c, int d) { } +} + +public class Class2 +{ + public void foo() + { + Class1 c1 = new Class1(); + c1.MyMethod($$); + } + + }"; + var actual = await GetSignatureHelp(source); + Assert.Equal(4, actual.Signatures.Count()); + } [Fact] public async Task SkipReceiverOfExtensionMethods() { From ef0352ab66dc2d762b422c08e00cea881feb92f7 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Thu, 23 Nov 2017 11:29:12 -0800 Subject: [PATCH 03/15] Changed local variables to lowerCase and added spacing --- .../Services/Signatures/SignatureHelpService.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index 0356795929..e823de34f9 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -133,15 +133,15 @@ private IEnumerable GetMethodOverloads(SemanticModel semanticMode return new IMethodSymbol[] { }; } - var MethodOverloads = symbol.ContainingType.GetMembers(symbol.Name).OfType(); - var BaseType = symbol.ContainingType.BaseType; - while(BaseType!=null && BaseType.ContainingNamespace.Name!= "System") + var methodOverloads = symbol.ContainingType.GetMembers(symbol.Name).OfType(); + var baseTypeSymbol = symbol.ContainingType.BaseType; + while(baseTypeSymbol != null && baseTypeSymbol.ContainingNamespace.Name != "System") { - MethodOverloads = MethodOverloads.Concat(BaseType.GetMembers(symbol.Name).OfType()); - BaseType = BaseType.BaseType; + methodOverloads = methodOverloads.Concat(baseTypeSymbol.GetMembers(symbol.Name).OfType()); + baseTypeSymbol = baseTypeSymbol.BaseType; } - return MethodOverloads; + return methodOverloads; } private int InvocationScore(IMethodSymbol symbol, IEnumerable types) From eff068d19af0fdee8e0eea3159fd2fa630893608 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Mon, 27 Nov 2017 10:42:39 -0800 Subject: [PATCH 04/15] Test for Inaccesible Methods --- .../SignatureHelpFacts.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index 55a0800a3a..49a5eef7cc 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -508,6 +508,35 @@ public void foo() var actual = await GetSignatureHelp(source); Assert.Equal(4, actual.Signatures.Count()); } + + [Fact] + public async Task SignatureHelpForOverloadedInaccesibleMethods() + { + const string source = +@"public class MyBase +{ + private void MyMethod(int a) { } +} + +public class Class1 : MyBase +{ + public void MyMethod(int a, int b, int c) { } + protected void MyMethod(int a, int b, int c, int d) { } +} + +public class Class2 +{ + public void foo() + { + Class1 c1 = new Class1(); + c1.MyMethod($$); + } + + }"; + var actual = await GetSignatureHelp(source); + Assert.Equal(2, actual.Signatures.Count()); + } + [Fact] public async Task SkipReceiverOfExtensionMethods() { From cf8f7908b421dde1e72b8f33fd0bbedcfa95f3c0 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Mon, 27 Nov 2017 10:58:48 -0800 Subject: [PATCH 05/15] Using GetMemberGroup --- .../Signatures/SignatureHelpService.cs | 34 ++----------------- .../SignatureHelpFacts.cs | 2 +- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index e823de34f9..073949542c 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -2,6 +2,7 @@ using System.Composition; using System.Linq; using System.Threading.Tasks; +using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; @@ -59,7 +60,7 @@ public async Task Handle(SignatureHelpRequest request) foreach (var invocation in invocations) { var types = invocation.ArgumentTypes; - foreach (var methodOverload in GetMethodOverloads(invocation.SemanticModel, invocation.Receiver)) + foreach (var methodOverload in invocation.SemanticModel.GetMemberGroup(invocation.Receiver).OfType()) { var signature = BuildSignature(methodOverload); signaturesSet.Add(signature); @@ -115,35 +116,6 @@ private async Task GetInvocation(Document document, Request r return null; } - private IEnumerable GetMethodOverloads(SemanticModel semanticModel, SyntaxNode node) - { - ISymbol symbol = null; - var symbolInfo = semanticModel.GetSymbolInfo(node); - if (symbolInfo.Symbol != null) - { - symbol = symbolInfo.Symbol; - } - else if (!symbolInfo.CandidateSymbols.IsEmpty) - { - symbol = symbolInfo.CandidateSymbols.First(); - } - - if (symbol == null || symbol.ContainingType == null) - { - return new IMethodSymbol[] { }; - } - - var methodOverloads = symbol.ContainingType.GetMembers(symbol.Name).OfType(); - var baseTypeSymbol = symbol.ContainingType.BaseType; - while(baseTypeSymbol != null && baseTypeSymbol.ContainingNamespace.Name != "System") - { - methodOverloads = methodOverloads.Concat(baseTypeSymbol.GetMembers(symbol.Name).OfType()); - baseTypeSymbol = baseTypeSymbol.BaseType; - } - - return methodOverloads; - } - private int InvocationScore(IMethodSymbol symbol, IEnumerable types) { var parameters = GetParameters(symbol); @@ -170,7 +142,7 @@ private int InvocationScore(IMethodSymbol symbol, IEnumerable types) } } - return score; + return score; } private static SignatureHelpItem BuildSignature(IMethodSymbol symbol) diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index 49a5eef7cc..b60c80e059 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -534,7 +534,7 @@ public void foo() }"; var actual = await GetSignatureHelp(source); - Assert.Equal(2, actual.Signatures.Count()); + Assert.Single(actual.Signatures); } [Fact] From 6362fdab1dc5e5fa1ba8b415355a27468dbc69f1 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Mon, 27 Nov 2017 11:01:39 -0800 Subject: [PATCH 06/15] Unnecessary using removed --- .../Services/Signatures/SignatureHelpService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index 073949542c..942f2aeebb 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -2,7 +2,6 @@ using System.Composition; using System.Linq; using System.Threading.Tasks; -using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; From 997d104dec9c6aed5d95740123ad139a7c8a9030 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Mon, 27 Nov 2017 14:15:51 -0800 Subject: [PATCH 07/15] Test for Overloaded Extension Methods --- .../SignatureHelpFacts.cs | 62 ++++++++++++++++++- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index b60c80e059..49fa3c259a 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -481,7 +481,7 @@ public Program(Program p, int n) } [Fact] - public async Task SignatureHelpForOverloadedMethodsInheritance() + public async Task SignatureHelpForInheritedMethods() { const string source = @"public class MyBase @@ -510,7 +510,7 @@ public void foo() } [Fact] - public async Task SignatureHelpForOverloadedInaccesibleMethods() + public async Task SignatureHelpForInheritedInaccesibleMethods() { const string source = @"public class MyBase @@ -537,6 +537,64 @@ public void foo() Assert.Single(actual.Signatures); } + [Fact] + public async Task SignatureHelpForOverloadedExtensionMethods1() + { + const string source = +@"public static class ExtensionMethods +{ + public static void MyMethod(this string value, int number) + { + } +} + +class Program +{ + public static void MyMethod(string a, int b) + { + } + public static void Main() + { + string value = ""Hello""; + value.MyMethod($$); + } +}"; + var actual = await GetSignatureHelp(source); + Assert.Single(actual.Signatures); + + var signature = actual.Signatures.ElementAt(0); + Assert.Equal("void string.MyMethod(int number)",signature.Label); + } + + [Fact] + public async Task SignatureHelpForOverloadedExtensionMethods2() + { + const string source = +@"public static class ExtensionMethods +{ + public static void MyMethod(this string value, int number) + { + } +} + +class Program +{ + public static void MyMethod(string a, int b) + { + } + public static void Main() + { + string value = ""Hello""; + MyMethod($$); + } +}"; + var actual = await GetSignatureHelp(source); + Assert.Single(actual.Signatures); + + var signature = actual.Signatures.ElementAt(0); + Assert.Equal("void Program.MyMethod(string a, int b)", signature.Label); + } + [Fact] public async Task SkipReceiverOfExtensionMethods() { From 41d4d2c8418663c008b76696b346eb9628326c99 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Mon, 27 Nov 2017 17:27:32 -0800 Subject: [PATCH 08/15] Changes for handling Extension Methods --- .../Signatures/SignatureHelpService.cs | 16 ++------- .../SignatureHelpFacts.cs | 33 ++++++++++++------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index 942f2aeebb..73b1561f57 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -117,7 +117,7 @@ private async Task GetInvocation(Document document, Request r private int InvocationScore(IMethodSymbol symbol, IEnumerable types) { - var parameters = GetParameters(symbol); + var parameters = symbol.Parameters; if (parameters.Count() < types.Count()) { return int.MinValue; @@ -151,7 +151,7 @@ private static SignatureHelpItem BuildSignature(IMethodSymbol symbol) signature.Name = symbol.MethodKind == MethodKind.Constructor ? symbol.ContainingType.Name : symbol.Name; signature.Label = symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); - signature.Parameters = GetParameters(symbol).Select(parameter => + signature.Parameters = symbol.Parameters.Select(parameter => { return new SignatureHelpParameter() { @@ -163,17 +163,5 @@ private static SignatureHelpItem BuildSignature(IMethodSymbol symbol) return signature; } - - private static IEnumerable GetParameters(IMethodSymbol methodSymbol) - { - if (!methodSymbol.IsExtensionMethod) - { - return methodSymbol.Parameters; - } - else - { - return methodSymbol.Parameters.RemoveAt(0); - } - } } } diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index 49fa3c259a..f293b60f87 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -564,6 +564,8 @@ public static void Main() var signature = actual.Signatures.ElementAt(0); Assert.Equal("void string.MyMethod(int number)",signature.Label); + Assert.Single(signature.Parameters); + Assert.Equal("number", signature.Parameters.ElementAt(0).Name); } [Fact] @@ -599,27 +601,34 @@ public static void Main() public async Task SkipReceiverOfExtensionMethods() { const string source = -@"class Program +@"public class Program1 { - public static void Main() - { - new Program().B($$); - } - public Program() + public Program1() { } +} + +public static class ExtensionClass{ + public static bool B(this Program1 p, int n) { + return p.Foo() > n; } - public bool B(this Program p, int n) +} + +public class ProgramClass +{ + public static void Main() { - return p.Foo() > n; + new Program1().B($$); } }"; - var actual = await GetSignatureHelp(source); Assert.Single(actual.Signatures); - Assert.Single(actual.Signatures.ElementAt(actual.ActiveSignature).Parameters); - Assert.Equal("n", actual.Signatures.ElementAt(actual.ActiveSignature).Parameters.ElementAt(0).Name); - } + var signature = actual.Signatures.ElementAt(0); + Assert.Single(signature.Parameters); + Assert.Equal("n", signature.Parameters.ElementAt(0).Name); + Assert.Equal("int n", signature.Parameters.ElementAt(0).Label); + } + private async Task GetSignatureHelp(string source) { var testFile = new TestFile("dummy.cs", source); From 2c0bc6fb9100714491c842e2ce8f9e26fee96b57 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Mon, 27 Nov 2017 18:59:15 -0800 Subject: [PATCH 09/15] Added test for Access Modifiers --- .../SignatureHelpFacts.cs | 153 ++++++++++++++++-- 1 file changed, 143 insertions(+), 10 deletions(-) diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index f293b60f87..6b90a26dea 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -153,7 +153,7 @@ private int Foo(int one, int two, int three) } [Fact] - public async Task SignatureHelpforAttributeCtorSingleParam() + public async Task AttributeCtorSingleParam() { const string source = @"using System; @@ -180,7 +180,7 @@ public MyTestAttribute(int value) } [Fact] - public async Task SignatureHelpforAttributeCtorTestParameterLabels() + public async Task AttributeCtorTestParameterLabels() { const string source = @"using System; @@ -210,7 +210,7 @@ public MyTestAttribute(int value1,double value2) } [Fact] - public async Task SignatureHelpforAttributeCtorActiveParamBasedOnComma() + public async Task AttributeCtorActiveParamBasedOnComma() { const string source = @"using System; @@ -233,7 +233,7 @@ public MyTestAttribute(int value1,double value2) } [Fact] - public async Task SignatureHelpforAttributeCtorNoParam() + public async Task AttributeCtorNoParam() { const string source = @"using System; @@ -429,7 +429,7 @@ private int Foo(string m, int n) } [Fact] - public async Task SignatureHelpForCtor() + public async Task TestForConstructorHelp() { const string source = @"class Program @@ -454,7 +454,7 @@ public Program(Program p) } [Fact] - public async Task SignatureHelpForCtorWithOverloads() + public async Task TestForCtorWithOverloads() { const string source = @"class Program @@ -481,7 +481,7 @@ public Program(Program p, int n) } [Fact] - public async Task SignatureHelpForInheritedMethods() + public async Task TestForInheritedMethods() { const string source = @"public class MyBase @@ -510,7 +510,7 @@ public void foo() } [Fact] - public async Task SignatureHelpForInheritedInaccesibleMethods() + public async Task InheritedInaccesibleMethods() { const string source = @"public class MyBase @@ -538,7 +538,140 @@ public void foo() } [Fact] - public async Task SignatureHelpForOverloadedExtensionMethods1() + public async Task InheritedProtectedMethod() + { + const string source = +@"class A +{ + protected void M1() { } +} + +class B : A +{ + void M1(int a) + { + M1($$) + } +}"; + var actual = await GetSignatureHelp(source); + Assert.Equal(2,actual.Signatures.Count()); + } + + [Fact] + public async Task InheritedProtectedMethodWithThis() + { + const string source = +@"class A +{ + protected void M1() { } +} + +class B : A +{ + void M1(int a) + { + this.M1($$) + } +}"; + var actual = await GetSignatureHelp(source); + Assert.Equal(2, actual.Signatures.Count()); + } + + [Fact] + public async Task InheritedProtectedMethodWithBase() + { + const string source = +@"class A +{ + protected void M1() { } +} + +class B : A +{ + void M1(int a) + { + base.M1($$); + } +}"; + var actual = await GetSignatureHelp(source); + Assert.Single(actual.Signatures); + Assert.Empty(actual.Signatures.ElementAt(0).Parameters); + } + + [Fact] + public async Task StaticContextMethod1() + { + const string source = +@"class A +{ + protected static void M1(int a) { } + public void M1(double b) { } +} + +class B : A +{ + static void M1() + { + A.M1($$); + } + public void M1(string c) { } +}"; + var actual = await GetSignatureHelp(source); + Assert.Single(actual.Signatures); + + var signature = actual.Signatures.ElementAt(0); + Assert.Single(signature.Parameters); + Assert.Equal("int a", signature.Parameters.ElementAt(0).Label); + } + + [Fact] + public async Task StaticContextMethod2() + { + const string source = +@"class A +{ + protected static void M1(int a) { } + public void M1(int a,int b) { } +} + +class B : A +{ + static void M1(int a,int b,int c) + { + B.M1($$) + } + public void M1(int a,int b,int c,int d) { } +}"; + var actual = await GetSignatureHelp(source); + Assert.Equal(2, actual.Signatures.Count()); + var signatures = actual.Signatures.OrderBy(sig => sig.Parameters.Count()); + Assert.Single(signatures.ElementAt(0).Parameters); + Assert.Equal(3,signatures.ElementAt(1).Parameters.Count()); + } + + [Fact] + public async Task InstanceContextMethod() + { + const string source = +@"class A +{ + protected static void M1(int a) { } + public void M1(int a, int b) { } +} + +class B : A +{ + static void M1(int a,int b,int c) + { + M1($$) + } + public void M1(int a,int b,int c,int d) { } +}"; + var actual = await GetSignatureHelp(source); + Assert.Equal(4, actual.Signatures.Count()); + } + [Fact] + public async Task OverloadedExtensionMethods1() { const string source = @"public static class ExtensionMethods @@ -569,7 +702,7 @@ public static void Main() } [Fact] - public async Task SignatureHelpForOverloadedExtensionMethods2() + public async Task OverloadedExtensionMethods2() { const string source = @"public static class ExtensionMethods From 9cb58b43a3fc98dea10fedc83e5dc1b217759403 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Tue, 28 Nov 2017 14:37:50 -0800 Subject: [PATCH 10/15] Changes for static invocations --- .../OmniSharp.Roslyn.CSharp.csproj | 8 + .../Signatures/CheckStaticInvocation.cs | 175 ++++++++++++++++++ .../Services/Signatures/InvocationContext.cs | 7 +- .../Signatures/SignatureHelpService.cs | 30 ++- .../SignatureHelpFacts.cs | 4 +- 5 files changed, 215 insertions(+), 9 deletions(-) create mode 100644 src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs diff --git a/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj b/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj index 85f94fb919..5e8555efba 100644 --- a/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj +++ b/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj @@ -5,6 +5,14 @@ AnyCPU + + 7.1 + + + + 7.1 + + diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs new file mode 100644 index 0000000000..6d5d2ac5ee --- /dev/null +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs @@ -0,0 +1,175 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System; +using System.Collections.Generic; +using System.Linq; +namespace OmniSharp.Roslyn.CSharp.Services.Signatures +{ + static internal class CheckForStatic + { + public static bool IsInStaticContext(this SyntaxNode node) + { + // this/base calls are always static. + if (node.FirstAncestorOrSelf() != null) + { + return true; + } + + var memberDeclaration = node.FirstAncestorOrSelf(); + if (memberDeclaration == null) + { + return false; + } + + switch (memberDeclaration.Kind()) + { + case SyntaxKind.MethodDeclaration: + case SyntaxKind.ConstructorDeclaration: + case SyntaxKind.EventDeclaration: + case SyntaxKind.IndexerDeclaration: + return GetModifiers(memberDeclaration).Any(SyntaxKind.StaticKeyword); + + case SyntaxKind.PropertyDeclaration: + return GetModifiers(memberDeclaration).Any(SyntaxKind.StaticKeyword) || + node.IsFoundUnder((PropertyDeclarationSyntax p) => p.Initializer); + + case SyntaxKind.FieldDeclaration: + case SyntaxKind.EventFieldDeclaration: + // Inside a field one can only access static members of a type (unless it's top-level). + return !memberDeclaration.Parent.IsKind(SyntaxKind.CompilationUnit); + + case SyntaxKind.DestructorDeclaration: + return false; + } + + // Global statements are not a static context. + if (node.FirstAncestorOrSelf() != null) + { + return false; + } + + // any other location is considered static + return true; + } + public static SyntaxTokenList GetModifiers(SyntaxNode member) + { + if (member != null) + { + switch (member.Kind()) + { + case SyntaxKind.EnumDeclaration: + return ((EnumDeclarationSyntax)member).Modifiers; + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.StructDeclaration: + return ((TypeDeclarationSyntax)member).Modifiers; + case SyntaxKind.DelegateDeclaration: + return ((DelegateDeclarationSyntax)member).Modifiers; + case SyntaxKind.FieldDeclaration: + return ((FieldDeclarationSyntax)member).Modifiers; + case SyntaxKind.EventFieldDeclaration: + return ((EventFieldDeclarationSyntax)member).Modifiers; + case SyntaxKind.ConstructorDeclaration: + return ((ConstructorDeclarationSyntax)member).Modifiers; + case SyntaxKind.DestructorDeclaration: + return ((DestructorDeclarationSyntax)member).Modifiers; + case SyntaxKind.PropertyDeclaration: + return ((PropertyDeclarationSyntax)member).Modifiers; + case SyntaxKind.EventDeclaration: + return ((EventDeclarationSyntax)member).Modifiers; + case SyntaxKind.IndexerDeclaration: + return ((IndexerDeclarationSyntax)member).Modifiers; + case SyntaxKind.OperatorDeclaration: + return ((OperatorDeclarationSyntax)member).Modifiers; + case SyntaxKind.ConversionOperatorDeclaration: + return ((ConversionOperatorDeclarationSyntax)member).Modifiers; + case SyntaxKind.MethodDeclaration: + return ((MethodDeclarationSyntax)member).Modifiers; + case SyntaxKind.GetAccessorDeclaration: + case SyntaxKind.SetAccessorDeclaration: + case SyntaxKind.AddAccessorDeclaration: + case SyntaxKind.RemoveAccessorDeclaration: + return ((AccessorDeclarationSyntax)member).Modifiers; + } + } + + return default; + } + public static bool IsFoundUnder(this SyntaxNode node, Func childGetter) + where TParent : SyntaxNode + { + var ancestor = node.GetAncestor(); + if (ancestor == null) + { + return false; + } + + var child = childGetter(ancestor); + + // See if node passes through child on the way up to ancestor. + return node.GetAncestorsOrThis().Contains(child); + } + public static TNode GetAncestor(this SyntaxNode node) + where TNode : SyntaxNode + { + var current = node.Parent; + while (current != null) + { + if (current is TNode tNode) + { + return tNode; + } + + current = current.GetParent(); + } + + return null; + } + private static SyntaxNode GetParent(this SyntaxNode node) + { + return node is IStructuredTriviaSyntax trivia ? trivia.ParentTrivia.Token.Parent : node.Parent; + } + + public static TNode FirstAncestorOrSelfUntil(this SyntaxNode node, Func predicate) + where TNode : SyntaxNode + { + for (var current = node; current != null; current = current.GetParent()) + { + if (current is TNode tnode) + { + return tnode; + } + + if (predicate(current)) + { + break; + } + } + + return default; + } + + public static TNode GetAncestorOrThis(this SyntaxNode node) + where TNode : SyntaxNode + { + return node?.GetAncestorsOrThis().FirstOrDefault(); + } + + public static IEnumerable GetAncestorsOrThis(this SyntaxNode node) + where TNode : SyntaxNode + { + var current = node; + while (current != null) + { + if (current is TNode tNode) + { + yield return tNode; + } + + current = current.GetParent(); + } + } + } +} + diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs index e06abc6bb5..71ccbe90c9 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs @@ -13,23 +13,26 @@ internal class InvocationContext public SyntaxNode Receiver { get; } public IEnumerable ArgumentTypes { get; } public IEnumerable Separators { get; } + public bool IsStatic { get; } - public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiver, ArgumentListSyntax argList) + public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiver, ArgumentListSyntax argList, bool isStatic) { SemanticModel = semModel; Position = position; Receiver = receiver; ArgumentTypes = argList.Arguments.Select(argument => semModel.GetTypeInfo(argument.Expression)); Separators = argList.Arguments.GetSeparators(); + IsStatic = isStatic; } - public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiver, AttributeArgumentListSyntax argList) + public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiver, AttributeArgumentListSyntax argList, bool isStatic) { SemanticModel = semModel; Position = position; Receiver = receiver; ArgumentTypes = argList.Arguments.Select(argument => semModel.GetTypeInfo(argument.Expression)); Separators = argList.Arguments.GetSeparators(); + IsStatic = isStatic; } } } diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index 73b1561f57..8d4953773b 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; using OmniSharp.Mef; @@ -59,7 +60,25 @@ public async Task Handle(SignatureHelpRequest request) foreach (var invocation in invocations) { var types = invocation.ArgumentTypes; - foreach (var methodOverload in invocation.SemanticModel.GetMemberGroup(invocation.Receiver).OfType()) + ISymbol throughSymbol = null; + ISymbol throughType = null; + var methodGroup = invocation.SemanticModel.GetMemberGroup(invocation.Receiver).OfType(); + if (invocation.Receiver is MemberAccessExpressionSyntax) + { + var throughExpression = ((MemberAccessExpressionSyntax)invocation.Receiver).Expression; + throughSymbol = invocation.SemanticModel.GetSpeculativeSymbolInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsExpression).Symbol; + throughType = invocation.SemanticModel.GetSpeculativeTypeInfo(invocation.Position, throughExpression, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; + var includeInstance = throughSymbol != null && !(throughSymbol is ITypeSymbol); + var includeStatic = (throughSymbol is INamedTypeSymbol) || throughType != null; + methodGroup = methodGroup.Where(m => (m.IsStatic && includeStatic) || (!m.IsStatic && includeInstance)); + } + + else if (invocation.Receiver is SimpleNameSyntax && invocation.IsStatic) + { + methodGroup = methodGroup.Where(m => m.IsStatic); + } + + foreach (var methodOverload in methodGroup) { var signature = BuildSignature(methodOverload); signaturesSet.Add(signature); @@ -94,19 +113,19 @@ private async Task GetInvocation(Document document, Request r if (node is InvocationExpressionSyntax invocation && invocation.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(); - return new InvocationContext(semanticModel, position, invocation.Expression, invocation.ArgumentList); + return new InvocationContext(semanticModel, position, invocation.Expression, invocation.ArgumentList, invocation.IsInStaticContext()); } if (node is ObjectCreationExpressionSyntax objectCreation && objectCreation.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(); - return new InvocationContext(semanticModel, position, objectCreation, objectCreation.ArgumentList); + return new InvocationContext(semanticModel, position, objectCreation, objectCreation.ArgumentList,objectCreation.IsInStaticContext()); } if (node is AttributeSyntax attributeSyntax && attributeSyntax.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(); - return new InvocationContext(semanticModel, position, attributeSyntax, attributeSyntax.ArgumentList); + return new InvocationContext(semanticModel, position, attributeSyntax, attributeSyntax.ArgumentList, attributeSyntax.IsInStaticContext()); } node = node.Parent; @@ -141,7 +160,7 @@ private int InvocationScore(IMethodSymbol symbol, IEnumerable types) } } - return score; + return score; } private static SignatureHelpItem BuildSignature(IMethodSymbol symbol) @@ -163,5 +182,6 @@ private static SignatureHelpItem BuildSignature(IMethodSymbol symbol) return signature; } + } } diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index 6b90a26dea..0f9661b2d2 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -661,11 +661,11 @@ public void M1(int a, int b) { } class B : A { - static void M1(int a,int b,int c) + void M1(int a,int b,int c) { M1($$) } - public void M1(int a,int b,int c,int d) { } + static void M1(int a,int b,int c,int d) { } }"; var actual = await GetSignatureHelp(source); Assert.Equal(4, actual.Signatures.Count()); From 07cee28f2755c122f378efb8a15f41719e5004af Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 29 Nov 2017 13:12:32 -0800 Subject: [PATCH 11/15] Removed unnecessary Blank Lines and Renamed IsInStaticContext --- .../Services/Signatures/CheckStaticInvocation.cs | 15 ++++++++++----- .../Services/Signatures/InvocationContext.cs | 6 +++--- .../Services/Signatures/SignatureHelpService.cs | 5 ++--- .../SignatureHelpFacts.cs | 4 ++++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs index 6d5d2ac5ee..cb5b676500 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs @@ -1,12 +1,13 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System; +using System; using System.Collections.Generic; using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + namespace OmniSharp.Roslyn.CSharp.Services.Signatures { - static internal class CheckForStatic + internal static class CheckForStaticExtension { public static bool IsInStaticContext(this SyntaxNode node) { @@ -52,6 +53,7 @@ public static bool IsInStaticContext(this SyntaxNode node) // any other location is considered static return true; } + public static SyntaxTokenList GetModifiers(SyntaxNode member) { if (member != null) @@ -96,6 +98,7 @@ public static SyntaxTokenList GetModifiers(SyntaxNode member) return default; } + public static bool IsFoundUnder(this SyntaxNode node, Func childGetter) where TParent : SyntaxNode { @@ -110,6 +113,7 @@ public static bool IsFoundUnder(this SyntaxNode node, Func().Contains(child); } + public static TNode GetAncestor(this SyntaxNode node) where TNode : SyntaxNode { @@ -126,6 +130,7 @@ public static TNode GetAncestor(this SyntaxNode node) return null; } + private static SyntaxNode GetParent(this SyntaxNode node) { return node is IStructuredTriviaSyntax trivia ? trivia.ParentTrivia.Token.Parent : node.Parent; diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs index 71ccbe90c9..fd2d46e63e 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/InvocationContext.cs @@ -13,7 +13,7 @@ internal class InvocationContext public SyntaxNode Receiver { get; } public IEnumerable ArgumentTypes { get; } public IEnumerable Separators { get; } - public bool IsStatic { get; } + public bool IsInStaticContext { get; } public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiver, ArgumentListSyntax argList, bool isStatic) { @@ -22,7 +22,7 @@ public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiv Receiver = receiver; ArgumentTypes = argList.Arguments.Select(argument => semModel.GetTypeInfo(argument.Expression)); Separators = argList.Arguments.GetSeparators(); - IsStatic = isStatic; + IsInStaticContext = isStatic; } public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiver, AttributeArgumentListSyntax argList, bool isStatic) @@ -32,7 +32,7 @@ public InvocationContext(SemanticModel semModel, int position, SyntaxNode receiv Receiver = receiver; ArgumentTypes = argList.Arguments.Select(argument => semModel.GetTypeInfo(argument.Expression)); Separators = argList.Arguments.GetSeparators(); - IsStatic = isStatic; + IsInStaticContext = isStatic; } } } diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs index 8d4953773b..8687fd1fb7 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/SignatureHelpService.cs @@ -72,8 +72,7 @@ public async Task Handle(SignatureHelpRequest request) var includeStatic = (throughSymbol is INamedTypeSymbol) || throughType != null; methodGroup = methodGroup.Where(m => (m.IsStatic && includeStatic) || (!m.IsStatic && includeInstance)); } - - else if (invocation.Receiver is SimpleNameSyntax && invocation.IsStatic) + else if (invocation.Receiver is SimpleNameSyntax && invocation.IsInStaticContext) { methodGroup = methodGroup.Where(m => m.IsStatic); } @@ -119,7 +118,7 @@ private async Task GetInvocation(Document document, Request r if (node is ObjectCreationExpressionSyntax objectCreation && objectCreation.ArgumentList.Span.Contains(position)) { var semanticModel = await document.GetSemanticModelAsync(); - return new InvocationContext(semanticModel, position, objectCreation, objectCreation.ArgumentList,objectCreation.IsInStaticContext()); + return new InvocationContext(semanticModel, position, objectCreation, objectCreation.ArgumentList, objectCreation.IsInStaticContext()); } if (node is AttributeSyntax attributeSyntax && attributeSyntax.ArgumentList.Span.Contains(position)) diff --git a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs index 0f9661b2d2..b670e41dc4 100644 --- a/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs +++ b/tests/OmniSharp.Roslyn.CSharp.Tests/SignatureHelpFacts.cs @@ -535,6 +535,9 @@ public void foo() }"; var actual = await GetSignatureHelp(source); Assert.Single(actual.Signatures); + + var signature = actual.Signatures.ElementAt(0); + Assert.Equal(3, signature.Parameters.Count()); } [Fact] @@ -670,6 +673,7 @@ static void M1(int a,int b,int c,int d) { } var actual = await GetSignatureHelp(source); Assert.Equal(4, actual.Signatures.Count()); } + [Fact] public async Task OverloadedExtensionMethods1() { From 29b3803b070ae7b65309e7970dd0d7d67a1b225d Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 29 Nov 2017 13:38:47 -0800 Subject: [PATCH 12/15] Added copyright and todo --- .../Services/Signatures/CheckStaticInvocation.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs index cb5b676500..288ea18930 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs @@ -1,4 +1,6 @@ -using System; +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; using System.Collections.Generic; using System.Linq; using Microsoft.CodeAnalysis; @@ -7,6 +9,7 @@ namespace OmniSharp.Roslyn.CSharp.Services.Signatures { + //TO DO: Reomove this class once a public API for Signature Help from Roslyn is available internal static class CheckForStaticExtension { public static bool IsInStaticContext(this SyntaxNode node) From cda2c2853cdd5156d0332ed37e6b774cbaa12e5a Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 29 Nov 2017 14:22:15 -0800 Subject: [PATCH 13/15] Changed Language Version --- build/Settings.props | 1 + .../OmniSharp.Roslyn.CSharp.csproj | 8 -------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/build/Settings.props b/build/Settings.props index 225b86c07d..be3acd24d9 100644 --- a/build/Settings.props +++ b/build/Settings.props @@ -2,6 +2,7 @@ + 7.1 true Debug false diff --git a/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj b/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj index 5e8555efba..85f94fb919 100644 --- a/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj +++ b/src/OmniSharp.Roslyn.CSharp/OmniSharp.Roslyn.CSharp.csproj @@ -5,14 +5,6 @@ AnyCPU - - 7.1 - - - - 7.1 - - From a13a6b0cffea2f58805dc6d30692116f5279f639 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 29 Nov 2017 16:19:40 -0800 Subject: [PATCH 14/15] Added Attribution --- .../Services/Signatures/CheckStaticInvocation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs index 288ea18930..2022358d58 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs @@ -1,5 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - +// Adapted from https://github.com/dotnet/roslyn/blob/master/src/Workspaces/CSharp/Portable/Extensions/SyntaxNodeExtensions.cs using System; using System.Collections.Generic; using System.Linq; From 17f52cf7361aaea3c2bc4d38a636b341dc69daf1 Mon Sep 17 00:00:00 2001 From: Akshita Agarwal Date: Wed, 6 Dec 2017 16:06:52 -0800 Subject: [PATCH 15/15] Corrected spelling --- .../Services/Signatures/CheckStaticInvocation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs index 2022358d58..d96a26daf6 100644 --- a/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs +++ b/src/OmniSharp.Roslyn.CSharp/Services/Signatures/CheckStaticInvocation.cs @@ -9,7 +9,7 @@ namespace OmniSharp.Roslyn.CSharp.Services.Signatures { - //TO DO: Reomove this class once a public API for Signature Help from Roslyn is available + //TO DO: Remove this class once a public API for Signature Help from Roslyn is available internal static class CheckForStaticExtension { public static bool IsInStaticContext(this SyntaxNode node)