提交 f9fed067 编写于 作者: J Jason Malinowski

Update override completion for nullable reference support

- Ensure we show the ? in all the appropriate places
- Ensure we don't spit ? if we shouldn't
- Ensure we drop ? for the special case of the ToString return
上级 4c13e377
...@@ -693,6 +693,23 @@ public class SomeClass : Base ...@@ -693,6 +693,23 @@ public class SomeClass : Base
await VerifyItemExistsAsync(markup, "Goo(Exception e)"); await VerifyItemExistsAsync(markup, "Goo(Exception e)");
} }
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NullableAnnotationsIncluded()
{
var markup = @"#nullable enable
public abstract class Base
{
public abstract void Goo(string? s);
}
public class SomeClass : Base
{
override $$
}";
await VerifyItemExistsAsync(markup, "Goo(string? s)");
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task EscapedMethodNameInIntelliSenseList() public async Task EscapedMethodNameInIntelliSenseList()
{ {
...@@ -1631,6 +1648,121 @@ public override void goo<T>() ...@@ -1631,6 +1648,121 @@ public override void goo<T>()
await VerifyCustomCommitProviderAsync(markupBeforeCommit, "goo<T>()", expectedCodeAfterCommit); await VerifyCustomCommitProviderAsync(markupBeforeCommit, "goo<T>()", expectedCodeAfterCommit);
} }
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitMethodWithNullableAttributes()
{
var markupBeforeCommit = @"
#nullable enable
class C
{
public virtual string? Goo(string? s) { }
}
class D : C
{
override $$
}";
var expectedCodeAfterCommit = @"
#nullable enable
class C
{
public virtual string? Goo(string? s) { }
}
class D : C
{
public override string? Goo(string? s)
{
return base.Goo(s);$$
}
}";
await VerifyCustomCommitProviderAsync(markupBeforeCommit, "Goo(string? s)", expectedCodeAfterCommit);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitMethodInNullableDisableContext()
{
var markupBeforeCommit = @"
#nullable enable
class C
{
public virtual string? Goo(string? s) { }
}
#nullable disable
class D : C
{
override $$
}";
var expectedCodeAfterCommit = @"
#nullable enable
class C
{
public virtual string? Goo(string? s) { }
}
#nullable disable
class D : C
{
public override string Goo(string s)
{
return base.Goo(s);$$
}
}";
await VerifyCustomCommitProviderAsync(markupBeforeCommit, "Goo(string? s)", expectedCodeAfterCommit);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitToStringIsExplicitlyNonNullReturning()
{
var markupBeforeCommit = @"
#nullable enable
namespace System
{
public class Object
{
public virtual string? ToString() { }
}
}
class D : System.Object
{
override $$
}";
var expectedCodeAfterCommit = @"
#nullable enable
namespace System
{
public class Object
{
public virtual string? ToString() { }
}
}
class D : System.Object
{
public override string ToString()
{
return base.ToString();$$
}
}";
await VerifyCustomCommitProviderAsync(markupBeforeCommit, "ToString()", expectedCodeAfterCommit);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)] [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitInsertIndexer() public async Task CommitInsertIndexer()
{ {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.LanguageServices; using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
...@@ -24,7 +25,8 @@ private partial class ItemGetter ...@@ -24,7 +25,8 @@ private partial class ItemGetter
SymbolDisplayParameterOptions.IncludeExtensionThis | SymbolDisplayParameterOptions.IncludeExtensionThis |
SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeType |
SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeName |
SymbolDisplayParameterOptions.IncludeParamsRefOut); SymbolDisplayParameterOptions.IncludeParamsRefOut)
.AddMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier);
private readonly Document _document; private readonly Document _document;
private readonly SourceText _text; private readonly SourceText _text;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeGeneration;
using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
...@@ -37,6 +38,20 @@ public override async Task ProvideCompletionsAsync(CompletionContext context) ...@@ -37,6 +38,20 @@ public override async Task ProvideCompletionsAsync(CompletionContext context)
protected override Task<ISymbol> GenerateMemberAsync(ISymbol newOverriddenMember, INamedTypeSymbol newContainingType, Document newDocument, CompletionItem completionItem, CancellationToken cancellationToken) protected override Task<ISymbol> GenerateMemberAsync(ISymbol newOverriddenMember, INamedTypeSymbol newContainingType, Document newDocument, CompletionItem completionItem, CancellationToken cancellationToken)
{ {
// Special case: if you are overriding object.ToString(), we will make the return value as non-nullable. The return was made nullable because
// are implementations out there that will return null, but that's not something we really want new implementations doing. We may need to consider
// expanding this behavior to other methods in the future; if that is the case then we would want there to be an attribute on the return type
// rather than updating this list, but for now there is no such attribute until we find more cases for it. See
// https://github.com/dotnet/roslyn/issues/30317 for some additional conversation about this design decision.
//
// We don't check if methodSymbol.ContainingType is object, in case you're overriding something that is itself an override
if (newOverriddenMember is IMethodSymbol methodSymbol &&
methodSymbol.Name == "ToString" &&
methodSymbol.Parameters.Length == 0)
{
newOverriddenMember = CodeGenerationSymbolFactory.CreateMethodSymbol(methodSymbol, returnType: methodSymbol.ReturnType.WithNullability(NullableAnnotation.NotAnnotated));
}
// Figure out what to insert, and do it. Throw if we've somehow managed to get this far and can't. // Figure out what to insert, and do it. Throw if we've somehow managed to get this far and can't.
var syntaxFactory = newDocument.GetLanguageService<SyntaxGenerator>(); var syntaxFactory = newDocument.GetLanguageService<SyntaxGenerator>();
......
...@@ -427,14 +427,15 @@ public static INamespaceSymbol CreateNamespaceSymbol(string name, IList<ISymbol> ...@@ -427,14 +427,15 @@ public static INamespaceSymbol CreateNamespaceSymbol(string name, IList<ISymbol>
string name = null, string name = null,
ImmutableArray<IParameterSymbol>? parameters = default, ImmutableArray<IParameterSymbol>? parameters = default,
ImmutableArray<SyntaxNode> statements = default, ImmutableArray<SyntaxNode> statements = default,
INamedTypeSymbol containingType = null) INamedTypeSymbol containingType = null,
ITypeSymbol returnType = null)
{ {
return CreateMethodSymbol( return CreateMethodSymbol(
containingType, containingType,
attributes, attributes,
accessibility ?? method.DeclaredAccessibility, accessibility ?? method.DeclaredAccessibility,
modifiers ?? method.GetSymbolModifiers(), modifiers ?? method.GetSymbolModifiers(),
method.GetReturnTypeWithAnnotatedNullability(), returnType ?? method.GetReturnTypeWithAnnotatedNullability(),
method.RefKind, method.RefKind,
explicitInterfaceImplementations, explicitInterfaceImplementations,
name ?? method.Name, name ?? method.Name,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册