Skip to content

Commit

Permalink
Merge pull request #29929 from dotnet/merges/dev16.0.x-to-master
Browse files Browse the repository at this point in the history
Merge dev16.0.x to master
  • Loading branch information
dotnet-automerge-bot committed Sep 20, 2018
2 parents d7cd622 + 7b2e39a commit 1060b7c
Show file tree
Hide file tree
Showing 21 changed files with 541 additions and 229 deletions.
Expand Up @@ -457,6 +457,21 @@ class C : I
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task PropertyIsUnused_ExplicitInterfaceImplementation()
{
await TestMissingInRegularAndScriptAsync(
@"interface I
{
int P { get; set; }
}
class C : I
{
int I.[|P|] { get { return 0; } set { } }
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task FieldIsUnused_Const()
{
Expand Down Expand Up @@ -1707,6 +1722,125 @@ class C2
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task StructLayoutAttribute_ExplicitLayout()
{
await TestMissingInRegularAndScriptAsync(
@"using System.Runtime.InteropServices;
[StructLayoutAttribute(LayoutKind.Explicit)]
class C
{
[FieldOffset(0)]
private int [|i|];
[FieldOffset(4)]
private int i2;
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task StructLayoutAttribute_SequentialLayout()
{
await TestMissingInRegularAndScriptAsync(
@"using System.Runtime.InteropServices;
[StructLayoutAttribute(LayoutKind.Sequential)]
struct S
{
private int [|i|];
private int i2;
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnType_ReferencesField()
{
await TestMissingInRegularAndScriptAsync(
@"[System.Diagnostics.DebuggerDisplayAttribute(""{s}"")]
class C
{
private string [|s|];
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnType_ReferencesMethod()
{
await TestMissingInRegularAndScriptAsync(
@"[System.Diagnostics.DebuggerDisplayAttribute(""{GetString()}"")]
class C
{
private string [|GetString|]() => """";
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnType_ReferencesProperty()
{
await TestMissingInRegularAndScriptAsync(
@"[System.Diagnostics.DebuggerDisplayAttribute(""{MyString}"")]
class C
{
private string [|MyString|] => """";
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnField_ReferencesField()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
private string [|s|];
[System.Diagnostics.DebuggerDisplayAttribute(""{s}"")]
public int M;
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnProperty_ReferencesMethod()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
private string [|GetString|]() => """";
[System.Diagnostics.DebuggerDisplayAttribute(""{GetString()}"")]
public int M => 0;
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnProperty_ReferencesProperty()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
private string [|MyString|] { get { return """"; } }
[System.Diagnostics.DebuggerDisplayAttribute(""{MyString}"")]
public int M { get { return 0; } }
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task DebuggerDisplayAttribute_OnNestedTypeMember_ReferencesField()
{
await TestMissingInRegularAndScriptAsync(
@"class C
{
private static string [|s|];
class Nested
{
[System.Diagnostics.DebuggerDisplayAttribute(""{C.s}"")]
public int M;
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsRemoveUnusedMembers)]
public async Task FixAllFields_Document()
{
Expand Down
@@ -0,0 +1,68 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.CodeQuality
{
internal abstract class AbstractCodeQualityDiagnosticAnalyzer : DiagnosticAnalyzer, IBuiltInAnalyzer
{
private readonly GeneratedCodeAnalysisFlags _generatedCodeAnalysisFlags;

protected AbstractCodeQualityDiagnosticAnalyzer(
ImmutableArray<DiagnosticDescriptor> descriptors,
GeneratedCodeAnalysisFlags generatedCodeAnalysisFlags)
{
SupportedDiagnostics = descriptors;
_generatedCodeAnalysisFlags = generatedCodeAnalysisFlags;
}

public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }

public sealed override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(_generatedCodeAnalysisFlags);
context.EnableConcurrentExecution();

InitializeWorker(context);
}

protected abstract void InitializeWorker(AnalysisContext context);

public abstract DiagnosticAnalyzerCategory GetAnalyzerCategory();
public abstract bool OpenFileOnly(Workspace workspace);

protected static DiagnosticDescriptor CreateDescriptor(
string id,
LocalizableString title,
LocalizableString messageFormat,
bool isUnneccessary,
bool isEnabledByDefault = true,
bool isConfigurable = true,
params string[] customTags)
{
var customTagsBuilder = ArrayBuilder<string>.GetInstance();
customTagsBuilder.AddRange(customTags.Concat(WellKnownDiagnosticTags.Telemetry));

if (!isConfigurable)
{
customTagsBuilder.Add(WellKnownDiagnosticTags.NotConfigurable);
}

if (isUnneccessary)
{
customTagsBuilder.Add(WellKnownDiagnosticTags.Unnecessary);
}

return new DiagnosticDescriptor(
id, title, messageFormat,
DiagnosticCategory.CodeQuality,
DiagnosticSeverity.Info,
isEnabledByDefault,
customTags: customTagsBuilder.ToArrayAndFree());
}
}
}
Expand Up @@ -2,7 +2,6 @@

using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Diagnostics;
using Roslyn.Utilities;
Expand Down Expand Up @@ -58,23 +57,15 @@ internal abstract class AbstractCodeStyleDiagnosticAnalyzer : DiagnosticAnalyzer
Descriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor);
}

protected AbstractCodeStyleDiagnosticAnalyzer(ImmutableArray<DiagnosticDescriptor> diagnosticDescriptors)
{
Debug.Assert(diagnosticDescriptors.Length > 0);
SupportedDiagnostics = diagnosticDescriptors;
}

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }

protected DiagnosticDescriptor CreateUnnecessaryDescriptor()
=> CreateUnnecessaryDescriptor(DescriptorId);

protected DiagnosticDescriptor CreateUnnecessaryDescriptor(string descriptorId)
=> CreateUnnecessaryDescriptor(descriptorId, _localizableTitle, _localizableMessageFormat, _configurable, enabledByDefault: true);
=> CreateDescriptorWithId(
descriptorId, _localizableTitle, _localizableMessageFormat,
DiagnosticCustomTags.Unnecessary);

protected static DiagnosticDescriptor CreateUnnecessaryDescriptor(
string id, LocalizableString title, LocalizableString messageFormat, bool configurable, bool enabledByDefault)
=> CreateDescriptor(id, title, messageFormat, configurable, enabledByDefault, DiagnosticCustomTags.Unnecessary);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }

protected DiagnosticDescriptor CreateDescriptor(params string[] customTags)
=> CreateDescriptorWithId(DescriptorId, _localizableTitle, _localizableMessageFormat, customTags);
Expand All @@ -85,13 +76,8 @@ protected DiagnosticDescriptor CreateDescriptorWithTitle(LocalizableString title
protected DiagnosticDescriptor CreateDescriptorWithId(
string id, LocalizableString title, LocalizableString messageFormat,
params string[] customTags)
=> CreateDescriptor(id, title, messageFormat, _configurable, customTags: customTags, enabledByDefault: true);

protected static DiagnosticDescriptor CreateDescriptor(
string id, LocalizableString title, LocalizableString messageFormat,
bool configurable, bool enabledByDefault, params string[] customTags)
{
if (!configurable)
if (!_configurable)
{
customTags = customTags.Concat(WellKnownDiagnosticTags.NotConfigurable).ToArray();
}
Expand All @@ -100,7 +86,7 @@ protected DiagnosticDescriptor CreateDescriptorWithTitle(LocalizableString title
id, title, messageFormat,
DiagnosticCategory.Style,
DiagnosticSeverity.Hidden,
isEnabledByDefault: enabledByDefault,
isEnabledByDefault: true,
customTags: customTags);
}

Expand Down
Expand Up @@ -5,6 +5,7 @@ namespace Microsoft.CodeAnalysis.Diagnostics
internal static class DiagnosticCategory
{
public static readonly string Style = FeaturesResources.Style;
public static readonly string CodeQuality = FeaturesResources.Code_Quality;
public static readonly string EditAndContinue = FeaturesResources.Edit_and_Continue2;
public static readonly string Compiler = FeaturesResources.Compiler1;
}
Expand Down
46 changes: 27 additions & 19 deletions src/Features/Core/Portable/FeaturesResources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions src/Features/Core/Portable/FeaturesResources.resx
Expand Up @@ -1421,17 +1421,20 @@ This version used in: {2}</value>
<data name="Remove_unused_member" xml:space="preserve">
<value>Remove unused member</value>
</data>
<data name="Type_0_has_an_unused_private_member_1_which_can_be_removed" xml:space="preserve">
<value>Type '{0}' has an unused private member '{1}' which can be removed.</value>
<data name="Private_member_0_is_unused" xml:space="preserve">
<value>Private member '{0}' is unused.</value>
</data>
<data name="Remove_unused_private_members" xml:space="preserve">
<value>Remove unused private members</value>
</data>
<data name="Remove_unread_private_members" xml:space="preserve">
<value>Remove unread private members</value>
</data>
<data name="Type_0_has_a_private_member_1_that_can_be_removed_as_the_value_assigned_to_it_is_never_read" xml:space="preserve">
<value>Type '{0}' has a private member '{1}' that can be removed as the value assigned to it is never read.</value>
<data name="Private_member_0_can_be_removed_as_the_value_assigned_to_it_is_never_read" xml:space="preserve">
<value>Private member '{0}' can be removed as the value assigned to it is never read.</value>
</data>
<data name="Code_Quality" xml:space="preserve">
<value>Code Quality</value>
</data>
<data name="Invert_conditional" xml:space="preserve">
<value>Invert conditional</value>
Expand Down

0 comments on commit 1060b7c

Please sign in to comment.