From b42117c3c26b15c76321db06596379cbd5e3b827 Mon Sep 17 00:00:00 2001 From: srivatsn Date: Fri, 30 Jan 2015 11:55:32 -0800 Subject: [PATCH] Removing IVT from workspaces to FxCop analyzers Now that Matt has gone through the fxcop fixers and switched them to use SyntaxGenerator, we can remove IVT from workspaces - i just needed to add a few simple helpers - nothing unreasonable. (changeset 1407864) --- ...CSharpFxCopRulesDiagnosticAnalyzers.csproj | 8 +- .../CodeFixes/CA1052CSharpCodeFixProvider.cs | 28 +++--- .../CodeFixes/CA1309CSharpCodeFixProvider.cs | 4 +- .../CodeFixes/CA2213CSharpCodeFixProvider.cs | 2 +- .../FxCop/Core/CodeFixProviderBase.cs | 2 +- .../AssemblyAttributesDiagnosticAnalyzer.cs | 2 - .../Core/Design/CA1003DiagnosticAnalyzer.cs | 2 - .../Core/Design/CA1017DiagnosticAnalyzer.cs | 2 - .../Core/Design/CA1018DiagnosticAnalyzer.cs | 1 - .../Core/Design/CA1019DiagnosticAnalyzer.cs | 1 - .../Core/Design/CA1024DiagnosticAnalyzer.cs | 2 - .../CodeFixes/CA1001CodeFixProviderBase.cs | 1 - .../CodeFixes/CA1008CodeFixProviderBase.cs | 6 +- .../Design/CodeFixes/CA1012CodeFixProvider.cs | 2 - .../EnumWithFlagsCodeFixProviderBase.cs | 7 +- .../Design/EnumWithFlagsDiagnosticAnalyzer.cs | 7 +- .../FxCop/Core/DiagnosticCustomTags.cs | 17 +--- .../FxCop/Core/DocumentChangeAction.cs | 31 +++++++ .../Core/FxCopRulesDiagnosticAnalyzers.csproj | 9 +- .../Globalization/CA1309DiagnosticAnalyzer.cs | 1 - .../CodeFixes/CA1309CodeFixProviderBase.cs | 1 - .../PInvokeDiagnosticAnalyzer.cs | 2 - .../Core/Naming/CA1708DiagnosticAnalyzer.cs | 4 +- .../Core/Naming/CA1715DiagnosticAnalyzer.cs | 2 - .../Performance/CA1813DiagnosticAnalyzer.cs | 1 - .../Performance/CA1821DiagnosticAnalyzer.cs | 3 - .../CodeFixes/CA1813CodeFixProviderBase.cs | 1 - .../Reliability/CA2002DiagnosticAnalyzer.cs | 3 - .../Shared/CommonAccessibilityUtilities.cs | 2 - .../FxCop/Core/Shared/DiagnosticHelpers.cs | 6 +- .../Shared/Extensions/DiagnosticExtensions.cs | 1 - .../Extensions/IEnumerableExtensions.cs | 89 +++++++++++++++++++ .../Extensions/INamedTypeSymbolExtensions.cs | 2 +- .../Shared/Extensions/ISymbolExtensions.cs | 84 ++++++++++++++++- .../Extensions/ITypeSymbolExtensions.cs | 3 +- .../Shared/Extensions/ObjectExtensions.cs | 2 +- .../FxCop/Core/Shared/WordParser.cs | 3 - .../FxCop/Core/Shared/WordParserOptions.cs | 4 - .../FxCop/Core/SolutionChangeAction.cs | 31 +++++++ .../Core/Usage/CA2200DiagnosticAnalyzer.cs | 5 -- .../Core/Usage/CA2213DiagnosticAnalyzer.cs | 5 -- .../Core/Usage/CA2214DiagnosticAnalyzer.cs | 6 +- .../Core/Usage/CA2231DiagnosticAnalyzer.cs | 2 - .../CodeFixes/CA2213CodeFixProviderBase.cs | 1 - .../Usage/CodeFixes/CA2229CodeFixProvider.cs | 1 - .../CodeFixes/CA2231CodeFixProviderBase.cs | 1 - .../CodeFixes/CA2235CodeFixProviderBase.cs | 59 +++++++----- .../Usage/CodeFixes/CA2237CodeFixProvider.cs | 1 - .../SerializationRulesDiagnosticAnalyzer.cs | 4 - .../CodeFixes/CA1052BasicCodeFixProvider.vb | 24 ++--- .../EnumWithFlagsBasicCodeFixProvider.vb | 2 +- .../CodeFixes/CA1309BasicCodeFixProvider.vb | 4 +- .../CodeFixes/CA2213BasicCodeFixProvider.vb | 2 +- .../Core/Portable/Workspaces.csproj | 3 - 54 files changed, 343 insertions(+), 156 deletions(-) create mode 100644 src/Diagnostics/FxCop/Core/DocumentChangeAction.cs create mode 100644 src/Diagnostics/FxCop/Core/Shared/Extensions/IEnumerableExtensions.cs create mode 100644 src/Diagnostics/FxCop/Core/SolutionChangeAction.cs diff --git a/src/Diagnostics/FxCop/CSharp/CSharpFxCopRulesDiagnosticAnalyzers.csproj b/src/Diagnostics/FxCop/CSharp/CSharpFxCopRulesDiagnosticAnalyzers.csproj index 94d688c9b89..1cdc5bf52f6 100644 --- a/src/Diagnostics/FxCop/CSharp/CSharpFxCopRulesDiagnosticAnalyzers.csproj +++ b/src/Diagnostics/FxCop/CSharp/CSharpFxCopRulesDiagnosticAnalyzers.csproj @@ -75,13 +75,17 @@ - + + true + - + + true + diff --git a/src/Diagnostics/FxCop/CSharp/Design/CodeFixes/CA1052CSharpCodeFixProvider.cs b/src/Diagnostics/FxCop/CSharp/Design/CodeFixes/CA1052CSharpCodeFixProvider.cs index 950dd66bc6d..ac9852cd844 100644 --- a/src/Diagnostics/FxCop/CSharp/Design/CodeFixes/CA1052CSharpCodeFixProvider.cs +++ b/src/Diagnostics/FxCop/CSharp/Design/CodeFixes/CA1052CSharpCodeFixProvider.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Immutable; using System.Composition; +using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; @@ -34,22 +36,28 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) cancellationToken.ThrowIfCancellationRequested(); var root = await document.GetSyntaxRootAsync(cancellationToken); - var classDeclaration = root.FindToken(span.Start).GetAncestor(); + var classDeclaration = root.FindToken(span.Start).Parent?.FirstAncestorOrSelf(); if (classDeclaration != null) { - var staticKeyword = SyntaxFactory.Token(SyntaxKind.StaticKeyword).WithAdditionalAnnotations(Formatter.Annotation); - var newDeclaration = classDeclaration.AddModifiers(staticKeyword); - var newRoot = root.ReplaceNode(classDeclaration, newDeclaration); - context.RegisterCodeFix( - new MyCodeAction(string.Format(FxCopRulesResources.StaticHolderTypeIsNotStatic, classDeclaration.Identifier.Text), document.WithSyntaxRoot(newRoot)), - context.Diagnostics); + + var title = string.Format(FxCopRulesResources.StaticHolderTypeIsNotStatic, classDeclaration.Identifier.Text); + var codeAction = new MyCodeAction(title, ct => AddStaticKeyword(document, root, classDeclaration)); + context.RegisterCodeFix(codeAction, context.Diagnostics); } } - private class MyCodeAction : CodeAction.DocumentChangeAction + private Task AddStaticKeyword(Document document, SyntaxNode root, ClassDeclarationSyntax classDeclaration) + { + var staticKeyword = SyntaxFactory.Token(SyntaxKind.StaticKeyword).WithAdditionalAnnotations(Formatter.Annotation); + var newDeclaration = classDeclaration.AddModifiers(staticKeyword); + var newRoot = root.ReplaceNode(classDeclaration, newDeclaration); + return Task.FromResult(document.WithSyntaxRoot(newRoot)); + } + + private class MyCodeAction : DocumentChangeAction { - public MyCodeAction(string title, Document newDocument) : - base(title, c => Task.FromResult(newDocument)) + public MyCodeAction(string title, Func> createChangedDocument) : + base(title, createChangedDocument) { } } diff --git a/src/Diagnostics/FxCop/CSharp/Globalization/CodeFixes/CA1309CSharpCodeFixProvider.cs b/src/Diagnostics/FxCop/CSharp/Globalization/CodeFixes/CA1309CSharpCodeFixProvider.cs index 0b6f91769b8..8614eb73753 100644 --- a/src/Diagnostics/FxCop/CSharp/Globalization/CodeFixes/CA1309CSharpCodeFixProvider.cs +++ b/src/Diagnostics/FxCop/CSharp/Globalization/CodeFixes/CA1309CSharpCodeFixProvider.cs @@ -21,7 +21,7 @@ internal override Task GetUpdatedDocumentAsync(Document document, Sema // if nothing can be fixed, return the unchanged node var newRoot = root; var kind = nodeToFix.Kind(); - var syntaxFactoryService = document.GetLanguageService(); + var syntaxFactoryService = document.Project.LanguageServices.GetService(); switch (kind) { case SyntaxKind.Argument: @@ -44,7 +44,7 @@ internal override Task GetUpdatedDocumentAsync(Document document, Sema // string.Equals(a, b) => string.Equals(a, b, StringComparison.Ordinal) // string.Compare(a, b) => string.Compare(a, b, StringComparison.Ordinal) var identifier = (IdentifierNameSyntax)nodeToFix; - var invokeParent = identifier.GetAncestor(); + var invokeParent = identifier.Parent?.FirstAncestorOrSelf(); if (invokeParent != null) { var methodSymbol = model.GetSymbolInfo(identifier, cancellationToken).Symbol as IMethodSymbol; diff --git a/src/Diagnostics/FxCop/CSharp/Usage/CodeFixes/CA2213CSharpCodeFixProvider.cs b/src/Diagnostics/FxCop/CSharp/Usage/CodeFixes/CA2213CSharpCodeFixProvider.cs index 1c893820119..af139debcd3 100644 --- a/src/Diagnostics/FxCop/CSharp/Usage/CodeFixes/CA2213CSharpCodeFixProvider.cs +++ b/src/Diagnostics/FxCop/CSharp/Usage/CodeFixes/CA2213CSharpCodeFixProvider.cs @@ -45,7 +45,7 @@ internal override Task GetUpdatedDocumentAsync(Document document, Sema return Task.FromResult(document); } - var factory = document.GetLanguageService(); + var factory = document.Project.LanguageServices.GetService(); var symbol = model.GetDeclaredSymbol(syntaxNode, cancellationToken); // handle a case where a local in the Dipose method with the same name by generating this (or ClassName) and simplifying it diff --git a/src/Diagnostics/FxCop/Core/CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/CodeFixProviderBase.cs index 39a0d8ab288..d826d7d27fb 100644 --- a/src/Diagnostics/FxCop/Core/CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/CodeFixProviderBase.cs @@ -39,7 +39,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) } } - private class MyCodeAction : CodeAction.DocumentChangeAction + private class MyCodeAction : DocumentChangeAction { public MyCodeAction(string title, Document newDocument) : base(title, c => Task.FromResult(newDocument)) diff --git a/src/Diagnostics/FxCop/Core/Design/AssemblyAttributesDiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/AssemblyAttributesDiagnosticAnalyzer.cs index 3f0d429d421..8b8f2ece519 100644 --- a/src/Diagnostics/FxCop/Core/Design/AssemblyAttributesDiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/AssemblyAttributesDiagnosticAnalyzer.cs @@ -1,8 +1,6 @@ // 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.Threading; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; diff --git a/src/Diagnostics/FxCop/Core/Design/CA1003DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/CA1003DiagnosticAnalyzer.cs index 4e6902503e0..40ad6e6c496 100644 --- a/src/Diagnostics/FxCop/Core/Design/CA1003DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/CA1003DiagnosticAnalyzer.cs @@ -3,11 +3,9 @@ using System; using System.Collections.Immutable; using System.Linq; -using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Shared.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design { diff --git a/src/Diagnostics/FxCop/Core/Design/CA1017DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/CA1017DiagnosticAnalyzer.cs index e799832ae4a..494af99a65f 100644 --- a/src/Diagnostics/FxCop/Core/Design/CA1017DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/CA1017DiagnosticAnalyzer.cs @@ -1,9 +1,7 @@ // 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.Threading; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; diff --git a/src/Diagnostics/FxCop/Core/Design/CA1018DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/CA1018DiagnosticAnalyzer.cs index 13409a4b635..994d66dcd8e 100644 --- a/src/Diagnostics/FxCop/Core/Design/CA1018DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/CA1018DiagnosticAnalyzer.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design diff --git a/src/Diagnostics/FxCop/Core/Design/CA1019DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/CA1019DiagnosticAnalyzer.cs index 46dea66b283..99940ff39cd 100644 --- a/src/Diagnostics/FxCop/Core/Design/CA1019DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/CA1019DiagnosticAnalyzer.cs @@ -6,7 +6,6 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design diff --git a/src/Diagnostics/FxCop/Core/Design/CA1024DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/CA1024DiagnosticAnalyzer.cs index 0805d8e0720..01c10587233 100644 --- a/src/Diagnostics/FxCop/Core/Design/CA1024DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/CA1024DiagnosticAnalyzer.cs @@ -2,9 +2,7 @@ using System; using System.Collections.Immutable; -using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design diff --git a/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1001CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1001CodeFixProviderBase.cs index 712364f855b..620ef3d6b54 100644 --- a/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1001CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1001CodeFixProviderBase.cs @@ -1,7 +1,6 @@ // 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 Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design { diff --git a/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1008CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1008CodeFixProviderBase.cs index c82f0019b07..38ea76620dc 100644 --- a/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1008CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1008CodeFixProviderBase.cs @@ -3,10 +3,12 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; @@ -39,7 +41,7 @@ protected sealed override string GetCodeFixDescription(Diagnostic diagnostic) } } - throw ExceptionUtilities.Unreachable; + throw new InvalidOperationException("This program location is thought to be unreachable."); } private static SyntaxNode GetDeclaration(ISymbol symbol) @@ -136,7 +138,7 @@ private Document GetUpdatedDocumentWithFix(Document document, SyntaxNode root, S internal sealed override async Task GetUpdatedDocumentAsync(Document document, SemanticModel model, SyntaxNode root, SyntaxNode nodeToFix, Diagnostic diagnostic, CancellationToken cancellationToken) { ISymbol declaredSymbol = model.GetDeclaredSymbol(nodeToFix, cancellationToken); - Contract.ThrowIfNull(declaredSymbol); + Debug.Assert(declaredSymbol != null); var editor = SymbolEditor.Create(document); diff --git a/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1012CodeFixProvider.cs b/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1012CodeFixProvider.cs index 638aa67702f..a76fa5e779f 100644 --- a/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1012CodeFixProvider.cs +++ b/src/Diagnostics/FxCop/Core/Design/CodeFixes/CA1012CodeFixProvider.cs @@ -1,7 +1,5 @@ // 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.Composition; using System.Linq; diff --git a/src/Diagnostics/FxCop/Core/Design/CodeFixes/EnumWithFlagsCodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Design/CodeFixes/EnumWithFlagsCodeFixProviderBase.cs index 2fbcb362ffb..1ac9d1c30be 100644 --- a/src/Diagnostics/FxCop/Core/Design/CodeFixes/EnumWithFlagsCodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Design/CodeFixes/EnumWithFlagsCodeFixProviderBase.cs @@ -1,14 +1,13 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Design @@ -42,7 +41,7 @@ internal virtual SyntaxNode GetUpdatedRoot(SyntaxNode root, SyntaxNode nodeToFix internal sealed override Task GetUpdatedDocumentAsync(Document document, SemanticModel model, SyntaxNode root, SyntaxNode nodeToFix, Diagnostic diagnostic, CancellationToken cancellationToken) { var flagsAttributeType = WellKnownTypes.FlagsAttribute(model.Compilation); - Contract.ThrowIfNull(flagsAttributeType); + Debug.Assert(flagsAttributeType != null); var workspace = document.Project.Solution.Workspace; var newEnumBlockSyntax = diagnostic.Id == EnumWithFlagsDiagnosticAnalyzer.RuleIdMarkEnumsWithFlags ? @@ -62,7 +61,7 @@ private static SyntaxNode AddFlagsAttribute(Workspace workspace, SyntaxNode enum private static SyntaxNode RemoveFlagsAttribute(Workspace workspace, SemanticModel model, SyntaxNode enumTypeSyntax, INamedTypeSymbol flagsAttributeType, CancellationToken cancellationToken) { var enumType = model.GetDeclaredSymbol(enumTypeSyntax, cancellationToken) as INamedTypeSymbol; - Contract.ThrowIfNull(enumType); + Debug.Assert(enumType != null); var flagsAttribute = enumType.GetAttributes().First(a => a.AttributeClass == flagsAttributeType); var attributeNode = flagsAttribute.ApplicationSyntaxReference.GetSyntax(cancellationToken); diff --git a/src/Diagnostics/FxCop/Core/Design/EnumWithFlagsDiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Design/EnumWithFlagsDiagnosticAnalyzer.cs index ab562ad8f39..c7406001ca2 100644 --- a/src/Diagnostics/FxCop/Core/Design/EnumWithFlagsDiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Design/EnumWithFlagsDiagnosticAnalyzer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Diagnostics; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; @@ -91,7 +92,7 @@ protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compi IEnumerable missingValues; if (!ShouldBeFlags(memberValues, out missingValues)) { - Contract.ThrowIfNull(missingValues); + Debug.Assert(missingValues != null); var missingValuesString = missingValues.Select(v => v.ToString()).Aggregate((i, j) => i + ", " + j); var location = GetDiagnosticLocation(symbol.DeclaringSyntaxReferences[0].GetSyntax(cancellationToken)); @@ -116,7 +117,7 @@ protected override void AnalyzeSymbol(INamedTypeSymbol symbol, Compilation compi private static bool IsContiguous(IList list) { - Contract.ThrowIfNull(list); + Debug.Assert(list != null); bool first = true; ulong previous = 0; @@ -155,7 +156,7 @@ private static bool ShouldBeFlags(IList enumValues) private static ulong GetMissingBitsInBinaryForm(IList values) { - Contract.ThrowIfNull(values); + Debug.Assert(values != null); // all the powers of two that are individually represented ulong powersOfTwo = 0; diff --git a/src/Diagnostics/FxCop/Core/DiagnosticCustomTags.cs b/src/Diagnostics/FxCop/Core/DiagnosticCustomTags.cs index fef4fbcc017..73c6e4ef047 100644 --- a/src/Diagnostics/FxCop/Core/DiagnosticCustomTags.cs +++ b/src/Diagnostics/FxCop/Core/DiagnosticCustomTags.cs @@ -1,7 +1,4 @@ -using System.Diagnostics; -using Roslyn.Utilities; - -namespace Microsoft.CodeAnalysis.Diagnostics +namespace Microsoft.CodeAnalysis.Diagnostics { internal static class DiagnosticCustomTags { @@ -14,20 +11,8 @@ public static string[] Microsoft { get { - Assert(MicrosoftCustomTags, WellKnownDiagnosticTags.Telemetry); return MicrosoftCustomTags; } } - - [Conditional("DEBUG")] - private static void Assert(string[] customTags, params string[] tags) - { - Contract.Requires(customTags.Length == tags.Length); - - for (int i = 0; i < tags.Length; i++) - { - Contract.Requires(customTags[i] == tags[i]); - } - } } } diff --git a/src/Diagnostics/FxCop/Core/DocumentChangeAction.cs b/src/Diagnostics/FxCop/Core/DocumentChangeAction.cs new file mode 100644 index 00000000000..d372e0d7380 --- /dev/null +++ b/src/Diagnostics/FxCop/Core/DocumentChangeAction.cs @@ -0,0 +1,31 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; + +namespace Microsoft.CodeAnalysis +{ + internal class DocumentChangeAction : CodeAction + { + private readonly string title; + private readonly Func> createChangedDocument; + + public DocumentChangeAction(string title, Func> createChangedDocument) + { + this.title = title; + this.createChangedDocument = createChangedDocument; + } + + public override string Title + { + get { return this.title; } + } + + protected override Task GetChangedDocumentAsync(CancellationToken cancellationToken) + { + return this.createChangedDocument(cancellationToken); + } + } +} \ No newline at end of file diff --git a/src/Diagnostics/FxCop/Core/FxCopRulesDiagnosticAnalyzers.csproj b/src/Diagnostics/FxCop/Core/FxCopRulesDiagnosticAnalyzers.csproj index 6d4a29057db..5e5617aa22c 100644 --- a/src/Diagnostics/FxCop/Core/FxCopRulesDiagnosticAnalyzers.csproj +++ b/src/Diagnostics/FxCop/Core/FxCopRulesDiagnosticAnalyzers.csproj @@ -119,6 +119,7 @@ + True @@ -147,14 +148,18 @@ + - + + true + + @@ -193,4 +198,4 @@ - + \ No newline at end of file diff --git a/src/Diagnostics/FxCop/Core/Globalization/CA1309DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Globalization/CA1309DiagnosticAnalyzer.cs index a1d0d0dd297..80325d40434 100644 --- a/src/Diagnostics/FxCop/Core/Globalization/CA1309DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Globalization/CA1309DiagnosticAnalyzer.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Immutable; -using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; diff --git a/src/Diagnostics/FxCop/Core/Globalization/CodeFixes/CA1309CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Globalization/CodeFixes/CA1309CodeFixProviderBase.cs index 051f7426c73..f93e86f50d9 100644 --- a/src/Diagnostics/FxCop/Core/Globalization/CodeFixes/CA1309CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Globalization/CodeFixes/CA1309CodeFixProviderBase.cs @@ -4,7 +4,6 @@ using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Globalization { diff --git a/src/Diagnostics/FxCop/Core/Interoperability/PInvokeDiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Interoperability/PInvokeDiagnosticAnalyzer.cs index da58ab2d81e..8a94104b2c6 100644 --- a/src/Diagnostics/FxCop/Core/Interoperability/PInvokeDiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Interoperability/PInvokeDiagnosticAnalyzer.cs @@ -1,10 +1,8 @@ // 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.Runtime.InteropServices; -using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; diff --git a/src/Diagnostics/FxCop/Core/Naming/CA1708DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Naming/CA1708DiagnosticAnalyzer.cs index 73891f52232..0ccf408329b 100644 --- a/src/Diagnostics/FxCop/Core/Naming/CA1708DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Naming/CA1708DiagnosticAnalyzer.cs @@ -6,10 +6,8 @@ using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; using Microsoft.CodeAnalysis.Shared.Extensions; -using Microsoft.CodeAnalysis.Shared.Utilities; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Naming @@ -249,7 +247,7 @@ private static void CheckNamespaceNames(IEnumerable namespaces private static string GetSymbolDisplayString(IGrouping group) { - return string.Join(", ", group.Select(s => s.ToDisplayString()).OrderBy(StringComparer.InvariantCulture)); + return string.Join(", ", group.Select(s => s.ToDisplayString()).OrderBy(k => k, StringComparer.InvariantCulture)); } public static bool IsExternallyVisible(ISymbol symbol) diff --git a/src/Diagnostics/FxCop/Core/Naming/CA1715DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Naming/CA1715DiagnosticAnalyzer.cs index 88158700bb0..2e5552bbcbb 100644 --- a/src/Diagnostics/FxCop/Core/Naming/CA1715DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Naming/CA1715DiagnosticAnalyzer.cs @@ -2,9 +2,7 @@ using System; using System.Collections.Immutable; -using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Naming diff --git a/src/Diagnostics/FxCop/Core/Performance/CA1813DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Performance/CA1813DiagnosticAnalyzer.cs index b0839af26d9..d27530f0e5a 100644 --- a/src/Diagnostics/FxCop/Core/Performance/CA1813DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Performance/CA1813DiagnosticAnalyzer.cs @@ -4,7 +4,6 @@ using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Performance diff --git a/src/Diagnostics/FxCop/Core/Performance/CA1821DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Performance/CA1821DiagnosticAnalyzer.cs index 723a6e3cd7d..944b1c6cd30 100644 --- a/src/Diagnostics/FxCop/Core/Performance/CA1821DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Performance/CA1821DiagnosticAnalyzer.cs @@ -1,10 +1,7 @@ // 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.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Performance; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Performance diff --git a/src/Diagnostics/FxCop/Core/Performance/CodeFixes/CA1813CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Performance/CodeFixes/CA1813CodeFixProviderBase.cs index 308d6531202..ae1347ec67d 100644 --- a/src/Diagnostics/FxCop/Core/Performance/CodeFixes/CA1813CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Performance/CodeFixes/CA1813CodeFixProviderBase.cs @@ -1,7 +1,6 @@ // 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 Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Performance { diff --git a/src/Diagnostics/FxCop/Core/Reliability/CA2002DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Reliability/CA2002DiagnosticAnalyzer.cs index caac545a3a9..f77e336d7aa 100644 --- a/src/Diagnostics/FxCop/Core/Reliability/CA2002DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Reliability/CA2002DiagnosticAnalyzer.cs @@ -1,12 +1,9 @@ // 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 Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Reliability { diff --git a/src/Diagnostics/FxCop/Core/Shared/CommonAccessibilityUtilities.cs b/src/Diagnostics/FxCop/Core/Shared/CommonAccessibilityUtilities.cs index 14e4b39dbf7..0cd06193272 100644 --- a/src/Diagnostics/FxCop/Core/Shared/CommonAccessibilityUtilities.cs +++ b/src/Diagnostics/FxCop/Core/Shared/CommonAccessibilityUtilities.cs @@ -1,7 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.CodeAnalysis; - namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { internal static class CommonAccessibilityUtilities diff --git a/src/Diagnostics/FxCop/Core/Shared/DiagnosticHelpers.cs b/src/Diagnostics/FxCop/Core/Shared/DiagnosticHelpers.cs index 21e74182b58..f0bb108a445 100644 --- a/src/Diagnostics/FxCop/Core/Shared/DiagnosticHelpers.cs +++ b/src/Diagnostics/FxCop/Core/Shared/DiagnosticHelpers.cs @@ -1,8 +1,8 @@ // 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.Diagnostics; using System.Linq; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { @@ -60,8 +60,8 @@ internal static bool TryConvertToUInt64(object value, SpecialType specialType, o internal static bool TryGetEnumMemberValues(INamedTypeSymbol enumType, out IList values) { - Contract.ThrowIfNull(enumType); - Contract.ThrowIfFalse(enumType.TypeKind == TypeKind.Enum); + Debug.Assert(enumType != null); + Debug.Assert(enumType.TypeKind == TypeKind.Enum); values = new List(); foreach (IFieldSymbol field in enumType.GetMembers().Where(m => m.Kind == SymbolKind.Field && !m.IsImplicitlyDeclared)) diff --git a/src/Diagnostics/FxCop/Core/Shared/Extensions/DiagnosticExtensions.cs b/src/Diagnostics/FxCop/Core/Shared/Extensions/DiagnosticExtensions.cs index 810273f502d..6e6b1d2933f 100644 --- a/src/Diagnostics/FxCop/Core/Shared/Extensions/DiagnosticExtensions.cs +++ b/src/Diagnostics/FxCop/Core/Shared/Extensions/DiagnosticExtensions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; -using Microsoft.CodeAnalysis.Diagnostics; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { diff --git a/src/Diagnostics/FxCop/Core/Shared/Extensions/IEnumerableExtensions.cs b/src/Diagnostics/FxCop/Core/Shared/Extensions/IEnumerableExtensions.cs new file mode 100644 index 00000000000..7a6b97b7457 --- /dev/null +++ b/src/Diagnostics/FxCop/Core/Shared/Extensions/IEnumerableExtensions.cs @@ -0,0 +1,89 @@ +// 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; + +namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities +{ + internal static class IEnumerableExtensions + { + public static IEnumerable Concat(this IEnumerable source, T value) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + foreach (var v in source) + { + yield return v; + } + + yield return value; + } + + public static ISet ToSet(this IEnumerable source, IEqualityComparer comparer) + { + if (source == null) + { + throw new ArgumentNullException(nameof(source)); + } + + return new HashSet(source, comparer); + } + + public static ISet ToSet(this IEnumerable source) + { + if (source == null) + { + throw new ArgumentNullException("source"); + } + + return source as ISet ?? new HashSet(source); + } + + public static IEnumerable OrderBy(this IEnumerable source, IComparer comparer) + { + return source.OrderBy(t => t, comparer); + } + + public static IEnumerable OrderBy(this IEnumerable source, Comparison compare) + { + return source.OrderBy(new ComparisonComparer(compare)); + } + + public static IEnumerable Order(this IEnumerable source) where T : IComparable + { + return source.OrderBy((t1, t2) => t1.CompareTo(t2)); + } + + private static readonly Func NotNullTest = x => x != null; + + public static IEnumerable WhereNotNull(this IEnumerable source) where T : class + { + if (source == null) + { + return ImmutableArray.Empty; + } + + return source.Where((Func)NotNullTest); + } + + private class ComparisonComparer : Comparer + { + private readonly Comparison compare; + + public ComparisonComparer(Comparison compare) + { + this.compare = compare; + } + + public override int Compare(T x, T y) + { + return compare(x, y); + } + } + } +} diff --git a/src/Diagnostics/FxCop/Core/Shared/Extensions/INamedTypeSymbolExtensions.cs b/src/Diagnostics/FxCop/Core/Shared/Extensions/INamedTypeSymbolExtensions.cs index 4de0d973af6..06f575703c2 100644 --- a/src/Diagnostics/FxCop/Core/Shared/Extensions/INamedTypeSymbolExtensions.cs +++ b/src/Diagnostics/FxCop/Core/Shared/Extensions/INamedTypeSymbolExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; -namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions +namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { internal static class INamedTypeSymbolExtensions { diff --git a/src/Diagnostics/FxCop/Core/Shared/Extensions/ISymbolExtensions.cs b/src/Diagnostics/FxCop/Core/Shared/Extensions/ISymbolExtensions.cs index 9d5435bea7f..44812e92a1b 100644 --- a/src/Diagnostics/FxCop/Core/Shared/Extensions/ISymbolExtensions.cs +++ b/src/Diagnostics/FxCop/Core/Shared/Extensions/ISymbolExtensions.cs @@ -2,7 +2,7 @@ using System.Collections.Immutable; -namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions +namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { public static class ISymbolExtensions { @@ -31,5 +31,87 @@ public static bool IsErrorType(this ISymbol symbol) symbol is ITypeSymbol && ((ITypeSymbol)symbol).TypeKind == TypeKind.Error; } + + public static bool IsConstructor(this ISymbol symbol) + { + return (symbol as IMethodSymbol)?.MethodKind == MethodKind.Constructor; + } + + public static bool IsDestructor(this ISymbol symbol) + { + return (symbol as IMethodSymbol)?.MethodKind == MethodKind.Destructor; + } + + public static bool IsIndexer(this ISymbol symbol) + { + return (symbol as IPropertySymbol)?.IsIndexer == true; + } + + public static bool IsUserDefinedOperator(this ISymbol symbol) + { + return (symbol as IMethodSymbol)?.MethodKind == MethodKind.UserDefinedOperator; + } + + public static ImmutableArray GetParameters(this ISymbol symbol) + { + return symbol.TypeSwitch( + (IMethodSymbol m) => m.Parameters, + (IPropertySymbol p) => p.Parameters, + _ => ImmutableArray.Create()); + } + + public static SymbolVisibility GetResultantVisibility(this ISymbol symbol) + { + // Start by assuming it's visible. + var visibility = SymbolVisibility.Public; + + switch (symbol.Kind) + { + case SymbolKind.Alias: + // Aliases are uber private. They're only visible in the same file that they + // were declared in. + return SymbolVisibility.Private; + + case SymbolKind.Parameter: + // Parameters are only as visible as their containing symbol + return GetResultantVisibility(symbol.ContainingSymbol); + + case SymbolKind.TypeParameter: + // Type Parameters are private. + return SymbolVisibility.Private; + } + + while (symbol != null && symbol.Kind != SymbolKind.Namespace) + { + switch (symbol.DeclaredAccessibility) + { + // If we see anything private, then the symbol is private. + case Accessibility.NotApplicable: + case Accessibility.Private: + return SymbolVisibility.Private; + + // If we see anything internal, then knock it down from public to + // internal. + case Accessibility.Internal: + case Accessibility.ProtectedAndInternal: + visibility = SymbolVisibility.Internal; + break; + + // For anything else (Public, Protected, ProtectedOrInternal), the + // symbol stays at the level we've gotten so far. + } + + symbol = symbol.ContainingSymbol; + } + + return visibility; + } + } + + public enum SymbolVisibility + { + Public, + Internal, + Private, } } diff --git a/src/Diagnostics/FxCop/Core/Shared/Extensions/ITypeSymbolExtensions.cs b/src/Diagnostics/FxCop/Core/Shared/Extensions/ITypeSymbolExtensions.cs index 8b60704a717..5558242287b 100644 --- a/src/Diagnostics/FxCop/Core/Shared/Extensions/ITypeSymbolExtensions.cs +++ b/src/Diagnostics/FxCop/Core/Shared/Extensions/ITypeSymbolExtensions.cs @@ -2,9 +2,8 @@ using System; using System.Collections.Generic; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions +namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { public static class ITypeSymbolExtensions { diff --git a/src/Diagnostics/FxCop/Core/Shared/Extensions/ObjectExtensions.cs b/src/Diagnostics/FxCop/Core/Shared/Extensions/ObjectExtensions.cs index 384c3373c17..ffbb9812e11 100644 --- a/src/Diagnostics/FxCop/Core/Shared/Extensions/ObjectExtensions.cs +++ b/src/Diagnostics/FxCop/Core/Shared/Extensions/ObjectExtensions.cs @@ -2,7 +2,7 @@ using System; -namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions +namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { internal static class ObjectExtensions { diff --git a/src/Diagnostics/FxCop/Core/Shared/WordParser.cs b/src/Diagnostics/FxCop/Core/Shared/WordParser.cs index 9e65f0558a0..bda74088e26 100644 --- a/src/Diagnostics/FxCop/Core/Shared/WordParser.cs +++ b/src/Diagnostics/FxCop/Core/Shared/WordParser.cs @@ -1,12 +1,9 @@ // 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.ObjectModel; using System.ComponentModel; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { diff --git a/src/Diagnostics/FxCop/Core/Shared/WordParserOptions.cs b/src/Diagnostics/FxCop/Core/Shared/WordParserOptions.cs index 374c42e842b..af02bcd7b45 100644 --- a/src/Diagnostics/FxCop/Core/Shared/WordParserOptions.cs +++ b/src/Diagnostics/FxCop/Core/Shared/WordParserOptions.cs @@ -1,10 +1,6 @@ // 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.Linq; -using System.Text; -using System.Threading.Tasks; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities { diff --git a/src/Diagnostics/FxCop/Core/SolutionChangeAction.cs b/src/Diagnostics/FxCop/Core/SolutionChangeAction.cs new file mode 100644 index 00000000000..7bb00f34402 --- /dev/null +++ b/src/Diagnostics/FxCop/Core/SolutionChangeAction.cs @@ -0,0 +1,31 @@ +// 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.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; + +namespace Microsoft.CodeAnalysis +{ + internal class SolutionChangeAction : CodeAction + { + private readonly string title; + private readonly Func> createChangedSolution; + + public SolutionChangeAction(string title, Func> createChangedSolution) + { + this.title = title; + this.createChangedSolution = createChangedSolution; + } + + public override string Title + { + get { return this.title; } + } + + protected override Task GetChangedSolutionAsync(CancellationToken cancellationToken) + { + return this.createChangedSolution(cancellationToken); + } + } +} diff --git a/src/Diagnostics/FxCop/Core/Usage/CA2200DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Usage/CA2200DiagnosticAnalyzer.cs index 5dfbbac6c12..ad5f56e36c0 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CA2200DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CA2200DiagnosticAnalyzer.cs @@ -1,13 +1,8 @@ // 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.Text; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/CA2213DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Usage/CA2213DiagnosticAnalyzer.cs index e6b8129e77e..211b7438067 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CA2213DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CA2213DiagnosticAnalyzer.cs @@ -1,15 +1,10 @@ // 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.Concurrent; -using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; -using System.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/CA2214DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Usage/CA2214DiagnosticAnalyzer.cs index 541547f6ce8..86d66162d98 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CA2214DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CA2214DiagnosticAnalyzer.cs @@ -1,12 +1,8 @@ // 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.Threading; using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.FxCopAnalyzers.Shared.Extensions; -using Roslyn.Utilities; +using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/CA2231DiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Usage/CA2231DiagnosticAnalyzer.cs index 2bde8c45aea..abfc0605297 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CA2231DiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CA2231DiagnosticAnalyzer.cs @@ -1,13 +1,11 @@ // 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; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2213CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2213CodeFixProviderBase.cs index fe813aad581..019ff630377 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2213CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2213CodeFixProviderBase.cs @@ -1,7 +1,6 @@ // 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 Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2229CodeFixProvider.cs b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2229CodeFixProvider.cs index 6ba8e08c20d..e563e631ff5 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2229CodeFixProvider.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2229CodeFixProvider.cs @@ -1,6 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Diagnostics; diff --git a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2231CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2231CodeFixProviderBase.cs index f3e9d35089e..84e6e08a4a1 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2231CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2231CodeFixProviderBase.cs @@ -1,7 +1,6 @@ // 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 Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2235CodeFixProviderBase.cs b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2235CodeFixProviderBase.cs index 44e537cb21a..7109c71961a 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2235CodeFixProviderBase.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2235CodeFixProviderBase.cs @@ -1,5 +1,6 @@ // 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; @@ -21,54 +22,66 @@ public sealed override ImmutableArray FixableDiagnosticIds protected abstract SyntaxNode GetFieldDeclarationNode(SyntaxNode node); - internal async override Task> GetFixesAsync(Document document, SemanticModel model, SyntaxNode root, SyntaxNode nodeToFix, CancellationToken cancellationToken) + internal override Task> GetFixesAsync(Document document, SemanticModel model, SyntaxNode root, SyntaxNode nodeToFix, CancellationToken cancellationToken) { - IEnumerable actions = null; + var actions = ImmutableArray.CreateBuilder(); // Fix 1: Add a NonSerialized attribute to the field var fieldNode = GetFieldDeclarationNode(nodeToFix); if (fieldNode != null) { var generator = SyntaxGenerator.GetGenerator(document); - var attr = generator.Attribute(generator.TypeExpression(WellKnownTypes.NonSerializedAttribute(model.Compilation))); - var newNode = generator.AddAttributes(fieldNode, attr); - var newDocument = document.WithSyntaxRoot(root.ReplaceNode(fieldNode, newNode)); - var codeAction = new MyDocumentCodeAction(FxCopFixersResources.AddNonSerializedAttribute, newDocument); - actions = SpecializedCollections.SingletonEnumerable(codeAction); + var codeAction = new MyDocumentCodeAction(FxCopFixersResources.AddNonSerializedAttribute, + async ct => await AddNonSerializedAttribute(document, model, root, fieldNode, generator).ConfigureAwait(false)); + actions.Add(codeAction); // Fix 2: If the type of the field is defined in source, then add the serializable attribute to the type. var fieldSymbol = model.GetDeclaredSymbol(nodeToFix, cancellationToken) as IFieldSymbol; var type = fieldSymbol.Type; if (type.Locations.Any(l => l.IsInSource)) { - var typeDeclNode = type.DeclaringSyntaxReferences.First().GetSyntax(cancellationToken); + var typeCodeAction = new MySolutionCodeAction(FxCopFixersResources.AddSerializableAttribute, + async ct => await AddSerializableAttributeToType(document, model, generator, type, cancellationToken).ConfigureAwait(false)); - var serializableAttr = generator.Attribute(generator.TypeExpression(WellKnownTypes.SerializableAttribute(model.Compilation))); - var newTypeDeclNode = generator.AddAttributes(typeDeclNode, serializableAttr); - var documentContainingNode = document.Project.Solution.GetDocument(typeDeclNode.SyntaxTree); - var docRoot = await documentContainingNode.GetSyntaxRootAsync(cancellationToken); - var newDocumentContainingNode = documentContainingNode.WithSyntaxRoot(docRoot.ReplaceNode(typeDeclNode, newTypeDeclNode)); - var typeCodeAction = new MySolutionCodeAction(FxCopFixersResources.AddSerializableAttribute, newDocumentContainingNode.Project.Solution); - - actions = actions.Concat(typeCodeAction); + actions.Add(typeCodeAction); } } - return actions; + return Task.FromResult>(actions.ToImmutable()); + } + + private static async Task AddSerializableAttributeToType(Document document, SemanticModel model, SyntaxGenerator generator, ITypeSymbol type, CancellationToken cancellationToken) + { + var typeDeclNode = type.DeclaringSyntaxReferences.First().GetSyntax(cancellationToken); + + var serializableAttr = generator.Attribute(generator.TypeExpression(WellKnownTypes.SerializableAttribute(model.Compilation))); + var newTypeDeclNode = generator.AddAttributes(typeDeclNode, serializableAttr); + var documentContainingNode = document.Project.Solution.GetDocument(typeDeclNode.SyntaxTree); + var docRoot = await documentContainingNode.GetSyntaxRootAsync(cancellationToken); + var newDocumentContainingNode = documentContainingNode.WithSyntaxRoot(docRoot.ReplaceNode(typeDeclNode, newTypeDeclNode)); + return newDocumentContainingNode.Project.Solution; + } + + private Task AddNonSerializedAttribute(Document document, SemanticModel model, SyntaxNode root, SyntaxNode fieldNode, SyntaxGenerator generator) + { + var attr = generator.Attribute(generator.TypeExpression(WellKnownTypes.NonSerializedAttribute(model.Compilation))); + var newNode = generator.AddAttributes(fieldNode, attr); + var newDocument = document.WithSyntaxRoot(root.ReplaceNode(fieldNode, newNode)); + return Task.FromResult(newDocument); } - private class MyDocumentCodeAction : CodeAction.DocumentChangeAction + private class MyDocumentCodeAction : DocumentChangeAction { - public MyDocumentCodeAction(string title, Document newDocument) : - base(title, c => Task.FromResult(newDocument)) + public MyDocumentCodeAction(string title, Func> createChangedDocument) : + base(title, createChangedDocument) { } } - private class MySolutionCodeAction : CodeAction.SolutionChangeAction + private class MySolutionCodeAction : SolutionChangeAction { - public MySolutionCodeAction(string title, Solution newSolution) : - base(title, c => Task.FromResult(newSolution)) + public MySolutionCodeAction(string title, Func> createChangedSolution) : + base(title, createChangedSolution) { } } diff --git a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2237CodeFixProvider.cs b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2237CodeFixProvider.cs index 568b8896b6f..38f5d668719 100644 --- a/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2237CodeFixProvider.cs +++ b/src/Diagnostics/FxCop/Core/Usage/CodeFixes/CA2237CodeFixProvider.cs @@ -7,7 +7,6 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/Core/Usage/SerializationRulesDiagnosticAnalyzer.cs b/src/Diagnostics/FxCop/Core/Usage/SerializationRulesDiagnosticAnalyzer.cs index 6ebf6226fc7..72446589065 100644 --- a/src/Diagnostics/FxCop/Core/Usage/SerializationRulesDiagnosticAnalyzer.cs +++ b/src/Diagnostics/FxCop/Core/Usage/SerializationRulesDiagnosticAnalyzer.cs @@ -1,13 +1,9 @@ // 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; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.FxCopAnalyzers.Utilities; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.FxCopAnalyzers.Usage { diff --git a/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/CA1052BasicCodeFixProvider.vb b/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/CA1052BasicCodeFixProvider.vb index 86c7d0ff8b7..1173bf15a84 100644 --- a/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/CA1052BasicCodeFixProvider.vb +++ b/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/CA1052BasicCodeFixProvider.vb @@ -34,22 +34,26 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Design cancellationToken.ThrowIfCancellationRequested() Dim root = Await document.GetSyntaxRootAsync(cancellationToken) - Dim classStatement = root.FindToken(span.Start).GetAncestor(Of ClassStatementSyntax) + Dim classStatement = root.FindToken(span.Start).Parent?.FirstAncestorOrSelf(Of ClassStatementSyntax) If classStatement IsNot Nothing Then - Dim notInheritableKeyword = SyntaxFactory.Token(SyntaxKind.NotInheritableKeyword).WithAdditionalAnnotations(Formatter.Annotation) - Dim newClassStatement = classStatement.AddModifiers(notInheritableKeyword) - Dim newRoot = root.ReplaceNode(classStatement, newClassStatement) - context.RegisterCodeFix( - New MyCodeAction(String.Format(FxCopRulesResources.StaticHolderTypeIsNotStatic, classStatement.Identifier.Text), document.WithSyntaxRoot(newRoot)), - context.Diagnostics) + Dim title As String = String.Format(FxCopRulesResources.StaticHolderTypeIsNotStatic, classStatement.Identifier.Text) + Dim fix = New MyCodeAction(title, Function(ct) AddNotInheritableKeyword(document, root, classStatement)) + context.RegisterCodeFix(fix, context.Diagnostics) End If End Function + Private Function AddNotInheritableKeyword(document As Document, root As SyntaxNode, classStatement As ClassStatementSyntax) As Task(Of Document) + Dim notInheritableKeyword = SyntaxFactory.Token(SyntaxKind.NotInheritableKeyword).WithAdditionalAnnotations(Formatter.Annotation) + Dim newClassStatement = classStatement.AddModifiers(notInheritableKeyword) + Dim newRoot = root.ReplaceNode(classStatement, newClassStatement) + Return Task.FromResult(document.WithSyntaxRoot(newRoot)) + End Function + Private Class MyCodeAction - Inherits CodeAction.DocumentChangeAction + Inherits DocumentChangeAction - Public Sub New(title As String, newDocument As Document) - MyBase.New(title, Function(c) Task.FromResult(newDocument)) + Public Sub New(title As String, createChangedDocument As Func(Of CancellationToken, Task(Of Document))) + MyBase.New(title, createChangedDocument) End Sub End Class End Class diff --git a/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/EnumWithFlagsBasicCodeFixProvider.vb b/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/EnumWithFlagsBasicCodeFixProvider.vb index aa61d432a29..6bbbf77806c 100644 --- a/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/EnumWithFlagsBasicCodeFixProvider.vb +++ b/src/Diagnostics/FxCop/VisualBasic/Design/CodeFixes/EnumWithFlagsBasicCodeFixProvider.vb @@ -30,7 +30,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Design End If End If - Throw ExceptionUtilities.Unreachable + Throw New InvalidOperationException("Unreachable code") End Function End Class End Namespace diff --git a/src/Diagnostics/FxCop/VisualBasic/Globalization/CodeFixes/CA1309BasicCodeFixProvider.vb b/src/Diagnostics/FxCop/VisualBasic/Globalization/CodeFixes/CA1309BasicCodeFixProvider.vb index 4ac9900d51e..e4819c0e98a 100644 --- a/src/Diagnostics/FxCop/VisualBasic/Globalization/CodeFixes/CA1309BasicCodeFixProvider.vb +++ b/src/Diagnostics/FxCop/VisualBasic/Globalization/CodeFixes/CA1309BasicCodeFixProvider.vb @@ -20,7 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Globalization ' if nothing can be fixed, return the unchanged node Dim newRoot = root Dim kind = nodeToFix.Kind() - Dim syntaxFactoryService = document.GetLanguageService(Of SyntaxGenerator) + Dim syntaxFactoryService = document.Project.LanguageServices.GetService(Of SyntaxGenerator) Select Case kind Case SyntaxKind.SimpleArgument If Not CType(nodeToFix, SimpleArgumentSyntax).IsNamed Then @@ -41,7 +41,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Globalization ' String.Equals(a, b) => String.Equals(a, b, StringComparison.Ordinal) ' String.Compare(a, b) => String.Compare(a, b, StringComparison.Ordinal) Dim identifier = CType(nodeToFix, IdentifierNameSyntax) - Dim invokeParent = identifier.GetAncestor(Of InvocationExpressionSyntax)() + Dim invokeParent = identifier.Parent?.FirstAncestorOrSelf(Of InvocationExpressionSyntax)() If invokeParent IsNot Nothing Then Dim methodSymbol = TryCast(model.GetSymbolInfo(identifier).Symbol, IMethodSymbol) If methodSymbol IsNot Nothing AndAlso CanAddStringComparison(methodSymbol) Then diff --git a/src/Diagnostics/FxCop/VisualBasic/Usage/CodeFixes/CA2213BasicCodeFixProvider.vb b/src/Diagnostics/FxCop/VisualBasic/Usage/CodeFixes/CA2213BasicCodeFixProvider.vb index 636c711d3df..a0c4ef23604 100644 --- a/src/Diagnostics/FxCop/VisualBasic/Usage/CodeFixes/CA2213BasicCodeFixProvider.vb +++ b/src/Diagnostics/FxCop/VisualBasic/Usage/CodeFixes/CA2213BasicCodeFixProvider.vb @@ -43,7 +43,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.FxCopAnalyzers.Usage Return Task.FromResult(document) End If - Dim factory = document.GetLanguageService(Of SyntaxGenerator)() + Dim factory = document.Project.LanguageServices.GetService(Of SyntaxGenerator)() ' Handle a case where a local in the Dipose method with the same name by generating this (or ClassName) and simplifying it Dim path = If(fieldSymbol.IsStatic, factory.IdentifierName(typeSymbol.MetadataName), factory.ThisExpression()) diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj index 321e05944d5..211f8cbde58 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -235,16 +235,13 @@ - - - -- GitLab