未验证 提交 84418b26 编写于 作者: S Shyam-Gupta 提交者: GitHub

Merge pull request #28443 from dotnet/merges/dev15.8.x-to-dev15.9.x

Merge dev15.8.x to dev15.9.x
// 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 Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.UseExplicitOrImplicitType
{
public abstract class AbstractUseTypeRefactoringTests : AbstractCSharpCodeActionTest
{
private readonly CodeStyleOption<bool> onWithNone = new CodeStyleOption<bool>(true, NotificationOption.None);
private readonly CodeStyleOption<bool> offWithNone = new CodeStyleOption<bool>(false, NotificationOption.None);
private readonly CodeStyleOption<bool> onWithSilent = new CodeStyleOption<bool>(true, NotificationOption.Silent);
private readonly CodeStyleOption<bool> offWithSilent = new CodeStyleOption<bool>(false, NotificationOption.Silent);
private readonly CodeStyleOption<bool> onWithInfo = new CodeStyleOption<bool>(true, NotificationOption.Suggestion);
private readonly CodeStyleOption<bool> offWithInfo = new CodeStyleOption<bool>(false, NotificationOption.Suggestion);
private readonly CodeStyleOption<bool> onWithWarning = new CodeStyleOption<bool>(true, NotificationOption.Warning);
private readonly CodeStyleOption<bool> offWithWarning = new CodeStyleOption<bool>(false, NotificationOption.Warning);
private readonly CodeStyleOption<bool> offWithError = new CodeStyleOption<bool>(false, NotificationOption.Error);
private readonly CodeStyleOption<bool> onWithError = new CodeStyleOption<bool>(true, NotificationOption.Error);
protected IDictionary<OptionKey, object> PreferExplicitTypeWithError() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithError),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithError),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithError));
protected IDictionary<OptionKey, object> PreferImplicitTypeWithError() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithError),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithError),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithError));
protected IDictionary<OptionKey, object> PreferExplicitTypeWithWarning() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithWarning),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithWarning),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithWarning));
protected IDictionary<OptionKey, object> PreferImplicitTypeWithWarning() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithWarning),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithWarning),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithWarning));
protected IDictionary<OptionKey, object> PreferExplicitTypeWithInfo() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithInfo));
protected IDictionary<OptionKey, object> PreferImplicitTypeWithInfo() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithInfo));
protected IDictionary<OptionKey, object> PreferExplicitTypeWithSilent() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithSilent));
protected IDictionary<OptionKey, object> PreferImplicitTypeWithSilent() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithSilent));
protected IDictionary<OptionKey, object> PreferExplicitTypeWithNone() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithNone),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithNone),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithNone));
protected IDictionary<OptionKey, object> PreferImplicitTypeWithNone() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithNone),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithNone),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithNone));
}
}
// 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.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeRefactorings.UseExplicitType;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.UseExplicitType
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.UseExplicitOrImplicitType
{
[Trait(Traits.Feature, Traits.Features.CodeActionsUseExplicitType)]
public class UseExplicitTypeRefactoringTests : AbstractCSharpCodeActionTest
public class UseExplicitTypeRefactoringTests : AbstractUseTypeRefactoringTests
{
protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspace workspace, TestParameters parameters)
=> new UseExplicitTypeCodeRefactoringProvider();
private readonly CodeStyleOption<bool> onWithSilent = new CodeStyleOption<bool>(true, NotificationOption.Silent);
private readonly CodeStyleOption<bool> offWithSilent = new CodeStyleOption<bool>(false, NotificationOption.Silent);
private readonly CodeStyleOption<bool> onWithInfo = new CodeStyleOption<bool>(true, NotificationOption.Suggestion);
private readonly CodeStyleOption<bool> offWithInfo = new CodeStyleOption<bool>(false, NotificationOption.Suggestion);
private IDictionary<OptionKey, object> PreferExplicitTypeWithInfo() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithInfo));
private IDictionary<OptionKey, object> PreferExplicitTypeWithSilent() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithSilent));
private IDictionary<OptionKey, object> PreferImplicitTypeWithInfo() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithInfo));
private IDictionary<OptionKey, object> PreferImplicitTypeWithSilent() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithSilent));
[Fact]
public async Task TestIntLocalDeclaration()
{
......@@ -65,9 +36,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptAsync(code, expected, options: PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -91,7 +60,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -106,9 +75,7 @@ static void Main()
}
}";
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code);
}
[Fact]
......@@ -124,9 +91,7 @@ static void Main()
}";
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code);
}
[Fact]
......@@ -165,7 +130,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -189,7 +154,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -203,7 +168,7 @@ static void Main()
var[||] i = null;
}
}";
await TestMissingInRegularAndScriptAsync(code, options: PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code);
}
[Fact]
......@@ -227,7 +192,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -251,7 +216,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -275,9 +240,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptAsync(code, expected, options: PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -292,7 +255,7 @@ static void Main()
}
}";
await TestMissingInRegularAndScriptAsync(code, options: PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code);
}
[Fact, WorkItem(26923, "https://github.com/dotnet/roslyn/issues/26923")]
......@@ -313,15 +276,42 @@ void Method(List<int> var)
}";
// We never want to get offered here under any circumstances.
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code);
}
private async Task TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(string initialMarkup, string expectedMarkup)
{
// Enabled because the diagnostic is disabled
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferExplicitTypeWithNone());
// Enabled because the diagnostic is checking for the other direction
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferImplicitTypeWithNone());
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferImplicitTypeWithInfo());
// Disabled because the diagnostic will report it instead
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithSilent()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithInfo()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithWarning()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithError()));
// Currently this refactoring is still enabled in cases where it would cause a warning or error
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferImplicitTypeWithWarning());
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferImplicitTypeWithError());
}
private Task TestMissingInRegularAndScriptAsync(string initialMarkup, IDictionary<OptionKey, object> options)
private async Task TestMissingInRegularAndScriptAsync(string initialMarkup)
{
return TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: options));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithNone()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithNone()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithSilent()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithSilent()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithInfo()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithInfo()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithWarning()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithWarning()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithError()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithError()));
}
}
}
// 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.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeRefactorings.UseImplicitType;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.UseExplicitType
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings.UseExplicitOrImplicitType
{
[Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)]
public class UseImplicitTypeRefactoringTests : AbstractCSharpCodeActionTest
public class UseImplicitTypeRefactoringTests : AbstractUseTypeRefactoringTests
{
protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspace workspace, TestParameters parameters)
=> new UseImplicitTypeCodeRefactoringProvider();
private readonly CodeStyleOption<bool> onWithSilent = new CodeStyleOption<bool>(true, NotificationOption.Silent);
private readonly CodeStyleOption<bool> offWithSilent = new CodeStyleOption<bool>(false, NotificationOption.Silent);
private readonly CodeStyleOption<bool> onWithInfo = new CodeStyleOption<bool>(true, NotificationOption.Suggestion);
private readonly CodeStyleOption<bool> offWithInfo = new CodeStyleOption<bool>(false, NotificationOption.Suggestion);
private IDictionary<OptionKey, object> PreferExplicitTypeWithInfo() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithInfo));
private IDictionary<OptionKey, object> PreferImplicitTypeWithInfo() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithInfo),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithInfo));
private IDictionary<OptionKey, object> PreferExplicitTypeWithSilent() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, offWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, offWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, offWithSilent));
private IDictionary<OptionKey, object> PreferImplicitTypeWithSilent() => OptionsSet(
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible, onWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, onWithSilent),
SingleOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes, onWithSilent));
[Fact]
public async Task TestIntLocalDeclaration()
{
......@@ -65,10 +36,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptAsync(code, expected, options: PreferExplicitTypeWithSilent());
await TestInRegularAndScriptAsync(code, expected, options: PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithInfo());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -92,7 +60,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -107,10 +75,7 @@ static void Main()
}
}";
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code);
}
[Fact]
......@@ -126,10 +91,7 @@ static void Main()
}";
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code);
}
[Fact]
......@@ -168,7 +130,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -192,7 +154,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -216,7 +178,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -240,7 +202,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact]
......@@ -264,9 +226,7 @@ static void Main()
}
}";
await TestInRegularAndScriptAsync(code, expected, options: PreferImplicitTypeWithSilent());
await TestInRegularAndScriptAsync(code, expected, options: PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithInfo());
await TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(code, expected);
}
[Fact, WorkItem(26923, "https://github.com/dotnet/roslyn/issues/26923")]
......@@ -287,15 +247,42 @@ static void Main(string[] args)
}";
// We never want to get offered here under any circumstances.
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithSilent());
await TestMissingInRegularAndScriptAsync(code, PreferImplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code, PreferExplicitTypeWithInfo());
await TestMissingInRegularAndScriptAsync(code);
}
private async Task TestInRegularAndScriptWhenDiagnosticNotAppliedAsync(string initialMarkup, string expectedMarkup)
{
// Enabled because the diagnostic is disabled
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferImplicitTypeWithNone());
// Enabled because the diagnostic is checking for the other direction
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferExplicitTypeWithNone());
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferExplicitTypeWithSilent());
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferExplicitTypeWithInfo());
// Disabled because the diagnostic will report it instead
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithSilent()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithInfo()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithWarning()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithError()));
// Currently this refactoring is still enabled in cases where it would cause a warning or error
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferExplicitTypeWithWarning());
await TestInRegularAndScriptAsync(initialMarkup, expectedMarkup, options: PreferExplicitTypeWithError());
}
private Task TestMissingInRegularAndScriptAsync(string initialMarkup, IDictionary<OptionKey, object> options)
private async Task TestMissingInRegularAndScriptAsync(string initialMarkup)
{
return TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: options));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithNone()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithNone()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithSilent()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithSilent()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithInfo()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithInfo()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithWarning()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithWarning()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferImplicitTypeWithError()));
await TestMissingInRegularAndScriptAsync(initialMarkup, parameters: new TestParameters(options: PreferExplicitTypeWithError()));
}
}
}
......@@ -3,11 +3,11 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeFixes.PreferFrameworkType;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Diagnostics.Analyzers;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PreferFrameworkType;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
......
......@@ -412,9 +412,9 @@ private System.Int32 F(System.Int32 p1, System.Int16 p2)
using System;
class ProgramA
{
private int x = 0;
private int y = 0;
private int z = 0;
private Int32 x = 0;
private Int32 y = 0;
private Int32 z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
......@@ -432,9 +432,9 @@ private System.Int32 F(System.Int32 p1, System.Int16 p2)
using System;
class ProgramA2
{
private int x = 0;
private int y = 0;
private int z = 0;
private Int32 x = 0;
private Int32 y = 0;
private Int32 z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
......@@ -454,9 +454,9 @@ private System.Int32 F(System.Int32 p1, System.Int16 p2)
using System;
class ProgramA3
{
private int x = 0;
private int y = 0;
private int z = 0;
private Int32 x = 0;
private Int32 y = 0;
private Int32 z = 0;
private System.Int32 F(System.Int32 p1, System.Int16 p2)
{
......
......@@ -1539,8 +1539,10 @@ static void M()
[|var|] n1 = new C();
}
}";
await TestMissingInRegularAndScriptAsync(source,
new TestParameters(options: ExplicitTypeSilentEnforcement()));
await TestDiagnosticInfoAsync(source,
options: ExplicitTypeSilentEnforcement(),
diagnosticId: IDEDiagnosticIds.UseExplicitTypeDiagnosticId,
diagnosticSeverity: DiagnosticSeverity.Hidden);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)]
......
......@@ -1524,8 +1524,10 @@ static void M()
[|C|] n1 = new C();
}
}";
await TestMissingInRegularAndScriptAsync(source,
new TestParameters(options: ImplicitTypeSilentEnforcement()));
await TestDiagnosticInfoAsync(source,
options: ImplicitTypeSilentEnforcement(),
diagnosticId: IDEDiagnosticIds.UseImplicitTypeDiagnosticId,
diagnosticSeverity: DiagnosticSeverity.Hidden);
}
[WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsUseImplicitType)]
......
......@@ -8,12 +8,9 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeCleanup;
using Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames;
using Microsoft.CodeAnalysis.CSharp.TypeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics.CSharp;
using Microsoft.CodeAnalysis.Diagnostics.SimplifyTypeNames;
using Microsoft.CodeAnalysis.Editor.UnitTests;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Options;
......@@ -87,6 +84,7 @@ static void Main(string[] args)
return AssertCodeCleanupResult(expected, code,
(CodeCleanupOptions.AreCodeCleanupRulesConfigured, enabled: true),
(CodeCleanupOptions.SortImports, enabled: true),
(CodeCleanupOptions.ApplyImplicitExplicitTypePreferences, enabled: false),
(CodeCleanupOptions.AddAccessibilityModifiers, enabled: false));
}
......
......@@ -888,9 +888,9 @@ void Handler(object sender, EventArgs args)
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsQualifyMemberAccess)]
public async Task QualifyMemberAccessNotPresentOnNotificationOptionSilent()
public async Task QualifyMemberAccessOnNotificationOptionSilent()
{
await TestMissingAsyncWithOptionAndNotificationOption(
await TestAsyncWithOptionAndNotificationOption(
@"class Class
{
int Property { get; set; };
......@@ -900,6 +900,15 @@ void M()
[|Property|] = 1;
}
}",
@"class Class
{
int Property { get; set; };
void M()
{
this.Property = 1;
}
}",
CodeStyleOptions.QualifyPropertyAccess, NotificationOption.Silent);
}
......
......@@ -1189,9 +1189,9 @@ static void Main(string[] args)
[WorkItem(995168, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/995168"), WorkItem(1073099, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1073099")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSimplifyTypeNames)]
public async Task SimplifyToPredefinedTypeNameShouldNotBeOfferedInsideNameOf4()
public async Task SimplifyToPredefinedTypeNameShouldBeOfferedInsideFunctionCalledNameOf()
{
await TestMissingInRegularAndScriptAsync(
await TestInRegularAndScriptAsync(
@"using System;
class Program
......@@ -1201,6 +1201,20 @@ static void Main(string[] args)
var x = nameof(typeof([|Int32|]));
}
static string nameof(Type t)
{
return string.Empty;
}
}",
@"using System;
class Program
{
static void Main(string[] args)
{
var x = nameof(typeof(int));
}
static string nameof(Type t)
{
return string.Empty;
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
......@@ -23,21 +24,41 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithSilentEnforcement));
private IDictionary<OptionKey, object> UseExpressionBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)));
private IDictionary<OptionKey, object> UseExpressionBodyForAccessors_ExpressionBodyForProperties =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement));
private IDictionary<OptionKey, object> UseExpressionBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_ExpressionBodyForProperties =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.NeverWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_BlockBodyForProperties =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.NeverWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithSilentEnforcement));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestUpdatePropertyIfPropertyWantsBlockAndAccessorWantsExpression()
{
......@@ -74,6 +95,46 @@ int Goo
}", parameters: new TestParameters(options: UseExpressionBodyForAccessors_ExpressionBodyForProperties));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo
{
get
{
return [||]Bar();
}
}
}",
@"class C
{
int Goo => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody2()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo
{
get
{
return [||]Bar();
}
}
}",
@"class C
{
int Goo => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesAndInBlockBody()
{
......@@ -127,6 +188,36 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody()
}", parameters: new TestParameters(options: UseBlockBodyForAccessors_ExpressionBodyForProperties));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo { get => [||]Bar(); }
}",
@"class C
{
int Goo => Bar();
}", parameters: new TestParameters(options: UseBlockBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody2()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo { get => [||]Bar(); }
}",
@"class C
{
int Goo => Bar();
}", parameters: new TestParameters(options: UseBlockBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedForPropertyIfUserPrefersBlockPropertiesAndHasBlockProperty()
{
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
......@@ -20,9 +21,15 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
private IDictionary<OptionKey, object> UseExpressionBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement);
private IDictionary<OptionKey, object> UseExpressionBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None));
private IDictionary<OptionKey, object> UseBlockBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.NeverWithSilentEnforcement);
private IDictionary<OptionKey, object> UseBlockBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
{
......@@ -36,6 +43,23 @@ public C()
}", parameters: new TestParameters(options: UseExpressionBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
public C()
{
[||]Bar();
}
}",
@"class C
{
public C() => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesAndInBlockBody()
{
......@@ -76,6 +100,23 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody()
}", parameters: new TestParameters(options: UseBlockBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
public C() => [||]Bar();
}",
@"class C
{
public C()
{
Bar();
}
}", parameters: new TestParameters(options: UseBlockBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesAndInExpressionBody()
{
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
......@@ -20,9 +21,15 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
private IDictionary<OptionKey, object> UseExpressionBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement);
private IDictionary<OptionKey, object> UseExpressionBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None));
private IDictionary<OptionKey, object> UseBlockBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, CSharpCodeStyleOptions.NeverWithSilentEnforcement);
private IDictionary<OptionKey, object> UseBlockBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
{
......@@ -36,6 +43,23 @@ public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
}", parameters: new TestParameters(options: UseExpressionBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
public static implicit operator bool(C c1)
{
[||]Bar();
}
}",
@"class C
{
public static implicit operator bool(C c1) => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesAndInBlockBody()
{
......@@ -76,6 +100,23 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody()
}", parameters: new TestParameters(options: UseBlockBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
public static implicit operator bool(C c1) => [||]Bar();
}",
@"class C
{
public static implicit operator bool(C c1)
{
return Bar();
}
}", parameters: new TestParameters(options: UseBlockBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesAndInExpressionBody()
{
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
......@@ -21,9 +22,15 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
private IDictionary<OptionKey, object> UseExpressionBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement);
private IDictionary<OptionKey, object> UseExpressionBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None));
private IDictionary<OptionKey, object> UseBlockBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, CSharpCodeStyleOptions.NeverWithSilentEnforcement);
private IDictionary<OptionKey, object> UseBlockBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
{
......@@ -40,6 +47,26 @@ public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
}", parameters: new TestParameters(options: UseExpressionBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
int this[int i]
{
get
{
[||]return Bar();
}
}
}",
@"class C
{
int this[int i] => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesAndInBlockBody()
{
......@@ -86,6 +113,26 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody()
}", parameters: new TestParameters(options: UseBlockBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
int this[int i] => [||]Bar();
}",
@"class C
{
int this[int i]
{
get
{
return Bar();
}
}
}", parameters: new TestParameters(options: UseBlockBodyDisabledDiagnostic));
}
[WorkItem(20363, "https://github.com/dotnet/roslyn/issues/20363")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesAndInExpressionBody()
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
......@@ -20,9 +21,15 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
private IDictionary<OptionKey, object> UseExpressionBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement);
private IDictionary<OptionKey, object> UseExpressionBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedMethods, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None));
private IDictionary<OptionKey, object> UseBlockBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.NeverWithSilentEnforcement);
private IDictionary<OptionKey, object> UseBlockBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedMethods, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
{
......@@ -36,6 +43,23 @@ void Goo()
}", parameters: new TestParameters(options: UseExpressionBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
void Goo()
{
[||]Bar();
}
}",
@"class C
{
void Goo() => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesAndInBlockBody()
{
......@@ -76,6 +100,23 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody()
}", parameters: new TestParameters(options: UseBlockBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
void Goo() => [||]Bar();
}",
@"class C
{
void Goo()
{
Bar();
}
}", parameters: new TestParameters(options: UseBlockBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesAndInExpressionBody()
{
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.CodeRefactorings;
......@@ -20,9 +21,15 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
private IDictionary<OptionKey, object> UseExpressionBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement);
private IDictionary<OptionKey, object> UseExpressionBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None));
private IDictionary<OptionKey, object> UseBlockBody =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, CSharpCodeStyleOptions.NeverWithSilentEnforcement);
private IDictionary<OptionKey, object> UseBlockBodyDisabledDiagnostic =>
this.Option(CSharpCodeStyleOptions.PreferExpressionBodiedOperators, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
{
......@@ -36,6 +43,23 @@ public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
}", parameters: new TestParameters(options: UseExpressionBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
public static bool operator +(C c1, C c2)
{
[||]Bar();
}
}",
@"class C
{
public static bool operator +(C c1, C c2) => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesAndInBlockBody()
{
......@@ -76,6 +100,23 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody()
}", parameters: new TestParameters(options: UseBlockBody));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
public static bool operator +(C c1, C c2) => [||]Bar();
}",
@"class C
{
public static bool operator +(C c1, C c2)
{
return Bar();
}
}", parameters: new TestParameters(options: UseBlockBodyDisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesAndInExpressionBody()
{
......
......@@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.UseExpressionBody;
......@@ -24,21 +25,41 @@ protected override CodeRefactoringProvider CreateCodeRefactoringProvider(Workspa
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithSilentEnforcement));
private IDictionary<OptionKey, object> UseExpressionBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)));
private IDictionary<OptionKey, object> UseExpressionBodyForAccessors_ExpressionBodyForProperties =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement));
private IDictionary<OptionKey, object> UseExpressionBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_ExpressionBodyForProperties =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.NeverWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.WhenPossible, NotificationOption.None)));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_BlockBodyForProperties =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, CSharpCodeStyleOptions.NeverWithSilentEnforcement),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, CSharpCodeStyleOptions.NeverWithSilentEnforcement));
private IDictionary<OptionKey, object> UseBlockBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic =>
OptionsSet(
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedAccessors, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)),
this.SingleOption(CSharpCodeStyleOptions.PreferExpressionBodiedProperties, new CodeStyleOption<ExpressionBodyPreference>(ExpressionBodyPreference.Never, NotificationOption.None)));
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestNotOfferedIfUserPrefersExpressionBodiesAndInBlockBody()
{
......@@ -55,6 +76,26 @@ int Goo
}", parameters: new TestParameters(options: UseExpressionBodyForAccessors_ExpressionBodyForProperties));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesWithoutDiagnosticAndInBlockBody()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo
{
get
{
[||]return Bar();
}
}
}",
@"class C
{
int Goo => Bar();
}", parameters: new TestParameters(options: UseExpressionBodyForAccessors_ExpressionBodyForProperties_DisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestUpdateAccessorIfAccessWantsBlockAndPropertyWantsExpression()
{
......@@ -154,6 +195,46 @@ public async Task TestNotOfferedIfUserPrefersBlockBodiesAndInExpressionBody2()
}", parameters: new TestParameters(options: UseBlockBodyForAccessors_BlockBodyForProperties));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo => [||]Bar();
}",
@"class C
{
int Goo
{
get
{
return Bar();
}
}
}", parameters: new TestParameters(options: UseExpressionBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic));
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersBlockBodiesWithoutDiagnosticAndInExpressionBody2()
{
await TestInRegularAndScript1Async(
@"class C
{
int Goo => [||]Bar();
}",
@"class C
{
int Goo
{
get
{
return Bar();
}
}
}", parameters: new TestParameters(options: UseBlockBodyForAccessors_BlockBodyForProperties_DisabledDiagnostic));
}
[WorkItem(20363, "https://github.com/dotnet/roslyn/issues/20363")]
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUseExpressionBody)]
public async Task TestOfferedIfUserPrefersExpressionBodiesAndInExpressionBody()
......
......@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.Text.Shared.Extensions;
......@@ -186,6 +187,7 @@ private CompletionProvider GetCompletionProvider(CompletionItem item)
}
transaction.Complete();
Logger.Log(FunctionId.Intellisense_Completion_Commit, KeyValueLogMessage.NoProperty);
}
// Let the completion rules know that this item was committed.
......
......@@ -3,10 +3,10 @@
Option Strict On
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.CodeFixes.PreferFrameworkType
Imports Microsoft.CodeAnalysis.CodeStyle
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.PreferFrameworkType
Imports Microsoft.CodeAnalysis.VisualBasic.Diagnostics.Analyzers
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.PreferFrameworkTypeTests
......
......@@ -346,9 +346,9 @@ End Class]]>
<Document><![CDATA[
Imports System
Class ProgramA
Dim x As Integer = 0
Dim y As Integer = 0
Dim z As Integer = 0
Dim x As Int32 = 0
Dim y As Int32 = 0
Dim z As Int32 = 0
Private Function F(p1 As System.Int32, p2 As System.Int16) As System.Int32
Dim i1 As System.Int32 = Me.x
......@@ -364,9 +364,9 @@ End Class]]>
<Document><![CDATA[
Imports System
Class ProgramA2
Dim x As Integer = 0
Dim y As Integer = 0
Dim z As Integer = 0
Dim x As Int32 = 0
Dim y As Int32 = 0
Dim z As Int32 = 0
Private Function F(p1 As System.Int32, p2 As System.Int16) As System.Int32
Dim i1 As System.Int32 = Me.x
......@@ -385,9 +385,9 @@ End Class]]>
<Document><![CDATA[
Imports System
Class ProgramA3
Dim x As Integer = 0
Dim y As Integer = 0
Dim z As Integer = 0
Dim x As Int32 = 0
Dim y As Int32 = 0
Dim z As Int32 = 0
Private Function F(p1 As System.Int32, p2 As System.Int16) As System.Int32
Dim i1 As System.Int32 = Me.x
......
......@@ -434,9 +434,10 @@ CodeStyleOptions.QualifyEventAccess)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsQualifyMemberAccess)>
Public Async Function QualifyMemberAccessNotPresentOnNotificationOptionSilent() As Task
Await TestMissingAsyncWithOptionAndNotification(
Public Async Function QualifyMemberAccessOnNotificationOptionSilent() As Task
Await TestAsyncWithOptionAndNotification(
"Class C : Property I As Integer : Sub M() : [|I|] = 1 : End Sub : End Class",
"Class C : Property I As Integer : Sub M() : Me.I = 1 : End Sub : End Class",
CodeStyleOptions.QualifyPropertyAccess, NotificationOption.Silent)
End Function
......
......@@ -2417,7 +2417,7 @@ End Module
Dim parameters2 As New TestParameters()
Using workspace = CreateWorkspaceFromFile(source.ToString(), parameters2)
workspace.ApplyOptions(PreferIntrinsicPredefinedTypeEverywhere())
Dim diagnostics = (Await GetDiagnosticsAsync(workspace, parameters2)).Where(Function(d) d.Id = IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId)
Dim diagnostics = (Await GetDiagnosticsAsync(workspace, parameters2)).Where(Function(d) d.Id = IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId)
Assert.Equal(1, diagnostics.Count)
End Using
......
......@@ -43,8 +43,7 @@ internal class CSharpCodeCleanupService : ICodeCleanupService
private static ImmutableArray<Tuple<PerLanguageOption<bool>, ImmutableArray<string>>> GetCodeCleanupOptionMapping()
{
return ImmutableArray.Create<Tuple<PerLanguageOption<bool>, ImmutableArray<string>>>
(
return ImmutableArray.Create(
Tuple.Create(
CodeCleanupOptions.ApplyImplicitExplicitTypePreferences,
ImmutableArray.Create(IDEDiagnosticIds.UseImplicitTypeDiagnosticId,
......@@ -57,8 +56,7 @@ internal class CSharpCodeCleanupService : ICodeCleanupService
),
Tuple.Create(
CodeCleanupOptions.ApplyLanguageFrameworkTypePreferences,
ImmutableArray.Create(IDEDiagnosticIds.PreferFrameworkTypeInDeclarationsDiagnosticId,
IDEDiagnosticIds.PreferFrameworkTypeInMemberAccessDiagnosticId)
ImmutableArray.Create(IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId)
),
Tuple.Create(
CodeCleanupOptions.AddRemoveBracesForSingleLineControlStatements,
......
......@@ -69,7 +69,7 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
}
var typeStyle = AnalyzeTypeName(declaredType, semanticModel, optionSet, cancellationToken);
if (typeStyle.IsStylePreferred && typeStyle.Severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) < ReportDiagnostic.Hidden)
if (typeStyle.IsStylePreferred && typeStyle.Severity != ReportDiagnostic.Suppress)
{
// the analyzer would handle this. So we do not.
return;
......
......@@ -4,7 +4,7 @@
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics.PreferFrameworkType;
using Microsoft.CodeAnalysis.PreferFrameworkType;
namespace Microsoft.CodeAnalysis.CSharp.Diagnostics.Analyzers
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
......@@ -9,8 +7,8 @@
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics.SimplifyTypeNames;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.SimplifyTypeNames;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Diagnostics.SimplifyTypeNames
......@@ -93,13 +91,23 @@ private static bool IsCrefCandidate(SyntaxNode node)
return node is QualifiedCrefSyntax;
}
protected sealed override bool CanSimplifyTypeNameExpressionCore(SemanticModel model, SyntaxNode node, OptionSet optionSet, out TextSpan issueSpan, out string diagnosticId, CancellationToken cancellationToken)
protected sealed override bool CanSimplifyTypeNameExpressionCore(
SemanticModel model, SyntaxNode node, OptionSet optionSet,
out TextSpan issueSpan, out string diagnosticId, out bool inDeclaration,
CancellationToken cancellationToken)
{
return CanSimplifyTypeNameExpression(model, node, optionSet, out issueSpan, out diagnosticId, cancellationToken);
return CanSimplifyTypeNameExpression(
model, node, optionSet,
out issueSpan, out diagnosticId, out inDeclaration,
cancellationToken);
}
internal override bool CanSimplifyTypeNameExpression(SemanticModel model, SyntaxNode node, OptionSet optionSet, out TextSpan issueSpan, out string diagnosticId, CancellationToken cancellationToken)
internal override bool CanSimplifyTypeNameExpression(
SemanticModel model, SyntaxNode node, OptionSet optionSet,
out TextSpan issueSpan, out string diagnosticId, out bool inDeclaration,
CancellationToken cancellationToken)
{
inDeclaration = false;
issueSpan = default;
diagnosticId = IDEDiagnosticIds.SimplifyNamesDiagnosticId;
......@@ -138,11 +146,13 @@ internal override bool CanSimplifyTypeNameExpression(SemanticModel model, Syntax
// set proper diagnostic ids.
if (replacementSyntax.HasAnnotations(nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration)))
{
diagnosticId = IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId;
inDeclaration = true;
diagnosticId = IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId;
}
else if (replacementSyntax.HasAnnotations(nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess)))
{
diagnosticId = IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId;
inDeclaration = false;
diagnosticId = IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId;
}
else if (expression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
{
......
// 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.Diagnostics;
using System.Threading;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Diagnostics.TypeStyle
......@@ -62,9 +58,7 @@ private void HandleVariableDeclaration(SyntaxNodeAnalysisContext context)
var typeStyle = Helper.AnalyzeTypeName(
declaredType, semanticModel, optionSet, cancellationToken);
if (!typeStyle.IsStylePreferred ||
typeStyle.Severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) >= ReportDiagnostic.Hidden ||
!typeStyle.CanConvert())
if (!typeStyle.IsStylePreferred || !typeStyle.CanConvert())
{
return;
}
......
......@@ -26,11 +26,10 @@ protected override string GetTitle(string diagnosticId, string nodeText)
switch (diagnosticId)
{
case IDEDiagnosticIds.SimplifyNamesDiagnosticId:
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId:
case IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId:
return string.Format(CSharpFeaturesResources.Simplify_name_0, nodeText);
case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId:
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId:
return string.Format(CSharpFeaturesResources.Simplify_member_access_0, nodeText);
case IDEDiagnosticIds.RemoveQualificationDiagnosticId:
......
......@@ -5,7 +5,6 @@
using System.Linq;
using Microsoft.CodeAnalysis.CodeRefactorings;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
......@@ -82,12 +81,15 @@ protected virtual Location GetDiagnosticLocation(TDeclaration declaration)
public bool CanOfferUseExpressionBody(
OptionSet optionSet, TDeclaration declaration, bool forAnalyzer)
{
var preference = optionSet.GetOption(this.Option).Value;
var currentOptionValue = optionSet.GetOption(Option);
var preference = currentOptionValue.Value;
var userPrefersExpressionBodies = preference != ExpressionBodyPreference.Never;
var analyzerDisabled = currentOptionValue.Notification.Severity == ReportDiagnostic.Suppress;
// If the user likes expression bodies, then we offer expression bodies from the diagnostic analyzer.
// If the user does not like expression bodies then we offer expression bodies from the refactoring provider.
if (userPrefersExpressionBodies == forAnalyzer)
// If the analyzer is disabled completely, the refactoring is enabled in both directions.
if (userPrefersExpressionBodies == forAnalyzer || (!forAnalyzer && analyzerDisabled))
{
var expressionBody = this.GetExpressionBody(declaration);
if (expressionBody == null)
......@@ -156,8 +158,10 @@ protected virtual Location GetDiagnosticLocation(TDeclaration declaration)
public (bool canOffer, bool fixesError) CanOfferUseBlockBody(
OptionSet optionSet, TDeclaration declaration, bool forAnalyzer)
{
var preference = optionSet.GetOption(this.Option).Value;
var currentOptionValue = optionSet.GetOption(Option);
var preference = currentOptionValue.Value;
var userPrefersBlockBodies = preference == ExpressionBodyPreference.Never;
var analyzerDisabled = currentOptionValue.Notification.Severity == ReportDiagnostic.Suppress;
var expressionBodyOpt = this.GetExpressionBody(declaration);
var canOffer = expressionBodyOpt?.TryConvertToBlock(
......@@ -197,7 +201,9 @@ protected virtual Location GetDiagnosticLocation(TDeclaration declaration)
// If the user likes block bodies, then we offer block bodies from the diagnostic analyzer.
// If the user does not like block bodies then we offer block bodies from the refactoring provider.
return (userPrefersBlockBodies == forAnalyzer, fixesError: false);
// If the analyzer is disabled completely, the refactoring is enabled in both directions.
canOffer = userPrefersBlockBodies == forAnalyzer || (!forAnalyzer && analyzerDisabled);
return (canOffer, fixesError: false);
}
public TDeclaration Update(
......
......@@ -31,7 +31,7 @@ public UseExpressionBodyCodeFixProvider()
}
protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic)
=> diagnostic.Severity != DiagnosticSeverity.Hidden ||
=> !diagnostic.IsSuppressed ||
diagnostic.Properties.ContainsKey(UseExpressionBodyDiagnosticAnalyzer.FixesError);
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
......
......@@ -30,7 +30,7 @@ public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.UseLocalFunctionDiagnosticId);
protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic)
=> diagnostic.Severity != DiagnosticSeverity.Hidden && !diagnostic.IsSuppressed;
=> !diagnostic.IsSuppressed;
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
......
......@@ -15,10 +15,13 @@ internal static class IDEDiagnosticIds
public const string AddQualificationDiagnosticId = "IDE0009";
public const string PopulateSwitchDiagnosticId = "IDE0010";
public const string AddBracesDiagnosticId = "IDE0011";
public const string PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId = "IDE0012";
public const string PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId = "IDE0013";
public const string PreferFrameworkTypeInDeclarationsDiagnosticId = "IDE0014";
public const string PreferFrameworkTypeInMemberAccessDiagnosticId = "IDE0015";
// IDE0012-IDE0015 deprecated and replaced with PreferBuiltInOrFrameworkTypeDiagnosticId (IDE0049)
// public const string PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId = "IDE0012";
// public const string PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId = "IDE0013";
// public const string PreferFrameworkTypeInDeclarationsDiagnosticId = "IDE0014";
// public const string PreferFrameworkTypeInMemberAccessDiagnosticId = "IDE0015";
public const string UseThrowExpressionDiagnosticId = "IDE0016";
public const string UseObjectInitializerDiagnosticId = "IDE0017";
public const string InlineDeclarationDiagnosticId = "IDE0018";
......@@ -72,6 +75,9 @@ internal static class IDEDiagnosticIds
public const string RemoveUnnecessaryParenthesesDiagnosticId = "IDE0047";
public const string AddRequiredParenthesesDiagnosticId = "IDE0048";
public const string PreferBuiltInOrFrameworkTypeDiagnosticId = "IDE0049";
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
public const string AnalyzerDependencyConflictId = "IDE1002";
......
......@@ -2,7 +2,6 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
......@@ -118,7 +117,7 @@ void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
var namingStyleRules = namingPreferences.Rules;
if (!namingStyleRules.TryGetApplicableRule(symbol, out var applicableRule) ||
applicableRule.EnforcementLevel.WithDefaultSeverity(DiagnosticSeverity.Hidden) >= ReportDiagnostic.Hidden)
applicableRule.EnforcementLevel == ReportDiagnostic.Suppress)
{
return null;
}
......
......@@ -6,34 +6,31 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CodeFixes.PreferFrameworkType
namespace Microsoft.CodeAnalysis.PreferFrameworkType
{
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic,
Name = PredefinedCodeFixProviderNames.PreferFrameworkType), Shared]
internal class PreferFrameworkTypeCodeFixProvider : SyntaxEditorBasedCodeFixProvider
{
public const string EquivalenceKey = nameof(EquivalenceKey);
public const string DeclarationsEquivalenceKey = nameof(DeclarationsEquivalenceKey);
public const string MemberAccessEquivalenceKey = nameof(MemberAccessEquivalenceKey);
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
IDEDiagnosticIds.PreferFrameworkTypeInDeclarationsDiagnosticId,
IDEDiagnosticIds.PreferFrameworkTypeInMemberAccessDiagnosticId);
public sealed override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(
IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId);
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics[0];
var equivalenceKey = diagnostic.Properties[EquivalenceKey];
context.RegisterCodeFix(
new PreferFrameworkTypeCodeAction(
c => this.FixAsync(context.Document, context.Diagnostics[0], c),
equivalenceKey),
context.Diagnostics);
if (diagnostic.Properties.ContainsKey(PreferFrameworkTypeConstants.PreferFrameworkType))
{
context.RegisterCodeFix(
new PreferFrameworkTypeCodeAction(
c => this.FixAsync(context.Document, diagnostic, c)),
context.Diagnostics);
}
return Task.CompletedTask;
}
......@@ -60,13 +57,13 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
}
protected override bool IncludeDiagnosticDuringFixAll(FixAllState state, Diagnostic diagnostic)
=> diagnostic.Properties[EquivalenceKey] == state.CodeActionEquivalenceKey;
=> diagnostic.Properties.ContainsKey(PreferFrameworkTypeConstants.PreferFrameworkType);
private class PreferFrameworkTypeCodeAction : CodeAction.DocumentChangeAction
{
public PreferFrameworkTypeCodeAction(
Func<CancellationToken, Task<Document>> createChangedDocument, string equivalenceKey)
: base(FeaturesResources.Use_framework_type, createChangedDocument, equivalenceKey)
Func<CancellationToken, Task<Document>> createChangedDocument)
: base(FeaturesResources.Use_framework_type, createChangedDocument, FeaturesResources.Use_framework_type)
{
}
}
......
// 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;
namespace Microsoft.CodeAnalysis.PreferFrameworkType
{
internal static class PreferFrameworkTypeConstants
{
public const string PreferFrameworkType = nameof(PreferFrameworkType);
public static readonly ImmutableDictionary<string, string> Properties =
ImmutableDictionary<string, string>.Empty.Add(PreferFrameworkType, "");
}
}
// 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 Microsoft.CodeAnalysis.CodeFixes.PreferFrameworkType;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
namespace Microsoft.CodeAnalysis.Diagnostics.PreferFrameworkType
namespace Microsoft.CodeAnalysis.PreferFrameworkType
{
internal abstract class PreferFrameworkTypeDiagnosticAnalyzerBase<TSyntaxKind, TExpressionSyntax, TPredefinedTypeSyntax> :
AbstractCodeStyleDiagnosticAnalyzer
......@@ -13,13 +13,8 @@ internal abstract class PreferFrameworkTypeDiagnosticAnalyzerBase<TSyntaxKind, T
where TExpressionSyntax : SyntaxNode
where TPredefinedTypeSyntax : TExpressionSyntax
{
private static readonly ImmutableDictionary<string, string> DeclarationsEquivalenceKey = ImmutableDictionary<string, string>.Empty.Add(
PreferFrameworkTypeCodeFixProvider.EquivalenceKey, PreferFrameworkTypeCodeFixProvider.DeclarationsEquivalenceKey);
private static readonly ImmutableDictionary<string, string> MemberAccessEquivalenceKey = ImmutableDictionary<string, string>.Empty.Add(
PreferFrameworkTypeCodeFixProvider.EquivalenceKey, PreferFrameworkTypeCodeFixProvider.MemberAccessEquivalenceKey);
protected PreferFrameworkTypeDiagnosticAnalyzerBase()
: base(IDEDiagnosticIds.PreferFrameworkTypeInDeclarationsDiagnosticId,
: base(IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId,
new LocalizableResourceString(nameof(FeaturesResources.Use_framework_type), FeaturesResources.ResourceManager, typeof(FeaturesResources)),
new LocalizableResourceString(nameof(FeaturesResources.Use_framework_type), FeaturesResources.ResourceManager, typeof(FeaturesResources)))
{
......@@ -87,14 +82,16 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
return;
}
// earlier we did a context insensitive check to see if this style was preferred in *any* context at all.
// now, we have to make a context sensitive check to see if options settings for our context requires us to report a diagnostic.
if (ShouldReportDiagnostic(predefinedTypeNode, optionSet, language,
out var severity, out var properties))
out var diagnosticSeverity))
{
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor, predefinedTypeNode.GetLocation(),
severity, additionalLocations: null, properties));
diagnosticSeverity, additionalLocations: null,
PreferFrameworkTypeConstants.Properties));
}
}
......@@ -102,8 +99,8 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
/// Detects the context of this occurrence of predefined type and determines if we should report it.
/// </summary>
private bool ShouldReportDiagnostic(
TPredefinedTypeSyntax predefinedTypeNode, OptionSet optionSet, string language,
out ReportDiagnostic severity, out ImmutableDictionary<string, string> properties)
TPredefinedTypeSyntax predefinedTypeNode, OptionSet optionSet,
string language, out ReportDiagnostic severity)
{
// we have a predefined type syntax that is either in a member access context or a declaration context.
// check the appropriate option and determine if we should report a diagnostic.
......@@ -113,7 +110,6 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
var optionValue = optionSet.GetOption(option, language);
severity = optionValue.Notification.Severity;
properties = isMemberAccessOrCref ? MemberAccessEquivalenceKey : DeclarationsEquivalenceKey;
return OptionSettingPrefersFrameworkType(optionValue, severity);
}
......@@ -132,6 +128,6 @@ private bool IsFrameworkTypePreferred(OptionSet optionSet, PerLanguageOption<Cod
/// </summary>
/// <remarks>if predefined type is not preferred, it implies the preference is framework type.</remarks>
private static bool OptionSettingPrefersFrameworkType(CodeStyleOption<bool> optionValue, ReportDiagnostic severity)
=> !optionValue.Value && severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) < ReportDiagnostic.Hidden;
=> !optionValue.Value && severity != ReportDiagnostic.Suppress;
}
}
......@@ -121,19 +121,20 @@ private void AnalyzeOperation(OperationAnalysisContext context, IOperation opera
var optionValue = optionSet.GetOption(applicableOption, context.Operation.Syntax.Language);
var shouldOptionBePresent = optionValue.Value;
var isQualificationPresent = IsAlreadyQualifiedMemberAccess(simpleName);
if (shouldOptionBePresent && !isQualificationPresent)
var severity = optionValue.Notification.Severity;
if (!shouldOptionBePresent || severity == ReportDiagnostic.Suppress)
{
var severity = optionValue.Notification.Severity;
if (severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) < ReportDiagnostic.Hidden)
{
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
GetLocation(operation),
severity,
additionalLocations: null,
properties: null));
}
return;
}
if (!IsAlreadyQualifiedMemberAccess(simpleName))
{
context.ReportDiagnostic(DiagnosticHelper.Create(
Descriptor,
GetLocation(operation),
severity,
additionalLocations: null,
properties: null));
}
}
......
......@@ -7,7 +7,6 @@
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Diagnostics.SimplifyTypeNames;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Options;
......@@ -36,8 +35,7 @@ internal abstract partial class AbstractSimplifyTypeNamesCodeFixProvider<TSyntax
IDEDiagnosticIds.SimplifyNamesDiagnosticId,
IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId,
IDEDiagnosticIds.RemoveQualificationDiagnosticId,
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId,
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId);
IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId);
private SyntaxNode GetNodeToSimplify(SyntaxNode root, SemanticModel model, TextSpan span, OptionSet optionSet, out string diagnosticId, CancellationToken cancellationToken)
{
......@@ -122,7 +120,8 @@ private bool CanSimplifyTypeNameExpression(SemanticModel model, SyntaxNode node,
{
diagnosticId = null;
if (!_analyzer.IsCandidate(node) ||
!_analyzer.CanSimplifyTypeNameExpression(model, node, optionSet, out var issueSpan, out diagnosticId, cancellationToken))
!_analyzer.CanSimplifyTypeNameExpression(
model, node, optionSet, out var issueSpan, out diagnosticId, out var inDeclaration, cancellationToken))
{
return false;
}
......
......@@ -4,13 +4,14 @@
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.QualifyMemberAccess;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Diagnostics.SimplifyTypeNames
namespace Microsoft.CodeAnalysis.SimplifyTypeNames
{
internal abstract class SimplifyTypeNamesDiagnosticAnalyzerBase<TLanguageKindEnum> : DiagnosticAnalyzer, IBuiltInAnalyzer where TLanguageKindEnum : struct
{
......@@ -43,32 +44,26 @@ internal abstract class SimplifyTypeNamesDiagnosticAnalyzerBase<TLanguageKindEnu
isEnabledByDefault: true,
customTags: DiagnosticCustomTags.Unnecessary);
private static readonly DiagnosticDescriptor s_descriptorPreferIntrinsicTypeInDeclarations = new DiagnosticDescriptor(IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId,
s_localizableTitleSimplifyNames,
s_localizableMessage,
DiagnosticCategory.Style,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true,
customTags: DiagnosticCustomTags.Unnecessary);
private static readonly DiagnosticDescriptor s_descriptorPreferIntrinsicTypeInMemberAccess = new DiagnosticDescriptor(IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId,
s_localizableTitleSimplifyNames,
s_localizableMessage,
DiagnosticCategory.Style,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true,
customTags: DiagnosticCustomTags.Unnecessary);
private static readonly DiagnosticDescriptor s_descriptorPreferBuiltinOrFrameworkType = new DiagnosticDescriptor(IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId,
s_localizableTitleSimplifyNames,
s_localizableMessage,
DiagnosticCategory.Style,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true,
customTags: DiagnosticCustomTags.Unnecessary);
internal abstract bool IsCandidate(SyntaxNode node);
internal abstract bool CanSimplifyTypeNameExpression(SemanticModel model, SyntaxNode node, OptionSet optionSet, out TextSpan issueSpan, out string diagnosticId, CancellationToken cancellationToken);
internal abstract bool CanSimplifyTypeNameExpression(
SemanticModel model, SyntaxNode node, OptionSet optionSet,
out TextSpan issueSpan, out string diagnosticId, out bool inDeclaration,
CancellationToken cancellationToken);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
= ImmutableArray.Create(
s_descriptorSimplifyNames,
s_descriptorSimplifyMemberAccess,
s_descriptorRemoveThisOrMe,
s_descriptorPreferIntrinsicTypeInDeclarations,
s_descriptorPreferIntrinsicTypeInMemberAccess);
s_descriptorPreferBuiltinOrFrameworkType);
private readonly ImmutableArray<TLanguageKindEnum> _kindsOfInterest;
......@@ -98,7 +93,10 @@ public sealed override void Initialize(AnalysisContext context)
protected abstract void AnalyzeNode(SyntaxNodeAnalysisContext context);
protected abstract bool CanSimplifyTypeNameExpressionCore(SemanticModel model, SyntaxNode node, OptionSet optionSet, out TextSpan issueSpan, out string diagnosticId, CancellationToken cancellationToken);
protected abstract bool CanSimplifyTypeNameExpressionCore(
SemanticModel model, SyntaxNode node, OptionSet optionSet,
out TextSpan issueSpan, out string diagnosticId, out bool inDeclaration,
CancellationToken cancellationToken);
protected abstract string GetLanguageName();
......@@ -113,7 +111,10 @@ protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode nod
return false;
}
if (!CanSimplifyTypeNameExpressionCore(model, node, optionSet, out var issueSpan, out string diagnosticId, cancellationToken))
if (!CanSimplifyTypeNameExpressionCore(
model, node, optionSet,
out var issueSpan, out var diagnosticId, out var inDeclaration,
cancellationToken))
{
return false;
}
......@@ -142,18 +143,15 @@ protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode nod
(descriptor, severity) = GetRemoveQualificationDiagnosticDescriptor(model, node, optionSet, cancellationToken);
break;
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId:
option = CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration;
(descriptor, severity) = GetApplicablePredefinedTypeDiagnosticDescriptor(
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId, option, optionSet);
break;
case IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId:
option = inDeclaration
? CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration
: CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess;
descriptor = s_descriptorPreferBuiltinOrFrameworkType;
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId:
option = CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess;
(descriptor, severity) = GetApplicablePredefinedTypeDiagnosticDescriptor(
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId, option, optionSet);
var optionValue = optionSet.GetOption(option, GetLanguageName());
severity = optionValue.Notification.Severity;
break;
default:
throw ExceptionUtilities.UnexpectedValue(diagnosticId);
}
......@@ -171,31 +169,6 @@ protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode nod
return true;
}
private (DiagnosticDescriptor descriptor, ReportDiagnostic severity) GetApplicablePredefinedTypeDiagnosticDescriptor<T>(string id, PerLanguageOption<T> option, OptionSet optionSet) where T : CodeStyleOption<bool>
{
var optionValue = optionSet.GetOption(option, GetLanguageName());
DiagnosticDescriptor descriptor = null;
if (optionValue.Notification.Severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) < ReportDiagnostic.Hidden)
{
switch (id)
{
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId:
descriptor = s_descriptorPreferIntrinsicTypeInDeclarations;
break;
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId:
descriptor = s_descriptorPreferIntrinsicTypeInMemberAccess;
break;
default:
throw ExceptionUtilities.UnexpectedValue(id);
}
}
return (descriptor, optionValue.Notification.Severity);
}
private (DiagnosticDescriptor descriptor, ReportDiagnostic severity) GetRemoveQualificationDiagnosticDescriptor(SemanticModel model, SyntaxNode node, OptionSet optionSet, CancellationToken cancellationToken)
{
var symbolInfo = model.GetSymbolInfo(node, cancellationToken);
......
// 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;
using System.Threading;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
......@@ -41,7 +39,7 @@ private void AnalyzeOperation(OperationAnalysisContext context)
var option = optionSet.GetOption(CodeStyleOptions.PreferExplicitTupleNames, context.Compilation.Language);
var severity = option.Notification.Severity;
if (severity.WithDefaultSeverity(DiagnosticSeverity.Hidden) >= ReportDiagnostic.Hidden)
if (severity == ReportDiagnostic.Suppress)
{
return;
}
......
......@@ -2,7 +2,7 @@
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Diagnostics.PreferFrameworkType
Imports Microsoft.CodeAnalysis.PreferFrameworkType
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Diagnostics.Analyzers
......
......@@ -4,8 +4,8 @@ Imports System.Collections.Immutable
Imports System.Threading
Imports Microsoft.CodeAnalysis.CodeStyle
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Diagnostics.SimplifyTypeNames
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.SimplifyTypeNames
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
......@@ -57,11 +57,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.SimplifyTypeNames
Return node IsNot Nothing AndAlso IsNodeKindInteresting(node)
End Function
Protected Overrides Function CanSimplifyTypeNameExpressionCore(model As SemanticModel, node As SyntaxNode, optionSet As OptionSet, ByRef issueSpan As TextSpan, ByRef diagnosticId As String, cancellationToken As CancellationToken) As Boolean
Return CanSimplifyTypeNameExpression(model, node, optionSet, issueSpan, diagnosticId, cancellationToken)
Protected Overrides Function CanSimplifyTypeNameExpressionCore(
model As SemanticModel, node As SyntaxNode, optionSet As OptionSet,
ByRef issueSpan As TextSpan, ByRef diagnosticId As String, ByRef inDeclaration As Boolean,
cancellationToken As CancellationToken) As Boolean
Return CanSimplifyTypeNameExpression(
model, node, optionSet, issueSpan, diagnosticId, inDeclaration, cancellationToken)
End Function
Friend Overrides Function CanSimplifyTypeNameExpression(model As SemanticModel, node As SyntaxNode, optionSet As OptionSet, ByRef issueSpan As TextSpan, ByRef diagnosticId As String, cancellationToken As CancellationToken) As Boolean
Friend Overrides Function CanSimplifyTypeNameExpression(
model As SemanticModel, node As SyntaxNode, optionSet As OptionSet,
ByRef issueSpan As TextSpan, ByRef diagnosticId As String, ByRef inDeclaration As Boolean,
cancellationToken As CancellationToken) As Boolean
issueSpan = Nothing
diagnosticId = IDEDiagnosticIds.SimplifyNamesDiagnosticId
......@@ -77,9 +84,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.SimplifyTypeNames
' set proper diagnostic ids.
If replacementSyntax.HasAnnotations(NameOf(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration)) Then
diagnosticId = IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId
inDeclaration = True
diagnosticId = IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId
ElseIf replacementSyntax.HasAnnotations(NameOf(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess)) Then
diagnosticId = IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId
inDeclaration = False
diagnosticId = IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId
ElseIf expression.Kind = SyntaxKind.SimpleMemberAccessExpression Then
Dim memberAccess = DirectCast(expression, MemberAccessExpressionSyntax)
Dim method = model.GetMemberGroup(expression)
......
......@@ -21,11 +21,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.SimplifyTypeNames
Protected Overrides Function GetTitle(simplifyDiagnosticId As String, nodeText As String) As String
Select Case simplifyDiagnosticId
Case IDEDiagnosticIds.SimplifyNamesDiagnosticId,
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId
IDEDiagnosticIds.PreferBuiltInOrFrameworkTypeDiagnosticId
Return String.Format(VBFeaturesResources.Simplify_name_0, nodeText)
Case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId,
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId
Case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId
Return String.Format(VBFeaturesResources.Simplify_member_access_0, nodeText)
Case IDEDiagnosticIds.RemoveQualificationDiagnosticId
......
......@@ -141,8 +141,8 @@ public IInteractiveWindow CurrentWindow
_currentWindow = value;
_workspace.Window = value;
_interactiveHost.Output = _currentWindow.OutputWriter;
_interactiveHost.ErrorOutput = _currentWindow.ErrorOutputWriter;
_interactiveHost.SetOutput( _currentWindow.OutputWriter);
_interactiveHost.SetErrorOutput(_currentWindow.ErrorOutputWriter);
_currentWindow.SubmissionBufferAdded += SubmissionBufferAdded;
_interactiveCommands = _commandsFactory.CreateInteractiveCommands(_currentWindow, CommandPrefix, _commands);
......@@ -447,8 +447,8 @@ Task<ExecutionResult> IInteractiveEvaluator.InitializeAsync()
var window = GetCurrentWindowOrThrow();
var resetOptions = ResetOptions;
_interactiveHost.Output = window.OutputWriter;
_interactiveHost.ErrorOutput = window.ErrorOutputWriter;
_interactiveHost.SetOutput(window.OutputWriter);
_interactiveHost.SetErrorOutput(window.ErrorOutputWriter);
return ResetAsyncWorker(GetHostOptions(initialize: true, resetOptions.Is64Bit));
}
......
......@@ -81,8 +81,8 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
if (!initializationResult.Success)
{
remoteService.Dispose(joinThreads: false);
Host.ReportProcessExited(remoteService.Process);
remoteService.Dispose(joinThreads: false);
return default;
}
......
......@@ -74,9 +74,14 @@ private async void ProcessExitedHandler(object _, EventArgs __)
_processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
// Should set _processExitHandlerStatus before calling OnProcessExited to avoid deadlocks.
// Calling the host should be within the lock to prevent its disposing during the execution.
await _host.OnProcessExited(Process).ConfigureAwait(false);
}
}
var host = _host;
if (host != null)
{
await host.OnProcessExited(Process).ConfigureAwait(false);
}
}
catch (Exception e) when (FatalError.Report(e))
{
......@@ -114,19 +119,17 @@ private void ReadOutput(bool error)
}
}
// Dispose may called anytime.
internal void Dispose(bool joinThreads)
{
// There can be a call from host initiated from OnProcessExit.
// This check on the beginning helps to avoid a reentrancy.
if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
// We should not proceed with disposing if _disposeSemaphore is locked.
using (_disposeSemaphore.DisposableWait())
{
using (_disposeSemaphore.DisposableWait())
if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
{
if (_processExitHandlerStatus == ProcessExitHandlerStatus.Hooked)
{
Process.Exited -= ProcessExitedHandler;
_processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
}
Process.Exited -= ProcessExitedHandler;
_processExitHandlerStatus = ProcessExitHandlerStatus.Handled;
}
}
......
......@@ -41,6 +41,8 @@ internal sealed partial class InteractiveHost : MarshalByRefObject
private TextWriter _output;
private TextWriter _errorOutput;
private readonly object _outputGuard;
private readonly object _errorOutputGuard;
internal event Action<bool> ProcessStarting;
......@@ -54,6 +56,8 @@ internal sealed partial class InteractiveHost : MarshalByRefObject
_errorOutput = TextWriter.Null;
_replServiceProviderType = replServiceProviderType;
_initialWorkingDirectory = workingDirectory;
_outputGuard = new object();
_errorOutputGuard = new object();
var serverProvider = new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full };
_serverChannel = new IpcServerChannel(GenerateUniqueChannelLocalName(), "ReplChannel-" + Guid.NewGuid(), serverProvider);
......@@ -68,9 +72,9 @@ internal sealed partial class InteractiveHost : MarshalByRefObject
internal Process TryGetProcess()
{
InitializedRemoteService initializedService;
return (_lazyRemoteService?.InitializedService != null &&
_lazyRemoteService.InitializedService.TryGetValue(out initializedService)) ? initializedService.ServiceOpt.Process : null;
var lazyRemoteService = _lazyRemoteService;
return (lazyRemoteService?.InitializedService != null &&
lazyRemoteService.InitializedService.TryGetValue(out initializedService)) ? initializedService.ServiceOpt.Process : null;
}
internal Service TryGetService()
......@@ -169,7 +173,11 @@ private RemoteService TryStartProcess(string hostPath, CultureInfo culture, Canc
return null;
}
_output.WriteLine(FeaturesResources.Attempt_to_connect_to_process_Sharp_0_failed_retrying, newProcessId);
lock (_outputGuard)
{
_output.WriteLine(FeaturesResources.Attempt_to_connect_to_process_Sharp_0_failed_retrying, newProcessId);
}
cancellationToken.ThrowIfCancellationRequested();
}
......@@ -215,8 +223,12 @@ private bool CheckAlive(Process process, string hostPath)
bool alive = process.IsAlive();
if (!alive)
{
_errorOutput.WriteLine(FeaturesResources.Failed_to_launch_0_process_exit_code_colon_1_with_output_colon, hostPath, process.ExitCode);
_errorOutput.WriteLine(process.StandardError.ReadToEnd());
string errorString = process.StandardError.ReadToEnd();
lock (_errorOutputGuard)
{
_errorOutput.WriteLine(FeaturesResources.Failed_to_launch_0_process_exit_code_colon_1_with_output_colon, hostPath, process.ExitCode);
_errorOutput.WriteLine(errorString);
}
}
return alive;
......@@ -227,9 +239,12 @@ private bool CheckAlive(Process process, string hostPath)
DisposeRemoteService(disposing: false);
}
// Dispose may be called anytime.
public void Dispose()
{
DisposeChannel();
SetOutput(TextWriter.Null);
SetErrorOutput(TextWriter.Null);
DisposeRemoteService(disposing: true);
GC.SuppressFinalize(this);
}
......@@ -252,41 +267,31 @@ private void DisposeChannel()
}
}
public TextWriter Output
public void SetOutput(TextWriter value)
{
get
if (value == null)
{
return _output;
throw new ArgumentNullException(nameof(value));
}
set
lock(_outputGuard)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
var oldOutput = Interlocked.Exchange(ref _output, value);
oldOutput.Flush();
_output.Flush();
_output = value;
}
}
public TextWriter ErrorOutput
public void SetErrorOutput(TextWriter value)
{
get
if (value == null)
{
return _errorOutput;
throw new ArgumentNullException(nameof(value));
}
set
lock(_errorOutputGuard)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
var oldOutput = Interlocked.Exchange(ref _errorOutput, value);
oldOutput.Flush();
_errorOutput.Flush();
_errorOutput = value;
}
}
......@@ -294,8 +299,12 @@ internal void OnOutputReceived(bool error, char[] buffer, int count)
{
(error ? ErrorOutputReceived : OutputReceived)?.Invoke(buffer, count);
var writer = error ? ErrorOutput : Output;
writer.Write(buffer, 0, count);
var writer = error ? _errorOutput : _output;
var guard = error ? _errorOutputGuard : _outputGuard;
lock (guard)
{
writer.Write(buffer, 0, count);
}
}
private LazyRemoteService CreateRemoteService(InteractiveHostOptions options, bool skipInitialization)
......@@ -323,7 +332,10 @@ private void ReportProcessExited(Process process)
if (exitCode.HasValue)
{
_errorOutput.WriteLine(FeaturesResources.Hosting_process_exited_with_exit_code_0, exitCode.Value);
lock (_errorOutputGuard)
{
_errorOutput.WriteLine(FeaturesResources.Hosting_process_exited_with_exit_code_0, exitCode.Value);
}
}
}
......@@ -333,11 +345,14 @@ private async Task<InitializedRemoteService> TryGetOrCreateRemoteServiceAsync(bo
{
LazyRemoteService currentRemoteService = _lazyRemoteService;
// disposed or not reset:
Debug.Assert(currentRemoteService != null);
for (int attempt = 0; attempt < MaxAttemptsToCreateProcess; attempt++)
{
// Remote service may be disposed anytime.
if (currentRemoteService == null)
{
return default;
}
var initializedService = await currentRemoteService.InitializedService.GetValueAsync(currentRemoteService.CancellationSource.Token).ConfigureAwait(false);
if (initializedService.ServiceOpt != null && initializedService.ServiceOpt.Process.IsAlive())
{
......@@ -362,7 +377,10 @@ private async Task<InitializedRemoteService> TryGetOrCreateRemoteServiceAsync(bo
}
}
_errorOutput.WriteLine(FeaturesResources.Unable_to_create_hosting_process);
lock (_errorOutputGuard)
{
_errorOutput.WriteLine(FeaturesResources.Unable_to_create_hosting_process);
}
}
catch (OperationCanceledException)
{
......
......@@ -92,8 +92,8 @@ private void RedirectOutput()
_synchronizedOutput = new SynchronizedStringWriter();
_synchronizedErrorOutput = new SynchronizedStringWriter();
ClearOutput();
_host.Output = _synchronizedOutput;
_host.ErrorOutput = _synchronizedErrorOutput;
_host.SetOutput(_synchronizedOutput);
_host.SetErrorOutput(_synchronizedErrorOutput);
}
private static ImmutableArray<string> SplitLines(string text)
......
......@@ -25,6 +25,11 @@ internal sealed class AnalyzerFileWatcherService
private readonly IVsFileChangeEx _fileChangeService;
private readonly Dictionary<string, FileChangeTracker> _fileChangeTrackers = new Dictionary<string, FileChangeTracker>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Holds a list of assembly modified times that we can use to detect a file change prior to the <see cref="FileChangeTracker"/> being in place.
/// Once it's in place and subscribed, we'll remove the entry because any further changes will be detected that way.
/// </summary>
private readonly Dictionary<string, DateTime> _assemblyUpdatedTimesUtc = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);
private readonly object _guard = new object();
......@@ -47,27 +52,6 @@ internal sealed class AnalyzerFileWatcherService
_updateSource = hostDiagnosticUpdateSource;
_fileChangeService = (IVsFileChangeEx)serviceProvider.GetService(typeof(SVsFileChangeEx));
}
internal void ErrorIfAnalyzerAlreadyLoaded(ProjectId projectId, string analyzerPath)
{
DateTime loadedAssemblyUpdateTimeUtc;
lock (_guard)
{
if (!_assemblyUpdatedTimesUtc.TryGetValue(analyzerPath, out loadedAssemblyUpdateTimeUtc))
{
return;
}
}
DateTime? fileUpdateTimeUtc = GetLastUpdateTimeUtc(analyzerPath);
if (fileUpdateTimeUtc != null &&
loadedAssemblyUpdateTimeUtc != fileUpdateTimeUtc)
{
RaiseAnalyzerChangedWarning(projectId, analyzerPath);
}
}
internal void RemoveAnalyzerAlreadyLoadedDiagnostics(ProjectId projectId, string analyzerPath)
{
_updateSource.ClearDiagnosticsForProject(projectId, Tuple.Create(s_analyzerChangedErrorId, analyzerPath));
......@@ -101,7 +85,7 @@ private void RaiseAnalyzerChangedWarning(ProjectId projectId, string analyzerPat
}
}
internal void AddPath(string filePath)
internal void TrackFilePathAndReportErrorIfChanged(string filePath, ProjectId projectId)
{
lock (_guard)
{
......@@ -114,11 +98,39 @@ internal void AddPath(string filePath)
_fileChangeTrackers.Add(filePath, tracker);
}
DateTime? fileUpdateTime = GetLastUpdateTimeUtc(filePath);
DateTime assemblyUpdatedTime;
if (fileUpdateTime.HasValue)
if (_assemblyUpdatedTimesUtc.TryGetValue(filePath, out assemblyUpdatedTime))
{
DateTime? currentFileUpdateTime = GetLastUpdateTimeUtc(filePath);
if (currentFileUpdateTime != null)
{
if (currentFileUpdateTime != assemblyUpdatedTime)
{
RaiseAnalyzerChangedWarning(projectId, filePath);
}
// If the the tracker is in place, at this point we can stop checking any further for this assembly
if (tracker.PreviousCallToStartFileChangeHasAsynchronouslyCompleted)
{
_assemblyUpdatedTimesUtc.Remove(filePath);
}
}
}
else
{
_assemblyUpdatedTimesUtc[filePath] = fileUpdateTime.Value;
// We don't have an assembly updated time. This means we either haven't ever checked it, or we have a file watcher in place.
// If the file watcher is in place, then nothing further to do. Otherwise we'll add the update time to the map for future checking
if (!tracker.PreviousCallToStartFileChangeHasAsynchronouslyCompleted)
{
DateTime? currentFileUpdateTime = GetLastUpdateTimeUtc(filePath);
if (currentFileUpdateTime != null)
{
_assemblyUpdatedTimesUtc[filePath] = currentFileUpdateTime.Value;
}
}
}
}
}
......
......@@ -40,6 +40,12 @@ internal sealed class DiagnosticProgressReporter
_taskCenterService = (IVsTaskStatusCenterService)serviceProvider.GetService(typeof(SVsTaskStatusCenterService));
_diagnosticService = diagnosticService;
_options = new TaskHandlerOptions()
{
Title = ServicesVSResources.Live_code_analysis,
ActionsAfterCompletion = CompletionActions.None
};
var crawlerService = workspace.Services.GetService<ISolutionCrawlerService>();
var reporter = crawlerService.GetProgressReporter(workspace);
......@@ -48,12 +54,6 @@ internal sealed class DiagnosticProgressReporter
// no event unsubscription since it will remain alive until VS shutdown
reporter.ProgressChanged += OnSolutionCrawlerProgressChanged;
_diagnosticService.DiagnosticsUpdated += OnDiagnosticsUpdated;
_options = new TaskHandlerOptions()
{
Title = ServicesVSResources.Live_code_analysis,
ActionsAfterCompletion = CompletionActions.None
};
}
private void OnDiagnosticsUpdated(object sender, DiagnosticsUpdatedArgs e)
......
......@@ -61,8 +61,7 @@ public void AddAnalyzerReference(string analyzerAssemblyFullPath)
if (File.Exists(analyzerAssemblyFullPath))
{
GetAnalyzerFileWatcherService().AddPath(analyzerAssemblyFullPath);
GetAnalyzerFileWatcherService().ErrorIfAnalyzerAlreadyLoaded(Id, analyzerAssemblyFullPath);
GetAnalyzerFileWatcherService().TrackFilePathAndReportErrorIfChanged(analyzerAssemblyFullPath, projectId: Id);
}
else
{
......
......@@ -5,6 +5,8 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
......@@ -82,7 +84,7 @@ private class StandardTextDocument : ForegroundThreadAffinitizedObject, IVisualS
// The project system does not tell us the CodePage specified in the proj file, so
// we use null to auto-detect.
_doNotAccessDirectlyLoader = new FileTextLoader(documentKey.Moniker, defaultEncoding: null);
_doNotAccessDirectlyLoader = new FileChangeTrackingTextLoader(_fileChangeTracker, new FileTextLoader(documentKey.Moniker, defaultEncoding: null));
// If we aren't already open in the editor, then we should create a file change notification
if (openTextBuffer == null)
......@@ -135,7 +137,6 @@ public TextLoader Loader
{
get
{
_fileChangeTracker.EnsureSubscription();
return _doNotAccessDirectlyLoader;
}
}
......@@ -237,6 +238,33 @@ public uint GetItemId()
return Project.Hierarchy.TryGetItemId(_itemMoniker);
}
/// <summary>
/// A wrapper for a <see cref="TextLoader"/> that ensures we are watching file contents prior to reading the file.
/// </summary>
private sealed class FileChangeTrackingTextLoader : TextLoader
{
private readonly FileChangeTracker _fileChangeTracker;
private readonly TextLoader _innerTextLoader;
public FileChangeTrackingTextLoader(FileChangeTracker fileChangeTracker, TextLoader innerTextLoader)
{
_fileChangeTracker = fileChangeTracker;
_innerTextLoader = innerTextLoader;
}
public override Task<TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
{
_fileChangeTracker.EnsureSubscription();
return _innerTextLoader.LoadTextAndVersionAsync(workspace, documentId, cancellationToken);
}
internal override TextAndVersion LoadTextAndVersionSynchronously(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken)
{
_fileChangeTracker.EnsureSubscription();
return _innerTextLoader.LoadTextAndVersionSynchronously(workspace, documentId, cancellationToken);
}
}
}
}
}
......@@ -67,6 +67,18 @@ public string FilePath
get { return _filePath; }
}
/// <summary>
/// Returns true if a previous call to <see cref="StartFileChangeListeningAsync"/> has completed.
/// </summary>
public bool PreviousCallToStartFileChangeHasAsynchronouslyCompleted
{
get
{
var cookie = _fileChangeCookie;
return cookie != s_none && cookie.IsValueCreated;
}
}
public void AssertUnsubscription()
{
// We must have been disposed properly.
......
......@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Execution;
using Microsoft.CodeAnalysis.Host;
......@@ -31,7 +32,7 @@ internal partial class VisualStudioMetadataReference
internal sealed class Snapshot : PortableExecutableReference, ISupportTemporaryStorage
{
private readonly VisualStudioMetadataReferenceManager _provider;
private readonly DateTime _timestamp;
private readonly Lazy<DateTime> _timestamp;
private Exception _error;
internal Snapshot(VisualStudioMetadataReferenceManager provider, MetadataReferenceProperties properties, string fullPath)
......@@ -40,20 +41,29 @@ internal Snapshot(VisualStudioMetadataReferenceManager provider, MetadataReferen
Contract.Requires(Properties.Kind == MetadataImageKind.Assembly);
_provider = provider;
try
{
_timestamp = FileUtilities.GetFileTimeStamp(this.FilePath);
}
catch (IOException e)
{
// Reading timestamp of a file might fail.
// Let's remember the failure and report it to the compiler when it asks for metadata.
_error = e;
}
_timestamp = new Lazy<DateTime>(() => {
try
{
return FileUtilities.GetFileTimeStamp(this.FilePath);
}
catch (IOException e)
{
// Reading timestamp of a file might fail.
// Let's remember the failure and report it to the compiler when it asks for metadata.
// We could let the Lazy hold onto this (since it knows how to rethrow exceptions), but
// our support of GetStorages needs to gracefully handle the case where we have no timestamp.
// If Lazy had a "IsValueFaulted" we could be cleaner here.
_error = e;
return DateTime.MinValue;
}
}, LazyThreadSafetyMode.PublicationOnly);
}
protected override Metadata GetMetadataImpl()
{
// Fetch the timestamp first, so as to populate _error if needed
var timestamp = _timestamp.Value;
if (_error != null)
{
throw _error;
......@@ -61,7 +71,7 @@ protected override Metadata GetMetadataImpl()
try
{
return _provider.GetMetadata(this.FilePath, _timestamp);
return _provider.GetMetadata(this.FilePath, timestamp);
}
catch (Exception e) when (SaveMetadataReadingException(e))
{
......@@ -98,7 +108,7 @@ private string GetDebuggerDisplay()
public IEnumerable<ITemporaryStreamStorage> GetStorages()
{
return _provider.GetStorages(this.FilePath, _timestamp);
return _provider.GetStorages(this.FilePath, _timestamp.Value);
}
}
}
......
......@@ -48,14 +48,17 @@ void Method()
var analyzerType = typeof(CSharpUseExplicitTypeDiagnosticAnalyzer);
var analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType);
Assert.True(analyzerResult.IsEmpty);
var diagnostics = analyzerResult.SemanticLocals[analyzerResult.DocumentIds.First()];
Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id);
Assert.Equal(DiagnosticSeverity.Hidden, diagnostics[0].Severity);
// set option
workspace.Options = workspace.Options.WithChangedOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent, new CodeStyleOption<bool>(false, NotificationOption.Suggestion));
analyzerResult = await AnalyzeAsync(workspace, workspace.CurrentSolution.ProjectIds.First(), analyzerType);
var diagnostics = analyzerResult.SemanticLocals[analyzerResult.DocumentIds.First()];
diagnostics = analyzerResult.SemanticLocals[analyzerResult.DocumentIds.First()];
Assert.Equal(IDEDiagnosticIds.UseExplicitTypeDiagnosticId, diagnostics[0].Id);
Assert.Equal(DiagnosticSeverity.Info, diagnostics[0].Severity);
}
}
......
......@@ -18,16 +18,17 @@ internal struct TypeStyleResult
private readonly CancellationToken _cancellationToken;
/// <summary>
/// Whether or not converting would transition the code to the style the user prefers. i.e.
/// if the user likes 'var' for everything, and you have 'int i = 0' then IsStylePreffered
/// will be true. however, if the user likes 'var' for everything and you have 'var i = 0',
/// then it's still possible to convert that, it would just be 'false' for IsStylePreferred
/// because it goes against the user's preferences.
///
/// In general, most features should only convert the type if IsStylePreferred is true. The
/// one exception is the refactoring, which is explicitly there to still let people convert
/// things quickly, even if it's going against their stated style.
/// Whether or not converting would transition the code to the style the user prefers. i.e. if the user likes
/// <c>var</c> for everything, and you have <c>int i = 0</c> then <see cref="IsStylePreferred"/> will be
/// <see langword="true"/>. However, if the user likes <c>var</c> for everything and you have <c>var i = 0</c>,
/// then it's still possible to convert that, it would just be <see langword="false"/> for
/// <see cref="IsStylePreferred"/> because it goes against the user's preferences.
/// </summary>
/// <remarks>
/// <para>In general, most features should only convert the type if <see cref="IsStylePreferred"/> is
/// <see langword="true"/>. The one exception is the refactoring, which is explicitly there to still let people
/// convert things quickly, even if it's going against their stated style.</para>
/// </remarks>
public readonly bool IsStylePreferred;
public readonly ReportDiagnostic Severity;
......
......@@ -98,6 +98,7 @@ public static bool TryParseNotification(string value, out NotificationOption not
notification = NotificationOption.None;
return true;
case EditorConfigSeverityStrings.Refactoring:
case EditorConfigSeverityStrings.Silent:
notification = NotificationOption.Silent;
return true;
......
......@@ -31,7 +31,7 @@ public DiagnosticSeverity Value
}
public static readonly NotificationOption None = new NotificationOption(WorkspacesResources.None, ReportDiagnostic.Suppress);
public static readonly NotificationOption Silent = new NotificationOption(WorkspacesResources.None, ReportDiagnostic.Hidden);
public static readonly NotificationOption Silent = new NotificationOption(WorkspacesResources.Refactoring_Only, ReportDiagnostic.Hidden);
public static readonly NotificationOption Suggestion = new NotificationOption(WorkspacesResources.Suggestion, ReportDiagnostic.Info);
public static readonly NotificationOption Warning = new NotificationOption(WorkspacesResources.Warning, ReportDiagnostic.Warn);
public static readonly NotificationOption Error = new NotificationOption(WorkspacesResources.Error, ReportDiagnostic.Error);
......
......@@ -416,6 +416,7 @@ internal enum FunctionId
RemoteHostService_SynchronizeTextAsync,
SymbolFinder_Solution_Pattern_FindSourceDeclarationsAsync,
SymbolFinder_Project_Pattern_FindSourceDeclarationsAsync
SymbolFinder_Project_Pattern_FindSourceDeclarationsAsync,
Intellisense_Completion_Commit,
}
}
......@@ -52,6 +52,7 @@ private static ReportDiagnostic ParseEnforcementLevel(string ruleSeverity)
case EditorConfigSeverityStrings.None:
return ReportDiagnostic.Suppress;
case EditorConfigSeverityStrings.Refactoring:
case EditorConfigSeverityStrings.Silent:
return ReportDiagnostic.Hidden;
......
......@@ -5,6 +5,7 @@ namespace Microsoft.CodeAnalysis
internal static class EditorConfigSeverityStrings
{
public const string None = "none";
public const string Refactoring = "refactoring";
public const string Silent = "silent";
public const string Suggestion = "suggestion";
public const string Warning = "warning";
......
......@@ -1052,6 +1052,15 @@ internal class WorkspacesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Refactoring Only.
/// </summary>
internal static string Refactoring_Only {
get {
return ResourceManager.GetString("Refactoring_Only", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Removed:.
/// </summary>
......
......@@ -616,4 +616,7 @@
<data name="Changing_document_property_is_not_supported" xml:space="preserve">
<value>Changing document properties is not supported</value>
</data>
<data name="Refactoring_Only" xml:space="preserve">
<value>Refactoring Only</value>
</data>
</root>
\ No newline at end of file
......@@ -7,6 +7,11 @@
<target state="translated">Došlo k chybě při čtení zadaného konfiguračního souboru: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Symbol {0} nepochází ze zdroje.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Beim Lesen der angegebenen Konfigurationsdatei ist ein Fehler aufgetreten: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Symbol "{0}" ist nicht aus Quelle.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Error al leer el archivo de configuración especificado: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">El símbolo "{0}" no procede del código fuente.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Une erreur s'est produite lors de la lecture du fichier de configuration spécifié : {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Le symbole "{0}" ne provient pas de la source.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Si è verificato un errore durante la lettura del file di configurazione specificato: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Il simbolo "{0}" non proviene dall'origine.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">指定した構成ファイルの読み取り中にエラーが発生しました: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">シンボル "{0}" は、ソースからではありません。</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">지정한 구성 파일을 읽는 동안 오류가 발생했습니다({0}).</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">"{0}" 기호가 소스에 없습니다.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Wystąpił błąd podczas odczytywania określonego pliku konfiguracji: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Symbol „{0}” nie pochodzi ze źródła.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Ocorreu um erro ao ler o arquivo de configuração especificado: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Símbolo "{0}" não é da fonte.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Произошла ошибка при чтении указанного файла конфигурации: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">Символ "{0}" не из источника.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">Belirtilen yapılandırma dosyası okunurken bir hata oluştu: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">"{0}" sembolü kaynağa ait değil.</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">读取指定的配置文件时出错: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">符号“{0}”不是来自源。</target>
......
......@@ -7,6 +7,11 @@
<target state="translated">讀取指定的組態檔時發生錯誤: {0}</target>
<note />
</trans-unit>
<trans-unit id="Refactoring_Only">
<source>Refactoring Only</source>
<target state="new">Refactoring Only</target>
<note />
</trans-unit>
<trans-unit id="Symbol_0_is_not_from_source">
<source>Symbol "{0}" is not from source.</source>
<target state="translated">符號 "{0}" 非來自來源。</target>
......
......@@ -14,12 +14,14 @@ public class EditorConfigCodeStyleParserTests
{
[Theory]
[InlineData("true:none", true, ReportDiagnostic.Suppress)]
[InlineData("true:refactoring", true, ReportDiagnostic.Hidden)]
[InlineData("true:silent", true, ReportDiagnostic.Hidden)]
[InlineData("true:suggestion", true, ReportDiagnostic.Info)]
[InlineData("true:warning", true, ReportDiagnostic.Warn)]
[InlineData("true:error", true, ReportDiagnostic.Error)]
[InlineData("true", false, ReportDiagnostic.Hidden)]
[InlineData("false:none", false, ReportDiagnostic.Suppress)]
[InlineData("false:refactoring", false, ReportDiagnostic.Hidden)]
[InlineData("false:silent", false, ReportDiagnostic.Hidden)]
[InlineData("false:suggestion", false, ReportDiagnostic.Info)]
[InlineData("false:warning", false, ReportDiagnostic.Warn)]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册