提交 19cb9aa2 编写于 作者: C CyrusNajmabadi

Merge remote-tracking branch 'upstream/master' into mergeMasterIndoDev15.6

......@@ -221,6 +221,7 @@
<VSSDKComponentModelHostVersion>12.0.4</VSSDKComponentModelHostVersion>
<VsWebsiteInteropVersion>8.0.0.0-alpha</VsWebsiteInteropVersion>
<xunitVersion>2.2.0-beta4-build3444</xunitVersion>
<xunitassertVersion>2.2.0-beta4-build3444</xunitassertVersion>
<xunitconsolenetcoreVersion>1.0.2-prerelease-00104</xunitconsolenetcoreVersion>
<xunitrunnerconsoleVersion>2.2.0-beta4-build3444</xunitrunnerconsoleVersion>
<xunitrunnervisualstudioVersion>2.2.0-beta4-build1194</xunitrunnervisualstudioVersion>
......
......@@ -146,14 +146,13 @@
<Compile Include="Emit\EditAndContinue\LocalSlotMappingTests.cs" />
<Compile Include="Emit\EmitCustomModifiers.cs" />
<Compile Include="Emit\EmitErrorTests.cs" />
<Compile Include="Emit\EmitMetadata.cs" />
<Compile Include="Emit\EmitMetadataTests.cs" />
<Compile Include="Emit\EmitMetadataTestBase.cs" />
<Compile Include="Attributes\EmitTestStrongNameProvider.cs" />
<Compile Include="Emit\EndToEndTests.cs" />
<Compile Include="Emit\EntryPointTests.cs" />
<Compile Include="Emit\NoPiaEmbedTypes.cs" />
<Compile Include="Emit\OptionalArgumentsTests.cs" />
<Compile Include="Emit\OutputStreams.cs" />
<Compile Include="Emit\ResourceTests.cs" />
<Compile Include="CodeGen\CodeGenScriptTests.cs" />
<Compile Include="PDB\CheckSumTest.cs" />
......
......@@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
{
public static class LocalFunctionTestsUtil
{
public static IMethodSymbol FindLocalFunction(this CommonTestBase.CompilationVerifier verifier, string localFunctionName)
public static IMethodSymbol FindLocalFunction(this CompilationVerifier verifier, string localFunctionName)
{
localFunctionName = (char)GeneratedNameKind.LocalFunction + "__" + localFunctionName;
var methods = verifier.TestData.GetMethodsByName();
......
......@@ -2,6 +2,7 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
......@@ -703,14 +704,6 @@ public static IEnumerable Power(int number, int exponent)
CompileAndVerify(text, expectedOutput: expectedOutput);
}
// When ReflectionEmit supports writing exception handler info, this method
// can be removed and CompileAndVerify references above will resolve to
// the overload that emits with both CCI and ReflectionEmit. (Bug #7012)
private CompilationVerifier CompileAndVerify(string source, string expectedOutput = null)
{
return base.CompileAndVerify(source: source, expectedOutput: expectedOutput);
}
[WorkItem(540719, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540719")]
[Fact]
public void LabelBetweenLocalAndInitialize()
......
// 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.IO;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Emit
{
internal class NameResolver
{
public string GetDebugInformationFileName(SyntaxTree syntaxTree)
{
throw new NotImplementedException();
}
public Stream GetXmlInclude(SyntaxTree syntaxTree, string xmlIncludeFile)
{
throw new NotImplementedException();
}
}
}
......@@ -2214,7 +2214,7 @@ class C
var emitResult1 = c.Emit(peStream: peStream1, pdbStream: pdbStream);
var emitResult2 = c.Emit(peStream: peStream2);
PdbValidation.VerifyMetadataEqualModuloMvid(peStream1, peStream2);
MetadataValidation.VerifyMetadataEqualModuloMvid(peStream1, peStream2);
}
[Fact]
......
......@@ -483,7 +483,7 @@ static System.Action<object> F()
Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "value__").WithArguments("A.value__"));
// PEVerify should not report "Field value__ ... is not marked RTSpecialName".
var verifier = new CompilationVerifier(this, compilation);
var verifier = new CompilationVerifier(compilation);
verifier.EmitAndVerify(
"Error: Field name value__ is reserved for Enums only.",
"Error: Field name value__ is reserved for Enums only.",
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// 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 Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using static Microsoft.CodeAnalysis.Test.Utilities.CommonTestBase;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
......
......@@ -899,6 +899,7 @@
<InternalsVisibleToTest Include="Roslyn.Test.Utilities.Desktop" />
<InternalsVisibleToTest Include="Roslyn.Test.Utilities.FX45" />
<InternalsVisibleToTest Include="Roslyn.Test.Utilities" />
<InternalsVisibleToTest Include="Roslyn.Test.PdbUtilities" />
<InternalsVisibleToTest Include="Roslyn.Compilers.CompilerServer.UnitTests" />
<InternalsVisibleToMoq Include="DynamicProxyGenAssembly2" />
</ItemGroup>
......
......@@ -53,11 +53,6 @@ protected override Compilation GetCompilationForEmit(IEnumerable<string> source,
throw new NotImplementedException();
}
internal override IEnumerable<IModuleSymbol> ReferencesToModuleSymbols(IEnumerable<MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
{
throw new NotImplementedException();
}
internal override string VisualizeRealIL(IModuleSymbol peModule, CodeAnalysis.CodeGen.CompilationTestData.MethodData methodData, IReadOnlyDictionary<int, string> markers)
{
throw new NotImplementedException();
......
......@@ -38,11 +38,6 @@ public abstract class CSharpTestBase : CSharpTestBaseBase
return (CSharpCompilation)base.GetCompilationForEmit(source, additionalRefs, options, parseOptions);
}
internal new IEnumerable<ModuleSymbol> ReferencesToModuleSymbols(IEnumerable<MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
{
return base.ReferencesToModuleSymbols(references, importOptions).Cast<ModuleSymbol>();
}
private Action<IModuleSymbol> Translate2(Action<ModuleSymbol> action)
{
if (action != null)
......@@ -219,24 +214,6 @@ public static CSharpCompilation CreateWinRtCompilation(string text, MetadataRefe
TestOptions.ReleaseExe);
}
internal override IEnumerable<IModuleSymbol> ReferencesToModuleSymbols(IEnumerable<MetadataReference> references, MetadataImportOptions importOptions = MetadataImportOptions.Public)
{
var options = TestOptions.ReleaseDll.WithMetadataImportOptions(importOptions);
var tc1 = CSharpCompilation.Create("Dummy", new SyntaxTree[0], references, options);
return references.Select(r =>
{
if (r.Properties.Kind == MetadataImageKind.Assembly)
{
var assemblySymbol = tc1.GetReferencedAssemblySymbol(r);
return (object)assemblySymbol == null ? null : assemblySymbol.Modules[0];
}
else
{
return tc1.GetReferencedModuleSymbol(r);
}
});
}
protected override CompilationOptions CompilationOptionsReleaseDll
{
get { return TestOptions.ReleaseDll; }
......
......@@ -414,20 +414,6 @@ End Class
Public MustInherit Class BasicTestBaseBase
Inherits CommonTestBase
Friend Overrides Function ReferencesToModuleSymbols(references As IEnumerable(Of MetadataReference), Optional importOptions As MetadataImportOptions = MetadataImportOptions.Public) As IEnumerable(Of IModuleSymbol)
Dim options = DirectCast(CompilationOptionsReleaseDll, VisualBasicCompilationOptions).WithMetadataImportOptions(importOptions)
Dim tc1 = VisualBasicCompilation.Create("Dummy", references:=references, options:=options)
Return references.Select(
Function(r)
If r.Properties.Kind = MetadataImageKind.Assembly Then
Dim assemblySymbol = tc1.GetReferencedAssemblySymbol(r)
Return If(assemblySymbol Is Nothing, Nothing, assemblySymbol.Modules(0))
Else
Return tc1.GetReferencedModuleSymbol(r)
End If
End Function)
End Function
Protected Overrides ReadOnly Property CompilationOptionsReleaseDll As CompilationOptions
Get
Return TestOptions.ReleaseDll
......
......@@ -2,6 +2,7 @@
Imports System.IO
Imports Microsoft.CodeAnalysis.Test.Utilities
Imports Roslyn.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.PDB
Public Class PDBNamespaceScopes
......@@ -383,7 +384,7 @@ End Class
Dim emitResult1 = c.Emit(peStream:=peStream1, pdbStream:=pdbStream)
Dim emitResult2 = c.Emit(peStream:=peStream2)
PdbValidation.VerifyMetadataEqualModuloMvid(peStream1, peStream2)
MetadataValidation.VerifyMetadataEqualModuloMvid(peStream1, peStream2)
End Sub
<Fact>
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Test.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.PDB
......
......@@ -491,7 +491,7 @@ End Module
compilation.AssertNoErrors()
' PEVerify should not report "Field value__ ... is not marked RTSpecialName".
Dim verifier = New CompilationVerifier(Me, compilation)
Dim verifier = New CompilationVerifier(compilation)
verifier.EmitAndVerify(
"Error: Field name value__ is reserved for Enums only.")
End Sub
......
......@@ -136,14 +136,12 @@
<Compile Include="Highlighting\KeywordHighlighters\UnsafeStatementHighlighter.cs" />
<Compile Include="Highlighting\KeywordHighlighters\UsingStatementHighlighter.cs" />
<Compile Include="Highlighting\KeywordHighlighters\YieldStatementHighlighter.cs" />
<Compile Include="HighlightReferences\CSharpDocumentHighlightsService.cs" />
<Compile Include="InlineRename\CSharpEditorInlineRenameService.cs" />
<Compile Include="LanguageServices\CSharpContentTypeLanguageService.cs" />
<Compile Include="LineSeparators\CSharpLineSeparatorService.cs" />
<Compile Include="NavigationBar\CSharpNavigationBarItemService.cs" />
<Compile Include="QuickInfo\SemanticQuickInfoProvider.cs" />
<Compile Include="QuickInfo\SyntacticQuickInfoProvider.cs" />
<Compile Include="ReferenceHighlighting\ReferenceHighlightingAdditionalReferenceProvider.cs" />
<Compile Include="RenameTracking\CSharpRenameTrackingCodeFixProvider.cs" />
<Compile Include="RenameTracking\CSharpRenameTrackingLanguageHeuristicsService.cs" />
<Compile Include="SplitStringLiteral\SplitStringLiteralCommandHandler.cs" />
......
// 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.Composition;
using Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting;
using Microsoft.CodeAnalysis.Host.Mef;
namespace Microsoft.CodeAnalysis.Editor.CSharp.HighlightReferences
{
[ExportLanguageService(typeof(IDocumentHighlightsService), LanguageNames.CSharp), Shared]
internal class CSharpDocumentHighlightsService : AbstractDocumentHighlightsService
{
}
}
......@@ -246,7 +246,7 @@
<Compile Include="ConvertToInterpolatedString\ConvertPlaceholderToInterpolatedStringTests.cs" />
<Compile Include="CodeActions\EncapsulateField\EncapsulateFieldTests.cs" />
<Compile Include="CodeActions\ExtractMethod\ExtractMethodTests.cs" />
<Compile Include="CodeActions\GenerateDefaultConstructors\GenerateDefaultConstructorsTests.cs" />
<Compile Include="GenerateDefaultConstructors\GenerateDefaultConstructorsTests.cs" />
<Compile Include="Diagnostics\UpgradeProject\UpgradeProjectTests.cs" />
<Compile Include="Completion\CompletionProviders\DeclarationNameCompletionProviderTests_NameDeclarationInfoTests.cs" />
<Compile Include="GenerateFromMembers\AddConstructorParametersFromMembers\AddConstructorParametersFromMembersTests.cs" />
......@@ -396,6 +396,7 @@
<Compile Include="UseCollectionInitializer\UseCollectionInitializerTests.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionForNullableTests.cs" />
<Compile Include="UseCoalesceExpression\UseCoalesceExpressionTests.cs" />
<Compile Include="UseDefaultLiteral\UseDefaultLiteralTests.cs" />
<Compile Include="UseExplicitTupleName\UseExplicitTupleNameTests.cs" />
<Compile Include="UseExpressionBody\Refactoring\UseExpressionBodyForConstructorsRefactoringTests.cs" />
<Compile Include="UseExpressionBody\Refactoring\UseExpressionBodyForConversionOperatorsRefactoringTests.cs" />
......
......@@ -326,6 +326,36 @@ class C
{
void M(Action arg1, int arg2)
=> M([|1 + 2|], 3);
}");
}
[WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)]
public async Task TestCaretPositionAtTheEnd1()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(int arg1) => M(arg1[||]);
}",
@"class C
{
void M(int arg1) => M(arg1: arg1);
}");
}
[WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)]
public async Task TestCaretPositionAtTheEnd2()
{
await TestInRegularAndScriptAsync(
@"class C
{
void M(int arg1, int arg2) => M(arg1[||], arg2);
}",
@"class C
{
void M(int arg1, int arg2) => M(arg1: arg1, arg2: arg2);
}");
}
}
......
......@@ -176,5 +176,41 @@ public class A
</Workspace>";
await RunMethodReferenceTest(input);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeLens)]
public async Task TestFullyQualifiedName()
{
const string input = @"<Workspace>
<Project Language=""C#"" CommonReferences=""true"" AssemblyName=""Proj1"">
<Document FilePath=""CurrentDocument.cs""><![CDATA[
public class A
{
{|A.C: public void C()
{
C();
}|}
public class B
{
{|A+B.C: public void C()
{
C();
}|}
public class D
{
{|A+B+D.C: public void C()
{
C();
}|}
}
}
}
]]>
</Document>
</Project>
</Workspace>";
await RunFullyQualifiedNameTest(input);
}
}
}
......@@ -1483,7 +1483,6 @@ public void InterpolationFormatClause_update()
edits.VerifyEdits("Update [x = $\"Hello{123:N1}\"]@8 -> [x = $\"Hello{123:N2}\"]@8");
}
[WorkItem(18970, "https://github.com/dotnet/roslyn/issues/18970")]
[Fact]
public void MatchCasePattern_UpdateDelete()
{
......@@ -1507,9 +1506,9 @@ public void MatchCasePattern_UpdateDelete()
var expected = new MatchingPairs {
{ "switch(shape) { case Point p: return 0; case Circle c: return 1; }", "switch(shape) { case Circle circle: return 1; }" },
{ "p", "circle" },
{ "case Circle c: return 1;", "case Circle circle: return 1;" },
{ "case Circle c:", "case Circle circle:" },
{ "c", "circle" },
{ "return 1;", "return 1;" }
};
......@@ -1716,7 +1715,6 @@ public void Switch_Case_Update()
"Update [case 1: f(); break;]@18 -> [case 2: f(); break;]@18");
}
[WorkItem(18970, "https://github.com/dotnet/roslyn/issues/18970")]
[Fact]
public void CasePatternLabel_UpdateDelete()
{
......@@ -1739,12 +1737,11 @@ public void CasePatternLabel_UpdateDelete()
edits.VerifyEdits(
"Update [case Circle c: return 1;]@55 -> [case Circle circle: return 1;]@26",
"Update [p]@37 -> [circle]@38",
"Move [p]@37 -> @38",
"Update [c]@67 -> [circle]@38",
"Delete [case Point p: return 0;]@26",
"Delete [case Point p:]@26",
"Delete [return 0;]@40",
"Delete [c]@67");
"Delete [p]@37",
"Delete [return 0;]@40");
}
#endregion
......@@ -8423,12 +8420,11 @@ public void CasePattern_UpdateDelete()
edits.VerifyEdits(
"Update [case Circle c: A(c); break;]@55 -> [case Circle c1: A(c1); break;]@26",
"Update [A(c);]@70 -> [A(c1);]@42",
"Update [p]@37 -> [c1]@38",
"Move [p]@37 -> @38",
"Update [c]@67 -> [c1]@38",
"Delete [case Point p: return 0;]@26",
"Delete [case Point p:]@26",
"Delete [return 0;]@40",
"Delete [c]@67");
"Delete [p]@37",
"Delete [return 0;]@40");
}
[Fact]
......
......@@ -2316,66 +2316,6 @@ public Base(bool val = false)
}");
}
[WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)]
public async Task TestGenerateFromDerivedClass()
{
await TestInRegularAndScriptAsync(
@"class Base
{
public Base(string value)
{
}
}
class [||]Derived : Base
{
}",
@"class Base
{
public Base(string value)
{
}
}
class Derived : Base
{
public Derived(string value) : base(value)
{
}
}");
}
[WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)]
public async Task TestGenerateFromDerivedClass2()
{
await TestInRegularAndScriptAsync(
@"class Base
{
public Base(int a, string value = null)
{
}
}
class [||]Derived : Base
{
}",
@"class Base
{
public Base(int a, string value = null)
{
}
}
class Derived : Base
{
public Derived(int a, string value = null) : base(a, value)
{
}
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)]
public async Task TestGenerateWithIncorrectConstructorArguments_Crash()
{
......
......@@ -2,11 +2,12 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeRefactorings.GenerateDefaultConstructors;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
using Microsoft.CodeAnalysis.GenerateDefaultConstructors;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.GenerateDefaultConstructors
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GenerateDefaultConstructors
{
public class GenerateDefaultConstructorsTests : AbstractCSharpCodeActionTest
{
......@@ -590,7 +591,7 @@ protected Program(SerializationInfo info, StreamingContext context) : base(info,
{
}
}",
index: 3,
index: 4,
ignoreTrivia: false);
}
......@@ -728,10 +729,6 @@ public Program()
{
}
public Program()
{
}
public Program(string message) : base(message)
{
}
......@@ -806,6 +803,66 @@ class B
public B((int a, string b) x)
{
}
}");
}
[WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)]
public async Task TestGenerateFromDerivedClass()
{
await TestInRegularAndScriptAsync(
@"class Base
{
public Base(string value)
{
}
}
class [||]Derived : Base
{
}",
@"class Base
{
public Base(string value)
{
}
}
class Derived : Base
{
public Derived(string value) : base(value)
{
}
}");
}
[WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)]
public async Task TestGenerateFromDerivedClass2()
{
await TestInRegularAndScriptAsync(
@"class Base
{
public Base(int a, string value = null)
{
}
}
class [||]Derived : Base
{
}",
@"class Base
{
public Base(int a, string value = null)
{
}
}
class Derived : Base
{
public Derived(int a, string value = null) : base(a, value)
{
}
}");
}
}
......
......@@ -159,7 +159,7 @@ public Program(int i)
this.i = i;
}
public Program(int i, string s, bool b = default(bool)) : this(i)
public Program(int i, string s, bool b = false) : this(i)
{
this.s = s;
this.b = b;
......
......@@ -47,6 +47,8 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider
SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithNoneEnforcement),
SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, CSharpCodeStyleOptions.NeverWithNoneEnforcement));
private static readonly ParseOptions CSharp7_1 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1);
internal async Task TestWithAllCodeStyleOptionsOffAsync(
string initialMarkup, string expectedMarkup,
int index = 0, bool ignoreTrivia = true,
......@@ -6789,5 +6791,37 @@ class Class : IInterface
ImplementTypeOptions.PropertyGenerationBehavior,
ImplementTypePropertyGenerationBehavior.PreferAutoProperties)));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public async Task TestOptionalParameterWithDefaultLiteral()
{
await TestWithAllCodeStyleOptionsOffAsync(
@"
using System.Threading;
interface IInterface
{
void Method1(CancellationToken cancellationToken = default(CancellationToken));
}
class Class : [|IInterface|]
{
}",
@"
using System.Threading;
interface IInterface
{
void Method1(CancellationToken cancellationToken = default(CancellationToken));
}
class Class : IInterface
{
public void Method1(CancellationToken cancellationToken = default)
{
throw new System.NotImplementedException();
}
}", parseOptions: CSharp7_1);
}
}
}
\ No newline at end of file
// 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.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.UseDefaultLiteral;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.UseDefaultLiteral
{
public class UseDefaultLiteralTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
{
internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
=> (new CSharpUseDefaultLiteralDiagnosticAnalyzer(), new CSharpUseDefaultLiteralCodeFixProvider());
private static readonly CSharpParseOptions s_parseOptions =
CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1);
private static readonly TestParameters s_testParameters =
new TestParameters(parseOptions: s_parseOptions);
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestNotInCSharp7()
{
await TestMissingAsync(
@"
class C
{
void Foo(string s = [||]default(string))
{
}
}", parameters: new TestParameters(
parseOptions: CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7)));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInParameterList()
{
await TestAsync(
@"
class C
{
void Foo(string s = [||]default(string))
{
}
}",
@"
class C
{
void Foo(string s = default)
{
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInIfCheck()
{
await TestAsync(
@"
class C
{
void Foo(string s)
{
if (s == [||]default(string)) { }
}
}",
@"
class C
{
void Foo(string s)
{
if (s == default) { }
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInReturnStatement()
{
await TestAsync(
@"
class C
{
string Foo()
{
return [||]default(string);
}
}",
@"
class C
{
string Foo()
{
return default;
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInReturnStatement2()
{
await TestMissingAsync(
@"
class C
{
string Foo()
{
return [||]default(int);
}
}", parameters: s_testParameters);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInLambda1()
{
await TestAsync(
@"
using System;
class C
{
void Foo()
{
Func<string> f = () => [||]default(string);
}
}",
@"
using System;
class C
{
void Foo()
{
Func<string> f = () => [||]default;
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInLambda2()
{
await TestMissingAsync(
@"
using System;
class C
{
void Foo()
{
Func<string> f = () => [||]default(int);
}
}", parameters: s_testParameters);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInLocalInitializer()
{
await TestAsync(
@"
class C
{
void Foo()
{
string s = [||]default(string);
}
}",
@"
class C
{
void Foo()
{
string s = default;
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInLocalInitializer2()
{
await TestMissingAsync(
@"
class C
{
void Foo()
{
string s = [||]default(int);
}
}", parameters: s_testParameters);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestNotForVar()
{
await TestMissingAsync(
@"
class C
{
void Foo()
{
var s = [||]default(string);
}
}", parameters: s_testParameters);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestInInvocationExpression()
{
await TestAsync(
@"
class C
{
void Foo()
{
Bar([||]default(string));
}
void Bar(string s) { }
}",
@"
class C
{
void Foo()
{
Bar(default);
}
void Bar(string s) { }
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestNotWithMultipleOverloads()
{
await TestMissingAsync(
@"
class C
{
void Foo()
{
Bar([||]default(string));
}
void Bar(string s) { }
void Bar(int i);
}", parameters: s_testParameters);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestLeftSideOfTernary()
{
await TestAsync(
@"
class C
{
void Foo(bool b)
{
var v = b ? [||]default(string) : default(string);
}
}",
@"
class C
{
void Foo(bool b)
{
var v = b ? default : default(string);
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestRightSideOfTernary()
{
await TestAsync(
@"
class C
{
void Foo(bool b)
{
var v = b ? default(string) : [||]default(string);
}
}",
@"
class C
{
void Foo(bool b)
{
var v = b ? default(string) : default;
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestFixAll1()
{
await TestAsync(
@"
class C
{
void Foo()
{
string s1 = {|FixAllInDocument:default|}(string);
string s2 = default(string);
}
}",
@"
class C
{
void Foo()
{
string s1 = default;
string s2 = default;
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestFixAll2()
{
await TestAsync(
@"
class C
{
void Foo(bool b)
{
string s1 = b ? {|FixAllInDocument:default|}(string) : default(string);
}
}",
@"
class C
{
void Foo(bool b)
{
string s1 = b ? default : default(string);
}
}", parseOptions: s_parseOptions);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseDefaultLiteral)]
public async Task TestFixAll3()
{
await TestAsync(
@"
class C
{
void Foo()
{
string s1 = {|FixAllInDocument:default|}(string);
string s2 = default(int);
}
}",
@"
class C
{
void Foo()
{
string s1 = default;
string s2 = default(int);
}
}", parseOptions: s_parseOptions);
}
}
}
\ No newline at end of file
......@@ -165,9 +165,19 @@
<Compile Include="Implementation\Intellisense\QuickInfo\Providers\LinkedFileDiscrepancyException.cs" />
<Compile Include="Implementation\Intellisense\Completion\CompletionFilterReason.cs" />
<Compile Include="Implementation\Intellisense\Completion\FilterResult.cs" />
<Compile Include="ReferenceHighlighting\IDocumentHighlightsService.cs" />
<Compile Include="Implementation\Structure\BlockTagState.cs" />
<Compile Include="Implementation\Suggestions\ISuggestedActionCallback.cs" />
<Compile Include="Implementation\Suggestions\SuggestedActionSetComparer.cs" />
<Compile Include="Implementation\Suggestions\SuggestedActionsSource.cs" />
<Compile Include="ReferenceHighlighting\NagivateToHighlightReferenceCommandHandler.cs" />
<Compile Include="ReferenceHighlighting\NagivateToHighlightReferenceCommandHandler.StartComparer.cs" />
<Compile Include="ReferenceHighlighting\ReferenceHighlightingViewTaggerProvider.cs" />
<Compile Include="ReferenceHighlighting\Tags\DefinitionHighlightTag.cs" />
<Compile Include="ReferenceHighlighting\Tags\DefinitionHighlightTagDefinition.cs" />
<Compile Include="ReferenceHighlighting\Tags\ReferenceHighlightTag.cs" />
<Compile Include="ReferenceHighlighting\Tags\WrittenReferenceHighlightTag.cs" />
<Compile Include="ReferenceHighlighting\Tags\WrittenReferenceHighlightTagDefinition.cs" />
<Compile Include="Implementation\InfoBar\EditorInfoBarService.cs" />
<Compile Include="SymbolSearch\IAddReferenceDatabaseWrapper.cs" />
<Compile Include="SymbolSearch\IDatabaseFactoryService.cs" />
......@@ -631,8 +641,6 @@
<Compile Include="Implementation\Peek\PeekableItemSource.cs" />
<Compile Include="Implementation\Peek\PeekableItemSourceProvider.cs" />
<Compile Include="Implementation\Peek\PeekHelpers.cs" />
<Compile Include="Implementation\ReferenceHighlighting\WrittenReferenceHighlightTag.cs" />
<Compile Include="Implementation\ReferenceHighlighting\WrittenReferenceHighlightTagDefinition.cs" />
<Compile Include="Implementation\RenameTracking\IRenameTrackingLanguageHeuristicsService.cs" />
<Compile Include="Implementation\RenameTracking\RenameTrackingCancellationCommandHandler.cs" />
<Compile Include="Implementation\RenameTracking\RenameTrackingTagDefinition.cs" />
......@@ -644,15 +652,6 @@
<Compile Include="Implementation\Preview\PreviewConflictViewTaggerProvider.cs" />
<Compile Include="Implementation\Preview\PreviewFactoryService.cs" />
<Compile Include="Implementation\Preview\PreviewWarningViewTaggerProvider.cs" />
<Compile Include="Implementation\ReferenceHighlighting\AbstractDocumentHighlightsService.cs" />
<Compile Include="Implementation\ReferenceHighlighting\DefinitionHighlightTag.cs" />
<Compile Include="Implementation\ReferenceHighlighting\DefinitionHighlightTagDefinition.cs" />
<Compile Include="Implementation\ReferenceHighlighting\IDocumentHighlightsService.cs" />
<Compile Include="Implementation\ReferenceHighlighting\IReferenceHighlightingAdditionalReferenceProvider.cs" />
<Compile Include="Implementation\ReferenceHighlighting\NagivateToHighlightReferenceCommandHandler.cs" />
<Compile Include="Implementation\ReferenceHighlighting\NagivateToHighlightReferenceCommandHandler.StartComparer.cs" />
<Compile Include="Implementation\ReferenceHighlighting\ReferenceHighlightingViewTaggerProvider.cs" />
<Compile Include="Implementation\ReferenceHighlighting\ReferenceHighlightTag.cs" />
<Compile Include="Implementation\RenameTracking\AbstractRenameTrackingCodeFixProvider.cs" />
<Compile Include="Implementation\RenameTracking\RenameTrackingDiagnosticAnalyzer.cs" />
<Compile Include="Implementation\RenameTracking\RenameTrackingTaggerProvider.cs" />
......
......@@ -43,7 +43,8 @@ internal struct ClassifiedSpansAndHighlightSpan
// If the document span is providing us with the classified spans up front, then we
// can just use that. Otherwise, go back and actually classify the text for the line
// the document span is on.
if (documentSpan.Properties.TryGetValue(Key, out var value))
if (documentSpan.Properties != null &&
documentSpan.Properties.TryGetValue(Key, out var value))
{
return (ClassifiedSpansAndHighlightSpan)value;
}
......
......@@ -12,6 +12,7 @@
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.FindUsages
{
......@@ -47,7 +48,7 @@ internal static class DefinitionItemExtensions
// to compute the classified spans for the locations of the definition. So it's totally
// fine to pass in CancellationToken.None and block on the result.
return ToDefinitionItemAsync(definition, solution, includeHiddenLocations,
includeClassifiedSpans: false, cancellationToken: CancellationToken.None).Result;
includeClassifiedSpans: false, cancellationToken: CancellationToken.None).WaitAndGetResult_CanCallOnBackground(CancellationToken.None);
}
public static Task<DefinitionItem> ToClassifiedDefinitionItemAsync(
......
......@@ -61,8 +61,27 @@ internal static class GoToDefinitionHelpers
}
var definitions = ArrayBuilder<DefinitionItem>.GetInstance();
var definitionItem = symbol.ToClassifiedDefinitionItemAsync(
solution, includeHiddenLocations: true, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken);
// Going to a symbol may end up actually showing the symbol in the Find-Usages window.
// This happens when there is more than one location for the symbol (i.e. for partial
// symbols) and we don't know the best place to take you to.
//
// The FindUsages window supports showing the classified text for an item. It does this
// in two ways. Either the item can pass along its classified text (and the window will
// defer to that), or the item will have no classified text, and the window will compute
// it in the BG.
//
// Passing along the classified information is valuable for OOP scenarios where we want
// all that expensive computation done on the OOP side and not in the VS side.
//
// However, Go To Definition is all in-process, and is also synchronous. So we do not
// want to fetch the classifications here. It slows down the command and leads to a
// measurable delay in our perf tests.
//
// So, if we only have a single location to go to, this does no unnecessary work. And,
// if we do have multiple locations to show, it will just be done in the BG, unblocking
// this command thread so it can return the user faster.
var definitionItem = symbol.ToNonClassifiedDefinitionItem(solution, includeHiddenLocations: true);
if (thirdPartyNavigationAllowed)
{
......
......@@ -19,9 +19,12 @@ internal sealed class MetadataAsSourceGeneratedFileInfo
public readonly string TemporaryFilePath;
private readonly ParseOptions _parseOptions;
public MetadataAsSourceGeneratedFileInfo(string rootPath, Project sourceProject, INamedTypeSymbol topLevelNamedType)
{
this.SourceProjectId = sourceProject.Id;
_parseOptions = sourceProject.ParseOptions;
this.Workspace = sourceProject.Solution.Workspace;
this.LanguageName = sourceProject.Language;
this.References = sourceProject.MetadataReferences.ToImmutableArray();
......@@ -79,10 +82,11 @@ public MetadataAsSourceGeneratedFileInfo(string rootPath, Project sourceProject,
assemblyName: AssemblyIdentity.Name,
language: LanguageName,
compilationOptions: compilationOptions,
parseOptions: _parseOptions,
documents: new[] { assemblyInfoDocument, generatedDocument },
metadataReferences: References);
return Tuple.Create(projectInfo, generatedDocumentId);
}
}
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.Utilities;
using Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting;
using Microsoft.CodeAnalysis.Editor.ReferenceHighlighting;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Preview
{
......
// 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.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
{
internal interface IReferenceHighlightingAdditionalReferenceProvider : ILanguageService
{
Task<IEnumerable<Location>> GetAdditionalReferencesAsync(Document document, ISymbol symbol, CancellationToken cancellationToken);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
{
internal interface ISuggestedActionCallback
{
void OnSuggestedActionExecuted(SuggestedAction action);
}
}
......@@ -90,21 +90,25 @@ protected Task<ImmutableArray<CodeActionOperation>> GetPreviewOperationsAsync(Ca
public void Invoke(CancellationToken cancellationToken)
{
// While we're not technically doing anything async here, we need to let the
// While we're not technically doing anything async here, we need to let the
// integration test harness know that it should not proceed until all this
// work is done. Otherwise it might ask to do some work before we finish.
// That can happen because although we're on the UI thread, we may do things
// that end up causing VS to pump the messages that the test harness enqueues
// to the UI thread as well.
// to the UI thread as well.
using (SourceProvider.OperationListener.BeginAsyncOperation($"{nameof(SuggestedAction)}.{nameof(Invoke)}"))
{
// WaitIndicator cannot be used with async/await. Even though we call async methods
// WaitIndicator cannot be used with async/await. Even though we call async methods
// later in this call chain, do not await them.
SourceProvider.WaitIndicator.Wait(CodeAction.Title, CodeAction.Message, allowCancel: true, showProgress: true, action: waitContext =>
{
using (var linkedSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, waitContext.CancellationToken))
{
InnerInvoke(waitContext.ProgressTracker, linkedSource.Token);
foreach (var actionCallback in SourceProvider.ActionCallbacks)
{
actionCallback.Value.OnSuggestedActionExecuted(this);
}
}
});
}
......
......@@ -39,6 +39,7 @@ internal partial class SuggestedActionsSourceProvider : ISuggestedActionsSourceP
public readonly ICodeActionEditHandlerService EditHandler;
public readonly IAsynchronousOperationListener OperationListener;
public readonly IWaitIndicator WaitIndicator;
public readonly ImmutableArray<Lazy<ISuggestedActionCallback>> ActionCallbacks;
public readonly ImmutableArray<Lazy<IImageMonikerService, OrderableMetadata>> ImageMonikerServices;
......@@ -50,11 +51,13 @@ internal partial class SuggestedActionsSourceProvider : ISuggestedActionsSourceP
ICodeActionEditHandlerService editHandler,
IWaitIndicator waitIndicator,
[ImportMany] IEnumerable<Lazy<IAsynchronousOperationListener, FeatureMetadata>> asyncListeners,
[ImportMany] IEnumerable<Lazy<IImageMonikerService, OrderableMetadata>> imageMonikerServices)
[ImportMany] IEnumerable<Lazy<IImageMonikerService, OrderableMetadata>> imageMonikerServices,
[ImportMany] IEnumerable<Lazy<ISuggestedActionCallback>> actionCallbacks)
{
_codeRefactoringService = codeRefactoringService;
_diagnosticService = diagnosticService;
_codeFixService = codeFixService;
ActionCallbacks = actionCallbacks.ToImmutableArray();
EditHandler = editHandler;
WaitIndicator = waitIndicator;
OperationListener = new AggregateAsynchronousOperationListener(asyncListeners, FeatureAttribute.LightBulb);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// 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.Collections.Generic;
using System;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
......@@ -41,9 +41,13 @@ public DocumentHighlights(Document document, ImmutableArray<HighlightSpan> highl
}
}
/// <summary>
/// Note: kept around for back compat until F# and TypeScript move over to
/// <see cref="Microsoft.CodeAnalysis.DocumentHighlighting.IDocumentHighlightsService"/>.
/// </summary>
internal interface IDocumentHighlightsService : ILanguageService
{
Task<ImmutableArray<DocumentHighlights>> GetDocumentHighlightsAsync(
Document document, int position, IImmutableSet<Document> documentsToSearch, CancellationToken cancellationToken);
}
}
}
\ No newline at end of file
......@@ -3,7 +3,7 @@
using System.Collections.Generic;
using Microsoft.VisualStudio.Text;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
internal partial class NavigateToHighlightReferenceCommandHandler
{
......
......@@ -14,7 +14,7 @@
using Microsoft.VisualStudio.Text.Tagging;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
[ExportCommandHandler(PredefinedCommandHandlerNames.NavigateToHighlightedReference,
ContentTypeNames.RoslynContentType)]
......
......@@ -5,13 +5,17 @@
using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.DocumentHighlighting;
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.Editor.Shared.Tagging;
using Microsoft.CodeAnalysis.Editor.Tagging;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
......@@ -21,7 +25,7 @@
using Microsoft.VisualStudio.Utilities;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
[Export(typeof(IViewTaggerProvider))]
[ContentType(ContentTypeNames.RoslynContentType)]
......@@ -110,13 +114,12 @@ protected override Task ProduceTagsAsync(TaggerContext<NavigableHighlightTag> co
}
// Otherwise, we need to go produce all tags.
return ProduceTagsAsync(context, caretPosition, workspace, document);
return ProduceTagsAsync(context, caretPosition, document);
}
internal async Task ProduceTagsAsync(
TaggerContext<NavigableHighlightTag> context,
SnapshotPoint position,
Workspace workspace,
Document document)
{
var cancellationToken = context.CancellationToken;
......@@ -127,25 +130,73 @@ protected override Task ProduceTagsAsync(TaggerContext<NavigableHighlightTag> co
{
if (document != null)
{
var documentHighlightsService = document.Project.LanguageServices.GetService<IDocumentHighlightsService>();
if (documentHighlightsService != null)
// As we transition to the new API (defined at the Features layer) we support
// calling into both it and the old API (defined at the EditorFeatures layer).
//
// Once TypeScript and F# can move over, then we can remove the calls to the old
// API.
await TryNewServiceAsync(context, position, document).ConfigureAwait(false);
await TryOldServiceAsync(context, position, document).ConfigureAwait(false);
}
}
}
private Task TryOldServiceAsync(TaggerContext<NavigableHighlightTag> context, SnapshotPoint position, Document document)
{
return TryServiceAsync<IDocumentHighlightsService>(
context, position, document,
(s, d, p, ds, c) => s.GetDocumentHighlightsAsync(d, p, ds, c));
}
private Task TryNewServiceAsync(
TaggerContext<NavigableHighlightTag> context, SnapshotPoint position, Document document)
{
return TryServiceAsync<DocumentHighlighting.IDocumentHighlightsService>(
context, position, document,
async (service, doc, point, documents, cancellation) =>
{
// Call into the new service.
var newHighlights = await service.GetDocumentHighlightsAsync(doc, point, documents, cancellation).ConfigureAwait(false);
// then convert the result to the form the old service would return.
return ConvertHighlights(newHighlights);
});
}
private async Task TryServiceAsync<T>(
TaggerContext<NavigableHighlightTag> context, SnapshotPoint position, Document document,
Func<T, Document, SnapshotPoint, ImmutableHashSet<Document>, CancellationToken, Task<ImmutableArray<DocumentHighlights>>> getDocumentHighlightsAsync)
where T : class, ILanguageService
{
var cancellationToken = context.CancellationToken;
var documentHighlightsService = document.GetLanguageService<T>();
if (documentHighlightsService != null)
{
// We only want to search inside documents that correspond to the snapshots
// we're looking at
var documentsToSearch = ImmutableHashSet.CreateRange(context.SpansToTag.Select(vt => vt.Document).WhereNotNull());
var documentHighlightsList = await getDocumentHighlightsAsync(
documentHighlightsService, document, position, documentsToSearch, cancellationToken).ConfigureAwait(false);
if (documentHighlightsList != null)
{
foreach (var documentHighlights in documentHighlightsList)
{
// We only want to search inside documents that correspond to the snapshots
// we're looking at
var documentsToSearch = ImmutableHashSet.CreateRange(context.SpansToTag.Select(vt => vt.Document).WhereNotNull());
var documentHighlightsList = await documentHighlightsService.GetDocumentHighlightsAsync(document, position, documentsToSearch, cancellationToken).ConfigureAwait(false);
if (documentHighlightsList != null)
{
foreach (var documentHighlights in documentHighlightsList)
{
await AddTagSpansAsync(context, solution, documentHighlights).ConfigureAwait(false);
}
}
await AddTagSpansAsync(
context, document.Project.Solution, documentHighlights).ConfigureAwait(false);
}
}
}
}
private ImmutableArray<DocumentHighlights> ConvertHighlights(ImmutableArray<DocumentHighlighting.DocumentHighlights> newHighlights)
=> newHighlights.SelectAsArray(
documentHighlights => new DocumentHighlights(
documentHighlights.Document,
documentHighlights.HighlightSpans.SelectAsArray(
highlightSpan => new HighlightSpan(
highlightSpan.TextSpan,
(HighlightSpanKind)highlightSpan.Kind))));
private async Task AddTagSpansAsync(
TaggerContext<NavigableHighlightTag> context,
Solution solution,
......
......@@ -2,7 +2,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Tagging;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
internal class DefinitionHighlightTag : NavigableHighlightTag
{
......
......@@ -5,7 +5,7 @@
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
[Export(typeof(EditorFormatDefinition))]
[Name(DefinitionHighlightTag.TagId)]
......
......@@ -2,7 +2,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Tagging;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
internal class ReferenceHighlightTag : NavigableHighlightTag
{
......
......@@ -2,7 +2,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Tagging;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
internal class WrittenReferenceHighlightTag : NavigableHighlightTag
{
......
......@@ -5,7 +5,7 @@
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
{
[Export(typeof(EditorFormatDefinition))]
[Name(WrittenReferenceHighlightTag.TagId)]
......
......@@ -597,7 +597,7 @@ public async Task AddDefaultParameterWithNonDefaultValueToMethod()
public async Task AddDefaultParameterWithDefaultValueToMethod()
{
var input = "class C { public void [|M|]() { } }";
var expected = "class C { public void M(double number = default(double)) { } }";
var expected = "class C { public void M(double number = 0) { } }";
await TestAddParametersAsync(input, expected,
Parameters(Parameter(typeof(double), "number", true)));
}
......
......@@ -127,10 +127,6 @@
<Project>{eba4dfa1-6ded-418f-a485-a3b608978906}</Project>
<Name>InteractiveHost</Name>
</ProjectReference>
<ProjectReference Include="..\..\Test\PdbUtilities\PdbUtilities.csproj">
<Project>{afde6bea-5038-4a4a-a88e-dbd2e4088eed}</Project>
<Name>PdbUtilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\Workspaces\Remote\Core\RemoteWorkspaces.csproj">
<Project>{f822f72a-cc87-4e31-b57d-853f65cbebf3}</Project>
<Name>RemoteWorkspaces</Name>
......
......@@ -27,7 +27,12 @@ internal class TestContext : IDisposable
private readonly IMetadataAsSourceFileService _metadataAsSourceService;
private readonly ITextBufferFactoryService _textBufferFactoryService;
public static TestContext Create(string projectLanguage = null, IEnumerable<string> metadataSources = null, bool includeXmlDocComments = false, string sourceWithSymbolReference = null)
public static TestContext Create(
string projectLanguage = null,
IEnumerable<string> metadataSources = null,
bool includeXmlDocComments = false,
string sourceWithSymbolReference = null,
string languageVersion = null)
{
projectLanguage = projectLanguage ?? LanguageNames.CSharp;
metadataSources = metadataSources ?? SpecializedCollections.EmptyEnumerable<string>();
......@@ -35,7 +40,9 @@ public static TestContext Create(string projectLanguage = null, IEnumerable<stri
? new[] { AbstractMetadataAsSourceTests.DefaultMetadataSource }
: metadataSources;
var workspace = CreateWorkspace(projectLanguage, metadataSources, includeXmlDocComments, sourceWithSymbolReference);
var workspace = CreateWorkspace(
projectLanguage, metadataSources, includeXmlDocComments,
sourceWithSymbolReference, languageVersion);
return new TestContext(workspace);
}
......@@ -214,11 +221,21 @@ private static string DeduceLanguageString(string input)
? LanguageNames.VisualBasic : LanguageNames.CSharp;
}
private static TestWorkspace CreateWorkspace(string projectLanguage, IEnumerable<string> metadataSources, bool includeXmlDocComments, string sourceWithSymbolReference)
private static TestWorkspace CreateWorkspace(
string projectLanguage, IEnumerable<string> metadataSources,
bool includeXmlDocComments, string sourceWithSymbolReference,
string languageVersion)
{
var xmlString = string.Concat(@"
<Workspace>
<Project Language=""", projectLanguage, @""" CommonReferences=""true"">");
<Project Language=""", projectLanguage, @""" CommonReferences=""true""");
if (languageVersion != null)
{
xmlString += $@" LanguageVersion=""{languageVersion}""";
}
xmlString += ">";
metadataSources = metadataSources ?? new[] { AbstractMetadataAsSourceTests.DefaultMetadataSource };
......
......@@ -14,9 +14,11 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.MetadataAsSource
{
public abstract partial class AbstractMetadataAsSourceTests
{
internal static async Task GenerateAndVerifySourceAsync(string metadataSource, string symbolName, string projectLanguage, string expected, bool ignoreTrivia = true, bool includeXmlDocComments = false)
internal static async Task GenerateAndVerifySourceAsync(
string metadataSource, string symbolName, string projectLanguage, string expected,
bool ignoreTrivia = true, bool includeXmlDocComments = false, string languageVersion = null)
{
using (var context = TestContext.Create(projectLanguage, SpecializedCollections.SingletonEnumerable(metadataSource), includeXmlDocComments))
using (var context = TestContext.Create(projectLanguage, SpecializedCollections.SingletonEnumerable(metadataSource), includeXmlDocComments, languageVersion: languageVersion))
{
await context.GenerateAndVerifySourceAsync(symbolName, expected, ignoreTrivia);
}
......
......@@ -1360,5 +1360,30 @@ public interface [|IComImport|]
int Prop {{ get; }}
}}");
}
[Fact, Trait(Traits.Feature, Traits.Features.MetadataAsSource)]
public async Task TestOptionalParameterWithDefaultLiteral()
{
var metadataSource = @"
using System.Threading;
public class C {
public void M(CancellationToken cancellationToken = default(CancellationToken)) { }
}";
var symbolName = "C";
await GenerateAndVerifySourceAsync(metadataSource, symbolName, LanguageNames.CSharp, $@"
#region {FeaturesResources.Assembly} ReferencedAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// {CodeAnalysisResources.InMemoryAssembly}
#endregion
using System.Threading;
public class [|C|]
{{
public C();
public void M(CancellationToken cancellationToken = default);
}}", languageVersion: "CSharp7_1");
}
}
}
\ No newline at end of file
......@@ -3311,6 +3311,31 @@ class C
New TextChange(New TextSpan(0, _caretPosition), newText))
Return Task.FromResult(change)
End Function
<WorkItem(15348, "https://github.com/dotnet/roslyn/issues/15348")>
<WpfFact, Trait(Traits.Feature, Traits.Features.Completion)>
Public Async Function TestAfterCasePatternSwitchLabel() As Task
Using state = TestState.CreateCSharpTestState(
<Document>
class C
{
void M()
{
object o = 1;
switch(o)
{
case int i:
$$
break;
}
}
}
</Document>)
state.SendTypeChars("this")
Await state.AssertSelectedCompletionItem(displayText:="this", isHardSelected:=True)
End Using
End Function
End Class
End Class
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Threading
Imports Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
Imports Microsoft.CodeAnalysis.DocumentHighlighting
Imports Microsoft.CodeAnalysis.Editor.ReferenceHighlighting
Imports Microsoft.CodeAnalysis.Editor.Shared.Extensions
Imports Microsoft.CodeAnalysis.Editor.Shared.Options
Imports Microsoft.CodeAnalysis.Editor.Shared.Tagging
......@@ -16,9 +17,17 @@ Namespace Microsoft.CodeAnalysis.Editor.UnitTests.ReferenceHighlighting
Public MustInherit Class AbstractReferenceHighlightingTests
Protected Async Function VerifyHighlightsAsync(test As XElement, Optional optionIsEnabled As Boolean = True) As Tasks.Task
Await VerifyHighlightsAsync(test, optionIsEnabled, outOfProcess:=False)
Await VerifyHighlightsAsync(test, optionIsEnabled, outOfProcess:=True)
End Function
Private Async Function VerifyHighlightsAsync(test As XElement, optionIsEnabled As Boolean, outOfProcess As Boolean) As Tasks.Task
Using workspace = TestWorkspace.Create(test)
WpfTestCase.RequireWpfFact($"{NameOf(AbstractReferenceHighlightingTests)}.VerifyHighlightsAsync creates asynchronous taggers")
workspace.Options = workspace.Options.WithChangedOption(
DocumentHighlightingOptions.OutOfProcessAllowed, outOfProcess)
Dim tagProducer = New ReferenceHighlightingViewTaggerProvider(
workspace.GetService(Of IForegroundNotificationService),
workspace.GetService(Of ISemanticChangeNotificationService),
......
......@@ -103,5 +103,34 @@ protected static Task RunMethodReferenceTest(string input)
{
return RunMethodReferenceTest(XElement.Parse(input));
}
protected static async Task RunFullyQualifiedNameTest(XElement input)
{
using (var workspace = TestWorkspace.Create(input))
{
foreach (var annotatedDocument in workspace.Documents.Where(d => d.AnnotatedSpans.Any()))
{
var document = workspace.CurrentSolution.GetDocument(annotatedDocument.Id);
var syntaxNode = await document.GetSyntaxRootAsync();
foreach (var annotatedSpan in annotatedDocument.AnnotatedSpans)
{
var expected = annotatedSpan.Key;
foreach (var span in annotatedSpan.Value)
{
var declarationSyntaxNode = syntaxNode.FindNode(span);
var actual = await new CodeLensReferencesService().GetFullyQualifiedName(workspace.CurrentSolution,
annotatedDocument.Id, declarationSyntaxNode, CancellationToken.None);
Assert.Equal(expected, actual);
}
}
}
}
}
protected static Task RunFullyQualifiedNameTest(string input)
{
return RunFullyQualifiedNameTest(XElement.Parse(input));
}
}
}
......@@ -96,6 +96,7 @@ public static class Features
public const string CodeActionsUseAutoProperty = "CodeActions.UseAutoProperty";
public const string CodeActionsUseCoalesceExpression = "CodeActions.UseCoalesceExpression";
public const string CodeActionsUseCollectionInitializer = "CodeActions.UseCollectionInitializer";
public const string CodeActionsUseDefaultLiteral = "CodeActions.UseDefaultLiteral";
public const string CodeActionsUseExpressionBody = "CodeActions.UseExpressionBody";
public const string CodeActionsUseImplicitType = "CodeActions.UseImplicitType";
public const string CodeActionsUseExplicitType = "CodeActions.UseExplicitType";
......
......@@ -129,7 +129,6 @@
<Compile Include="Highlighting\KeywordHighlighters\XmlEmbeddedExpressionHighlighter.vb" />
<Compile Include="Highlighting\KeywordHighlighters\XmlProcessingInstructionHighlighter.vb" />
<Compile Include="Highlighting\KeywordHighlightingHelpers.vb" />
<Compile Include="HighlightReferences\VisualBasicDocumentHighlightsService.vb" />
<Compile Include="ImplementAbstractClass\ImplementAbstractClassCommandHandler.vb" />
<Compile Include="ImplementInterface\ImplementInterfaceCommandHandler.vb" />
<Compile Include="InlineRename\VisualBasicEditorInlineRenameService.vb" />
......@@ -155,7 +154,6 @@
<Compile Include="NavigationBar\GenerateMethodItem.vb" />
<Compile Include="NavigationBar\VisualBasicNavigationBarItemService.vb" />
<Compile Include="QuickInfo\SemanticQuickInfoProvider.vb" />
<Compile Include="ReferenceHighlighting\ReferenceHighlightingAdditionalReferenceProvider.vb" />
<Compile Include="RenameTracking\BasicRenameTrackingLanguageHeuristicsService.vb" />
<Compile Include="RenameTracking\RenameTrackingCodeFixProvider.vb" />
<Compile Include="TextStructureNavigation\TextStructureNavigatorProvider.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Composition
Imports System.Threading
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
Imports Microsoft.CodeAnalysis.Host.Mef
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.ReferenceHighlighting
<ExportLanguageService(GetType(IReferenceHighlightingAdditionalReferenceProvider), LanguageNames.VisualBasic), [Shared]>
Friend Class ReferenceHighlightingAdditionalReferenceProvider
Implements IReferenceHighlightingAdditionalReferenceProvider
Public Function GetAdditionalReferencesAsync(document As Document, symbol As ISymbol, cancellationToken As CancellationToken) As Task(Of IEnumerable(Of Location)) Implements IReferenceHighlightingAdditionalReferenceProvider.GetAdditionalReferencesAsync
Return SpecializedTasks.EmptyEnumerable(Of Location)()
End Function
End Class
End Namespace
......@@ -227,7 +227,7 @@
<Compile Include="ConvertToInterpolatedString\ConvertPlaceholderToInterpolatedStringTests.vb" />
<Compile Include="CodeActions\EncapsulateField\EncapsulateFieldTests.vb" />
<Compile Include="CodeActions\ExtractMethod\ExtractMethodTests.vb" />
<Compile Include="CodeActions\GenerateDefaultConstructors\GenerateDefaultConstructorsTests.vb" />
<Compile Include="GenerateDefaultConstructors\GenerateDefaultConstructorsTests.vb" />
<Compile Include="AddConstructorParametersFromMembers\AddConstructorParametersFromMembersTests.vb" />
<Compile Include="GenerateConstructorFromMembers\GenerateConstructorFromMembersTests.vb" />
<Compile Include="GenerateEqualsAndGetHashCodeFromMembers\GenerateEqualsAndGetHashCodeFromMembersTests.vb" />
......@@ -276,7 +276,7 @@
<Compile Include="Diagnostics\ExitContinue\ExitContinueCodeActionTests.vb" />
<Compile Include="Diagnostics\FixIncorrectFunctionReturnType\FixIncorrectFunctionReturnTypeTests.vb" />
<Compile Include="Diagnostics\FullyQualify\FullyQualifyTests.vb" />
<Compile Include="Diagnostics\GenerateConstructor\GenerateConstructorTests.vb" />
<Compile Include="GenerateConstructor\GenerateConstructorTests.vb" />
<Compile Include="Diagnostics\GenerateEndConstruct\GenerateEndConstructTests.vb" />
<Compile Include="Diagnostics\GenerateEnumMember\GenerateEnumMemberTests.vb" />
<Compile Include="Diagnostics\GenerateEvent\GenerateEventTests.vb" />
......
......@@ -258,6 +258,71 @@ Class C
Inherits System.Attribute
Public Sub New(arg As Integer)
End Sub
End Class")
End Function
<WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)>
Public Async Function TestCaretPositionAtTheEnd1() As Task
Await TestInRegularAndScriptAsync(
"Class C
Sub M(arg1 As Integer)
M(arg1[||])
End Sub
End Class",
"Class C
Sub M(arg1 As Integer)
M(arg1:=arg1)
End Sub
End Class")
End Function
<WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)>
Public Async Function TestCaretPositionAtTheEnd2() As Task
Await TestInRegularAndScriptAsync(
"Class C
Sub M(arg1 As Integer, arg2 As Integer)
M(arg1[||], arg2)
End Sub
End Class",
"Class C
Sub M(arg1 As Integer, arg2 As Integer)
M(arg1:=arg1, arg2:=arg2)
End Sub
End Class")
End Function
<WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)>
Public Async Function TestCaretPositionAtTheEnd3() As Task
Await TestMissingInRegularAndScriptAsync(
"Class C
Sub M(arg1 As Integer, optional arg2 As Integer=1, optional arg3 as Integer=1)
M(1,[||],3)
End Sub
End Class")
End Function
<WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)>
Public Async Function TestCaretPositionAtTheEnd4() As Task
Await TestMissingInRegularAndScriptAsync(
"Class C
Sub M(arg1 As Integer, optional arg2 As Integer=1, optional arg3 as Integer=1)
M(1[||],,3)
End Sub
End Class")
End Function
<WorkItem(19175, "https://github.com/dotnet/roslyn/issues/19175")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseNamedArguments)>
Public Async Function TestCaretPositionAtTheEnd5() As Task
Await TestMissingInRegularAndScriptAsync(
"Class C
Function M(arg1 As Integer, optional arg2 As Integer=1, optional arg3 as Integer=1) As Integer
M(1, M(1,[||], 3))
End Function
End Class")
End Function
End Class
......
......@@ -2,10 +2,11 @@
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.GenerateConstructor
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.GenerateConstructor
Public Class GenerateConstructorTests
Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest
......@@ -1528,98 +1529,6 @@ End Class")
End Function
End Class
<WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateInDerivedType1() As Task
Await TestInRegularAndScriptAsync(
"
Public Class Base
Public Sub New(a As String)
End Sub
End Class
Public Class [||]Derived
Inherits Base
End Class",
"
Public Class Base
Public Sub New(a As String)
End Sub
End Class
Public Class Derived
Inherits Base
Public Sub New(a As String)
MyBase.New(a)
End Sub
End Class")
End Function
<WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateInDerivedType2() As Task
Await TestInRegularAndScriptAsync(
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class [||]Derived
Inherits Base
End Class",
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class Derived
Inherits Base
Public Sub New(a As Integer, Optional b As String = Nothing)
MyBase.New(a, b)
End Sub
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateInDerivedType_InvalidClassStatement() As Task
Await TestInRegularAndScriptAsync(
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class [|;;|]Derived
Inherits Base
End Class",
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class ;;Derived
Inherits Base
Public Sub New(a As Integer, Optional b As String = Nothing)
MyBase.New(a, b)
End Sub
End Class")
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateConstructorNotOfferedForDuplicate() As Task
Await TestMissingInRegularAndScriptAsync(
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.CodeRefactorings
Imports Microsoft.CodeAnalysis.CodeRefactorings.GenerateDefaultConstructors
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings
Imports Microsoft.CodeAnalysis.GenerateDefaultConstructors
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.CodeRefactorings.GenerateDefaultConstructors
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.GenerateDefaultConstructors
Public Class GenerateDefaultConstructorsTests
Inherits AbstractVisualBasicCodeActionTest
......@@ -27,8 +28,7 @@ Imports System.Collections.Generic
Imports System.Linq
Class Program
Inherits Exception
Public Sub New(message As String)
MyBase.New(message)
Public Sub New()
End Sub
Sub Main(args As String())
End Sub
......@@ -51,8 +51,8 @@ Imports System.Collections.Generic
Imports System.Linq
Class Program
Inherits Exception
Public Sub New(message As String, innerException As Exception)
MyBase.New(message, innerException)
Public Sub New(message As String)
MyBase.New(message)
End Sub
Sub Main(args As String())
End Sub
......@@ -74,20 +74,50 @@ End Class",
"Imports System
Imports System.Collections.Generic
Imports System.Linq
Class Program
Inherits Exception
Public Sub New(message As String, innerException As Exception)
MyBase.New(message, innerException)
End Sub
Sub Main(args As String())
End Sub
End Class",
index:=2)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateDefaultConstructors)>
Public Async Function TestException3() As Task
Await TestInRegularAndScriptAsync(
"Imports System
Imports System.Collections.Generic
Imports System.Linq
Class Program
Inherits [||]Exception
Sub Main(args As String())
End Sub
End Class",
"Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Class Program
Inherits Exception
Protected Sub New(info As SerializationInfo, context As StreamingContext)
MyBase.New(info, context)
End Sub
Sub Main(args As String())
End Sub
End Class",
index:=2)
index:=3)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateDefaultConstructors)>
Public Async Function TestException3() As Task
Public Async Function TestException4() As Task
Await TestInRegularAndScriptAsync(
"Imports System
Imports System.Collections.Generic
......@@ -101,33 +131,47 @@ End Class",
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Serialization
Class Program
Inherits Exception
Public Sub New()
End Sub
Public Sub New(message As String)
MyBase.New(message)
End Sub
Public Sub New(message As String, innerException As Exception)
MyBase.New(message, innerException)
End Sub
Protected Sub New(info As SerializationInfo, context As StreamingContext)
MyBase.New(info, context)
End Sub
Sub Main(args As String())
End Sub
End Class",
index:=3)
index:=4)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateDefaultConstructors)>
<WorkItem(539676, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539676")>
Public Async Function TestNotOfferedOnResolvedBaseClassName() As Task
Await TestMissingInRegularAndScriptAsync(
Await TestInRegularAndScript1Async(
"Class Base
End Class
Class Derived
Inherits B[||]ase
End Class",
"Class Base
End Class
Class Derived
Inherits Base
Public Sub New()
End Sub
End Class")
End Function
......@@ -252,8 +296,7 @@ Imports System.Collections.Generic
Imports System.Linq
Class Program
Inherits Exception
Public Sub New()
End Sub
Public Sub New()
End Sub
Public Sub New(message As String)
......@@ -288,8 +331,7 @@ Imports System.Collections.Generic
Imports System.Linq
Class Program
Inherits Exception
Public Sub New(message As String)
MyBase.New(message)
Public Sub New()
End Sub
Sub Main(args As String())
End Sub
......@@ -484,5 +526,97 @@ End Class
index:=2,
ignoreTrivia:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateInDerivedType_InvalidClassStatement() As Task
Await TestInRegularAndScriptAsync(
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public [||]Class ;;Derived
Inherits Base
End Class",
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class ;;Derived
Inherits Base
Public Sub New(a As Integer, Optional b As String = Nothing)
MyBase.New(a, b)
End Sub
End Class")
End Function
<WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateInDerivedType1() As Task
Await TestInRegularAndScriptAsync(
"
Public Class Base
Public Sub New(a As String)
End Sub
End Class
Public Class [||]Derived
Inherits Base
End Class",
"
Public Class Base
Public Sub New(a As String)
End Sub
End Class
Public Class Derived
Inherits Base
Public Sub New(a As String)
MyBase.New(a)
End Sub
End Class")
End Function
<WorkItem(6541, "https://github.com/dotnet/Roslyn/issues/6541")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestGenerateInDerivedType2() As Task
Await TestInRegularAndScriptAsync(
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class [||]Derived
Inherits Base
End Class",
"
Public Class Base
Public Sub New(a As Integer, Optional b As String = Nothing)
End Sub
End Class
Public Class Derived
Inherits Base
Public Sub New(a As Integer, Optional b As String = Nothing)
MyBase.New(a, b)
End Sub
End Class")
End Function
End Class
End Namespace
End Namespace
\ No newline at end of file
......@@ -27,7 +27,6 @@
using Microsoft.VisualStudio.Debugger.Evaluation.ClrCompilation;
using Roslyn.Test.Utilities;
using Xunit;
using PDB::Roslyn.Test.MetadataUtilities;
using PDB::Roslyn.Test.PdbUtilities;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
......
......@@ -81,6 +81,7 @@
</Compile>
<Compile Include="DesignerAttributes\CSharpDesignerAttributeService.cs" />
<Compile Include="Completion\CompletionProviders\DeclarationNameCompletionProvider.cs" />
<Compile Include="DocumentHighlighting\CSharpDocumentHighlightsService.cs" />
<Compile Include="ImplementAbstractClass\CSharpImplementAbstractClassCodeFixProvider.cs" />
<Compile Include="ImplementInterface\CSharpImplementInterfaceCodeFixProvider.cs" />
<Compile Include="InitializeParameter\CSharpAddParameterCheckCodeRefactoringProvider.cs" />
......@@ -95,6 +96,7 @@
<Compile Include="UpgradeProject\CSharpUpgradeProjectCodeFixProvider.cs" />
<Compile Include="UseCoalesceExpression\CSharpUseCoalesceExpressionForNullableDiagnosticAnalyzer.cs" />
<Compile Include="UseCoalesceExpression\CSharpUseCoalesceExpressionDiagnosticAnalyzer.cs" />
<Compile Include="UseDefaultLiteral\CSharpUseDefaultLiteralCodeFixProvider.cs" />
<Compile Include="UseExpressionBody\Helpers\UseExpressionBodyHelper.cs" />
<Compile Include="UseExpressionBody\UseExpressionBodyCodeRefactoringProvider.cs" />
<Compile Include="UseExpressionBody\UseExpressionBodyDiagnosticAnalyzer.cs" />
......@@ -109,6 +111,7 @@
<Compile Include="AddBraces\CSharpAddBracesDiagnosticAnalyzer.cs" />
<Compile Include="UseCollectionInitializer\CSharpUseCollectionInitializerCodeFixProvider.cs" />
<Compile Include="UseCollectionInitializer\CSharpUseCollectionInitializerDiagnosticAnalyzer.cs" />
<Compile Include="UseDefaultLiteral\CSharpUseDefaultLiteralDiagnosticAnalyzer.cs" />
<Compile Include="UseNullPropagation\CSharpUseNullPropagationCodeFixProvider.cs" />
<Compile Include="UseNullPropagation\CSharpUseNullPropagationDiagnosticAnalyzer.cs" />
<Compile Include="UseObjectInitializer\UseInitializerHelpers.cs" />
......
......@@ -19,11 +19,14 @@ private abstract class BaseAnalyzer<TSyntax, TSyntaxList> : Analyzer<TSyntax, TS
where TSyntax : SyntaxNode
where TSyntaxList : SyntaxNode
{
protected override SyntaxNode GetReceiver(SyntaxNode argument)
protected sealed override SyntaxNode GetReceiver(SyntaxNode argument)
=> argument.Parent.Parent;
protected override bool IsLegalToAddNamedArguments(ImmutableArray<IParameterSymbol> parameters, int argumentCount)
protected sealed override bool IsLegalToAddNamedArguments(ImmutableArray<IParameterSymbol> parameters, int argumentCount)
=> !parameters.Last().IsParams || parameters.Length >= argumentCount;
protected sealed override bool IsCloseParenOrComma(SyntaxToken token)
=> token.IsKind(SyntaxKind.CloseParenToken, SyntaxKind.CommaToken);
}
private class ArgumentAnalyzer :
......
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting;
using Microsoft.CodeAnalysis.DocumentHighlighting;
using Microsoft.CodeAnalysis.Host.Mef;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.CSharp.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.CSharp.DocumentHighlighting
{
[ExportLanguageService(typeof(IReferenceHighlightingAdditionalReferenceProvider), LanguageNames.CSharp), Shared]
internal class ReferenceHighlightingAdditionalReferenceProvider : IReferenceHighlightingAdditionalReferenceProvider
[ExportLanguageService(typeof(IDocumentHighlightsService), LanguageNames.CSharp), Shared]
internal class CSharpDocumentHighlightsService : AbstractDocumentHighlightsService
{
public async Task<IEnumerable<Location>> GetAdditionalReferencesAsync(
protected override async Task<ImmutableArray<Location>> GetAdditionalReferencesAsync(
Document document, ISymbol symbol, CancellationToken cancellationToken)
{
// The FindRefs engine won't find references through 'var' for performance reasons.
// Also, they are not needed for things like rename/sig change, and the normal find refs
// feature. However, we would lke the results to be highlighted to get a good experience
// feature. However, we would like the results to be highlighted to get a good experience
// while editing (especially since highlighting may have been invoked off of 'var' in
// the first place).
//
// So we look for the references through 'var' directly in this file and add them to the
// results found by the engine.
List<Location> results = null;
var results = ArrayBuilder<Location>.GetInstance();
if (symbol is INamedTypeSymbol && symbol.Name != "var")
{
......@@ -52,18 +51,13 @@ internal class ReferenceHighlightingAdditionalReferenceProvider : IReferenceHigh
if (originalSymbol.Equals(boundSymbol))
{
if (results == null)
{
results = new List<Location>();
}
results.Add(type.GetLocation());
}
}
}
}
return results ?? SpecializedCollections.EmptyEnumerable<Location>();
return results.ToImmutableAndFree();
}
}
}
}
\ No newline at end of file
......@@ -681,6 +681,10 @@ protected override bool TryComputeWeightedDistance(SyntaxNode leftNode, SyntaxNo
distance = (leftNode.RawKind == rightNode.RawKind) ? 0.0 : 0.1;
return true;
case SyntaxKind.SingleVariableDesignation:
distance = ComputeWeightedDistance((SingleVariableDesignationSyntax)leftNode, (SingleVariableDesignationSyntax)rightNode);
return true;
default:
distance = 0;
return false;
......@@ -837,6 +841,25 @@ private bool TryComputeWeightedDistance(BlockSyntax leftBlock, BlockSyntax right
}
}
private double ComputeWeightedDistance(SingleVariableDesignationSyntax leftNode, SingleVariableDesignationSyntax rightNode)
{
double distance = ComputeDistance(leftNode, rightNode);
double parentDistance;
if (leftNode.Parent != null &&
rightNode.Parent != null &&
GetLabel(leftNode.Parent) == GetLabel(rightNode.Parent))
{
parentDistance = ComputeDistance(leftNode.Parent, rightNode.Parent);
}
else
{
parentDistance = 1;
}
return 0.5 * parentDistance + 0.5 * distance;
}
private static double ComputeWeightedBlockDistance(BlockSyntax leftBlock, BlockSyntax rightBlock)
{
if (TryComputeLocalsDistance(leftBlock, rightBlock, out var distance))
......
......@@ -21,19 +21,10 @@ internal class CSharpGenerateConstructorService : AbstractGenerateConstructorSer
private static readonly SyntaxAnnotation s_annotation = new SyntaxAnnotation();
protected override bool IsSimpleNameGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken)
{
return node is SimpleNameSyntax;
}
=> node is SimpleNameSyntax;
protected override bool IsConstructorInitializerGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken)
{
return node is ConstructorInitializerSyntax;
}
protected override bool IsClassDeclarationGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken)
{
return node is ClassDeclarationSyntax;
}
=> node is ConstructorInitializerSyntax;
protected override bool TryInitializeConstructorInitializerGeneration(
SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken,
......@@ -60,35 +51,6 @@ protected override bool IsClassDeclarationGeneration(SemanticDocument document,
return false;
}
protected override bool TryInitializeClassDeclarationGenerationState(
SemanticDocument document,
SyntaxNode node,
CancellationToken cancellationToken,
out SyntaxToken token,
out IMethodSymbol delegatedConstructor,
out INamedTypeSymbol typeToGenerateIn)
{
token = default(SyntaxToken);
typeToGenerateIn = null;
delegatedConstructor = null;
var semanticModel = document.SemanticModel;
var classDeclaration = (ClassDeclarationSyntax)node;
var classSymbol = semanticModel.GetDeclaredSymbol(classDeclaration, cancellationToken);
var baseType = classSymbol.BaseType;
var constructor = baseType.Constructors.FirstOrDefault(c => IsSymbolAccessible(c, document));
if (constructor == null)
{
return false;
}
typeToGenerateIn = classSymbol;
delegatedConstructor = constructor;
token = classDeclaration.Identifier;
return true;
}
protected override bool TryInitializeSimpleNameGenerationState(
SemanticDocument document,
SyntaxNode node,
......
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Threading;
......@@ -12,7 +11,6 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.GenerateMember.GenerateConstructor;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.GenerateConstructor
{
......@@ -31,6 +29,18 @@ internal static class GenerateConstructorDiagnosticIds
ImmutableArray.Create(CS1729);
}
/// <summary>
/// This <see cref="CodeFixProvider"/> gives users a way to generate constructors for an existing
/// type when a user tries to 'new' up an instance of that type with a set of parameter that does
/// not match any existing constructor. i.e. it is the equivalent of 'Generate-Method' but for
/// constructors. Parameters for the constructor will be picked in a manner similar to Generate-
/// Method. However, this type will also attempt to hook up those parameters to existing fields
/// and properties, or pass them to a this/base constructor if available.
///
/// Importantly, this type is not responsible for generating constructors for a type based on
/// the user selecting some fields/properties of that type. Nor is it responsible for generating
/// derived class constructors for all unmatched base class constructors in a type hierarchy.
/// </summary>
[ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.GenerateConstructor), Shared]
[ExtensionOrder(After = PredefinedCodeFixProviderNames.FullyQualify)]
internal class GenerateConstructorCodeFixProvider : AbstractGenerateMemberCodeFixProvider
......@@ -46,43 +56,22 @@ internal class GenerateConstructorCodeFixProvider : AbstractGenerateMemberCodeFi
protected override bool IsCandidate(SyntaxNode node, SyntaxToken token, Diagnostic diagnostic)
{
if (node is ObjectCreationExpressionSyntax ||
node is ConstructorInitializerSyntax ||
node is AttributeSyntax)
{
return true;
}
return diagnostic.Id == GenerateConstructorDiagnosticIds.CS7036 &&
node is ClassDeclarationSyntax &&
IsInClassDeclarationHeader((ClassDeclarationSyntax)node, token);
}
private bool IsInClassDeclarationHeader(ClassDeclarationSyntax node, SyntaxToken token)
{
var start = node.SpanStart;
var end = node.BaseList != null
? node.BaseList.Span.End
: node.Identifier.Span.End;
return TextSpan.FromBounds(start, end).Contains(token.Span);
return node is ObjectCreationExpressionSyntax ||
node is ConstructorInitializerSyntax ||
node is AttributeSyntax;
}
protected override SyntaxNode GetTargetNode(SyntaxNode node)
{
var objectCreationNode = node as ObjectCreationExpressionSyntax;
if (objectCreationNode != null)
{
return objectCreationNode.Type.GetRightmostName();
}
var attributeNode = node as AttributeSyntax;
if (attributeNode != null)
switch (node)
{
return attributeNode.Name;
case ObjectCreationExpressionSyntax objectCreationNode:
return objectCreationNode.Type.GetRightmostName();
case AttributeSyntax attributeNode:
return attributeNode.Name;
}
return node;
}
}
}
}
\ No newline at end of file
......@@ -4,8 +4,10 @@
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.GenerateFromMembers;
using Microsoft.CodeAnalysis.GenerateMember.GenerateDefaultConstructors;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
......@@ -16,33 +18,41 @@ internal class CSharpGenerateDefaultConstructorsService : AbstractGenerateDefaul
{
protected override bool TryInitializeState(
SemanticDocument document, TextSpan textSpan, CancellationToken cancellationToken,
out SyntaxNode baseTypeNode, out INamedTypeSymbol classType)
out INamedTypeSymbol classOrStructType)
{
if (!cancellationToken.IsCancellationRequested)
cancellationToken.ThrowIfCancellationRequested();
// Offer the feature if we're on the header for the class/struct, or if we're on the
// first base-type of a class.
var syntaxFacts = document.Document.GetLanguageService<ISyntaxFactsService>();
if (syntaxFacts.IsOnTypeHeader(document.Root, textSpan.Start))
{
classOrStructType = AbstractGenerateFromMembersCodeRefactoringProvider.GetEnclosingNamedType(
document.SemanticModel, document.Root, textSpan.Start, cancellationToken);
return classOrStructType != null;
}
var syntaxTree = document.SyntaxTree;
var node = document.Root.FindToken(textSpan.Start).GetAncestor<TypeSyntax>();
if (node != null)
{
var syntaxTree = document.SyntaxTree;
var node = document.Root.FindToken(textSpan.Start).GetAncestor<TypeSyntax>();
if (node != null)
if (node.Parent is BaseTypeSyntax && node.Parent.IsParentKind(SyntaxKind.BaseList))
{
if (node.Parent is BaseTypeSyntax && node.Parent.IsParentKind(SyntaxKind.BaseList))
var baseList = (BaseListSyntax)node.Parent.Parent;
if (baseList.Types.Count > 0 &&
baseList.Types[0].Type == node &&
baseList.IsParentKind(SyntaxKind.ClassDeclaration))
{
var baseList = (BaseListSyntax)node.Parent.Parent;
if (baseList.Types.Count > 0 &&
baseList.Types[0].Type == node &&
baseList.IsParentKind(SyntaxKind.ClassDeclaration))
{
var semanticModel = document.SemanticModel;
classType = semanticModel.GetDeclaredSymbol(baseList.Parent, cancellationToken) as INamedTypeSymbol;
baseTypeNode = node;
return classType != null;
}
var semanticModel = document.SemanticModel;
classOrStructType = semanticModel.GetDeclaredSymbol(baseList.Parent, cancellationToken) as INamedTypeSymbol;
return classOrStructType != null;
}
}
}
baseTypeNode = null;
classType = null;
classOrStructType = null;
return false;
}
}
}
}
\ No newline at end of file
......@@ -73,7 +73,8 @@ protected override ImmutableArray<AbstractReducer> GetReducers()
=> ImmutableArray.Create<AbstractReducer>(
new CSharpNameReducer(),
new CSharpEscapingReducer(),
new CSharpParenthesesReducer());
new CSharpParenthesesReducer(),
new CSharpDefaultExpressionReducer());
private class FormattingRule : AbstractFormattingRule
{
......
// 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.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UseDefaultLiteral
{
[ExportCodeFixProvider(LanguageNames.CSharp), Shared]
internal partial class CSharpUseDefaultLiteralCodeFixProvider : SyntaxEditorBasedCodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; }
= ImmutableArray.Create(IDEDiagnosticIds.UseDefaultLiteralDiagnosticId);
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
context.RegisterCodeFix(new MyCodeAction(
c => FixAsync(context.Document, context.Diagnostics.First(), c)),
context.Diagnostics);
return SpecializedTasks.EmptyTask;
}
protected override async Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
// Fix-All for this feature is somewhat complicated. Each time we fix one case, it
// may make the next case unfixable. For example:
//
// 'var v = x ? default(string) : default(string)'.
//
// Here, we can replace either of the default expressions, but not both. So we have
// to replace one at a time, and only actually replace if it's still safe to do so.
var parseOptions = (CSharpParseOptions)document.Project.ParseOptions;
var options = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false);
var workspace = document.Project.Solution.Workspace;
var originalRoot = editor.OriginalRoot;
var originalNodes = diagnostics.SelectAsArray(
d => (DefaultExpressionSyntax)originalRoot.FindNode(d.Location.SourceSpan, getInnermostNodeForTie: true));
// We're going to be continually editing this tree. Track all the nodes we
// care about so we can find them across each edit.
document = document.WithSyntaxRoot(originalRoot.TrackNodes(originalNodes));
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var currentRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
foreach (var originalDefaultExpression in originalNodes)
{
var defaultExpression = currentRoot.GetCurrentNode(originalDefaultExpression);
if (defaultExpression.CanReplaceWithDefaultLiteral(parseOptions, options, semanticModel, cancellationToken))
{
var replacement = SyntaxFactory.LiteralExpression(SyntaxKind.DefaultLiteralExpression)
.WithTriviaFrom(defaultExpression);
document = document.WithSyntaxRoot(currentRoot.ReplaceNode(defaultExpression, replacement));
semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
currentRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
}
}
editor.ReplaceNode(originalRoot, currentRoot);
}
private class MyCodeAction : CodeAction.DocumentChangeAction
{
public MyCodeAction(Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Simplify_default_expression, createChangedDocument)
{
}
}
}
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.UseDefaultLiteral
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal class CSharpUseDefaultLiteralDiagnosticAnalyzer : AbstractCodeStyleDiagnosticAnalyzer
{
public CSharpUseDefaultLiteralDiagnosticAnalyzer()
: base(IDEDiagnosticIds.UseDefaultLiteralDiagnosticId,
new LocalizableResourceString(nameof(FeaturesResources.Simplify_default_expression), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.default_expression_can_be_simplified), FeaturesResources.ResourceManager, typeof(FeaturesResources)))
{
}
public override DiagnosticAnalyzerCategory GetAnalyzerCategory()
=> DiagnosticAnalyzerCategory.SemanticSpanAnalysis;
public override bool OpenFileOnly(Workspace workspace)
=> false;
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeSyntax, SyntaxKind.DefaultExpression);
private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
{
var cancellationToken = context.CancellationToken;
var syntaxTree = context.Node.SyntaxTree;
var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();
if (optionSet == null)
{
return;
}
var parseOptions = (CSharpParseOptions)syntaxTree.Options;
var defaultExpression = (DefaultExpressionSyntax)context.Node;
if (!defaultExpression.CanReplaceWithDefaultLiteral(parseOptions, optionSet, context.SemanticModel, cancellationToken))
{
return;
}
var fadeSpan = TextSpan.FromBounds(defaultExpression.OpenParenToken.SpanStart, defaultExpression.CloseParenToken.Span.End);
// Create a normal diagnostic that covers the entire default expression.
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression).Notification.Value),
defaultExpression.GetLocation()));
// Also fade out the part of the default expression from the open paren through
// the close paren.
context.ReportDiagnostic(
Diagnostic.Create(
UnnecessaryWithoutSuggestionDescriptor,
syntaxTree.GetLocation(fadeSpan)));
}
}
}
\ No newline at end of file
......@@ -4,8 +4,10 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Collections;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
......@@ -268,8 +270,60 @@ public Task<IEnumerable<ReferenceMethodDescriptor>> FindReferenceMethodsAsync(So
using (solution.Services.CacheService?.EnableCaching(document.Project.Id))
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var declaredSymbol = semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken);
return semanticModel.GetDeclaredSymbol(syntaxNode, cancellationToken)?.ToDisplayString(MethodDisplayFormat);
if (declaredSymbol == null)
{
return string.Empty;
}
var parts = declaredSymbol.ToDisplayParts(MethodDisplayFormat);
var pool = PooledStringBuilder.GetInstance();
try
{
var actualBuilder = pool.Builder;
var previousWasClass = false;
for (var index = 0; index < parts.Length; index++)
{
var part = parts[index];
if (previousWasClass &&
part.Kind == SymbolDisplayPartKind.Punctuation &&
index < parts.Length - 1)
{
switch (parts[index + 1].Kind)
{
case SymbolDisplayPartKind.ClassName:
case SymbolDisplayPartKind.DelegateName:
case SymbolDisplayPartKind.EnumName:
case SymbolDisplayPartKind.ErrorTypeName:
case SymbolDisplayPartKind.InterfaceName:
case SymbolDisplayPartKind.StructName:
actualBuilder.Append('+');
break;
default:
actualBuilder.Append(part);
break;
}
}
else
{
actualBuilder.Append(part);
}
previousWasClass = part.Kind == SymbolDisplayPartKind.ClassName ||
part.Kind == SymbolDisplayPartKind.InterfaceName ||
part.Kind == SymbolDisplayPartKind.StructName;
}
return actualBuilder.ToString();
}
finally
{
pool.Free();
}
}
}
}
......
......@@ -34,7 +34,19 @@ protected abstract class Analyzer<TBaseArgumentSyntax, TArgumentSyntax, TArgumen
return;
}
var argument = root.FindNode(context.Span).FirstAncestorOrSelf<TBaseArgumentSyntax>() as TArgumentSyntax;
var position = context.Span.Start;
var token = root.FindToken(position);
if (token.Span.Start == position &&
IsCloseParenOrComma(token))
{
token = token.GetPreviousToken();
if (token.Span.End != position)
{
return;
}
}
var argument = root.FindNode(token.Span).FirstAncestorOrSelfUntil<TBaseArgumentSyntax>(node => node is TArgumentListSyntax) as TArgumentSyntax;
if (argument == null)
{
return;
......@@ -51,7 +63,7 @@ protected abstract class Analyzer<TBaseArgumentSyntax, TArgumentSyntax, TArgumen
var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
var argumentStartLine = sourceText.Lines.GetLineFromPosition(argument.Span.Start).LineNumber;
var caretLine = sourceText.Lines.GetLineFromPosition(context.Span.Start).LineNumber;
var caretLine = sourceText.Lines.GetLineFromPosition(position).LineNumber;
if (argumentStartLine != caretLine)
{
......@@ -141,6 +153,7 @@ protected abstract class Analyzer<TBaseArgumentSyntax, TArgumentSyntax, TArgumen
protected abstract TArgumentListSyntax WithArguments(
TArgumentListSyntax argumentList, IEnumerable<TBaseArgumentSyntax> namedArguments, IEnumerable<SyntaxToken> separators);
protected abstract bool IsCloseParenOrComma(SyntaxToken token);
protected abstract bool IsLegalToAddNamedArguments(ImmutableArray<IParameterSymbol> parameters, int argumentCount);
protected abstract TArgumentSyntax WithName(TArgumentSyntax argument, string name);
protected abstract bool IsPositionalArgument(TArgumentSyntax argument);
......
......@@ -44,6 +44,8 @@ internal static class IDEDiagnosticIds
public const string UseExplicitTupleNameDiagnosticId = "IDE0033";
public const string UseDefaultLiteralDiagnosticId = "IDE0034";
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
public const string AnalyzerDependencyConflictId = "IDE1002";
......
......@@ -14,12 +14,47 @@
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
namespace Microsoft.CodeAnalysis.DocumentHighlighting
{
internal abstract class AbstractDocumentHighlightsService : IDocumentHighlightsService
internal abstract partial class AbstractDocumentHighlightsService : IDocumentHighlightsService
{
public async Task<ImmutableArray<DocumentHighlights>> GetDocumentHighlightsAsync(
Document document, int position, IImmutableSet<Document> documentsToSearch, CancellationToken cancellationToken)
{
var (succeeded, highlights) = await GetDocumentHighlightsInRemoteProcessAsync(
document, position, documentsToSearch, cancellationToken).ConfigureAwait(false);
if (succeeded)
{
return highlights;
}
return await GetDocumentHighlightsInCurrentProcessAsync(
document, position, documentsToSearch, cancellationToken).ConfigureAwait(false);
}
private async Task<(bool succeeded, ImmutableArray<DocumentHighlights> highlights)> GetDocumentHighlightsInRemoteProcessAsync(
Document document, int position, IImmutableSet<Document> documentsToSearch, CancellationToken cancellationToken)
{
using (var session = await TryGetRemoteSessionAsync(
document.Project.Solution, cancellationToken).ConfigureAwait(false))
{
if (session == null)
{
return (succeeded: false, ImmutableArray<DocumentHighlights>.Empty);
}
var result = await session.InvokeAsync<SerializableDocumentHighlights[]>(
nameof(IRemoteDocumentHighlights.GetDocumentHighlightsAsync),
document.Id,
position,
documentsToSearch.Select(d => d.Id).ToArray()).ConfigureAwait(false);
return (true, SerializableDocumentHighlights.Rehydrate(result, document.Project.Solution));
}
}
private async Task<ImmutableArray<DocumentHighlights>> GetDocumentHighlightsInCurrentProcessAsync(
Document document, int position, IImmutableSet<Document> documentsToSearch, CancellationToken cancellationToken)
{
// use speculative semantic model to see whether we are on a symbol we can do HR
var span = new TextSpan(position, 0);
......@@ -41,11 +76,11 @@ internal abstract class AbstractDocumentHighlightsService : IDocumentHighlightsS
// Get unique tags for referenced symbols
return await GetTagsForReferencedSymbolAsync(
new SymbolAndProjectId(symbol, document.Project.Id), documentsToSearch,
new SymbolAndProjectId(symbol, document.Project.Id), documentsToSearch,
solution, cancellationToken).ConfigureAwait(false);
}
private async Task<ISymbol> GetSymbolToSearchAsync(Document document, int position, SemanticModel semanticModel, ISymbol symbol, CancellationToken cancellationToken)
private static async Task<ISymbol> GetSymbolToSearchAsync(Document document, int position, SemanticModel semanticModel, ISymbol symbol, CancellationToken cancellationToken)
{
// see whether we can use the symbol as it is
var currentSemanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
......@@ -82,7 +117,7 @@ private async Task<ISymbol> GetSymbolToSearchAsync(Document document, int positi
return ImmutableArray<DocumentHighlights>.Empty;
}
private bool ShouldConsiderSymbol(ISymbol symbol)
private static bool ShouldConsiderSymbol(ISymbol symbol)
{
switch (symbol.Kind)
{
......@@ -132,19 +167,13 @@ private bool ShouldConsiderSymbol(ISymbol symbol)
documentsToSearch, cancellationToken).ConfigureAwait(false);
}
private Task<IEnumerable<Location>> GetAdditionalReferencesAsync(
protected virtual Task<ImmutableArray<Location>> GetAdditionalReferencesAsync(
Document document, ISymbol symbol, CancellationToken cancellationToken)
{
var additionalReferenceProvider = document.Project.LanguageServices.GetService<IReferenceHighlightingAdditionalReferenceProvider>();
if (additionalReferenceProvider != null)
{
return additionalReferenceProvider.GetAdditionalReferencesAsync(document, symbol, cancellationToken);
}
return Task.FromResult(SpecializedCollections.EmptyEnumerable<Location>());
return SpecializedTasks.EmptyImmutableArray<Location>();
}
private async Task<ImmutableArray<DocumentHighlights>> CreateSpansAsync(
private static async Task<ImmutableArray<DocumentHighlights>> CreateSpansAsync(
Solution solution,
ISymbol symbol,
IEnumerable<ReferencedSymbol> references,
......@@ -252,7 +281,7 @@ private static bool ShouldIncludeDefinition(ISymbol symbol)
return true;
}
private async Task AddLocationSpan(Location location, Solution solution, HashSet<DocumentSpan> spanSet, MultiDictionary<Document, HighlightSpan> tagList, HighlightSpanKind kind, CancellationToken cancellationToken)
private static async Task AddLocationSpan(Location location, Solution solution, HashSet<DocumentSpan> spanSet, MultiDictionary<Document, HighlightSpan> tagList, HighlightSpanKind kind, CancellationToken cancellationToken)
{
var span = await GetLocationSpanAsync(solution, location, cancellationToken).ConfigureAwait(false);
if (span != null && !spanSet.Contains(span.Value))
......@@ -262,7 +291,7 @@ private async Task AddLocationSpan(Location location, Solution solution, HashSet
}
}
private async Task<DocumentSpan?> GetLocationSpanAsync(
private static async Task<DocumentSpan?> GetLocationSpanAsync(
Solution solution, Location location, CancellationToken cancellationToken)
{
try
......
// 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.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Remote;
namespace Microsoft.CodeAnalysis.DocumentHighlighting
{
internal abstract partial class AbstractDocumentHighlightsService : IDocumentHighlightsService
{
private static async Task<RemoteHostClient.Session> TryGetRemoteSessionAsync(
Solution solution, CancellationToken cancellationToken)
{
var outOfProcessAllowed = solution.Workspace.Options.GetOption(DocumentHighlightingOptions.OutOfProcessAllowed);
if (!outOfProcessAllowed)
{
return null;
}
var client = await solution.Workspace.TryGetRemoteHostClientAsync(cancellationToken).ConfigureAwait(false);
if (client == null)
{
return null;
}
return await client.TryCreateCodeAnalysisServiceSessionAsync(
solution, cancellationToken).ConfigureAwait(false);
}
}
}
\ No newline at end of file
// 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 Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.DocumentHighlighting
{
internal static class DocumentHighlightingOptions
{
private const string LocalRegistryPath = @"Roslyn\Features\DocumentHighlighting\";
public static readonly Option<bool> OutOfProcessAllowed = new Option<bool>(
nameof(DocumentHighlightingOptions), nameof(OutOfProcessAllowed), defaultValue: false,
storageLocations: new LocalUserProfileStorageLocation(LocalRegistryPath + nameof(OutOfProcessAllowed)));
}
}
\ No newline at end of file
// 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.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.DocumentHighlighting
{
internal enum HighlightSpanKind
{
None,
Definition,
Reference,
WrittenReference,
}
internal struct HighlightSpan
{
public TextSpan TextSpan { get; }
public HighlightSpanKind Kind { get; }
public HighlightSpan(TextSpan textSpan, HighlightSpanKind kind) : this()
{
this.TextSpan = textSpan;
this.Kind = kind;
}
}
internal struct DocumentHighlights
{
public Document Document { get; }
public ImmutableArray<HighlightSpan> HighlightSpans { get; }
public DocumentHighlights(Document document, ImmutableArray<HighlightSpan> highlightSpans)
{
this.Document = document;
this.HighlightSpans = highlightSpans;
}
}
/// <summary>
/// Note: This is the new version of the language service and superceded the same named type
/// in the EditorFeatures layer.
/// </summary>
internal interface IDocumentHighlightsService : ILanguageService
{
Task<ImmutableArray<DocumentHighlights>> GetDocumentHighlightsAsync(
Document document, int position, IImmutableSet<Document> documentsToSearch, CancellationToken cancellationToken);
}
}
\ No newline at end of file
// 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.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.DocumentHighlighting
{
internal interface IRemoteDocumentHighlights
{
Task<SerializableDocumentHighlights[]> GetDocumentHighlightsAsync(
DocumentId documentId, int position, DocumentId[] documentIdsToSearch);
}
internal struct SerializableDocumentHighlights
{
public DocumentId DocumentId;
public SerializableHighlightSpan[] HighlightSpans;
public static ImmutableArray<DocumentHighlights> Rehydrate(SerializableDocumentHighlights[] array, Solution solution)
{
var result = ArrayBuilder<DocumentHighlights>.GetInstance(array.Length);
foreach (var dehydrated in array)
{
result.Push(dehydrated.Rehydrate(solution));
}
return result.ToImmutableAndFree();
}
private DocumentHighlights Rehydrate(Solution solution)
=> new DocumentHighlights(solution.GetDocument(DocumentId), SerializableHighlightSpan.Rehydrate(HighlightSpans));
public static SerializableDocumentHighlights[] Dehydrate(ImmutableArray<DocumentHighlights> array)
{
var result = new SerializableDocumentHighlights[array.Length];
var index = 0;
foreach (var highlights in array)
{
result[index] = Dehydrate(highlights);
index++;
}
return result;
}
private static SerializableDocumentHighlights Dehydrate(DocumentHighlights highlights)
=> new SerializableDocumentHighlights
{
DocumentId = highlights.Document.Id,
HighlightSpans = SerializableHighlightSpan.Dehydrate(highlights.HighlightSpans)
};
}
internal struct SerializableHighlightSpan
{
public TextSpan TextSpan;
public HighlightSpanKind Kind;
internal static SerializableHighlightSpan[] Dehydrate(ImmutableArray<HighlightSpan> array)
{
var result = new SerializableHighlightSpan[array.Length];
var index = 0;
foreach (var span in array)
{
result[index] = Dehydrate(span);
index++;
}
return result;
}
private static SerializableHighlightSpan Dehydrate(HighlightSpan span)
=> new SerializableHighlightSpan
{
Kind = span.Kind,
TextSpan = span.TextSpan
};
internal static ImmutableArray<HighlightSpan> Rehydrate(SerializableHighlightSpan[] array)
{
var result = ArrayBuilder<HighlightSpan>.GetInstance(array.Length);
foreach (var dehydrated in array)
{
result.Push(dehydrated.Rehydrate());
}
return result.ToImmutableAndFree();
}
private HighlightSpan Rehydrate()
=> new HighlightSpan(TextSpan, Kind);
}
}
\ No newline at end of file
......@@ -132,6 +132,7 @@
<Compile Include="Diagnostics\DiagnosticArguments.cs" />
<Compile Include="Diagnostics\DiagnosticResultSerializer.cs" />
<Compile Include="Diagnostics\SymbolAnalysisContextExtensions.cs" />
<Compile Include="DocumentHighlighting\DocumentHighlightingOptions.cs" />
<Compile Include="EncapsulateField\EncapsulateFieldRefactoringProvider.cs" />
<Compile Include="ExtractInterface\ExtractInterfaceCodeRefactoringProvider.cs" />
<Compile Include="CodeFixes\FixAllOccurrences\FixSomeCodeAction.cs" />
......@@ -157,6 +158,10 @@
<Compile Include="GenerateFromMembers\SelectedMemberInfo.cs" />
<Compile Include="ImplementType\ImplementTypeOptions.cs" />
<Compile Include="ImplementType\ImplementTypeOptionsProvider.cs" />
<Compile Include="DocumentHighlighting\AbstractDocumentHighlightsService.cs" />
<Compile Include="DocumentHighlighting\AbstractDocumentHighlightsService_Remote.cs" />
<Compile Include="DocumentHighlighting\IDocumentHighlightsService.cs" />
<Compile Include="DocumentHighlighting\IRemoteDocumentHighlights.cs" />
<Compile Include="RemoveUnnecessaryImports\AbstractRemoveUnnecessaryImportsCodeFixProvider.cs" />
<Compile Include="RemoveUnnecessaryImports\IUnnecessaryImportsService.cs" />
<Compile Include="NavigateTo\AbstractNavigateToSearchService.SearchResult.cs" />
......@@ -323,7 +328,7 @@
<Compile Include="CodeRefactorings\CodeRefactoringService.cs" />
<Compile Include="ConvertToInterpolatedString\AbstractConvertPlaceholderToInterpolatedStringRefactoringProvider.cs" />
<Compile Include="CodeRefactorings\ExtractMethod\AbstractExtractMethodCodeRefactoringProvider.cs" />
<Compile Include="CodeRefactorings\GenerateDefaultConstructors\GenerateDefaultConstructorsCodeRefactoringProvider.cs" />
<Compile Include="GenerateDefaultConstructors\GenerateDefaultConstructorsCodeRefactoringProvider.cs" />
<Compile Include="AddConstructorParametersFromMembers\AddConstructorParametersFromMembersCodeRefactoringProvider.cs" />
<Compile Include="GenerateConstructorFromMembers\GenerateConstructorFromMembersCodeRefactoringProvider.cs" />
<Compile Include="GenerateEqualsAndGetHashCodeFromMembers\GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.cs" />
......
......@@ -20,7 +20,7 @@ namespace Microsoft.CodeAnalysis {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class FeaturesResources {
......@@ -863,6 +863,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;default&apos; expression can be simplified.
/// </summary>
internal static string default_expression_can_be_simplified {
get {
return ResourceManager.GetString("default_expression_can_be_simplified", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to delegate.
/// </summary>
......@@ -2664,6 +2673,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Simplify &apos;default&apos; expression.
/// </summary>
internal static string Simplify_default_expression {
get {
return ResourceManager.GetString("Simplify_default_expression", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Simplify Member Access.
/// </summary>
......
......@@ -1241,4 +1241,10 @@ This version used in: {2}</value>
<data name="Implement_0" xml:space="preserve">
<value>Implement {0}</value>
</data>
<data name="Simplify_default_expression" xml:space="preserve">
<value>Simplify 'default' expression</value>
</data>
<data name="default_expression_can_be_simplified" xml:space="preserve">
<value>'default' expression can be simplified</value>
</data>
</root>
\ No newline at end of file
......@@ -16,6 +16,18 @@
namespace Microsoft.CodeAnalysis.GenerateConstructorFromMembers
{
/// <summary>
/// This <see cref="CodeRefactoringProvider"/> is responsible for allowing a user to pick a
/// set of members from a class or struct, and then generate a constructor for that takes in
/// matching parameters and assigns them to those members. The members can be picked using
/// a actual selection in the editor, or they can be picked using a picker control that will
/// then display all the viable members and allow the user to pick which ones they want to
/// use.
///
/// Importantly, this type is not responsible for generating constructors when the user types
/// something like "new MyType(x, y, z)", nor is it responsible for generating constructors
/// in a derived type that delegate to a base type. Both of those are handled by other services.
/// </summary>
[ExportCodeRefactoringProvider(LanguageNames.CSharp, LanguageNames.VisualBasic,
Name = PredefinedCodeRefactoringProviderNames.GenerateConstructorFromMembers), Shared]
[ExtensionOrder(Before = PredefinedCodeRefactoringProviderNames.GenerateEqualsAndGetHashCodeFromMembers)]
......@@ -93,26 +105,10 @@ private async Task HandleNonSelectionAsync(CodeRefactoringContext context)
// Find all the possible writable instance fields/properties. If there are any, then
// show a dialog to the user to select the ones they want. Otherwise, if there are none
// just offer to generate the no-param constructor if they don't already have one.
// don't offer to generate anything.
var viableMembers = containingType.GetMembers().WhereAsArray(IsWritableInstanceFieldOrProperty);
if (viableMembers.Length == 0)
{
var noParamConstructor = containingType.InstanceConstructors.FirstOrDefault(c => c.Parameters.Length == 0);
if (noParamConstructor == null ||
noParamConstructor.IsImplicitlyDeclared)
{
// Offer to just make the no-param-constructor directly.
var state = State.TryGenerate(this, document, textSpan, containingType,
ImmutableArray<ISymbol>.Empty, cancellationToken);
if (state != null)
{
context.RegisterRefactoring(
new FieldDelegatingCodeAction(this, document, state, addNullChecks: false));
}
}
// already had an explicit, no-param constructor. No need to offer anything.
return;
}
......
......@@ -2,11 +2,24 @@
using System.Composition;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.GenerateMember.GenerateDefaultConstructors;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis.CodeRefactorings.GenerateDefaultConstructors
namespace Microsoft.CodeAnalysis.GenerateDefaultConstructors
{
/// <summary>
/// This <see cref="CodeRefactoringProvider"/> gives users a way to generate constructors for
/// a derived type that delegate to a base type. For all accessibly constructors in the base
/// type, the user will be offered to create a constructor in the derived type with the same
/// signature if they don't already have one. This way, a user can override a type and easily
/// create all the forwarding constructors.
///
/// Importantly, this type is not responsible for generating constructors when the user types
/// something like "new MyType(x, y, z)", nor is it responsible for generating constructors
/// for a type based on the fields/properties of that type. Both of those are handled by other
/// services.
/// </summary>
[ExportCodeRefactoringProvider(LanguageNames.CSharp, LanguageNames.VisualBasic,
Name = PredefinedCodeRefactoringProviderNames.GenerateDefaultConstructors), Shared]
internal class GenerateDefaultConstructorsCodeRefactoringProvider : CodeRefactoringProvider
......
......@@ -74,13 +74,6 @@ private State()
return false;
}
}
else if (service.IsClassDeclarationGeneration(document, node, cancellationToken))
{
if (!await TryInitializeClassDeclarationGenerationAsync(service, document, node, cancellationToken).ConfigureAwait(false))
{
return false;
}
}
else
{
return false;
......@@ -196,25 +189,6 @@ private ITypeSymbol FixType(ITypeSymbol typeSymbol, SemanticModel semanticModel,
return await TryDetermineTypeToGenerateInAsync(document, typeToGenerateIn, cancellationToken).ConfigureAwait(false);
}
private async Task<bool> TryInitializeClassDeclarationGenerationAsync(
TService service,
SemanticDocument document,
SyntaxNode simpleName,
CancellationToken cancellationToken)
{
if (service.TryInitializeClassDeclarationGenerationState(document, simpleName, cancellationToken,
out var token, out var constructor, out var typeToGenerateIn))
{
this.Token = token;
this.DelegatedConstructorOpt = constructor;
this.ParameterTypes = constructor.Parameters.Select(p => p.Type).ToImmutableArray();
this.ParameterRefKinds = constructor.Parameters.Select(p => p.RefKind).ToList();
}
cancellationToken.ThrowIfCancellationRequested();
return await TryDetermineTypeToGenerateInAsync(document, typeToGenerateIn, cancellationToken).ConfigureAwait(false);
}
private async Task<bool> TryInitializeSimpleNameGenerationAsync(
TService service,
SemanticDocument document,
......
......@@ -23,11 +23,9 @@ protected AbstractGenerateConstructorService()
}
protected abstract bool IsSimpleNameGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken);
protected abstract bool IsClassDeclarationGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken);
protected abstract bool IsConstructorInitializerGeneration(SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken);
protected abstract bool TryInitializeSimpleNameGenerationState(SemanticDocument document, SyntaxNode simpleName, CancellationToken cancellationToken, out SyntaxToken token, out ImmutableArray<TArgumentSyntax> arguments, out INamedTypeSymbol typeToGenerateIn);
protected abstract bool TryInitializeClassDeclarationGenerationState(SemanticDocument document, SyntaxNode classDeclaration, CancellationToken cancellationToken, out SyntaxToken token, out IMethodSymbol constructor, out INamedTypeSymbol typeToGenerateIn);
protected abstract bool TryInitializeConstructorInitializerGeneration(SemanticDocument document, SyntaxNode constructorInitializer, CancellationToken cancellationToken, out SyntaxToken token, out ImmutableArray<TArgumentSyntax> arguments, out INamedTypeSymbol typeToGenerateIn);
protected abstract bool TryInitializeSimpleAttributeNameGenerationState(SemanticDocument document, SyntaxNode simpleName, CancellationToken cancellationToken, out SyntaxToken token, out ImmutableArray<TArgumentSyntax> arguments, out ImmutableArray<TAttributeArgumentSyntax> attributeArguments, out INamedTypeSymbol typeToGenerateIn);
protected abstract ImmutableArray<ParameterName> GenerateParameterNames(SemanticModel semanticModel, IEnumerable<TArgumentSyntax> arguments, IList<string> reservedNames, CancellationToken cancellationToken);
......
......@@ -42,7 +42,7 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
{
var result = await CodeGenerator.AddMemberDeclarationsAsync(
_document.Project.Solution,
_state.ClassType,
_state.ClassOrStructType,
_constructors.Select(CreateConstructorDefinition),
cancellationToken: cancellationToken).ConfigureAwait(false);
......@@ -61,7 +61,7 @@ protected override async Task<Document> GetChangedDocumentAsync(CancellationToke
attributes: default(ImmutableArray<AttributeData>),
accessibility: constructor.DeclaredAccessibility,
modifiers: new DeclarationModifiers(),
typeName: _state.ClassType.Name,
typeName: _state.ClassOrStructType.Name,
parameters: constructor.Parameters,
statements: default(ImmutableArray<SyntaxNode>),
baseConstructorArguments: baseConstructorArguments);
......
......@@ -22,9 +22,9 @@ private static string GetDisplayText(State state, IMethodSymbol constructor)
var parameters = constructor.Parameters.Select(p => p.Name);
var parameterString = string.Join(", ", parameters);
return string.Format(FeaturesResources.Generate_constructor_0_1 + ".",
state.ClassType.Name, parameterString);
return string.Format(FeaturesResources.Generate_constructor_0_1,
state.ClassOrStructType.Name, parameterString);
}
}
}
}
}
\ No newline at end of file
// 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.Collections.Generic;
using System.Linq;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.GenerateMember.GenerateDefaultConstructors
{
......@@ -15,16 +13,9 @@ private class CodeActionAll : AbstractCodeAction
Document document,
State state,
IList<IMethodSymbol> constructors)
: base(service, document, state, GetConstructors(state, constructors), FeaturesResources.Generate_all)
: base(service, document, state, constructors, FeaturesResources.Generate_all)
{
}
private static IList<IMethodSymbol> GetConstructors(State state, IList<IMethodSymbol> constructors)
{
return state.UnimplementedDefaultConstructor != null
? new[] { state.UnimplementedDefaultConstructor }.Concat(constructors).ToList()
: constructors;
}
}
}
}
}
\ No newline at end of file
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Shared.Utilities;
......@@ -15,12 +14,9 @@ internal abstract partial class AbstractGenerateDefaultConstructorsService<TServ
{
private class State
{
public INamedTypeSymbol ClassType { get; private set; }
public INamedTypeSymbol ClassOrStructType { get; private set; }
public IList<IMethodSymbol> UnimplementedConstructors { get; private set; }
public IMethodSymbol UnimplementedDefaultConstructor { get; private set; }
public SyntaxNode BaseTypeNode { get; private set; }
public ImmutableArray<IMethodSymbol> UnimplementedConstructors { get; private set; }
private State()
{
......@@ -47,56 +43,54 @@ private State()
TextSpan textSpan,
CancellationToken cancellationToken)
{
if (!service.TryInitializeState(document, textSpan, cancellationToken, out var baseTypeNode, out var classType))
{
return false;
}
if (!baseTypeNode.Span.IntersectsWith(textSpan.Start))
if (!service.TryInitializeState(document, textSpan, cancellationToken, out var classOrStructType))
{
return false;
}
this.BaseTypeNode = baseTypeNode;
this.ClassType = classType;
var baseType = this.ClassType.BaseType;
this.ClassOrStructType = classOrStructType;
if (this.ClassType.TypeKind != TypeKind.Class ||
this.ClassType.IsStatic ||
var baseType = this.ClassOrStructType.BaseType;
if (this.ClassOrStructType.IsStatic ||
baseType == null ||
baseType.SpecialType == SpecialType.System_Object ||
baseType.TypeKind == TypeKind.Error)
{
return false;
}
var semanticFacts = document.Project.LanguageServices.GetService<ISemanticFactsService>();
var classConstructors = this.ClassType.InstanceConstructors;
var baseTypeConstructors =
baseType.InstanceConstructors
.Where(c => c.IsAccessibleWithin(this.ClassType));
var classConstructors = this.ClassOrStructType.InstanceConstructors;
var destinationProvider = document.Project.Solution.Workspace.Services.GetLanguageServices(this.ClassType.Language);
var destinationProvider = document.Project.Solution.Workspace.Services.GetLanguageServices(this.ClassOrStructType.Language);
var syntaxFacts = destinationProvider.GetService<ISyntaxFactsService>();
var isCaseSensitive = syntaxFacts.IsCaseSensitive;
var missingConstructors =
baseTypeConstructors.Where(c1 => !classConstructors.Any(
c2 => SignatureComparer.Instance.HaveSameSignature(c1.Parameters, c2.Parameters, compareParameterName: true, isCaseSensitive: syntaxFacts.IsCaseSensitive))).ToList();
this.UnimplementedConstructors =
baseType.InstanceConstructors
.WhereAsArray(c => c.IsAccessibleWithin(this.ClassOrStructType) &&
IsMissing(c, classConstructors, isCaseSensitive));
this.UnimplementedConstructors = missingConstructors;
return this.UnimplementedConstructors.Length > 0;
}
private bool IsMissing(
IMethodSymbol constructor,
ImmutableArray<IMethodSymbol> classConstructors,
bool isCaseSensitive)
{
var matchingConstructor = classConstructors.FirstOrDefault(
c => SignatureComparer.Instance.HaveSameSignature(
constructor.Parameters, c.Parameters, compareParameterName: true, isCaseSensitive: isCaseSensitive));
this.UnimplementedDefaultConstructor = baseTypeConstructors.FirstOrDefault(c => c.Parameters.Length == 0);
if (this.UnimplementedDefaultConstructor != null)
if (matchingConstructor == null)
{
if (classConstructors.Any(c => c.Parameters.Length == 0 && !c.IsImplicitlyDeclared))
{
this.UnimplementedDefaultConstructor = null;
}
return true;
}
return this.UnimplementedConstructors.Count > 0;
// We have a matching constructor in this type. But we'll still offer to create the
// constructor if the constructor that we have is implicit.
return matchingConstructor.IsImplicitlyDeclared;
}
}
}
}
}
\ No newline at end of file
// 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.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
......@@ -17,7 +16,7 @@ protected AbstractGenerateDefaultConstructorsService()
{
}
protected abstract bool TryInitializeState(SemanticDocument document, TextSpan textSpan, CancellationToken cancellationToken, out SyntaxNode baseTypeNode, out INamedTypeSymbol classType);
protected abstract bool TryInitializeState(SemanticDocument document, TextSpan textSpan, CancellationToken cancellationToken, out INamedTypeSymbol classOrStructType);
public async Task<ImmutableArray<CodeAction>> GenerateDefaultConstructorsAsync(
Document document,
......@@ -28,30 +27,26 @@ protected AbstractGenerateDefaultConstructorsService()
{
var semanticDocument = await SemanticDocument.CreateAsync(document, cancellationToken).ConfigureAwait(false);
var result = ArrayBuilder<CodeAction>.GetInstance();
if (textSpan.IsEmpty)
{
var state = State.Generate((TService)this, semanticDocument, textSpan, cancellationToken);
if (state != null)
{
return GetActions(document, state).AsImmutableOrNull();
foreach (var constructor in state.UnimplementedConstructors)
{
result.Add(new GenerateDefaultConstructorCodeAction((TService)this, document, state, constructor));
}
if (state.UnimplementedConstructors.Length > 1)
{
result.Add(new CodeActionAll((TService)this, document, state, state.UnimplementedConstructors));
}
}
}
return default(ImmutableArray<CodeAction>);
}
}
private IEnumerable<CodeAction> GetActions(Document document, State state)
{
foreach (var constructor in state.UnimplementedConstructors)
{
yield return new GenerateDefaultConstructorCodeAction((TService)this, document, state, constructor);
}
if (state.UnimplementedConstructors.Count > 1)
{
yield return new CodeActionAll((TService)this, document, state, state.UnimplementedConstructors);
return result.ToImmutableAndFree();
}
}
}
}
}
\ No newline at end of file
......@@ -66,6 +66,7 @@
<Link>InternalUtilities\LambdaUtilities.vb</Link>
</Compile>
<Compile Include="AddPackage\VisualBasicAddSpecificPackageCodeFixProvider.vb" />
<Compile Include="DocumentHighlighting\VisualBasicDocumentHighlightsService.vb" />
<Compile Include="InitializeParameter\InitializeParameterHelpers.vb" />
<Compile Include="InitializeParameter\VisualBasicAddParameterCheckCodeRefactoringProvider.vb" />
<Compile Include="ChangeSignature\ChangeSignatureFormattingRule.vb" />
......
......@@ -43,6 +43,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.UseNamedArguments
Protected Overrides Function IsLegalToAddNamedArguments(parameters As ImmutableArray(Of IParameterSymbol), argumentCount As Integer) As Boolean
Return Not parameters.LastOrDefault().IsParams OrElse parameters.Length > argumentCount
End Function
Protected Overrides Function IsCloseParenOrComma(token As SyntaxToken) As Boolean
Return token.IsKind(SyntaxKind.CloseParenToken, SyntaxKind.CommaToken)
End Function
End Class
Public Sub New()
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Composition
Imports Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
Imports Microsoft.CodeAnalysis.DocumentHighlighting
Imports Microsoft.CodeAnalysis.Host.Mef
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.HighlightReferences
Namespace Microsoft.CodeAnalysis.VisualBasic.DocumentHighlighting
<ExportLanguageService(GetType(IDocumentHighlightsService), LanguageNames.VisualBasic), [Shared]>
Friend Class VisualBasicDocumentHighlightsService
Inherits AbstractDocumentHighlightsService
End Class
End Namespace
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Threading
Imports System.Collections.Immutable
Imports System.Composition
Imports System.Threading
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.CodeFixes.GenerateMember
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.GenerateMember.GenerateConstructor
Imports System.Composition
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor
Friend Class GenerateConstructorDiagnosticIds
......@@ -60,19 +60,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor
End Function
Protected Overrides Function IsCandidate(node As SyntaxNode, token As SyntaxToken, diagnostic As Diagnostic) As Boolean
If TypeOf node Is InvocationExpressionSyntax OrElse
TypeOf node Is ObjectCreationExpressionSyntax OrElse
TypeOf node Is AttributeSyntax Then
Return True
End If
Return diagnostic.Id = GenerateConstructorDiagnosticIds.BC30387 AndAlso
TypeOf node Is ClassBlockSyntax AndAlso
IsInClassDeclarationHeader(DirectCast(node, ClassBlockSyntax), token)
End Function
Private Function IsInClassDeclarationHeader(node As ClassBlockSyntax, token As SyntaxToken) As Boolean
Return node.ClassStatement.Span.Contains(token.Span)
Return TypeOf node Is InvocationExpressionSyntax OrElse
TypeOf node Is ObjectCreationExpressionSyntax OrElse
TypeOf node Is AttributeSyntax
End Function
End Class
End Namespace
End Namespace
\ No newline at end of file
......@@ -154,33 +154,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateConstructor
Return compilation.ClassifyConversion(sourceType, targetType).IsWidening
End Function
Protected Overrides Function IsClassDeclarationGeneration(document As SemanticDocument,
node As SyntaxNode,
cancellationToken As CancellationToken) As Boolean
Return TypeOf node Is ClassBlockSyntax
End Function
Protected Overrides Function TryInitializeClassDeclarationGenerationState(
document As SemanticDocument,
classDeclaration As SyntaxNode,
cancellationToken As CancellationToken,
ByRef token As SyntaxToken,
ByRef delegatedConstructor As IMethodSymbol,
ByRef typeToGenerateIn As INamedTypeSymbol) As Boolean
Dim semanticModel = document.SemanticModel
Dim classBlock = DirectCast(classDeclaration, ClassBlockSyntax)
Dim classSymbol = semanticModel.GetDeclaredSymbol(classBlock.BlockStatement, cancellationToken)
Dim constructor = classSymbol?.BaseType?.Constructors.FirstOrDefault(Function(c) IsSymbolAccessible(c, document))
If constructor Is Nothing Then
Return False
End If
typeToGenerateIn = classSymbol
delegatedConstructor = constructor
token = classBlock.BlockStatement.Identifier
Return True
End Function
Private Shared ReadOnly s_annotation As SyntaxAnnotation = New SyntaxAnnotation
Friend Overrides Function GetDelegatingConstructor(state As State,
......
......@@ -2,8 +2,10 @@
Imports System.Composition
Imports System.Threading
Imports Microsoft.CodeAnalysis.GenerateFromMembers
Imports Microsoft.CodeAnalysis.GenerateMember.GenerateDefaultConstructors
Imports Microsoft.CodeAnalysis.Host.Mef
Imports Microsoft.CodeAnalysis.LanguageServices
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -14,28 +16,36 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateDefaultConst
Protected Overrides Function TryInitializeState(
document As SemanticDocument, textSpan As TextSpan, cancellationToken As CancellationToken,
ByRef baseTypeNode As SyntaxNode, ByRef classType As INamedTypeSymbol) As Boolean
If cancellationToken.IsCancellationRequested Then
Return False
ByRef classOrStructType As INamedTypeSymbol) As Boolean
cancellationToken.ThrowIfCancellationRequested()
' Offer the feature if we're on the header for the class/struct, or if we're on the
' first base-type of a class.
Dim syntaxFacts = document.Document.GetLanguageService(Of ISyntaxFactsService)()
If syntaxFacts.IsOnTypeHeader(document.Root, textSpan.Start) Then
classOrStructType = AbstractGenerateFromMembersCodeRefactoringProvider.GetEnclosingNamedType(
document.SemanticModel, document.Root, textSpan.Start, cancellationToken)
Return classOrStructType IsNot Nothing
End If
Dim token = DirectCast(document.Root, SyntaxNode).FindToken(textSpan.Start)
Dim token = document.Root.FindToken(textSpan.Start)
Dim type = token.GetAncestor(Of TypeSyntax)()
If type IsNot Nothing AndAlso type.IsParentKind(SyntaxKind.InheritsStatement) Then
Dim baseList = DirectCast(type.Parent, InheritsStatementSyntax)
If baseList.Types.Count > 0 AndAlso
baseList.Types(0) Is type AndAlso
baseList.IsParentKind(SyntaxKind.ClassBlock) Then
classType = TryCast(document.SemanticModel.GetDeclaredSymbol(baseList.Parent, cancellationToken), INamedTypeSymbol)
baseTypeNode = type
Return classType IsNot Nothing
classOrStructType = TryCast(document.SemanticModel.GetDeclaredSymbol(baseList.Parent, cancellationToken), INamedTypeSymbol)
Return classOrStructType IsNot Nothing
End If
End If
baseTypeNode = Nothing
classType = Nothing
classOrStructType = Nothing
Return False
End Function
End Class
End Namespace
End Namespace
\ No newline at end of file
// 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.Immutable;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using Microsoft.Metadata.Tools;
namespace Roslyn.Test.MetadataUtilities
{
public static class MethodILExtensions
{
public static unsafe string GetMethodIL(this ImmutableArray<byte> ilArray)
{
var result = new StringBuilder();
fixed (byte* ilPtr = ilArray.ToArray())
{
int offset = 0;
while (true)
{
// skip padding:
while (offset < ilArray.Length && ilArray[offset] == 0)
{
offset++;
}
if (offset == ilArray.Length)
{
break;
}
var reader = new BlobReader(ilPtr + offset, ilArray.Length - offset);
var methodIL = MethodBodyBlock.Create(reader);
if (methodIL == null)
{
result.AppendFormat("<invalid byte 0x{0:X2} at offset {1}>", ilArray[offset], offset);
offset++;
}
else
{
ILVisualizer.Default.DumpMethod(
result,
methodIL.MaxStack,
methodIL.GetILContent(),
ImmutableArray.Create<ILVisualizer.LocalInfo>(),
ImmutableArray.Create<ILVisualizer.HandlerSpan>());
offset += methodIL.Size;
}
}
}
return result.ToString();
}
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册