提交 babe05fc 编写于 作者: R Ravi Chande

Do not add `Using System` in overrides completion

Adds an annotation, `DoNotAddImportsAnnotation` that prevents AbstractImportsAdder from adding imports.
Fixes #8257
上级 2b7bd605
......@@ -1171,7 +1171,9 @@ protected internal override void foo()
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitAbstractMethodThrows()
{
var markupBeforeCommit = @"abstract class c
var markupBeforeCommit = @"using System;
abstract class c
{
public abstract void foo();
}
......@@ -1599,9 +1601,7 @@ class d : MyIndexer<T>
override $$
}";
var expectedCodeAfterCommit = @"using System;
public class MyIndexer<T>
var expectedCodeAfterCommit = @"public class MyIndexer<T>
{
private T[] arr = new T[100];
public abstract T this[int i] { get; set; }
......@@ -1613,12 +1613,12 @@ class d : MyIndexer<T>
{
get
{
throw new NotImplementedException();$$
throw new System.NotImplementedException();$$
}
set
{
throw new NotImplementedException();
throw new System.NotImplementedException();
}
}
}";
......@@ -1729,7 +1729,9 @@ public override ArgumentException foo(Exception e)
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitEscapedMethodName()
{
var markupBeforeCommit = @"public abstract class Base
var markupBeforeCommit = @"using System;
public abstract class Base
{
public abstract void @class();
}
......@@ -1829,7 +1831,9 @@ public override void foo(int @class)
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitRefParameter()
{
var markupBeforeCommit = @"public abstract class Base
var markupBeforeCommit = @"using System;
public abstract class Base
{
public abstract void foo(int x, ref string y);
}
......@@ -1860,7 +1864,9 @@ public override void foo(int x, ref string y)
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CommitOutParameter()
{
var markupBeforeCommit = @"public abstract class Base
var markupBeforeCommit = @"using System;
public abstract class Base
{
public abstract void foo(int x, out string y);
}
......@@ -2555,5 +2561,72 @@ static void Main(string[] args)
Assert.Equal(change.Span, TextSpan.FromBounds(136, 145));
}
}
[WorkItem(8257, "https://github.com/dotnet/roslyn/issues/8257")]
[WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task NotImplementedQualifiedWhenSystemUsingNotPresent_Property()
{
var markupBeforeCommit = @"abstract class C
{
public abstract int foo { get; set; };
}
class Program : C
{
override $$
}";
var expectedCodeAfterCommit = @"abstract class C
{
public abstract int foo { get; set; };
}
class Program : C
{
public override int foo
{
get
{
throw new System.NotImplementedException();$$
}
set
{
throw new System.NotImplementedException();
}
}
}";
await VerifyCustomCommitProviderAsync(markupBeforeCommit, "foo", expectedCodeAfterCommit);
}
[WorkItem(8257, "https://github.com/dotnet/roslyn/issues/8257")]
public async Task NotImplementedQualifiedWhenSystemUsingNotPresent_Method()
{
var markupBeforeCommit = @"abstract class C
{
public abstract void foo();
}
class Program : C
{
override $$
}";
var expectedCodeAfterCommit = @"abstract class C
{
public abstract void foo();
}
class Program : C
{
public override void foo()
{
throw new System.NotImplementedException();$$
}
}";
await VerifyCustomCommitProviderAsync(markupBeforeCommit, "foo()", expectedCodeAfterCommit);
}
}
}
\ No newline at end of file
......@@ -844,7 +844,9 @@ End Class</a>
<WpfFact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestCommitAbstractThrows() As Task
Dim markupBeforeCommit = <a>Public MustInherit Class c
Dim markupBeforeCommit = <a>Imports System
Public MustInherit Class c
Public MustOverride Sub foo()
End Class
......@@ -1407,9 +1409,7 @@ Class Derived
Overrides $$
End Class</a>
Dim expectedCode = <a>Imports System
MustInherit Class CBase
Dim expectedCode = <a>MustInherit Class CBase
MustOverride Sub Foo()
End Class
......@@ -1417,7 +1417,7 @@ Class Derived
Inherits CBase
Public Overrides Sub Foo()
Throw New NotImplementedException()$$
Throw New System.NotImplementedException()$$
End Sub
End Class</a>
......
......@@ -49,7 +49,7 @@ internal partial class ImplementInterfaceCodeAction
if (ThroughMember == null)
{
var factory = this.Document.GetLanguageService<SyntaxGenerator>();
return factory.CreateThrowNotImplementStatement(compilation);
return factory.CreateThrowNotImplementedStatement(compilation, addImport: false);
}
else
{
......
......@@ -43,6 +43,11 @@ protected AbstractImportsAdder(Document document)
{
cancellationToken.ThrowIfCancellationRequested();
if (annotatedNode.GetAnnotations(DoNotAddImportsAnnotation.Kind).Any())
{
continue;
}
SyntaxNode namespaceScope = null;
var annotations = annotatedNode.GetAnnotations(SymbolAnnotation.Kind);
foreach (var annotation in annotations)
......
......@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Simplification;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editing
......@@ -1627,6 +1628,19 @@ public SyntaxNode DottedName(string dottedName)
/// </summary>
public abstract SyntaxNode TypeExpression(ITypeSymbol typeSymbol);
/// <summary>
/// Creates an expression that denotes a type.
/// Adds a <see cref="DoNotAddImportsAnnotation"/> which will prevent any
/// imports or usings from being added for the type.
/// </summary>
public SyntaxNode TypeExpression(ITypeSymbol typeSymbol, bool addImport)
{
var expression = TypeExpression(typeSymbol);
return addImport
? expression.WithAdditionalAnnotations(DoNotAddImportsAnnotation.Annotation)
: expression;
}
/// <summary>
/// Creates an expression that denotes a special type name.
/// </summary>
......
......@@ -370,7 +370,6 @@ Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NamespaceDeclaration(string name,
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NamespaceDeclaration(string name, params Microsoft.CodeAnalysis.SyntaxNode[] declarations) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NamespaceImportDeclaration(string name) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.NullLiteralExpression() -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ObjectCreationExpression(Microsoft.CodeAnalysis.ITypeSymbol type, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> arguments) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ObjectCreationExpression(Microsoft.CodeAnalysis.ITypeSymbol type, params Microsoft.CodeAnalysis.SyntaxNode[] arguments) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ObjectCreationExpression(Microsoft.CodeAnalysis.SyntaxNode type, params Microsoft.CodeAnalysis.SyntaxNode[] arguments) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.OperatorDeclaration(Microsoft.CodeAnalysis.IMethodSymbol method, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> statements = null) -> Microsoft.CodeAnalysis.SyntaxNode
......
......@@ -22,6 +22,8 @@ Microsoft.CodeAnalysis.DocumentActiveContextChangedEventArgs.OldActiveContextDoc
Microsoft.CodeAnalysis.DocumentActiveContextChangedEventArgs.Solution.get -> Microsoft.CodeAnalysis.Solution
Microsoft.CodeAnalysis.DocumentActiveContextChangedEventArgs.SourceTextContainer.get -> Microsoft.CodeAnalysis.Text.SourceTextContainer
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.AddSwitchSections(Microsoft.CodeAnalysis.SyntaxNode switchStatement, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> switchSections) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ObjectCreationExpression(Microsoft.CodeAnalysis.ITypeSymbol type, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> arguments) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.TypeExpression(Microsoft.CodeAnalysis.ITypeSymbol typeSymbol, bool addImport) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Options.DocumentOptionSet
Microsoft.CodeAnalysis.Options.DocumentOptionSet.GetOption<T>(Microsoft.CodeAnalysis.Options.PerLanguageOption<T> option) -> T
Microsoft.CodeAnalysis.Options.IOption.StorageLocations.get -> System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.Options.OptionStorageLocation>
......@@ -42,6 +44,7 @@ abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.AddEventHandler(Microsof
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.GetSwitchSections(Microsoft.CodeAnalysis.SyntaxNode switchStatement) -> System.Collections.Generic.IReadOnlyList<Microsoft.CodeAnalysis.SyntaxNode>
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.InsertSwitchSections(Microsoft.CodeAnalysis.SyntaxNode switchStatement, int index, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> switchSections) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.RemoveEventHandler(Microsoft.CodeAnalysis.SyntaxNode event, Microsoft.CodeAnalysis.SyntaxNode handler) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ObjectCreationExpression(Microsoft.CodeAnalysis.SyntaxNode namedType, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> arguments) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ThrowExpression(Microsoft.CodeAnalysis.SyntaxNode expression) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.XmlDocumentationProvider.GetSourceStream(System.Threading.CancellationToken cancellationToken) -> System.IO.Stream
const Microsoft.CodeAnalysis.Tags.WellKnownTags.Assembly = "Assembly" -> string
......
......@@ -15,21 +15,21 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static partial class ICodeDefinitionFactoryExtensions
{
public static SyntaxNode CreateThrowNotImplementStatement(
public static SyntaxNode CreateThrowNotImplementedStatement(
this SyntaxGenerator codeDefinitionFactory,
Compilation compilation)
{
return codeDefinitionFactory.ThrowStatement(
codeDefinitionFactory.ObjectCreationExpression(
compilation.NotImplementedExceptionType(),
SpecializedCollections.EmptyList<SyntaxNode>()));
codeDefinitionFactory.ObjectCreationExpression(
codeDefinitionFactory.TypeExpression(compilation.NotImplementedExceptionType(), addImport: false),
SpecializedCollections.EmptyList<SyntaxNode>()));
}
public static IList<SyntaxNode> CreateThrowNotImplementedStatementBlock(
this SyntaxGenerator codeDefinitionFactory,
Compilation compilation)
{
return new[] { CreateThrowNotImplementStatement(codeDefinitionFactory, compilation) };
return new[] { CreateThrowNotImplementedStatement(codeDefinitionFactory, compilation) };
}
public static IList<SyntaxNode> CreateArguments(
......@@ -223,8 +223,10 @@ private static bool TryGetValue(IDictionary<string, ISymbol> dictionary, string
if (overriddenProperty.IsAbstract)
{
var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
getBody = codeFactory.CreateThrowNotImplementStatement(compilation);
setBody = getBody;
var statement = codeFactory.CreateThrowNotImplementedStatement(compilation);
getBody = statement;
setBody = statement;
}
else if (overriddenProperty.IsIndexer() && document.Project.Language == LanguageNames.CSharp)
{
......@@ -361,11 +363,13 @@ private static bool TryGetValue(IDictionary<string, ISymbol> dictionary, string
if (overriddenMethod.IsAbstract)
{
var compilation = await newDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var statement = codeFactory.CreateThrowNotImplementedStatement(compilation);
return CodeGenerationSymbolFactory.CreateMethodSymbol(
overriddenMethod,
accessibility: overriddenMethod.ComputeResultantAccessibility(newContainingType),
modifiers: modifiers,
statements: new[] { codeFactory.CreateThrowNotImplementStatement(compilation) });
statements: new[] { statement });
}
else
{
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Simplification
{
// When applied to a SyntaxNode, prevents AbstractImportsAdder from
// adding imports for this node. Applied alongside SymbolAnnotation
// when a type should be simplified without adding a using for the type.
//
// For example, override completion adds
// void foo() => throw new System.NotImplementedException()
// with a SymbolAnnotation and a DoNotAddImportsAnnotation.
//
// This allows the simplifier to remove the `System.` if
// `using System` is already in the file but prevents the addition
// of `using System` just for the NotImplementedException.
//
// This could have been implemented as an additional bit serialized
// into the `Data` string of SymbolAnnotation. However that would
// require additional substring operations to retrieve SymbolAnnotation
// symbols even in the common case where we don't need to supress
// add imports. This is therefore implemented as a separate annnotation.
internal class DoNotAddImportsAnnotation
{
public static readonly SyntaxAnnotation Annotation = new SyntaxAnnotation(Kind);
public const string Kind = "DoNotAddImports";
}
}
......@@ -395,6 +395,7 @@
<Compile Include="NamingStyles\Serialization\NamingStylePreferences.cs" />
<Compile Include="NamingStyles\Serialization\SymbolSpecification.cs" />
<Compile Include="Shared\Extensions\SolutionExtensions.cs" />
<Compile Include="Simplification\DoNotAddImportsAnnotation.cs" />
<Compile Include="SymbolKey\SymbolKey.AnonymousFunctionOrDelegateSymbolKey.cs" />
<Compile Include="Workspace\Host\TaskScheduler\WorkspaceTaskSchedulerFactory.WorkspaceTaskScheduler.cs" />
<Compile Include="Tags\WellKnownTags.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册