From b38cef381242f3f2306e4e2317ff54a58b368b13 Mon Sep 17 00:00:00 2001 From: ngobzin11 Date: Wed, 20 Apr 2016 14:51:35 -0500 Subject: [PATCH 001/152] Restricted ReadonlyFieldAnalyzer to primitive and reference types, #775 --- .../Usage/ReadonlyFieldAnalyzer.cs | 15 ++- .../Usage/ReadonlyFieldTests.cs | 95 +++++++++++++++++++ 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs b/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs index 97d3ebd64..6c031eebd 100644 --- a/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs @@ -145,8 +145,12 @@ private static Dictionary GetCandidateVa private static Dictionary GetCandidateVariables(SemanticModel semanticModel, FieldDeclarationSyntax fieldDeclaration) { var variablesToMakeReadonly = new Dictionary(); - if (fieldDeclaration == null) return variablesToMakeReadonly; - if (!CanBeMadeReadonly(fieldDeclaration)) return variablesToMakeReadonly; + if (fieldDeclaration == null || + IsComplexValueType(semanticModel, fieldDeclaration) || + !CanBeMadeReadonly(fieldDeclaration)) + { + return variablesToMakeReadonly; + } foreach (var variable in fieldDeclaration.Declaration.Variables) { if (variable.Initializer == null) continue; @@ -167,6 +171,13 @@ private static bool CanBeMadeReadonly(FieldDeclarationSyntax fieldDeclaration) || m.IsKind(SyntaxKind.ConstKeyword)); } + private static bool IsComplexValueType(SemanticModel semanticModel, FieldDeclarationSyntax fieldDeclaration) + { + var fieldTypeName = fieldDeclaration.Declaration.Type; + var fieldType = semanticModel.GetTypeInfo(fieldTypeName).ConvertedType; + return fieldType.IsValueType && !(fieldType.TypeKind == TypeKind.Enum || fieldType.IsPrimitive()); + } + private static bool CanBeMadeReadonly(IFieldSymbol fieldSymbol) { return (fieldSymbol.DeclaredAccessibility == Accessibility.NotApplicable diff --git a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs index b7fb708b6..bd528508c 100644 --- a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs @@ -846,5 +846,100 @@ static void B() }"; await VerifyCSharpHasNoDiagnosticsAsync(source); } + + [Fact] + public async Task UserDefinedStructFieldDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private MyStruct myStruct = default(MyStruct); + + private struct MyStruct + { + public int Value; + } + } + } + "; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DateTimeFieldInitializedOnDeclarationDoesNotCreateDiagnostic() + { + const string source = @" + using System; + + namespace ConsoleApplication1 + { + public class MyClass + { + private DateTime date = new DateTime(2008, 5, 1, 8, 30, 52); + } + } + "; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task EnumerationFieldInitializedOnDeclarationCreatesADiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private VehicleType car = VehicleType.Car; + + private enum VehicleType + { + None = 0, + Car = 1, + Truck = 2 + } + } + } + "; + + var expected = new DiagnosticResult + { + Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), + Message = string.Format(ReadonlyFieldAnalyzer.Message, "car"), + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 33) } + }; + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] + public async Task ReferenceTypeFieldInitializedInConstructorCreatesADiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + public class Person + { + private string name; + + public Person(string name) + { + this.name = name; + } + } + } + "; + + var expected = new DiagnosticResult + { + Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), + Message = string.Format(ReadonlyFieldAnalyzer.Message, "name"), + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 28) } + }; + await VerifyCSharpDiagnosticAsync(source, expected); + } } } From 0e2adc07c7de3eabed62e82dba60d715d434cc4f Mon Sep 17 00:00:00 2001 From: Hubert Kindermann Date: Tue, 28 Jun 2016 16:49:48 +0200 Subject: [PATCH 002/152] Fixes #773. --- .../CSharpGeneratedCodeAnalysisExtensions.cs | 14 ++-- .../GeneratedCodeAnalysisExtensionsTests.cs | 77 ++++++++----------- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/src/CSharp/CodeCracker/Extensions/CSharpGeneratedCodeAnalysisExtensions.cs b/src/CSharp/CodeCracker/Extensions/CSharpGeneratedCodeAnalysisExtensions.cs index d7386b3c5..339e64ae1 100644 --- a/src/CSharp/CodeCracker/Extensions/CSharpGeneratedCodeAnalysisExtensions.cs +++ b/src/CSharp/CodeCracker/Extensions/CSharpGeneratedCodeAnalysisExtensions.cs @@ -1,8 +1,8 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using System.Linq; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.CSharp; namespace CodeCracker { @@ -48,9 +48,13 @@ public static bool HasAutoGeneratedComment(this SyntaxTree tree) if (!firstToken.HasLeadingTrivia) return false; trivia = firstToken.LeadingTrivia; } - var commentLines = trivia.Where(t => t.IsKind(SyntaxKind.SingleLineCommentTrivia)).Take(2).ToList(); - if (commentLines.Count != 2) return false; - return commentLines[1].ToString() == "// "; + + var comments = trivia.Where(t => t.IsKind(SyntaxKind.SingleLineCommentTrivia) || t.IsKind(SyntaxKind.MultiLineCommentTrivia)); + return comments.Any(t => + { + var s = t.ToString(); + return s.Contains(" GetSymbolAnalysisContext(source).IsGenerated().Should().BeTrue(); - [Fact] - public static void SyntaxNodeAnalysis_WithAutoGeneratedCommentBasedOnWebForms() => - GetSyntaxNodeAnalysisContext( + [Theory] + [InlineData( @"//------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -304,11 +303,8 @@ namespace WebApplication3 public partial class _Default { } -}").IsGenerated().Should().BeTrue(); - - [Fact] - public static void SyntaxTreeAnalysis_WithAutoGeneratedCommentBasedOnWebForms() => - GetSyntaxTreeAnalysisContext( +}", false)] + [InlineData( @"//------------------------------------------------------------------------------ // // This code was generated by a tool. @@ -316,57 +312,46 @@ public static void SyntaxTreeAnalysis_WithAutoGeneratedCommentBasedOnWebForms() // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // -//------------------------------------------------------------------------------ - +//------------------------------------------------------------------------------", true)] + [InlineData( +@"// +// This code was generated by a tool. namespace WebApplication3 { public partial class _Default { } -}").IsGenerated().Should().BeTrue(); - - [Fact] - public static void SyntaxTreeAnalysis_WithAutoGeneratedCommentEmpty() => - GetSyntaxTreeAnalysisContext( -@"//------------------------------------------------------------------------------ -// -// This code was generated by a tool. +}", false)] + [InlineData( +@"// +// This code was generated by a tool.", true)] + [InlineData( +@"// This code was generated by a tool. // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------").IsGenerated().Should().BeTrue(); - - [Fact] - public static void SymbolicAnalysis_WithAutoGeneratedCommentBasedOnWebForms() => - GetSymbolAnalysisContext( -@"//------------------------------------------------------------------------------ // -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - namespace WebApplication3 { public partial class _Default { } -}").IsGenerated().Should().BeTrue(); - - [Fact] - public static void SyntaxNodeAnalysis_WithAutoGeneratedCommentEmpty() => - GetSyntaxNodeAnalysisContext( -@"//------------------------------------------------------------------------------ -// -// This code was generated by a tool. +}", false)] + [InlineData( +@"// This code was generated by a tool. // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------").IsGenerated().Should().BeTrue(); +// ", true)] + public static void SyntaxNodeAnalysis_WithAutoGeneratedComment(string source, bool isEmpty) + { + GetSyntaxTreeAnalysisContext(source).IsGenerated().Should().BeTrue(); + if (isEmpty) + { + GetSyntaxNodeAnalysisContext(source).IsGenerated().Should().BeTrue(); + } + else + { + GetSyntaxNodeAnalysisContext(source).IsGenerated().Should().BeTrue(); + GetSymbolAnalysisContext(source).IsGenerated().Should().BeTrue(); + } + } private static SyntaxNodeAnalysisContext GetSyntaxNodeAnalysisContext(string code, string fileName = baseProjectPath + "a.cs") => GetSyntaxNodeAnalysisContext(code, fileName); From 794c05aaedd35f207c6bc9e6c327d0c2df967f36 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 7 Aug 2016 16:22:57 -0300 Subject: [PATCH 003/152] Bump version to 1.1.0 --- src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest | 2 +- src/CSharp/CodeCracker/CodeCracker.nuspec | 2 +- src/CSharp/CodeCracker/Properties/AssemblyInfo.cs | 2 +- src/CodeCracker.nuspec | 6 +++--- src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs | 2 +- .../CodeCracker.Vsix/source.extension.vsixmanifest | 2 +- src/VisualBasic/CodeCracker/CodeCracker.nuspec | 2 +- src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb | 2 +- test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs | 2 +- .../CodeCracker.Test.Common/Properties/AssemblyInfo.cs | 2 +- .../VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest index 19b4ff34c..3a3f50bbe 100644 --- a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + Code Cracker for C# An analyzer library for C# that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. diff --git a/src/CSharp/CodeCracker/CodeCracker.nuspec b/src/CSharp/CodeCracker/CodeCracker.nuspec index f659d5f96..72744d97a 100644 --- a/src/CSharp/CodeCracker/CodeCracker.nuspec +++ b/src/CSharp/CodeCracker/CodeCracker.nuspec @@ -2,7 +2,7 @@ codecracker.CSharp - 1.0.1 + 1.1.0 CodeCracker for C# giggio,elemarjr,carloscds giggio,elemarjr,carloscds diff --git a/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs b/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs index e73618076..f63d51c3e 100644 --- a/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs +++ b/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs @@ -14,5 +14,5 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.1.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] [assembly: InternalsVisibleTo("CodeCracker.Test.CSharp")] diff --git a/src/CodeCracker.nuspec b/src/CodeCracker.nuspec index c910e7aba..f5113b83b 100644 --- a/src/CodeCracker.nuspec +++ b/src/CodeCracker.nuspec @@ -2,7 +2,7 @@ codecracker - 1.0.1 + 1.1.0 CodeCracker for C# and VB giggio,elemarjr,carloscds giggio,elemarjr,carloscds @@ -19,8 +19,8 @@ This is a community project, free and open source. Everyone is invited to contri Copyright CodeCracker 2014-2016 roslyn, analyzers - - + + diff --git a/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs b/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs index 8fd31cfbe..b57f8b71e 100644 --- a/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs +++ b/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs @@ -14,6 +14,6 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.1.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] [assembly: InternalsVisibleTo("CodeCracker.Test.CSharp")] [assembly: InternalsVisibleTo("CodeCracker.Test.VisualBasic")] \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest index 2292f0dec..6cff126bc 100644 --- a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + Code Cracker for Visual Basic An analyzer library for VB that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. diff --git a/src/VisualBasic/CodeCracker/CodeCracker.nuspec b/src/VisualBasic/CodeCracker/CodeCracker.nuspec index 70abb04ba..326c5ccb4 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.nuspec +++ b/src/VisualBasic/CodeCracker/CodeCracker.nuspec @@ -2,7 +2,7 @@ codecracker.VisualBasic - 1.0.1 + 1.1.0 CodeCracker for Visual Basic giggio,elemarjr,carloscds giggio,elemarjr,carloscds diff --git a/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb b/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb index 9f6f2650c..0758c2287 100644 --- a/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb +++ b/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb @@ -14,5 +14,5 @@ Imports System.Runtime.InteropServices - + \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs b/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs index 9da58a97d..4b18b5a68 100644 --- a/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs +++ b/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs @@ -14,4 +14,4 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.1.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.1.0.0")] \ No newline at end of file diff --git a/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs b/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs index 8c492b358..d56074edd 100644 --- a/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs +++ b/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs @@ -14,4 +14,4 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en-us")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.1.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.1.0.0")] \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb b/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb index 2599bd9f5..8823e3c6f 100644 --- a/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb +++ b/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb @@ -14,4 +14,4 @@ Imports System.Runtime.InteropServices - \ No newline at end of file + \ No newline at end of file From 27fd04d11cecb86843626b470da26ca3713841dc Mon Sep 17 00:00:00 2001 From: Carlos dos Santos Date: Mon, 22 Aug 2016 08:08:03 -0300 Subject: [PATCH 004/152] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f3ae91e29..f928ce0d9 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ msbuild Then add a reference to CodeCracker.dll from within the Analyzers node inside References, in Visual Studio. +## SonarQube Plugin + +CodeCracker has a SonarQube Plugin that was downloaded at ([Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). + ## Contributing Questions, comments, bug reports, and pull requests are all welcome. From 194ba06aae5859f9aaf8e69fdb81eba6474458d5 Mon Sep 17 00:00:00 2001 From: Carlos dos Santos Date: Mon, 22 Aug 2016 08:08:39 -0300 Subject: [PATCH 005/152] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f928ce0d9..1036a22c1 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Then add a reference to CodeCracker.dll from within the Analyzers node inside Re ## SonarQube Plugin -CodeCracker has a SonarQube Plugin that was downloaded at ([Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). +CodeCracker has a SonarQube Plugin that can downloaded at [Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). ## Contributing From 442eb755a150d4d1fbd1006d47ae2b5bdef62990 Mon Sep 17 00:00:00 2001 From: Lazaro Fernandes Lima Suleiman Date: Sun, 28 Aug 2016 16:51:48 -0300 Subject: [PATCH 006/152] Add support to remove unnecessary '.ToString()' in a string concatenation --- src/CSharp/CodeCracker/CodeCracker.csproj | 2 + ...ryToStringInStringConcatenationAnalyzer.cs | 74 +++++++ ...ingInStringConcatenationCodeFixProvider.cs | 54 +++++ src/Common/CodeCracker.Common/DiagnosticId.cs | 1 + .../CodeCracker.Test/CodeCracker.Test.csproj | 1 + ...ssaryToStringInStringConcatenationTests.cs | 208 ++++++++++++++++++ 6 files changed, 340 insertions(+) create mode 100644 src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs create mode 100644 src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationCodeFixProvider.cs create mode 100644 test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index e1a60a05e..965fba6b7 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -83,6 +83,8 @@ + + diff --git a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs new file mode 100644 index 000000000..fb9a0974a --- /dev/null +++ b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs @@ -0,0 +1,74 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Text; +using System.Collections.Immutable; +using System.Linq; + +namespace CodeCracker.CSharp.Style +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class UnnecessaryToStringInStringConcatenationAnalyzer : DiagnosticAnalyzer + { + internal const string Title = "Unnecessary '.ToString()' call in string concatenation."; + internal const string MessageFormat = Title; + internal const string Category = SupportedCategories.Style; + const string Description = "The runtime automatically calls '.ToString()' method for" + + " string concatenation operations when there is no parameters. Remove them."; + + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( + DiagnosticId.UnnecessaryToStringInStringConcatenation.ToDiagnosticId(), + Title, + MessageFormat, + Category, + DiagnosticSeverity.Info, + customTags: WellKnownDiagnosticTags.Unnecessary, + isEnabledByDefault: true, + description: Description, + helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.UnnecessaryToStringInStringConcatenation)); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) => + context.RegisterSyntaxNodeAction(Analyzer, SyntaxKind.AddExpression); + + private static void Analyzer(SyntaxNodeAnalysisContext context) + { + if (context.IsGenerated()) return; + var addExpression = context.Node as BinaryExpressionSyntax; + + if (!addExpression.IsKind(SyntaxKind.AddExpression)) return; + + var hasPlusToken = addExpression.ChildNodesAndTokens().Any(x => x.IsKind(SyntaxKind.PlusToken)); + var hasInvocationExpression = addExpression.ChildNodesAndTokens().Any(x => x.IsKind(SyntaxKind.InvocationExpression)); + + //string concatenation must have PlusToken and an InvocationExpression + if (!hasPlusToken || !hasInvocationExpression) return; + var invocationExpressionsThatHaveToStringCall = GetInvocationExpressionsThatHaveToStringCall(addExpression); + + foreach (var expression in invocationExpressionsThatHaveToStringCall) + { + var lastDot = expression.Expression.ChildNodesAndTokens().Last(x => x.IsKind(SyntaxKind.DotToken)); + var argumentList = expression.ChildNodes().Last(x => x.IsKind(SyntaxKind.ArgumentList)); + + //Only default call to ToString method must be accepted + if (expression.ArgumentList.Arguments.Count > 0) + break; + + var tree = expression.SyntaxTree; + var textspan = new TextSpan(lastDot.Span.Start, argumentList.Span.End - lastDot.Span.Start); + + var diagnostic = Diagnostic.Create(Rule, Location.Create(context.Node.SyntaxTree, textspan)); + context.ReportDiagnostic(diagnostic); + } + } + + private static System.Collections.Generic.List GetInvocationExpressionsThatHaveToStringCall(BinaryExpressionSyntax addExpression) + { + return addExpression.ChildNodes().OfType() + .Where(x => x.Expression.ToString().EndsWith(@".ToString")) + .ToList(); + } + } +} \ No newline at end of file diff --git a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationCodeFixProvider.cs new file mode 100644 index 000000000..4d895d8f5 --- /dev/null +++ b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationCodeFixProvider.cs @@ -0,0 +1,54 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using System.Collections.Immutable; +using System.Composition; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace CodeCracker.CSharp.Style +{ + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(UnnecessaryParenthesisCodeFixProvider)), Shared] + public class UnnecessaryToStringInStringConcatenationCodeFixProvider : CodeFixProvider + { + public sealed override ImmutableArray FixableDiagnosticIds => + ImmutableArray.Create(DiagnosticId.UnnecessaryToStringInStringConcatenation.ToDiagnosticId()); + + public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + + public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) + { + var diagnostic = context.Diagnostics.First(); + context.RegisterCodeFix(CodeAction.Create("Remove unnecessary ToString", ct => RemoveUnnecessaryToStringAsync(context.Document, diagnostic, ct), nameof(UnnecessaryToStringInStringConcatenationCodeFixProvider)), diagnostic); + return Task.FromResult(0); + } + private static async Task RemoveUnnecessaryToStringAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) + { + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + var invocationExpression = + root + .FindToken(diagnostic.Location.SourceSpan.Start) + .Parent + .AncestorsAndSelf() + .OfType() + .First(); + + var onlyMemberAccessNode = + invocationExpression + .ChildNodes() + .First() + .ChildNodes() + .First(); + + var newRoot = root.ReplaceNode(invocationExpression, onlyMemberAccessNode); + + var newDocument = document.WithSyntaxRoot(newRoot); + return newDocument; + } + + } + +} \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/DiagnosticId.cs b/src/Common/CodeCracker.Common/DiagnosticId.cs index 156dc6285..7d48257fd 100644 --- a/src/Common/CodeCracker.Common/DiagnosticId.cs +++ b/src/Common/CodeCracker.Common/DiagnosticId.cs @@ -80,5 +80,6 @@ public enum DiagnosticId NameOf_External = 108, StringFormatArgs_ExtraArgs = 111, AlwaysUseVarOnPrimitives = 105, + UnnecessaryToStringInStringConcatenation = 118, } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index b17ba4a79..7168f11df 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -146,6 +146,7 @@ + diff --git a/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs b/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs new file mode 100644 index 000000000..077f095e7 --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs @@ -0,0 +1,208 @@ +using CodeCracker.CSharp.Style; +using Microsoft.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +namespace CodeCracker.Test.CSharp.Style +{ + public class UnnecessaryToStringInStringConcatenationTests : CodeFixVerifier + { + [Fact] + public async Task InstantiatingAnObjectAndCallToStringInsideAStringConcatenationShouldGenerateDiagnosticResult() + { + const string source = @"var foo = ""a"" + new object().ToString();"; + + var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(1, 29); + + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] + public async Task InstantiatingAnStringBuilderAndCallToStringInsideAStringConcatenationShouldGenerateDiagnosticResult() + { + const string source = @"var foo = ""a"" + new System.Text.StringBuilder().ToString();"; + + var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(1, 48); + + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] + public async Task CallToStringForAnInstantiatedObjectInsideAStringConcatenationShouldGenerateDiagnosticResult() + { + const string test = @" + using System; + + namespace ConsoleApplication1 + { + class AuxClass + { + public override void ToString() + { + return ""Test""; + } + } + + class TypeName + { + public void Foo() + { + var auxClass = new AuxClass(); + + var bar = ""a"" + new AuxClass().ToString(); + var foo = ""a"" + auxClass.ToString(); + var far = ""a"" + new AuxClass().ToString() + auxClass.ToString() + new object().ToString(""C""); + } + } + }"; + + var expected1 = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(20, 47); + var expected2 = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(21, 41); + var expected3 = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(22, 47); + var expected4 = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(22, 69); + + var expected = new DiagnosticResult[] { expected1, expected2, expected3, expected4 }; + + await VerifyCSharpDiagnosticAsync(test, expected); + } + + [Fact] + public async Task CallToStringInsideAStringConcatenationWithAFormatParameterShouldNotGenerateDiagnosticResult() + { + const string source = @"var salary = ""salary: "" + 1000.ToString(""C"");"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + + [Fact] + public async Task CallToStringOutsideAStringConcatenationWithoutParameterShouldNotGenerateDiagnosticResult() + { + const string source = @"var value = 1000.ToString();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + + private static DiagnosticResult CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(int expectedRow, int expectedColumn) + { + var expected = new DiagnosticResult + { + Id = DiagnosticId.UnnecessaryToStringInStringConcatenation.ToDiagnosticId(), + Message = "Unnecessary '.ToString()' call in string concatenation.", + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", expectedRow, expectedColumn) } + }; + + return expected; + } + + [Fact] + public async Task FixReplacesToStringCallInAStringConcatenationWithAVariable() + { + const string test = @" + using System; + + namespace ConsoleApplication1 + { + class TypeName + { + public async Task Foo() + { + var text = ""def""; + var a = ""abc"" + text.ToString(); + Console.Log(a); + } + } + }"; + + const string expected = @" + using System; + + namespace ConsoleApplication1 + { + class TypeName + { + public async Task Foo() + { + var text = ""def""; + var a = ""abc"" + text; + Console.Log(a); + } + } + }"; + await VerifyCSharpFixAsync(test, expected); + } + + + [Fact] + public async Task FixReplacesToStringCallInAStringConcatenation() + { + const string test = @" + using System; + + namespace ConsoleApplication1 + { + class TypeName + { + public async Task Foo() + { + var a = ""abc"" + ""def"".ToString(); + Console.Log(a); + } + } + }"; + + const string expected = @" + using System; + + namespace ConsoleApplication1 + { + class TypeName + { + public async Task Foo() + { + var a = ""abc"" + ""def""; + Console.Log(a); + } + } + }"; + await VerifyCSharpFixAsync(test, expected); + } + + [Fact] + public async Task FixReplacesToStringCallInAStringConcatenationWithAnObject() + { + const string test = @" + using System; + + namespace ConsoleApplication1 + { + class TypeName + { + public async Task Foo() + { + var foo = ""a"" + new object().ToString(); + Console.Log(foo); + } + } + }"; + + const string expected = @" + using System; + + namespace ConsoleApplication1 + { + class TypeName + { + public async Task Foo() + { + var foo = ""a"" + new object(); + Console.Log(foo); + } + } + }"; + await VerifyCSharpFixAsync(test, expected); + } + } +} \ No newline at end of file From e718be3e5dd13f5fdb7b61630ae076e6355183b6 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Tue, 6 Sep 2016 16:19:36 -0300 Subject: [PATCH 007/152] Refactor UnnecessaryToStringInStringConcatenationAnalyzer --- ...ryToStringInStringConcatenationAnalyzer.cs | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs index fb9a0974a..d2c56f355 100644 --- a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs @@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -36,39 +37,28 @@ public override void Initialize(AnalysisContext context) => private static void Analyzer(SyntaxNodeAnalysisContext context) { if (context.IsGenerated()) return; - var addExpression = context.Node as BinaryExpressionSyntax; + var addExpression = (BinaryExpressionSyntax)context.Node; - if (!addExpression.IsKind(SyntaxKind.AddExpression)) return; - - var hasPlusToken = addExpression.ChildNodesAndTokens().Any(x => x.IsKind(SyntaxKind.PlusToken)); var hasInvocationExpression = addExpression.ChildNodesAndTokens().Any(x => x.IsKind(SyntaxKind.InvocationExpression)); - //string concatenation must have PlusToken and an InvocationExpression - if (!hasPlusToken || !hasInvocationExpression) return; + //string concatenation must have an InvocationExpression + if (!hasInvocationExpression) return; var invocationExpressionsThatHaveToStringCall = GetInvocationExpressionsThatHaveToStringCall(addExpression); foreach (var expression in invocationExpressionsThatHaveToStringCall) - { + { var lastDot = expression.Expression.ChildNodesAndTokens().Last(x => x.IsKind(SyntaxKind.DotToken)); - var argumentList = expression.ChildNodes().Last(x => x.IsKind(SyntaxKind.ArgumentList)); - - //Only default call to ToString method must be accepted - if (expression.ArgumentList.Arguments.Count > 0) - break; - - var tree = expression.SyntaxTree; - var textspan = new TextSpan(lastDot.Span.Start, argumentList.Span.End - lastDot.Span.Start); - - var diagnostic = Diagnostic.Create(Rule, Location.Create(context.Node.SyntaxTree, textspan)); + var toStringTextSpan = new TextSpan(lastDot.Span.Start, expression.ArgumentList.Span.End - lastDot.Span.Start); + var diagnostic = Diagnostic.Create(Rule, Location.Create(context.Node.SyntaxTree, toStringTextSpan)); context.ReportDiagnostic(diagnostic); } } - private static System.Collections.Generic.List GetInvocationExpressionsThatHaveToStringCall(BinaryExpressionSyntax addExpression) + private static IEnumerable GetInvocationExpressionsThatHaveToStringCall(BinaryExpressionSyntax addExpression) { return addExpression.ChildNodes().OfType() - .Where(x => x.Expression.ToString().EndsWith(@".ToString")) - .ToList(); + //Only default call to ToString method must be accepted + .Where(x => x.Expression.ToString().EndsWith(@".ToString") && !x.ArgumentList.Arguments.Any()); } } } \ No newline at end of file From e981d303edd938f2e3da422c21035d9002688119 Mon Sep 17 00:00:00 2001 From: Nozziel Date: Wed, 19 Oct 2016 21:15:26 +0200 Subject: [PATCH 008/152] #848 - "Disposable Field Not Disposed" rule does not recognize null propagation - Fix + Unit test --- .../DisposableFieldNotDisposedAnalyzer.cs | 38 ++++++++++++++++--- .../Usage/DisposableFieldNotDisposedTests.cs | 23 +++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/DisposableFieldNotDisposedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/DisposableFieldNotDisposedAnalyzer.cs index 2e625e04d..b90b12001 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableFieldNotDisposedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableFieldNotDisposedAnalyzer.cs @@ -92,13 +92,41 @@ private static bool CallsDisposeOnField(IFieldSymbol fieldSymbol, MethodDeclarat var hasDisposeCall = body.DescendantNodes().OfKind(SyntaxKind.InvocationExpression) .Any(invocation => { - if (!invocation?.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) ?? true) return false; - var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression; - if (memberAccess?.Name == null) return false; - if (memberAccess.Name.Identifier.ToString() != "Dispose" || memberAccess.Name.Arity != 0) return false; - return fieldSymbol.Equals(semanticModel.GetSymbolInfo(memberAccess.Expression).Symbol); + if (invocation?.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) ?? false) + { + return IsDisposeCallOnField(invocation, fieldSymbol, semanticModel); + + } + + if (invocation?.Expression?.IsKind(SyntaxKind.MemberBindingExpression) ?? false) + { + return IsDisposeWithNullPropagationCallOnField(invocation, fieldSymbol, semanticModel); + } + + return false; }); return hasDisposeCall; } + + private static bool IsDisposeCallOnField(InvocationExpressionSyntax expression, IFieldSymbol fieldSymbol, SemanticModel semanticModel) + { + var memberAccess = (MemberAccessExpressionSyntax)expression.Expression; + if (memberAccess?.Name == null) return false; + if (memberAccess.Name.Identifier.ToString() != "Dispose" || memberAccess.Name.Arity != 0) return false; + var result = fieldSymbol.Equals(semanticModel.GetSymbolInfo(memberAccess.Expression).Symbol); + return result; + } + + private static bool IsDisposeWithNullPropagationCallOnField(InvocationExpressionSyntax expression, IFieldSymbol fieldSymbol, SemanticModel semanticModel) + { + var memberBinding = (MemberBindingExpressionSyntax)expression.Expression; + if (memberBinding?.Name == null) return false; + if (memberBinding.Name.Identifier.ToString() != "Dispose" || memberBinding.Name.Arity != 0) return false; + + var conditionalAccessExpression = memberBinding.Parent.Parent as ConditionalAccessExpressionSyntax; + if (conditionalAccessExpression == null) return false; + var result = fieldSymbol.Equals(semanticModel.GetSymbolInfo(conditionalAccessExpression.Expression).Symbol); + return result; + } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs index ba84e4bc6..1c46e93f2 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs @@ -45,6 +45,29 @@ private void Dispose(bool disposing) await VerifyCSharpHasNoDiagnosticsAsync(source); } + [Fact] + public async Task WhenUsingTheDisposablePatternWithNullPropagationItDoesNotCreateDiagnostic() + { + const string source = @" +using System; +using System.IO; +public class A : IDisposable +{ + private MemoryStream disposableField = new MemoryStream(); + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + private void Dispose(bool disposing) + { + if (disposing) + disposableField?.Dispose(); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + [Fact] public async Task WhenAFieldThatImplementsIDisposableIsAssignedThroughAMethodCallCreatesDiagnostic() { From dce78e2a591fcd6f58320d5a53912942d8accf96 Mon Sep 17 00:00:00 2001 From: cezar teste Date: Thu, 27 Oct 2016 11:22:35 -0200 Subject: [PATCH 009/152] - Adding test for: bool method param, int var situations,CS0151Exception and common situations with boolean variables. --- src/CSharp/CodeCracker/CodeCracker.csproj | 2 + .../Design/SwitchWithoutDefaultAnalyzer.cs | 66 ++++ .../SwitchWithoutDefaultCodeFixProvider.cs | 121 ++++++ src/Common/CodeCracker.Common/DiagnosticId.cs | 1 + .../CodeCracker.Test/CodeCracker.Test.csproj | 1 + .../Design/SwicthWithoutDefaultTests.cs | 353 ++++++++++++++++++ 6 files changed, 544 insertions(+) create mode 100644 src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs create mode 100644 src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs create mode 100644 test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index 965fba6b7..8b9e64a32 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -46,6 +46,8 @@ + + diff --git a/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs new file mode 100644 index 000000000..b4531315f --- /dev/null +++ b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs @@ -0,0 +1,66 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + + +namespace CodeCracker.CSharp.Design +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class SwitchWithoutDefaultAnalyzer : DiagnosticAnalyzer + { + internal const string Title = "Your Switch maybe include default clause"; + internal const string MessageFormat = "{0}"; + internal const string Category = SupportedCategories.Design; + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( + DiagnosticId.SwitchCaseWithoutDefault.ToDiagnosticId(), + Title, + MessageFormat, + Category, + DiagnosticSeverity.Warning, + isEnabledByDefault: true, + helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.SwitchCaseWithoutDefault)); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) => context.RegisterSyntaxNodeAction(Analyzer, SyntaxKind.SwitchStatement); + + private static void Analyzer(SyntaxNodeAnalysisContext context) + { + if (context.IsGenerated()) return; + // checks if the compile error CS0151 it has fired.If Yes, don't report the diagnostic + var diagnostics = from dia in context.SemanticModel.GetDiagnostics() + where dia.Id == "CS0151" + select dia; + if (diagnostics.Any()) return; + if (context.Node.IsKind(SyntaxKind.SwitchStatement)) + { + var switchStatementToAnalyse = (SwitchStatementSyntax)context.Node; + if (switchStatementToAnalyse.DescendantNodes().Where(n => n.Kind() == SyntaxKind.DefaultSwitchLabel).ToList().Count == 0) + { + var hasInitializer = from nodes in switchStatementToAnalyse.DescendantNodes() + where nodes.Kind() == SyntaxKind.IdentifierName + select nodes; + if (!hasInitializer.Any()) + return; + var hasTrueExpression = from nodes in switchStatementToAnalyse.DescendantNodes() + where nodes.Kind() == SyntaxKind.FalseLiteralExpression + select nodes; + var hasfalseExpression = from nodes in switchStatementToAnalyse.DescendantNodes() + where nodes.Kind() == SyntaxKind.TrueLiteralExpression + select nodes; + if ((hasfalseExpression.Any()) && (hasTrueExpression.Any())) + return; + var diagnostic = Diagnostic.Create(Rule, switchStatementToAnalyse.GetLocation(), "Consider put an default clause in Switch."); + context.ReportDiagnostic(diagnostic); + } + } + } + } +} diff --git a/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs new file mode 100644 index 000000000..192d1ac5e --- /dev/null +++ b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs @@ -0,0 +1,121 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Formatting; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +namespace CodeCracker.CSharp.Design +{ + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(SwitchWithoutDefaultCodeFixProvider)), Shared] + public class SwitchWithoutDefaultCodeFixProvider : CodeFixProvider + { + private const string EmptyString = "\"\""; + private const string BreakString = "\n\t\t\t\t\tbreak;"; + private const string ThrowString = "throw new Exception(\"Unexpected Case\");"; + public sealed override ImmutableArray FixableDiagnosticIds => + ImmutableArray.Create(DiagnosticId.SwitchCaseWithoutDefault.ToDiagnosticId()); + public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + + public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) + { + var diagnostic = context.Diagnostics.First(); + context.RegisterCodeFix(CodeAction.Create("Add a default clause", c => SwitchWithoutDefaultAsync(context.Document, diagnostic, c), + nameof(SwitchWithoutDefaultCodeFixProvider)), diagnostic); + return Task.FromResult(0); + } + + private async static Task SwitchWithoutDefaultAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) + { + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var switchCaseLabel = new SyntaxList(); + var kindOfVariable = string.Empty; + var idForVariable = string.Empty; + var breakStatement = new SyntaxList(); + var diagnosticSpan = diagnostic.Location.SourceSpan; + var newSections = new List(); + var switchCaseStatement = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); + idForVariable = ((IdentifierNameSyntax)switchCaseStatement.ChildNodes().ToList().First(n => n.Kind() == SyntaxKind.IdentifierName)).Identifier.ValueText; + var parametersOfMethod = from init in root.DescendantNodesAndSelf() + where init.Kind() == SyntaxKind.Parameter + select init; + // Verify if the variable of Switch as a same of Method Parameter + foreach (var parameter in parametersOfMethod) + if (idForVariable == ((ParameterSyntax)parameter).Identifier.ValueText) + kindOfVariable = ((ParameterSyntax)parameter).Type.ToString(); + + if (kindOfVariable == string.Empty) + { + var statements = ((BlockSyntax)switchCaseStatement.Parent).Statements; + var inicializerOfSwitch = from init in statements + where init.Kind() == SyntaxKind.LocalDeclarationStatement + select init; + if (inicializerOfSwitch.Any()) + { + var local = (LocalDeclarationStatementSyntax)inicializerOfSwitch.First(); + var switchCaseVariable = ((local).Declaration).Variables[0]; + kindOfVariable = ((LiteralExpressionSyntax)(switchCaseVariable.Initializer.Value)).Kind().ToString(); + } + } + + if ((kindOfVariable.Equals("FalseLiteralExpression")) || (kindOfVariable.Equals("TrueLiteralExpression")) + || (kindOfVariable.Equals("bool"))) + { + var oldSections = switchCaseStatement.Sections.ToList(); + var type = string.Empty; + foreach (var sec in oldSections) + { + newSections.Add(sec); + type = (((CaseSwitchLabelSyntax)((SwitchSectionSyntax)sec).ChildNodes().ToList().First()).Value).GetFirstToken().Text; + } + var againstType = string.Empty; + if (type.Equals("true")) againstType = "false"; else againstType = "true"; + + newSections.Add(SyntaxFactory.SwitchSection().WithLabels( + switchCaseLabel.Add(SyntaxFactory.CaseSwitchLabel(SyntaxFactory.ParseExpression(againstType)))). + WithStatements(breakStatement.Add(SyntaxFactory.ParseStatement(BreakString)))); + } + else + { + var oldSections = switchCaseStatement.Sections.ToList(); + foreach (var sec in oldSections) + newSections.Add(sec); + + breakStatement = breakStatement.Add(SyntaxFactory.ParseStatement(BreakString)); + newSections.Add(CreateSection(SyntaxFactory.DefaultSwitchLabel(), SyntaxFactory.ParseStatement(ThrowString))); + } + var switchExpression = SyntaxFactory.ParseExpression(idForVariable); + var newsSwitchCaseStatement = SyntaxFactory.SwitchStatement(switchExpression). + WithSections(new SyntaxList().AddRange(newSections)); + var newRoot = root.ReplaceNode(switchCaseStatement, newsSwitchCaseStatement); + var newDocument = document.WithSyntaxRoot(newRoot); + return newDocument; + } + static SwitchSectionSyntax CreateSection(SwitchLabelSyntax label, StatementSyntax statement) + { + var labels = new SyntaxList(); + labels = labels.Add(label); + return SyntaxFactory.SwitchSection(labels, CreateSectionStatements(statement)); + } + + static SyntaxList CreateSectionStatements(StatementSyntax source) + { + var result = new SyntaxList(); + if (source is BlockSyntax) + { + var block = source as BlockSyntax; + result = result.AddRange(block.Statements); + } + else + { + result = result.Add(source); + } + return result; + } + } +} diff --git a/src/Common/CodeCracker.Common/DiagnosticId.cs b/src/Common/CodeCracker.Common/DiagnosticId.cs index 7d48257fd..1ac3b7f5e 100644 --- a/src/Common/CodeCracker.Common/DiagnosticId.cs +++ b/src/Common/CodeCracker.Common/DiagnosticId.cs @@ -81,5 +81,6 @@ public enum DiagnosticId StringFormatArgs_ExtraArgs = 111, AlwaysUseVarOnPrimitives = 105, UnnecessaryToStringInStringConcatenation = 118, + SwitchCaseWithoutDefault = 120, } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 7168f11df..915d2199d 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -129,6 +129,7 @@ + diff --git a/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs b/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs new file mode 100644 index 000000000..c9fa24b44 --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs @@ -0,0 +1,353 @@ +using CodeCracker.CSharp.Design; +using System.Threading.Tasks; +using Xunit; + +namespace CodeCracker.Test.CSharp.Design +{ + public class SwicthWithoutDefaultTests : CodeFixVerifier + { + [Fact] + public async Task SwithWithoutDefaultAnalyserString() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { +var a = """"; + switch (a) + { + case """": + break; + } + } + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { +var a = """"; + switch (a) + { + case """": + break; + default: + throw new Exception(""Unexpected Case""); + } + } + } + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + } + + [Fact] + public async Task SwithWithoutDefaultAnalyserBool() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { + var s = true; + switch (s) + { + case false: + break; + } + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { + var s = true; + switch (s) + { + case false: + break; + case true: + break; + } + } + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + } + + [Fact] + public async Task SwithWithoutDefaultAnalyserInt() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { +var s = 10; + switch (s) + { + case 10: + break; + } + +} + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { +var s = 10; + switch (s) + { + case 10: + break; + default: + throw new Exception(""Unexpected Case""); + } + } +} + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + + } + + public async Task SwithWithoutDefaultAnalyserBoolMethod() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + void Bar(bool myBool) + { + switch (myBool) + { + case false: + break; + } + } + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + void Bar(bool myBool) + { + switch (myBool) + { + case false: + break; + case true: + break; + } + } + + } + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + } + + public async Task SwithWithoutDefaultAnalyserIntMethod() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + void Bar3(int a) + { + switch (a) + { + case 10: + break; + } + } + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + void Bar3(int a) + { + switch (a) + { + case 10: + break; + default: + throw new Exception(""Unexpected Case""); + } + } +} + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + } + + public async Task SwithWithoutDefaultAnalyserIntMethodTwoParams() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { +void Bar4(int a, int b) + { + switch (a) + { + case 10: + break; + } + } + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { +void Bar4(int a, int b) + { + switch (a) + { + case 10: + break; + default: + throw new Exception(""Unexpected Case""); + } + } +} + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + } + + [Fact] + public async Task SwithWithoutDefaultAnalyserIntMethodStatic() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { +static void Bar5(int a) + { + switch (a) + { + case 10: + break; + } + } + + } + }"; + + const string fixtest = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { +static void Bar5(int a) + { + switch (a) + { + case 10: + break; + default: + throw new Exception(""Unexpected Case""); + } + } + +} + }"; + await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + } + + [Fact] + public async Task SwithWithoutDefaultAnalyseCS0151Exception() + { + const string source = @"static void M() { } + static void Main() + { + + switch (M()) // CS0151 + { + default: + break; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + + [Fact] + public async Task SwithWithoutDefaultAnalyserNoDiagnostic() + { + const string source = @"using System;namespace + ConsoleApplication1 + { + class TypeName + { + static void Main() + { + var s = ""; + switch (s) + { + case "":{break;} + default:{break;} + } + } + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task SwitchWithoutDefaultAnalyzerNoDiagnosticWithCompileError() + { + const string source = @"using System; + namespace ConsoleApplication1 + { + ConsoleApplication1 + { + class Teste { } + class Program + { + static void Main(string[] args) + { + Teste vo_teste = new Teste(); + switch (vo_teste) + { + case "":break; + default:break; + } + } + } + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + } +} From 5729fe362e47fab5492bdb6fb0ec2e7449c7d7a8 Mon Sep 17 00:00:00 2001 From: cezar teste Date: Tue, 22 Nov 2016 10:08:18 -0200 Subject: [PATCH 010/152] Fix #808 Added the suggested changes in Title and Description on ReadOnlyComplexTypesAnalyzer --- src/CSharp/CodeCracker/CodeCracker.csproj | 1 + .../Usage/ReadOnlyComplexTypesAnalyzer.cs | 69 +++ .../Usage/ReadonlyFieldCodeFixProvider.cs | 3 +- src/Common/CodeCracker.Common/DiagnosticId.cs | 1 + .../CodeCracker.Test/CodeCracker.Test.csproj | 1 + .../Usage/ReadOnlyComplexTypesTests.cs | 441 ++++++++++++++++++ 6 files changed, 515 insertions(+), 1 deletion(-) create mode 100644 src/CSharp/CodeCracker/Usage/ReadOnlyComplexTypesAnalyzer.cs create mode 100644 test/CSharp/CodeCracker.Test/Usage/ReadOnlyComplexTypesTests.cs diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index 8b9e64a32..da195cbf0 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -139,6 +139,7 @@ + diff --git a/src/CSharp/CodeCracker/Usage/ReadOnlyComplexTypesAnalyzer.cs b/src/CSharp/CodeCracker/Usage/ReadOnlyComplexTypesAnalyzer.cs new file mode 100644 index 000000000..089013936 --- /dev/null +++ b/src/CSharp/CodeCracker/Usage/ReadOnlyComplexTypesAnalyzer.cs @@ -0,0 +1,69 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using System.Collections.Immutable; +using System.Linq; +using System.Collections.Generic; +using System; + +namespace CodeCracker.CSharp.Usage +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class ReadOnlyComplexTypesAnalyzer : DiagnosticAnalyzer + { + internal const string Title = "Complex fields must be readonly"; + internal const string Message = "Make '{0}' readonly"; + internal const string Category = SupportedCategories.Usage; + const string Description = "Complex fields must be readonly"; + + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( + DiagnosticId.ReadOnlyComplexTypes.ToDiagnosticId(), + Title, + Message, + Category, + DiagnosticSeverity.Warning, + isEnabledByDefault: false, + description: Description, + helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.ReadOnlyComplexTypes)); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) => context.RegisterSyntaxNodeAction(AnalyzeNode, + new[] { SyntaxKind.FieldDeclaration }); + + private static void AnalyzeNode(SyntaxNodeAnalysisContext context) + { + if (context.IsGenerated()) return; + var fieldDeclaration = context.Node as FieldDeclarationSyntax; + var variable = fieldDeclaration?.Declaration.Variables.LastOrDefault(); + if (variable?.Initializer == null) return; + var semanticModel = context.SemanticModel; + var fieldSymbol = semanticModel.GetDeclaredSymbol(variable) as IFieldSymbol; + if (!IsComplexValueType(semanticModel, fieldDeclaration)) return; + if (!CanBeMadeReadonly(fieldSymbol)) return; + ReportDiagnostic(context, variable, variable.Initializer.Value); + } + private static bool IsComplexValueType(SemanticModel semanticModel, FieldDeclarationSyntax fieldDeclaration) + { + var fieldTypeName = fieldDeclaration.Declaration.Type; + var fieldType = semanticModel.GetTypeInfo(fieldTypeName).ConvertedType; + return fieldType.IsValueType && !(fieldType.TypeKind == TypeKind.Enum || fieldType.IsPrimitive()); + } + + private static bool CanBeMadeReadonly(IFieldSymbol fieldSymbol) + { + return (fieldSymbol.DeclaredAccessibility == Accessibility.NotApplicable + || fieldSymbol.DeclaredAccessibility == Accessibility.Private) + && !fieldSymbol.IsReadOnly + && !fieldSymbol.IsConst; + } + + private static void ReportDiagnostic(SyntaxNodeAnalysisContext context, VariableDeclaratorSyntax variable, ExpressionSyntax initializerValue) + { + var props = new Dictionary { { "identifier", variable.Identifier.Text } }.ToImmutableDictionary(); + var diag = Diagnostic.Create(Rule, variable.GetLocation(), props, initializerValue.ToString()); + context.ReportDiagnostic(diag); + } + } +} diff --git a/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs b/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs index 9b0d0be1a..1b9e85a58 100644 --- a/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Usage/ReadonlyFieldCodeFixProvider.cs @@ -16,7 +16,8 @@ namespace CodeCracker.CSharp.Usage public class ReadonlyFieldCodeFixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds => - ImmutableArray.Create(DiagnosticId.ReadonlyField.ToDiagnosticId()); + ImmutableArray.Create(DiagnosticId.ReadonlyField.ToDiagnosticId(), + DiagnosticId.ReadOnlyComplexTypes.ToDiagnosticId()); public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; diff --git a/src/Common/CodeCracker.Common/DiagnosticId.cs b/src/Common/CodeCracker.Common/DiagnosticId.cs index 1ac3b7f5e..e60eb36f8 100644 --- a/src/Common/CodeCracker.Common/DiagnosticId.cs +++ b/src/Common/CodeCracker.Common/DiagnosticId.cs @@ -82,5 +82,6 @@ public enum DiagnosticId AlwaysUseVarOnPrimitives = 105, UnnecessaryToStringInStringConcatenation = 118, SwitchCaseWithoutDefault = 120, + ReadOnlyComplexTypes = 121, } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 915d2199d..aa793b0cd 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -172,6 +172,7 @@ + diff --git a/test/CSharp/CodeCracker.Test/Usage/ReadOnlyComplexTypesTests.cs b/test/CSharp/CodeCracker.Test/Usage/ReadOnlyComplexTypesTests.cs new file mode 100644 index 000000000..d6fe05fb9 --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Usage/ReadOnlyComplexTypesTests.cs @@ -0,0 +1,441 @@ +using CodeCracker.CSharp.Usage; +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CodeCracker.Test.CSharp.Usage +{ + public class ReadOnlyComplexTypesTests : CodeFixVerifier + { + [Fact] + public async Task FieldWithAssignmentOnDeclarationAlreadyReadonlyDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + class TypeName + { + private readonly int i = 1; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task ConstantFieldDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + class TypeName + { + private const int i = 1; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task dateTimeDoesNotCreateDiagnostics() + { + const string source1 = @" +namespace codeCrackerConsole +{ + public class MyClass + { + private readonly DateTime dt = new DateTime(1, 1, 2015); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source1); + } + [Fact] + public async Task protectedFieldDoesNotCreateDiagnostics() + { + const string source = @" + namespace ConsoleApplication1 + { +public class MyClass + { + protected MyStruct myStruct = default(MyStruct); + private struct MyStruct + { + public int Value; + } + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task publicFieldDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + public MyStruct myStruct = default(MyStruct); + private struct MyStruct + { + public int Value; + } + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task publicFieldWithClassDoesNotCreateDiagnostics() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + public MyStruct myStruct = new MyStruct(); + private struct MyStruct + { + public int Value; + } + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task readOnlyVarDoesNotCreateDiagnostics() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + readonly var s = ""; + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task readOnlyFieldDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + readonly string s; + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task primitiveTypesDoesNotCreateDiagnostics() + { + const string source = @" + namespace ConsoleApplication1 + { + class test + { + private byte b = new byte(); + private sbyte s = new sbyte(); + private int i = new int(); + private uint u = new uint(); + private short ss = new short(); + public ushort us = new ushort(); + public long l = new long(); + public ulong ul = new ulong(); + public float fl = new float(); + public double d = new double(); + public char c = new char(); + public bool bo = new bool(); + public object o = new object(); + public string st = ""; + public decimal dc = new decimal(); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task enumDoesNotCreateDiagnostics() + { + const string source = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private test testEnum; + public enum test + { + test1 = 1, + test2 = 2 + } + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + [Fact] + public async Task IgnoreOut() + { + const string source = @" +public class C +{ + private string field = ""; + private static void Foo(out string bar) => bar = ""; + public void Baz() => Foo(out field); +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task IgnoreRef() + { + const string source = @" +public class C +{ + private string field = ""; + private static void Foo(ref string bar) => bar = ""; + public void Baz() => Foo(ref field); +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task IgnoreAssignmentToFieldsInOtherTypes() + { + const string source1 = @" +class TypeName1 +{ + public int i; +}"; + const string source2 = @" +class TypeName2 +{ + public TypeName2() + { + var t = new TypeName1(); + t.i = 1; + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source1, source2 }); + } + + [Fact] + public async Task FieldWithoutAssignmentDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + class TypeName + { + private int i; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task FieldWithoutAssignmentInAStructDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + struct TypeName + { + private int i; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task PublicFieldWithAssignmentOnDeclarationDoesNotCreateDiagnostic() + { + const string source = @" + namespace ConsoleApplication1 + { + class TypeName + { + public int i = 1; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + + [Fact] + public async Task structNoDiagnostic() + { + const string source1 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private MyStruct myStruct; + private struct MyStruct + { + public int Value; + } + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source1 }); + } + + [Fact] + public async Task structWithNullValue() + { + const string source1 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private MyStruct myStruct = null; + private struct MyStruct + { + public int Value; + } + } + }"; + const string source2 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private readonly MyStruct myStruct = null; + private struct MyStruct + { + public int Value; + } + } + }"; + await VerifyCSharpFixAsync(source1, source2, 0); + } + [Fact] + public async Task structDefaultCreateWithoutReadOnlyDeclarationSameClass() + { + const string source1 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private MyStruct myStruct = default(MyStruct); + private struct MyStruct + { + public int Value; + } + } + }"; + const string source2 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private readonly MyStruct myStruct = default(MyStruct); + private struct MyStruct + { + public int Value; + } + } + }"; + await VerifyCSharpFixAsync(source1, source2, 0); + } + + [Fact] + public async Task structCreateWithoutReadonlyDeclaration() + { + const string source1 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private MyStruct myStruct = new MyStruct(); + } + private struct MyStruct + { + public int Value; + } + }"; + const string source2 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private readonly MyStruct myStruct = new MyStruct(); + } + private struct MyStruct + { + public int Value; + } + }"; + await VerifyCSharpFixAsync(source1, source2, 0); + } + + [Fact] + public async Task structDefaultCreateWithoutReadonlyDeclaration() + { + const string source1 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private MyStruct myStruct = default(MyStruct); + } + private struct MyStruct + { + public int Value; + } + }"; + const string source2 = @" + namespace ConsoleApplication1 + { + public class MyClass + { + private readonly MyStruct myStruct = default(MyStruct); + } + private struct MyStruct + { + public int Value; + } + }"; + await VerifyCSharpFixAsync(source1, source2, 0); + } + [Fact] + public async Task enumerationsDoesNotCreateDiagnostic() + { + const string source = @" + public class EnumTest + { + enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }; + + static void Main() + { + int x = (int)Days.Sun; + int y = (int)Days.Fri; + int z = x + y; + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + + [Fact] + public async Task privateEnumerationsDoesNotCreateDiagnostic() + { + const string source = @" + public class EnumTest + { + enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }; + private Days enumDays; + static void Main() + { + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(new[] { source }); + } + } +} From e1c18b6be36ce56e3f84e6f3c6f0b2cfdda7a68f Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sat, 7 Jan 2017 16:40:28 -0200 Subject: [PATCH 011/152] Fix bug on CC0120 when there was a conversion Also major refactors Fixes #859 --- .../Design/SwitchWithoutDefaultAnalyzer.cs | 10 +- .../SwitchWithoutDefaultCodeFixProvider.cs | 71 ++---- .../Design/SwicthWithoutDefaultTests.cs | 208 ++++++++++-------- 3 files changed, 142 insertions(+), 147 deletions(-) diff --git a/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs index b4531315f..82a31165c 100644 --- a/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs +++ b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultAnalyzer.cs @@ -47,16 +47,14 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) var hasInitializer = from nodes in switchStatementToAnalyse.DescendantNodes() where nodes.Kind() == SyntaxKind.IdentifierName select nodes; - if (!hasInitializer.Any()) - return; + if (!hasInitializer.Any()) return; var hasTrueExpression = from nodes in switchStatementToAnalyse.DescendantNodes() - where nodes.Kind() == SyntaxKind.FalseLiteralExpression + where nodes.IsKind(SyntaxKind.FalseLiteralExpression) select nodes; var hasfalseExpression = from nodes in switchStatementToAnalyse.DescendantNodes() - where nodes.Kind() == SyntaxKind.TrueLiteralExpression + where nodes.IsKind(SyntaxKind.TrueLiteralExpression) select nodes; - if ((hasfalseExpression.Any()) && (hasTrueExpression.Any())) - return; + if (hasfalseExpression.Any() && hasTrueExpression.Any()) return; var diagnostic = Diagnostic.Create(Rule, switchStatementToAnalyse.GetLocation(), "Consider put an default clause in Switch."); context.ReportDiagnostic(diagnostic); } diff --git a/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs index 192d1ac5e..086dd9055 100644 --- a/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Design/SwitchWithoutDefaultCodeFixProvider.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Simplification; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; @@ -15,9 +16,6 @@ namespace CodeCracker.CSharp.Design [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(SwitchWithoutDefaultCodeFixProvider)), Shared] public class SwitchWithoutDefaultCodeFixProvider : CodeFixProvider { - private const string EmptyString = "\"\""; - private const string BreakString = "\n\t\t\t\t\tbreak;"; - private const string ThrowString = "throw new Exception(\"Unexpected Case\");"; public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.SwitchCaseWithoutDefault.ToDiagnosticId()); public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; @@ -33,69 +31,32 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) private async static Task SwitchWithoutDefaultAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var switchCaseLabel = new SyntaxList(); - var kindOfVariable = string.Empty; - var idForVariable = string.Empty; - var breakStatement = new SyntaxList(); - var diagnosticSpan = diagnostic.Location.SourceSpan; var newSections = new List(); - var switchCaseStatement = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); - idForVariable = ((IdentifierNameSyntax)switchCaseStatement.ChildNodes().ToList().First(n => n.Kind() == SyntaxKind.IdentifierName)).Identifier.ValueText; - var parametersOfMethod = from init in root.DescendantNodesAndSelf() - where init.Kind() == SyntaxKind.Parameter - select init; - // Verify if the variable of Switch as a same of Method Parameter - foreach (var parameter in parametersOfMethod) - if (idForVariable == ((ParameterSyntax)parameter).Identifier.ValueText) - kindOfVariable = ((ParameterSyntax)parameter).Type.ToString(); - - if (kindOfVariable == string.Empty) - { - var statements = ((BlockSyntax)switchCaseStatement.Parent).Statements; - var inicializerOfSwitch = from init in statements - where init.Kind() == SyntaxKind.LocalDeclarationStatement - select init; - if (inicializerOfSwitch.Any()) - { - var local = (LocalDeclarationStatementSyntax)inicializerOfSwitch.First(); - var switchCaseVariable = ((local).Declaration).Variables[0]; - kindOfVariable = ((LiteralExpressionSyntax)(switchCaseVariable.Initializer.Value)).Kind().ToString(); - } - } - - if ((kindOfVariable.Equals("FalseLiteralExpression")) || (kindOfVariable.Equals("TrueLiteralExpression")) - || (kindOfVariable.Equals("bool"))) + var switchCaseStatement = root.FindToken(diagnostic.Location.SourceSpan.Start).Parent.AncestorsAndSelf().OfType().First(); + var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + var expressionSymbol = semanticModel.GetSymbolInfo(switchCaseStatement.Expression).Symbol; + if (semanticModel.GetTypeInfo(switchCaseStatement.Expression).Type.SpecialType == SpecialType.System_Boolean) { - var oldSections = switchCaseStatement.Sections.ToList(); - var type = string.Empty; - foreach (var sec in oldSections) - { - newSections.Add(sec); - type = (((CaseSwitchLabelSyntax)((SwitchSectionSyntax)sec).ChildNodes().ToList().First()).Value).GetFirstToken().Text; - } - var againstType = string.Empty; - if (type.Equals("true")) againstType = "false"; else againstType = "true"; - + var type = ((CaseSwitchLabelSyntax)switchCaseStatement.Sections.Last().ChildNodes().First()).Value.GetFirstToken().Text; + var againstType = type == "true" ? "false" : "true"; newSections.Add(SyntaxFactory.SwitchSection().WithLabels( - switchCaseLabel.Add(SyntaxFactory.CaseSwitchLabel(SyntaxFactory.ParseExpression(againstType)))). - WithStatements(breakStatement.Add(SyntaxFactory.ParseStatement(BreakString)))); + new SyntaxList().Add(SyntaxFactory.CaseSwitchLabel(SyntaxFactory.ParseExpression(againstType)))) + .WithStatements(new SyntaxList().Add(SyntaxFactory.ParseStatement("break;")))); } else { - var oldSections = switchCaseStatement.Sections.ToList(); - foreach (var sec in oldSections) - newSections.Add(sec); - - breakStatement = breakStatement.Add(SyntaxFactory.ParseStatement(BreakString)); - newSections.Add(CreateSection(SyntaxFactory.DefaultSwitchLabel(), SyntaxFactory.ParseStatement(ThrowString))); + newSections.Add(CreateSection(SyntaxFactory.DefaultSwitchLabel(), + SyntaxFactory.ThrowStatement(SyntaxFactory.ObjectCreationExpression(SyntaxFactory.ParseTypeName("System.Exception").WithAdditionalAnnotations(Simplifier.Annotation), + SyntaxFactory.ArgumentList(new SeparatedSyntaxList().Add(SyntaxFactory.Argument(SyntaxFactory.ParseExpression("\"Unexpected Case\"")))), null)))); } - var switchExpression = SyntaxFactory.ParseExpression(idForVariable); - var newsSwitchCaseStatement = SyntaxFactory.SwitchStatement(switchExpression). - WithSections(new SyntaxList().AddRange(newSections)); + var newsSwitchCaseStatement = switchCaseStatement + .AddSections(newSections.ToArray()) + .WithAdditionalAnnotations(Formatter.Annotation); var newRoot = root.ReplaceNode(switchCaseStatement, newsSwitchCaseStatement); var newDocument = document.WithSyntaxRoot(newRoot); return newDocument; } + static SwitchSectionSyntax CreateSection(SwitchLabelSyntax label, StatementSyntax statement) { var labels = new SyntaxList(); diff --git a/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs b/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs index c9fa24b44..88d7a4cc8 100644 --- a/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/SwicthWithoutDefaultTests.cs @@ -9,49 +9,49 @@ public class SwicthWithoutDefaultTests : CodeFixVerifier 1; +}"; + + const string fixtest = @" +using System; +class TypeName +{ + void Bar() + { + var t = new TypeName(); + switch ((int)t) + { + case 1: break; + default: + throw new Exception(""Unexpected Case""); + } + } + public static explicit operator int(TypeName v) => 1; +}"; + await VerifyCSharpFixAsync(source, fixtest); } + [Fact] public async Task SwithWithoutDefaultAnalyserIntMethodTwoParams() { - const string source = @"using System;namespace - ConsoleApplication1 + const string source = @"using System;namespace + ConsoleApplication1 { class TypeName { @@ -218,17 +255,17 @@ void Bar4(int a, int b) switch (a) { case 10: - break; + break; } } } }"; - const string fixtest = @"using System;namespace - ConsoleApplication1 + const string fixtest = @"using System;namespace + ConsoleApplication1 { class TypeName - { + { void Bar4(int a, int b) { switch (a) @@ -241,14 +278,14 @@ void Bar4(int a, int b) } } }"; - await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + await VerifyCSharpFixAsync(source, fixtest); } [Fact] public async Task SwithWithoutDefaultAnalyserIntMethodStatic() { - const string source = @"using System;namespace - ConsoleApplication1 + const string source = @"using System;namespace + ConsoleApplication1 { class TypeName { @@ -257,18 +294,18 @@ static void Bar5(int a) switch (a) { case 10: - break; + break; } } } }"; - const string fixtest = @"using System;namespace - ConsoleApplication1 + const string fixtest = @"using System;namespace + ConsoleApplication1 { class TypeName - { + { static void Bar5(int a) { switch (a) @@ -282,7 +319,7 @@ static void Bar5(int a) } }"; - await VerifyCSharpFixAsync(source, fixtest, 0, allowNewCompilerDiagnostics: true); + await VerifyCSharpFixAsync(source, fixtest); } [Fact] @@ -291,7 +328,6 @@ public async Task SwithWithoutDefaultAnalyseCS0151Exception() const string source = @"static void M() { } static void Main() { - switch (M()) // CS0151 { default: @@ -305,8 +341,8 @@ static void Main() [Fact] public async Task SwithWithoutDefaultAnalyserNoDiagnostic() { - const string source = @"using System;namespace - ConsoleApplication1 + const string source = @"using System;namespace + ConsoleApplication1 { class TypeName { @@ -329,25 +365,25 @@ public async Task SwitchWithoutDefaultAnalyzerNoDiagnosticWithCompileError() { const string source = @"using System; namespace ConsoleApplication1 - { - ConsoleApplication1 + { + ConsoleApplication1 { class Teste { } class Program { static void Main(string[] args) { - Teste vo_teste = new Teste(); + Teste vo_teste = new Teste(); switch (vo_teste) { - case "":break; + case "":break; default:break; } } - } - } + } + } }"; await VerifyCSharpHasNoDiagnosticsAsync(source); } } -} +} \ No newline at end of file From e071c8ad8392d6c007d7fbaf1056b89cb6343a33 Mon Sep 17 00:00:00 2001 From: Hubert Kindermann Date: Fri, 13 Jan 2017 11:36:57 +0100 Subject: [PATCH 012/152] Fixes #854. --- .../Usage/ReadonlyFieldAnalyzer.cs | 8 +++--- .../Usage/ReadonlyFieldTests.cs | 26 +++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs b/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs index d9db192ba..6ee2c84e1 100644 --- a/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/ReadonlyFieldAnalyzer.cs @@ -2,9 +2,9 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; -using System.Collections.Generic; namespace CodeCracker.CSharp.Usage { @@ -137,7 +137,7 @@ private static void AddVariableThatWasSkippedBeforeBecauseItLackedAInitializer(D parent = parent.Parent; } - if (!fieldSymbol.IsReadOnly && !variablesToMakeReadonly.Keys.Contains(fieldSymbol)) + if (!fieldSymbol.IsReadOnly && !variablesToMakeReadonly.Keys.Contains(fieldSymbol) && !IsComplexValueType(fieldSymbol.Type)) { var containingType = assignment.FirstAncestorOfKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration); if (containingType == null) return; @@ -196,9 +196,11 @@ private static bool IsComplexValueType(SemanticModel semanticModel, FieldDeclara { var fieldTypeName = fieldDeclaration.Declaration.Type; var fieldType = semanticModel.GetTypeInfo(fieldTypeName).ConvertedType; - return fieldType.IsValueType && !(fieldType.TypeKind == TypeKind.Enum || fieldType.IsPrimitive()); + return IsComplexValueType(fieldType); } + private static bool IsComplexValueType(ITypeSymbol fieldType) => fieldType.IsValueType && !(fieldType.TypeKind == TypeKind.Enum || fieldType.IsPrimitive()); + private static bool CanBeMadeReadonly(IFieldSymbol fieldSymbol) { return (fieldSymbol.DeclaredAccessibility == Accessibility.NotApplicable diff --git a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs index e4181d876..fb208a531 100644 --- a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs @@ -988,6 +988,32 @@ public Test() { value = 8; } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task ComplexTypeDoesNotCreateDiagnosticAsync() + { + const string source = @" +class C +{ + private S s; + + public C() + { + s = default(S); + } + + public void M1() + { + s.Value = 1; + } + + public struct S + { + public int Value; + } }"; await VerifyCSharpHasNoDiagnosticsAsync(source); } From 50ea8e08577c4df93702814cb9722484bf0d010a Mon Sep 17 00:00:00 2001 From: Hubert Kindermann Date: Mon, 16 Jan 2017 13:07:18 +0100 Subject: [PATCH 013/152] Fix #CC0060. --- ...ctClassShouldNotHavePublicCtorsAnalyzer.cs | 8 +++---- ...stractClassShouldNotHavePublicCtorTests.cs | 24 +++++++++++++++++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs b/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs index 4e70142cd..f753cbebe 100644 --- a/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs @@ -1,9 +1,9 @@ -using System.Collections.Immutable; -using System.Linq; -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using System.Collections.Immutable; +using System.Linq; namespace CodeCracker.CSharp.Usage { @@ -33,7 +33,7 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context) var ctor = (ConstructorDeclarationSyntax)context.Node; if (!ctor.Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))) return; - var @class = ctor.Ancestors().OfType().FirstOrDefault(); + var @class = ctor.Ancestors().FirstOrDefault() as ClassDeclarationSyntax; if (@class == null) return; if (!@class.Modifiers.Any(m => m.IsKind(SyntaxKind.AbstractKeyword))) return; diff --git a/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs b/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs index 6d804ca61..4fd659794 100644 --- a/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs @@ -1,6 +1,6 @@ -using System.Threading.Tasks; -using CodeCracker.CSharp.Usage; +using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using System.Threading.Tasks; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -66,6 +66,26 @@ private Foo() { /* .. */ } await VerifyCSharpHasNoDiagnosticsAsync(test); } + [Fact] + public async Task IgnoresCtorOfStructNestedInAbstractClasses() + { + const string test = @" + public abstract class C + { + public struct S + { + private int x; + + public S(int x) + { + this.x = x; + } + } + }"; + + await VerifyCSharpHasNoDiagnosticsAsync(test); + } + [Fact] public async Task FixReplacesPublicWithProtectedModifierInAbstractClasses() { From 8a8dc0ee8221f76aca22b871411a97560442ca7a Mon Sep 17 00:00:00 2001 From: Hubert Kindermann Date: Mon, 16 Jan 2017 13:16:27 +0100 Subject: [PATCH 014/152] Revert "Fix #CC0060." This reverts commit 50ea8e08577c4df93702814cb9722484bf0d010a. --- ...ctClassShouldNotHavePublicCtorsAnalyzer.cs | 8 +++---- ...stractClassShouldNotHavePublicCtorTests.cs | 24 ++----------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs b/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs index f753cbebe..4e70142cd 100644 --- a/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/AbstractClassShouldNotHavePublicCtorsAnalyzer.cs @@ -1,9 +1,9 @@ -using Microsoft.CodeAnalysis; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; -using System.Collections.Immutable; -using System.Linq; namespace CodeCracker.CSharp.Usage { @@ -33,7 +33,7 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context) var ctor = (ConstructorDeclarationSyntax)context.Node; if (!ctor.Modifiers.Any(m => m.IsKind(SyntaxKind.PublicKeyword))) return; - var @class = ctor.Ancestors().FirstOrDefault() as ClassDeclarationSyntax; + var @class = ctor.Ancestors().OfType().FirstOrDefault(); if (@class == null) return; if (!@class.Modifiers.Any(m => m.IsKind(SyntaxKind.AbstractKeyword))) return; diff --git a/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs b/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs index 4fd659794..6d804ca61 100644 --- a/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/AbstractClassShouldNotHavePublicCtorTests.cs @@ -1,6 +1,6 @@ -using CodeCracker.CSharp.Usage; +using System.Threading.Tasks; +using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; -using System.Threading.Tasks; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -66,26 +66,6 @@ private Foo() { /* .. */ } await VerifyCSharpHasNoDiagnosticsAsync(test); } - [Fact] - public async Task IgnoresCtorOfStructNestedInAbstractClasses() - { - const string test = @" - public abstract class C - { - public struct S - { - private int x; - - public S(int x) - { - this.x = x; - } - } - }"; - - await VerifyCSharpHasNoDiagnosticsAsync(test); - } - [Fact] public async Task FixReplacesPublicWithProtectedModifierInAbstractClasses() { From 20bd8a042b47e8b7523d47c3e04673b086c9c7a6 Mon Sep 17 00:00:00 2001 From: Stefan Theiner Date: Mon, 6 Feb 2017 09:25:34 +0100 Subject: [PATCH 015/152] Fix #872: UnusedParametersAnalyzer Analyzer should not be triggered on virtual methods Includes test case and fix. --- .../Usage/UnusedParametersAnalyzer.cs | 6 ++++++ .../Usage/UnusedParametersTests.cs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/CSharp/CodeCracker/Usage/UnusedParametersAnalyzer.cs b/src/CSharp/CodeCracker/Usage/UnusedParametersAnalyzer.cs index cec3e43ea..cae19517e 100644 --- a/src/CSharp/CodeCracker/Usage/UnusedParametersAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/UnusedParametersAnalyzer.cs @@ -59,6 +59,12 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) } var method = methodOrConstructor as MethodDeclarationSyntax; + + // It is legit for virtual methods to have parameters that aren't used in the default + // base class implementation, but are only provided for sub classes instead. + // See https://github.com/code-cracker/code-cracker/issues/872 + if (method?.Modifiers.Any(SyntaxKind.VirtualKeyword) == true) return; + IEnumerable methodChildren = methodOrConstructor.Body?.Statements; var expressionBody = (methodOrConstructor as MethodDeclarationSyntax)?.ExpressionBody; if (methodChildren == null && expressionBody != null) diff --git a/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs b/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs index 44cf5f2b9..2b08add48 100644 --- a/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs @@ -893,5 +893,24 @@ public class TypeName }"; await VerifyCSharpFixAsync(source, fixtest); } + + /// + /// Virtual methods should be ignored by the analyzer, because variables don't need + /// to be actually used by the base class and still serve a legit purpose. + /// + [Fact] + public async Task VirtualMethodsShouldBeIgnored() + { + + const string source = @" +public class BaseClass +{ + protected virtual void PreProcess(string data) + { + // no real action in base class + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } } } \ No newline at end of file From a9df7f4496941157c90aeafd57fd16a2becb5487 Mon Sep 17 00:00:00 2001 From: sdygert Date: Mon, 20 Feb 2017 20:31:51 -0800 Subject: [PATCH 016/152] Fixed grammer in CatchEmptyAnalyzer --- src/CSharp/CodeCracker/Design/CatchEmptyAnalyzer.cs | 6 +++--- src/VisualBasic/CodeCracker/Design/CatchEmptyAnalyzer.vb | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CSharp/CodeCracker/Design/CatchEmptyAnalyzer.cs b/src/CSharp/CodeCracker/Design/CatchEmptyAnalyzer.cs index ca0c5506a..82e455d7f 100644 --- a/src/CSharp/CodeCracker/Design/CatchEmptyAnalyzer.cs +++ b/src/CSharp/CodeCracker/Design/CatchEmptyAnalyzer.cs @@ -10,7 +10,7 @@ namespace CodeCracker.CSharp.Design [DiagnosticAnalyzer(LanguageNames.CSharp)] public class CatchEmptyAnalyzer : DiagnosticAnalyzer { - internal const string Title = "Your catch maybe include some Exception"; + internal const string Title = "Your catch should include an Exception"; internal const string MessageFormat = "{0}"; internal const string Category = SupportedCategories.Design; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( @@ -33,7 +33,7 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) var catchStatement = (CatchClauseSyntax)context.Node; if (catchStatement == null || catchStatement.Declaration != null) return; - if (catchStatement.Block?.Statements.Count == 0) return; // there is another analizer for this: EmptyCatchBlock + if (catchStatement.Block?.Statements.Count == 0) return; // there is another analyzer for this: EmptyCatchBlock if (catchStatement.Block != null) { @@ -42,7 +42,7 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) if (!controlFlow.EndPointIsReachable && controlFlow.ExitPoints.All(i => i.IsKind(SyntaxKind.ThrowStatement))) return; } - var diagnostic = Diagnostic.Create(Rule, catchStatement.GetLocation(), "Consider put an Exception Class in catch."); + var diagnostic = Diagnostic.Create(Rule, catchStatement.GetLocation(), "Consider adding an Exception to the catch."); context.ReportDiagnostic(diagnostic); } } diff --git a/src/VisualBasic/CodeCracker/Design/CatchEmptyAnalyzer.vb b/src/VisualBasic/CodeCracker/Design/CatchEmptyAnalyzer.vb index 132345083..e4f1b7c9c 100644 --- a/src/VisualBasic/CodeCracker/Design/CatchEmptyAnalyzer.vb +++ b/src/VisualBasic/CodeCracker/Design/CatchEmptyAnalyzer.vb @@ -9,7 +9,7 @@ Namespace Design Inherits DiagnosticAnalyzer Public Shared ReadOnly Id As String = DiagnosticId.CatchEmpty.ToDiagnosticId() - Public Const Title As String = "Your catch may includes some Exception" + Public Const Title As String = "Your catch should include an Exception" Public Const MessageFormat As String = "{0}" Public Const Category As String = SupportedCategories.Design Protected Shared Rule As DiagnosticDescriptor = New DiagnosticDescriptor( @@ -33,7 +33,7 @@ Namespace Design If catchStatement Is Nothing Then Exit Sub If catchStatement.IdentifierName Is Nothing Then - Dim diag = Diagnostic.Create(Rule, catchStatement.GetLocation(), "Consider including an Exception Class in catch.") + Dim diag = Diagnostic.Create(Rule, catchStatement.GetLocation(), "Consider adding an Exception to the catch.") context.ReportDiagnostic(diag) End If End Sub From e4d2a3152a8fb20ca0ccac48a58e3f388ca89a16 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 27 Feb 2017 19:17:58 +0100 Subject: [PATCH 017/152] #522 first prototype --- .../Style/TernaryOperatorCodeFixProvider.cs | 69 +++++++++- .../Style/TernaryOperatorTests.cs | 123 ++++++++++++++++++ 2 files changed, 185 insertions(+), 7 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 97ebd2e3f..0e6a22ed6 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using System; namespace CodeCracker.CSharp.Style { @@ -37,11 +38,10 @@ private static async Task MakeTernaryAsync(Document document, Diagnost var elseStatement = ifStatement.Else; var returnStatementInsideElse = (ReturnStatementSyntax)(elseStatement.Statement is BlockSyntax ? ((BlockSyntax)elseStatement.Statement).Statements.Single() : elseStatement.Statement); var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - ExpressionSyntax trueExpression, falseExpression; - TernaryOperatorCodeFixHelper.CreateExpressions(returnStatementInsideIf.Expression, returnStatementInsideElse.Expression, semanticModel, out trueExpression, out falseExpression); + var conditionalExpression = TernaryOperatorCodeFixHelper.CreateExpressions(returnStatementInsideIf.Expression, returnStatementInsideElse.Expression, ifStatement.Condition, semanticModel); var ternary = SyntaxFactory.ReturnStatement( - SyntaxFactory.ConditionalExpression(ifStatement.Condition, trueExpression, falseExpression)) + conditionalExpression) .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(ifStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); @@ -76,14 +76,13 @@ private static async Task MakeTernaryAsync(Document document, Diagnost var assignmentExpressionInsideIf = (AssignmentExpressionSyntax)expressionInsideIf.Expression; var assignmentExpressionInsideElse = (AssignmentExpressionSyntax)expressionInsideElse.Expression; var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - ExpressionSyntax trueExpression, falseExpression; - TernaryOperatorCodeFixHelper.CreateExpressions(assignmentExpressionInsideIf.Right, assignmentExpressionInsideElse.Right, semanticModel, out trueExpression, out falseExpression); + var conditionalExpression = TernaryOperatorCodeFixHelper.CreateExpressions(assignmentExpressionInsideIf.Right, assignmentExpressionInsideElse.Right, ifStatement.Condition, semanticModel); var ternary = SyntaxFactory.ExpressionStatement( SyntaxFactory.AssignmentExpression( assignmentExpressionInsideIf.Kind(), assignmentExpressionInsideIf.Left, - SyntaxFactory.ConditionalExpression(ifStatement.Condition, trueExpression, falseExpression))) + conditionalExpression)) .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(ifStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); @@ -95,13 +94,69 @@ private static async Task MakeTernaryAsync(Document document, Diagnost internal static class TernaryOperatorCodeFixHelper { - public static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel, out ExpressionSyntax trueExpression, out ExpressionSyntax falseExpression) + public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, ExpressionSyntax ifStatementCondition, SemanticModel semanticModel) + { + + var methodCallSimplification = TrySimplifyMethodCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (methodCallSimplification != null) return methodCallSimplification; + var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); + var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); + var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); + ExpressionSyntax trueExpression; ExpressionSyntax falseExpression; + CreateExpressions(ifExpression, elseExpression, ifTypeInfo.Type, elseTypeInfo.Type, + ifTypeInfo.ConvertedType, elseTypeInfo.ConvertedType, typeSyntax, semanticModel, out trueExpression, out falseExpression); + return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); + } + + private static ExpressionSyntax TrySimplifyMethodCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + { + if (ifExpression is InvocationExpressionSyntax && elseExpression is InvocationExpressionSyntax) + { + var ifInvocation = ifExpression as InvocationExpressionSyntax; + var elseInvocation = elseExpression as InvocationExpressionSyntax; + var ifMethodinfo = semanticModel.GetSymbolInfo(ifInvocation.Expression); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation.Expression); + if (object.Equals(ifMethodinfo, elseMethodinfo)) //same method and overload + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.InvocationExpression(ifInvocation.Expression, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel)); + } + } + return null; + } + + private static ArgumentListSyntax CreateMethodArgumentList(ExpressionSyntax ifStatementCondition, ArgumentListSyntax argList1, ArgumentListSyntax argList2, int argumentIndexThatDiffers, SemanticModel semanticModel) + { + var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); + var argSelector = zipped.Select((args, i) => + (i == argumentIndexThatDiffers) ? + SyntaxFactory.Argument(GetConditionalExpressionForArgument(ifStatementCondition, args.a1.Expression, args.a2.Expression, semanticModel)) + : args.a1); + return SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(argSelector)); + } + + private static ConditionalExpressionSyntax GetConditionalExpressionForArgument(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) { var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); + ExpressionSyntax trueExpression; ExpressionSyntax falseExpression; CreateExpressions(ifExpression, elseExpression, ifTypeInfo.Type, elseTypeInfo.Type, ifTypeInfo.ConvertedType, elseTypeInfo.ConvertedType, typeSyntax, semanticModel, out trueExpression, out falseExpression); + return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); + } + + private static int FindSingleArgumentIndexThatDiffers(ArgumentListSyntax argList1, ArgumentListSyntax argList2, SemanticModel semanticModel) + { + var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); + var singleMissmatch = zipped.Where(args => + { + var a1Text = args.a1.GetText(); + var a2Text = args.a2.GetText(); + return !a1Text.ContentEquals(a2Text); + }).Take(2).ToList(); + return (singleMissmatch.Count == 0 || singleMissmatch.Count > 1) ? -1 : singleMissmatch[0].i; } private static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index 68d90f96d..fcd61b6a1 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -723,5 +723,128 @@ public static Base Foo() "; await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenReturnStatementContainsMethodCallAnalyzerCreatesDiagnostic() + { + var source = @" + private int Method(int i) => i; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = DiagnosticId.TernaryOperator_Return.ToDiagnosticId(), + Message = "You can use a ternary operator.", + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 17) } + }; + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithSingleDifferentArgumentGetsSimplified() + { + var source = @" + private int Method(int i) => i; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i) => i; + + public int Foo() + { + return Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereSingleDifferentGetsSimplified() + { + var source = @" + private int Method(int i, string t) => i; + + public int Foo() + { + if (true) + return Method(1, ""hello""); + else + return Method(2, ""hello""); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i, string t) => i; + + public int Foo() + { + return Method(true?1:2, ""hello""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereMultipleDifferentGetsNotSimplified() + { + var source = @" + private int Method(int i, string t) => i; + + public int Foo() + { + if (true) + return Method(1, ""hello1""); + else + return Method(2, ""hello2""); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i, string t) => i; + + public int Foo() + { + return true?Method(1,""hello1""):Method(2, ""hello2""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodArgumentsGetCastedWhenSimplified() + { + var source = @" + class Base { } + class A : Base { } + class B : Base { } + + private string Method(Base b, string t) => t; + + public int Foo() + { + if (true) + return Method(new A(), ""hello""); + else + return Method(new B(), ""hello""); + }".WrapInCSharpClass(); + var fixtest = @" + class Base { } + class A : Base { } + class B : Base { } + + private string Method(Base b, string t) => t; + + public int Foo() + { + return Method(true?(Base)new A():new B(),""hello""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From 0b218c0ffa0107b21c7a24b3e32805de112e82f6 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Tue, 28 Feb 2017 18:55:27 +0100 Subject: [PATCH 018/152] Small improvement and many more tests --- .../Style/TernaryOperatorCodeFixProvider.cs | 11 +- .../Style/TernaryOperatorTests.cs | 230 +++++++++++++++++- 2 files changed, 235 insertions(+), 6 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 0e6a22ed6..33a44e884 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -118,9 +118,12 @@ private static ExpressionSyntax TrySimplifyMethodCalls(ExpressionSyntax ifStatem var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation.Expression); if (object.Equals(ifMethodinfo, elseMethodinfo)) //same method and overload { - var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); - if (findSingleArgumentIndexThatDiffers >= 0) - return SyntaxFactory.InvocationExpression(ifInvocation.Expression, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel)); + if (ifInvocation.Expression.GetText().ContentEquals(elseInvocation.Expression.GetText())) //same 'path' to the invocation + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.InvocationExpression(ifInvocation.Expression, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel)); + } } } return null; @@ -156,7 +159,7 @@ private static int FindSingleArgumentIndexThatDiffers(ArgumentListSyntax argList var a2Text = args.a2.GetText(); return !a1Text.ContentEquals(a2Text); }).Take(2).ToList(); - return (singleMissmatch.Count == 0 || singleMissmatch.Count > 1) ? -1 : singleMissmatch[0].i; + return (singleMissmatch.Count == 1) ? singleMissmatch[0].i : -1; } private static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index fcd61b6a1..0300d66b0 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -334,6 +334,68 @@ public static void Foo() "; await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultChangeToTernaryFixGetsSimplified() + { + var source = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + if (something) + { + a = Method(1); + } + else + { + a = Method(2); + } + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + a = Method(something?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultWithComplexArgumentEvaluationChangeToTernaryFixGetsSimplified() + { + var source = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + if (something) + { + a = Method(1); + } + else + { + a = Method(2 + 2); + } + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + a = Method(something?1:2 + 2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } public class TernaryOperatorWithReturnTests : CodeFixVerifier @@ -824,7 +886,7 @@ class Base { } class A : Base { } class B : Base { } - private string Method(Base b, string t) => t; + private int Method(Base b, string t) => 1; public int Foo() { @@ -838,7 +900,7 @@ class Base { } class A : Base { } class B : Base { } - private string Method(Base b, string t) => t; + private int Method(Base b, string t) => 1; public int Foo() { @@ -846,5 +908,169 @@ public int Foo() }".WrapInCSharpClass(); await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task FixWhenReturningWithPrefixedMethodGetsSimplified() + { + var source = @" + private int Method(int a) => a; + + public int Foo() + { + if (true) + return this.Method(1); + else + return this.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int a) => a; + + public int Foo() + { + return this.Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfPropertyGetsSimplified() + { + var source = @" + class A { + private int Method(int a) => a; + } + + public int Foo() + { + var a=new A(); + if (true) + return a.Method(1); + else + return a.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + class A { + private int Method(int a) => a; + } + + public int Foo() + { + var a=new A(); + return a.Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentPropertyGetsNotSimplified() + { + var source = @" + class A { + public int Method(int a) => a; + } + A Prop1 { get { return new A(); } } + A Prop2 { get { return new A(); } } + + public int Foo() + { + if (true) + return this.Prop1.Method(1); + else + return this.Prop2.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + class A { + public int Method(int a) => a; + } + A Prop1 { get { return new A(); } } + A Prop2 { get { return new A(); } } + + public int Foo() + { + return true?this.Prop1.Method(1):this.Prop2.Method(2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfSameOverloadGetsSimplified() + { + var source = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + return Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentOverloadGetsNotSimplified() + { + var source = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(""2""); + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + return true?Method(1):Method(""2""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodNestedInMemberAccessGetsNotSimplified() + { + var source = @" + class A { + public int Prop { get; } + } + + A GetA(int i) => new A(); + + public int Foo() + { + if (true) + return GetA(1).Prop; + else + return GetA(2).Prop; + }".WrapInCSharpClass(); + var fixtest = @" + class A { + public int Prop { get; } + } + + A GetA(int i) => new A(); + + public int Foo() + { + return true?GetA(1).Prop:GetA(2).Prop; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From e86f1ffca13e8e561433f71b06ea945be3705d25 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 8 Mar 2017 14:32:30 +0100 Subject: [PATCH 019/152] Supoport for constructor calls added. --- .../Style/TernaryOperatorCodeFixProvider.cs | 20 +++++++++++++++++++ .../Style/TernaryOperatorTests.cs | 19 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 33a44e884..2f3b6a0c0 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -99,6 +99,8 @@ public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, var methodCallSimplification = TrySimplifyMethodCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); if (methodCallSimplification != null) return methodCallSimplification; + var constructorSimplification = TrySimplifyConstructorCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (constructorSimplification != null) return constructorSimplification; var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); @@ -108,6 +110,24 @@ public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); } + private static ExpressionSyntax TrySimplifyConstructorCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + { + if (ifExpression is ObjectCreationExpressionSyntax && elseExpression is ObjectCreationExpressionSyntax) + { + var ifInvocation = ifExpression as ObjectCreationExpressionSyntax; + var elseInvocation = elseExpression as ObjectCreationExpressionSyntax; + var ifMethodinfo = semanticModel.GetSymbolInfo(ifInvocation); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation); + if (object.Equals(ifMethodinfo, elseMethodinfo)) //same method and overload + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.ObjectCreationExpression(ifInvocation.Type, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel), null); + } + } + return null; + } + private static ExpressionSyntax TrySimplifyMethodCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) { if (ifExpression is InvocationExpressionSyntax && elseExpression is InvocationExpressionSyntax) diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index 0300d66b0..714041c00 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -1072,5 +1072,24 @@ public int Foo() }".WrapInCSharpClass(); await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task FixWhenReturningWithConstructorGetsSimplified() + { + var source = @" + public int Foo() + { + if (true) + return new System.Collections.Generic.List(1); + else + return new System.Collections.Generic.List(2); + }".WrapInCSharpClass(); + var fixtest = @" + public int Foo() + { + return new System.Collections.Generic.List(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From 75a2904613a3cbfb912bbd2b3ef22ef8159be907 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Sun, 12 Mar 2017 17:27:22 +0100 Subject: [PATCH 020/152] Support and tests for dynamic and params added. --- .../Style/TernaryOperatorCodeFixProvider.cs | 36 +-- .../Style/TernaryOperatorTests.cs | 239 ++++++++++++++++-- 2 files changed, 244 insertions(+), 31 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 2f3b6a0c0..8444c0705 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -97,10 +97,10 @@ internal static class TernaryOperatorCodeFixHelper public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, ExpressionSyntax ifStatementCondition, SemanticModel semanticModel) { - var methodCallSimplification = TrySimplifyMethodCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); - if (methodCallSimplification != null) return methodCallSimplification; - var constructorSimplification = TrySimplifyConstructorCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); - if (constructorSimplification != null) return constructorSimplification; + var methodCallArgApplied = TryApplyArgsOnMethodCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (methodCallArgApplied != null) return methodCallArgApplied; + var constructorArgsApplied = TryApplyArgsOnConstructorCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (constructorArgsApplied != null) return constructorArgsApplied; var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); @@ -110,25 +110,30 @@ public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); } - private static ExpressionSyntax TrySimplifyConstructorCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + private static ExpressionSyntax TryApplyArgsOnConstructorCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) { if (ifExpression is ObjectCreationExpressionSyntax && elseExpression is ObjectCreationExpressionSyntax) { - var ifInvocation = ifExpression as ObjectCreationExpressionSyntax; - var elseInvocation = elseExpression as ObjectCreationExpressionSyntax; - var ifMethodinfo = semanticModel.GetSymbolInfo(ifInvocation); - var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation); - if (object.Equals(ifMethodinfo, elseMethodinfo)) //same method and overload + var ifObjCreation = ifExpression as ObjectCreationExpressionSyntax; + var elseObjCreation = elseExpression as ObjectCreationExpressionSyntax; + if ((ifObjCreation.Initializer == null && elseObjCreation.Initializer == null) || + ifObjCreation.Initializer != null && elseObjCreation.Initializer != null && + ifObjCreation.Initializer.GetText().ContentEquals(elseObjCreation.Initializer.GetText())) // Initializer are either absent or text equals { - var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); - if (findSingleArgumentIndexThatDiffers >= 0) - return SyntaxFactory.ObjectCreationExpression(ifInvocation.Type, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel), null); + var ifMethodinfo = semanticModel.GetSymbolInfo(ifObjCreation); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseObjCreation); + if (object.Equals(ifMethodinfo, elseMethodinfo)) //same constructor and overload + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifObjCreation.ArgumentList, elseObjCreation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.ObjectCreationExpression(ifObjCreation.Type, CreateMethodArgumentList(ifStatementCondition, ifObjCreation.ArgumentList, elseObjCreation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel), ifObjCreation.Initializer); + } } } return null; } - private static ExpressionSyntax TrySimplifyMethodCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + private static ExpressionSyntax TryApplyArgsOnMethodCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) { if (ifExpression is InvocationExpressionSyntax && elseExpression is InvocationExpressionSyntax) { @@ -136,7 +141,7 @@ private static ExpressionSyntax TrySimplifyMethodCalls(ExpressionSyntax ifStatem var elseInvocation = elseExpression as InvocationExpressionSyntax; var ifMethodinfo = semanticModel.GetSymbolInfo(ifInvocation.Expression); var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation.Expression); - if (object.Equals(ifMethodinfo, elseMethodinfo)) //same method and overload + if (object.Equals(ifMethodinfo, elseMethodinfo) && ifMethodinfo.CandidateReason != CandidateReason.LateBound) //same method and overload, but not dynamic { if (ifInvocation.Expression.GetText().ContentEquals(elseInvocation.Expression.GetText())) //same 'path' to the invocation { @@ -172,6 +177,7 @@ private static ConditionalExpressionSyntax GetConditionalExpressionForArgument(E private static int FindSingleArgumentIndexThatDiffers(ArgumentListSyntax argList1, ArgumentListSyntax argList2, SemanticModel semanticModel) { + if (argList1.Arguments.Count != argList2.Arguments.Count) return -1; // in case of 'params' var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); var singleMissmatch = zipped.Where(args => { diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index 714041c00..c9f42e24f 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -336,8 +336,8 @@ public static void Foo() } [Fact] - public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultChangeToTernaryFixGetsSimplified() - { + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultChangeToTernaryFixGetsArgsApplied() + { var source = @" int Method(int a) => a; @@ -353,7 +353,7 @@ public void Foo() { a = Method(2); } - }".WrapInCSharpClass(); + }".WrapInCSharpClass(); var fixtest = @" int Method(int a) => a; @@ -367,7 +367,7 @@ public void Foo() } [Fact] - public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultWithComplexArgumentEvaluationChangeToTernaryFixGetsSimplified() + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultWithComplexArgumentEvaluationChangeToTernaryFixGetsArgsApplied() { var source = @" int Method(int a) => a; @@ -810,7 +810,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodWithSingleDifferentArgumentGetsSimplified() + public async Task FixWhenReturningWithMethodWithSingleDifferentArgumentGetsArgsApplied() { var source = @" private int Method(int i) => i; @@ -833,7 +833,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereSingleDifferentGetsSimplified() + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereSingleDifferentGetsArgsApplied() { var source = @" private int Method(int i, string t) => i; @@ -856,7 +856,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereMultipleDifferentGetsNotSimplified() + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereMultipleDifferentGetsArgsNotApplied() { var source = @" private int Method(int i, string t) => i; @@ -879,7 +879,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodArgumentsGetCastedWhenSimplified() + public async Task FixWhenReturningWithMethodArgumentsGetCastedWhenGetsArgsApplied() { var source = @" class Base { } @@ -910,7 +910,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithPrefixedMethodGetsSimplified() + public async Task FixWhenReturningWithPrefixedMethodGetsArgsApplied() { var source = @" private int Method(int a) => a; @@ -933,7 +933,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodOfPropertyGetsSimplified() + public async Task FixWhenReturningWithMethodOfPropertyGetsArgsApplied() { var source = @" class A { @@ -962,7 +962,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodOfDifferentPropertyGetsNotSimplified() + public async Task FixWhenReturningWithMethodOfDifferentPropertyGetsArgsNotApplied() { var source = @" class A { @@ -993,7 +993,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodOfSameOverloadGetsSimplified() + public async Task FixWhenReturningWithMethodOfSameOverloadGetsArgsApplied() { var source = @" int Method(int a)=>a; @@ -1018,7 +1018,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodOfDifferentOverloadGetsNotSimplified() + public async Task FixWhenReturningWithMethodOfDifferentOverloadGetsArgsNotApplied() { var source = @" int Method(int a)=>a; @@ -1043,7 +1043,7 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithMethodNestedInMemberAccessGetsNotSimplified() + public async Task FixWhenReturningWithMethodNestedInMemberAccessGetsArgsNotApplied() { var source = @" class A { @@ -1074,10 +1074,113 @@ public int Foo() } [Fact] - public async Task FixWhenReturningWithConstructorGetsSimplified() + public async Task FixWhenReturningWithMethodParamOverloadAndNumerOfArgsAreEqualGetsApplied() + { + var source = @" + private int M(params int[] args) { } + + public int Foo() + { + if (true) + return M(1,1); + else + return M(1,2); + }".WrapInCSharpClass(); + var fixtest = @" + private int M(params int[] args) { } + + public int Foo() + { + return M(1,true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodParamOverloadAndNumerOfArgsAreDifferentGetsNotApplied() { var source = @" + private int M(params int[] args) { } + public int Foo() + { + if (true) + return M(1,1); + else + return M(1,2,3); + }".WrapInCSharpClass(); + var fixtest = @" + private int M(params int[] args) { } + + public int Foo() + { + return true?M(1,1):M(1,2,3); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDynamicObjGetsArgsNotApplied() + { + // Calls on dynamic objects get dispatched during runtime. + // Therefore the semantic would be changed if we apply to arguments + // and casting is involved: + // d.M(new A()) else d.M(new B()) -> d.M(cond?(Base)new A():new B()); + // is not the same as cond?d.M(new A()): d.M(new B()) on dynamic objects. + var source = @" + public class Base {} + public class A: Base {} + public class B: Base {} + + public int Foo() + { + dynamic d = new object(); + if (true) + return d.M(new A()); + else + return d.M(new B()); + }".WrapInCSharpClass(); + var fixtest = @" + public class Base {} + public class A: Base {} + public class B: Base {} + + public int Foo() + { + dynamic d = new object(); + return true?d.M(new A()):d.M(new B()); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDynamicObjGetsArgsNeverApplied() + { + // arguments on dynamic method calls are never applied even if it would be save. + // see comments above for why dynamic is dangerous. + var source = @" + public int Foo() + { + dynamic d = new object(); + if (true) + return d.M(1,1); + else + return d.M(1,2); + }".WrapInCSharpClass(); + var fixtest = @" + public int Foo() + { + dynamic d = new object(); + return true?d.M(1,1):d.M(1,2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorGetsArgsApplied() + { + var source = @" + public System.Collections.Generic.List Foo() { if (true) return new System.Collections.Generic.List(1); @@ -1085,11 +1188,115 @@ public int Foo() return new System.Collections.Generic.List(2); }".WrapInCSharpClass(); var fixtest = @" - public int Foo() + public System.Collections.Generic.List Foo() { return new System.Collections.Generic.List(true?1:2); }".WrapInCSharpClass(); await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task FixWhenReturningWithConstructorWithIdenticalInitializerGetsArgsApplied() + { + var source = @" + public new System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1) { 1 }; + else + return new System.Collections.Generic.List(2) { 1 }; + }".WrapInCSharpClass(); + var fixtest = @" + public new System.Collections.Generic.List Foo() + { + return new System.Collections.Generic.List(true?1:2) { 1 }; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithDifferentInitializerGetsArgsNotApplied() + { + var source = @" + public System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1) { 1 }; + else + return new System.Collections.Generic.List(2) { 1, 2 }; + }".WrapInCSharpClass(); + var fixtest = @" + public System.Collections.Generic.List Foo() + { + return true?new System.Collections.Generic.List(1) { 1 } : new System.Collections.Generic.List(2) { 1, 2 }; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithDifferentOverloadsGetArgsNotApplied() + { + var source = @" + public class A + { + public A(int i) { } + public A(string s) { } + } + public A Foo() + { + if (true) + return new A(1); + else + return new A(""1""); + }".WrapInCSharpClass(); + var fixtest = @" + public class A + { + public A(int i) { } + public A(string s) { } + } + public A Foo() + { + return true?new A(1):new A(""1""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorOfDifferentObjectsGetArgsNotApplied() + { + var source = @" + public class A + { + public A(int i) { } + } + public class B + { + public B(int i) { } + } + + public Object Foo() + { + if (true) + return new A(1); + else + return new B(2); + }".WrapInCSharpClass(); + var fixtest = @" + public class A + { + public A(int i) { } + } + public class B + { + public B(int i) { } + } + + public Object Foo() + { + return true?(object)new A(1):new B(2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From 61dae0431931613fb86479aec29648a409fefb45 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Sun, 12 Mar 2017 17:39:11 +0100 Subject: [PATCH 021/152] Added additional test for overload resolution. --- .../Style/TernaryOperatorTests.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index c9f42e24f..c9c86f91c 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -1042,6 +1042,35 @@ public int Foo() await VerifyCSharpFixAsync(source, fixtest); } + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentOverloadButCastingPossibleGetsArgsNotApplied() + { + var source = @" + public class A { } + public class B:A { } + void Method(A a) { }; + void Method(B b) { }; + + public int Foo() + { + if (true) + return Method(new A()); + else + return Method(new B()); + }".WrapInCSharpClass(); + var fixtest = @" + public class A { } + public class B:A { } + void Method(A a) { }; + void Method(B b) { }; + + public int Foo() + { + return true?Method(new A()):Method(new B()); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + [Fact] public async Task FixWhenReturningWithMethodNestedInMemberAccessGetsArgsNotApplied() { From bf783486f04425fba8047e2dbdfc2acd235bae03 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 12 Mar 2017 21:24:08 -0300 Subject: [PATCH 022/152] Add changelog --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31c87d874..8af91802e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Change Log +## [Unreleased](https://github.com/code-cracker/code-cracker/tree/HEAD) + +[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.2...HEAD) + +**Closed issues:** + + +## [v1.0.2](https://github.com/code-cracker/code-cracker/tree/v1.0.2) (2017-03-12) +[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.1...v1.0.2) + +**Implemented enhancements:** + +- VS 2017RC Support [\#856](https://github.com/code-cracker/code-cracker/issues/856) + +**Fixed bugs:** + +- CC0057 UnusedParametersAnalyzer should not be triggered on virtual methods [\#872](https://github.com/code-cracker/code-cracker/issues/872) +- BUG: CC0060 - detected for nested struct in abstract class [\#867](https://github.com/code-cracker/code-cracker/issues/867) +- Bug on CC0120 for the fix when there is a conversion [\#859](https://github.com/code-cracker/code-cracker/issues/859) +- BUG: CC0052 \(Make readonly\) sometimes detects complex value types [\#854](https://github.com/code-cracker/code-cracker/issues/854) +- BUG: CC0052 \(Make readonly\) does not work with lambda expressions and initialized variables [\#853](https://github.com/code-cracker/code-cracker/issues/853) +- "Disposable Field Not Disposed" rule does not recognize null propagation [\#848](https://github.com/code-cracker/code-cracker/issues/848) +- CC0082: ComputeExpressionCodeFixProvider crashs [\#841](https://github.com/code-cracker/code-cracker/issues/841) +- CC0030: Bad grammar in message [\#838](https://github.com/code-cracker/code-cracker/issues/838) +- CC0008: Don't suggest for dynamic objects [\#837](https://github.com/code-cracker/code-cracker/issues/837) +- Bug: Should not use Async methods in analyzers \(CC0029\) [\#821](https://github.com/code-cracker/code-cracker/issues/821) +- BUG: CC0014 converts if y then x += 1 else x =1 to x +=\(if\(y, 1, 1\) [\#798](https://github.com/code-cracker/code-cracker/issues/798) + ## [v1.0.1](https://github.com/code-cracker/code-cracker/tree/v1.0.1) (2016-09-06) [Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.0...v1.0.1) From c92c0001514ba8e777858714b6417e8b75ab4a92 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 12 Mar 2017 21:36:43 -0300 Subject: [PATCH 023/152] Update vsix --- .../CodeCracker.Vsix/source.extension.vsixmanifest | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest index ddd2f9d9d..49925d371 100644 --- a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest @@ -25,4 +25,8 @@ This is a community project, free and open source. Everyone is invited to contri + + + + From 9e87cfe904e564da4865bb81719981ba6dedebab Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 12 Mar 2017 21:51:07 -0300 Subject: [PATCH 024/152] Bump version to 1.0.2 --- src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest | 2 +- src/CSharp/CodeCracker/CodeCracker.nuspec | 2 +- src/CSharp/CodeCracker/Properties/AssemblyInfo.cs | 2 +- src/CodeCracker.nuspec | 6 +++--- src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs | 2 +- .../CodeCracker.Vsix/source.extension.vsixmanifest | 2 +- src/VisualBasic/CodeCracker/CodeCracker.nuspec | 2 +- src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb | 2 +- test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs | 2 +- .../CodeCracker.Test.Common/Properties/AssemblyInfo.cs | 2 +- .../VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest index d2b7702fd..940a535fc 100644 --- a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + Code Cracker for C# An analyzer library for C# that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. diff --git a/src/CSharp/CodeCracker/CodeCracker.nuspec b/src/CSharp/CodeCracker/CodeCracker.nuspec index cf2da4160..31a6c4a08 100644 --- a/src/CSharp/CodeCracker/CodeCracker.nuspec +++ b/src/CSharp/CodeCracker/CodeCracker.nuspec @@ -2,7 +2,7 @@ codecracker.CSharp - 1.0.2 + 1.0.3 CodeCracker for C# giggio,elemarjr,carloscds giggio,elemarjr,carloscds diff --git a/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs b/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs index a2cbcaa12..3d1250f56 100644 --- a/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs +++ b/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs @@ -14,5 +14,5 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.2.0")] +[assembly: AssemblyFileVersion("1.0.3.0")] [assembly: InternalsVisibleTo("CodeCracker.Test.CSharp")] diff --git a/src/CodeCracker.nuspec b/src/CodeCracker.nuspec index 6ceea0773..61ef261bc 100644 --- a/src/CodeCracker.nuspec +++ b/src/CodeCracker.nuspec @@ -2,7 +2,7 @@ codecracker - 1.0.2 + 1.0.3 CodeCracker for C# and VB giggio,elemarjr,carloscds giggio,elemarjr,carloscds @@ -19,8 +19,8 @@ This is a community project, free and open source. Everyone is invited to contri Copyright CodeCracker 2014-2016 roslyn, analyzers - - + + diff --git a/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs b/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs index 9bee0ce03..c63e0d98f 100644 --- a/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs +++ b/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs @@ -14,6 +14,6 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.2.0")] +[assembly: AssemblyFileVersion("1.0.3.0")] [assembly: InternalsVisibleTo("CodeCracker.Test.CSharp")] [assembly: InternalsVisibleTo("CodeCracker.Test.VisualBasic")] \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest index 49925d371..4f7911589 100644 --- a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + Code Cracker for Visual Basic An analyzer library for VB that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. diff --git a/src/VisualBasic/CodeCracker/CodeCracker.nuspec b/src/VisualBasic/CodeCracker/CodeCracker.nuspec index ecb28d922..0b6a31ec4 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.nuspec +++ b/src/VisualBasic/CodeCracker/CodeCracker.nuspec @@ -2,7 +2,7 @@ codecracker.VisualBasic - 1.0.2 + 1.0.3 CodeCracker for Visual Basic giggio,elemarjr,carloscds giggio,elemarjr,carloscds diff --git a/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb b/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb index 1425d7339..a3478becf 100644 --- a/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb +++ b/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb @@ -14,5 +14,5 @@ Imports System.Runtime.InteropServices - + \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs b/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs index 8809cfb5b..92983d5f5 100644 --- a/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs +++ b/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs @@ -14,4 +14,4 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.2.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.0.3.0")] \ No newline at end of file diff --git a/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs b/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs index 2a6956dbe..e7a08f024 100644 --- a/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs +++ b/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs @@ -14,4 +14,4 @@ [assembly: ComVisible(false)] [assembly: NeutralResourcesLanguage("en-us")] [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("1.0.2.0")] \ No newline at end of file +[assembly: AssemblyFileVersion("1.0.3.0")] \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb b/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb index f7d706ba8..2b5faf79b 100644 --- a/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb +++ b/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb @@ -14,4 +14,4 @@ Imports System.Runtime.InteropServices - \ No newline at end of file + \ No newline at end of file From b63870c10e19a71b80cf78a46085cf316a81364d Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 27 Feb 2017 19:17:58 +0100 Subject: [PATCH 025/152] Tenary operator: apply to arguments. Fix: #522 --- .../Style/TernaryOperatorCodeFixProvider.cs | 98 ++- .../Style/TernaryOperatorTests.cs | 604 ++++++++++++++++++ 2 files changed, 695 insertions(+), 7 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 97ebd2e3f..8444c0705 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using System; namespace CodeCracker.CSharp.Style { @@ -37,11 +38,10 @@ private static async Task MakeTernaryAsync(Document document, Diagnost var elseStatement = ifStatement.Else; var returnStatementInsideElse = (ReturnStatementSyntax)(elseStatement.Statement is BlockSyntax ? ((BlockSyntax)elseStatement.Statement).Statements.Single() : elseStatement.Statement); var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - ExpressionSyntax trueExpression, falseExpression; - TernaryOperatorCodeFixHelper.CreateExpressions(returnStatementInsideIf.Expression, returnStatementInsideElse.Expression, semanticModel, out trueExpression, out falseExpression); + var conditionalExpression = TernaryOperatorCodeFixHelper.CreateExpressions(returnStatementInsideIf.Expression, returnStatementInsideElse.Expression, ifStatement.Condition, semanticModel); var ternary = SyntaxFactory.ReturnStatement( - SyntaxFactory.ConditionalExpression(ifStatement.Condition, trueExpression, falseExpression)) + conditionalExpression) .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(ifStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); @@ -76,14 +76,13 @@ private static async Task MakeTernaryAsync(Document document, Diagnost var assignmentExpressionInsideIf = (AssignmentExpressionSyntax)expressionInsideIf.Expression; var assignmentExpressionInsideElse = (AssignmentExpressionSyntax)expressionInsideElse.Expression; var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - ExpressionSyntax trueExpression, falseExpression; - TernaryOperatorCodeFixHelper.CreateExpressions(assignmentExpressionInsideIf.Right, assignmentExpressionInsideElse.Right, semanticModel, out trueExpression, out falseExpression); + var conditionalExpression = TernaryOperatorCodeFixHelper.CreateExpressions(assignmentExpressionInsideIf.Right, assignmentExpressionInsideElse.Right, ifStatement.Condition, semanticModel); var ternary = SyntaxFactory.ExpressionStatement( SyntaxFactory.AssignmentExpression( assignmentExpressionInsideIf.Kind(), assignmentExpressionInsideIf.Left, - SyntaxFactory.ConditionalExpression(ifStatement.Condition, trueExpression, falseExpression))) + conditionalExpression)) .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(ifStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); @@ -95,13 +94,98 @@ private static async Task MakeTernaryAsync(Document document, Diagnost internal static class TernaryOperatorCodeFixHelper { - public static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel, out ExpressionSyntax trueExpression, out ExpressionSyntax falseExpression) + public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, ExpressionSyntax ifStatementCondition, SemanticModel semanticModel) + { + + var methodCallArgApplied = TryApplyArgsOnMethodCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (methodCallArgApplied != null) return methodCallArgApplied; + var constructorArgsApplied = TryApplyArgsOnConstructorCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (constructorArgsApplied != null) return constructorArgsApplied; + var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); + var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); + var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); + ExpressionSyntax trueExpression; ExpressionSyntax falseExpression; + CreateExpressions(ifExpression, elseExpression, ifTypeInfo.Type, elseTypeInfo.Type, + ifTypeInfo.ConvertedType, elseTypeInfo.ConvertedType, typeSyntax, semanticModel, out trueExpression, out falseExpression); + return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); + } + + private static ExpressionSyntax TryApplyArgsOnConstructorCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + { + if (ifExpression is ObjectCreationExpressionSyntax && elseExpression is ObjectCreationExpressionSyntax) + { + var ifObjCreation = ifExpression as ObjectCreationExpressionSyntax; + var elseObjCreation = elseExpression as ObjectCreationExpressionSyntax; + if ((ifObjCreation.Initializer == null && elseObjCreation.Initializer == null) || + ifObjCreation.Initializer != null && elseObjCreation.Initializer != null && + ifObjCreation.Initializer.GetText().ContentEquals(elseObjCreation.Initializer.GetText())) // Initializer are either absent or text equals + { + var ifMethodinfo = semanticModel.GetSymbolInfo(ifObjCreation); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseObjCreation); + if (object.Equals(ifMethodinfo, elseMethodinfo)) //same constructor and overload + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifObjCreation.ArgumentList, elseObjCreation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.ObjectCreationExpression(ifObjCreation.Type, CreateMethodArgumentList(ifStatementCondition, ifObjCreation.ArgumentList, elseObjCreation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel), ifObjCreation.Initializer); + } + } + } + return null; + } + + private static ExpressionSyntax TryApplyArgsOnMethodCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + { + if (ifExpression is InvocationExpressionSyntax && elseExpression is InvocationExpressionSyntax) + { + var ifInvocation = ifExpression as InvocationExpressionSyntax; + var elseInvocation = elseExpression as InvocationExpressionSyntax; + var ifMethodinfo = semanticModel.GetSymbolInfo(ifInvocation.Expression); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation.Expression); + if (object.Equals(ifMethodinfo, elseMethodinfo) && ifMethodinfo.CandidateReason != CandidateReason.LateBound) //same method and overload, but not dynamic + { + if (ifInvocation.Expression.GetText().ContentEquals(elseInvocation.Expression.GetText())) //same 'path' to the invocation + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.InvocationExpression(ifInvocation.Expression, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel)); + } + } + } + return null; + } + + private static ArgumentListSyntax CreateMethodArgumentList(ExpressionSyntax ifStatementCondition, ArgumentListSyntax argList1, ArgumentListSyntax argList2, int argumentIndexThatDiffers, SemanticModel semanticModel) + { + var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); + var argSelector = zipped.Select((args, i) => + (i == argumentIndexThatDiffers) ? + SyntaxFactory.Argument(GetConditionalExpressionForArgument(ifStatementCondition, args.a1.Expression, args.a2.Expression, semanticModel)) + : args.a1); + return SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(argSelector)); + } + + private static ConditionalExpressionSyntax GetConditionalExpressionForArgument(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) { var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); + ExpressionSyntax trueExpression; ExpressionSyntax falseExpression; CreateExpressions(ifExpression, elseExpression, ifTypeInfo.Type, elseTypeInfo.Type, ifTypeInfo.ConvertedType, elseTypeInfo.ConvertedType, typeSyntax, semanticModel, out trueExpression, out falseExpression); + return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); + } + + private static int FindSingleArgumentIndexThatDiffers(ArgumentListSyntax argList1, ArgumentListSyntax argList2, SemanticModel semanticModel) + { + if (argList1.Arguments.Count != argList2.Arguments.Count) return -1; // in case of 'params' + var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); + var singleMissmatch = zipped.Where(args => + { + var a1Text = args.a1.GetText(); + var a2Text = args.a2.GetText(); + return !a1Text.ContentEquals(a2Text); + }).Take(2).ToList(); + return (singleMissmatch.Count == 1) ? singleMissmatch[0].i : -1; } private static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index 68d90f96d..c9c86f91c 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -334,6 +334,68 @@ public static void Foo() "; await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultChangeToTernaryFixGetsArgsApplied() + { + var source = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + if (something) + { + a = Method(1); + } + else + { + a = Method(2); + } + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + a = Method(something?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultWithComplexArgumentEvaluationChangeToTernaryFixGetsArgsApplied() + { + var source = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + if (something) + { + a = Method(1); + } + else + { + a = Method(2 + 2); + } + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + a = Method(something?1:2 + 2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } public class TernaryOperatorWithReturnTests : CodeFixVerifier @@ -723,5 +785,547 @@ public static Base Foo() "; await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenReturnStatementContainsMethodCallAnalyzerCreatesDiagnostic() + { + var source = @" + private int Method(int i) => i; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = DiagnosticId.TernaryOperator_Return.ToDiagnosticId(), + Message = "You can use a ternary operator.", + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 17) } + }; + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithSingleDifferentArgumentGetsArgsApplied() + { + var source = @" + private int Method(int i) => i; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i) => i; + + public int Foo() + { + return Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereSingleDifferentGetsArgsApplied() + { + var source = @" + private int Method(int i, string t) => i; + + public int Foo() + { + if (true) + return Method(1, ""hello""); + else + return Method(2, ""hello""); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i, string t) => i; + + public int Foo() + { + return Method(true?1:2, ""hello""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereMultipleDifferentGetsArgsNotApplied() + { + var source = @" + private int Method(int i, string t) => i; + + public int Foo() + { + if (true) + return Method(1, ""hello1""); + else + return Method(2, ""hello2""); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i, string t) => i; + + public int Foo() + { + return true?Method(1,""hello1""):Method(2, ""hello2""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodArgumentsGetCastedWhenGetsArgsApplied() + { + var source = @" + class Base { } + class A : Base { } + class B : Base { } + + private int Method(Base b, string t) => 1; + + public int Foo() + { + if (true) + return Method(new A(), ""hello""); + else + return Method(new B(), ""hello""); + }".WrapInCSharpClass(); + var fixtest = @" + class Base { } + class A : Base { } + class B : Base { } + + private int Method(Base b, string t) => 1; + + public int Foo() + { + return Method(true?(Base)new A():new B(),""hello""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithPrefixedMethodGetsArgsApplied() + { + var source = @" + private int Method(int a) => a; + + public int Foo() + { + if (true) + return this.Method(1); + else + return this.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int a) => a; + + public int Foo() + { + return this.Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfPropertyGetsArgsApplied() + { + var source = @" + class A { + private int Method(int a) => a; + } + + public int Foo() + { + var a=new A(); + if (true) + return a.Method(1); + else + return a.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + class A { + private int Method(int a) => a; + } + + public int Foo() + { + var a=new A(); + return a.Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentPropertyGetsArgsNotApplied() + { + var source = @" + class A { + public int Method(int a) => a; + } + A Prop1 { get { return new A(); } } + A Prop2 { get { return new A(); } } + + public int Foo() + { + if (true) + return this.Prop1.Method(1); + else + return this.Prop2.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + class A { + public int Method(int a) => a; + } + A Prop1 { get { return new A(); } } + A Prop2 { get { return new A(); } } + + public int Foo() + { + return true?this.Prop1.Method(1):this.Prop2.Method(2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfSameOverloadGetsArgsApplied() + { + var source = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + return Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentOverloadGetsArgsNotApplied() + { + var source = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(""2""); + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + return true?Method(1):Method(""2""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentOverloadButCastingPossibleGetsArgsNotApplied() + { + var source = @" + public class A { } + public class B:A { } + void Method(A a) { }; + void Method(B b) { }; + + public int Foo() + { + if (true) + return Method(new A()); + else + return Method(new B()); + }".WrapInCSharpClass(); + var fixtest = @" + public class A { } + public class B:A { } + void Method(A a) { }; + void Method(B b) { }; + + public int Foo() + { + return true?Method(new A()):Method(new B()); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodNestedInMemberAccessGetsArgsNotApplied() + { + var source = @" + class A { + public int Prop { get; } + } + + A GetA(int i) => new A(); + + public int Foo() + { + if (true) + return GetA(1).Prop; + else + return GetA(2).Prop; + }".WrapInCSharpClass(); + var fixtest = @" + class A { + public int Prop { get; } + } + + A GetA(int i) => new A(); + + public int Foo() + { + return true?GetA(1).Prop:GetA(2).Prop; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodParamOverloadAndNumerOfArgsAreEqualGetsApplied() + { + var source = @" + private int M(params int[] args) { } + + public int Foo() + { + if (true) + return M(1,1); + else + return M(1,2); + }".WrapInCSharpClass(); + var fixtest = @" + private int M(params int[] args) { } + + public int Foo() + { + return M(1,true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodParamOverloadAndNumerOfArgsAreDifferentGetsNotApplied() + { + var source = @" + private int M(params int[] args) { } + + public int Foo() + { + if (true) + return M(1,1); + else + return M(1,2,3); + }".WrapInCSharpClass(); + var fixtest = @" + private int M(params int[] args) { } + + public int Foo() + { + return true?M(1,1):M(1,2,3); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDynamicObjGetsArgsNotApplied() + { + // Calls on dynamic objects get dispatched during runtime. + // Therefore the semantic would be changed if we apply to arguments + // and casting is involved: + // d.M(new A()) else d.M(new B()) -> d.M(cond?(Base)new A():new B()); + // is not the same as cond?d.M(new A()): d.M(new B()) on dynamic objects. + var source = @" + public class Base {} + public class A: Base {} + public class B: Base {} + + public int Foo() + { + dynamic d = new object(); + if (true) + return d.M(new A()); + else + return d.M(new B()); + }".WrapInCSharpClass(); + var fixtest = @" + public class Base {} + public class A: Base {} + public class B: Base {} + + public int Foo() + { + dynamic d = new object(); + return true?d.M(new A()):d.M(new B()); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDynamicObjGetsArgsNeverApplied() + { + // arguments on dynamic method calls are never applied even if it would be save. + // see comments above for why dynamic is dangerous. + var source = @" + public int Foo() + { + dynamic d = new object(); + if (true) + return d.M(1,1); + else + return d.M(1,2); + }".WrapInCSharpClass(); + var fixtest = @" + public int Foo() + { + dynamic d = new object(); + return true?d.M(1,1):d.M(1,2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorGetsArgsApplied() + { + var source = @" + public System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1); + else + return new System.Collections.Generic.List(2); + }".WrapInCSharpClass(); + var fixtest = @" + public System.Collections.Generic.List Foo() + { + return new System.Collections.Generic.List(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithIdenticalInitializerGetsArgsApplied() + { + var source = @" + public new System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1) { 1 }; + else + return new System.Collections.Generic.List(2) { 1 }; + }".WrapInCSharpClass(); + var fixtest = @" + public new System.Collections.Generic.List Foo() + { + return new System.Collections.Generic.List(true?1:2) { 1 }; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithDifferentInitializerGetsArgsNotApplied() + { + var source = @" + public System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1) { 1 }; + else + return new System.Collections.Generic.List(2) { 1, 2 }; + }".WrapInCSharpClass(); + var fixtest = @" + public System.Collections.Generic.List Foo() + { + return true?new System.Collections.Generic.List(1) { 1 } : new System.Collections.Generic.List(2) { 1, 2 }; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithDifferentOverloadsGetArgsNotApplied() + { + var source = @" + public class A + { + public A(int i) { } + public A(string s) { } + } + public A Foo() + { + if (true) + return new A(1); + else + return new A(""1""); + }".WrapInCSharpClass(); + var fixtest = @" + public class A + { + public A(int i) { } + public A(string s) { } + } + public A Foo() + { + return true?new A(1):new A(""1""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorOfDifferentObjectsGetArgsNotApplied() + { + var source = @" + public class A + { + public A(int i) { } + } + public class B + { + public B(int i) { } + } + + public Object Foo() + { + if (true) + return new A(1); + else + return new B(2); + }".WrapInCSharpClass(); + var fixtest = @" + public class A + { + public A(int i) { } + } + public class B + { + public B(int i) { } + } + + public Object Foo() + { + return true?(object)new A(1):new B(2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From 1e6d745cac04c93f0bc303b14835df2f63f375a3 Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:04:58 -0700 Subject: [PATCH 026/152] Update grammar in StaticConstructorExceptionAnalyzer.cs #839 --- .../Design/StaticConstructorExceptionAnalyzer.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs b/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs index 946cae300..c8a9f2f23 100644 --- a/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs +++ b/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs @@ -10,13 +10,11 @@ namespace CodeCracker.CSharp.Design [DiagnosticAnalyzer(LanguageNames.CSharp)] public class StaticConstructorExceptionAnalyzer : DiagnosticAnalyzer { - internal const string Title = "Don't throw exception inside static constructors."; - internal const string MessageFormat = "Don't throw exception inside static constructors."; + internal const string Title = "Don't throw exceptions inside static constructors."; + internal const string MessageFormat = "Don't throw exceptions inside static constructors."; internal const string Category = SupportedCategories.Design; - const string Description = "Static constructor are called before the first time a class is used but the " - + "caller doesn't control when exactly.\r\n" - + "Exception thrown in this context force callers to use 'try' block around any useage of the class " - + "and should be avoided."; + const string Description = "Static constructors are called before a class is used for the first time. Exceptions thrown " + + "in static constructors force the use of a try block and should be avoided."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.StaticConstructorException.ToDiagnosticId(), @@ -49,4 +47,4 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) context.ReportDiagnostic(Diagnostic.Create(Rule, @throw.GetLocation(), ctor.Identifier.Text)); } } -} \ No newline at end of file +} From 2e74e2698ede0d57426192deed7b5a652eaa3ed8 Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:06:30 -0700 Subject: [PATCH 027/152] Update grammar in StaticConstructorExceptionAnalyzer.vb #839 --- .../Design/StaticConstructorExceptionAnalyzer.vb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb b/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb index 72799cbd9..3cfaab1f3 100644 --- a/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb +++ b/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb @@ -9,11 +9,11 @@ Namespace Design Inherits DiagnosticAnalyzer Public Shared ReadOnly Id As String = DiagnosticId.StaticConstructorException.ToDiagnosticId() - Public Const Title As String = "Don't throw exception inside static constructors." + Public Const Title As String = "Don't throw exceptions inside static constructors." Public Const MessageFormat As String = "Don't throw exceptions inside static constructors." Public Const Category As String = SupportedCategories.Design - Public Const Description As String = "Static constructor are called before the first time a class is used but the caller doesn't control when exactly. -Exception thrown in this context forces callers to use 'try' block around any useage of the class and should be avoided." + Public Const Description As String = "Static constructors are called before a class is used for the first time. Exceptions thrown + in static constructors force the use of a try block and should be avoided." Protected Shared Rule As DiagnosticDescriptor = New DiagnosticDescriptor( Id, Title, From 05ef8216052afc705d7de3abc3f4a6c7780cbcae Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:08:11 -0700 Subject: [PATCH 028/152] Update grammar in StaticConstructorExceptionAnalyzer.cs #839 From 089f3a6cff713e81d485d0c5c534b438d9077601 Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:23:19 -0700 Subject: [PATCH 029/152] Update grammar in StaticConstructorExceptionTests.cs #839 --- .../Design/StaticConstructorExceptionTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs b/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs index 5672bd5a9..f6ba9d8a0 100644 --- a/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs @@ -22,7 +22,7 @@ static MyClass() var expected = new DiagnosticResult { Id = DiagnosticId.StaticConstructorException.ToDiagnosticId(), - Message = "Don't throw exception inside static constructors.", + Message = "Don't throw exceptions inside static constructors.", Severity = DiagnosticSeverity.Warning, Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } }; @@ -149,4 +149,4 @@ static MyClass2() await VerifyCSharpFixAllAsync(new string[] { source1, source2 }, new string[] { fixtest1, fixtest2 }); } } -} \ No newline at end of file +} From 0459cc5ef6c1d86e60f4248c40184868b5c44deb Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:48:57 -0700 Subject: [PATCH 030/152] Update grammar in StringBuilderInLoopAnalyzer.cs #839 --- .../CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs b/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs index 27427a1f3..60960be01 100644 --- a/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs +++ b/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs @@ -14,8 +14,7 @@ public class StringBuilderInLoopAnalyzer : DiagnosticAnalyzer internal const string Title = "Don't concatenate strings in loops"; internal const string MessageFormat = "Don't concatenate '{0}' in a loop"; internal const string Category = SupportedCategories.Performance; - const string Description = "Do not concatenate a string on a loop. It will alocate a lot of memory." - + "Use a StringBuilder instead. It will will require less allocation, less garbage collector work, less CPU cycles, and less overall time."; + const string Description = "Don't concatenate strings in a loop. Using a StringBuilder will require less memory and time."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), @@ -84,4 +83,4 @@ private static void AnalyzeAssignment(SyntaxNodeAnalysisContext context) context.ReportDiagnostic(diagnostic); } } -} \ No newline at end of file +} From 0dc0321d89a6a27da2b02cf119f5e91dc8497bbf Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:50:00 -0700 Subject: [PATCH 031/152] Update grammar in StringBuilderInLoopAnalyzer.vb #839 --- .../CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb b/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb index e00b20f13..36c1a1ac1 100644 --- a/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb +++ b/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb @@ -13,7 +13,7 @@ Namespace Performance Public Const Title As String = "Don't concatenate strings in loops" Public Const MessageFormat As String = "Don't concatenate '{0}' in a loop." Public Const Category As String = SupportedCategories.Performance - Public Const Description As String = "Do not concatenate a string in a loop. It will allocate a lot of memory. Use a StringBuilder instead. It will require less allocation, less garbage collection work, less CPU cycles, and less overall time." + Public Const Description As String = "Don't concatenate strings in a loop. Using a StringBuilder will require less memory and time." Protected Shared Rule As DiagnosticDescriptor = New DiagnosticDescriptor( Id, Title, @@ -71,4 +71,4 @@ Namespace Performance context.ReportDiagnostic(diag) End Sub End Class -End Namespace \ No newline at end of file +End Namespace From 51fbe1cd7ce47e3fd5c1f0d93a70302fb1295e7b Mon Sep 17 00:00:00 2001 From: sdygert Date: Sat, 18 Mar 2017 07:47:05 -0700 Subject: [PATCH 032/152] Update grammar in RemovePrivateMethodNeverUsedAnalyzer.cs #839 --- .../CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs index 40b86f79d..25bd20246 100644 --- a/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs @@ -16,7 +16,7 @@ public class RemovePrivateMethodNeverUsedAnalyzer : DiagnosticAnalyzer internal const string Title = "Unused Method"; internal const string Message = "Method is not used."; internal const string Category = SupportedCategories.Usage; - const string Description = "When a private method declared does not used might bring incorrect conclusions."; + const string Description = "Unused private methods can be safely removed as they are unnecessary."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.RemovePrivateMethodNeverUsed.ToDiagnosticId(), @@ -126,4 +126,4 @@ private static bool IsMainMethodEntryPoint(MethodDeclarationSyntax methodTarget, return true; } } -} \ No newline at end of file +} From d7fe7955f96d2e64a76c00a1982c83dd94282739 Mon Sep 17 00:00:00 2001 From: sdygert Date: Sat, 18 Mar 2017 07:47:31 -0700 Subject: [PATCH 033/152] Update grammar in RemovePrivateMethodNeverUsedAnalyzer.vb #839 --- .../CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualBasic/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.vb b/src/VisualBasic/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.vb index e1ecd9068..652a83ca7 100644 --- a/src/VisualBasic/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.vb +++ b/src/VisualBasic/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.vb @@ -11,7 +11,7 @@ Namespace Usage Friend Const Title = "Unused Method" Friend Const Message = "Method is not used." - Private Const Description = "When a private method is declared but not used, remove it to avoid confusion." + Private Const Description = "Unused private methods can be safely removed as they are unnecessary." Friend Shared Rule As New DiagnosticDescriptor( DiagnosticId.RemovePrivateMethodNeverUsed.ToDiagnosticId(), From b71177cbde7855104f2334e9d5c8b3cf815c377c Mon Sep 17 00:00:00 2001 From: sdygert Date: Sat, 18 Mar 2017 07:54:39 -0700 Subject: [PATCH 034/152] Update grammar in RegexAnalyzer.cs #839 --- src/CSharp/CodeCracker/Usage/RegexAnalyzer.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/RegexAnalyzer.cs b/src/CSharp/CodeCracker/Usage/RegexAnalyzer.cs index 6ce7c1a5d..41393ac96 100644 --- a/src/CSharp/CodeCracker/Usage/RegexAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/RegexAnalyzer.cs @@ -10,11 +10,10 @@ namespace CodeCracker.CSharp.Usage [DiagnosticAnalyzer(LanguageNames.CSharp)] public class RegexAnalyzer : DiagnosticAnalyzer { - internal const string Title = "Your Regex expression is wrong"; + internal const string Title = "Your regex expression is incorrect"; internal const string MessageFormat = "{0}"; internal const string Category = SupportedCategories.Naming; - const string Description = "This diagnostic compile the Regex expression and trigger if the compilation fail " - + "by throwing an exception."; + const string Description = "There is an error in your regex expression."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.Regex.ToDiagnosticId(), @@ -63,4 +62,4 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) } } } -} \ No newline at end of file +} From 0b1a1783aa94fa2a09622117036b42677c8727cc Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:48:57 -0700 Subject: [PATCH 035/152] Update grammar in StringBuilderInLoopAnalyzer.cs #839 --- .../CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs b/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs index 27427a1f3..60960be01 100644 --- a/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs +++ b/src/CSharp/CodeCracker/Performance/StringBuilderInLoopAnalyzer.cs @@ -14,8 +14,7 @@ public class StringBuilderInLoopAnalyzer : DiagnosticAnalyzer internal const string Title = "Don't concatenate strings in loops"; internal const string MessageFormat = "Don't concatenate '{0}' in a loop"; internal const string Category = SupportedCategories.Performance; - const string Description = "Do not concatenate a string on a loop. It will alocate a lot of memory." - + "Use a StringBuilder instead. It will will require less allocation, less garbage collector work, less CPU cycles, and less overall time."; + const string Description = "Don't concatenate strings in a loop. Using a StringBuilder will require less memory and time."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), @@ -84,4 +83,4 @@ private static void AnalyzeAssignment(SyntaxNodeAnalysisContext context) context.ReportDiagnostic(diagnostic); } } -} \ No newline at end of file +} From 7b3122aefb4a3f1ff184d3ef0f3a85af8be2e1c0 Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:50:00 -0700 Subject: [PATCH 036/152] Update grammar in StringBuilderInLoopAnalyzer.vb #839 --- .../CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb b/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb index e00b20f13..36c1a1ac1 100644 --- a/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb +++ b/src/VisualBasic/CodeCracker/Performance/StringBuilderInLoopAnalyzer.vb @@ -13,7 +13,7 @@ Namespace Performance Public Const Title As String = "Don't concatenate strings in loops" Public Const MessageFormat As String = "Don't concatenate '{0}' in a loop." Public Const Category As String = SupportedCategories.Performance - Public Const Description As String = "Do not concatenate a string in a loop. It will allocate a lot of memory. Use a StringBuilder instead. It will require less allocation, less garbage collection work, less CPU cycles, and less overall time." + Public Const Description As String = "Don't concatenate strings in a loop. Using a StringBuilder will require less memory and time." Protected Shared Rule As DiagnosticDescriptor = New DiagnosticDescriptor( Id, Title, @@ -71,4 +71,4 @@ Namespace Performance context.ReportDiagnostic(diag) End Sub End Class -End Namespace \ No newline at end of file +End Namespace From 1699a3178249cee656541bd3d885a30f519dec2c Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:04:58 -0700 Subject: [PATCH 037/152] Update grammar in StaticConstructorExceptionAnalyzer.cs #839 --- .../Design/StaticConstructorExceptionAnalyzer.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs b/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs index 946cae300..c8a9f2f23 100644 --- a/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs +++ b/src/CSharp/CodeCracker/Design/StaticConstructorExceptionAnalyzer.cs @@ -10,13 +10,11 @@ namespace CodeCracker.CSharp.Design [DiagnosticAnalyzer(LanguageNames.CSharp)] public class StaticConstructorExceptionAnalyzer : DiagnosticAnalyzer { - internal const string Title = "Don't throw exception inside static constructors."; - internal const string MessageFormat = "Don't throw exception inside static constructors."; + internal const string Title = "Don't throw exceptions inside static constructors."; + internal const string MessageFormat = "Don't throw exceptions inside static constructors."; internal const string Category = SupportedCategories.Design; - const string Description = "Static constructor are called before the first time a class is used but the " - + "caller doesn't control when exactly.\r\n" - + "Exception thrown in this context force callers to use 'try' block around any useage of the class " - + "and should be avoided."; + const string Description = "Static constructors are called before a class is used for the first time. Exceptions thrown " + + "in static constructors force the use of a try block and should be avoided."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.StaticConstructorException.ToDiagnosticId(), @@ -49,4 +47,4 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) context.ReportDiagnostic(Diagnostic.Create(Rule, @throw.GetLocation(), ctor.Identifier.Text)); } } -} \ No newline at end of file +} From c1d348985b116736f9ba1092ac05d1de1b47d269 Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:06:30 -0700 Subject: [PATCH 038/152] Update grammar in StaticConstructorExceptionAnalyzer.vb #839 --- .../Design/StaticConstructorExceptionAnalyzer.vb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb b/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb index 72799cbd9..3cfaab1f3 100644 --- a/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb +++ b/src/VisualBasic/CodeCracker/Design/StaticConstructorExceptionAnalyzer.vb @@ -9,11 +9,11 @@ Namespace Design Inherits DiagnosticAnalyzer Public Shared ReadOnly Id As String = DiagnosticId.StaticConstructorException.ToDiagnosticId() - Public Const Title As String = "Don't throw exception inside static constructors." + Public Const Title As String = "Don't throw exceptions inside static constructors." Public Const MessageFormat As String = "Don't throw exceptions inside static constructors." Public Const Category As String = SupportedCategories.Design - Public Const Description As String = "Static constructor are called before the first time a class is used but the caller doesn't control when exactly. -Exception thrown in this context forces callers to use 'try' block around any useage of the class and should be avoided." + Public Const Description As String = "Static constructors are called before a class is used for the first time. Exceptions thrown + in static constructors force the use of a try block and should be avoided." Protected Shared Rule As DiagnosticDescriptor = New DiagnosticDescriptor( Id, Title, From 67e4081bd90b48f57365fa28ed85879805e9e2e1 Mon Sep 17 00:00:00 2001 From: sdygert Date: Wed, 15 Mar 2017 19:23:19 -0700 Subject: [PATCH 039/152] Update grammar in StaticConstructorExceptionTests.cs #839 --- .../Design/StaticConstructorExceptionTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs b/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs index 5672bd5a9..f6ba9d8a0 100644 --- a/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs @@ -22,7 +22,7 @@ static MyClass() var expected = new DiagnosticResult { Id = DiagnosticId.StaticConstructorException.ToDiagnosticId(), - Message = "Don't throw exception inside static constructors.", + Message = "Don't throw exceptions inside static constructors.", Severity = DiagnosticSeverity.Warning, Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } }; @@ -149,4 +149,4 @@ static MyClass2() await VerifyCSharpFixAllAsync(new string[] { source1, source2 }, new string[] { fixtest1, fixtest2 }); } } -} \ No newline at end of file +} From 62ecc7729f766f781a3eb07da4120a78eb57e4ca Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 19 Mar 2017 12:25:54 -0300 Subject: [PATCH 040/152] Update dependencies This will enable tests to run in VS again, including live unit testing. We had to roll back Microsoft.CodeAnalysis.Analyzers, because it conflicted with other packages, we might have to upgrade them all to 1.1.0 so that we don't get those nasty build warnings. --- build.targets.ps1 | 2 +- src/CSharp/CodeCracker/CodeCracker.csproj | 8 ++-- src/CSharp/CodeCracker/packages.config | 4 +- .../CodeCracker.Common.csproj | 8 ++-- src/Common/CodeCracker.Common/packages.config | 4 +- .../CodeCracker/CodeCracker.vbproj | 8 ++-- src/VisualBasic/CodeCracker/packages.config | 4 +- .../CodeCracker.Test/CodeCracker.Test.csproj | 45 ++++++++--------- test/CSharp/CodeCracker.Test/packages.config | 22 ++++----- .../CodeCracker.Test.Common.csproj | 48 +++++++------------ .../CodeCracker.Test.Common/packages.config | 24 +++++----- .../CodeCracker.Test/CodeCracker.Test.vbproj | 41 +++++++--------- .../CodeCracker.Test/packages.config | 22 ++++----- 13 files changed, 106 insertions(+), 134 deletions(-) diff --git a/build.targets.ps1 b/build.targets.ps1 index 42ee817bb..430e72c21 100644 --- a/build.targets.ps1 +++ b/build.targets.ps1 @@ -23,7 +23,7 @@ Properties { $testDirVB = "$testDir\VisualBasic\CodeCracker.Test\bin\Release" $logDir = "$rootDir\log" $outputXml = "$logDir\CodeCoverageResults.xml" - $reportGeneratorExe = "$packagesDir\ReportGenerator.2.4.4.0\tools\ReportGenerator.exe" + $reportGeneratorExe = "$packagesDir\ReportGenerator.2.5.6\tools\ReportGenerator.exe" $coverageReportDir = "$logDir\codecoverage\" $coverallsNetExe = "$packagesDir\coveralls.io.1.3.4\tools\coveralls.net.exe" $isRelease = $isAppVeyor -and (($env:APPVEYOR_REPO_BRANCH -eq "release") -or ($env:APPVEYOR_REPO_TAG -eq "true")) diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index e1a60a05e..762e6c620 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -221,10 +221,10 @@ - - - - + + + + diff --git a/src/CSharp/CodeCracker/packages.config b/src/CSharp/CodeCracker/packages.config index 26624b6d1..d1bbcab2c 100644 --- a/src/CSharp/CodeCracker/packages.config +++ b/src/CSharp/CodeCracker/packages.config @@ -1,7 +1,7 @@  - - + + diff --git a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj index 6ecee6f01..3426e7d12 100644 --- a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj +++ b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj @@ -70,10 +70,10 @@ - - - - + + + + diff --git a/src/Common/CodeCracker.Common/packages.config b/src/Common/CodeCracker.Common/packages.config index 564e6399a..d8681f9ca 100644 --- a/src/Common/CodeCracker.Common/packages.config +++ b/src/Common/CodeCracker.Common/packages.config @@ -1,7 +1,7 @@  - - + + diff --git a/src/VisualBasic/CodeCracker/CodeCracker.vbproj b/src/VisualBasic/CodeCracker/CodeCracker.vbproj index ba1b36a08..e2deff9b9 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.vbproj +++ b/src/VisualBasic/CodeCracker/CodeCracker.vbproj @@ -162,10 +162,10 @@ - - - - + + + + diff --git a/src/VisualBasic/CodeCracker/packages.config b/src/VisualBasic/CodeCracker/packages.config index 06a0521ef..20b3df7df 100644 --- a/src/VisualBasic/CodeCracker/packages.config +++ b/src/VisualBasic/CodeCracker/packages.config @@ -1,7 +1,7 @@  - - + + diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index b17ba4a79..e0e64dccb 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -1,6 +1,6 @@  - + Debug AnyCPU @@ -40,13 +40,11 @@ false - - ..\..\..\packages\FluentAssertions.4.3.2\lib\net45\FluentAssertions.dll - True + + ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll - - ..\..\..\packages\FluentAssertions.4.3.2\lib\net45\FluentAssertions.Core.dll - True + + ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.dll @@ -68,9 +66,8 @@ ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll True - - ..\..\..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll - True + + ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll @@ -108,20 +105,16 @@ - ..\..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll - True + ..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - - ..\..\..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll - True + + ..\..\..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll - - ..\..\..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll - True + + ..\..\..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll - - ..\..\..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll - True + + ..\..\..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll @@ -235,17 +228,17 @@ - - - - + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + From 099159dfedd4c57105d26a196bde2c3c5833c902 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 19 Mar 2017 12:47:27 -0300 Subject: [PATCH 052/152] Fix xunit console location in script --- build.targets.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.targets.ps1 b/build.targets.ps1 index 430e72c21..d5c0cc057 100644 --- a/build.targets.ps1 +++ b/build.targets.ps1 @@ -15,7 +15,7 @@ Properties { $nupkgPathCS = "$rootDir\src\CSharp\CodeCracker.CSharp.{0}.nupkg" $nupkgPathVB = "$rootDir\src\VisualBasic\CodeCracker.VisualBasic.{0}.nupkg" $nupkgPathJoint = "$rootDir\CodeCracker.{0}.nupkg" - $xunitConsoleExe = "$packagesDir\xunit.runner.console.2.1.0\tools\xunit.console.x86.exe" + $xunitConsoleExe = "$packagesDir\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" $openCoverExe = "$packagesDir\OpenCover.4.6.519\tools\OpenCover.Console.exe" $testDllCS = "CodeCracker.Test.CSharp.dll" $testDllVB = "CodeCracker.Test.VisualBasic.dll" @@ -223,4 +223,4 @@ function RunTestWithCoverage($fullTestDllPaths) { Write-Host -ForegroundColor DarkBlue "Uploading coverage report to Coveralls.io" Exec { . $coverallsNetExe --opencover $outputXml --full-sources } } -} \ No newline at end of file +} From ac872ca9ebdd3db4aece2c60ef9e80b4173c42f9 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 19 Mar 2017 13:09:32 -0300 Subject: [PATCH 053/152] Fix test run scripts --- runTestsCS.ps1 | 2 +- runTestsVB.ps1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runTestsCS.ps1 b/runTestsCS.ps1 index 2131ad77c..930bdccb4 100644 --- a/runTestsCS.ps1 +++ b/runTestsCS.ps1 @@ -2,7 +2,7 @@ param([String]$testClass) $testDllDirPath = "$PSScriptRoot\test\CSharp\CodeCracker.Test\bin\Debug\" $testDllFileName = "CodeCracker.Test.CSharp.dll" $testDllFullFileName = "$testDllDirPath$testDllFileName" -$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.1.0\tools\xunit.console.x86.exe" +$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" if (!(gcm nodemon -ErrorAction Ignore)) { Write-Host -ForegroundColor DarkRed 'Nodemon not found, install it with npm: `npm i -g nodemon`' diff --git a/runTestsVB.ps1 b/runTestsVB.ps1 index 2da22c936..b2d53d619 100644 --- a/runTestsVB.ps1 +++ b/runTestsVB.ps1 @@ -2,7 +2,7 @@ param([String]$testClass) $testDllDirPath = "$PSScriptRoot\test\VisualBasic\CodeCracker.Test\bin\Debug\" $testDllFileName = "CodeCracker.Test.VisualBasic.dll" $testDllFullFileName = "$testDllDirPath$testDllFileName" -$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.1.0\tools\xunit.console.x86.exe" +$xunitConsole = "$PSScriptRoot\packages\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" if (!(gcm nodemon -ErrorAction Ignore)) { Write-Host -ForegroundColor DarkRed 'Nodemon not found, install it with npm: `npm i -g nodemon`' From 8247e6509729acd2513ab478bc5ac2fee7ce48f8 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 19 Mar 2017 13:09:59 -0300 Subject: [PATCH 054/152] Do not raise a diagnostic for disposables with yield return Fixes #877 --- .../Extensions/CSharpAnalyzerExtensions.cs | 7 ++++++ .../DisposableVariableNotDisposedAnalyzer.cs | 6 +++-- .../DisposableVariableNotDisposedTests.cs | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs b/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs index 50065c3d7..8a248fad1 100644 --- a/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs +++ b/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs @@ -469,6 +469,13 @@ public static IEnumerable OfKind(this IEnumerable node yield return (TNode)node; } + public static IEnumerable OfKind(this IEnumerable nodes, params SyntaxKind[] kinds) where TNode : SyntaxNode + { + foreach (var node in nodes) + if (node.IsAnyKind(kinds)) + yield return (TNode)node; + } + public static IEnumerable OfKind(this IEnumerable nodes, SyntaxKind kind) where TNode : SyntaxNode { foreach (var node in nodes) diff --git a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs index e53f40891..75ed943f4 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs @@ -43,7 +43,7 @@ private static void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context) while (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ParenthesizedExpression, SyntaxKind.ConditionalExpression, SyntaxKind.CastExpression)) topSyntaxNode = topSyntaxNode.Parent; - if (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ReturnStatement, SyntaxKind.UsingStatement)) + if (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ReturnStatement, SyntaxKind.UsingStatement, SyntaxKind.YieldReturnStatement)) return; if (topSyntaxNode.Ancestors().Any(i => i.IsAnyKind( @@ -148,10 +148,12 @@ private static bool IsReturned(MethodDeclarationSyntax method, StatementSyntax s body = method.Body; } if (body == null) return true; - var returnExpressions = body.DescendantNodes().OfType().Select(r => r.Expression); var returnTypeSymbol = methodSymbol?.ReturnType; if (returnTypeSymbol == null) return false; if (returnTypeSymbol.SpecialType == SpecialType.System_Void) return false; + var bodyDescendantNodes = body.DescendantNodes().ToList(); + var returnExpressions = bodyDescendantNodes.OfType().Select(r => r.Expression).Union( + bodyDescendantNodes.OfKind(SyntaxKind.YieldReturnStatement).Select(yr => yr.Expression)); var isReturning = returnExpressions.Any(returnExpression => { var returnSymbol = semanticModel.GetSymbolInfo(returnExpression).Symbol; diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index a07c13405..83564c0be 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -123,6 +123,29 @@ public async Task VariableNotDisposableDoesNotCreateDiagnostic() await VerifyCSharpHasNoDiagnosticsAsync(source); } + [Fact] + public async Task IteratorWithDirectReturnDoesNotCreateDiagnostic() + { + var source = @" +public System.Collections.Generic.IEnumerable Foo() +{ + yield return new System.IO.MemoryStream(); +}".WrapInCSharpClass(); + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task IteratorWithIndirectReturnDoesNotCreateDiagnostic() + { + var source = @" +public System.Collections.Generic.IEnumerable Foo() +{ + var disposable = new System.IO.MemoryStream(); + yield return disposable; +}".WrapInCSharpClass(); + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + [Fact] public async Task DisposableVariableCreatesDiagnostic() { From f93c65c84f344218e0e100074c5e314168364f1c Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 19 Mar 2017 13:40:53 -0300 Subject: [PATCH 055/152] Disregard disposables in arrow expressions Fixes #880 --- .../Usage/DisposableVariableNotDisposedAnalyzer.cs | 1 + .../Usage/DisposableVariableNotDisposedTests.cs | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs index 75ed943f4..2a4b4c32f 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs @@ -47,6 +47,7 @@ private static void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context) return; if (topSyntaxNode.Ancestors().Any(i => i.IsAnyKind( + SyntaxKind.ArrowExpressionClause, SyntaxKind.ThisConstructorInitializer, SyntaxKind.BaseConstructorInitializer, SyntaxKind.ObjectCreationExpression))) diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index 83564c0be..d1ad9d3e9 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -123,6 +123,13 @@ public async Task VariableNotDisposableDoesNotCreateDiagnostic() await VerifyCSharpHasNoDiagnosticsAsync(source); } + [Fact] + public async Task ReturnOnExpressionBodiedMembersDoNotCreateDiagnostic() + { + var source = @"public static System.IO.MemoryStream Foo() => new System.IO.MemoryStream();".WrapInCSharpClass(); + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + [Fact] public async Task IteratorWithDirectReturnDoesNotCreateDiagnostic() { From 5c769f3431f3fbd1e867069b87fc1409d6877292 Mon Sep 17 00:00:00 2001 From: sdygert Date: Sun, 19 Mar 2017 13:39:28 -0700 Subject: [PATCH 056/152] Update grammar in TaskNameAsyncAnalyzer.cs #839 --- src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs index d90d22915..6c0f8997c 100644 --- a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs @@ -10,10 +10,10 @@ namespace CodeCracker.CSharp.Style [DiagnosticAnalyzer(LanguageNames.CSharp)] public class TaskNameAsyncAnalyzer : DiagnosticAnalyzer { - internal const string Title = "Async method can be terminating with 'Async' name."; + internal const string Title = "Asynchronous method can be terminated with the 'Async' keyword."; internal const string MessageFormat = "Change method name to {0}"; internal const string Category = SupportedCategories.Style; - const string Description = "Async method can be terminating with 'Async' name."; + const string Description = "Asynchronous method can be terminated with the 'Async' keyword."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.TaskNameAsync.ToDiagnosticId(), @@ -55,4 +55,4 @@ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) context.ReportDiagnostic(diag); } } -} \ No newline at end of file +} From c3402230b1fde51ae52837a27469fc57d4f0509b Mon Sep 17 00:00:00 2001 From: sdygert Date: Sun, 19 Mar 2017 13:50:01 -0700 Subject: [PATCH 057/152] Update grammar in EmptyObjectInitializerAnalyzer.cs #839 --- .../CodeCracker/Style/EmptyObjectInitializerAnalyzer.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/EmptyObjectInitializerAnalyzer.cs b/src/CSharp/CodeCracker/Style/EmptyObjectInitializerAnalyzer.cs index 7597ea48c..1ae23376f 100644 --- a/src/CSharp/CodeCracker/Style/EmptyObjectInitializerAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/EmptyObjectInitializerAnalyzer.cs @@ -12,8 +12,7 @@ public class EmptyObjectInitializerAnalyzer : DiagnosticAnalyzer internal const string Title = "Empty Object Initializer"; internal const string MessageFormat = "{0}"; internal const string Category = SupportedCategories.Style; - const string Description = "An empty object initializer doesn't add any information and only clutter the code.\r\n" - + "If there is no member to initialize, prefer using the standard constructor syntax."; + const string Description = "An object initializer without any arguments can be replaced with the standard constructor syntax."; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.EmptyObjectInitializer.ToDiagnosticId(), @@ -38,9 +37,9 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) if (objectCreation.Initializer != null && !objectCreation.Initializer.Expressions.Any()) { - var diagnostic = Diagnostic.Create(Rule, objectCreation.Initializer.OpenBraceToken.GetLocation(), "Remove empty object initializer."); + var diagnostic = Diagnostic.Create(Rule, objectCreation.Initializer.OpenBraceToken.GetLocation(), "Remove the empty object initializer."); context.ReportDiagnostic(diagnostic); } } } -} \ No newline at end of file +} From fafd44dc44387d31936c9b8cac50ba20fb54f138 Mon Sep 17 00:00:00 2001 From: sdygert Date: Sun, 19 Mar 2017 13:50:21 -0700 Subject: [PATCH 058/152] Update grammar in EmptyObjectInitializerTests.cs #839 --- .../CodeCracker.Test/Style/EmptyObjectInitializerTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs b/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs index a32dccc61..129824e22 100644 --- a/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs @@ -14,7 +14,7 @@ public async Task EmptyObjectInitializerTriggersFix() var expected = new DiagnosticResult { Id = DiagnosticId.EmptyObjectInitializer.ToDiagnosticId(), - Message = "Remove empty object initializer.", + Message = "Remove the empty object initializer.", Severity = DiagnosticSeverity.Warning, Locations = new[] { new DiagnosticResultLocation("Test0.cs", 1, 15) } }; @@ -54,4 +54,4 @@ public async Task AbsenceOfObjectInitializerIsIgnored() await VerifyCSharpHasNoDiagnosticsAsync(code); } } -} \ No newline at end of file +} From 6d7ad2139631d24555d23aae321b8e2be210b728 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 19 Mar 2017 22:20:13 -0300 Subject: [PATCH 059/152] Update changelog --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8af91802e..1b460cecb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,15 @@ ## [Unreleased](https://github.com/code-cracker/code-cracker/tree/HEAD) -[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.2...HEAD) +[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.3...HEAD) -**Closed issues:** +## [v1.0.3](https://github.com/code-cracker/code-cracker/tree/v1.0.3) (2017-03-20) +[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.2...v1.0.3) + +**Fixed bugs:** +- BUG: CC0022 DisposableVariableNotDisposedAnalyzer: False positive for expression bodied members [\#880](https://github.com/code-cracker/code-cracker/issues/880) +- BUG: CC0022 DisposableVariableNotDisposedAnalyzer: False positive in iterator methods [\#877](https://github.com/code-cracker/code-cracker/issues/877) ## [v1.0.2](https://github.com/code-cracker/code-cracker/tree/v1.0.2) (2017-03-12) [Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.1...v1.0.2) From 02bbf094a2f92e93e527758b6cd2f5bec4347dc1 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 20 Mar 2017 18:05:43 +0100 Subject: [PATCH 060/152] Ported analyzer and codefixprovider from https://github.com/ifpanalytics/Ifp.Analyzers/ --- .../CodeCracker.Vsix/CodeCracker.Vsix.csproj | 5 +- src/CSharp/CodeCracker/CodeCracker.csproj | 2 + .../Extensions/CSharpAnalyzerExtensions.cs | 5 + ...placeWithGetterOnlyAutoPropertyAnalyzer.cs | 77 +++++ ...thGetterOnlyAutoPropertyCodeFixProvider.cs | 140 ++++++++ src/Common/CodeCracker.Common/DiagnosticId.cs | 1 + .../Properties/Resources.Designer.cs | 126 ++++--- .../Properties/Resources.resx | 12 + .../CodeCracker.Test/CodeCracker.Test.csproj | 1 + .../ReplaceWithGetterOnlyAutoPropertyTests.cs | 325 ++++++++++++++++++ 10 files changed, 646 insertions(+), 48 deletions(-) create mode 100644 src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs create mode 100644 src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs create mode 100644 test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs diff --git a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj index 12f744c47..7dde1ebf3 100644 --- a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj +++ b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj @@ -1,14 +1,13 @@  - + - 15.0 + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 15.0 diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index 19bb1a9e7..a6d7d52d7 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -67,6 +67,8 @@ + + diff --git a/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs b/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs index 8a248fad1..0ccb8b5a6 100644 --- a/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs +++ b/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs @@ -17,12 +17,17 @@ public static void RegisterSyntaxNodeAction(this AnalysisCont public static void RegisterCompilationStartAction(this AnalysisContext context, LanguageVersion greaterOrEqualThanLanguageVersion, Action registrationAction) => context.RegisterCompilationStartAction(compilationContext => compilationContext.RunIfCSharpVersionOrGreater(greaterOrEqualThanLanguageVersion, () => registrationAction?.Invoke(compilationContext))); + + public static void RegisterSymbolAction(this AnalysisContext context, LanguageVersion greaterOrEqualThanLanguageVersion, Action registrationAction, params SymbolKind[] symbolKinds) => + context.RegisterSymbolAction(compilationContext => compilationContext.RunIfCSharpVersionOrGreater(greaterOrEqualThanLanguageVersion, () => registrationAction?.Invoke(compilationContext)), symbolKinds); #pragma warning disable RS1012 private static void RunIfCSharpVersionOrGreater(this CompilationStartAnalysisContext context, LanguageVersion greaterOrEqualThanLanguageVersion, Action action) => context.Compilation.RunIfCSharpVersionOrGreater(action, greaterOrEqualThanLanguageVersion); #pragma warning restore RS1012 private static void RunIfCSharpVersionOrGreater(this Compilation compilation, Action action, LanguageVersion greaterOrEqualThanLanguageVersion) => (compilation as CSharpCompilation)?.LanguageVersion.RunIfCSharpVersionGreater(action, greaterOrEqualThanLanguageVersion); + private static void RunIfCSharpVersionOrGreater(this SymbolAnalysisContext context, LanguageVersion greaterOrEqualThanLanguageVersion, Action action) => + context.Compilation.RunIfCSharpVersionOrGreater(action, greaterOrEqualThanLanguageVersion); private static void RunIfCSharpVersionGreater(this LanguageVersion languageVersion, Action action, LanguageVersion greaterOrEqualThanLanguageVersion) { diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs new file mode 100644 index 000000000..b9d16cc4a --- /dev/null +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs @@ -0,0 +1,77 @@ +using CodeCracker.Properties; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeCracker.CSharp.Refactoring +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public class ReplaceWithGetterOnlyAutoPropertyAnalyzer : DiagnosticAnalyzer + { + internal const string Category = SupportedCategories.Refactoring; + internal static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.ReplaceWithGetterOnlyAutoPropertyAnalyzer_Title), Resources.ResourceManager, typeof(Resources)); + internal static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.ReplaceWithGetterOnlyAutoPropertyAnalyzer_Description), Resources.ResourceManager, typeof(Resources)); + internal static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.ReplaceWithGetterOnlyAutoPropertyAnalyzer_MessageFormat), Resources.ResourceManager, typeof(Resources)); + + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( + DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Title, + MessageFormat, + Category, + DiagnosticSeverity.Hidden, + isEnabledByDefault: true, + description: Description, + helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.ReplaceWithGetterOnlyAutoProperty)); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + public override void Initialize(AnalysisContext context) + { + context.RegisterSymbolAction(LanguageVersion.CSharp6, AnalyzeSymbol, SymbolKind.Property); + } + + private static void AnalyzeSymbol(SymbolAnalysisContext context) + { + if (context.IsGenerated()) return; + var namedTypeSymbol = (IPropertySymbol)context.Symbol; + var properties = GetPropsWithOnlyGettersAndReadonlyBackingField(namedTypeSymbol, context); + if (properties == null) return; + var diagnostic = Diagnostic.Create(Rule, properties.Item1.Locations[0], properties.Item1.Name); + context.ReportDiagnostic(diagnostic); + } + private static Tuple GetPropsWithOnlyGettersAndReadonlyBackingField(IPropertySymbol propertySymbol, SymbolAnalysisContext context) + { + SemanticModel model = null; + if (!propertySymbol.IsReadOnly || propertySymbol.IsStatic || !propertySymbol.CanBeReferencedByName) return null; + var getMethod = propertySymbol.GetMethod; + if (getMethod == null) return null; + var reference = getMethod.DeclaringSyntaxReferences.FirstOrDefault(); + if (reference == null) return null; + var declaration = reference.GetSyntax(context.CancellationToken) as AccessorDeclarationSyntax; + if (declaration?.Body == null) return null; + var returnNode = declaration.Body.ChildNodes().FirstOrDefault(); + if (returnNode?.Kind() != SyntaxKind.ReturnStatement) return null; + var fieldNode = returnNode.ChildNodes().FirstOrDefault(); + if (fieldNode == null) return null; + if (fieldNode.Kind() == SyntaxKind.SimpleMemberAccessExpression) + fieldNode = (fieldNode as MemberAccessExpressionSyntax).Name; + if (fieldNode.Kind() != SyntaxKind.IdentifierName) return null; + model = model ?? context.Compilation.GetSemanticModel(fieldNode.SyntaxTree); + var symbolInfo = model.GetSymbolInfo(fieldNode).Symbol as IFieldSymbol; + if (symbolInfo != null && + symbolInfo.IsReadOnly && + (symbolInfo.DeclaredAccessibility == Accessibility.Private || symbolInfo.DeclaredAccessibility == Accessibility.NotApplicable) && + symbolInfo.ContainingType == propertySymbol.ContainingType && + symbolInfo.Type.Equals(propertySymbol.Type)) + + return new Tuple(propertySymbol, symbolInfo); + return null; + } + } +} diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs new file mode 100644 index 000000000..c67c076ed --- /dev/null +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs @@ -0,0 +1,140 @@ +using CodeCracker.Properties; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Text; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace CodeCracker.CSharp.Refactoring +{ + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(ReplaceWithGetterOnlyAutoPropertyCodeFixProvider)), Shared] + public class ReplaceWithGetterOnlyAutoPropertyCodeFixProvider : CodeFixProvider + { + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId()); + + public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + + public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) + { + var diagnostic = context.Diagnostics.First(); + var diagnosticSpan = diagnostic.Location.SourceSpan; + + context.RegisterCodeFix( + CodeAction.Create( + title: Resources.ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title, + createChangedDocument: c => ReplaceByGetterOnlyAutoPropertyAsync(context.Document, diagnosticSpan, c), + equivalenceKey: nameof(ReplaceWithGetterOnlyAutoPropertyCodeFixProvider)), + diagnostic); + return Task.FromResult(0); + } + private async static Task ReplaceByGetterOnlyAutoPropertyAsync(Document document, TextSpan propertyDeclarationSpan, CancellationToken cancellationToken) + { + var semanticModel = await document.GetSemanticModelAsync(cancellationToken); + var root = await document.GetSyntaxRootAsync(cancellationToken); + var token = root.FindToken(propertyDeclarationSpan.Start); + var property = token.Parent.AncestorsAndSelf().OfType().First(); + var fieldVariableDeclaratorSyntax = await GetFieldDeclarationSyntaxNodeAsync(property, cancellationToken, semanticModel); + if (fieldVariableDeclaratorSyntax == null) return document; + var fieldReferences = await GetFieldReferencesAsync(fieldVariableDeclaratorSyntax, cancellationToken, semanticModel); + var nodesToUpdate = fieldReferences.Cast().Union(Enumerable.Repeat(property, 1)).Union(Enumerable.Repeat(fieldVariableDeclaratorSyntax, 1)); + var newRoot = FixWithTrackNode(root, property, fieldVariableDeclaratorSyntax, nodesToUpdate); + var resultDocument = document.WithSyntaxRoot(newRoot); + return resultDocument; + } + + private static SyntaxNode FixWithTrackNode(SyntaxNode root, PropertyDeclarationSyntax property, VariableDeclaratorSyntax fieldVariableDeclaratorSyntax, IEnumerable nodesToUpdate) + { + var newRoot = root.TrackNodes(nodesToUpdate); + var fieldReferences = newRoot.GetCurrentNodes(nodesToUpdate.OfType()); + foreach (var identifier in fieldReferences) + { + var newIdentifier = SyntaxFactory.IdentifierName(property.Identifier.Text); + newIdentifier = newIdentifier.WithLeadingTrivia(identifier.GetLeadingTrivia()).WithTrailingTrivia(identifier.GetTrailingTrivia()).WithAdditionalAnnotations(Formatter.Annotation); + newRoot = newRoot.ReplaceNode(identifier, newIdentifier); + } + var prop = newRoot.GetCurrentNode(nodesToUpdate.OfType().Single()); + var fieldInitilization = GetFieldInitialization(fieldVariableDeclaratorSyntax); + var getter = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); + var accessorList = SyntaxFactory.AccessorList( + SyntaxFactory.List(new[] { + getter + })); + var newProp = prop.WithAccessorList(accessorList); + if (fieldInitilization != null) + newProp = newProp.WithInitializer(fieldInitilization).WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); + newProp = newProp.WithLeadingTrivia(prop.GetLeadingTrivia()).WithTrailingTrivia(prop.GetTrailingTrivia()).WithAdditionalAnnotations(Formatter.Annotation); + newRoot = newRoot.ReplaceNode(prop, newProp); + var variableDeclarator = newRoot.GetCurrentNode(nodesToUpdate.OfType().Single()); + var declaration = variableDeclarator.AncestorsAndSelf().OfType().First(); + if (declaration.Variables.Count == 1) + { + var fieldDeclaration = declaration.AncestorsAndSelf().OfType().First(); + newRoot = newRoot.RemoveNode(fieldDeclaration, SyntaxRemoveOptions.KeepUnbalancedDirectives); + } + else + newRoot = newRoot.RemoveNode(variableDeclarator, SyntaxRemoveOptions.KeepUnbalancedDirectives); + return newRoot; + } + + private static EqualsValueClauseSyntax GetFieldInitialization(VariableDeclaratorSyntax fieldVariableDeclaratorSyntax) + { + var declaration = fieldVariableDeclaratorSyntax.AncestorsAndSelf().OfType().First(); + if (declaration == null) + return null; + var variableWithPotentialInitializer = declaration.Variables.SkipWhile(v => v != fieldVariableDeclaratorSyntax).FirstOrDefault(v => v.Initializer != null); + if (variableWithPotentialInitializer == null) + return null; + var initializer = variableWithPotentialInitializer.Initializer; + return initializer; + } + + private static async Task> GetFieldReferencesAsync(VariableDeclaratorSyntax fieldDeclarationSyntax, CancellationToken cancellationToken, SemanticModel semanticModel) + { + HashSet fieldReferences = null; + var fieldSymbol = semanticModel.GetDeclaredSymbol(fieldDeclarationSyntax); + var declaredInType = fieldSymbol.ContainingType; + foreach (var reference in declaredInType.DeclaringSyntaxReferences) + { + var allNodesOfType = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); + var allFieldReferenceNodes = from n in allNodesOfType.OfType() + where n.Identifier.ValueText == fieldDeclarationSyntax.Identifier.ValueText + select n; + foreach (var fieldReference in allFieldReferenceNodes) + { + var parentExpression = fieldReference.Parent; + if (parentExpression is MemberAccessExpressionSyntax) + parentExpression = parentExpression.Parent; + if (parentExpression is AssignmentExpressionSyntax) + { + var assignmentEx = (AssignmentExpressionSyntax)parentExpression; + if (assignmentEx.Left == fieldReference || assignmentEx.Left == fieldReference.Parent) + (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); + } + } + } + return fieldReferences ?? Enumerable.Empty(); + } + + private static async Task GetFieldDeclarationSyntaxNodeAsync(PropertyDeclarationSyntax propertyDeclaration, CancellationToken cancellationToken, SemanticModel semanticModel) + { + var propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken); + var declaredProperty = propertySymbol.GetMethod.DeclaringSyntaxReferences.FirstOrDefault(); + var declaredPropertySyntax = await declaredProperty.GetSyntaxAsync(cancellationToken); + var fieldIdentifier = declaredPropertySyntax.DescendantNodesAndTokens().FirstOrDefault(n => n.IsNode && n.Kind() == SyntaxKind.IdentifierName); + var fieldInfo = semanticModel.GetSymbolInfo(fieldIdentifier.AsNode()); + var fieldDeclaration = fieldInfo.Symbol.DeclaringSyntaxReferences.FirstOrDefault(); + var fieldDeclarationSyntax = await fieldDeclaration.GetSyntaxAsync(); + return fieldDeclarationSyntax as VariableDeclaratorSyntax; + } + } +} diff --git a/src/Common/CodeCracker.Common/DiagnosticId.cs b/src/Common/CodeCracker.Common/DiagnosticId.cs index e60eb36f8..a0d12446a 100644 --- a/src/Common/CodeCracker.Common/DiagnosticId.cs +++ b/src/Common/CodeCracker.Common/DiagnosticId.cs @@ -83,5 +83,6 @@ public enum DiagnosticId UnnecessaryToStringInStringConcatenation = 118, SwitchCaseWithoutDefault = 120, ReadOnlyComplexTypes = 121, + ReplaceWithGetterOnlyAutoProperty=125, } } \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs b/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs index a9cc2ac5f..318839da0 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs +++ b/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// Dieser Code wurde von einem Tool generiert. +// Laufzeitversion:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn +// der Code erneut generiert wird. // //------------------------------------------------------------------------------ @@ -14,12 +14,12 @@ namespace CodeCracker.Properties { /// - /// A strongly-typed resource class, for looking up localized strings, etc. + /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. + // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert + // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. + // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen + // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -34,7 +34,7 @@ internal Resources() { } /// - /// Returns the cached ResourceManager instance used by this class. + /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { @@ -48,8 +48,8 @@ internal Resources() { } /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. + /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { @@ -62,7 +62,7 @@ internal Resources() { } /// - /// Looks up a localized string similar to String interpolation allows for better reading of the resulting string when compared to Console.WriteLine arguments. You should use Console.WriteLine with arguments only when another method is supplying the format string.. + /// Sucht eine lokalisierte Zeichenfolge, die String interpolation allows for better reading of the resulting string when compared to Console.WriteLine arguments. You should use Console.WriteLine with arguments only when another method is supplying the format string. ähnelt. /// public static string ConsoleWriteLineAnalyzer_Description { get { @@ -71,7 +71,7 @@ public static string ConsoleWriteLineAnalyzer_Description { } /// - /// Looks up a localized string similar to Use string interpolation. + /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation ähnelt. /// public static string ConsoleWriteLineAnalyzer_MessageFormat { get { @@ -80,7 +80,7 @@ public static string ConsoleWriteLineAnalyzer_MessageFormat { } /// - /// Looks up a localized string similar to Use string interpolation instead of arguments on Console.WriteLine. + /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation instead of arguments on Console.WriteLine ähnelt. /// public static string ConsoleWriteLineAnalyzer_Title { get { @@ -89,7 +89,7 @@ public static string ConsoleWriteLineAnalyzer_Title { } /// - /// Looks up a localized string similar to Change to string interpolation. + /// Sucht eine lokalisierte Zeichenfolge, die Change to string interpolation ähnelt. /// public static string ConsoleWriteLineCodeFixProvider_Title { get { @@ -98,7 +98,7 @@ public static string ConsoleWriteLineCodeFixProvider_Title { } /// - /// Looks up a localized string similar to An empty catch block suppress all errors and shouldn't be used.\r\nIf the error is expected consider logging it or changing the control flow such that it is explicit.. + /// Sucht eine lokalisierte Zeichenfolge, die An empty catch block suppress all errors and shouldn't be used.\r\nIf the error is expected consider logging it or changing the control flow such that it is explicit. ähnelt. /// public static string EmptyCatchBlockAnalyzer_Description { get { @@ -107,7 +107,7 @@ public static string EmptyCatchBlockAnalyzer_Description { } /// - /// Looks up a localized string similar to Empty Catch Block.. + /// Sucht eine lokalisierte Zeichenfolge, die Empty Catch Block. ähnelt. /// public static string EmptyCatchBlockAnalyzer_Message { get { @@ -116,7 +116,7 @@ public static string EmptyCatchBlockAnalyzer_Message { } /// - /// Looks up a localized string similar to Catch block cannot be empty. + /// Sucht eine lokalisierte Zeichenfolge, die Catch block cannot be empty ähnelt. /// public static string EmptyCatchBlockAnalyzer_Title { get { @@ -125,7 +125,7 @@ public static string EmptyCatchBlockAnalyzer_Title { } /// - /// Looks up a localized string similar to Insert Exception class to Catch. + /// Sucht eine lokalisierte Zeichenfolge, die Insert Exception class to Catch ähnelt. /// public static string EmptyCatchBlockCodeFixProvider_InsertException { get { @@ -134,7 +134,7 @@ public static string EmptyCatchBlockCodeFixProvider_InsertException { } /// - /// Looks up a localized string similar to Remove Empty Catch Block. + /// Sucht eine lokalisierte Zeichenfolge, die Remove Empty Catch Block ähnelt. /// public static string EmptyCatchBlockCodeFixProvider_Remove { get { @@ -143,7 +143,7 @@ public static string EmptyCatchBlockCodeFixProvider_Remove { } /// - /// Looks up a localized string similar to Remove Empty Catch Block and Put a Documentation Link about Try...Catch use. + /// Sucht eine lokalisierte Zeichenfolge, die Remove Empty Catch Block and Put a Documentation Link about Try...Catch use ähnelt. /// public static string EmptyCatchBlockCodeFixProvider_RemoveAndDocumentation { get { @@ -152,7 +152,7 @@ public static string EmptyCatchBlockCodeFixProvider_RemoveAndDocumentation { } /// - /// Looks up a localized string similar to Remove wrapping Try Block. + /// Sucht eine lokalisierte Zeichenfolge, die Remove wrapping Try Block ähnelt. /// public static string EmptyCatchBlockCodeFixProvider_RemoveTry { get { @@ -161,7 +161,7 @@ public static string EmptyCatchBlockCodeFixProvider_RemoveTry { } /// - /// Looks up a localized string similar to Change field type '{0}' accessibility to be as accessible as field '{1}'. + /// Sucht eine lokalisierte Zeichenfolge, die Change field type '{0}' accessibility to be as accessible as field '{1}' ähnelt. /// public static string InconsistentAccessibilityInFieldType_Title { get { @@ -170,7 +170,7 @@ public static string InconsistentAccessibilityInFieldType_Title { } /// - /// Looks up a localized string similar to Change parameter type '{0}' accessibility to be as accessible as indexer 'this[{1}]'. + /// Sucht eine lokalisierte Zeichenfolge, die Change parameter type '{0}' accessibility to be as accessible as indexer 'this[{1}]' ähnelt. /// public static string InconsistentAccessibilityInIndexerParameter_Title { get { @@ -179,7 +179,7 @@ public static string InconsistentAccessibilityInIndexerParameter_Title { } /// - /// Looks up a localized string similar to Change indexer return type '{0}' accessibility to be as accessible as indexer 'this[{1}]'. + /// Sucht eine lokalisierte Zeichenfolge, die Change indexer return type '{0}' accessibility to be as accessible as indexer 'this[{1}]' ähnelt. /// public static string InconsistentAccessibilityInIndexerReturnType_Title { get { @@ -188,7 +188,7 @@ public static string InconsistentAccessibilityInIndexerReturnType_Title { } /// - /// Looks up a localized string similar to Change parameter type '{0}' accessibility to be as accessible as method '{1}'. + /// Sucht eine lokalisierte Zeichenfolge, die Change parameter type '{0}' accessibility to be as accessible as method '{1}' ähnelt. /// public static string InconsistentAccessibilityInMethodParameter_Title { get { @@ -197,7 +197,7 @@ public static string InconsistentAccessibilityInMethodParameter_Title { } /// - /// Looks up a localized string similar to Change return type '{0}' accessibility to be as accessible as method '{1}'. + /// Sucht eine lokalisierte Zeichenfolge, die Change return type '{0}' accessibility to be as accessible as method '{1}' ähnelt. /// public static string InconsistentAccessibilityInMethodReturnType_Title { get { @@ -206,7 +206,7 @@ public static string InconsistentAccessibilityInMethodReturnType_Title { } /// - /// Looks up a localized string similar to Change property type '{0}' accessibility to be as accessible as property '{1}'. + /// Sucht eine lokalisierte Zeichenfolge, die Change property type '{0}' accessibility to be as accessible as property '{1}' ähnelt. /// public static string InconsistentAccessibilityInPropertyType_Title { get { @@ -215,7 +215,7 @@ public static string InconsistentAccessibilityInPropertyType_Title { } /// - /// Looks up a localized string similar to Make method non async. + /// Sucht eine lokalisierte Zeichenfolge, die Make method non async ähnelt. /// public static string MakeMethodNonAsyncCodeFixProvider_Title { get { @@ -224,7 +224,7 @@ public static string MakeMethodNonAsyncCodeFixProvider_Title { } /// - /// Looks up a localized string similar to In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produce code that is easier to refactor.. + /// Sucht eine lokalisierte Zeichenfolge, die In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produce code that is easier to refactor. ähnelt. /// public static string NameOfAnalyzer_Description { get { @@ -233,7 +233,7 @@ public static string NameOfAnalyzer_Description { } /// - /// Looks up a localized string similar to Use 'nameof({0})' instead of specifying the program element name.. + /// Sucht eine lokalisierte Zeichenfolge, die Use 'nameof({0})' instead of specifying the program element name. ähnelt. /// public static string NameOfAnalyzer_MessageFormat { get { @@ -242,7 +242,7 @@ public static string NameOfAnalyzer_MessageFormat { } /// - /// Looks up a localized string similar to Use nameof. + /// Sucht eine lokalisierte Zeichenfolge, die Use nameof ähnelt. /// public static string NameOfAnalyzer_Title { get { @@ -251,7 +251,7 @@ public static string NameOfAnalyzer_Title { } /// - /// Looks up a localized string similar to Use nameof(). + /// Sucht eine lokalisierte Zeichenfolge, die Use nameof() ähnelt. /// public static string NameOfCodeFixProvider_Title { get { @@ -260,7 +260,43 @@ public static string NameOfCodeFixProvider_Title { } /// - /// Looks up a localized string similar to String interpolation allows for better reading of the resulting string when compared to String.Format. You should use String.Format only when another method is supplying the format string.. + /// Sucht eine lokalisierte Zeichenfolge, die Getter only properties with backing read-only field can be converted to getter-only auto-properties. ähnelt. + /// + public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_Description { + get { + return ResourceManager.GetString("ReplaceWithGetterOnlyAutoPropertyAnalyzer_Description", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Property {0} can be converted to an getter-only auto-property. ähnelt. + /// + public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_MessageFormat { + get { + return ResourceManager.GetString("ReplaceWithGetterOnlyAutoPropertyAnalyzer_MessageFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Property can be simplified by using an getter-only auto-property. ähnelt. + /// + public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_Title { + get { + return ResourceManager.GetString("ReplaceWithGetterOnlyAutoPropertyAnalyzer_Title", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Simplify by using an getter-only auto-property ähnelt. + /// + public static string ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title { + get { + return ResourceManager.GetString("ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die String interpolation allows for better reading of the resulting string when compared to String.Format. You should use String.Format only when another method is supplying the format string. ähnelt. /// public static string StringFormatAnalyzer_Description { get { @@ -269,7 +305,7 @@ public static string StringFormatAnalyzer_Description { } /// - /// Looks up a localized string similar to Use string interpolation. + /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation ähnelt. /// public static string StringFormatAnalyzer_MessageFormat { get { @@ -278,7 +314,7 @@ public static string StringFormatAnalyzer_MessageFormat { } /// - /// Looks up a localized string similar to Use string interpolation instead of String.Format. + /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation instead of String.Format ähnelt. /// public static string StringFormatAnalyzer_Title { get { @@ -287,7 +323,7 @@ public static string StringFormatAnalyzer_Title { } /// - /// Looks up a localized string similar to Change to string interpolation. + /// Sucht eine lokalisierte Zeichenfolge, die Change to string interpolation ähnelt. /// public static string StringFormatCodeFixProvider_Title { get { @@ -296,7 +332,7 @@ public static string StringFormatCodeFixProvider_Title { } /// - /// Looks up a localized string similar to Auto properties offer a more concise way of defining a property. If you are using simple getters and setters you are able to simplify your code with autoproperties.. + /// Sucht eine lokalisierte Zeichenfolge, die Auto properties offer a more concise way of defining a property. If you are using simple getters and setters you are able to simplify your code with autoproperties. ähnelt. /// public static string SwitchToAutoPropAnalyzer_Description { get { @@ -305,7 +341,7 @@ public static string SwitchToAutoPropAnalyzer_Description { } /// - /// Looks up a localized string similar to Change {0} to an auto property. + /// Sucht eine lokalisierte Zeichenfolge, die Change {0} to an auto property ähnelt. /// public static string SwitchToAutoPropAnalyzer_MessageFormat { get { @@ -314,7 +350,7 @@ public static string SwitchToAutoPropAnalyzer_MessageFormat { } /// - /// Looks up a localized string similar to Use auto property. + /// Sucht eine lokalisierte Zeichenfolge, die Use auto property ähnelt. /// public static string SwitchToAutoPropAnalyzer_Title { get { @@ -323,7 +359,7 @@ public static string SwitchToAutoPropAnalyzer_Title { } /// - /// Looks up a localized string similar to Change to auto property. + /// Sucht eine lokalisierte Zeichenfolge, die Change to auto property ähnelt. /// public static string SwitchToAutoPropCodeFixProvider_Title { get { @@ -332,7 +368,7 @@ public static string SwitchToAutoPropCodeFixProvider_Title { } /// - /// Looks up a localized string similar to You have missing/unexistent parameters in Xml Docs. + /// Sucht eine lokalisierte Zeichenfolge, die You have missing/unexistent parameters in Xml Docs ähnelt. /// public static string XmlDocumentationAnalyzer_Title { get { @@ -341,7 +377,7 @@ public static string XmlDocumentationAnalyzer_Title { } /// - /// Looks up a localized string similar to Create missing parameters in xml docs. + /// Sucht eine lokalisierte Zeichenfolge, die Create missing parameters in xml docs ähnelt. /// public static string XmlDocumentationCreateMissingParametersCodeFixProvider_Title { get { @@ -350,7 +386,7 @@ public static string XmlDocumentationCreateMissingParametersCodeFixProvider_Titl } /// - /// Looks up a localized string similar to Remove unexistent parameters in xml docs. + /// Sucht eine lokalisierte Zeichenfolge, die Remove unexistent parameters in xml docs ähnelt. /// public static string XmlDocumentationRemoveNonExistentParametersCodeFixProvider_Title { get { diff --git a/src/Common/CodeCracker.Common/Properties/Resources.resx b/src/Common/CodeCracker.Common/Properties/Resources.resx index 1b6e5d917..accb497bd 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.resx +++ b/src/Common/CodeCracker.Common/Properties/Resources.resx @@ -216,4 +216,16 @@ Remove wrapping Try Block + + Getter only properties with backing read-only field can be converted to getter-only auto-properties. + + + Property {0} can be converted to an getter-only auto-property. + + + Property can be simplified by using an getter-only auto-property. + + + Simplify by using an getter-only auto-property + \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 1b62b386c..4198a1676 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -135,6 +135,7 @@ + diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs new file mode 100644 index 000000000..ec2ad725b --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs @@ -0,0 +1,325 @@ +using CodeCracker.CSharp.Refactoring; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CodeCracker.Test.CSharp.Refactoring +{ + public class ReplaceWithGetterOnlyAutoPropertyTests : CodeFixVerifier + { + private static string GetDiagnosticMessage(string propertyName) => $"Property {propertyName} can be converted to an getter-only auto-property."; + + [Fact] + public async Task EmptyCodeBlockPassesWithoutErrors() + { + const string test = @""; + await VerifyCSharpHasNoDiagnosticsAsync(test); + } + + [Fact] + public async Task SimplePropertyGetsTransformed() + { + var test = @" + readonly string _value; + + TypeName(string value) + { + _value=value; + } + + public string Value { get { return _value; } } + ".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = "CC0125", + Message = GetDiagnosticMessage("Value"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 16, 27) + } + }; + + await VerifyCSharpDiagnosticAsync(test, expected); + + var fixtest = @" + TypeName(string value) + { + Value = value; + } + + public string Value { get; } + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task SimplePropertyGetsNotTransformedIfLessThanCSharp6() + { + var test = @" + readonly string _value; + + TypeName(string value) + { + _value=value; + } + + public string Value { get { return _value; } } + ".WrapInCSharpClass(); + await VerifyCSharpHasNoDiagnosticsAsync(test, LanguageVersion.CSharp5); + } + + [Fact] + public async Task FieldInitializerIsPreserved() + { + var test = @" + readonly string value, value2 = ""InitValue""; + + TypeName(string value) + { + this.value=value; + } + + public string Value { get { return this.value; } } + ".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("Value"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 16, 27) + } + }; + + await VerifyCSharpDiagnosticAsync(test, expected); + + var fixtest = @" + readonly string value2 = ""InitValue""; + + TypeName(string value) + { + this.Value = value; + } + + public string Value { get; } = ""InitValue""; + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task MultiplePropertiesPerClassGetTranformed() + { + var test = @" + readonly string value, value2=""InitValue""; + + TypeName(string value) + { + this.value=value; + this.value2=value; + } + + public string Value { get { return this.value; } } + public string Value2 { get { return this.value2; } } + ".WrapInCSharpClass(); + + var expected1 = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("Value"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 17, 27) + } + }; + var expected2 = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("Value2"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 18, 27) + } + }; + + await VerifyCSharpDiagnosticAsync(test, new DiagnosticResult[] { expected1, expected2 }); + + var fixtest = @" + TypeName(string value) + { + this.Value = value; + this.Value2 = value; + } + + public string Value { get; } = ""InitValue""; + public string Value2 { get; } = ""InitValue""; + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task MultiplePropertiesPerClassWithFieldInitilizerAndUnusedFieldsGetTranformed() + { + var test = @" + readonly string value, value2, value3=""InitValue""; + + TypeName(string value) + { + this.value=value; + this.value2=value; + } + + public string Value { get { return this.value; } } + public string Value2 { get { return this.value2; } } + ".WrapInCSharpClass(); + var expected1 = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("Value"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 17, 27) + } + }; + var expected2 = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("Value2"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 18, 27) + } + }; + + await VerifyCSharpDiagnosticAsync(test, new DiagnosticResult[] { expected1, expected2 }); + + var fixtest = @" + readonly string value3=""InitValue""; + + TypeName(string value) + { + this.Value = value; + this.Value2 = value; + } + + public string Value { get; } = ""InitValue""; + public string Value2 { get; } = ""InitValue""; + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task TypeOfPropertyMustFitTypeOfBackingField() + { + var test = @" + readonly IList value, value2; + + TypeName(IEnumerable value) + { + this.value=value.ToList(); + this.value2=value.ToList(); + } + + public IEnumerable Value { get { return this.value; } } + public IList Value2 { get { return this.value2; } } + ".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("Value2"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 18, 34) + } + }; + + await VerifyCSharpDiagnosticAsync(test, expected); + + var fixtest = @" + readonly IList value; + + TypeName(IEnumerable value) + { + this.value=value.ToList(); + this.Value2 = value.ToList(); + } + + public IEnumerable Value { get { return this.value; } } + public IList Value2 { get; } + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task ExplicitPropertyImplementationsAreIgnored() + { + const string test = @" + namespace ConsoleApplication1 + { + interface ITestInterface + { + string Property { get; } + } + class TestClass2: ITestInterface + { + readonly string _Property; + + string ITestInterface.Property + { + get + { + return _Property; + } + } + } + }"; + await VerifyCSharpHasNoDiagnosticsAsync(test); + } + + [Fact] + public async Task SeveralInitializerAreAssignedProperly() + { + var test = @" + readonly int a = 0, x, y = 1, z = 2; + + public int X + { + get + { + return x; + } + } + ".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), + Message = GetDiagnosticMessage("X"), + Severity = DiagnosticSeverity.Hidden, + Locations = + new[] { + new DiagnosticResultLocation("Test0.cs", 11, 24) + } + }; + + await VerifyCSharpDiagnosticAsync(test, expected); + + var fixtest = @" + readonly int a = 0, y = 1, z = 2; + + public int X { get; } = 1; + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + } +} From 07c9a00e0810a522d9d1ff43f4ea92fc7fbb8a1a Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 22 Mar 2017 10:13:13 +0100 Subject: [PATCH 061/152] Changed Renaming logic and added some renaming tests. --- ...thGetterOnlyAutoPropertyCodeFixProvider.cs | 30 +-- .../ReplaceWithGetterOnlyAutoPropertyTests.cs | 219 ++++++++++++++++-- 2 files changed, 215 insertions(+), 34 deletions(-) diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs index c67c076ed..5503dbe8f 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs @@ -34,7 +34,7 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) title: Resources.ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title, createChangedDocument: c => ReplaceByGetterOnlyAutoPropertyAsync(context.Document, diagnosticSpan, c), equivalenceKey: nameof(ReplaceWithGetterOnlyAutoPropertyCodeFixProvider)), - diagnostic); + diagnostic); return Task.FromResult(0); } private async static Task ReplaceByGetterOnlyAutoPropertyAsync(Document document, TextSpan propertyDeclarationSpan, CancellationToken cancellationToken) @@ -55,12 +55,13 @@ private async static Task ReplaceByGetterOnlyAutoPropertyAsync(Documen private static SyntaxNode FixWithTrackNode(SyntaxNode root, PropertyDeclarationSyntax property, VariableDeclaratorSyntax fieldVariableDeclaratorSyntax, IEnumerable nodesToUpdate) { var newRoot = root.TrackNodes(nodesToUpdate); - var fieldReferences = newRoot.GetCurrentNodes(nodesToUpdate.OfType()); + var fieldReferences = nodesToUpdate.OfType(); foreach (var identifier in fieldReferences) { - var newIdentifier = SyntaxFactory.IdentifierName(property.Identifier.Text); - newIdentifier = newIdentifier.WithLeadingTrivia(identifier.GetLeadingTrivia()).WithTrailingTrivia(identifier.GetTrailingTrivia()).WithAdditionalAnnotations(Formatter.Annotation); - newRoot = newRoot.ReplaceNode(identifier, newIdentifier); + var trackedIdentifierNode = newRoot.GetCurrentNode(identifier); + var newIdentifierExpression = SyntaxFactory.IdentifierName(property.Identifier.Text); + newIdentifierExpression = newIdentifierExpression.WithLeadingTrivia(trackedIdentifierNode.GetLeadingTrivia()).WithTrailingTrivia(trackedIdentifierNode.GetTrailingTrivia()).WithAdditionalAnnotations(Formatter.Annotation); + newRoot = newRoot.ReplaceNode(trackedIdentifierNode, newIdentifierExpression); } var prop = newRoot.GetCurrentNode(nodesToUpdate.OfType().Single()); var fieldInitilization = GetFieldInitialization(fieldVariableDeclaratorSyntax); @@ -101,25 +102,18 @@ private static EqualsValueClauseSyntax GetFieldInitialization(VariableDeclarator private static async Task> GetFieldReferencesAsync(VariableDeclaratorSyntax fieldDeclarationSyntax, CancellationToken cancellationToken, SemanticModel semanticModel) { HashSet fieldReferences = null; - var fieldSymbol = semanticModel.GetDeclaredSymbol(fieldDeclarationSyntax); + var fieldSymbol = semanticModel.GetDeclaredSymbol(fieldDeclarationSyntax, cancellationToken); var declaredInType = fieldSymbol.ContainingType; foreach (var reference in declaredInType.DeclaringSyntaxReferences) { - var allNodesOfType = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); - var allFieldReferenceNodes = from n in allNodesOfType.OfType() - where n.Identifier.ValueText == fieldDeclarationSyntax.Identifier.ValueText + var allNodes = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); + var allFieldReferenceNodes = from n in allNodes.OfType() + let nodeSymbolInfo = semanticModel.GetSymbolInfo(n, cancellationToken) + where object.Equals(nodeSymbolInfo.Symbol, fieldSymbol) select n; foreach (var fieldReference in allFieldReferenceNodes) { - var parentExpression = fieldReference.Parent; - if (parentExpression is MemberAccessExpressionSyntax) - parentExpression = parentExpression.Parent; - if (parentExpression is AssignmentExpressionSyntax) - { - var assignmentEx = (AssignmentExpressionSyntax)parentExpression; - if (assignmentEx.Left == fieldReference || assignmentEx.Left == fieldReference.Parent) - (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); - } + (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); } } return fieldReferences ?? Enumerable.Empty(); diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs index ec2ad725b..825a083e0 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs @@ -1,10 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Xunit; @@ -301,25 +297,216 @@ public int X } } ".WrapInCSharpClass(); - var expected = new DiagnosticResult + var fixtest = @" + readonly int a = 0, y = 1, z = 2; + + public int X { get; } = 1; + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task FieldNameIsRenamedInClass() + { + var test = @" + readonly int _X; + + public TypeName(int x) { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("X"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 11, 24) - } - }; + _X=x; + _X=_X*2; + Console.Write(_X); + } - await VerifyCSharpDiagnosticAsync(test, expected); + protected void M() => Console.Write(_X); + public int X + { + get + { + return _X; + } + } + ".WrapInCSharpClass(); var fixtest = @" - readonly int a = 0, y = 1, z = 2; + public TypeName(int x) + { + X=x; + X=X*2; + Console.Write(X); + } - public int X { get; } = 1; + protected void M() => Console.Write(X); + + public int X { get; } + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task ShadowedFieldNameIsNotRenamedInClass() + { + var test = @" + readonly int _X; + + public TypeName(int x) + { + _X=x; + } + + protected void M() + { + string _X=""; + Console.Write(_X); + } + + public int X + { + get + { + return _X; + } + } + ".WrapInCSharpClass(); + var fixtest = @" + public TypeName(int x) + { + X=x; + } + + protected void M() + { + string _X=""; + Console.Write(_X); + } + + public int X { get; } + ".WrapInCSharpClass(); + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task FieldAccessInInnerClassIsRenamed() + { + var test = @" + readonly int _A; + + public TypeName(int a) + { + _A=a; + } + + class InnerClass { + InnerClass(TypeName outterObject) + { + Console.Write(outterObject._A); + } + } + public int A + { + get + { + return _A; + } + } + ".WrapInCSharpClass(); + var fixtest = @" + public TypeName(int a) + { + A=a; + } + + class InnerClass { + InnerClass(TypeName outterObject) + { + Console.Write(outterObject.A); + } + } + public int A { get; } ".WrapInCSharpClass(); await VerifyCSharpFixAsync(test, fixtest); } + + [Fact] + public async Task FieldWithSameNameInOtherClassIsNotRenamed() + { + var test = @" + using System; + namespace App { + public class C1 + { + readonly int _A; + + public C1(int a) + { + _A=a; + } + + public int A + { + get + { + return _A; + } + } + } + public class C2 + { + readonly int _A; + } + }"; + var fixtest = @" + using System; + namespace App { + public class C1 + { + + public C1(int a) + { + A=a; + } + + public int A { get; } + } + public class C2 + { + readonly int _A; + } + }"; + await VerifyCSharpFixAsync(test, fixtest); + } + + [Fact] + public async Task RenamingOfFieldAccessCanIntroduceNameClashesCaughtByCompilerWarningCS1717() + { + var test = @" + readonly int _A; + + public TypeName(int A) + { + _A=A; + } + + public int A + { + get + { + return _A; + } + } + ".WrapInCSharpClass(); + var fixtest = @" + public TypeName(int A) + { + A=A; + } + + public int A { get; } + ".WrapInCSharpClass(); + // "A=A;" causes new compiler warning CS1717: Assignment made to same variable; did you mean to assign something else? + // The fix would be to transform the expression to this.A=A; + // Maybe using Microsoft.CodeAnalysis.Rename.Renamer.RenameSymbolAsync() for the renaming is the able to fix this. + await VerifyCSharpFixAsync(oldSource: test, newSource: fixtest, allowNewCompilerDiagnostics: true); + } } } From c1bdfbda9fd4578b4b2613a4fd5269a7e74d4eb0 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 22 Mar 2017 10:57:30 +0100 Subject: [PATCH 062/152] Prepare Pull Request: Reverted some VS2015 compatibility changes. --- src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj index 7dde1ebf3..12f744c47 100644 --- a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj +++ b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj @@ -1,13 +1,14 @@  - + - 14.0 + 15.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + 15.0 From 5c4007b3ce70e48cd3df2f1d7b219624d58de410 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 22 Mar 2017 11:00:01 +0100 Subject: [PATCH 063/152] Cleanup before PullRequest --- .../Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs | 3 --- .../ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs | 2 -- src/Common/CodeCracker.Common/DiagnosticId.cs | 2 +- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs index b9d16cc4a..59291bf23 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs @@ -4,11 +4,8 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using System; -using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace CodeCracker.CSharp.Refactoring { diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs index 5503dbe8f..e467153ed 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs @@ -6,12 +6,10 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Text; -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Linq; -using System.Text; using System.Threading; using System.Threading.Tasks; diff --git a/src/Common/CodeCracker.Common/DiagnosticId.cs b/src/Common/CodeCracker.Common/DiagnosticId.cs index a0d12446a..28feee0f8 100644 --- a/src/Common/CodeCracker.Common/DiagnosticId.cs +++ b/src/Common/CodeCracker.Common/DiagnosticId.cs @@ -83,6 +83,6 @@ public enum DiagnosticId UnnecessaryToStringInStringConcatenation = 118, SwitchCaseWithoutDefault = 120, ReadOnlyComplexTypes = 121, - ReplaceWithGetterOnlyAutoProperty=125, + ReplaceWithGetterOnlyAutoProperty = 125, } } \ No newline at end of file From b4d2856fc88dd38366f1ad41311f11890d08f7ed Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 22 Mar 2017 11:07:20 +0100 Subject: [PATCH 064/152] Clean up of analyzer. --- .../ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs index 59291bf23..cc8b4ef13 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyAnalyzer.cs @@ -28,6 +28,7 @@ public class ReplaceWithGetterOnlyAutoPropertyAnalyzer : DiagnosticAnalyzer helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.ReplaceWithGetterOnlyAutoProperty)); public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + public override void Initialize(AnalysisContext context) { context.RegisterSymbolAction(LanguageVersion.CSharp6, AnalyzeSymbol, SymbolKind.Property); @@ -39,12 +40,11 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context) var namedTypeSymbol = (IPropertySymbol)context.Symbol; var properties = GetPropsWithOnlyGettersAndReadonlyBackingField(namedTypeSymbol, context); if (properties == null) return; - var diagnostic = Diagnostic.Create(Rule, properties.Item1.Locations[0], properties.Item1.Name); + var diagnostic = Diagnostic.Create(Rule, properties.Locations[0], properties.Name); context.ReportDiagnostic(diagnostic); } - private static Tuple GetPropsWithOnlyGettersAndReadonlyBackingField(IPropertySymbol propertySymbol, SymbolAnalysisContext context) + private static ISymbol GetPropsWithOnlyGettersAndReadonlyBackingField(IPropertySymbol propertySymbol, SymbolAnalysisContext context) { - SemanticModel model = null; if (!propertySymbol.IsReadOnly || propertySymbol.IsStatic || !propertySymbol.CanBeReferencedByName) return null; var getMethod = propertySymbol.GetMethod; if (getMethod == null) return null; @@ -59,7 +59,7 @@ private static Tuple GetPropsWithOnlyGettersAndReadonlyBa if (fieldNode.Kind() == SyntaxKind.SimpleMemberAccessExpression) fieldNode = (fieldNode as MemberAccessExpressionSyntax).Name; if (fieldNode.Kind() != SyntaxKind.IdentifierName) return null; - model = model ?? context.Compilation.GetSemanticModel(fieldNode.SyntaxTree); + var model = context.Compilation.GetSemanticModel(fieldNode.SyntaxTree); var symbolInfo = model.GetSymbolInfo(fieldNode).Symbol as IFieldSymbol; if (symbolInfo != null && symbolInfo.IsReadOnly && @@ -67,7 +67,7 @@ private static Tuple GetPropsWithOnlyGettersAndReadonlyBa symbolInfo.ContainingType == propertySymbol.ContainingType && symbolInfo.Type.Equals(propertySymbol.Type)) - return new Tuple(propertySymbol, symbolInfo); + return propertySymbol; return null; } } From fa20c951cf11e561a64c1d141a8a95614f53f7ca Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Mon, 27 Mar 2017 13:58:44 +0200 Subject: [PATCH 065/152] Bugfix: semanticModel.GetSymbolInfo might raise ArgumentException (Node not found in tree) for certain symbols. --- .../ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs index e467153ed..80db718c6 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs @@ -106,6 +106,7 @@ private static async Task> GetFieldReferencesA { var allNodes = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); var allFieldReferenceNodes = from n in allNodes.OfType() + where n.Identifier.Text == fieldSymbol.Name let nodeSymbolInfo = semanticModel.GetSymbolInfo(n, cancellationToken) where object.Equals(nodeSymbolInfo.Symbol, fieldSymbol) select n; From 308f450277867ad479105b1b7b2c8bb4f2589c90 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 29 Mar 2017 13:52:12 +0200 Subject: [PATCH 066/152] Bugfix: Partial classes in different documents cause ArgumentException. --- ...thGetterOnlyAutoPropertyCodeFixProvider.cs | 20 ++-- .../ReplaceWithGetterOnlyAutoPropertyTests.cs | 94 ++++++++++++++++++- 2 files changed, 102 insertions(+), 12 deletions(-) diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs index 80db718c6..d22626bae 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs @@ -102,18 +102,16 @@ private static async Task> GetFieldReferencesA HashSet fieldReferences = null; var fieldSymbol = semanticModel.GetDeclaredSymbol(fieldDeclarationSyntax, cancellationToken); var declaredInType = fieldSymbol.ContainingType; - foreach (var reference in declaredInType.DeclaringSyntaxReferences) + var reference = declaredInType.DeclaringSyntaxReferences[0]; + var allNodes = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); + var allFieldReferenceNodes = from n in allNodes.OfType() + where n.Identifier.Text == fieldSymbol.Name + let nodeSymbolInfo = semanticModel.GetSymbolInfo(n, cancellationToken) + where object.Equals(nodeSymbolInfo.Symbol, fieldSymbol) + select n; + foreach (var fieldReference in allFieldReferenceNodes) { - var allNodes = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); - var allFieldReferenceNodes = from n in allNodes.OfType() - where n.Identifier.Text == fieldSymbol.Name - let nodeSymbolInfo = semanticModel.GetSymbolInfo(n, cancellationToken) - where object.Equals(nodeSymbolInfo.Symbol, fieldSymbol) - select n; - foreach (var fieldReference in allFieldReferenceNodes) - { - (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); - } + (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); } return fieldReferences ?? Enumerable.Empty(); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs index 825a083e0..d7ffc711d 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs @@ -508,5 +508,97 @@ public TypeName(int A) // Maybe using Microsoft.CodeAnalysis.Rename.Renamer.RenameSymbolAsync() for the renaming is the able to fix this. await VerifyCSharpFixAsync(oldSource: test, newSource: fixtest, allowNewCompilerDiagnostics: true); } + + [Fact] + public async Task FieldReferencesInPartialClassesGetNotRenamedAndCasueCompilerErrorCS0103() + { + const string test = @" + namespace A + { + using System; + public partial class A1 + { + readonly int _I; + public A1(int i) + { + _I = i; + } + public int I { get { return _I; } } + } + public partial class A1 + { + public void Print() => Console.Write(_I); + } + }"; + const string fixtest = @" + namespace A + { + using System; + public partial class A1 + { + public A1(int i) + { + I = i; + } + public int I { get; } + } + public partial class A1 + { + public void Print() => Console.Write(_I); + } + }"; + //Console.Write(_I); causes CS0103 The name '_I' does not exist in the current context + await VerifyCSharpFixAsync(oldSource: test, newSource: fixtest, allowNewCompilerDiagnostics: true); + } + + [Fact] + public async Task FieldReferencesInPartialClassesInDifferentDocumentsGetNotRenamedAndCauseCompilerErrorCS0103() + { + const string testPart1 = @" + namespace A + { + public partial class A1 + { + readonly int _I; + public A1(int i) + { + _I = i; + } + public int I { get { return _I; } } + } + }"; + const string testPart2 = @" + namespace A + { + using System; + public partial class A1 + { + public void Print() => Console.Write(_I); + } + }"; + const string fixtestPart1 = @" + namespace A + { + public partial class A1 + { + public A1(int i) + { + I = i; + } + public int I { get; } + } + }"; + const string fixtestPart2 = @" + namespace A + { + using System; + public partial class A1 + { + public void Print() => Console.Write(_I); + } + }"; + //Console.Write(_I); causes CS0103 The name '_I' does not exist in the current context + await VerifyCSharpFixAllAsync(oldSources: new string[] { testPart1, testPart2 }, newSources: new string[] { fixtestPart1, fixtestPart2 }, allowNewCompilerDiagnostics: true); + } } -} +} \ No newline at end of file From e6d44e596af62dcb89fa1b6fe10b2162e14b8b37 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 27 Apr 2017 15:54:10 +0200 Subject: [PATCH 067/152] Added CoalesceExpression to the list of possible parents in topSyntaxNode discovery. --- .../DisposableVariableNotDisposedAnalyzer.cs | 2 +- .../DisposableVariableNotDisposedTests.cs | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs index 2a4b4c32f..3ed958b5f 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs @@ -40,7 +40,7 @@ private static void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context) var originalNode = objectCreation; SyntaxNode topSyntaxNode = originalNode; - while (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ParenthesizedExpression, SyntaxKind.ConditionalExpression, SyntaxKind.CastExpression)) + while (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ParenthesizedExpression, SyntaxKind.ConditionalExpression, SyntaxKind.CastExpression, SyntaxKind.CoalesceExpression)) topSyntaxNode = topSyntaxNode.Parent; if (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ReturnStatement, SyntaxKind.UsingStatement, SyntaxKind.YieldReturnStatement)) diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index d1ad9d3e9..e2f2a9fd9 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -1577,5 +1577,26 @@ void Bar() }"; await VerifyCSharpHasNoDiagnosticsAsync(source); } + + [Fact] + public async Task IgnoreWhenAssignedToFieldByNullCoalescingOperator() + { + const string source = @" +using System.IO; +public class Test : IDisposable +{ + private IDisposable _stream; + + public void Update() + { + _stream = _stream ?? new MemoryStream(); + } + + public void Dispose() + { + _stream.Dispose(); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); } -} \ No newline at end of file +}} \ No newline at end of file From e74608cf2fd991ac3b353fb0d44671dd37e1e596 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 27 Apr 2017 16:12:09 +0200 Subject: [PATCH 068/152] Code formating. --- .../Usage/DisposableVariableNotDisposedTests.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index e2f2a9fd9..cb1437596 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -1578,10 +1578,10 @@ void Bar() await VerifyCSharpHasNoDiagnosticsAsync(source); } - [Fact] - public async Task IgnoreWhenAssignedToFieldByNullCoalescingOperator() - { - const string source = @" + [Fact] + public async Task IgnoreWhenAssignedToFieldByNullCoalescingOperator() + { + const string source = @" using System.IO; public class Test : IDisposable { @@ -1597,6 +1597,7 @@ public void Dispose() _stream.Dispose(); } }"; - await VerifyCSharpHasNoDiagnosticsAsync(source); + await VerifyCSharpHasNoDiagnosticsAsync(source); + } } -}} \ No newline at end of file +} \ No newline at end of file From 41aa788fc2752e83318edc600ccc73f11dadf37f Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 27 Apr 2017 18:05:34 +0200 Subject: [PATCH 069/152] Added support for Winforms property default value definition methods. --- .../RemovePrivateMethodNeverUsedAnalyzer.cs | 35 +++++++++ ...emovePrivateMethodNeverUsedAnalyzerTest.cs | 76 +++++++++++++++++++ 2 files changed, 111 insertions(+) diff --git a/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs index 25bd20246..26b80458c 100644 --- a/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/RemovePrivateMethodNeverUsedAnalyzer.cs @@ -44,6 +44,7 @@ private static void AnalyzeNode(SyntaxNodeAnalysisContext context) if (IsMethodUsed(methodDeclaration, context.SemanticModel)) return; if (IsMainMethodEntryPoint(methodDeclaration, context.SemanticModel)) return; if (methodDeclaration.Modifiers.Any(SyntaxKind.ExternKeyword)) return; + if (IsWinformsPropertyDefaultValueDefinitionMethod(methodDeclaration, context.SemanticModel)) return; var props = new Dictionary { { "identifier", methodDeclaration.Identifier.Text } }.ToImmutableDictionary(); var diagnostic = Diagnostic.Create(Rule, methodDeclaration.GetLocation(), props); context.ReportDiagnostic(diagnostic); @@ -125,5 +126,39 @@ private static bool IsMainMethodEntryPoint(MethodDeclarationSyntax methodTarget, if (!parameterType.OriginalDefinition.ToString().Equals("String[]", StringComparison.OrdinalIgnoreCase)) return false; return true; } + + // see https://msdn.microsoft.com/en-us/library/53b8022e(v=vs.110).aspx + private static bool IsWinformsPropertyDefaultValueDefinitionMethod(MethodDeclarationSyntax methodTarget, SemanticModel semanticModel) + { + var propertyName = GetPropertyNameForWinformDefaultValueMethods(methodTarget, semanticModel); + if (string.IsNullOrWhiteSpace(propertyName)) return false; + if (!ExistsProperty(propertyName, methodTarget, semanticModel)) return false; + return true; + } + + private static string GetPropertyNameForWinformDefaultValueMethods(MethodDeclarationSyntax methodTarget, SemanticModel semanticModel) => + GetPropertyNameForMethodWithSignature(methodTarget, semanticModel, "Reset", "Void") ?? + GetPropertyNameForMethodWithSignature(methodTarget, semanticModel, "ShouldSerialize", "Boolean"); + + private static string GetPropertyNameForMethodWithSignature(MethodDeclarationSyntax methodTarget, SemanticModel semanticModel, string startsWith, string returnType) + { + var methodName = methodTarget.Identifier.Text; + if (methodName.StartsWith(startsWith)) + if (methodTarget.ParameterList.Parameters.Count == 0) + { + var returnTypeInfo = semanticModel.GetTypeInfo(methodTarget.ReturnType).Type; + if (returnTypeInfo.Name.Equals(returnType, StringComparison.OrdinalIgnoreCase)) + return methodName.Substring(startsWith.Length); ; + } + return null; + } + + private static bool ExistsProperty(string propertyName, SyntaxNode nodeInType, SemanticModel semanticModel) + { + var typeDeclaration = nodeInType.AncestorsAndSelf().OfType().FirstOrDefault(); + if (typeDeclaration == null) return false; + var propertyDeclarations = typeDeclaration.DescendantNodes().OfType(); + return propertyDeclarations.Any(pd => pd.Identifier.Text == propertyName); + } } } diff --git a/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs b/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs index abc0c6e97..3c5383c1e 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs @@ -1,4 +1,5 @@ using CodeCracker.CSharp.Usage; +using Microsoft.CodeAnalysis; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -408,5 +409,80 @@ bool System.IEquatable.Equals(Foo other) }"; await VerifyCSharpHasNoDiagnosticsAsync(source); } + + // see https://msdn.microsoft.com/en-us/library/53b8022e(v=vs.110).aspx + [Fact] + public async void WinFormsPropertyDefaultValueDefinitionMethodsShouldBeIgnored() + { + var source = @" +public int PropertyXXX { + get; + set; +} + +private bool ShouldSerializePropertyXXX() => true; + +private void ResetPropertyXXX() { }; +".WrapInCSharpClass(); + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + private static DiagnosticResult CreateDiagnosticResult(int line, int column) => + new DiagnosticResult + { + Id = DiagnosticId.RemovePrivateMethodNeverUsed.ToDiagnosticId(), + Locations = new DiagnosticResultLocation[] { new DiagnosticResultLocation("Test0.cs", line, column) }, + Message = RemovePrivateMethodNeverUsedAnalyzer.Message, + Severity = DiagnosticSeverity.Info, + }; + + [Fact] + public async void WinFormsPropertyDefaultValueDefinitionMethodsMustHaveCorrectSignature() + { + var source = @" +public int Property1 { get; set; } +public int Property2 { get; set; } +public int Property3 { get; set; } + +private int ShouldSerializeProperty1() => 1; +private bool ShouldSerializeProperty2(int i) => true; +private void ShouldSerializeProperty3() { }; + +private bool ResetProperty1() => true; +private void ResetProperty2(int i) { }; +".WrapInCSharpClass(); + var result1 = CreateDiagnosticResult(13, 1); + var result2 = CreateDiagnosticResult(14, 1); + var result3 = CreateDiagnosticResult(15, 1); + var result4 = CreateDiagnosticResult(17, 1); + var result5 = CreateDiagnosticResult(18, 1); + await VerifyCSharpDiagnosticAsync(source, new DiagnosticResult[] { result1, result2, result3, result4, result5 }); + } + + [Fact] + public async void WinFormsPropertyDefaultValueDefinitionMethodsMustHaveCorrespondingProperty() + { + var source = @" +private bool ShouldSerializePropertyXXX() => true; + +private void ResetPropertyXXX() { }; +".WrapInCSharpClass(); + var result1 = CreateDiagnosticResult(9, 1); + var result2 = CreateDiagnosticResult(11, 1); + await VerifyCSharpDiagnosticAsync(source, new DiagnosticResult[] { result1, result2 }); + } + + [Fact] + public async void WinFormsPropertyDefaultValueDefinitionMethodsMustHaveASuffix() + { + var source = @" +private bool ShouldSerialize() => true; + +private void ResetProperty() { }; +".WrapInCSharpClass(); + var result1 = CreateDiagnosticResult(9, 1); + var result2 = CreateDiagnosticResult(11, 1); + await VerifyCSharpDiagnosticAsync(source, new DiagnosticResult[] { result1, result2 }); + } } } \ No newline at end of file From d8cc1f75f2b75dcb10d5f4a4082da4b918501e74 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 27 Apr 2017 15:54:10 +0200 Subject: [PATCH 070/152] Added CoalesceExpression to the list of possible parents in topSyntaxNode discovery. --- .../DisposableVariableNotDisposedAnalyzer.cs | 2 +- .../DisposableVariableNotDisposedTests.cs | 23 ++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs index 2a4b4c32f..3ed958b5f 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs @@ -40,7 +40,7 @@ private static void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context) var originalNode = objectCreation; SyntaxNode topSyntaxNode = originalNode; - while (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ParenthesizedExpression, SyntaxKind.ConditionalExpression, SyntaxKind.CastExpression)) + while (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ParenthesizedExpression, SyntaxKind.ConditionalExpression, SyntaxKind.CastExpression, SyntaxKind.CoalesceExpression)) topSyntaxNode = topSyntaxNode.Parent; if (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.ReturnStatement, SyntaxKind.UsingStatement, SyntaxKind.YieldReturnStatement)) diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index d1ad9d3e9..e2f2a9fd9 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -1577,5 +1577,26 @@ void Bar() }"; await VerifyCSharpHasNoDiagnosticsAsync(source); } + + [Fact] + public async Task IgnoreWhenAssignedToFieldByNullCoalescingOperator() + { + const string source = @" +using System.IO; +public class Test : IDisposable +{ + private IDisposable _stream; + + public void Update() + { + _stream = _stream ?? new MemoryStream(); + } + + public void Dispose() + { + _stream.Dispose(); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); } -} \ No newline at end of file +}} \ No newline at end of file From 98270b530444432601a68d937297ed47f4f52a04 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 27 Apr 2017 16:12:09 +0200 Subject: [PATCH 071/152] Code formating. --- .../Usage/DisposableVariableNotDisposedTests.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index e2f2a9fd9..cb1437596 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -1578,10 +1578,10 @@ void Bar() await VerifyCSharpHasNoDiagnosticsAsync(source); } - [Fact] - public async Task IgnoreWhenAssignedToFieldByNullCoalescingOperator() - { - const string source = @" + [Fact] + public async Task IgnoreWhenAssignedToFieldByNullCoalescingOperator() + { + const string source = @" using System.IO; public class Test : IDisposable { @@ -1597,6 +1597,7 @@ public void Dispose() _stream.Dispose(); } }"; - await VerifyCSharpHasNoDiagnosticsAsync(source); + await VerifyCSharpHasNoDiagnosticsAsync(source); + } } -}} \ No newline at end of file +} \ No newline at end of file From 871d40f53d43ba7891c427349d6ae21722025b5a Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 19:38:39 -0300 Subject: [PATCH 072/152] Create a single dll for the nupkg Using ilmerge, we are merging the C# and VB dlls with the common dll, which generates a simpler experience for the user. --- .gitignore | 1 + .nuget/packages.config | 1 + build.ps1 | 13 ++- build.targets.ps1 | 99 ++++++++++++++----- src/CSharp/CodeCracker/CodeCracker.nuspec | 2 +- src/CodeCracker.nuspec | 30 ------ .../CodeCracker/CodeCracker.nuspec | 2 +- 7 files changed, 93 insertions(+), 55 deletions(-) delete mode 100644 src/CodeCracker.nuspec diff --git a/.gitignore b/.gitignore index 3da239e30..b5c6a38ac 100644 --- a/.gitignore +++ b/.gitignore @@ -192,3 +192,4 @@ ModelManifest.xml log/ .vs nuget.exe +*.nupkg diff --git a/.nuget/packages.config b/.nuget/packages.config index 5e0ac7672..964028c5c 100644 --- a/.nuget/packages.config +++ b/.nuget/packages.config @@ -2,4 +2,5 @@ + diff --git a/build.ps1 b/build.ps1 index d1a072785..95d279b16 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,4 +1,6 @@ $ErrorActionPreference = "Stop" +$tempDir = Join-Path "$([System.IO.Path]::GetTempPath())" "CodeCracker" +if (!(Test-Path $tempDir)) { mkdir $tempDir | Out-Null } # functions: function IsNugetVersion3OrAbove($theNugetExe) { @@ -47,7 +49,7 @@ function Download-Nuget { } function Import-Psake { - $psakeModule = "$PSScriptRoot\packages\psake.4.5.0\tools\psake.psm1" + $psakeModule = "$PSScriptRoot\packages\psake.4.6.0\tools\psake.psm1" if ((Test-Path $psakeModule) -ne $true) { Write-Host "Restoring $PSScriptRoot\.nuget with $script:nugetExe" . "$script:nugetExe" restore $PSScriptRoot\.nuget\packages.config -SolutionDirectory $PSScriptRoot @@ -55,12 +57,21 @@ function Import-Psake { Import-Module $psakeModule -force } +function Import-ILMerge { + $ilmergeExe = "$PSScriptRoot\packages\ilmerge.2.14.1208\tools\ILMerge.exe" + if ((Test-Path $ilmergeExe) -ne $true) { + Write-Host "Restoring $PSScriptRoot\.nuget with $script:nugetExe" + . "$script:nugetExe" restore $PSScriptRoot\.nuget\packages.config -SolutionDirectory $PSScriptRoot + } +} + # statements: $localNuget = "$PSScriptRoot\.nuget\nuget.exe" $nugetExe = "" Get-Nuget Import-Psake +Import-ILMerge if ($MyInvocation.UnboundArguments.Count -ne 0) { . $PSScriptRoot\psake.ps1 -taskList ($MyInvocation.UnboundArguments -join " ") } diff --git a/build.targets.ps1 b/build.targets.ps1 index d5c0cc057..253bf1955 100644 --- a/build.targets.ps1 +++ b/build.targets.ps1 @@ -10,24 +10,33 @@ Properties { $buildNumber = [Convert]::ToInt32($env:APPVEYOR_BUILD_NUMBER).ToString("0000") $nuspecPathCS = "$rootDir\src\CSharp\CodeCracker\CodeCracker.nuspec" $nuspecPathVB = "$rootDir\src\VisualBasic\CodeCracker\CodeCracker.nuspec" - $nuspecPathJoint = "$rootDir\src\CodeCracker.nuspec" $nugetExe = "$packagesDir\NuGet.CommandLine.3.3.0\tools\NuGet.exe" $nupkgPathCS = "$rootDir\src\CSharp\CodeCracker.CSharp.{0}.nupkg" $nupkgPathVB = "$rootDir\src\VisualBasic\CodeCracker.VisualBasic.{0}.nupkg" - $nupkgPathJoint = "$rootDir\CodeCracker.{0}.nupkg" $xunitConsoleExe = "$packagesDir\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" $openCoverExe = "$packagesDir\OpenCover.4.6.519\tools\OpenCover.Console.exe" + $dllCS = "CodeCracker.CSharp.dll" + $dllVB = "CodeCracker.VisualBasic.dll" + $dllCommon = "CodeCracker.Common.dll" $testDllCS = "CodeCracker.Test.CSharp.dll" $testDllVB = "CodeCracker.Test.VisualBasic.dll" $testDirCS = "$testDir\CSharp\CodeCracker.Test\bin\Release" $testDirVB = "$testDir\VisualBasic\CodeCracker.Test\bin\Release" + $projectDirVB = "$srcDir\VisualBasic\CodeCracker" + $projectFileVB = "$projectDirVB\CodeCracker.vbproj" + $releaseDirVB = "$projectDirVB\bin\Release" + $projectDirCS = "$srcDir\CSharp\CodeCracker" + $projectFileCS = "$projectDirCS\CodeCracker.csproj" + $releaseDirCS = "$projectDirCS\bin\Release" $logDir = "$rootDir\log" $outputXml = "$logDir\CodeCoverageResults.xml" $reportGeneratorExe = "$packagesDir\ReportGenerator.2.5.6\tools\ReportGenerator.exe" $coverageReportDir = "$logDir\codecoverage\" $coverallsNetExe = "$packagesDir\coveralls.io.1.3.4\tools\coveralls.net.exe" + $ilmergeExe = "$packagesDir\ilmerge.2.14.1208\tools\ILMerge.exe" $isRelease = $isAppVeyor -and (($env:APPVEYOR_REPO_BRANCH -eq "release") -or ($env:APPVEYOR_REPO_TAG -eq "true")) $isPullRequest = $env:APPVEYOR_PULL_REQUEST_NUMBER -ne $null + $tempDir = Join-Path "$([System.IO.Path]::GetTempPath())" "CodeCracker" } FormatTaskName (("-"*25) + "[{0}]" + ("-"*25)) @@ -49,14 +58,16 @@ Task Build-CS -depends Prepare-Build, Build-Only-CS Task Build-VB -depends Prepare-Build, Build-Only-VB Task Build-Only -depends Build-Only-CS, Build-Only-VB -Task Build-Only-CS { +Task Build-Only-CS -depends Build-MSBuild-CS, ILMerge-CS +Task Build-MSBuild-CS { if ($isAppVeyor) { Exec { msbuild $solutionFileCS /m /verbosity:minimal /p:Configuration=ReleaseNoVsix /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" } } else { Exec { msbuild $solutionFileCS /m /verbosity:minimal /p:Configuration=ReleaseNoVsix } } } -Task Build-Only-VB { +Task Build-Only-VB -depends Build-MSBuild-VB, ILMerge-VB +Task Build-MSBuild-VB { if ($isAppVeyor) { Exec { msbuild $solutionFileVB /m /verbosity:minimal /p:Configuration=ReleaseNoVsix /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" } } else { @@ -64,6 +75,49 @@ Task Build-Only-VB { } } +Task ILMerge-VB { ILMerge $releaseDirVB $dllVB $projectFileVB $projectDirVB } +Task ILMerge-CS { ILMerge $releaseDirCS $dllCS $projectFileCS $projectDirCS } + +function ILMerge($releaseDir, $dll, $projectFile, $projectDir) { + Write-Host "IL Merge:" + $mergedDir = $tempDir + if (!(Test-Path $mergedDir)) { mkdir "$mergedDir" } + $inputDll = "$releaseDir\$dll" + $inputDllCommon = "$releaseDir\$dllCommon" + $pdbCommon = Change-Extension $inputDllCommon "pdb" + if (Test-Path $inputDllCommon) { + if ((ls $inputDllCommon).LastWriteTime -gt (ls $inputDll).LastWriteTime) { + # common is newer, but no changes on main dll + Write-Host "Common dll is newer than $inputDll, stopping IL merge." + return + } + } else { + # no common dll, can't merge + Write-Host "Can't find common dll, stopping IL merge." + return + } + $mergedDll = "$mergedDir\$dll" + [xml]$proj = cat $projectFile + $libs = @() + foreach ($ref in $proj.Project.ItemGroup.Reference.HintPath) { + $dir += [System.IO.Path]::GetDirectoryName("$projectDir\$ref") + $libs += "/lib:`"$([System.IO.Path]::GetDirectoryName("$projectDir\$ref"))`" " + } + Exec { . $ilmergeExe $libs /out:"$mergedDll" "$inputDll" "$inputDllCommon" } + $releaseMergedDir = "$releaseDir\merged" + if (!(Test-Path $releaseMergedDir)) { mkdir $releaseMergedDir | Out-Null } + cp $mergedDll "$releaseMergedDir\" -Force + Write-Host " $dll -> $releaseMergedDir\$dll" + $mergedPdb = Change-Extension $mergedDll "pdb" + cp $mergedPdb "$releaseMergedDir\" -Force + $pdb = (ls $mergedPdb).Name + Write-Host " $pdb -> $releaseMergedDir\$pdb" +} + +function Change-Extension ($filename, $extension) { + Join-Path "$([System.IO.Path]::GetDirectoryName($filename))" "$([System.IO.Path]::GetFileNameWithoutExtension($filename)).$extension" +} + Task Clean { Exec { msbuild $solutionFileCS /t:Clean /v:quiet } Exec { msbuild $solutionFileVB /t:Clean /v:quiet } @@ -99,10 +153,7 @@ Task Test-No-Coverage-CSharp { RunTest "$testDirCS\$testDllCS" } -Task Update-Nuspec -precondition { return $isAppVeyor -and ($isRelease -ne $true) } -depends Update-Nuspec-Joint -Task Update-Nuspec-Joint -precondition { return $isAppVeyor -and ($isRelease -ne $true) } -depends Update-Nuspec-CSharp, Update-Nuspec-VB { - UpdateNuspec $nuspecPathJoint "joint package" -} +Task Update-Nuspec -precondition { return $isAppVeyor -and ($isRelease -ne $true) } -depends Update-Nuspec-CSharp, Update-Nuspec-VB Task Update-Nuspec-CSharp -precondition { return $isAppVeyor -and ($isRelease -ne $true) } { UpdateNuspec $nuspecPathCS "C#" } @@ -110,31 +161,35 @@ Task Update-Nuspec-VB -precondition { return $isAppVeyor -and ($isRelease -ne $t UpdateNuspec $nuspecPathVB "VB" } -Task Pack-Nuget -precondition { return $isAppVeyor } -depends Pack-Nuget-Joint -Task Pack-Nuget-Joint -precondition { return $isAppVeyor } -depends Pack-Nuget-Csharp, Pack-Nuget-VB { - #we won't be publishing the common package anymore - #PackNuget "Joint package" "$rootDir" $nuspecPathJoint $nupkgPathJoint -} +Task Pack-Nuget -precondition { return $isAppVeyor } -depends Pack-Nuget-Csharp, Pack-Nuget-VB Task Pack-Nuget-CSharp -precondition { return $isAppVeyor } { PackNuget "C#" "$rootDir\src\CSharp" $nuspecPathCS $nupkgPathCS } Task Pack-Nuget-VB -precondition { return $isAppVeyor } { PackNuget "VB" "$rootDir\src\VisualBasic" $nuspecPathVB $nupkgPathVB } +Task Pack-Nuget-Force -depends Pack-Nuget-Csharp-Force, Pack-Nuget-VB-Force +Task Pack-Nuget-Csharp-Force { + PackNuget "C#" "$rootDir\src\CSharp" $nuspecPathCS $nupkgPathCS +} +Task Pack-Nuget-VB-Force { + PackNuget "VB" "$rootDir\src\VisualBasic" $nuspecPathVB $nupkgPathVB +} Task Echo { echo echo } function PackNuget($language, $dir, $nuspecFile, $nupkgFile) { Write-Host "Packing nuget for $language..." - [xml]$xml = cat $nuspecFile + [xml]$xml = cat "$nuspecFile" $nupkgFile = $nupkgFile -f $xml.package.metadata.version - Write-Host "Nupkg path is $nupkgFile" - . $nugetExe pack $nuspecFile -OutputDirectory $dir - ls $nupkgFile - Write-Host "Nuget packed for $language!" - Write-Host "Pushing nuget artifact for $language..." - appveyor PushArtifact $nupkgFile - Write-Host "Nupkg pushed for $language!" + . $nugetExe pack "$nuspecFile" -OutputDirectory "$dir" + $nuspecFileName = (ls $nuspecFile).Name + Write-Host " $nuspecFileName ($language/$($xml.package.metadata.version)) -> $nupkgFile" + if ($isAppVeyor) { + Write-Host "Pushing nuget artifact for $language..." + appveyor PushArtifact $nupkgFile + Write-Host "Nupkg pushed for $language!" + } } function UpdateNuspec($nuspecPath, $language) { @@ -223,4 +278,4 @@ function RunTestWithCoverage($fullTestDllPaths) { Write-Host -ForegroundColor DarkBlue "Uploading coverage report to Coveralls.io" Exec { . $coverallsNetExe --opencover $outputXml --full-sources } } -} +} \ No newline at end of file diff --git a/src/CSharp/CodeCracker/CodeCracker.nuspec b/src/CSharp/CodeCracker/CodeCracker.nuspec index fdfc1e815..91e3f5c70 100644 --- a/src/CSharp/CodeCracker/CodeCracker.nuspec +++ b/src/CSharp/CodeCracker/CodeCracker.nuspec @@ -22,7 +22,7 @@ This is a community project, free and open source. Everyone is invited to contri true - + diff --git a/src/CodeCracker.nuspec b/src/CodeCracker.nuspec deleted file mode 100644 index f5113b83b..000000000 --- a/src/CodeCracker.nuspec +++ /dev/null @@ -1,30 +0,0 @@ - - - - codecracker - 1.1.0 - CodeCracker for C# and VB - giggio,elemarjr,carloscds - giggio,elemarjr,carloscds - https://github.com/code-cracker/code-cracker/blob/master/LICENSE.txt - http://code-cracker.github.io/ - https://avatars1.githubusercontent.com/u/9695920?v=3&s=200 - true - A analyzer library for C# and VB that uses Roslyn to produce refactorings, code analysis, and other niceties. - -You probably don't want this package directly, search for the C# or Visual Basic specific packages (codecracker.CSharp and codecracker.VisualBasic). This will install both. - -This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. - See https://github.com/code-cracker/code-cracker/blob/master/CHANGELOG.md - Copyright CodeCracker 2014-2016 - roslyn, analyzers - - - - - - - - - - diff --git a/src/VisualBasic/CodeCracker/CodeCracker.nuspec b/src/VisualBasic/CodeCracker/CodeCracker.nuspec index 326c5ccb4..8c35dc85b 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.nuspec +++ b/src/VisualBasic/CodeCracker/CodeCracker.nuspec @@ -21,7 +21,7 @@ This is a community project, free and open source. Everyone is invited to contri - + From d37dbd240d893574d35c1f1fe322d1742aa5d961 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 19:44:52 -0300 Subject: [PATCH 073/152] Update dependencies --- .nuget/packages.config | 4 +- build.targets.ps1 | 3 +- psake.ps1 | 4 +- src/CSharp/CodeCracker/CodeCracker.csproj | 50 ++++++++----------- src/CSharp/CodeCracker/packages.config | 16 +++--- .../CodeCracker.Common.csproj | 28 +++++------ src/Common/CodeCracker.Common/packages.config | 12 ++--- .../CodeCracker/CodeCracker.vbproj | 38 ++++++-------- src/VisualBasic/CodeCracker/packages.config | 16 +++--- .../CodeCracker.Test/CodeCracker.Test.csproj | 44 +++++++--------- test/CSharp/CodeCracker.Test/packages.config | 24 ++++++--- .../CodeCracker.Test.Common.csproj | 45 ++++++++--------- .../CodeCracker.Test.Common/packages.config | 28 +++++++---- .../CodeCracker.Test/CodeCracker.Test.vbproj | 44 +++++++--------- .../CodeCracker.Test/packages.config | 24 ++++++--- 15 files changed, 188 insertions(+), 192 deletions(-) diff --git a/.nuget/packages.config b/.nuget/packages.config index 964028c5c..9707f7736 100644 --- a/.nuget/packages.config +++ b/.nuget/packages.config @@ -1,6 +1,6 @@  - - + + diff --git a/build.targets.ps1 b/build.targets.ps1 index 253bf1955..f5be72100 100644 --- a/build.targets.ps1 +++ b/build.targets.ps1 @@ -10,7 +10,8 @@ Properties { $buildNumber = [Convert]::ToInt32($env:APPVEYOR_BUILD_NUMBER).ToString("0000") $nuspecPathCS = "$rootDir\src\CSharp\CodeCracker\CodeCracker.nuspec" $nuspecPathVB = "$rootDir\src\VisualBasic\CodeCracker\CodeCracker.nuspec" - $nugetExe = "$packagesDir\NuGet.CommandLine.3.3.0\tools\NuGet.exe" + $nugetPackagesExe = "$packagesDir\NuGet.CommandLine.4.1.0\tools\NuGet.exe" + $nugetExe = if (Test-Path $nugetPackagesExe) { $nugetPackagesExe } else { 'nuget' } $nupkgPathCS = "$rootDir\src\CSharp\CodeCracker.CSharp.{0}.nupkg" $nupkgPathVB = "$rootDir\src\VisualBasic\CodeCracker.VisualBasic.{0}.nupkg" $xunitConsoleExe = "$packagesDir\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" diff --git a/psake.ps1 b/psake.ps1 index de6e34a2d..ce647902b 100644 --- a/psake.ps1 +++ b/psake.ps1 @@ -1,3 +1,3 @@ -Import-Module $PSScriptRoot\packages\psake.4.5.0\tools\psake.psm1 -force -Invoke-Expression("Invoke-psake -framework '4.5.2' build.targets.ps1 " + $MyInvocation.UnboundArguments -join " ") +Import-Module $PSScriptRoot\packages\psake.4.6.0\tools\psake.psm1 -force +Invoke-Expression("Invoke-psake -framework '4.5.2' $PSScriptRoot\build.targets.ps1 " + $MyInvocation.UnboundArguments -join " ") exit !($psake.build_success) \ No newline at end of file diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index a6d7d52d7..ea63f7981 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -222,37 +222,26 @@ - - {753d4757-fcba-43ba-b1be-89201acda192} - CodeCracker.Common - + + + + - - - - - - - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.CSharp.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.CSharp.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - - ..\..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - False + + ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll @@ -274,11 +263,16 @@ ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll False - - ..\..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll - False + + ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + + + {753d4757-fcba-43ba-b1be-89201acda192} + CodeCracker.Common + + diff --git a/src/CSharp/CodeCracker/packages.config b/src/CSharp/CodeCracker/packages.config index d1bbcab2c..fcde436eb 100644 --- a/src/CSharp/CodeCracker/packages.config +++ b/src/CSharp/CodeCracker/packages.config @@ -1,12 +1,12 @@  - - - - - - + + + + + + - - + + \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj index 3426e7d12..f20344f73 100644 --- a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj +++ b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj @@ -70,23 +70,20 @@ - - - - + + + + - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - - ..\..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - False + + ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll @@ -108,9 +105,8 @@ ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll False - - ..\..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll - False + + ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll diff --git a/src/Common/CodeCracker.Common/packages.config b/src/Common/CodeCracker.Common/packages.config index d8681f9ca..847a13861 100644 --- a/src/Common/CodeCracker.Common/packages.config +++ b/src/Common/CodeCracker.Common/packages.config @@ -1,10 +1,10 @@  - - - - + + + + - - + + \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker/CodeCracker.vbproj b/src/VisualBasic/CodeCracker/CodeCracker.vbproj index e2deff9b9..02045debc 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.vbproj +++ b/src/VisualBasic/CodeCracker/CodeCracker.vbproj @@ -162,31 +162,26 @@ - - - - + + + + - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.VisualBasic.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.VisualBasic.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - False + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - - ..\..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - False + + ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll @@ -208,9 +203,8 @@ ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll False - - ..\..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll - False + + ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll diff --git a/src/VisualBasic/CodeCracker/packages.config b/src/VisualBasic/CodeCracker/packages.config index 20b3df7df..bc11241d0 100644 --- a/src/VisualBasic/CodeCracker/packages.config +++ b/src/VisualBasic/CodeCracker/packages.config @@ -1,12 +1,12 @@  - - - - - - + + + + + + - - + + \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 4198a1676..c45a93ec6 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -46,32 +46,27 @@ ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.0.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.0.0\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - - ..\..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll True @@ -95,9 +90,8 @@ True - - ..\..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll - True + + ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll @@ -213,7 +207,7 @@ CodeCracker.Common - {FF1097FB-A890-461B-979E-064697891B96} + {ff1097fb-a890-461b-979e-064697891b96} CodeCracker @@ -232,10 +226,10 @@ - - - - + + + + diff --git a/test/CSharp/CodeCracker.Test/packages.config b/test/CSharp/CodeCracker.Test/packages.config index e6e8b042c..22638264b 100644 --- a/test/CSharp/CodeCracker.Test/packages.config +++ b/test/CSharp/CodeCracker.Test/packages.config @@ -1,16 +1,24 @@  - + - - - - - + + + + + - - + + + + + + + + + + diff --git a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj index fb0650aee..905792f36 100644 --- a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj +++ b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj @@ -41,33 +41,33 @@ ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.0.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.0.0\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.0.0\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.0.0\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - - ..\..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll True @@ -91,9 +91,8 @@ True - - ..\..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll - True + + ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll @@ -130,10 +129,10 @@ - - - - + + + + diff --git a/test/Common/CodeCracker.Test.Common/packages.config b/test/Common/CodeCracker.Test.Common/packages.config index b75a21670..c24c4bdc2 100644 --- a/test/Common/CodeCracker.Test.Common/packages.config +++ b/test/Common/CodeCracker.Test.Common/packages.config @@ -1,21 +1,29 @@  - + - - - - - - - + + + + + + + - - + + + + + + + + + + diff --git a/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj b/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj index 77000d42d..a0ead244c 100644 --- a/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj +++ b/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj @@ -60,32 +60,27 @@ ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.0.0\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.0.0\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.0.0\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll - True + + ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - - ..\..\..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll + + ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll True @@ -108,9 +103,8 @@ ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll True - - ..\..\..\packages\System.Reflection.Metadata.1.0.21\lib\portable-net45+win8\System.Reflection.Metadata.dll - True + + ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll @@ -222,10 +216,10 @@ - - - - + + + + @@ -241,4 +235,4 @@ --> - + \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/packages.config b/test/VisualBasic/CodeCracker.Test/packages.config index 8742f779c..4e3b70206 100644 --- a/test/VisualBasic/CodeCracker.Test/packages.config +++ b/test/VisualBasic/CodeCracker.Test/packages.config @@ -1,16 +1,24 @@  - + - - - - - + + + + + - - + + + + + + + + + + From ae3513041ad8e7cabba002ab60cfdba907c11775 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 19:53:51 -0300 Subject: [PATCH 074/152] Move build.targets.ps1 to default.ps1 to ease psake use Now we don't need to go through build.ps1 for eveything anymore, we can use psake directly as default.ps1 is the default file name for psake. --- CodeCracker.sln | 7 +++---- build.ps1 | 2 +- build.targets.ps1 => default.ps1 | 0 psake.ps1 | 3 --- 4 files changed, 4 insertions(+), 8 deletions(-) rename build.targets.ps1 => default.ps1 (100%) delete mode 100644 psake.ps1 diff --git a/CodeCracker.sln b/CodeCracker.sln index 8061066fb..64406cda0 100644 --- a/CodeCracker.sln +++ b/CodeCracker.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" EndProject @@ -42,8 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{234973E7 ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - build.targets.ps1 = build.targets.ps1 - psake.ps1 = psake.ps1 + default.ps1 = default.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5584F20-6E93-4D2D-B6F0-141B977AFC9F}" diff --git a/build.ps1 b/build.ps1 index 95d279b16..821027472 100644 --- a/build.ps1 +++ b/build.ps1 @@ -73,7 +73,7 @@ Get-Nuget Import-Psake Import-ILMerge if ($MyInvocation.UnboundArguments.Count -ne 0) { - . $PSScriptRoot\psake.ps1 -taskList ($MyInvocation.UnboundArguments -join " ") + Invoke-Expression("Invoke-psake -framework '4.5.2' $PSScriptRoot\default.ps1 -taskList " + $MyInvocation.UnboundArguments -join " ") } else { . $PSScriptRoot\build.ps1 Build diff --git a/build.targets.ps1 b/default.ps1 similarity index 100% rename from build.targets.ps1 rename to default.ps1 diff --git a/psake.ps1 b/psake.ps1 deleted file mode 100644 index ce647902b..000000000 --- a/psake.ps1 +++ /dev/null @@ -1,3 +0,0 @@ -Import-Module $PSScriptRoot\packages\psake.4.6.0\tools\psake.psm1 -force -Invoke-Expression("Invoke-psake -framework '4.5.2' $PSScriptRoot\build.targets.ps1 " + $MyInvocation.UnboundArguments -join " ") -exit !($psake.build_success) \ No newline at end of file From 163f6bfca19085a65b95a01180c8d357b01a3fd8 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 20:03:15 -0300 Subject: [PATCH 075/152] Adjust sln files to the new psake structure --- CodeCracker.2015.sln | 5 ++--- CodeCracker.CSharp.2015.sln | 7 +++---- CodeCracker.CSharp.sln | 7 +++---- CodeCracker.VisualBasic.2015.sln | 5 ++--- CodeCracker.VisualBasic.sln | 7 +++---- 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/CodeCracker.2015.sln b/CodeCracker.2015.sln index 729d7ca60..61766491e 100644 --- a/CodeCracker.2015.sln +++ b/CodeCracker.2015.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" EndProject @@ -42,8 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{234973E7 ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - build.targets.ps1 = build.targets.ps1 - psake.ps1 = psake.ps1 + default.ps1 = default.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5584F20-6E93-4D2D-B6F0-141B977AFC9F}" diff --git a/CodeCracker.CSharp.2015.sln b/CodeCracker.CSharp.2015.sln index 0600d9a27..f1ddbefd2 100644 --- a/CodeCracker.CSharp.2015.sln +++ b/CodeCracker.CSharp.2015.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F5240AD-2B4E-48A4-B9FC-7D19DACEF2CD}" ProjectSection(SolutionItems) = preProject @@ -11,7 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F5240 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker", "src\CSharp\CodeCracker\CodeCracker.csproj", "{FF1097FB-A890-461B-979E-064697891B96}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.2015.Vsix", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.2015.csproj", "{6BAC4057-7239-485E-A04B-02E687A83BAA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.2015", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.2015.csproj", "{6BAC4057-7239-485E-A04B-02E687A83BAA}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test", "test\CSharp\CodeCracker.Test\CodeCracker.Test.csproj", "{F7843158-046E-4B22-95D7-CAC7BB01283D}" EndProject @@ -36,8 +36,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{40545653 ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - build.targets.ps1 = build.targets.ps1 - psake.ps1 = psake.ps1 + default.ps1 = default.ps1 EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" diff --git a/CodeCracker.CSharp.sln b/CodeCracker.CSharp.sln index 2f52cf033..e075a10f0 100644 --- a/CodeCracker.CSharp.sln +++ b/CodeCracker.CSharp.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F5240AD-2B4E-48A4-B9FC-7D19DACEF2CD}" ProjectSection(SolutionItems) = preProject @@ -36,8 +36,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{40545653 ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - build.targets.ps1 = build.targets.ps1 - psake.ps1 = psake.ps1 + default.ps1 = default.ps1 EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" diff --git a/CodeCracker.VisualBasic.2015.sln b/CodeCracker.VisualBasic.2015.sln index 9d3b4ba56..cec5830dd 100644 --- a/CodeCracker.VisualBasic.2015.sln +++ b/CodeCracker.VisualBasic.2015.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CodeCracker", "src\VisualBasic\CodeCracker\CodeCracker.vbproj", "{41FA4971-D354-4647-A269-4A886DA2EF4C}" EndProject @@ -24,8 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D1591C8E ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - build.targets.ps1 = build.targets.ps1 - psake.ps1 = psake.ps1 + default.ps1 = default.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{22D6C608-E7F1-4236-BB07-BE5F97A4C810}" diff --git a/CodeCracker.VisualBasic.sln b/CodeCracker.VisualBasic.sln index 6b903192a..b338754d2 100644 --- a/CodeCracker.VisualBasic.sln +++ b/CodeCracker.VisualBasic.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CodeCracker", "src\VisualBasic\CodeCracker\CodeCracker.vbproj", "{41FA4971-D354-4647-A269-4A886DA2EF4C}" EndProject @@ -24,8 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D1591C8E ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - build.targets.ps1 = build.targets.ps1 - psake.ps1 = psake.ps1 + default.ps1 = default.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{22D6C608-E7F1-4236-BB07-BE5F97A4C810}" From 143c6861fd0c3858503066c5ba94b593807eda43 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 20:08:46 -0300 Subject: [PATCH 076/152] Remove vs 2015 solutions from psake file --- default.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.ps1 b/default.ps1 index f5be72100..d524aad28 100644 --- a/default.ps1 +++ b/default.ps1 @@ -5,7 +5,7 @@ Properties { $srcDir = "$rootDir\src" $testDir = "$rootDir\test" $isAppVeyor = $env:APPVEYOR -eq $true - $slns = ls "$rootDir\*.sln" + $slns = ls "$rootDir\*.sln" | ? { ! $_.Name.Contains('.2015.') } $packagesDir = "$rootDir\packages" $buildNumber = [Convert]::ToInt32($env:APPVEYOR_BUILD_NUMBER).ToString("0000") $nuspecPathCS = "$rootDir\src\CSharp\CodeCracker\CodeCracker.nuspec" From 6af54565725cae759e8b6469053ee3631d6f3ee0 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 20:27:06 -0300 Subject: [PATCH 077/152] Be more specific about nuget restore --- default.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/default.ps1 b/default.ps1 index d524aad28..a36f5fad6 100644 --- a/default.ps1 +++ b/default.ps1 @@ -205,7 +205,7 @@ function UpdateNuspec($nuspecPath, $language) { function RestorePkgs($sln) { Write-Host "Restoring $sln..." -ForegroundColor Green Retry { - . $nugetExe restore $sln + . $nugetExe restore "$sln" -MSBuildVersion 14 -NonInteractive -ConfigFile "$rootDir\nuget.config" if ($LASTEXITCODE) { throw "Nuget restore for $sln failed." } } } From 1e3e459407ac2661f634112b872325e29c31cd65 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Fri, 23 Jun 2017 02:08:26 +0200 Subject: [PATCH 078/152] Fix CC0014 casting rule bugs Closes #911 --- .../Style/TernaryOperatorCodeFixProvider.cs | 31 ++--------- .../Style/TernaryOperatorTests.cs | 55 +++++++++++++++++++ 2 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 8444c0705..b36fa9584 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -222,21 +222,16 @@ private static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionS if (!elseType.HasImplicitNumericConversion(ifType) && !IsEnumAndZero(ifType, elseExpression) && !IsEnumAndZero(elseType, ifExpression) - && (!isNullable && !ifType.CanBeAssignedTo(elseType) || !elseType.CanBeAssignedTo(ifType))) - trueExpression = CastToBaseType(ifExpression, ifType, elseType, trueExpression); + && (!isNullable && !ifType.CanBeAssignedTo(elseType) || !elseType.CanBeAssignedTo(ifType)) + && ifType != ifConvertedType) + trueExpression = CastToConvertedType(ifExpression, ifConvertedType); } private static bool IsEnumAndZero(ITypeSymbol type, ExpressionSyntax expression) => type?.BaseType?.SpecialType == SpecialType.System_Enum && expression?.ToString() == "0"; - private static ExpressionSyntax CastToBaseType(ExpressionSyntax ifExpression, ITypeSymbol ifType, ITypeSymbol elseType, ExpressionSyntax trueExpression) - { - var commonBaseType = ifType.GetCommonBaseType(elseType); - if (commonBaseType.Equals(ifType)) return trueExpression; - if (commonBaseType != null) - trueExpression = SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName(commonBaseType.Name).WithAdditionalAnnotations(Simplifier.Annotation), ifExpression); - return trueExpression; - } + private static ExpressionSyntax CastToConvertedType(ExpressionSyntax ifExpression, ITypeSymbol ifConvertedType) + => SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName(ifConvertedType.ToString()).WithAdditionalAnnotations(Simplifier.Annotation), ifExpression); private static bool CanBeAssignedTo(this ITypeSymbol type, ITypeSymbol possibleBaseType) { @@ -252,21 +247,5 @@ private static bool CanBeAssignedTo(this ITypeSymbol type, ITypeSymbol possibleB } return false; } - - private static ITypeSymbol GetCommonBaseType(this ITypeSymbol type, ITypeSymbol otherType) - { - var baseType = type; - while (baseType != null) - { - var otherBaseType = otherType; - while (otherBaseType != null) - { - if (baseType.Equals(otherBaseType)) return baseType; - otherBaseType = otherBaseType.BaseType; - } - baseType = baseType.BaseType; - } - return null; - } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index c9c86f91c..ccfc31761 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -396,6 +396,23 @@ public void Foo() }".WrapInCSharpClass(); await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentToAnInterfaceVariableAFittingCastIsInserted() + { + var source = @" + System.Collections.Generic.IEnumerable e= null; + if (true) + e = new int[10]; + else + e = new System.Collections.Generic.List(); + ".WrapInCSharpMethod(); + var fixtest = @" + System.Collections.Generic.IEnumerable e= null; + e = true ? (System.Collections.Generic.IEnumerable)new int[10] : new System.Collections.Generic.List(); + ".WrapInCSharpMethod(); + await VerifyCSharpFixAsync(source, fixtest); + } } public class TernaryOperatorWithReturnTests : CodeFixVerifier @@ -1327,5 +1344,43 @@ public Object Foo() }".WrapInCSharpClass(); await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenReturnTypeIsAnInterfaceAFittingCastIsInserted() + { + var source = @" + IComparable GetComparable() + { + if (true) + return 1; + else + return ""1""; + }".WrapInCSharpClass(); + var fixtest = @" + IComparable GetComparable() + { + return true?(IComparable)1 : ""1""; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithReturnTypeIsExplicitConvertable() + { + var source = @" + double GetNumber() + { + if (true) + return 1; + else + return 1.1; + }".WrapInCSharpClass(); + var fixtest = @" + double GetNumber() + { + return true?(double)1:1.1; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From bc88e5dc9ecec941224f5fc4a83af5875601f42f Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 21:10:18 -0300 Subject: [PATCH 079/152] Update .gitigore from master --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3da239e30..b5c6a38ac 100644 --- a/.gitignore +++ b/.gitignore @@ -192,3 +192,4 @@ ModelManifest.xml log/ .vs nuget.exe +*.nupkg From 4595fbe1696845b21f952f14c68ca19c6aa13168 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Fri, 23 Jun 2017 02:08:26 +0200 Subject: [PATCH 080/152] Fix CC0014 casting rule bugs Closes #911 --- .../Style/TernaryOperatorCodeFixProvider.cs | 31 +- .../Style/TernaryOperatorTests.cs | 659 ++++++++++++++++++ 2 files changed, 664 insertions(+), 26 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 97ebd2e3f..3c8c8a9f1 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -138,21 +138,16 @@ private static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionS if (!elseType.HasImplicitNumericConversion(ifType) && !IsEnumAndZero(ifType, elseExpression) && !IsEnumAndZero(elseType, ifExpression) - && (!isNullable && !ifType.CanBeAssignedTo(elseType) || !elseType.CanBeAssignedTo(ifType))) - trueExpression = CastToBaseType(ifExpression, ifType, elseType, trueExpression); + && (!isNullable && !ifType.CanBeAssignedTo(elseType) || !elseType.CanBeAssignedTo(ifType)) + && ifType != ifConvertedType) + trueExpression = CastToConvertedType(ifExpression, ifConvertedType); } private static bool IsEnumAndZero(ITypeSymbol type, ExpressionSyntax expression) => type?.BaseType?.SpecialType == SpecialType.System_Enum && expression?.ToString() == "0"; - private static ExpressionSyntax CastToBaseType(ExpressionSyntax ifExpression, ITypeSymbol ifType, ITypeSymbol elseType, ExpressionSyntax trueExpression) - { - var commonBaseType = ifType.GetCommonBaseType(elseType); - if (commonBaseType.Equals(ifType)) return trueExpression; - if (commonBaseType != null) - trueExpression = SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName(commonBaseType.Name).WithAdditionalAnnotations(Simplifier.Annotation), ifExpression); - return trueExpression; - } + private static ExpressionSyntax CastToConvertedType(ExpressionSyntax ifExpression, ITypeSymbol ifConvertedType) + => SyntaxFactory.CastExpression(SyntaxFactory.ParseTypeName(ifConvertedType.ToString()).WithAdditionalAnnotations(Simplifier.Annotation), ifExpression); private static bool CanBeAssignedTo(this ITypeSymbol type, ITypeSymbol possibleBaseType) { @@ -168,21 +163,5 @@ private static bool CanBeAssignedTo(this ITypeSymbol type, ITypeSymbol possibleB } return false; } - - private static ITypeSymbol GetCommonBaseType(this ITypeSymbol type, ITypeSymbol otherType) - { - var baseType = type; - while (baseType != null) - { - var otherBaseType = otherType; - while (otherBaseType != null) - { - if (baseType.Equals(otherBaseType)) return baseType; - otherBaseType = otherBaseType.BaseType; - } - baseType = baseType.BaseType; - } - return null; - } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs index 68d90f96d..ccfc31761 100644 --- a/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TernaryOperatorTests.cs @@ -334,6 +334,85 @@ public static void Foo() "; await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultChangeToTernaryFixGetsArgsApplied() + { + var source = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + if (something) + { + a = Method(1); + } + else + { + a = Method(2); + } + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + a = Method(something?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentOfMethodResultWithComplexArgumentEvaluationChangeToTernaryFixGetsArgsApplied() + { + var source = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + if (something) + { + a = Method(1); + } + else + { + a = Method(2 + 2); + } + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a) => a; + + public void Foo() + { + var something = true; + int a; + a = Method(something?1:2 + 2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task WhenUsingIfAndElseWithAssignmentToAnInterfaceVariableAFittingCastIsInserted() + { + var source = @" + System.Collections.Generic.IEnumerable e= null; + if (true) + e = new int[10]; + else + e = new System.Collections.Generic.List(); + ".WrapInCSharpMethod(); + var fixtest = @" + System.Collections.Generic.IEnumerable e= null; + e = true ? (System.Collections.Generic.IEnumerable)new int[10] : new System.Collections.Generic.List(); + ".WrapInCSharpMethod(); + await VerifyCSharpFixAsync(source, fixtest); + } } public class TernaryOperatorWithReturnTests : CodeFixVerifier @@ -723,5 +802,585 @@ public static Base Foo() "; await VerifyCSharpFixAsync(source, fixtest); } + + [Fact] + public async Task WhenReturnStatementContainsMethodCallAnalyzerCreatesDiagnostic() + { + var source = @" + private int Method(int i) => i; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var expected = new DiagnosticResult + { + Id = DiagnosticId.TernaryOperator_Return.ToDiagnosticId(), + Message = "You can use a ternary operator.", + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 17) } + }; + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithSingleDifferentArgumentGetsArgsApplied() + { + var source = @" + private int Method(int i) => i; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i) => i; + + public int Foo() + { + return Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereSingleDifferentGetsArgsApplied() + { + var source = @" + private int Method(int i, string t) => i; + + public int Foo() + { + if (true) + return Method(1, ""hello""); + else + return Method(2, ""hello""); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i, string t) => i; + + public int Foo() + { + return Method(true?1:2, ""hello""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodWithMultipleArgumentsWhereMultipleDifferentGetsArgsNotApplied() + { + var source = @" + private int Method(int i, string t) => i; + + public int Foo() + { + if (true) + return Method(1, ""hello1""); + else + return Method(2, ""hello2""); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int i, string t) => i; + + public int Foo() + { + return true?Method(1,""hello1""):Method(2, ""hello2""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodArgumentsGetCastedWhenGetsArgsApplied() + { + var source = @" + class Base { } + class A : Base { } + class B : Base { } + + private int Method(Base b, string t) => 1; + + public int Foo() + { + if (true) + return Method(new A(), ""hello""); + else + return Method(new B(), ""hello""); + }".WrapInCSharpClass(); + var fixtest = @" + class Base { } + class A : Base { } + class B : Base { } + + private int Method(Base b, string t) => 1; + + public int Foo() + { + return Method(true?(Base)new A():new B(),""hello""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithPrefixedMethodGetsArgsApplied() + { + var source = @" + private int Method(int a) => a; + + public int Foo() + { + if (true) + return this.Method(1); + else + return this.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + private int Method(int a) => a; + + public int Foo() + { + return this.Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfPropertyGetsArgsApplied() + { + var source = @" + class A { + private int Method(int a) => a; + } + + public int Foo() + { + var a=new A(); + if (true) + return a.Method(1); + else + return a.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + class A { + private int Method(int a) => a; + } + + public int Foo() + { + var a=new A(); + return a.Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentPropertyGetsArgsNotApplied() + { + var source = @" + class A { + public int Method(int a) => a; + } + A Prop1 { get { return new A(); } } + A Prop2 { get { return new A(); } } + + public int Foo() + { + if (true) + return this.Prop1.Method(1); + else + return this.Prop2.Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + class A { + public int Method(int a) => a; + } + A Prop1 { get { return new A(); } } + A Prop2 { get { return new A(); } } + + public int Foo() + { + return true?this.Prop1.Method(1):this.Prop2.Method(2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfSameOverloadGetsArgsApplied() + { + var source = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(2); + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + return Method(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentOverloadGetsArgsNotApplied() + { + var source = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + if (true) + return Method(1); + else + return Method(""2""); + }".WrapInCSharpClass(); + var fixtest = @" + int Method(int a)=>a; + int Method(string a)=>1; + + public int Foo() + { + return true?Method(1):Method(""2""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDifferentOverloadButCastingPossibleGetsArgsNotApplied() + { + var source = @" + public class A { } + public class B:A { } + void Method(A a) { }; + void Method(B b) { }; + + public int Foo() + { + if (true) + return Method(new A()); + else + return Method(new B()); + }".WrapInCSharpClass(); + var fixtest = @" + public class A { } + public class B:A { } + void Method(A a) { }; + void Method(B b) { }; + + public int Foo() + { + return true?Method(new A()):Method(new B()); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodNestedInMemberAccessGetsArgsNotApplied() + { + var source = @" + class A { + public int Prop { get; } + } + + A GetA(int i) => new A(); + + public int Foo() + { + if (true) + return GetA(1).Prop; + else + return GetA(2).Prop; + }".WrapInCSharpClass(); + var fixtest = @" + class A { + public int Prop { get; } + } + + A GetA(int i) => new A(); + + public int Foo() + { + return true?GetA(1).Prop:GetA(2).Prop; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodParamOverloadAndNumerOfArgsAreEqualGetsApplied() + { + var source = @" + private int M(params int[] args) { } + + public int Foo() + { + if (true) + return M(1,1); + else + return M(1,2); + }".WrapInCSharpClass(); + var fixtest = @" + private int M(params int[] args) { } + + public int Foo() + { + return M(1,true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodParamOverloadAndNumerOfArgsAreDifferentGetsNotApplied() + { + var source = @" + private int M(params int[] args) { } + + public int Foo() + { + if (true) + return M(1,1); + else + return M(1,2,3); + }".WrapInCSharpClass(); + var fixtest = @" + private int M(params int[] args) { } + + public int Foo() + { + return true?M(1,1):M(1,2,3); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDynamicObjGetsArgsNotApplied() + { + // Calls on dynamic objects get dispatched during runtime. + // Therefore the semantic would be changed if we apply to arguments + // and casting is involved: + // d.M(new A()) else d.M(new B()) -> d.M(cond?(Base)new A():new B()); + // is not the same as cond?d.M(new A()): d.M(new B()) on dynamic objects. + var source = @" + public class Base {} + public class A: Base {} + public class B: Base {} + + public int Foo() + { + dynamic d = new object(); + if (true) + return d.M(new A()); + else + return d.M(new B()); + }".WrapInCSharpClass(); + var fixtest = @" + public class Base {} + public class A: Base {} + public class B: Base {} + + public int Foo() + { + dynamic d = new object(); + return true?d.M(new A()):d.M(new B()); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithMethodOfDynamicObjGetsArgsNeverApplied() + { + // arguments on dynamic method calls are never applied even if it would be save. + // see comments above for why dynamic is dangerous. + var source = @" + public int Foo() + { + dynamic d = new object(); + if (true) + return d.M(1,1); + else + return d.M(1,2); + }".WrapInCSharpClass(); + var fixtest = @" + public int Foo() + { + dynamic d = new object(); + return true?d.M(1,1):d.M(1,2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorGetsArgsApplied() + { + var source = @" + public System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1); + else + return new System.Collections.Generic.List(2); + }".WrapInCSharpClass(); + var fixtest = @" + public System.Collections.Generic.List Foo() + { + return new System.Collections.Generic.List(true?1:2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithIdenticalInitializerGetsArgsApplied() + { + var source = @" + public new System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1) { 1 }; + else + return new System.Collections.Generic.List(2) { 1 }; + }".WrapInCSharpClass(); + var fixtest = @" + public new System.Collections.Generic.List Foo() + { + return new System.Collections.Generic.List(true?1:2) { 1 }; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithDifferentInitializerGetsArgsNotApplied() + { + var source = @" + public System.Collections.Generic.List Foo() + { + if (true) + return new System.Collections.Generic.List(1) { 1 }; + else + return new System.Collections.Generic.List(2) { 1, 2 }; + }".WrapInCSharpClass(); + var fixtest = @" + public System.Collections.Generic.List Foo() + { + return true?new System.Collections.Generic.List(1) { 1 } : new System.Collections.Generic.List(2) { 1, 2 }; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorWithDifferentOverloadsGetArgsNotApplied() + { + var source = @" + public class A + { + public A(int i) { } + public A(string s) { } + } + public A Foo() + { + if (true) + return new A(1); + else + return new A(""1""); + }".WrapInCSharpClass(); + var fixtest = @" + public class A + { + public A(int i) { } + public A(string s) { } + } + public A Foo() + { + return true?new A(1):new A(""1""); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithConstructorOfDifferentObjectsGetArgsNotApplied() + { + var source = @" + public class A + { + public A(int i) { } + } + public class B + { + public B(int i) { } + } + + public Object Foo() + { + if (true) + return new A(1); + else + return new B(2); + }".WrapInCSharpClass(); + var fixtest = @" + public class A + { + public A(int i) { } + } + public class B + { + public B(int i) { } + } + + public Object Foo() + { + return true?(object)new A(1):new B(2); + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task WhenReturnTypeIsAnInterfaceAFittingCastIsInserted() + { + var source = @" + IComparable GetComparable() + { + if (true) + return 1; + else + return ""1""; + }".WrapInCSharpClass(); + var fixtest = @" + IComparable GetComparable() + { + return true?(IComparable)1 : ""1""; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task FixWhenReturningWithReturnTypeIsExplicitConvertable() + { + var source = @" + double GetNumber() + { + if (true) + return 1; + else + return 1.1; + }".WrapInCSharpClass(); + var fixtest = @" + double GetNumber() + { + return true?(double)1:1.1; + }".WrapInCSharpClass(); + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From fe1b3ea9b9548a85d9e4aa2d85006795346f406c Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 21:40:04 -0300 Subject: [PATCH 081/152] Update TernaryOperatorCodeFixProvider.cs to match master branch --- .../Style/TernaryOperatorCodeFixProvider.cs | 98 +++++++++++++++++-- 1 file changed, 91 insertions(+), 7 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs index 3c8c8a9f1..b36fa9584 100644 --- a/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TernaryOperatorCodeFixProvider.cs @@ -10,6 +10,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using System; namespace CodeCracker.CSharp.Style { @@ -37,11 +38,10 @@ private static async Task MakeTernaryAsync(Document document, Diagnost var elseStatement = ifStatement.Else; var returnStatementInsideElse = (ReturnStatementSyntax)(elseStatement.Statement is BlockSyntax ? ((BlockSyntax)elseStatement.Statement).Statements.Single() : elseStatement.Statement); var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - ExpressionSyntax trueExpression, falseExpression; - TernaryOperatorCodeFixHelper.CreateExpressions(returnStatementInsideIf.Expression, returnStatementInsideElse.Expression, semanticModel, out trueExpression, out falseExpression); + var conditionalExpression = TernaryOperatorCodeFixHelper.CreateExpressions(returnStatementInsideIf.Expression, returnStatementInsideElse.Expression, ifStatement.Condition, semanticModel); var ternary = SyntaxFactory.ReturnStatement( - SyntaxFactory.ConditionalExpression(ifStatement.Condition, trueExpression, falseExpression)) + conditionalExpression) .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(ifStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); @@ -76,14 +76,13 @@ private static async Task MakeTernaryAsync(Document document, Diagnost var assignmentExpressionInsideIf = (AssignmentExpressionSyntax)expressionInsideIf.Expression; var assignmentExpressionInsideElse = (AssignmentExpressionSyntax)expressionInsideElse.Expression; var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - ExpressionSyntax trueExpression, falseExpression; - TernaryOperatorCodeFixHelper.CreateExpressions(assignmentExpressionInsideIf.Right, assignmentExpressionInsideElse.Right, semanticModel, out trueExpression, out falseExpression); + var conditionalExpression = TernaryOperatorCodeFixHelper.CreateExpressions(assignmentExpressionInsideIf.Right, assignmentExpressionInsideElse.Right, ifStatement.Condition, semanticModel); var ternary = SyntaxFactory.ExpressionStatement( SyntaxFactory.AssignmentExpression( assignmentExpressionInsideIf.Kind(), assignmentExpressionInsideIf.Left, - SyntaxFactory.ConditionalExpression(ifStatement.Condition, trueExpression, falseExpression))) + conditionalExpression)) .WithLeadingTrivia(ifStatement.GetLeadingTrivia()) .WithTrailingTrivia(ifStatement.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); @@ -95,13 +94,98 @@ private static async Task MakeTernaryAsync(Document document, Diagnost internal static class TernaryOperatorCodeFixHelper { - public static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel, out ExpressionSyntax trueExpression, out ExpressionSyntax falseExpression) + public static ExpressionSyntax CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, ExpressionSyntax ifStatementCondition, SemanticModel semanticModel) + { + + var methodCallArgApplied = TryApplyArgsOnMethodCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (methodCallArgApplied != null) return methodCallArgApplied; + var constructorArgsApplied = TryApplyArgsOnConstructorCalls(ifStatementCondition, ifExpression, elseExpression, semanticModel); + if (constructorArgsApplied != null) return constructorArgsApplied; + var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); + var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); + var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); + ExpressionSyntax trueExpression; ExpressionSyntax falseExpression; + CreateExpressions(ifExpression, elseExpression, ifTypeInfo.Type, elseTypeInfo.Type, + ifTypeInfo.ConvertedType, elseTypeInfo.ConvertedType, typeSyntax, semanticModel, out trueExpression, out falseExpression); + return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); + } + + private static ExpressionSyntax TryApplyArgsOnConstructorCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + { + if (ifExpression is ObjectCreationExpressionSyntax && elseExpression is ObjectCreationExpressionSyntax) + { + var ifObjCreation = ifExpression as ObjectCreationExpressionSyntax; + var elseObjCreation = elseExpression as ObjectCreationExpressionSyntax; + if ((ifObjCreation.Initializer == null && elseObjCreation.Initializer == null) || + ifObjCreation.Initializer != null && elseObjCreation.Initializer != null && + ifObjCreation.Initializer.GetText().ContentEquals(elseObjCreation.Initializer.GetText())) // Initializer are either absent or text equals + { + var ifMethodinfo = semanticModel.GetSymbolInfo(ifObjCreation); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseObjCreation); + if (object.Equals(ifMethodinfo, elseMethodinfo)) //same constructor and overload + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifObjCreation.ArgumentList, elseObjCreation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.ObjectCreationExpression(ifObjCreation.Type, CreateMethodArgumentList(ifStatementCondition, ifObjCreation.ArgumentList, elseObjCreation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel), ifObjCreation.Initializer); + } + } + } + return null; + } + + private static ExpressionSyntax TryApplyArgsOnMethodCalls(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) + { + if (ifExpression is InvocationExpressionSyntax && elseExpression is InvocationExpressionSyntax) + { + var ifInvocation = ifExpression as InvocationExpressionSyntax; + var elseInvocation = elseExpression as InvocationExpressionSyntax; + var ifMethodinfo = semanticModel.GetSymbolInfo(ifInvocation.Expression); + var elseMethodinfo = semanticModel.GetSymbolInfo(elseInvocation.Expression); + if (object.Equals(ifMethodinfo, elseMethodinfo) && ifMethodinfo.CandidateReason != CandidateReason.LateBound) //same method and overload, but not dynamic + { + if (ifInvocation.Expression.GetText().ContentEquals(elseInvocation.Expression.GetText())) //same 'path' to the invocation + { + var findSingleArgumentIndexThatDiffers = FindSingleArgumentIndexThatDiffers(ifInvocation.ArgumentList, elseInvocation.ArgumentList, semanticModel); + if (findSingleArgumentIndexThatDiffers >= 0) + return SyntaxFactory.InvocationExpression(ifInvocation.Expression, CreateMethodArgumentList(ifStatementCondition, ifInvocation.ArgumentList, elseInvocation.ArgumentList, findSingleArgumentIndexThatDiffers, semanticModel)); + } + } + } + return null; + } + + private static ArgumentListSyntax CreateMethodArgumentList(ExpressionSyntax ifStatementCondition, ArgumentListSyntax argList1, ArgumentListSyntax argList2, int argumentIndexThatDiffers, SemanticModel semanticModel) + { + var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); + var argSelector = zipped.Select((args, i) => + (i == argumentIndexThatDiffers) ? + SyntaxFactory.Argument(GetConditionalExpressionForArgument(ifStatementCondition, args.a1.Expression, args.a2.Expression, semanticModel)) + : args.a1); + return SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(argSelector)); + } + + private static ConditionalExpressionSyntax GetConditionalExpressionForArgument(ExpressionSyntax ifStatementCondition, ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, SemanticModel semanticModel) { var ifTypeInfo = semanticModel.GetTypeInfo(ifExpression); var elseTypeInfo = semanticModel.GetTypeInfo(elseExpression); var typeSyntax = SyntaxFactory.IdentifierName(ifTypeInfo.ConvertedType.ToMinimalDisplayString(semanticModel, ifExpression.SpanStart)); + ExpressionSyntax trueExpression; ExpressionSyntax falseExpression; CreateExpressions(ifExpression, elseExpression, ifTypeInfo.Type, elseTypeInfo.Type, ifTypeInfo.ConvertedType, elseTypeInfo.ConvertedType, typeSyntax, semanticModel, out trueExpression, out falseExpression); + return SyntaxFactory.ConditionalExpression(ifStatementCondition, trueExpression, falseExpression); + } + + private static int FindSingleArgumentIndexThatDiffers(ArgumentListSyntax argList1, ArgumentListSyntax argList2, SemanticModel semanticModel) + { + if (argList1.Arguments.Count != argList2.Arguments.Count) return -1; // in case of 'params' + var zipped = argList1.Arguments.Zip(argList2.Arguments, (a1, a2) => new { a1, a2 }).Select((a, i) => new { a.a1, a.a2, i }); + var singleMissmatch = zipped.Where(args => + { + var a1Text = args.a1.GetText(); + var a2Text = args.a2.GetText(); + return !a1Text.ContentEquals(a2Text); + }).Take(2).ToList(); + return (singleMissmatch.Count == 1) ? singleMissmatch[0].i : -1; } private static void CreateExpressions(ExpressionSyntax ifExpression, ExpressionSyntax elseExpression, From a62c6c70f0d5ea7ada3c69b15590363b47766e16 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Fri, 23 Jun 2017 03:34:47 +0200 Subject: [PATCH 082/152] Create reusable strategy for fix all See IFixDocumentInternalsOnly. Also add a fix all provider for ReplaceWithGetterOnlyAutoPropertyCodeFixProvider --- ...thGetterOnlyAutoPropertyCodeFixProvider.cs | 61 +++-- .../CodeCracker.Common.csproj | 2 + .../DocumentCodeFixProviderAll.cs | 98 +++++++++ .../IFixDocumentInternalsOnly.cs | 16 ++ .../ReplaceWithGetterOnlyAutoPropertyTests.cs | 208 +++++++++++++++++- 5 files changed, 358 insertions(+), 27 deletions(-) create mode 100644 src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs create mode 100644 src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs diff --git a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs index d22626bae..d8b59a702 100644 --- a/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/ReplaceWithGetterOnlyAutoPropertyCodeFixProvider.cs @@ -12,15 +12,18 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using System; +using CodeCracker.FixAllProviders; namespace CodeCracker.CSharp.Refactoring { [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(ReplaceWithGetterOnlyAutoPropertyCodeFixProvider)), Shared] - public class ReplaceWithGetterOnlyAutoPropertyCodeFixProvider : CodeFixProvider + public class ReplaceWithGetterOnlyAutoPropertyCodeFixProvider : CodeFixProvider, IFixDocumentInternalsOnly { + private static readonly FixAllProvider FixAllProvider = new DocumentCodeFixProviderAll(Resources.ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title); public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId()); - public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + public override FixAllProvider GetFixAllProvider() => FixAllProvider; public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { @@ -35,19 +38,32 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) diagnostic); return Task.FromResult(0); } - private async static Task ReplaceByGetterOnlyAutoPropertyAsync(Document document, TextSpan propertyDeclarationSpan, CancellationToken cancellationToken) + private async Task ReplaceByGetterOnlyAutoPropertyAsync(Document document, TextSpan propertyDeclarationSpan, CancellationToken cancellationToken) { - var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - var root = await document.GetSyntaxRootAsync(cancellationToken); - var token = root.FindToken(propertyDeclarationSpan.Start); - var property = token.Parent.AncestorsAndSelf().OfType().First(); - var fieldVariableDeclaratorSyntax = await GetFieldDeclarationSyntaxNodeAsync(property, cancellationToken, semanticModel); - if (fieldVariableDeclaratorSyntax == null) return document; - var fieldReferences = await GetFieldReferencesAsync(fieldVariableDeclaratorSyntax, cancellationToken, semanticModel); + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var node = root.FindNode(propertyDeclarationSpan); + return await FixDocumentAsync(node, document, cancellationToken).ConfigureAwait(false); + } + + public async Task FixDocumentAsync(SyntaxNode nodeWithDiagnostic, Document document, CancellationToken cancellationToken) + { + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var semanticModel = await document.GetSemanticModelAsync().ConfigureAwait(false); + var newRoot = await ReplacePropertyInSyntaxRootAsync(nodeWithDiagnostic, cancellationToken, semanticModel, root).ConfigureAwait(false); + var newDocument = document.WithSyntaxRoot(newRoot); + return newDocument; + } + + + private static async Task ReplacePropertyInSyntaxRootAsync(SyntaxNode propertyDeclarationSyntaxNode, CancellationToken cancellationToken, SemanticModel semanticModel, SyntaxNode root) + { + var property = propertyDeclarationSyntaxNode.AncestorsAndSelf().OfType().First(); + var fieldVariableDeclaratorSyntax = await GetFieldDeclarationSyntaxNodeAsync(property, cancellationToken, semanticModel).ConfigureAwait(false); + if (fieldVariableDeclaratorSyntax == null) return root; + var fieldReferences = await GetFieldReferencesAsync(fieldVariableDeclaratorSyntax, cancellationToken, semanticModel).ConfigureAwait(false); var nodesToUpdate = fieldReferences.Cast().Union(Enumerable.Repeat(property, 1)).Union(Enumerable.Repeat(fieldVariableDeclaratorSyntax, 1)); var newRoot = FixWithTrackNode(root, property, fieldVariableDeclaratorSyntax, nodesToUpdate); - var resultDocument = document.WithSyntaxRoot(newRoot); - return resultDocument; + return newRoot; } private static SyntaxNode FixWithTrackNode(SyntaxNode root, PropertyDeclarationSyntax property, VariableDeclaratorSyntax fieldVariableDeclaratorSyntax, IEnumerable nodesToUpdate) @@ -102,16 +118,19 @@ private static async Task> GetFieldReferencesA HashSet fieldReferences = null; var fieldSymbol = semanticModel.GetDeclaredSymbol(fieldDeclarationSyntax, cancellationToken); var declaredInType = fieldSymbol.ContainingType; - var reference = declaredInType.DeclaringSyntaxReferences[0]; - var allNodes = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); - var allFieldReferenceNodes = from n in allNodes.OfType() - where n.Identifier.Text == fieldSymbol.Name - let nodeSymbolInfo = semanticModel.GetSymbolInfo(n, cancellationToken) - where object.Equals(nodeSymbolInfo.Symbol, fieldSymbol) - select n; - foreach (var fieldReference in allFieldReferenceNodes) + var references = declaredInType.DeclaringSyntaxReferences.Where(r => r.SyntaxTree == semanticModel.SyntaxTree); + foreach (var reference in references) { - (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); + var allNodes = (await reference.GetSyntaxAsync(cancellationToken)).DescendantNodes(); + var allFieldReferenceNodes = from n in allNodes.OfType() + where n.Identifier.Text == fieldSymbol.Name + let nodeSymbolInfo = semanticModel.GetSymbolInfo(n, cancellationToken) + where object.Equals(nodeSymbolInfo.Symbol, fieldSymbol) + select n; + foreach (var fieldReference in allFieldReferenceNodes) + { + (fieldReferences ?? (fieldReferences = new HashSet())).Add(fieldReference); + } } return fieldReferences ?? Enumerable.Empty(); } diff --git a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj index f20344f73..34f859b17 100644 --- a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj +++ b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj @@ -40,6 +40,8 @@ + + diff --git a/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs b/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs new file mode 100644 index 000000000..7a885fcef --- /dev/null +++ b/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs @@ -0,0 +1,98 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace CodeCracker.FixAllProviders +{ + + public sealed class DocumentCodeFixProviderAll : FixAllProvider + { + private const string SyntaxAnnotationKey = "DocumentCodeFixProviderAllSyntaxAnnotation"; + + public DocumentCodeFixProviderAll(string codeFixTitle) + { + CodeFixTitle = codeFixTitle; + } + + private string CodeFixTitle { get; } + + public override Task GetFixAsync(FixAllContext fixAllContext) + { + switch (fixAllContext.Scope) + { + case FixAllScope.Document: + return Task.FromResult(CodeAction.Create(CodeFixTitle, + ct => GetFixedDocumentsAsync(fixAllContext, Enumerable.Repeat(fixAllContext.Document, 1)))); + case FixAllScope.Project: + return Task.FromResult(CodeAction.Create(CodeFixTitle, + ct => GetFixedDocumentsAsync(fixAllContext, fixAllContext.Project.Documents))); + case FixAllScope.Solution: + return Task.FromResult(CodeAction.Create(CodeFixTitle, + ct => GetFixedDocumentsAsync(fixAllContext, fixAllContext.Solution.Projects.SelectMany(p => p.Documents)))); + } + return null; + } + + private async static Task GetFixedDocumentsAsync(FixAllContext fixAllContext, IEnumerable documents) + { + var solution = fixAllContext.Solution; + var newDocuments = documents.ToDictionary(d => d.Id, d => GetFixedDocumentAsync(fixAllContext, d)); + await Task.WhenAll(newDocuments.Values).ConfigureAwait(false); + var changedDocuments = from kvp in newDocuments + where kvp.Value.Result != null + select new { DocumentId = kvp.Key, Document = kvp.Value.Result }; + foreach (var newDocument in changedDocuments) + solution = solution.WithDocumentSyntaxRoot(newDocument.DocumentId, await newDocument.Document.GetSyntaxRootAsync().ConfigureAwait(false)); + return solution; + } + + private async static Task GetFixedDocumentAsync(FixAllContext fixAllContext, Document document) + { + var codeFixer = fixAllContext.CodeFixProvider as IFixDocumentInternalsOnly; + if (codeFixer == null) throw new ArgumentException("This CodeFixAllProvider requires that your CodeFixProvider implements the IFixDocumentInternalsOnly."); + var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); + if (diagnostics.Length == 0) return null; + var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); + var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing); + var annotations = new List(); + var newRoot = root.ReplaceNodes(nodes, (original, rewritten) => + { + var annotation = new SyntaxAnnotation(SyntaxAnnotationKey); + annotations.Add(annotation); + var newNode = original.WithAdditionalAnnotations(annotation); + return newNode; + }); + var newDocument = document.WithSyntaxRoot(newRoot); + newDocument = await FixCodeForAnnotatedNodesAsync(newDocument, codeFixer, annotations, fixAllContext.CancellationToken).ConfigureAwait(false); + newDocument = await RemoveAnnontationsAsync(newDocument, annotations).ConfigureAwait(false); + return newDocument; + } + + private static async Task FixCodeForAnnotatedNodesAsync(Document document, IFixDocumentInternalsOnly codeFixer, IEnumerable annotations, CancellationToken cancellationToken) + { + foreach (var annotation in annotations) + { + var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var annotatedNodes = newRoot.GetAnnotatedNodes(annotation); + var node = annotatedNodes.FirstOrDefault(); + if (node == null) continue; + document = await codeFixer.FixDocumentAsync(node, document, cancellationToken).ConfigureAwait(false); + } + return document; + } + + private static async Task RemoveAnnontationsAsync(Document document, IEnumerable annotations) + { + var root = await document.GetSyntaxRootAsync().ConfigureAwait(false); + var nodes = annotations.SelectMany(annotation => root.GetAnnotatedNodes(annotation)); + root = root.ReplaceNodes(nodes, (original, rewritten) => original.WithoutAnnotations(annotations)); + var newDocument = document.WithSyntaxRoot(root); + return newDocument; + } + } +} \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs b/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs new file mode 100644 index 000000000..735c76cfa --- /dev/null +++ b/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs @@ -0,0 +1,16 @@ +using Microsoft.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; + +namespace CodeCracker.FixAllProviders +{ + /// + /// This interface must be implemented by the associated CodeFixProvider. The CodeFixProvider must operate on a single document and + /// should only change the document. This limits the possible operations of the CodeFixProvider to change only document internals without + /// effecting other parts of the solution. + /// + public interface IFixDocumentInternalsOnly + { + Task FixDocumentAsync(SyntaxNode nodeWithDiagnostic, Document document, CancellationToken cancellationToken); + } +} diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs index d7ffc711d..072643c56 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs @@ -430,7 +430,7 @@ class InnerClass { [Fact] public async Task FieldWithSameNameInOtherClassIsNotRenamed() { - var test = @" + const string test = @" using System; namespace App { public class C1 @@ -455,7 +455,7 @@ public class C2 readonly int _A; } }"; - var fixtest = @" + const string fixtest = @" using System; namespace App { public class C1 @@ -510,7 +510,7 @@ public TypeName(int A) } [Fact] - public async Task FieldReferencesInPartialClassesGetNotRenamedAndCasueCompilerErrorCS0103() + public async Task FieldReferencesInPartialClassesGetRenamedIfInTheSameDocument() { const string test = @" namespace A @@ -544,11 +544,10 @@ public A1(int i) } public partial class A1 { - public void Print() => Console.Write(_I); + public void Print() => Console.Write(I); } }"; - //Console.Write(_I); causes CS0103 The name '_I' does not exist in the current context - await VerifyCSharpFixAsync(oldSource: test, newSource: fixtest, allowNewCompilerDiagnostics: true); + await VerifyCSharpFixAsync(oldSource: test, newSource: fixtest, allowNewCompilerDiagnostics: false); } [Fact] @@ -600,5 +599,202 @@ public partial class A1 //Console.Write(_I); causes CS0103 The name '_I' does not exist in the current context await VerifyCSharpFixAllAsync(oldSources: new string[] { testPart1, testPart2 }, newSources: new string[] { fixtestPart1, fixtestPart2 }, allowNewCompilerDiagnostics: true); } + + #region FixAll Tests + + [Fact] + public async Task ReplaceMultiplePropertiesInOneClassFixAllTest() + { + var source1 = @" + readonly int _A; + readonly int _B; + readonly string _C; + + public TypeName(int a, int b, string c) + { + _A=a; + _B=b; + _C=c; + } + public int A { get { return _A; } } + public int B { get { return _B; } } + public string C { get { return _C; } } + ".WrapInCSharpClass(); + var fixtest1 = @" + public TypeName(int a, int b, string c) + { + A=a; + B=b; + C=c; + } + public int A { get; } + public int B { get; } + public string C { get; } + ".WrapInCSharpClass(); + await VerifyCSharpFixAllAsync(new[] { source1 }, new[] { fixtest1 }); + } + + [Fact] + public async Task ReplaceMultiplePropertiesInOneClassInMultipleDocumentsFixAllTest() + { + const string source1 = @" + namespace A + { + public class A1 + { + readonly int _A; + readonly int _B; + readonly string _C; + public A1(int a, int b, string c) + { + _A=a; + _B=b; + _C=c; + } + public int A { get { return _A; } } + public int B { get { return _B; } } + public string C { get { return _C; } } + } + }"; + const string source2 = @" + namespace A + { + public class A2 + { + readonly int _A; + readonly int _B; + readonly string _C; + public A2(int a, int b, string c) + { + _A=a; + _B=b; + _C=c; + } + public int A { get { return _A; } } + public int B { get { return _B; } } + public string C { get { return _C; } } + } + }"; + const string source3 = @" + namespace B + { + public class B1 + { + readonly int _A; + readonly int _B; + readonly string _C; + public B1(int a, int b, string c) + { + _A=a; + _B=b; + _C=c; + } + public int A { get { return _A; } } + public int B { get { return _B; } } + public string C { get { return _C; } } + } + }"; + const string fixtest1 = @" + namespace A + { + public class A1 + { + public A1(int a, int b, string c) + { + A=a; + B=b; + C=c; + } + public int A { get; } + public int B { get; } + public string C { get; } + } + }"; + const string fixtest2 = @" + namespace A + { + public class A2 + { + public A2(int a, int b, string c) + { + A=a; + B=b; + C=c; + } + public int A { get; } + public int B { get; } + public string C { get; } + } + }"; + const string fixtest3 = @" + namespace B + { + public class B1 + { + public B1(int a, int b, string c) + { + A=a; + B=b; + C=c; + } + public int A { get; } + public int B { get; } + public string C { get; } + } + }"; + await VerifyCSharpFixAllAsync(new[] { source1, source2, source3 }, new[] { fixtest1, fixtest2, fixtest3 }); + } + + [Fact] + public async Task ReplaceMultiplePropertiesInOneClassInMultipleDocumentsAndKeepExisitingDocumentsWithoutDiagnosticsFixAllTest() + { + const string source1 = @" + namespace A + { + public class A1 + { + readonly int _A; + readonly int _B; + readonly string _C; + public A1(int a, int b, string c) + { + _A=a; + _B=b; + _C=c; + } + public int A { get { return _A; } } + public int B { get { return _B; } } + public string C { get { return _C; } } + } + }"; + const string source2 = @" + namespace A + { + public class A2 + { + public A2() + { + } + } + }"; + const string fixtest1 = @" + namespace A + { + public class A1 + { + public A1(int a, int b, string c) + { + A=a; + B=b; + C=c; + } + public int A { get; } + public int B { get; } + public string C { get; } + } + }"; + await VerifyCSharpFixAllAsync(new[] { source1, source2 }, new[] { fixtest1, source2 }); + } + #endregion } } \ No newline at end of file From d6d7bdf720d5ddad627d744dcd8dea945b83420b Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Thu, 22 Jun 2017 22:36:58 -0300 Subject: [PATCH 083/152] Fix typo --- .../FixAllProviders/DocumentCodeFixProviderAll.cs | 4 ++-- .../FixAllProviders/IFixDocumentInternalsOnly.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs b/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs index 7a885fcef..255dfc074 100644 --- a/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs +++ b/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs @@ -69,7 +69,7 @@ private async static Task GetFixedDocumentAsync(FixAllContext fixAllCo }); var newDocument = document.WithSyntaxRoot(newRoot); newDocument = await FixCodeForAnnotatedNodesAsync(newDocument, codeFixer, annotations, fixAllContext.CancellationToken).ConfigureAwait(false); - newDocument = await RemoveAnnontationsAsync(newDocument, annotations).ConfigureAwait(false); + newDocument = await RemoveAnnotationsAsync(newDocument, annotations).ConfigureAwait(false); return newDocument; } @@ -86,7 +86,7 @@ private static async Task FixCodeForAnnotatedNodesAsync(Document docum return document; } - private static async Task RemoveAnnontationsAsync(Document document, IEnumerable annotations) + private static async Task RemoveAnnotationsAsync(Document document, IEnumerable annotations) { var root = await document.GetSyntaxRootAsync().ConfigureAwait(false); var nodes = annotations.SelectMany(annotation => root.GetAnnotatedNodes(annotation)); diff --git a/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs b/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs index 735c76cfa..901942669 100644 --- a/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs +++ b/src/Common/CodeCracker.Common/FixAllProviders/IFixDocumentInternalsOnly.cs @@ -13,4 +13,4 @@ public interface IFixDocumentInternalsOnly { Task FixDocumentAsync(SyntaxNode nodeWithDiagnostic, Document document, CancellationToken cancellationToken); } -} +} \ No newline at end of file From 8f48dfea083cf3583b6af449981b9b76a76e0ab4 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sat, 24 Jun 2017 00:12:33 -0300 Subject: [PATCH 084/152] Use latest msbuild --- build.ps1 | 2 +- default.ps1 | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/build.ps1 b/build.ps1 index 821027472..27cd8f2d8 100644 --- a/build.ps1 +++ b/build.ps1 @@ -73,7 +73,7 @@ Get-Nuget Import-Psake Import-ILMerge if ($MyInvocation.UnboundArguments.Count -ne 0) { - Invoke-Expression("Invoke-psake -framework '4.5.2' $PSScriptRoot\default.ps1 -taskList " + $MyInvocation.UnboundArguments -join " ") + Invoke-Expression("Invoke-psake -framework '4.6' $PSScriptRoot\default.ps1 -taskList " + $MyInvocation.UnboundArguments -join " ") } else { . $PSScriptRoot\build.ps1 Build diff --git a/default.ps1 b/default.ps1 index a36f5fad6..aef7b7d5d 100644 --- a/default.ps1 +++ b/default.ps1 @@ -38,6 +38,10 @@ Properties { $isRelease = $isAppVeyor -and (($env:APPVEYOR_REPO_BRANCH -eq "release") -or ($env:APPVEYOR_REPO_TAG -eq "true")) $isPullRequest = $env:APPVEYOR_PULL_REQUEST_NUMBER -ne $null $tempDir = Join-Path "$([System.IO.Path]::GetTempPath())" "CodeCracker" + # msbuild hack necessary until https://github.com/psake/psake/issues/201 is fixed: + $msbuild64 = Resolve-Path "$(if (${env:ProgramFiles(x86)}) { ${env:ProgramFiles(x86)} } else { $env:ProgramFiles } )\Microsoft Visual Studio\2017\*\MSBuild\15.0\Bin\msbuild.exe" + $msbuild32 = Resolve-Path "$(if (${env:ProgramFiles(x86)}) { ${env:ProgramFiles(x86)} } else { $env:ProgramFiles } )\Microsoft Visual Studio\2017\*\MSBuild\15.0\Bin\msbuild.exe" + $msbuild = if ($msbuild64) { $msbuild64 } else { $msbuild32 } } FormatTaskName (("-"*25) + "[{0}]" + ("-"*25)) @@ -62,17 +66,17 @@ Task Build-Only -depends Build-Only-CS, Build-Only-VB Task Build-Only-CS -depends Build-MSBuild-CS, ILMerge-CS Task Build-MSBuild-CS { if ($isAppVeyor) { - Exec { msbuild $solutionFileCS /m /verbosity:minimal /p:Configuration=ReleaseNoVsix /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" } + Exec { . $msbuild $solutionFileCS /m /verbosity:minimal /p:Configuration=ReleaseNoVsix /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" } } else { - Exec { msbuild $solutionFileCS /m /verbosity:minimal /p:Configuration=ReleaseNoVsix } + Exec { . $msbuild $solutionFileCS /m /verbosity:minimal /p:Configuration=ReleaseNoVsix } } } Task Build-Only-VB -depends Build-MSBuild-VB, ILMerge-VB Task Build-MSBuild-VB { if ($isAppVeyor) { - Exec { msbuild $solutionFileVB /m /verbosity:minimal /p:Configuration=ReleaseNoVsix /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" } + Exec { . $msbuild $solutionFileVB /m /verbosity:minimal /p:Configuration=ReleaseNoVsix /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" } } else { - Exec { msbuild $solutionFileVB /m /verbosity:minimal /p:Configuration=ReleaseNoVsix } + Exec { . $msbuild $solutionFileVB /m /verbosity:minimal /p:Configuration=ReleaseNoVsix } } } @@ -120,8 +124,8 @@ function Change-Extension ($filename, $extension) { } Task Clean { - Exec { msbuild $solutionFileCS /t:Clean /v:quiet } - Exec { msbuild $solutionFileVB /t:Clean /v:quiet } + Exec { . $msbuild $solutionFileCS /t:Clean /v:quiet } + Exec { . $msbuild $solutionFileVB /t:Clean /v:quiet } } Task Set-Log { From 6de6d0745daf942454555887939e900cd54cf228 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Sat, 24 Jun 2017 05:35:29 +0200 Subject: [PATCH 085/152] Fix bug for CC0118 Remove to string The string is only removed if safe to do. Fixes #866. Implemented option 2 as requested in #866. This fix now looks up the types of both sides of the plus operator and tries removes those candidates, that might break things. It turned out, that some of the checks in CheckAddOperationOverloadsOfTypes are not needed (After the second check every other check returns false). Essentially right now the removal of "ToString" is only save if either the underlying type is a string (as in 1 + "a".ToString()) or the type on the other side of the plus operator is a string (as in "a" + 1.ToString()). I kept all the other checks for future enhancements to make clear that there are several cases to consider. Further I added lots of unit tests to cover these cases. The idea is that CheckAddOperationOverloadsOfTypes can easily be expanded in the future to support more cases without breaking anything. Those redundant checks are also very cheap and are essentially just simple comparisons. --- ...ryToStringInStringConcatenationAnalyzer.cs | 132 +++++++++++++- ...ssaryToStringInStringConcatenationTests.cs | 170 ++++++++++++++++-- 2 files changed, 288 insertions(+), 14 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs index d2c56f355..23fa9dcbe 100644 --- a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs @@ -3,9 +3,11 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Text; +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using System.Threading; namespace CodeCracker.CSharp.Style { @@ -45,7 +47,9 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) if (!hasInvocationExpression) return; var invocationExpressionsThatHaveToStringCall = GetInvocationExpressionsThatHaveToStringCall(addExpression); - foreach (var expression in invocationExpressionsThatHaveToStringCall) + var redundantToStringCalls = FilterInvocationsThatAreRedundant(invocationExpressionsThatHaveToStringCall, addExpression, context.SemanticModel, context.CancellationToken); + + foreach (var expression in redundantToStringCalls) { var lastDot = expression.Expression.ChildNodesAndTokens().Last(x => x.IsKind(SyntaxKind.DotToken)); var toStringTextSpan = new TextSpan(lastDot.Span.Start, expression.ArgumentList.Span.End - lastDot.Span.Start); @@ -60,5 +64,131 @@ private static IEnumerable GetInvocationExpressionsT //Only default call to ToString method must be accepted .Where(x => x.Expression.ToString().EndsWith(@".ToString") && !x.ArgumentList.Arguments.Any()); } + + private static IEnumerable FilterInvocationsThatAreRedundant(IEnumerable invocationExpressionsThatHaveToStringCall, BinaryExpressionSyntax addExpression, SemanticModel semanticModel, CancellationToken cancellationToken) + { + foreach (var node in invocationExpressionsThatHaveToStringCall) + { + var toStringReceiver = GetTypeInfoOfReceiverOfToStringCall(node, semanticModel, cancellationToken); + //As long as the underlying type can not be resolved by the compiler (e.g. undefined type) + //removal is not save. + if (toStringReceiver == null || toStringReceiver.TypeKind==TypeKind.Error) + continue; + //If the underlying type is string, removal is save. + if (IsTypeSymbolSystem_String(toStringReceiver)) + yield return node; + var otherType = GetTypeInfoOfOtherNode(node, addExpression, semanticModel, cancellationToken); + if (otherType != null) + { + if (CheckAddOperationOverloadsOfTypes(toStringReceiver, otherType)) + { + yield return node; + } + } + } + } + + private static ITypeSymbol GetTypeInfoOfReceiverOfToStringCall(InvocationExpressionSyntax toStringCall, SemanticModel semanticModel, CancellationToken cancellationToken) + { + if (toStringCall.Expression is MemberAccessExpressionSyntax memberAccess) + { + return semanticModel.GetTypeInfo(memberAccess.Expression, cancellationToken).Type; + } + + return null; + } + + private static ITypeSymbol GetTypeInfoOfOtherNode(SyntaxNode toStringNode, BinaryExpressionSyntax addExpression, SemanticModel semanticModel, CancellationToken cancellationToken) + { + var otherNode = addExpression.Left == toStringNode + ? addExpression.Right + : addExpression.Right == toStringNode + ? addExpression.Left + : null; + if (otherNode != null) + { + return semanticModel.GetTypeInfo(otherNode, cancellationToken).Type; + } + + return null; + } + + private static bool CheckAddOperationOverloadsOfTypes(ITypeSymbol toStringReceiver, ITypeSymbol otherType) + { + //If the underlying type has a custom AddOperator this operator will take precedence over everything else + if (HasTypeCustomAddOperator(toStringReceiver)) + { + return false; + } + + //If the other side is a string the string concatenation will be applied and "ToString" will be implicit called by the concatenation operator + if (IsTypeSymbolSystem_String(otherType)) + { + return true; + } + + //If the underlying type is one of the build in types (numeric, datetime and so on) and the other side is not a string, + //the result a removal is hard to predict and might be wrong. + if (HasAdditionOperator(toStringReceiver)) + { + return false; + } + + //If both sides are delegates, the plus operator combines the delegates: + //https://msdn.microsoft.com/en-us/library/ms173175(v=vs.110).aspx + if (IsTypeSmybolDelegateType(toStringReceiver) && IsTypeSmybolDelegateType(otherType)) + { + return false; + } + + //There might be more cases were removal is save but for now we opt out. + return false; + } + + private static bool IsTypeSmybolDelegateType(ITypeSymbol typeSymbol) + => typeSymbol.TypeKind == TypeKind.Delegate; + + private static bool IsTypeSymbolSystem_String(ITypeSymbol typeSymbol) + => typeSymbol.SpecialType == SpecialType.System_String; + + + // see https://stackoverflow.com/a/41223159 + private static bool HasAdditionOperator(ITypeSymbol type) + { + switch (type.SpecialType) + { + case SpecialType.System_Enum: + case SpecialType.System_Boolean: + case SpecialType.System_Char: + case SpecialType.System_SByte: + case SpecialType.System_Byte: + case SpecialType.System_Int16: + case SpecialType.System_UInt16: + case SpecialType.System_Int32: + case SpecialType.System_UInt32: + case SpecialType.System_Int64: + case SpecialType.System_UInt64: + case SpecialType.System_Decimal: + case SpecialType.System_Single: + case SpecialType.System_Double: + //String has an addition operator but we are looking for types other than string with an addition overload. + //case SpecialType.System_String: + case SpecialType.System_IntPtr: + case SpecialType.System_UIntPtr: + case SpecialType.System_DateTime: + return true; + } + if (type.TypeKind == TypeKind.Enum) + { + return true; + } + return false; + } + + private static bool HasTypeCustomAddOperator(ITypeSymbol type) + { + var customAdditionOperators = type.GetMembers("op_Addition").OfType(); + return customAdditionOperators.Any(ms => ms.MethodKind == MethodKind.UserDefinedOperator); + } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs b/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs index 077f095e7..d6073bcad 100644 --- a/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs @@ -7,6 +7,19 @@ namespace CodeCracker.Test.CSharp.Style { public class UnnecessaryToStringInStringConcatenationTests : CodeFixVerifier { + private static DiagnosticResult CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(int expectedRow, int expectedColumn) + { + var expected = new DiagnosticResult + { + Id = DiagnosticId.UnnecessaryToStringInStringConcatenation.ToDiagnosticId(), + Message = "Unnecessary '.ToString()' call in string concatenation.", + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", expectedRow, expectedColumn) } + }; + + return expected; + } + [Fact] public async Task InstantiatingAnObjectAndCallToStringInsideAStringConcatenationShouldGenerateDiagnosticResult() { @@ -20,9 +33,9 @@ public async Task InstantiatingAnObjectAndCallToStringInsideAStringConcatenation [Fact] public async Task InstantiatingAnStringBuilderAndCallToStringInsideAStringConcatenationShouldGenerateDiagnosticResult() { - const string source = @"var foo = ""a"" + new System.Text.StringBuilder().ToString();"; + var source = @"var foo = ""a"" + new System.Text.StringBuilder().ToString();".WrapInCSharpMethod(); - var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(1, 48); + var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(10, 64); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -37,9 +50,9 @@ namespace ConsoleApplication1 { class AuxClass { - public override void ToString() + public override string ToString() { - return ""Test""; + return ""Test""; } } @@ -51,7 +64,7 @@ public void Foo() var bar = ""a"" + new AuxClass().ToString(); var foo = ""a"" + auxClass.ToString(); - var far = ""a"" + new AuxClass().ToString() + auxClass.ToString() + new object().ToString(""C""); + var far = ""a"" + new AuxClass().ToString() + auxClass.ToString() + new int().ToString(""C""); } } }"; @@ -66,6 +79,35 @@ public void Foo() await VerifyCSharpDiagnosticAsync(test, expected); } + [Fact] + public async Task CallToStringOnStringExpressionsShouldGenerateDiagnosticResult() + { + const string test = @"var t1 = (true ? ""1"" : ""2"") + new object().ToString();"; + + var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(1, 43); + + await VerifyCSharpDiagnosticAsync(test, expected); + } + + [Fact] + public async Task CallToStringFollowedByACallToAStringMethodShouldNotGenerateDiagnosticResult() + { + const string source = @"var salary = ""salary: "" + 1000.ToString().Trim();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task CallToLambdaNamedToStringShouldNotGenerateDiagnosticResult() + { + var source = @" + Func ToString = () => ""Dummy""; + var t = 1 + ToString(); + ".WrapInCSharpMethod(); + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + [Fact] public async Task CallToStringInsideAStringConcatenationWithAFormatParameterShouldNotGenerateDiagnosticResult() { @@ -83,18 +125,120 @@ public async Task CallToStringOutsideAStringConcatenationWithoutParameterShouldN await VerifyCSharpHasNoDiagnosticsAsync(source); } + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_NumericAddition_RightSide() + { + const string source = @"var value = 1 + 2.ToString();"; - private static DiagnosticResult CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(int expectedRow, int expectedColumn) + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_NumericAddition_LeftSide() { - var expected = new DiagnosticResult + const string source = @"var value = 2.ToString() + 1;"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_NumericAddition_WithExpression() + { + const string source = @"var value = (1 + 1) + 2.ToString();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_NumericAddition_Double() + { + const string source = @"var value = (true ? 1.1 : 0.99) + 2.ToString();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_NumericAddition_DateTime() + { + const string source = @"var value = new System.DateTime(2000, 1, 1) + 2.ToString();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_CompilerGeneratedEnumOperator() + { + const string source = @"var value = System.AttributeTargets.Assembly + System.AttributeTargets.Module.ToString();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_UnderlyingTypeDoesntHaveAddOperatorOverload() + { + const string source = @"var value = new System.Random() + new System.Random().ToString();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_UserDefinedOperator() + { + const string source = @" + namespace A + { + public class C1 + { + public static string operator +(C1 c, object o) => ""Dummy""; + } + + public class C2 + { + public void M() { - Id = DiagnosticId.UnnecessaryToStringInStringConcatenation.ToDiagnosticId(), - Message = "Unnecessary '.ToString()' call in string concatenation.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", expectedRow, expectedColumn) } - }; + var t = new C1().ToString() + ""a""; + } + } + } +"; - return expected; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfOtherOverloadsTakePrecedence_DelegateCombination() + { + var source = @" + var ea1 = new System.EventHandler((o, e) => { }); + var ea2 = new System.EventHandler((o, e) => { }); + var t = ea1 + ea2.ToString(); + ".WrapInCSharpMethod(); + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfTheTypesOfTheOperationAreNotResovable_ToStringReceiver() + { + const string source = @"var t = new UndefinedType().ToString() + ""a"""; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfTheTypesOfTheOperationAreNotResovable_OtherSide() + { + const string source = @"var t = 1.ToString() + new UndefinedType();"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task AStringConcatinationShouldNotBeRemovedIfTheTypesOfTheOperationAreNotResovable_SyntaxError() + { + const string source = @"var t = new System.Random().ToString() + new ThisIsAnSyntaxError"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); } [Fact] From 155634dae288bb7dafa2af7a7e82047d97d28983 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 28 Jun 2017 01:48:29 +0200 Subject: [PATCH 086/152] Use default fixall for IntroduceFieldFromConstructor/CC0071 From #940. --- src/CSharp/CodeCracker/CodeCracker.csproj | 1 - .../IntroduceFieldFromConstructorAnalyzer.cs | 9 ++- ...duceFieldFromConstructorCodeFixProvider.cs | 25 +++++-- ...eFieldFromConstructorCodeFixProviderAll.cs | 73 ------------------- .../Properties/Resources.Designer.cs | 45 ++++++++++++ .../Properties/Resources.resx | 15 ++++ 6 files changed, 83 insertions(+), 85 deletions(-) delete mode 100644 src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProviderAll.cs diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index ea63f7981..715a8f4ac 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -74,7 +74,6 @@ - diff --git a/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorAnalyzer.cs index 91562e3db..7b20fe932 100644 --- a/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorAnalyzer.cs +++ b/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorAnalyzer.cs @@ -1,4 +1,5 @@ -using Microsoft.CodeAnalysis; +using CodeCracker.Properties; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; @@ -11,10 +12,10 @@ namespace CodeCracker.CSharp.Refactoring [DiagnosticAnalyzer(LanguageNames.CSharp)] public class IntroduceFieldFromConstructorAnalyzer : DiagnosticAnalyzer { - internal const string Title = "Consider introduce field for constructor parameters."; - internal const string MessageFormat = "Introduce a field for parameter: {0}"; internal const string Category = SupportedCategories.Refactoring; - const string Description = "Consider introduce field for constructor parameters."; + internal static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.IntroduceFieldFromConstructorAnalyzer_Title), Resources.ResourceManager, typeof(Resources)); + internal static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.IntroduceFieldFromConstructorAnalyzer_Description), Resources.ResourceManager, typeof(Resources)); + internal static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.IntroduceFieldFromConstructorAnalyzer_MessageFormat), Resources.ResourceManager, typeof(Resources)); internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.IntroduceFieldFromConstructor.ToDiagnosticId(), diff --git a/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProvider.cs index 085196f21..9351d73b9 100644 --- a/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProvider.cs @@ -1,3 +1,5 @@ +using CodeCracker.FixAllProviders; +using CodeCracker.Properties; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; @@ -14,12 +16,14 @@ namespace CodeCracker.CSharp.Refactoring { [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(IntroduceFieldFromConstructorCodeFixProvider)), Shared] - public class IntroduceFieldFromConstructorCodeFixProvider : CodeFixProvider + public sealed class IntroduceFieldFromConstructorCodeFixProvider : CodeFixProvider, IFixDocumentInternalsOnly { + private static readonly FixAllProvider FixAllProvider = new DocumentCodeFixProviderAll(Resources.IntroduceFieldFromConstructorCodeFixProvider_Title); + private static readonly string MessageFormat = Resources.IntroduceFieldFromConstructorCodeFixProvider_MessageFormat; + public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.IntroduceFieldFromConstructor.ToDiagnosticId()); - public readonly static string MessageFormat = "Introduce field: {0} from constructor."; - public sealed override FixAllProvider GetFixAllProvider() => IntroduceFieldFromConstructorCodeFixAllProvider.Instance; + public sealed override FixAllProvider GetFixAllProvider() => FixAllProvider; public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { @@ -29,17 +33,24 @@ public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.FromResult(0); } - public async static Task IntroduceFieldFromConstructorDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) + public async Task FixDocumentAsync(SyntaxNode nodeWithDiagnostic, Document document, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - var diagnosticSpan = diagnostic.Location.SourceSpan; - var parameter = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); - var constructor = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); + var parameter = nodeWithDiagnostic.AncestorsAndSelf().OfType().First(); + var constructor = nodeWithDiagnostic.AncestorsAndSelf().OfType().First(); var newRoot = IntroduceFieldFromConstructor(root, constructor, parameter); var newDocument = document.WithSyntaxRoot(newRoot); return document.WithSyntaxRoot(newRoot); } + public async Task IntroduceFieldFromConstructorDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) + { + var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var diagnosticSpan = diagnostic.Location.SourceSpan; + var nodeWithDiagnostic = root.FindToken(diagnosticSpan.Start).Parent; + return await FixDocumentAsync(nodeWithDiagnostic, document, cancellationToken); + } + public static SyntaxNode IntroduceFieldFromConstructor(SyntaxNode root, ConstructorDeclarationSyntax constructorStatement, ParameterSyntax parameter) { // There are no constructors in interfaces, therefore all types remaining type (class and struct) are fine. diff --git a/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProviderAll.cs b/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProviderAll.cs deleted file mode 100644 index 81d29b07e..000000000 --- a/src/CSharp/CodeCracker/Refactoring/IntroduceFieldFromConstructorCodeFixProviderAll.cs +++ /dev/null @@ -1,73 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CodeActions; -using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using System.Linq; -using System.Threading.Tasks; - -namespace CodeCracker.CSharp.Refactoring -{ - public sealed class IntroduceFieldFromConstructorCodeFixAllProvider : FixAllProvider - { - private static readonly SyntaxAnnotation introduceFieldAnnotation = new SyntaxAnnotation(nameof(IntroduceFieldFromConstructorCodeFixAllProvider)); - private IntroduceFieldFromConstructorCodeFixAllProvider() { } - public static readonly IntroduceFieldFromConstructorCodeFixAllProvider Instance = new IntroduceFieldFromConstructorCodeFixAllProvider(); - - public override Task GetFixAsync(FixAllContext fixAllContext) - { - switch (fixAllContext.Scope) - { - case FixAllScope.Document: - return Task.FromResult(CodeAction.Create(IntroduceFieldFromConstructorCodeFixProvider.MessageFormat, - async ct => fixAllContext.Document.WithSyntaxRoot(await GetFixedDocumentAsync(fixAllContext, fixAllContext.Document)))); - case FixAllScope.Project: - return Task.FromResult(CodeAction.Create(IntroduceFieldFromConstructorCodeFixProvider.MessageFormat, - ct => GetFixedProjectAsync(fixAllContext, fixAllContext.Project))); - case FixAllScope.Solution: - return Task.FromResult(CodeAction.Create(IntroduceFieldFromConstructorCodeFixProvider.MessageFormat, - ct => GetFixedSolutionAsync(fixAllContext))); - } - return null; - } - - private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) - { - var newSolution = fixAllContext.Solution; - foreach (var projectId in newSolution.ProjectIds) - newSolution = await GetFixedProjectAsync(fixAllContext, newSolution.GetProject(projectId)).ConfigureAwait(false); - return newSolution; - } - - private async static Task GetFixedProjectAsync(FixAllContext fixAllContext, Project project) - { - var solution = project.Solution; - var newDocuments = project.Documents.ToDictionary(d => d.Id, d => GetFixedDocumentAsync(fixAllContext, d)); - await Task.WhenAll(newDocuments.Values).ConfigureAwait(false); - foreach (var newDoc in newDocuments) - solution = solution.WithDocumentSyntaxRoot(newDoc.Key, newDoc.Value.Result); - return solution; - } - - private async static Task GetFixedDocumentAsync(FixAllContext fixAllContext, Document document) - { - var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false); - var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); - var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing); - var newRoot = root.ReplaceNodes(nodes, (original, rewritten) => original.WithAdditionalAnnotations(introduceFieldAnnotation)); - var semanticModel = await document.GetSemanticModelAsync(fixAllContext.CancellationToken).ConfigureAwait(false); - while (true) - { - var annotatedNodes = newRoot.GetAnnotatedNodes(introduceFieldAnnotation); - var node = annotatedNodes.FirstOrDefault(); - if (node == null) break; - - var constructorMethod = (ConstructorDeclarationSyntax)node.Parent.Parent; - var parameter = (ParameterSyntax)node; - newRoot = IntroduceFieldFromConstructorCodeFixProvider.IntroduceFieldFromConstructor(newRoot, constructorMethod, parameter); - node = newRoot.GetAnnotatedNodes(introduceFieldAnnotation).First(); - newRoot = newRoot.ReplaceNode(node, node.WithoutAnnotations(introduceFieldAnnotation)); - } - return newRoot; - } - } -} diff --git a/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs b/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs index 318839da0..17f3ec989 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs +++ b/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs @@ -214,6 +214,51 @@ public static string InconsistentAccessibilityInPropertyType_Title { } } + /// + /// Sucht eine lokalisierte Zeichenfolge, die Consider introduce field for constructor parameters. ähnelt. + /// + public static string IntroduceFieldFromConstructorAnalyzer_Description { + get { + return ResourceManager.GetString("IntroduceFieldFromConstructorAnalyzer_Description", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Introduce a field for parameter: {0} ähnelt. + /// + public static string IntroduceFieldFromConstructorAnalyzer_MessageFormat { + get { + return ResourceManager.GetString("IntroduceFieldFromConstructorAnalyzer_MessageFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Consider introduce field for constructor parameters. ähnelt. + /// + public static string IntroduceFieldFromConstructorAnalyzer_Title { + get { + return ResourceManager.GetString("IntroduceFieldFromConstructorAnalyzer_Title", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Introduce field: {0} from constructor. ähnelt. + /// + public static string IntroduceFieldFromConstructorCodeFixProvider_MessageFormat { + get { + return ResourceManager.GetString("IntroduceFieldFromConstructorCodeFixProvider_MessageFormat", resourceCulture); + } + } + + /// + /// Sucht eine lokalisierte Zeichenfolge, die Introduce fields for constructor parameters. ähnelt. + /// + public static string IntroduceFieldFromConstructorCodeFixProvider_Title { + get { + return ResourceManager.GetString("IntroduceFieldFromConstructorCodeFixProvider_Title", resourceCulture); + } + } + /// /// Sucht eine lokalisierte Zeichenfolge, die Make method non async ähnelt. /// diff --git a/src/Common/CodeCracker.Common/Properties/Resources.resx b/src/Common/CodeCracker.Common/Properties/Resources.resx index accb497bd..aab3eb4fd 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.resx +++ b/src/Common/CodeCracker.Common/Properties/Resources.resx @@ -228,4 +228,19 @@ Simplify by using an getter-only auto-property + + Consider introduce field for constructor parameters. + + + Introduce a field for parameter: {0} + + + Consider introduce field for constructor parameters. + + + Introduce field: {0} from constructor. + + + Introduce fields for constructor parameters. + \ No newline at end of file From 7d7391c3c8ece06feaeb4910077fa649edcf9e09 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Wed, 28 Jun 2017 01:53:17 +0200 Subject: [PATCH 087/152] Added support for constructors in UseInvokeMethodToFireEventAnalyzer From #942. --- .../UseInvokeMethodToFireEventAnalyzer.cs | 2 +- .../Design/UseInvokeMethodToFireEventTests.cs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker/Design/UseInvokeMethodToFireEventAnalyzer.cs b/src/CSharp/CodeCracker/Design/UseInvokeMethodToFireEventAnalyzer.cs index 1ae8992d4..6a30e2533 100644 --- a/src/CSharp/CodeCracker/Design/UseInvokeMethodToFireEventAnalyzer.cs +++ b/src/CSharp/CodeCracker/Design/UseInvokeMethodToFireEventAnalyzer.cs @@ -62,7 +62,7 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) private static bool HasCheckForNullThatReturns(InvocationExpressionSyntax invocation, SemanticModel semanticModel, ISymbol symbol) { - var method = invocation.FirstAncestorOfKind(SyntaxKind.MethodDeclaration) as MethodDeclarationSyntax; + var method = invocation.FirstAncestorOfKind(SyntaxKind.MethodDeclaration, SyntaxKind.ConstructorDeclaration) as BaseMethodDeclarationSyntax; if (method != null && method.Body != null) { var ifs = method.Body.Statements.OfKind(SyntaxKind.IfStatement); diff --git a/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs b/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs index 0ff013093..f392107bc 100644 --- a/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs @@ -1134,6 +1134,23 @@ public void Bar() { var b = _filter != null && _filter(); } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(test.WrapInCSharpClass()); + } + + [Fact] + public async void IgnoreIfInConstructorAndThatCheckedForNotNull() + { + //https://github.com/code-cracker/code-cracker/issues/926 + const string test = @" +public class Foo +{ + public Foo(System.Action action) + { + if (action == null) + throw new System.ArgumentNullException(); + action(); + } }"; await VerifyCSharpHasNoDiagnosticsAsync(test.WrapInCSharpClass()); } From 4f5cd46f8e61009c5ae7cd6a91506bf1b6e81d3e Mon Sep 17 00:00:00 2001 From: baks Date: Thu, 31 Mar 2016 21:13:45 +0200 Subject: [PATCH 088/152] PropertyChangedEventArgs unnecessary allocation CodeFix provider & analyzer --- src/CSharp/CodeCracker/CodeCracker.csproj | 2 + ...dEventArgsUnnecessaryAllocationAnalyzer.cs | 244 ++++++++++++++ ...rgsUnnecessaryAllocationCodeFixProvider.cs | 93 +++++ src/Common/CodeCracker.Common/DiagnosticId.cs | 1 + .../Properties/Resources.Designer.cs | 144 +++++--- .../Properties/Resources.fr.resx | 12 + .../Properties/Resources.resx | 12 + .../CodeCracker.Test/CodeCracker.Test.csproj | 2 + ...tArgsUnnecessaryAllocationAnalyzerTests.cs | 169 ++++++++++ ...necessaryAllocationCodeFixProviderTests.cs | 318 ++++++++++++++++++ 10 files changed, 943 insertions(+), 54 deletions(-) create mode 100644 src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs create mode 100644 src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs create mode 100644 test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs create mode 100644 test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index 715a8f4ac..22c6e50a0 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -69,6 +69,8 @@ + + diff --git a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs new file mode 100644 index 000000000..b1a15bf7f --- /dev/null +++ b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs @@ -0,0 +1,244 @@ +using System; +using System.Collections.Immutable; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using CodeCracker.Properties; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; + +using static Microsoft.CodeAnalysis.CSharp.SyntaxFacts; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static Microsoft.CodeAnalysis.CSharp.SyntaxKind; + +namespace CodeCracker.CSharp.Refactoring +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class PropertyChangedEventArgsUnnecessaryAllocationAnalyzer : DiagnosticAnalyzer + { + private const string PropertyChangedEventArgsClassName = "PropertyChangedEventArgs"; + + internal const string Category = SupportedCategories.Refactoring; + + private static readonly IdentifierExtractor ExtractIdentifier = new IdentifierExtractor(); + private static readonly IsArgumentALiteralOrNameof IsAnyArgumentLiteralOrNameof = new IsArgumentALiteralOrNameof(); + + internal static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.PropertyChangedEventArgsUnnecessaryAllocation_Title), Resources.ResourceManager, typeof(Resources)); + internal static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.PropertyChangedEventArgsUnnecessaryAllocation_Description), Resources.ResourceManager, typeof(Resources)); + internal static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.PropertyChangedEventArgsUnnecessaryAllocation_MessageFormat), Resources.ResourceManager, typeof(Resources)); + + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( + DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId(), + Title, + MessageFormat, + Category, + DiagnosticSeverity.Hidden, + isEnabledByDefault: true, + description: Description, + helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation)); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) + { + context.RegisterSyntaxNodeAction(LanguageVersion.CSharp6, PropertyChangedCreation, SyntaxKind.ObjectCreationExpression); + } + + private static void PropertyChangedCreation(SyntaxNodeAnalysisContext context) + { + var propertyChangedEventArgsCreationExpr = (ObjectCreationExpressionSyntax) context.Node; + var identifier = propertyChangedEventArgsCreationExpr.Type.Accept(ExtractIdentifier); + if (ShouldReportDiagnostic(propertyChangedEventArgsCreationExpr, identifier.ValueText)) + { + var data = new PropertyChangedEventArgsAnalyzerData(propertyChangedEventArgsCreationExpr); + + context.ReportDiagnostic(Diagnostic.Create(Rule, propertyChangedEventArgsCreationExpr.GetLocation(), data.ToDiagnosticProperties())); + } + } + + private static bool ShouldReportDiagnostic(ObjectCreationExpressionSyntax propertyChangedExpr, + string identifierName) => + IsPropertyChangedEventArgs(identifierName) + && propertyChangedExpr.ArgumentList.Accept(IsAnyArgumentLiteralOrNameof) + && !IsAlreadyStatic(propertyChangedExpr); + + private static bool IsPropertyChangedEventArgs(string s) + => string.Equals(PropertyChangedEventArgsClassName, s, StringComparison.Ordinal); + + private static bool IsAlreadyStatic(ObjectCreationExpressionSyntax objectCreationExpr) + { + var result = false; + var memberForObjectCreationExpr = objectCreationExpr.FirstAncestorOrSelfThatIsAMember(); + switch (memberForObjectCreationExpr.Kind()) + { + case SyntaxKind.ConstructorDeclaration: + var constructorDeclaration = (ConstructorDeclarationSyntax) memberForObjectCreationExpr; + result = ContainsStaticModifier(constructorDeclaration.Modifiers); + break; + case SyntaxKind.FieldDeclaration: + var fieldDeclaration = (FieldDeclarationSyntax)memberForObjectCreationExpr; + result = ContainsStaticModifier(fieldDeclaration.Modifiers); + break; + } + return result; + } + + private static bool ContainsStaticModifier(SyntaxTokenList modifiers) => modifiers.Any(StaticKeyword); + + private class IdentifierExtractor : CSharpSyntaxVisitor + { + public override SyntaxToken VisitIdentifierName(IdentifierNameSyntax node) => node.Identifier; + public override SyntaxToken VisitQualifiedName(QualifiedNameSyntax node) => VisitIdentifierName((IdentifierNameSyntax)node.Right); + } + + private class IsArgumentALiteralOrNameof : CSharpSyntaxVisitor + { + public override bool VisitArgumentList(ArgumentListSyntax node) => node.Arguments.Any(arg => arg.Accept(this)); + public override bool VisitArgument(ArgumentSyntax node) => node.Expression.Accept(this); + public override bool VisitLiteralExpression(LiteralExpressionSyntax node) => true; + + public override bool VisitIdentifierName(IdentifierNameSyntax node) + => string.Equals("nameof", node.Identifier.ValueText, StringComparison.Ordinal); + + public override bool VisitInvocationExpression(InvocationExpressionSyntax node) => node.Expression.Accept(this); + } + } + + public class PropertyChangedEventArgsAnalyzerData + { + private const string ArgumentKeyName = "Argument"; + private const string IsNullKeyName = "IsNull"; + private const string IsNameofKeyName = "NameOf"; + private const string TypeKeyName = "Type"; + private const string SuffixAllProperties = "AllProperties"; + + public readonly string FullTypeName; + public readonly string ArgumentName; + public readonly bool ArgumentIsNullLiteral; + public readonly bool ArgumentIsNameofExpression; + public readonly string StaticFieldIdentifierNameProposition; + + private PropertyChangedEventArgsAnalyzerData(string fullTypeName, string argumentName, string isNullLiteral, string isNameof) + { + this.FullTypeName = fullTypeName; + this.ArgumentName = argumentName ?? string.Empty; + this.ArgumentIsNullLiteral = bool.Parse(isNullLiteral); + this.ArgumentIsNameofExpression = bool.Parse(isNameof); + + this.StaticFieldIdentifierNameProposition = $"PropertyChangedEventArgsFor{SuffixForStaticInstance()}"; + } + + public PropertyChangedEventArgsAnalyzerData(ObjectCreationExpressionSyntax propertyChangedInstanceCreationExpr) + { + if (propertyChangedInstanceCreationExpr == null) + { + throw new ArgumentNullException(nameof(propertyChangedInstanceCreationExpr)); + } + + var analyzer = new PropertyChangedCreationSyntaxAnalyzer(); + propertyChangedInstanceCreationExpr.ArgumentList.Accept(analyzer); + + this.FullTypeName = propertyChangedInstanceCreationExpr.Type.ToString(); + this.ArgumentName = analyzer.IdentifierName; + this.ArgumentIsNullLiteral = analyzer.NullLiteralExpressionFound; + this.ArgumentIsNameofExpression = analyzer.NameofExpressionFound; + } + + public string StaticFieldIdentifierName(IEnumerable nameHints) => nameHints.Contains(StaticFieldIdentifierNameProposition) ? + CreateNewIdenfitierName(StaticFieldIdentifierNameProposition, 1, nameHints) : StaticFieldIdentifierNameProposition; + + public MemberDeclarationSyntax PropertyChangedEventArgsStaticField(IEnumerable nameHints) + { + return FieldDeclaration(List(), + TokenList(Token(PrivateKeyword), Token(StaticKeyword), Token(ReadOnlyKeyword)), + VariableDeclaration(FieldType(FullTypeName), VariableName(StaticFieldIdentifierName(nameHints)))); + } + + public ImmutableDictionary ToDiagnosticProperties() + { + var dict = ImmutableDictionary.CreateBuilder(); + + dict.Add(ArgumentKeyName, ArgumentName); + dict.Add(IsNullKeyName, ArgumentIsNullLiteral.ToString()); + dict.Add(IsNameofKeyName, ArgumentIsNameofExpression.ToString()); + dict.Add(TypeKeyName, FullTypeName); + + return dict.ToImmutable(); + } + + public static PropertyChangedEventArgsAnalyzerData FromDiagnosticProperties(ImmutableDictionary properties) + { + return new PropertyChangedEventArgsAnalyzerData( + properties[TypeKeyName], properties[ArgumentKeyName], properties[IsNullKeyName], properties[IsNameofKeyName]); + } + + private EqualsValueClauseSyntax PropertyChangedEventArgsInstance() => + EqualsValueClause(Token(EqualsToken), + ObjectCreationExpression(ParseTypeName(FullTypeName), + ArgumentList( + SingletonSeparatedList( + PropertyChangedEventArgsCtorArgument())), default(InitializerExpressionSyntax))); + + private ArgumentSyntax PropertyChangedEventArgsCtorArgument() => + Argument(ArgumentIsNameofExpression + ? ParseExpression($"nameof({ArgumentName})") + : ArgumentIsNullLiteral ? LiteralExpression(NullLiteralExpression) : StringLiteral(ArgumentName)); + + private string SuffixForStaticInstance() + { + return ArgumentIsNullLiteral || ArgumentNameIsStar() ? SuffixAllProperties : MakeValidIdentifier(ArgumentName); + } + + private SeparatedSyntaxList VariableName(string fieldName) => + SeparatedList(new[] + { + VariableDeclarator(fieldName) + .WithInitializer(PropertyChangedEventArgsInstance()) + }); + + private bool ArgumentNameIsStar() => string.Equals(ArgumentName, "*", StringComparison.OrdinalIgnoreCase); + + private static string MakeValidIdentifier(string s) => IsValidIdentifier(s) ? s : SanitizeIdentifierName(s); + + private static string SanitizeIdentifierName(string s) => s.ToCharArray() + .Aggregate(new StringBuilder(), + (sanitized, nextChar) => IsValidIdentifier($"{sanitized.ToString()}{nextChar}") ? sanitized.Append(nextChar) : sanitized) + .ToString(); + + private static LiteralExpressionSyntax StringLiteral(string s) => LiteralExpression(StringLiteralExpression, Literal(s)); + + private static IdentifierNameSyntax FieldType(string type) => IdentifierName(type); + + private static string CreateNewIdenfitierName(string oldName, int extension, IEnumerable nameHints) + { + var number = int.Parse(new string(oldName.ToCharArray().Reverse().TakeWhile(char.IsNumber).DefaultIfEmpty('0').ToArray())); + var proposition = $"{oldName}{number+extension}"; + return nameHints.Contains(proposition) ? CreateNewIdenfitierName(oldName, extension+1, nameHints) : proposition; + } + + private class PropertyChangedCreationSyntaxAnalyzer : CSharpSyntaxWalker + { + public bool NullLiteralExpressionFound { get; private set; } + public bool NameofExpressionFound { get; private set; } + public string IdentifierName { get; private set; } + + public override void VisitLiteralExpression(LiteralExpressionSyntax node) + { + NameofExpressionFound = false; + NullLiteralExpressionFound = node.IsKind(NullLiteralExpression); + IdentifierName = node.Token.ValueText; + } + + public override void VisitInvocationExpression(InvocationExpressionSyntax node) + { + NameofExpressionFound = true; + base.VisitInvocationExpression(node); + } + + public override void VisitIdentifierName(IdentifierNameSyntax node) => IdentifierName = node.Identifier.ValueText; + } + } +} \ No newline at end of file diff --git a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs new file mode 100644 index 000000000..f0defd319 --- /dev/null +++ b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs @@ -0,0 +1,93 @@ +using System.Collections.Immutable; +using System.Collections.Generic; +using System.Composition; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +using CodeCracker.Properties; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Formatting; +using Microsoft.CodeAnalysis.Text; + +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; + +namespace CodeCracker.CSharp.Refactoring +{ + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider)), Shared] + public sealed class PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider : CodeFixProvider + { + public LocalizableString CodeActionTitle = new LocalizableResourceString(nameof(Resources.PropertyChangedEventArgsUnnecessaryAllocation_CodeActionTitle), Resources.ResourceManager, typeof(Resources)); + + public override ImmutableArray FixableDiagnosticIds + => ImmutableArray.Create(DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId()); + + public override Task RegisterCodeFixesAsync(CodeFixContext context) + { + var diagnostic = context.Diagnostics.First(); + context.RegisterCodeFix( + CodeAction.Create(CodeActionTitle.ToString(), + token => ChangePropertyChangedEventArgsToStatic(context.Document, diagnostic.Location, diagnostic.Properties, token), + nameof(PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider)), diagnostic); + + return Task.FromResult(true); + } + + private static async Task ChangePropertyChangedEventArgsToStatic(Document document, Location location, + ImmutableDictionary properties, CancellationToken cancellationToken) + { + var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken); + var data = PropertyChangedEventArgsAnalyzerData.FromDiagnosticProperties(properties); + + var newSyntaxRoot = new PropertyChangedUnnecessaryAllocationRewriter(data, location.SourceSpan).Visit(syntaxRoot); + + return document.WithSyntaxRoot(newSyntaxRoot); + } + + private class PropertyChangedUnnecessaryAllocationRewriter : CSharpSyntaxRewriter + { + private readonly PropertyChangedEventArgsAnalyzerData ContextData; + private readonly TextSpan DiagnosticLocation; + + private bool DiagnosticLocationFound = false; + private IEnumerable nameHints; + + public PropertyChangedUnnecessaryAllocationRewriter(PropertyChangedEventArgsAnalyzerData contextData, TextSpan diagnosticLocation) + { + this.ContextData = contextData; + this.DiagnosticLocation = diagnosticLocation; + } + + public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) + { + nameHints = node.Members.OfType() + .SelectMany(fd => fd.Declaration.Variables.Select(vds => vds.Identifier.ValueText)); + + var traverseResult = base.VisitClassDeclaration(node) as ClassDeclarationSyntax; + var result = DiagnosticLocationFound ? AddPropertyChangedEventArgsStaticField(traverseResult, nameHints ?? Enumerable.Empty()) : traverseResult; + DiagnosticLocationFound = false; + return result; + } + + public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) + { + if(node.Span == DiagnosticLocation) + { + DiagnosticLocationFound = true; + + return ParseExpression(ContextData.StaticFieldIdentifierName(nameHints ?? Enumerable.Empty())) + .WithLeadingTrivia(node.GetLeadingTrivia()) + .WithTrailingTrivia(node.GetTrailingTrivia()); + } + return base.VisitObjectCreationExpression(node); + } + + private ClassDeclarationSyntax AddPropertyChangedEventArgsStaticField(ClassDeclarationSyntax declaration, IEnumerable nameHints) => declaration + .WithMembers(declaration.Members.Insert(0, ContextData.PropertyChangedEventArgsStaticField(nameHints).WithAdditionalAnnotations(Formatter.Annotation))); + } + } +} diff --git a/src/Common/CodeCracker.Common/DiagnosticId.cs b/src/Common/CodeCracker.Common/DiagnosticId.cs index 28feee0f8..4dfc7ecb6 100644 --- a/src/Common/CodeCracker.Common/DiagnosticId.cs +++ b/src/Common/CodeCracker.Common/DiagnosticId.cs @@ -80,6 +80,7 @@ public enum DiagnosticId NameOf_External = 108, StringFormatArgs_ExtraArgs = 111, AlwaysUseVarOnPrimitives = 105, + PropertyChangedEventArgsUnnecessaryAllocation = 106, UnnecessaryToStringInStringConcatenation = 118, SwitchCaseWithoutDefault = 120, ReadOnlyComplexTypes = 121, diff --git a/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs b/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs index 17f3ec989..af567f32d 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs +++ b/src/Common/CodeCracker.Common/Properties/Resources.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.42000 +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. // //------------------------------------------------------------------------------ @@ -14,12 +14,12 @@ namespace CodeCracker.Properties { /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + /// A strongly-typed resource class, for looking up localized strings, etc. /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] @@ -34,7 +34,7 @@ internal Resources() { } /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + /// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Resources.ResourceManager ResourceManager { @@ -48,8 +48,8 @@ internal Resources() { } /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] public static global::System.Globalization.CultureInfo Culture { @@ -62,7 +62,7 @@ internal Resources() { } /// - /// Sucht eine lokalisierte Zeichenfolge, die String interpolation allows for better reading of the resulting string when compared to Console.WriteLine arguments. You should use Console.WriteLine with arguments only when another method is supplying the format string. ähnelt. + /// Looks up a localized string similar to String interpolation allows for better reading of the resulting string when compared to Console.WriteLine arguments. You should use Console.WriteLine with arguments only when another method is supplying the format string.. /// public static string ConsoleWriteLineAnalyzer_Description { get { @@ -71,7 +71,7 @@ public static string ConsoleWriteLineAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation ähnelt. + /// Looks up a localized string similar to Use string interpolation. /// public static string ConsoleWriteLineAnalyzer_MessageFormat { get { @@ -80,7 +80,7 @@ public static string ConsoleWriteLineAnalyzer_MessageFormat { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation instead of arguments on Console.WriteLine ähnelt. + /// Looks up a localized string similar to Use string interpolation instead of arguments on Console.WriteLine. /// public static string ConsoleWriteLineAnalyzer_Title { get { @@ -89,7 +89,7 @@ public static string ConsoleWriteLineAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change to string interpolation ähnelt. + /// Looks up a localized string similar to Change to string interpolation. /// public static string ConsoleWriteLineCodeFixProvider_Title { get { @@ -98,7 +98,7 @@ public static string ConsoleWriteLineCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die An empty catch block suppress all errors and shouldn't be used.\r\nIf the error is expected consider logging it or changing the control flow such that it is explicit. ähnelt. + /// Looks up a localized string similar to An empty catch block suppress all errors and shouldn't be used.\r\nIf the error is expected consider logging it or changing the control flow such that it is explicit.. /// public static string EmptyCatchBlockAnalyzer_Description { get { @@ -107,7 +107,7 @@ public static string EmptyCatchBlockAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Empty Catch Block. ähnelt. + /// Looks up a localized string similar to Empty Catch Block.. /// public static string EmptyCatchBlockAnalyzer_Message { get { @@ -116,7 +116,7 @@ public static string EmptyCatchBlockAnalyzer_Message { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Catch block cannot be empty ähnelt. + /// Looks up a localized string similar to Catch block cannot be empty. /// public static string EmptyCatchBlockAnalyzer_Title { get { @@ -125,7 +125,7 @@ public static string EmptyCatchBlockAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Insert Exception class to Catch ähnelt. + /// Looks up a localized string similar to Insert Exception class to Catch. /// public static string EmptyCatchBlockCodeFixProvider_InsertException { get { @@ -134,7 +134,7 @@ public static string EmptyCatchBlockCodeFixProvider_InsertException { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Remove Empty Catch Block ähnelt. + /// Looks up a localized string similar to Remove Empty Catch Block. /// public static string EmptyCatchBlockCodeFixProvider_Remove { get { @@ -143,7 +143,7 @@ public static string EmptyCatchBlockCodeFixProvider_Remove { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Remove Empty Catch Block and Put a Documentation Link about Try...Catch use ähnelt. + /// Looks up a localized string similar to Remove Empty Catch Block and Put a Documentation Link about Try...Catch use. /// public static string EmptyCatchBlockCodeFixProvider_RemoveAndDocumentation { get { @@ -152,7 +152,7 @@ public static string EmptyCatchBlockCodeFixProvider_RemoveAndDocumentation { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Remove wrapping Try Block ähnelt. + /// Looks up a localized string similar to Remove wrapping Try Block. /// public static string EmptyCatchBlockCodeFixProvider_RemoveTry { get { @@ -161,7 +161,7 @@ public static string EmptyCatchBlockCodeFixProvider_RemoveTry { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change field type '{0}' accessibility to be as accessible as field '{1}' ähnelt. + /// Looks up a localized string similar to Change field type '{0}' accessibility to be as accessible as field '{1}'. /// public static string InconsistentAccessibilityInFieldType_Title { get { @@ -170,7 +170,7 @@ public static string InconsistentAccessibilityInFieldType_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change parameter type '{0}' accessibility to be as accessible as indexer 'this[{1}]' ähnelt. + /// Looks up a localized string similar to Change parameter type '{0}' accessibility to be as accessible as indexer 'this[{1}]'. /// public static string InconsistentAccessibilityInIndexerParameter_Title { get { @@ -179,7 +179,7 @@ public static string InconsistentAccessibilityInIndexerParameter_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change indexer return type '{0}' accessibility to be as accessible as indexer 'this[{1}]' ähnelt. + /// Looks up a localized string similar to Change indexer return type '{0}' accessibility to be as accessible as indexer 'this[{1}]'. /// public static string InconsistentAccessibilityInIndexerReturnType_Title { get { @@ -188,7 +188,7 @@ public static string InconsistentAccessibilityInIndexerReturnType_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change parameter type '{0}' accessibility to be as accessible as method '{1}' ähnelt. + /// Looks up a localized string similar to Change parameter type '{0}' accessibility to be as accessible as method '{1}'. /// public static string InconsistentAccessibilityInMethodParameter_Title { get { @@ -197,7 +197,7 @@ public static string InconsistentAccessibilityInMethodParameter_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change return type '{0}' accessibility to be as accessible as method '{1}' ähnelt. + /// Looks up a localized string similar to Change return type '{0}' accessibility to be as accessible as method '{1}'. /// public static string InconsistentAccessibilityInMethodReturnType_Title { get { @@ -206,7 +206,7 @@ public static string InconsistentAccessibilityInMethodReturnType_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change property type '{0}' accessibility to be as accessible as property '{1}' ähnelt. + /// Looks up a localized string similar to Change property type '{0}' accessibility to be as accessible as property '{1}'. /// public static string InconsistentAccessibilityInPropertyType_Title { get { @@ -215,7 +215,7 @@ public static string InconsistentAccessibilityInPropertyType_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Consider introduce field for constructor parameters. ähnelt. + /// Looks up a localized string similar to Consider introduce field for constructor parameters.. /// public static string IntroduceFieldFromConstructorAnalyzer_Description { get { @@ -224,7 +224,7 @@ public static string IntroduceFieldFromConstructorAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Introduce a field for parameter: {0} ähnelt. + /// Looks up a localized string similar to Introduce a field for parameter: {0}. /// public static string IntroduceFieldFromConstructorAnalyzer_MessageFormat { get { @@ -233,7 +233,7 @@ public static string IntroduceFieldFromConstructorAnalyzer_MessageFormat { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Consider introduce field for constructor parameters. ähnelt. + /// Looks up a localized string similar to Consider introduce field for constructor parameters.. /// public static string IntroduceFieldFromConstructorAnalyzer_Title { get { @@ -242,7 +242,7 @@ public static string IntroduceFieldFromConstructorAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Introduce field: {0} from constructor. ähnelt. + /// Looks up a localized string similar to Introduce field: {0} from constructor.. /// public static string IntroduceFieldFromConstructorCodeFixProvider_MessageFormat { get { @@ -251,7 +251,7 @@ public static string IntroduceFieldFromConstructorCodeFixProvider_MessageFormat } /// - /// Sucht eine lokalisierte Zeichenfolge, die Introduce fields for constructor parameters. ähnelt. + /// Looks up a localized string similar to Introduce fields for constructor parameters.. /// public static string IntroduceFieldFromConstructorCodeFixProvider_Title { get { @@ -260,7 +260,7 @@ public static string IntroduceFieldFromConstructorCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Make method non async ähnelt. + /// Looks up a localized string similar to Make method non async. /// public static string MakeMethodNonAsyncCodeFixProvider_Title { get { @@ -269,7 +269,7 @@ public static string MakeMethodNonAsyncCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produce code that is easier to refactor. ähnelt. + /// Looks up a localized string similar to In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produce code that is easier to refactor.. /// public static string NameOfAnalyzer_Description { get { @@ -278,7 +278,7 @@ public static string NameOfAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use 'nameof({0})' instead of specifying the program element name. ähnelt. + /// Looks up a localized string similar to Use 'nameof({0})' instead of specifying the program element name.. /// public static string NameOfAnalyzer_MessageFormat { get { @@ -287,7 +287,7 @@ public static string NameOfAnalyzer_MessageFormat { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use nameof ähnelt. + /// Looks up a localized string similar to Use nameof. /// public static string NameOfAnalyzer_Title { get { @@ -296,7 +296,7 @@ public static string NameOfAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use nameof() ähnelt. + /// Looks up a localized string similar to Use nameof(). /// public static string NameOfCodeFixProvider_Title { get { @@ -305,7 +305,43 @@ public static string NameOfCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Getter only properties with backing read-only field can be converted to getter-only auto-properties. ähnelt. + /// Looks up a localized string similar to Create static PropertyChangedEventArgs instance and reuse. + /// + public static string PropertyChangedEventArgsUnnecessaryAllocation_CodeActionTitle { + get { + return ResourceManager.GetString("PropertyChangedEventArgsUnnecessaryAllocation_CodeActionTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Creating every time an instance of PropertyChangedEventArgs class causes unnecessary memory allocation. Instance can be created once and reused.. + /// + public static string PropertyChangedEventArgsUnnecessaryAllocation_Description { + get { + return ResourceManager.GetString("PropertyChangedEventArgsUnnecessaryAllocation_Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation.. + /// + public static string PropertyChangedEventArgsUnnecessaryAllocation_MessageFormat { + get { + return ResourceManager.GetString("PropertyChangedEventArgsUnnecessaryAllocation_MessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PropertyChangedEventArgs unnecessary allocation. + /// + public static string PropertyChangedEventArgsUnnecessaryAllocation_Title { + get { + return ResourceManager.GetString("PropertyChangedEventArgsUnnecessaryAllocation_Title", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Getter only properties with backing read-only field can be converted to getter-only auto-properties.. /// public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_Description { get { @@ -314,7 +350,7 @@ public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Property {0} can be converted to an getter-only auto-property. ähnelt. + /// Looks up a localized string similar to Property {0} can be converted to an getter-only auto-property.. /// public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_MessageFormat { get { @@ -323,7 +359,7 @@ public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_MessageFormat { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Property can be simplified by using an getter-only auto-property. ähnelt. + /// Looks up a localized string similar to Property can be simplified by using an getter-only auto-property.. /// public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_Title { get { @@ -332,7 +368,7 @@ public static string ReplaceWithGetterOnlyAutoPropertyAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Simplify by using an getter-only auto-property ähnelt. + /// Looks up a localized string similar to Simplify by using an getter-only auto-property. /// public static string ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title { get { @@ -341,7 +377,7 @@ public static string ReplaceWithGetterOnlyAutoPropertyCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die String interpolation allows for better reading of the resulting string when compared to String.Format. You should use String.Format only when another method is supplying the format string. ähnelt. + /// Looks up a localized string similar to String interpolation allows for better reading of the resulting string when compared to String.Format. You should use String.Format only when another method is supplying the format string.. /// public static string StringFormatAnalyzer_Description { get { @@ -350,7 +386,7 @@ public static string StringFormatAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation ähnelt. + /// Looks up a localized string similar to Use string interpolation. /// public static string StringFormatAnalyzer_MessageFormat { get { @@ -359,7 +395,7 @@ public static string StringFormatAnalyzer_MessageFormat { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use string interpolation instead of String.Format ähnelt. + /// Looks up a localized string similar to Use string interpolation instead of String.Format. /// public static string StringFormatAnalyzer_Title { get { @@ -368,7 +404,7 @@ public static string StringFormatAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change to string interpolation ähnelt. + /// Looks up a localized string similar to Change to string interpolation. /// public static string StringFormatCodeFixProvider_Title { get { @@ -377,7 +413,7 @@ public static string StringFormatCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Auto properties offer a more concise way of defining a property. If you are using simple getters and setters you are able to simplify your code with autoproperties. ähnelt. + /// Looks up a localized string similar to Auto properties offer a more concise way of defining a property. If you are using simple getters and setters you are able to simplify your code with autoproperties.. /// public static string SwitchToAutoPropAnalyzer_Description { get { @@ -386,7 +422,7 @@ public static string SwitchToAutoPropAnalyzer_Description { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change {0} to an auto property ähnelt. + /// Looks up a localized string similar to Change {0} to an auto property. /// public static string SwitchToAutoPropAnalyzer_MessageFormat { get { @@ -395,7 +431,7 @@ public static string SwitchToAutoPropAnalyzer_MessageFormat { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Use auto property ähnelt. + /// Looks up a localized string similar to Use auto property. /// public static string SwitchToAutoPropAnalyzer_Title { get { @@ -404,7 +440,7 @@ public static string SwitchToAutoPropAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Change to auto property ähnelt. + /// Looks up a localized string similar to Change to auto property. /// public static string SwitchToAutoPropCodeFixProvider_Title { get { @@ -413,7 +449,7 @@ public static string SwitchToAutoPropCodeFixProvider_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die You have missing/unexistent parameters in Xml Docs ähnelt. + /// Looks up a localized string similar to You have missing/unexistent parameters in Xml Docs. /// public static string XmlDocumentationAnalyzer_Title { get { @@ -422,7 +458,7 @@ public static string XmlDocumentationAnalyzer_Title { } /// - /// Sucht eine lokalisierte Zeichenfolge, die Create missing parameters in xml docs ähnelt. + /// Looks up a localized string similar to Create missing parameters in xml docs. /// public static string XmlDocumentationCreateMissingParametersCodeFixProvider_Title { get { @@ -431,7 +467,7 @@ public static string XmlDocumentationCreateMissingParametersCodeFixProvider_Titl } /// - /// Sucht eine lokalisierte Zeichenfolge, die Remove unexistent parameters in xml docs ähnelt. + /// Looks up a localized string similar to Remove unexistent parameters in xml docs. /// public static string XmlDocumentationRemoveNonExistentParametersCodeFixProvider_Title { get { diff --git a/src/Common/CodeCracker.Common/Properties/Resources.fr.resx b/src/Common/CodeCracker.Common/Properties/Resources.fr.resx index a7953b4d6..630db6544 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.fr.resx +++ b/src/Common/CodeCracker.Common/Properties/Resources.fr.resx @@ -214,4 +214,16 @@ Si l'erreur est attendu considérer ajouter du logging ou modifier le flow de co Enlever le block Catch vide et ajouter un lien vers la documentation des bonnes pratiques de Try...Catch + + Creating every time an instance of PropertyChangedEventArgs class causes unnecessary memory allocation. Instance can be created once and reused. + + + Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation. + + + PropertyChangedEventArgs unnecessary allocation + + + Create static PropertyChangedEventArgs instance and reuse + \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/Properties/Resources.resx b/src/Common/CodeCracker.Common/Properties/Resources.resx index aab3eb4fd..944e7b07e 100644 --- a/src/Common/CodeCracker.Common/Properties/Resources.resx +++ b/src/Common/CodeCracker.Common/Properties/Resources.resx @@ -243,4 +243,16 @@ Introduce fields for constructor parameters. + + Creating every time an instance of PropertyChangedEventArgs class causes unnecessary memory allocation. Instance can be created once and reused. + + + Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation. + + + PropertyChangedEventArgs unnecessary allocation + + + Create static PropertyChangedEventArgs instance and reuse + \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index c45a93ec6..902abbd5b 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -130,6 +130,8 @@ + + diff --git a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs new file mode 100644 index 000000000..a5707fa68 --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs @@ -0,0 +1,169 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using CodeCracker.CSharp.Refactoring; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Xunit; + +namespace CodeCracker.Test.CSharp.Refactoring +{ + public class PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests : CodeFixVerifier + { + public static IEnumerable SharedData + { + get + { + yield return new[] {"\"Name\""}; + yield return new[] {"nameof(Name)"}; + yield return new[] {"null"}; + } + } + + [Fact] + public async Task DoesNotTriggerDiagnosticWithEmptySourceCodeAsync() + { + const string source = @""; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreation(string ctorArg) + { + var source = $"var args = new PropertyChangedEventArgs({ctorArg})"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 12)); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInMethodInvocation(string ctorArg) + { + var source = $@" +public class Test +{{ + public void TestMethod() + {{ + PropertyChanged(new PropertyChangedEventArgs({ctorArg})) + }} +}}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(6, 25)); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInObjectInitializer(string ctorArg) + { + var source = $"object args = new {{ Name = new PropertyChangedEventArgs({ctorArg}) }}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 28)); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesNotTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInFieldAssignmentWhenFieldIsStatic(string ctorArg) + { + var source = $@" +public class Test +{{ + private static PropertyChangedEventArgs field = new PropertyChangedEventArgs({ctorArg}); +}}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DoesNotTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInStaticConstructor() + { + const string source = @" +public class Test +{ + private static PropertyChangedEventArgs field; + + static Test() + { + field = new PropertyChangedEventArgs(""Name""); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DoesNotTriggerDiagnosticAtObjectInstanceCreation() + { + const string source = @" +public class Test +{ + private object field = new object(); +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DoesTriggerDiagnosticAtObjectInstanceCreationUsingQualifiedName() + { + const string source = @" +public class Test +{ + private object field = new System.ComponentModel.PropertyChangedEventArgs(null); +}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(4,28)); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesTriggerDiagnosticInLambdaExpression(string ctorArg) + { + var source = $@" +using System; +using System.ComponentModel; +public class Test +{{ + private PropertyChangedEventArgs field; + + public Test() + {{ + Action action = () => field = new PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(10,39)); + } + + [Fact] + public async Task DoesNotTriggerWhenArgumentIsNotLiteral() + { + var source = $@" +public class Test +{{ + public void TestMethod(string propertyName) + {{ + PropertyChanged(new PropertyChangedEventArgs(propertyName)) + }} +}}"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() + { + return new PropertyChangedEventArgsUnnecessaryAllocationAnalyzer(); + } + + public static DiagnosticResult PropertyChangedUnnecessaryAllocationDiagnostic(int line, int column) + { + return new DiagnosticResult + { + Id = DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId(), + Message = "Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation.", + Severity = DiagnosticSeverity.Hidden, + Locations = new[] + { + new DiagnosticResultLocation("Test0.cs", line, column), + } + }; + } + } +} diff --git a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs new file mode 100644 index 000000000..f9a9ae410 --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs @@ -0,0 +1,318 @@ +using CodeCracker.CSharp.Refactoring; +using System.Collections.Generic; +using System.Threading.Tasks; +using Xunit; + +namespace CodeCracker.Test.CSharp.Refactoring +{ + public class PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests : + CodeFixVerifier + + { + public static IEnumerable SharedData + { + get + { + yield return new[] { "\"Name\"", "Name" }; + yield return new[] { "nameof(Name)", "Name" }; + yield return new[] { "null", "AllProperties" }; + yield return new[] { "\"*\"", "AllProperties" }; + yield return new[] { "\"Name-\"", "Name" }; + } + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task ChangesPropertyChangedEventArgsInstanceToUseStaticField(string ctorArg, string fieldSuffix) + { + var source = $@" +using System.ComponentModel; +public class TestClass +{{ + public string Name {{ get;set; }} + + public void Foo() + {{ + var args = new PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + var fixedCode = $@" +using System.ComponentModel; +public class TestClass +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + + public string Name {{ get;set; }} + + public void Foo() + {{ + var args = PropertyChangedEventArgsFor{fieldSuffix}; + }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesFixWhenEventArgsUsedInMethodInvocation(string ctorArg, string fieldSuffix) + { + var source = $@" +using System.ComponentModel; +public class TestClass +{{ + public string Name {{ get;set; }} + + public void Foo() + {{ + On(new PropertyChangedEventArgs({ctorArg})); + }} + + public void On(PropertyChangedEventArgs args) {{ }} +}}"; + + var fixedCode = $@" +using System.ComponentModel; +public class TestClass +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + + public string Name {{ get;set; }} + + public void Foo() + {{ + On(PropertyChangedEventArgsFor{fieldSuffix}); + }} + + public void On(PropertyChangedEventArgs args) {{ }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task HandlesMultipleClassDeclarations(string ctorArg, string fieldSuffix) + { + var source = $@" +using System.ComponentModel; +public class TestClass +{{ + public string Name {{ get;set; }} + + public void Foo() + {{ + var args = new PropertyChangedEventArgs({ctorArg}); + }} +}} + +public class TestClass2 +{{ +}}"; + + var fixedCode = $@" +using System.ComponentModel; +public class TestClass +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + + public string Name {{ get;set; }} + + public void Foo() + {{ + var args = PropertyChangedEventArgsFor{fieldSuffix}; + }} +}} + +public class TestClass2 +{{ +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesFixWhenQualifiedNameUsed(string ctorArg, string fieldSuffix) + { + var source = $@" +public class TestClass +{{ + public string Name {{ get;set; }} + + public void Foo() + {{ + var args = new System.ComponentModel.PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + var fixedCode = $@" +public class TestClass +{{ + private static readonly System.ComponentModel.PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new System.ComponentModel.PropertyChangedEventArgs({ctorArg}); + + public string Name {{ get;set; }} + + public void Foo() + {{ + var args = PropertyChangedEventArgsFor{fieldSuffix}; + }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode, allowNewCompilerDiagnostics: true); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesFixWhenEventArgsCreatedInField(string ctorArg, string fieldSuffix) + { + var source = $@" +using System.ComponentModel; +public class TestClass +{{ + private PropertyChangedEventArgs field = new PropertyChangedEventArgs({ctorArg}); +}}"; + + var fixedCode = $@" +using System.ComponentModel; +public class TestClass +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + private PropertyChangedEventArgs field = PropertyChangedEventArgsFor{fieldSuffix}; +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesFixWhenEventArgsCreatedInObjectInitializer(string ctorArg, string fieldSuffix) + { + var source = $@" +using System.ComponentModel; +public class TestClass +{{ + public string Name {{ get;set; }} + + public void Foo() + {{ + object args = new {{ Name = new PropertyChangedEventArgs({ctorArg}) }}; + }} +}}"; + + var fixedCode = $@" +using System.ComponentModel; +public class TestClass +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + + public string Name {{ get;set; }} + + public void Foo() + {{ + object args = new {{ Name = PropertyChangedEventArgsFor{fieldSuffix} }}; + }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task HandlesNestedClass(string ctorArg, string fieldSuffix) + { + var source = $@" +using System.ComponentModel; +public class OuterClass +{{ + public class TestClass + {{ + private PropertyChangedEventArgs field = new PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + var fixedCode = $@" +using System.ComponentModel; +public class OuterClass +{{ + public class TestClass + {{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + private PropertyChangedEventArgs field = PropertyChangedEventArgsFor{fieldSuffix}; + }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesFixLambdaExpression(string ctorArg, string fieldSuffix) + { + var source = $@" +using System; +using System.ComponentModel; +public class Test +{{ + private PropertyChangedEventArgs field; + + public Test() + {{ + Action action = () => field = new PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + var fixedCode = $@" +using System; +using System.ComponentModel; +public class Test +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + private PropertyChangedEventArgs field; + + public Test() + {{ + Action action = () => field = PropertyChangedEventArgsFor{fieldSuffix}; + }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + + [Theory] + [MemberData(nameof(SharedData))] + public async Task DoesFixWhenFieldNameIsAlreadyUsed(string ctorArg, string fieldSuffix) + { + var source = $@" +using System; +using System.ComponentModel; +public class Test +{{ + private PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix}; + + public Test() + {{ + Action action = () => PropertyChangedEventArgsFor{fieldSuffix} = new PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + var fixedCode = $@" +using System; +using System.ComponentModel; +public class Test +{{ + private static readonly PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix}1 = new PropertyChangedEventArgs({ctorArg}); + private PropertyChangedEventArgs PropertyChangedEventArgsFor{fieldSuffix}; + + public Test() + {{ + Action action = () => PropertyChangedEventArgsFor{fieldSuffix} = PropertyChangedEventArgsFor{fieldSuffix}1; + }} +}}"; + + await VerifyCSharpFixAsync(source, fixedCode); + } + } +} From 40b7e1834fa218cc28c66cc19e0a368f425b5011 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Wed, 28 Jun 2017 18:42:14 -0300 Subject: [PATCH 089/152] Refactor PropertyChangedEventArgsUnnecessaryAllocation --- ...dEventArgsUnnecessaryAllocationAnalyzer.cs | 54 +++--- ...rgsUnnecessaryAllocationCodeFixProvider.cs | 45 ++--- .../CodeCracker.Test/CodeCracker.Test.csproj | 3 +- ...tArgsUnnecessaryAllocationAnalyzerTests.cs | 169 ---------------- ...gedEventArgsUnnecessaryAllocationTests.cs} | 180 ++++++++++++++++-- 5 files changed, 209 insertions(+), 242 deletions(-) delete mode 100644 test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs rename test/CSharp/CodeCracker.Test/Refactoring/{PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs => PropertyChangedEventArgsUnnecessaryAllocationTests.cs} (59%) diff --git a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs index b1a15bf7f..e9924b9d3 100644 --- a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs +++ b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs @@ -1,17 +1,15 @@ -using System; -using System.Collections.Immutable; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -using CodeCracker.Properties; +using CodeCracker.Properties; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; - -using static Microsoft.CodeAnalysis.CSharp.SyntaxFacts; +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Text; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFacts; using static Microsoft.CodeAnalysis.CSharp.SyntaxKind; namespace CodeCracker.CSharp.Refactoring @@ -49,7 +47,7 @@ public override void Initialize(AnalysisContext context) private static void PropertyChangedCreation(SyntaxNodeAnalysisContext context) { - var propertyChangedEventArgsCreationExpr = (ObjectCreationExpressionSyntax) context.Node; + var propertyChangedEventArgsCreationExpr = (ObjectCreationExpressionSyntax)context.Node; var identifier = propertyChangedEventArgsCreationExpr.Type.Accept(ExtractIdentifier); if (ShouldReportDiagnostic(propertyChangedEventArgsCreationExpr, identifier.ValueText)) { @@ -59,14 +57,12 @@ private static void PropertyChangedCreation(SyntaxNodeAnalysisContext context) } } - private static bool ShouldReportDiagnostic(ObjectCreationExpressionSyntax propertyChangedExpr, - string identifierName) => + private static bool ShouldReportDiagnostic(ObjectCreationExpressionSyntax propertyChangedExpr, string identifierName) => IsPropertyChangedEventArgs(identifierName) && propertyChangedExpr.ArgumentList.Accept(IsAnyArgumentLiteralOrNameof) && !IsAlreadyStatic(propertyChangedExpr); - private static bool IsPropertyChangedEventArgs(string s) - => string.Equals(PropertyChangedEventArgsClassName, s, StringComparison.Ordinal); + private static bool IsPropertyChangedEventArgs(string s) => string.Equals(PropertyChangedEventArgsClassName, s, StringComparison.Ordinal); private static bool IsAlreadyStatic(ObjectCreationExpressionSyntax objectCreationExpr) { @@ -75,7 +71,7 @@ private static bool IsAlreadyStatic(ObjectCreationExpressionSyntax objectCreatio switch (memberForObjectCreationExpr.Kind()) { case SyntaxKind.ConstructorDeclaration: - var constructorDeclaration = (ConstructorDeclarationSyntax) memberForObjectCreationExpr; + var constructorDeclaration = (ConstructorDeclarationSyntax)memberForObjectCreationExpr; result = ContainsStaticModifier(constructorDeclaration.Modifiers); break; case SyntaxKind.FieldDeclaration: @@ -123,31 +119,27 @@ public class PropertyChangedEventArgsAnalyzerData private PropertyChangedEventArgsAnalyzerData(string fullTypeName, string argumentName, string isNullLiteral, string isNameof) { - this.FullTypeName = fullTypeName; - this.ArgumentName = argumentName ?? string.Empty; - this.ArgumentIsNullLiteral = bool.Parse(isNullLiteral); - this.ArgumentIsNameofExpression = bool.Parse(isNameof); + FullTypeName = fullTypeName; + ArgumentName = argumentName ?? string.Empty; + ArgumentIsNullLiteral = bool.Parse(isNullLiteral); + ArgumentIsNameofExpression = bool.Parse(isNameof); - this.StaticFieldIdentifierNameProposition = $"PropertyChangedEventArgsFor{SuffixForStaticInstance()}"; + StaticFieldIdentifierNameProposition = $"PropertyChangedEventArgsFor{SuffixForStaticInstance()}"; } public PropertyChangedEventArgsAnalyzerData(ObjectCreationExpressionSyntax propertyChangedInstanceCreationExpr) { if (propertyChangedInstanceCreationExpr == null) - { throw new ArgumentNullException(nameof(propertyChangedInstanceCreationExpr)); - } - var analyzer = new PropertyChangedCreationSyntaxAnalyzer(); propertyChangedInstanceCreationExpr.ArgumentList.Accept(analyzer); - - this.FullTypeName = propertyChangedInstanceCreationExpr.Type.ToString(); - this.ArgumentName = analyzer.IdentifierName; - this.ArgumentIsNullLiteral = analyzer.NullLiteralExpressionFound; - this.ArgumentIsNameofExpression = analyzer.NameofExpressionFound; + FullTypeName = propertyChangedInstanceCreationExpr.Type.ToString(); + ArgumentName = analyzer.IdentifierName; + ArgumentIsNullLiteral = analyzer.NullLiteralExpressionFound; + ArgumentIsNameofExpression = analyzer.NameofExpressionFound; } - public string StaticFieldIdentifierName(IEnumerable nameHints) => nameHints.Contains(StaticFieldIdentifierNameProposition) ? + public string StaticFieldIdentifierName(IEnumerable nameHints) => nameHints.Contains(StaticFieldIdentifierNameProposition) ? CreateNewIdenfitierName(StaticFieldIdentifierNameProposition, 1, nameHints) : StaticFieldIdentifierNameProposition; public MemberDeclarationSyntax PropertyChangedEventArgsStaticField(IEnumerable nameHints) @@ -215,8 +207,8 @@ private static string SanitizeIdentifierName(string s) => s.ToCharArray() private static string CreateNewIdenfitierName(string oldName, int extension, IEnumerable nameHints) { var number = int.Parse(new string(oldName.ToCharArray().Reverse().TakeWhile(char.IsNumber).DefaultIfEmpty('0').ToArray())); - var proposition = $"{oldName}{number+extension}"; - return nameHints.Contains(proposition) ? CreateNewIdenfitierName(oldName, extension+1, nameHints) : proposition; + var proposition = $"{oldName}{number + extension}"; + return nameHints.Contains(proposition) ? CreateNewIdenfitierName(oldName, extension + 1, nameHints) : proposition; } private class PropertyChangedCreationSyntaxAnalyzer : CSharpSyntaxWalker diff --git a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs index f0defd319..834906f67 100644 --- a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider.cs @@ -1,11 +1,4 @@ -using System.Collections.Immutable; -using System.Collections.Generic; -using System.Composition; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -using CodeCracker.Properties; +using CodeCracker.Properties; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; @@ -13,7 +6,12 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Text; - +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace CodeCracker.CSharp.Refactoring @@ -31,35 +29,32 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) var diagnostic = context.Diagnostics.First(); context.RegisterCodeFix( CodeAction.Create(CodeActionTitle.ToString(), - token => ChangePropertyChangedEventArgsToStatic(context.Document, diagnostic.Location, diagnostic.Properties, token), + token => ChangePropertyChangedEventArgsToStaticAsync(context.Document, diagnostic.Location, diagnostic.Properties, token), nameof(PropertyChangedEventArgsUnnecessaryAllocationCodeFixProvider)), diagnostic); return Task.FromResult(true); } - private static async Task ChangePropertyChangedEventArgsToStatic(Document document, Location location, + private static async Task ChangePropertyChangedEventArgsToStaticAsync(Document document, Location location, ImmutableDictionary properties, CancellationToken cancellationToken) { var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken); var data = PropertyChangedEventArgsAnalyzerData.FromDiagnosticProperties(properties); - var newSyntaxRoot = new PropertyChangedUnnecessaryAllocationRewriter(data, location.SourceSpan).Visit(syntaxRoot); - return document.WithSyntaxRoot(newSyntaxRoot); } private class PropertyChangedUnnecessaryAllocationRewriter : CSharpSyntaxRewriter { - private readonly PropertyChangedEventArgsAnalyzerData ContextData; - private readonly TextSpan DiagnosticLocation; - - private bool DiagnosticLocationFound = false; + private readonly PropertyChangedEventArgsAnalyzerData contextData; + private readonly TextSpan diagnosticLocation; + private bool diagnosticLocationFound; private IEnumerable nameHints; public PropertyChangedUnnecessaryAllocationRewriter(PropertyChangedEventArgsAnalyzerData contextData, TextSpan diagnosticLocation) { - this.ContextData = contextData; - this.DiagnosticLocation = diagnosticLocation; + this.contextData = contextData; + this.diagnosticLocation = diagnosticLocation; } public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) @@ -68,18 +63,18 @@ public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) .SelectMany(fd => fd.Declaration.Variables.Select(vds => vds.Identifier.ValueText)); var traverseResult = base.VisitClassDeclaration(node) as ClassDeclarationSyntax; - var result = DiagnosticLocationFound ? AddPropertyChangedEventArgsStaticField(traverseResult, nameHints ?? Enumerable.Empty()) : traverseResult; - DiagnosticLocationFound = false; + var result = diagnosticLocationFound ? AddPropertyChangedEventArgsStaticField(traverseResult, nameHints ?? Enumerable.Empty()) : traverseResult; + diagnosticLocationFound = false; return result; } public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) { - if(node.Span == DiagnosticLocation) + if(node.Span == diagnosticLocation) { - DiagnosticLocationFound = true; + diagnosticLocationFound = true; - return ParseExpression(ContextData.StaticFieldIdentifierName(nameHints ?? Enumerable.Empty())) + return ParseExpression(contextData.StaticFieldIdentifierName(nameHints ?? Enumerable.Empty())) .WithLeadingTrivia(node.GetLeadingTrivia()) .WithTrailingTrivia(node.GetTrailingTrivia()); } @@ -87,7 +82,7 @@ public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressio } private ClassDeclarationSyntax AddPropertyChangedEventArgsStaticField(ClassDeclarationSyntax declaration, IEnumerable nameHints) => declaration - .WithMembers(declaration.Members.Insert(0, ContextData.PropertyChangedEventArgsStaticField(nameHints).WithAdditionalAnnotations(Formatter.Annotation))); + .WithMembers(declaration.Members.Insert(0, contextData.PropertyChangedEventArgsStaticField(nameHints).WithAdditionalAnnotations(Formatter.Annotation))); } } } diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 902abbd5b..dcf1020ca 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -130,8 +130,7 @@ - - + diff --git a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs deleted file mode 100644 index a5707fa68..000000000 --- a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using CodeCracker.CSharp.Refactoring; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; -using Xunit; - -namespace CodeCracker.Test.CSharp.Refactoring -{ - public class PropertyChangedEventArgsUnnecessaryAllocationAnalyzerTests : CodeFixVerifier - { - public static IEnumerable SharedData - { - get - { - yield return new[] {"\"Name\""}; - yield return new[] {"nameof(Name)"}; - yield return new[] {"null"}; - } - } - - [Fact] - public async Task DoesNotTriggerDiagnosticWithEmptySourceCodeAsync() - { - const string source = @""; - - await VerifyCSharpHasNoDiagnosticsAsync(source); - } - - [Theory] - [MemberData(nameof(SharedData))] - public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreation(string ctorArg) - { - var source = $"var args = new PropertyChangedEventArgs({ctorArg})"; - - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 12)); - } - - [Theory] - [MemberData(nameof(SharedData))] - public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInMethodInvocation(string ctorArg) - { - var source = $@" -public class Test -{{ - public void TestMethod() - {{ - PropertyChanged(new PropertyChangedEventArgs({ctorArg})) - }} -}}"; - - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(6, 25)); - } - - [Theory] - [MemberData(nameof(SharedData))] - public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInObjectInitializer(string ctorArg) - { - var source = $"object args = new {{ Name = new PropertyChangedEventArgs({ctorArg}) }}"; - - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 28)); - } - - [Theory] - [MemberData(nameof(SharedData))] - public async Task DoesNotTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInFieldAssignmentWhenFieldIsStatic(string ctorArg) - { - var source = $@" -public class Test -{{ - private static PropertyChangedEventArgs field = new PropertyChangedEventArgs({ctorArg}); -}}"; - await VerifyCSharpHasNoDiagnosticsAsync(source); - } - - [Fact] - public async Task DoesNotTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInStaticConstructor() - { - const string source = @" -public class Test -{ - private static PropertyChangedEventArgs field; - - static Test() - { - field = new PropertyChangedEventArgs(""Name""); - } -}"; - await VerifyCSharpHasNoDiagnosticsAsync(source); - } - - [Fact] - public async Task DoesNotTriggerDiagnosticAtObjectInstanceCreation() - { - const string source = @" -public class Test -{ - private object field = new object(); -}"; - await VerifyCSharpHasNoDiagnosticsAsync(source); - } - - [Fact] - public async Task DoesTriggerDiagnosticAtObjectInstanceCreationUsingQualifiedName() - { - const string source = @" -public class Test -{ - private object field = new System.ComponentModel.PropertyChangedEventArgs(null); -}"; - - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(4,28)); - } - - [Theory] - [MemberData(nameof(SharedData))] - public async Task DoesTriggerDiagnosticInLambdaExpression(string ctorArg) - { - var source = $@" -using System; -using System.ComponentModel; -public class Test -{{ - private PropertyChangedEventArgs field; - - public Test() - {{ - Action action = () => field = new PropertyChangedEventArgs({ctorArg}); - }} -}}"; - - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(10,39)); - } - - [Fact] - public async Task DoesNotTriggerWhenArgumentIsNotLiteral() - { - var source = $@" -public class Test -{{ - public void TestMethod(string propertyName) - {{ - PropertyChanged(new PropertyChangedEventArgs(propertyName)) - }} -}}"; - - await VerifyCSharpHasNoDiagnosticsAsync(source); - } - - protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() - { - return new PropertyChangedEventArgsUnnecessaryAllocationAnalyzer(); - } - - public static DiagnosticResult PropertyChangedUnnecessaryAllocationDiagnostic(int line, int column) - { - return new DiagnosticResult - { - Id = DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId(), - Message = "Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] - { - new DiagnosticResultLocation("Test0.cs", line, column), - } - }; - } - } -} diff --git a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs similarity index 59% rename from test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs rename to test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs index f9a9ae410..9e004869e 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs @@ -1,16 +1,166 @@ using CodeCracker.CSharp.Refactoring; +using Microsoft.CodeAnalysis; using System.Collections.Generic; using System.Threading.Tasks; using Xunit; namespace CodeCracker.Test.CSharp.Refactoring { - public class PropertyChangedEventArgsUnnecessaryAllocationCodeFixProviderTests : - CodeFixVerifier - + public class PropertyChangedEventArgsUnnecessaryAllocationTests : CodeFixVerifier { - public static IEnumerable SharedData + public static IEnumerable SharedDataAnalyzer + { + get + { + yield return new[] { "\"Name\"" }; + yield return new[] { "nameof(Name)" }; + yield return new[] { "null" }; + } + } + + [Fact] + public async Task DoesNotTriggerDiagnosticWithEmptySourceCodeAsync() + { + const string source = @""; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Theory] + [MemberData(nameof(SharedDataAnalyzer))] + public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreation(string ctorArg) + { + var source = $"var args = new PropertyChangedEventArgs({ctorArg})"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 12)); + } + + [Theory] + [MemberData(nameof(SharedDataAnalyzer))] + public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInMethodInvocation(string ctorArg) + { + var source = $@" +public class Test +{{ + public void TestMethod() + {{ + PropertyChanged(new PropertyChangedEventArgs({ctorArg})) + }} +}}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(6, 25)); + } + + [Theory] + [MemberData(nameof(SharedDataAnalyzer))] + public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInObjectInitializer(string ctorArg) + { + var source = $"object args = new {{ Name = new PropertyChangedEventArgs({ctorArg}) }}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 28)); + } + + [Theory] + [MemberData(nameof(SharedDataAnalyzer))] + public async Task DoesNotTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInFieldAssignmentWhenFieldIsStatic(string ctorArg) + { + var source = $@" +public class Test +{{ + private static PropertyChangedEventArgs field = new PropertyChangedEventArgs({ctorArg}); +}}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DoesNotTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreationInStaticConstructor() + { + const string source = @" +public class Test +{ + private static PropertyChangedEventArgs field; + + static Test() + { + field = new PropertyChangedEventArgs(""Name""); + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DoesNotTriggerDiagnosticAtObjectInstanceCreation() + { + const string source = @" +public class Test +{ + private object field = new object(); +}"; + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + [Fact] + public async Task DoesTriggerDiagnosticAtObjectInstanceCreationUsingQualifiedName() + { + const string source = @" +public class Test +{ + private object field = new System.ComponentModel.PropertyChangedEventArgs(null); +}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(4, 28)); + } + + [Theory] + [MemberData(nameof(SharedDataAnalyzer))] + public async Task DoesTriggerDiagnosticInLambdaExpression(string ctorArg) + { + var source = $@" +using System; +using System.ComponentModel; +public class Test +{{ + private PropertyChangedEventArgs field; + + public Test() + {{ + Action action = () => field = new PropertyChangedEventArgs({ctorArg}); + }} +}}"; + + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(10, 39)); + } + + [Fact] + public async Task DoesNotTriggerWhenArgumentIsNotLiteral() + { + var source = $@" +public class Test +{{ + public void TestMethod(string propertyName) + {{ + PropertyChanged(new PropertyChangedEventArgs(propertyName)) + }} +}}"; + + await VerifyCSharpHasNoDiagnosticsAsync(source); + } + + public static DiagnosticResult PropertyChangedUnnecessaryAllocationDiagnostic(int line, int column) + { + return new DiagnosticResult + { + Id = DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId(), + Message = "Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation.", + Severity = DiagnosticSeverity.Hidden, + Locations = new[] + { + new DiagnosticResultLocation("Test0.cs", line, column), + } + }; + } + + public static IEnumerable SharedDataCodeFix { get { @@ -23,7 +173,7 @@ public static IEnumerable SharedData } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task ChangesPropertyChangedEventArgsInstanceToUseStaticField(string ctorArg, string fieldSuffix) { var source = $@" @@ -56,7 +206,7 @@ public void Foo() } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task DoesFixWhenEventArgsUsedInMethodInvocation(string ctorArg, string fieldSuffix) { var source = $@" @@ -93,7 +243,7 @@ public void On(PropertyChangedEventArgs args) {{ }} } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task HandlesMultipleClassDeclarations(string ctorArg, string fieldSuffix) { var source = $@" @@ -134,7 +284,7 @@ public class TestClass2 } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task DoesFixWhenQualifiedNameUsed(string ctorArg, string fieldSuffix) { var source = $@" @@ -165,7 +315,7 @@ public void Foo() } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task DoesFixWhenEventArgsCreatedInField(string ctorArg, string fieldSuffix) { var source = $@" @@ -187,7 +337,7 @@ public class TestClass } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task DoesFixWhenEventArgsCreatedInObjectInitializer(string ctorArg, string fieldSuffix) { var source = $@" @@ -220,7 +370,7 @@ public void Foo() } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task HandlesNestedClass(string ctorArg, string fieldSuffix) { var source = $@" @@ -248,7 +398,7 @@ public class TestClass } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task DoesFixLambdaExpression(string ctorArg, string fieldSuffix) { var source = $@" @@ -282,7 +432,7 @@ public Test() } [Theory] - [MemberData(nameof(SharedData))] + [MemberData(nameof(SharedDataCodeFix))] public async Task DoesFixWhenFieldNameIsAlreadyUsed(string ctorArg, string fieldSuffix) { var source = $@" @@ -315,4 +465,4 @@ public Test() await VerifyCSharpFixAsync(source, fixedCode); } } -} +} \ No newline at end of file From be103f0c4976446c5eb87b594c7940bf88368722 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Wed, 28 Jun 2017 18:50:16 -0300 Subject: [PATCH 090/152] Finally remove skip from tests --- .../CodeCracker/Style/RemoveCommentedCodeAnalyzer.cs | 2 +- .../CodeCracker.Test/Style/RemoveCommentedCodeTests.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/RemoveCommentedCodeAnalyzer.cs b/src/CSharp/CodeCracker/Style/RemoveCommentedCodeAnalyzer.cs index d94d0374d..a25c49944 100644 --- a/src/CSharp/CodeCracker/Style/RemoveCommentedCodeAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/RemoveCommentedCodeAnalyzer.cs @@ -52,7 +52,7 @@ private void AnalyzeSingleLineCommentTrivia(SyntaxTreeAnalysisContext context) } } - readonly CSharpParseOptions options = new CSharpParseOptions(documentationMode: DocumentationMode.None);//todo:bring kind: SourceCodeKind.Interactive back, it is not supported at the current release + readonly CSharpParseOptions options = new CSharpParseOptions(documentationMode: DocumentationMode.None, kind: SourceCodeKind.Script); bool CouldBeSourceCode(string source) { source = source.Trim(); diff --git a/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs b/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs index ef4f222db..e21ce8c9a 100644 --- a/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs @@ -21,7 +21,7 @@ public async Task IgnoresRegularComments() await VerifyCSharpHasNoDiagnosticsAsync(test); } - [Fact(Skip ="Skipped until SourceCodeKind.Interactive can be set on CSharpParseOptions on the analyzer.")] + [Fact] public async Task CreateDiagnosticForSingleLineCommentedCode() { var test = @"// a = 10;".WrapInCSharpMethod(); @@ -49,7 +49,7 @@ public async Task RemovesCommentedCodePreservingRegularComments() await VerifyCSharpFixAsync(test, fixtest); } - [Fact(Skip ="Skipped until SourceCodeKind.Interactive can be set on CSharpParseOptions on the analyzer.")] + [Fact] public async Task CreateDiagnosticForMultipleLinesCommentedCode() { var test = @" @@ -68,7 +68,7 @@ public async Task CreateDiagnosticForMultipleLinesCommentedCode() await VerifyCSharpDiagnosticAsync(test, expected); } - [Fact(Skip ="Skipped until SourceCodeKind.Interactive can be set on CSharpParseOptions on the analyzer.")] + [Fact] public async Task RemovesCommentedMultilineCodePreservingRegularComments() { var test = @" @@ -103,7 +103,7 @@ class Foo await VerifyCSharpFixAsync(test, fixtest); } - [Fact(Skip ="Skipped until SourceCodeKind.Interactive can be set on CSharpParseOptions on the analyzer.")] + [Fact] public async Task RemovesNonPerfectIfCommentedCode() { var test = @" From 187501c5fb95fc4a38fc09a7b8fab41a26169264 Mon Sep 17 00:00:00 2001 From: John Ellison Date: Wed, 25 Oct 2017 10:30:28 -0400 Subject: [PATCH 091/152] Minor spelling fix (#950) --- src/CSharp/CodeCracker/Usage/RethrowExceptionAnalyzer.cs | 2 +- test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Usage/RethrowExceptionAnalyzer.cs b/src/CSharp/CodeCracker/Usage/RethrowExceptionAnalyzer.cs index ffb335e6f..cf2376d77 100644 --- a/src/CSharp/CodeCracker/Usage/RethrowExceptionAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/RethrowExceptionAnalyzer.cs @@ -43,7 +43,7 @@ private static void Analyzer(SyntaxNodeAnalysisContext context) if (catchClause == null) return; var catchExSymbol = context.SemanticModel.GetDeclaredSymbol(catchClause.Declaration); if (!catchExSymbol.Equals(exSymbol)) return; - var diagnostic = Diagnostic.Create(Rule, throwStatement.GetLocation(), "Throwing the same exception that was caught will loose the original stack trace."); + var diagnostic = Diagnostic.Create(Rule, throwStatement.GetLocation(), "Throwing the same exception that was caught will lose the original stack trace."); context.ReportDiagnostic(diagnostic); } } diff --git a/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs b/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs index 7dcd8ce82..4bec3f3fd 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs @@ -30,7 +30,7 @@ public async Task WhenThrowingOriginalExceptionAnalyzerCreatesDiagnostic() var expected = new DiagnosticResult { Id = DiagnosticId.RethrowException.ToDiagnosticId(), - Message = "Throwing the same exception that was caught will loose the original stack trace.", + Message = "Throwing the same exception that was caught will lose the original stack trace.", Severity = DiagnosticSeverity.Warning, Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 21) } }; From fc13c29cb2df52fd8f04126be7eb0f52a0f9f859 Mon Sep 17 00:00:00 2001 From: hacking-god <33166103+hacking-god@users.noreply.github.com> Date: Sat, 28 Oct 2017 03:45:36 +0530 Subject: [PATCH 092/152] Documentation Code Cracker An analyzer library for C# and VB that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. There you will find information on how to contribute, our task board, definition of done, definition of ready, etc. Build status Nuget count License Issues open Coverage Status Source Browser This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. Installing You may use CodeCracker in two ways: as an analyzer library that you install with Nuget into your project or as a Visual Studio extension. The way you want to use it depends on the scenario you are working on. You most likely want the Nuget package. If you want the analyzers to work during your build, and generate warnings and errors during the build, also on build servers, then you want to use the Nuget package. The package is available on nuget (C#, VB). If you want to be able to configure which analyzers are being used in your project, and which ones you will ignore, and commit those changes to source control and share with your team, then you also want the Nuget package. To install from Nuget, for the C# version: Install-Package CodeCracker.CSharp Or for the Visual Basic version: Install-Package CodeCracker.VisualBasic Or use the Package Manager in Visual Studio. There is also a version for both named CodeCracker only, but it makes not sense to get it, you should search for the C# or VB version. If you want the alpha builds that build on each push to the repo, add https://www.myget.org/F/codecrackerbuild/ to your nuget feed. We only push complete releases to Nuget.org, and commit builds go to Myget.org. If you want global analyzers that will work on every project you open in Visual Studio, then you want the Extension. Grab the extension at the Visual Studio Extensions Gallery (C#, VB). To build from source: git clone https://github.com/code-cracker/code-cracker.git cd CodeCracker msbuild Then add a reference to CodeCracker.dll from within the Analyzers node inside References, in Visual Studio. SonarQube Plugin CodeCracker has a SonarQube Plugin that can downloaded at Plugins HomePage. --- Documentation | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Documentation diff --git a/Documentation b/Documentation new file mode 100644 index 000000000..bb9c50c19 --- /dev/null +++ b/Documentation @@ -0,0 +1,40 @@ +Code Cracker + +An analyzer library for C# and VB that uses Roslyn to produce refactorings, code analysis, and other niceties. + +Check the official project site on code-cracker.github.io. There you will find information on how to contribute, our task board, definition of done, definition of ready, etc. + +Build status Nuget count License Issues open Coverage Status Source Browser + +This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. + +Installing + +You may use CodeCracker in two ways: as an analyzer library that you install with Nuget into your project or as a Visual Studio extension. The way you want to use it depends on the scenario you are working on. You most likely want the Nuget package. + +If you want the analyzers to work during your build, and generate warnings and errors during the build, also on build servers, then you want to use the Nuget package. The package is available on nuget (C#, VB). If you want to be able to configure which analyzers are being used in your project, and which ones you will ignore, and commit those changes to source control and share with your team, then you also want the Nuget package. + +To install from Nuget, for the C# version: + +Install-Package CodeCracker.CSharp +Or for the Visual Basic version: + +Install-Package CodeCracker.VisualBasic +Or use the Package Manager in Visual Studio. + +There is also a version for both named CodeCracker only, but it makes not sense to get it, you should search for the C# or VB version. + +If you want the alpha builds that build on each push to the repo, add https://www.myget.org/F/codecrackerbuild/ to your nuget feed. We only push complete releases to Nuget.org, and commit builds go to Myget.org. + +If you want global analyzers that will work on every project you open in Visual Studio, then you want the Extension. Grab the extension at the Visual Studio Extensions Gallery (C#, VB). + +To build from source: + +git clone https://github.com/code-cracker/code-cracker.git +cd CodeCracker +msbuild +Then add a reference to CodeCracker.dll from within the Analyzers node inside References, in Visual Studio. + +SonarQube Plugin + +CodeCracker has a SonarQube Plugin that can downloaded at Plugins HomePage. From 464c3d353162e4c08129d0b16188e17888a3b3c6 Mon Sep 17 00:00:00 2001 From: love-ode <33171148+love-ode@users.noreply.github.com> Date: Sat, 28 Oct 2017 11:08:20 +0530 Subject: [PATCH 093/152] Create Readme Hacktoberfest Sign In Sheet 2017! The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! Instruction In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. Git and Pull Request Resources Github The Net Ninja Awesome-Git How to Create a Pull Request Click on the fork on the top to fork this repo. Go to your repo where you forked the project. Hit the clone button on your forked repo and copy the given link. On your terminal / command prompt, type "git clone [put the link here]". Change the index file in the folder. Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" Push the commit. For example, type "git push [remote-name] master". Go back to the original repo. Hit "new pull request" and compare between forks. Confirm the pull request and that's it! --- Create Readme | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Create Readme diff --git a/Create Readme b/Create Readme new file mode 100644 index 000000000..316700cd9 --- /dev/null +++ b/Create Readme @@ -0,0 +1,26 @@ +Hacktoberfest Sign In Sheet 2017! + +The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! + +Instruction + +In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. + +Git and Pull Request Resources + +Github +The Net Ninja +Awesome-Git +How to Create a Pull Request + +Click on the fork on the top to fork this repo. +Go to your repo where you forked the project. +Hit the clone button on your forked repo and copy the given link. +On your terminal / command prompt, type "git clone [put the link here]". +Change the index file in the folder. +Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. +Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" +Push the commit. For example, type "git push [remote-name] master". +Go back to the original repo. +Hit "new pull request" and compare between forks. +Confirm the pull request and that's it! From aac3be2efb548261641f770482403369c3991525 Mon Sep 17 00:00:00 2001 From: likeme <33179335+likeme@users.noreply.github.com> Date: Sun, 29 Oct 2017 04:58:20 +0530 Subject: [PATCH 094/152] Hacktoberfest Hacktoberfest Sign In Sheet 2017! The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! Instruction In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. Git and Pull Request Resources Github The Net Ninja Awesome-Git How to Create a Pull Request Click on the fork on the top to fork this repo. Go to your repo where you forked the project. Hit the clone button on your forked repo and copy the given link. On your terminal / command prompt, type "git clone [put the link here]". Change the index file in the folder. Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" Push the commit. For example, type "git push [remote-name] master". Go back to the original repo. Hit "new pull request" and compare between forks. Confirm the pull request and that's it! --- Hacktoberfest | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Hacktoberfest diff --git a/Hacktoberfest b/Hacktoberfest new file mode 100644 index 000000000..316700cd9 --- /dev/null +++ b/Hacktoberfest @@ -0,0 +1,26 @@ +Hacktoberfest Sign In Sheet 2017! + +The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! + +Instruction + +In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. + +Git and Pull Request Resources + +Github +The Net Ninja +Awesome-Git +How to Create a Pull Request + +Click on the fork on the top to fork this repo. +Go to your repo where you forked the project. +Hit the clone button on your forked repo and copy the given link. +On your terminal / command prompt, type "git clone [put the link here]". +Change the index file in the folder. +Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. +Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" +Push the commit. For example, type "git push [remote-name] master". +Go back to the original repo. +Hit "new pull request" and compare between forks. +Confirm the pull request and that's it! From 4813199b4d43bffe9720422e7cf4797fcc2eaa10 Mon Sep 17 00:00:00 2001 From: Bug Date: Mon, 30 Oct 2017 00:12:22 -0200 Subject: [PATCH 095/152] Another minor spelling fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3e2117dfd..65e96c1c0 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ The maintainers have to: To become part of the core team one has to be invited. Invitations happen only if all the core team agrees. -If a member of the core team is not active for at least to months, they will probably be removed from the core team. +If a member of the core team is not active for at least two months, they will probably be removed from the core team. ## Contact From 7becb60f65033d4eea1e09ee083ca9ff6ad893d8 Mon Sep 17 00:00:00 2001 From: kiss-me1997 <33254635+kiss-me1997@users.noreply.github.com> Date: Tue, 31 Oct 2017 18:09:03 +0530 Subject: [PATCH 096/152] Readme Hacktoberfest Sign In Sheet 2017! The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! Instruction In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. Git and Pull Request Resources Github The Net Ninja Awesome-Git How to Create a Pull Request Click on the fork on the top to fork this repo. Go to your repo where you forked the project. Hit the clone button on your forked repo and copy the given link. On your terminal / command prompt, type "git clone [put the link here]". Change the index file in the folder. Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" Push the commit. For example, type "git push [remote-name] master". Go back to the original repo. Hit "new pull request" and compare between forks. Confirm the pull request and that's it! Installation Make sure git is installed. --- Readme | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Readme diff --git a/Readme b/Readme new file mode 100644 index 000000000..a8f1c6b0d --- /dev/null +++ b/Readme @@ -0,0 +1,29 @@ +Hacktoberfest Sign In Sheet 2017! + +The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! + +Instruction + +In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. + +Git and Pull Request Resources + +Github +The Net Ninja +Awesome-Git +How to Create a Pull Request + +Click on the fork on the top to fork this repo. +Go to your repo where you forked the project. +Hit the clone button on your forked repo and copy the given link. +On your terminal / command prompt, type "git clone [put the link here]". +Change the index file in the folder. +Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. +Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" +Push the commit. For example, type "git push [remote-name] master". +Go back to the original repo. +Hit "new pull request" and compare between forks. +Confirm the pull request and that's it! +Installation + +Make sure git is installed. From 85c8558b38988f33442a05a82c8ea37c17445ecd Mon Sep 17 00:00:00 2001 From: David Wheatley Date: Sat, 11 Nov 2017 14:23:06 +0000 Subject: [PATCH 097/152] Add a newbie section to the installation. Added a TL;DR for the people who don't like big walls of text. Explains it very simply for newbies like myself to help them choose what they need. --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 65e96c1c0..c12e0b877 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,9 @@ msbuild Then add a reference to CodeCracker.dll from within the Analyzers node inside References, in Visual Studio. +TL;DR: +If you want to use CodeCracker in all your projects, install the Visual Studio extension ([C#](https://visualstudiogallery.msdn.microsoft.com/ab588981-91a5-478c-8e65-74d0ff450862), [VB](https://visualstudiogallery.msdn.microsoft.com/1a5f9551-e831-4812-abd0-ac48603fc2c1)). If you want to use CodeCracker for just one project, install the Nuget package as described above. + ## SonarQube Plugin CodeCracker has a SonarQube Plugin that can downloaded at [Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). From 414cae960360a176edaf2633059e6ceb62641a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9ury=20Sim=C3=B5es=20Bazzo?= Date: Fri, 17 Nov 2017 17:30:13 -0200 Subject: [PATCH 098/152] first commit --- .../Style/TaskNameAsyncAnalyzer.cs | 13 +++++++- .../Style/TaskNameASyncTests.cs | 33 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs index 6c0f8997c..8731f531c 100644 --- a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs @@ -7,6 +7,10 @@ namespace CodeCracker.CSharp.Style { + + + + [DiagnosticAnalyzer(LanguageNames.CSharp)] public class TaskNameAsyncAnalyzer : DiagnosticAnalyzer { @@ -32,7 +36,14 @@ public class TaskNameAsyncAnalyzer : DiagnosticAnalyzer private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) { if (context.IsGenerated()) return; + var method = (MethodDeclarationSyntax)context.Node; + + //for teste + var semanticModel = context.SemanticModel; + if (method.IsImplementingInterface(semanticModel)) return; + + if (method.Identifier.ToString().EndsWith("Async")) return; if (method.Modifiers.Any(SyntaxKind.NewKeyword, SyntaxKind.OverrideKeyword)) return; @@ -44,7 +55,7 @@ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) context.ReportDiagnostic(diag); return; } - var semanticModel = context.SemanticModel; + semanticModel = context.SemanticModel; var returnType = semanticModel.GetSymbolInfo(method.ReturnType).Symbol as INamedTypeSymbol; if (returnType == null) return; diff --git a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs index 76107647d..b8a56c098 100644 --- a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs @@ -7,6 +7,39 @@ namespace CodeCracker.Test.CSharp.Style { public class TaskNameAsyncTests : CodeFixVerifier { + + [Fact] + public async Task TaskNameAsyncMethodEqualsInterface() + { + const string source = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public interface IBar + { + Task Foo(); + } + + public class Bar : IBar + { + public Task Foo() + { } + } + }"; + + var expected = new DiagnosticResult + { + Id = DiagnosticId.TaskNameAsync.ToDiagnosticId(), + Message = string.Format(TaskNameAsyncAnalyzer.MessageFormat, "FooAsync"), + Severity = DiagnosticSeverity.Info, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 26) } + }; + + await VerifyCSharpDiagnosticAsync(source, expected); + } + + [Fact] public async Task TaskNameAsyncMethodCorrect() { From f7635048f02006f379943e6124418ea7ed14e776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9ury=20Sim=C3=B5es=20Bazzo?= Date: Sun, 19 Nov 2017 22:40:34 -0200 Subject: [PATCH 099/152] Last Commit --- .../CodeCracker/Style/TaskNameAsyncAnalyzer.cs | 13 ------------- .../CodeCracker.Test/Style/TaskNameASyncTests.cs | 6 ++---- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs index 8731f531c..daaf8019f 100644 --- a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs @@ -7,10 +7,6 @@ namespace CodeCracker.CSharp.Style { - - - - [DiagnosticAnalyzer(LanguageNames.CSharp)] public class TaskNameAsyncAnalyzer : DiagnosticAnalyzer { @@ -38,31 +34,22 @@ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) if (context.IsGenerated()) return; var method = (MethodDeclarationSyntax)context.Node; - - //for teste var semanticModel = context.SemanticModel; if (method.IsImplementingInterface(semanticModel)) return; - - if (method.Identifier.ToString().EndsWith("Async")) return; if (method.Modifiers.Any(SyntaxKind.NewKeyword, SyntaxKind.OverrideKeyword)) return; - var errorMessage = method.Identifier.ToString() + "Async"; var diag = Diagnostic.Create(Rule, method.Identifier.GetLocation(), errorMessage); - if (method.Modifiers.Any(SyntaxKind.AsyncKeyword)) { context.ReportDiagnostic(diag); return; } - semanticModel = context.SemanticModel; var returnType = semanticModel.GetSymbolInfo(method.ReturnType).Symbol as INamedTypeSymbol; if (returnType == null) return; - if (returnType.ToString() != "System.Threading.Tasks.Task" && (!returnType.IsGenericType || returnType.ConstructedFrom.ToString() != "System.Threading.Tasks.Task")) return; - if (method.IsImplementingInterface(semanticModel)) return; context.ReportDiagnostic(diag); } } diff --git a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs index b8a56c098..80d73afea 100644 --- a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs @@ -7,9 +7,8 @@ namespace CodeCracker.Test.CSharp.Style { public class TaskNameAsyncTests : CodeFixVerifier { - [Fact] - public async Task TaskNameAsyncMethodEqualsInterface() + public async Task TaskNameAsyncMethodEqualsNameMethodInterface() { const string source = @" using System.Threading.Tasks; @@ -38,8 +37,7 @@ public Task Foo() await VerifyCSharpDiagnosticAsync(source, expected); } - - + [Fact] public async Task TaskNameAsyncMethodCorrect() { From e2a96e26edae3dab77338c003ed115e973feb1b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?T=C3=A9ury=20Sim=C3=B5es=20Bazzo?= Date: Mon, 20 Nov 2017 11:18:36 -0200 Subject: [PATCH 100/152] Fix Bug: CC0061: Implementing interface using async keyword should not raise a diagnostic #936 --- src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs | 1 - test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs index daaf8019f..160d792e2 100644 --- a/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/TaskNameAsyncAnalyzer.cs @@ -32,7 +32,6 @@ public class TaskNameAsyncAnalyzer : DiagnosticAnalyzer private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) { if (context.IsGenerated()) return; - var method = (MethodDeclarationSyntax)context.Node; var semanticModel = context.SemanticModel; if (method.IsImplementingInterface(semanticModel)) return; diff --git a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs index 80d73afea..e897d37b1 100644 --- a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs @@ -26,7 +26,6 @@ public Task Foo() { } } }"; - var expected = new DiagnosticResult { Id = DiagnosticId.TaskNameAsync.ToDiagnosticId(), @@ -37,7 +36,7 @@ public Task Foo() await VerifyCSharpDiagnosticAsync(source, expected); } - + [Fact] public async Task TaskNameAsyncMethodCorrect() { From 3162618c943a3f7522761bac86bb624556e3e763 Mon Sep 17 00:00:00 2001 From: Pascal Berger Date: Thu, 14 Dec 2017 20:44:45 +0100 Subject: [PATCH 101/152] Fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c12e0b877..a8cb57814 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ If you want to use CodeCracker in all your projects, install the Visual Studio e ## SonarQube Plugin -CodeCracker has a SonarQube Plugin that can downloaded at [Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). +CodeCracker has a SonarQube Plugin that can be downloaded at [Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). ## Contributing From b890c9aa19340f8bae05d7d7ed176d2c052db06a Mon Sep 17 00:00:00 2001 From: Matt Rouse Date: Mon, 18 Dec 2017 16:26:51 +0000 Subject: [PATCH 102/152] Fix issue/958 Don't suggest changes for Async Main --- .../Style/TaskNameAsyncCodeFixProvider.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs index ac8192347..198444fb5 100644 --- a/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs @@ -22,10 +22,25 @@ public class TaskNameAsyncCodeFixProvider : CodeFixProvider public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { var diagnostic = context.Diagnostics.First(); + + if (GetMethodName(diagnostic) == "Main" && IsUsingCSharp7(diagnostic)) + return Task.FromResult(0); + context.RegisterCodeFix(CodeAction.Create("Change method name including 'Async'.", c => ChangeMethodNameAsync(context.Document, diagnostic, c), nameof(TaskNameAsyncCodeFixProvider)), diagnostic); + return Task.FromResult(0); } + private static string GetMethodName(Diagnostic diagnostic) + { + return diagnostic.Location.SourceTree.ToString().Substring(diagnostic.Location.SourceSpan.Start, diagnostic.Location.SourceSpan.End - diagnostic.Location.SourceSpan.Start); + } + + private static bool IsUsingCSharp7(Diagnostic diagnostic) + { + return ((CSharpParseOptions)diagnostic.Location.SourceTree.Options).LanguageVersion.ToString() == "CSharp7"; + } + private static async Task ChangeMethodNameAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); From 5ffe60b48e091b424a6ccd0949c64a5b576afadc Mon Sep 17 00:00:00 2001 From: BugAgain Date: Tue, 30 Jan 2018 17:47:14 -0200 Subject: [PATCH 103/152] Not the cat We are not referring to the :cat: here --- .../Refactoring/AllowMembersOrderingAnalyzerTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs index 07c58f2cc..724a2cfd6 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs @@ -14,7 +14,7 @@ protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() [Theory] [InlineData("class")] [InlineData("struct")] - public async void AllowMembersOrderingForEmptyTypeShouldNotTiggerDiagnostic(string typeDeclaration) + public async void AllowMembersOrderingForEmptyTypeShouldNotTriggerDiagnostic(string typeDeclaration) { var test = @" " + typeDeclaration + @" Foo @@ -27,7 +27,7 @@ public async void AllowMembersOrderingForEmptyTypeShouldNotTiggerDiagnostic(stri [Theory] [InlineData("class")] [InlineData("struct")] - public async void AllowMembersOrderingForOneMemberShouldNotTiggerDiagnostic(string typeDeclaration) + public async void AllowMembersOrderingForOneMemberShouldNotTriggerDiagnostic(string typeDeclaration) { var test = @" " + typeDeclaration + @" Foo @@ -41,7 +41,7 @@ public async void AllowMembersOrderingForOneMemberShouldNotTiggerDiagnostic(stri [Theory] [InlineData("class")] [InlineData("struct")] - public async void AllowMembersOrderingForMoreThanOneMemberShouldTiggerDiagnostic(string typeDeclaration) + public async void AllowMembersOrderingForMoreThanOneMemberShouldTriggerDiagnostic(string typeDeclaration) { var test = @" " + typeDeclaration + @" Foo From 01d956f39f0e91802b30fb30dfc56d9938ab7162 Mon Sep 17 00:00:00 2001 From: codetriage-readme-bot Date: Mon, 26 Feb 2018 14:11:58 -0600 Subject: [PATCH 104/152] Add CodeTriage badge to code-cracker/code-cracker Adds a badge showing the number of people helping this repo on CodeTriage. [![Open Source Helpers](https://www.codetriage.com/code-cracker/code-cracker/badges/users.svg)](https://www.codetriage.com/code-cracker/code-cracker) ## What is CodeTriage? CodeTriage is an Open Source app that is designed to make contributing to Open Source projects easier. It works by sending subscribers a few open issues in their inbox. If subscribers get busy, there is an algorithm that backs off issue load so they do not get overwhelmed [Read more about the CodeTriage project](https://www.codetriage.com/what). ## Why am I getting this PR? Your project was picked by the human, @schneems. They selected it from the projects submitted to https://www.codetriage.com and hand edited the PR. How did your project get added to [CodeTriage](https://www.codetriage.com/what)? Roughly about 1 year ago, [andrecarlucci](https://github.com/andrecarlucci) added this project to CodeTriage in order to start contributing. Since then, 6 people have subscribed to help this repo. ## What does adding a badge accomplish? Adding a badge invites people to help contribute to your project. It also lets developers know that others are invested in the longterm success and maintainability of the project. You can see an example of a CodeTriage badge on these popular OSS READMEs: - [![Email clients like GMAIL do not render SVG images](https://www.codetriage.com/rails/rails/badges/users.svg)](https://www.codetriage.com/rails/rails) https://github.com/rails/rails - [![Email clients like GMAIL do not render SVG images](https://www.codetriage.com/crystal-lang/crystal/badges/users.svg)](https://www.codetriage.com/crystal-lang/crystal) https://github.com/crystal-lang/crystal ## Have a question or comment? While I am a bot, this PR was manually reviewed and monitored by a human - @schneems. My job is writing commit messages and handling PR logistics. If you have any questions, you can reply back to this PR and they will be answered by @schneems. If you do not want a badge right now, no worries, close the PR, you will not hear from me again. Thanks for making your project Open Source! Any feedback is greatly appreciated. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a8cb57814..3f104f6f0 100644 --- a/README.md +++ b/README.md @@ -64,9 +64,9 @@ If you want to use CodeCracker in all your projects, install the Visual Studio e ## SonarQube Plugin -CodeCracker has a SonarQube Plugin that can be downloaded at [Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). +CodeCracker has a SonarQube Plugin that can be downloaded at [Plugins HomePage](http://docs.sonarqube.org/display/PLUG/Other+Plugins). -## Contributing +## Contributing [![Open Source Helpers](https://www.codetriage.com/code-cracker/code-cracker/badges/users.svg)](https://www.codetriage.com/code-cracker/code-cracker) The main supported IDE for development is Visual Studio 2015. If you want to use VS 2015 to contribute to Code Cracker use @@ -90,7 +90,7 @@ be assigned to this team. The easiest way to start is looking into the issues that are [up for grabs](https://github.com/code-cracker/code-cracker/labels/up-for-grabs). You -may ask to work on any of them, read below to see how. +may ask to work on any of them, read below to see how. You can also triage issues which may include reproducing bug reports, or asking for vital information such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to code-cracker on CodeTriage](https://www.codetriage.com/code-cracker/code-cracker). If you are just starting with Roslyn, want to contribute, and feel you are not yet ready to start working on full analyzers or code fixes, you can start helping with areas that are From fe14d752024d5d894bba6e9493a1c9bf4f2e3656 Mon Sep 17 00:00:00 2001 From: Justin Clareburt Date: Wed, 28 Feb 2018 09:40:58 -0800 Subject: [PATCH 105/152] Added release notes to VSIX manifest (C# and VB). Release notes point to ChangeLog. --- src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest | 1 + src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest | 1 + 2 files changed, 2 insertions(+) diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest index 7af8869e2..aa1218012 100644 --- a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest @@ -9,6 +9,7 @@ Build status Nuget count Nuget downloads Issues open This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. http://code-cracker.github.io/ LICENSE.txt + http://code-cracker.github.io/changelog.html codecrackerlogo.png ccexample.png ReSharper, Refactoring, code analysis, analyzer, CodeRush, roslyn, roslyn c#, Refactoring c# Roslyn diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest index 6423f798e..3de517a30 100644 --- a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest @@ -9,6 +9,7 @@ Build status Nuget count Nuget downloads Issues open This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. http://code-cracker.github.io/ LICENSE.txt + http://code-cracker.github.io/changelog.html codecrackerlogo.png ccexample.png ReSharper, Refactoring, code analysis, analyzer, CodeRush, roslyn, roslyn c#, Refactoring c# Roslyn From e680450e1f2c93f6dac5b1171933f173aa776705 Mon Sep 17 00:00:00 2001 From: Justin Clareburt Date: Wed, 28 Feb 2018 10:16:37 -0800 Subject: [PATCH 106/152] Started adding features to ReadeMe file. Added Design features. --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 3f104f6f0..bb5318b6a 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,20 @@ our task board, definition of done, definition of ready, etc. This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. +## Features + +The list of features is documented here: http://code-cracker.github.io/diagnostics.html + +#### Design +Code | Analyzer | Severity | Description +-- | -- | -- | -- +[CC0003](http://code-cracker.github.io/diagnostics/CC0003.html) | CatchEmptyAnalyzer | Warning | Catch statements with no Exception as an argument is not recommended. Consider adding an Exception class to the catch statement. +[CC0004](http://code-cracker.github.io/diagnostics/CC0004.html) | EmptyCatchBlockAnalyzer | Warning | An empty catch block suppress all errors and shouldn’t be used. If the error is expected consider logging it or changing the control flow such that it is explicit. +[CC0016](http://code-cracker.github.io/diagnostics/CC0016.html) | CopyEventToVariableBeforeFireAnalyzer | Warning | Events should always be checked for null before being invoked. As in a multi-threading context it is possible for an event to be unsuscribed between the moment where it is checked to be non-null and the moment it is raised, the event must be copied to a temporary variable before the check. +[CC0021](http://code-cracker.github.io/diagnostics/CC0021.html) | NameOfAnalyzer | Warning | In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produce code that is easier to refactor. +[CC0024](http://code-cracker.github.io/diagnostics/CC0024.html) | StaticConstructorExceptionAnalyzer | Warning | Static constructor are called before the first time a class is used but the caller doesn’t control when exactly. Exception thrown in this context force callers to use ‘try’ block around any useage of the class and should be avoided. +[CC0031](http://code-cracker.github.io/diagnostics/CC0031.html) | UseInvokeMethodToFireEventAnalyzer | Warning | In C#6 a delegate can be invoked using the null-propagating operator (?.) and it’s invoke method to avoid throwing a NullReference exception when there is no method attached to the delegate. + ## Installing You may use CodeCracker in two ways: as an analyzer library that you install with Nuget into your project or as a Visual Studio extension. From c5ffd288bbfcf70d85dd0bcafff084d3d9ae37c7 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 6 May 2018 21:33:24 -0300 Subject: [PATCH 107/152] Remove hacktober fest old files --- Create Readme | 26 -------------------------- Readme | 29 ----------------------------- 2 files changed, 55 deletions(-) delete mode 100644 Create Readme delete mode 100644 Readme diff --git a/Create Readme b/Create Readme deleted file mode 100644 index 316700cd9..000000000 --- a/Create Readme +++ /dev/null @@ -1,26 +0,0 @@ -Hacktoberfest Sign In Sheet 2017! - -The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! - -Instruction - -In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. - -Git and Pull Request Resources - -Github -The Net Ninja -Awesome-Git -How to Create a Pull Request - -Click on the fork on the top to fork this repo. -Go to your repo where you forked the project. -Hit the clone button on your forked repo and copy the given link. -On your terminal / command prompt, type "git clone [put the link here]". -Change the index file in the folder. -Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. -Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" -Push the commit. For example, type "git push [remote-name] master". -Go back to the original repo. -Hit "new pull request" and compare between forks. -Confirm the pull request and that's it! diff --git a/Readme b/Readme deleted file mode 100644 index a8f1c6b0d..000000000 --- a/Readme +++ /dev/null @@ -1,29 +0,0 @@ -Hacktoberfest Sign In Sheet 2017! - -The goal of this repo is to help beginners who are doing their first pull requests. Feel free to join! - -Instruction - -In the index file, look for the 'ol' tag. Then insert a 'li' tag with your link to your profile. - -Git and Pull Request Resources - -Github -The Net Ninja -Awesome-Git -How to Create a Pull Request - -Click on the fork on the top to fork this repo. -Go to your repo where you forked the project. -Hit the clone button on your forked repo and copy the given link. -On your terminal / command prompt, type "git clone [put the link here]". -Change the index file in the folder. -Afterward, on your terminal / command prompt, type "git add index.html"; then 'git commit -m "[type a message]" '. -Create a remote to link the repository on github to your local workspace. use "git remote add [remote-name] [put the github link here]" -Push the commit. For example, type "git push [remote-name] master". -Go back to the original repo. -Hit "new pull request" and compare between forks. -Confirm the pull request and that's it! -Installation - -Make sure git is installed. From 06ae9c914e692ae86c1871070b1e89184caba4ee Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sat, 19 May 2018 23:26:59 -0300 Subject: [PATCH 108/152] Fix tabs and spaces on default.ps1 --- default.ps1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/default.ps1 b/default.ps1 index aef7b7d5d..cf299c631 100644 --- a/default.ps1 +++ b/default.ps1 @@ -84,7 +84,7 @@ Task ILMerge-VB { ILMerge $releaseDirVB $dllVB $projectFileVB $projectDirVB } Task ILMerge-CS { ILMerge $releaseDirCS $dllCS $projectFileCS $projectDirCS } function ILMerge($releaseDir, $dll, $projectFile, $projectDir) { - Write-Host "IL Merge:" + Write-Host "IL Merge:" $mergedDir = $tempDir if (!(Test-Path $mergedDir)) { mkdir "$mergedDir" } $inputDll = "$releaseDir\$dll" @@ -112,11 +112,11 @@ function ILMerge($releaseDir, $dll, $projectFile, $projectDir) { $releaseMergedDir = "$releaseDir\merged" if (!(Test-Path $releaseMergedDir)) { mkdir $releaseMergedDir | Out-Null } cp $mergedDll "$releaseMergedDir\" -Force - Write-Host " $dll -> $releaseMergedDir\$dll" + Write-Host " $dll -> $releaseMergedDir\$dll" $mergedPdb = Change-Extension $mergedDll "pdb" cp $mergedPdb "$releaseMergedDir\" -Force - $pdb = (ls $mergedPdb).Name - Write-Host " $pdb -> $releaseMergedDir\$pdb" + $pdb = (ls $mergedPdb).Name + Write-Host " $pdb -> $releaseMergedDir\$pdb" } function Change-Extension ($filename, $extension) { @@ -189,7 +189,7 @@ function PackNuget($language, $dir, $nuspecFile, $nupkgFile) { $nupkgFile = $nupkgFile -f $xml.package.metadata.version . $nugetExe pack "$nuspecFile" -OutputDirectory "$dir" $nuspecFileName = (ls $nuspecFile).Name - Write-Host " $nuspecFileName ($language/$($xml.package.metadata.version)) -> $nupkgFile" + Write-Host " $nuspecFileName ($language/$($xml.package.metadata.version)) -> $nupkgFile" if ($isAppVeyor) { Write-Host "Pushing nuget artifact for $language..." appveyor PushArtifact $nupkgFile From 3cf1b2fbd8f680455e3a2b5885e5689afd3216ef Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sat, 19 May 2018 23:39:05 -0300 Subject: [PATCH 109/152] Add .debug vsix projects to facilitate debug As we are il merging for release the vsix did not contain the common dll and failed on debug when running the vs instance. This fix it. --- CodeCracker.CSharp.sln | 11 +++ CodeCracker.VisualBasic.sln | 13 +++ CodeCracker.sln | 25 +++++ .../CodeCracker.Vsix.Debug.csproj | 93 +++++++++++++++++++ .../source.extension.debug.vsixmanifest | 34 +++++++ .../CodeCracker.Vsix.Debug.csproj | 93 +++++++++++++++++++ .../source.extension.debug.vsixmanifest | 34 +++++++ 7 files changed, 303 insertions(+) create mode 100644 src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj create mode 100644 src/CSharp/CodeCracker.Vsix/source.extension.debug.vsixmanifest create mode 100644 src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj create mode 100644 src/VisualBasic/CodeCracker.Vsix/source.extension.debug.vsixmanifest diff --git a/CodeCracker.CSharp.sln b/CodeCracker.CSharp.sln index e075a10f0..79a90944e 100644 --- a/CodeCracker.CSharp.sln +++ b/CodeCracker.CSharp.sln @@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test.Common", "test\Common\CodeCracker.Test.Common\CodeCracker.Test.Common.csproj", "{1CD1A3EE-28CE-404B-A59E-AEACF762D938}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{E3B0C133-B97E-46B9-809D-16BB762EF74F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -89,6 +91,12 @@ Global {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.Build.0 = Release|Any CPU {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.Build.0 = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -97,4 +105,7 @@ Global {051F1BE2-9A44-4B84-9DF8-6537852B7BBC} = {7B4F0131-D598-4692-9E2C-111E6C42C6AD} {40545653-8444-49E0-8DAD-BBB381F8A3B2} = {7B4F0131-D598-4692-9E2C-111E6C42C6AD} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {80743E34-82D0-4E0A-9514-0C85FF873E14} + EndGlobalSection EndGlobal diff --git a/CodeCracker.VisualBasic.sln b/CodeCracker.VisualBasic.sln index b338754d2..d9cc68f85 100644 --- a/CodeCracker.VisualBasic.sln +++ b/CodeCracker.VisualBasic.sln @@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test.Common", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.csproj", "{B7B513B4-0317-4F32-B560-4BFC4FAEC239}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -85,6 +87,14 @@ Global {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.ActiveCfg = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.Build.0 = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.Build.0 = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -93,4 +103,7 @@ Global {D1591C8E-982D-402F-B3CB-1D1662104425} = {3DB077DC-387D-4AAD-9ECE-96D3D24FB3A6} {22D6C608-E7F1-4236-BB07-BE5F97A4C810} = {3DB077DC-387D-4AAD-9ECE-96D3D24FB3A6} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0D75A128-4A6D-4847-9699-93EF828F5B40} + EndGlobalSection EndGlobal diff --git a/CodeCracker.sln b/CodeCracker.sln index 64406cda0..223e057b8 100644 --- a/CodeCracker.sln +++ b/CodeCracker.sln @@ -55,6 +55,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5584F20-6 test.ps1 = test.ps1 EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{E3B0C133-B97E-46B9-809D-16BB762EF74F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -123,6 +127,22 @@ Global {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Release|Any CPU.Build.0 = Release|Any CPU {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.Build.0 = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.Build.0 = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU + {E3B0C133-B97E-46B9-809D-16BB762EF74F}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -136,5 +156,10 @@ Global {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} {234973E7-794D-4BC5-8D5F-FB98D8BFA967} = {E1B8ADBF-3442-4EF3-8C6B-146B576340E9} {C5584F20-6E93-4D2D-B6F0-141B977AFC9F} = {E1B8ADBF-3442-4EF3-8C6B-146B576340E9} + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} + {E3B0C133-B97E-46B9-809D-16BB762EF74F} = {90D62FF0-A374-4C14-B827-1FFA8E384E18} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EF50C6AB-1421-41AE-8CB3-927AB24A69EA} EndGlobalSection EndGlobal diff --git a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj new file mode 100644 index 000000000..b80feb9e7 --- /dev/null +++ b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj @@ -0,0 +1,93 @@ + + + + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + 15.0 + + + + Debug + AnyCPU + 2.0 + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {E3B0C133-B97E-46B9-809D-16BB762EF74F} + Library + Properties + CodeCracker + CodeCracker.CSharp + v4.5.2 + false + false + false + false + false + false + Roslyn + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Program + $(DevEnvDir)devenv.exe + /rootsuffix Roslyn + + + + Designer + + + + + {753d4757-fcba-43ba-b1be-89201acda192} + CodeCracker.Common + + + {FF1097FB-A890-461B-979E-064697891B96} + CodeCracker + + + + + Always + true + + + Always + true + + + Always + true + + + + + + \ No newline at end of file diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.debug.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.debug.vsixmanifest new file mode 100644 index 000000000..e81a560f6 --- /dev/null +++ b/src/CSharp/CodeCracker.Vsix/source.extension.debug.vsixmanifest @@ -0,0 +1,34 @@ + + + + + Code Cracker for C# + An analyzer library for C# that uses Roslyn to produce refactorings, code analysis, and other niceties. +Check the official project site on code-cracker.github.io. +Build status Nuget count Nuget downloads Issues open +This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. + http://code-cracker.github.io/ + LICENSE.txt + http://code-cracker.github.io/changelog.html + codecrackerlogo.png + ccexample.png + ReSharper, Refactoring, code analysis, analyzer, CodeRush, roslyn, roslyn c#, Refactoring c# Roslyn + + + + + + + + + + + + + + + + + + + diff --git a/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj b/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj new file mode 100644 index 000000000..bee9c5a1c --- /dev/null +++ b/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj @@ -0,0 +1,93 @@ + + + + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + 14.0 + + + + Debug + AnyCPU + 2.0 + {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38} + Library + Properties + CodeCracker + CodeCracker.VisualBasic + v4.5.2 + false + false + false + false + false + false + Roslyn + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Program + $(DevEnvDir)devenv.exe + /rootsuffix Roslyn + + + + Designer + + + + + Always + true + + + Always + true + + + Always + true + + + + + {753d4757-fcba-43ba-b1be-89201acda192} + CodeCracker.Common + + + {41fa4971-d354-4647-a269-4a886da2ef4c} + CodeCracker + + + + + + \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.debug.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/source.extension.debug.vsixmanifest new file mode 100644 index 000000000..6f6ab34bd --- /dev/null +++ b/src/VisualBasic/CodeCracker.Vsix/source.extension.debug.vsixmanifest @@ -0,0 +1,34 @@ + + + + + Code Cracker for Visual Basic + An analyzer library for VB that uses Roslyn to produce refactorings, code analysis, and other niceties. +Check the official project site on code-cracker.github.io. +Build status Nuget count Nuget downloads Issues open +This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. + http://code-cracker.github.io/ + LICENSE.txt + http://code-cracker.github.io/changelog.html + codecrackerlogo.png + ccexample.png + ReSharper, Refactoring, code analysis, analyzer, CodeRush, roslyn, roslyn c#, Refactoring c# Roslyn + + + + + + + + + + + + + + + + + + + From 1fb3fe15ed47d6d9697866af1416c73c1b71698e Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sat, 19 May 2018 23:42:03 -0300 Subject: [PATCH 110/152] Remove support for VS 2015 --- CodeCracker.2015.sln | 140 ------------------ CodeCracker.CSharp.2015.sln | 100 ------------- CodeCracker.VisualBasic.2015.sln | 96 ------------ README.md | 6 +- default.ps1 | 2 +- .../CodeCracker.Vsix.2015.csproj | 84 ----------- .../CodeCracker.Vsix.2015.csproj | 84 ----------- 7 files changed, 3 insertions(+), 509 deletions(-) delete mode 100644 CodeCracker.2015.sln delete mode 100644 CodeCracker.CSharp.2015.sln delete mode 100644 CodeCracker.VisualBasic.2015.sln delete mode 100644 src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj delete mode 100644 src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj diff --git a/CodeCracker.2015.sln b/CodeCracker.2015.sln deleted file mode 100644 index 61766491e..000000000 --- a/CodeCracker.2015.sln +++ /dev/null @@ -1,140 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker", "src\CSharp\CodeCracker\CodeCracker.csproj", "{FF1097FB-A890-461B-979E-064697891B96}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.2015", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.2015.csproj", "{6BAC4057-7239-485E-A04B-02E687A83BAA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test", "test\CSharp\CodeCracker.Test\CodeCracker.Test.csproj", "{F7843158-046E-4B22-95D7-CAC7BB01283D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "vb", "vb", "{11473308-7FD9-43CE-84CE-5912EEFDD1DC}" -EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CodeCracker", "src\VisualBasic\CodeCracker\CodeCracker.vbproj", "{41FA4971-D354-4647-A269-4A886DA2EF4C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "cs", "cs", "{90D62FF0-A374-4C14-B827-1FFA8E384E18}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.2015", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.2015.csproj", "{B7B513B4-0317-4F32-B560-4BFC4FAEC239}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test.Common", "test\Common\CodeCracker.Test.Common\CodeCracker.Test.Common.csproj", "{1CD1A3EE-28CE-404B-A59E-AEACF762D938}" -EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CodeCracker.Test", "test\VisualBasic\CodeCracker.Test\CodeCracker.Test.vbproj", "{5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{A26BEB5D-9C92-4F60-9789-563A327605C3}" - ProjectSection(SolutionItems) = preProject - src\CodeCracker.nuspec = src\CodeCracker.nuspec - nuget.config = nuget.config - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".Solution Items", ".Solution Items", "{E1B8ADBF-3442-4EF3-8C6B-146B576340E9}" - ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes - .gitignore = .gitignore - CHANGELOG.md = CHANGELOG.md - README.md = README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{234973E7-794D-4BC5-8D5F-FB98D8BFA967}" - ProjectSection(SolutionItems) = preProject - appveyor.yml = appveyor.yml - build.ps1 = build.ps1 - default.ps1 = default.ps1 - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5584F20-6E93-4D2D-B6F0-141B977AFC9F}" - ProjectSection(SolutionItems) = preProject - test\CSharp\AnalyzeCecil.ps1 = test\CSharp\AnalyzeCecil.ps1 - test\CSharp\AnalyzeCoreFx.ps1 = test\CSharp\AnalyzeCoreFx.ps1 - test\CSharp\AnalyzeRoslyn.ps1 = test\CSharp\AnalyzeRoslyn.ps1 - runTestsCS.ps1 = runTestsCS.ps1 - runTestsVB.ps1 = runTestsVB.ps1 - test.ps1 = test.ps1 - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - DebugNoVsix|Any CPU = DebugNoVsix|Any CPU - Release|Any CPU = Release|Any CPU - ReleaseNoVsix|Any CPU = ReleaseNoVsix|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Debug|Any CPU.Build.0 = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Release|Any CPU.ActiveCfg = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Release|Any CPU.Build.0 = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Release|Any CPU.Build.0 = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.Build.0 = Release|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Release|Any CPU.Build.0 = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Release|Any CPU.Build.0 = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.Build.0 = Release|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.Build.0 = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Release|Any CPU.Build.0 = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {FF1097FB-A890-461B-979E-064697891B96} = {90D62FF0-A374-4C14-B827-1FFA8E384E18} - {6BAC4057-7239-485E-A04B-02E687A83BAA} = {90D62FF0-A374-4C14-B827-1FFA8E384E18} - {F7843158-046E-4B22-95D7-CAC7BB01283D} = {90D62FF0-A374-4C14-B827-1FFA8E384E18} - {41FA4971-D354-4647-A269-4A886DA2EF4C} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} - {B7B513B4-0317-4F32-B560-4BFC4FAEC239} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} - {234973E7-794D-4BC5-8D5F-FB98D8BFA967} = {E1B8ADBF-3442-4EF3-8C6B-146B576340E9} - {C5584F20-6E93-4D2D-B6F0-141B977AFC9F} = {E1B8ADBF-3442-4EF3-8C6B-146B576340E9} - EndGlobalSection -EndGlobal diff --git a/CodeCracker.CSharp.2015.sln b/CodeCracker.CSharp.2015.sln deleted file mode 100644 index f1ddbefd2..000000000 --- a/CodeCracker.CSharp.2015.sln +++ /dev/null @@ -1,100 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F5240AD-2B4E-48A4-B9FC-7D19DACEF2CD}" - ProjectSection(SolutionItems) = preProject - nuget.config = nuget.config - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker", "src\CSharp\CodeCracker\CodeCracker.csproj", "{FF1097FB-A890-461B-979E-064697891B96}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.2015", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.2015.csproj", "{6BAC4057-7239-485E-A04B-02E687A83BAA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test", "test\CSharp\CodeCracker.Test\CodeCracker.Test.csproj", "{F7843158-046E-4B22-95D7-CAC7BB01283D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7B4F0131-D598-4692-9E2C-111E6C42C6AD}" - ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes - .gitignore = .gitignore - CHANGELOG.md = CHANGELOG.md - README.md = README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{051F1BE2-9A44-4B84-9DF8-6537852B7BBC}" - ProjectSection(SolutionItems) = preProject - test\CSharp\AnalyzeCecil.ps1 = test\CSharp\AnalyzeCecil.ps1 - test\CSharp\AnalyzeCoreFx.ps1 = test\CSharp\AnalyzeCoreFx.ps1 - test\CSharp\AnalyzeRoslyn.ps1 = test\CSharp\AnalyzeRoslyn.ps1 - runTestsCS.ps1 = runTestsCS.ps1 - test.ps1 = test.ps1 - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{40545653-8444-49E0-8DAD-BBB381F8A3B2}" - ProjectSection(SolutionItems) = preProject - appveyor.yml = appveyor.yml - build.ps1 = build.ps1 - default.ps1 = default.ps1 - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test.Common", "test\Common\CodeCracker.Test.Common\CodeCracker.Test.Common.csproj", "{1CD1A3EE-28CE-404B-A59E-AEACF762D938}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - DebugNoVsix|Any CPU = DebugNoVsix|Any CPU - Release|Any CPU = Release|Any CPU - ReleaseNoVsix|Any CPU = ReleaseNoVsix|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {FF1097FB-A890-461B-979E-064697891B96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.Release|Any CPU.Build.0 = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.Build.0 = Release|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.Release|Any CPU.Build.0 = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {F7843158-046E-4B22-95D7-CAC7BB01283D}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Debug|Any CPU.Build.0 = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Release|Any CPU.ActiveCfg = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Release|Any CPU.Build.0 = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.Build.0 = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {051F1BE2-9A44-4B84-9DF8-6537852B7BBC} = {7B4F0131-D598-4692-9E2C-111E6C42C6AD} - {40545653-8444-49E0-8DAD-BBB381F8A3B2} = {7B4F0131-D598-4692-9E2C-111E6C42C6AD} - EndGlobalSection -EndGlobal diff --git a/CodeCracker.VisualBasic.2015.sln b/CodeCracker.VisualBasic.2015.sln deleted file mode 100644 index cec5830dd..000000000 --- a/CodeCracker.VisualBasic.2015.sln +++ /dev/null @@ -1,96 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CodeCracker", "src\VisualBasic\CodeCracker\CodeCracker.vbproj", "{41FA4971-D354-4647-A269-4A886DA2EF4C}" -EndProject -Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "CodeCracker.Test", "test\VisualBasic\CodeCracker.Test\CodeCracker.Test.vbproj", "{5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3DB077DC-387D-4AAD-9ECE-96D3D24FB3A6}" - ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes - .gitignore = .gitignore - README.md = README.md - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{5413BEBC-2F00-4B54-98E9-B1A7618C3C2A}" - ProjectSection(SolutionItems) = preProject - nuget.config = nuget.config - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D1591C8E-982D-402F-B3CB-1D1662104425}" - ProjectSection(SolutionItems) = preProject - appveyor.yml = appveyor.yml - build.ps1 = build.ps1 - default.ps1 = default.ps1 - EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{22D6C608-E7F1-4236-BB07-BE5F97A4C810}" - ProjectSection(SolutionItems) = preProject - runTestsVB.ps1 = runTestsVB.ps1 - test.ps1 = test.ps1 - EndProjectSection -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Common", "src\Common\CodeCracker.Common\CodeCracker.Common.csproj", "{753D4757-FCBA-43BA-B1BE-89201ACDA192}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test.Common", "test\Common\CodeCracker.Test.Common\CodeCracker.Test.Common.csproj", "{1CD1A3EE-28CE-404B-A59E-AEACF762D938}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.2015", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.2015.csproj", "{B7B513B4-0317-4F32-B560-4BFC4FAEC239}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - DebugNoVsix|Any CPU = DebugNoVsix|Any CPU - Release|Any CPU = Release|Any CPU - ReleaseNoVsix|Any CPU = ReleaseNoVsix|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.Release|Any CPU.Build.0 = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {41FA4971-D354-4647-A269-4A886DA2EF4C}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Release|Any CPU.Build.0 = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Debug|Any CPU.Build.0 = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Release|Any CPU.ActiveCfg = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.Release|Any CPU.Build.0 = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {753D4757-FCBA-43BA-B1BE-89201ACDA192}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.Release|Any CPU.Build.0 = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.Build.0 = Release|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {D1591C8E-982D-402F-B3CB-1D1662104425} = {3DB077DC-387D-4AAD-9ECE-96D3D24FB3A6} - {22D6C608-E7F1-4236-BB07-BE5F97A4C810} = {3DB077DC-387D-4AAD-9ECE-96D3D24FB3A6} - EndGlobalSection -EndGlobal diff --git a/README.md b/README.md index bb5318b6a..3d2511162 100644 --- a/README.md +++ b/README.md @@ -82,10 +82,8 @@ CodeCracker has a SonarQube Plugin that can be downloaded at [Plugins HomePage]( ## Contributing [![Open Source Helpers](https://www.codetriage.com/code-cracker/code-cracker/badges/users.svg)](https://www.codetriage.com/code-cracker/code-cracker) -The main supported IDE for development is Visual Studio 2015. -If you want to use VS 2015 to contribute to Code Cracker use -the *.2015.sln files. We recommend migrating to VS 2017 ASAP, as -we might make VS 2015 obsolete at any time. +The main supported IDE for development is Visual Studio 2017. +We do not support VS 2015 anymore. Questions, comments, bug reports, and pull requests are all welcome. Bug reports that include steps-to-reproduce (including code) are diff --git a/default.ps1 b/default.ps1 index cf299c631..35934cb00 100644 --- a/default.ps1 +++ b/default.ps1 @@ -5,7 +5,7 @@ Properties { $srcDir = "$rootDir\src" $testDir = "$rootDir\test" $isAppVeyor = $env:APPVEYOR -eq $true - $slns = ls "$rootDir\*.sln" | ? { ! $_.Name.Contains('.2015.') } + $slns = ls "$rootDir\*.sln" $packagesDir = "$rootDir\packages" $buildNumber = [Convert]::ToInt32($env:APPVEYOR_BUILD_NUMBER).ToString("0000") $nuspecPathCS = "$rootDir\src\CSharp\CodeCracker\CodeCracker.nuspec" diff --git a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj deleted file mode 100644 index 05f70110b..000000000 --- a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - Debug - AnyCPU - 2.0 - {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {6BAC4057-7239-485E-A04B-02E687A83BAA} - Library - Properties - CodeCracker - CodeCracker.CSharp - v4.5.2 - false - false - false - false - false - false - Roslyn - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - Program - $(DevEnvDir)devenv.exe - /rootsuffix Roslyn - - - - Designer - - - - - {FF1097FB-A890-461B-979E-064697891B96} - CodeCracker - - - - - Always - true - - - Always - true - - - Always - true - - - - - - \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj b/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj deleted file mode 100644 index dcdad50cf..000000000 --- a/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.2015.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - Debug - AnyCPU - 2.0 - {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {B7B513B4-0317-4F32-B560-4BFC4FAEC239} - Library - Properties - CodeCracker - CodeCracker.VisualBasic - v4.5.2 - false - false - false - false - false - false - Roslyn - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - Program - $(DevEnvDir)devenv.exe - /rootsuffix Roslyn - - - - Designer - - - - - Always - true - - - Always - true - - - Always - true - - - - - {41fa4971-d354-4647-a269-4a886da2ef4c} - CodeCracker - - - - - - \ No newline at end of file From 60f441311c0a0811e768223d0c7bee7f2aa0abb3 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sat, 19 May 2018 23:44:15 -0300 Subject: [PATCH 111/152] Update Copyright to 2018 --- src/CSharp/CodeCracker.Vsix/LICENSE.txt | 2 +- src/CSharp/CodeCracker/Properties/AssemblyInfo.cs | 2 +- src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs | 2 +- src/VisualBasic/CodeCracker.Vsix/LICENSE.txt | 2 +- src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb | 2 +- src/VisualBasic/CodeCracker/Properties/AssemblyInfo.cs | 2 +- test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs | 2 +- test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs | 2 +- test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/CSharp/CodeCracker.Vsix/LICENSE.txt b/src/CSharp/CodeCracker.Vsix/LICENSE.txt index 9d626bb93..2717e6ad3 100644 --- a/src/CSharp/CodeCracker.Vsix/LICENSE.txt +++ b/src/CSharp/CodeCracker.Vsix/LICENSE.txt @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2014-2015 Giovanni Bassi and Elemar Jr. + Copyright 2014-2018 Giovanni Bassi and Elemar Jr. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs b/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs index f63d51c3e..8c689a126 100644 --- a/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs +++ b/src/CSharp/CodeCracker/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CodeCracker")] -[assembly: AssemblyCopyright("Copyright © 2014-2015")] +[assembly: AssemblyCopyright("Copyright © 2014-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs b/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs index 6acd8b6ed..ff625b1e5 100644 --- a/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs +++ b/src/Common/CodeCracker.Common/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CodeCracker")] -[assembly: AssemblyCopyright("Copyright © 2014-2015")] +[assembly: AssemblyCopyright("Copyright © 2014-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/src/VisualBasic/CodeCracker.Vsix/LICENSE.txt b/src/VisualBasic/CodeCracker.Vsix/LICENSE.txt index 9d626bb93..2717e6ad3 100644 --- a/src/VisualBasic/CodeCracker.Vsix/LICENSE.txt +++ b/src/VisualBasic/CodeCracker.Vsix/LICENSE.txt @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2014-2015 Giovanni Bassi and Elemar Jr. + Copyright 2014-2018 Giovanni Bassi and Elemar Jr. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb b/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb index 4cf3474fd..89f5f1675 100644 --- a/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb +++ b/src/VisualBasic/CodeCracker/My Project/AssemblyInfo.vb @@ -8,7 +8,7 @@ Imports System.Runtime.InteropServices - + diff --git a/src/VisualBasic/CodeCracker/Properties/AssemblyInfo.cs b/src/VisualBasic/CodeCracker/Properties/AssemblyInfo.cs index 68af67824..47c3f28ae 100644 --- a/src/VisualBasic/CodeCracker/Properties/AssemblyInfo.cs +++ b/src/VisualBasic/CodeCracker/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CodeCracker")] -[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyCopyright("Copyright © 2014-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs b/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs index db28a8bed..355d9badb 100644 --- a/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs +++ b/test/CSharp/CodeCracker.Test/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CodeCracker")] -[assembly: AssemblyCopyright("Copyright © 2014-2015")] +[assembly: AssemblyCopyright("Copyright © 2014-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs b/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs index b095e814c..c0189f778 100644 --- a/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs +++ b/test/Common/CodeCracker.Test.Common/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CodeCracker")] -[assembly: AssemblyCopyright("Copyright © 2014-2015")] +[assembly: AssemblyCopyright("Copyright © 2014-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] diff --git a/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb b/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb index 471e8e0cc..d3b84acfd 100644 --- a/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb +++ b/test/VisualBasic/CodeCracker.Test/My Project/AssemblyInfo.vb @@ -8,7 +8,7 @@ Imports System.Runtime.InteropServices - + From eeae7e78e290c32bc01c8a1933ca24644d05a357 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 00:47:00 -0300 Subject: [PATCH 112/152] Fix vsix debug build --- CodeCracker.CSharp.sln | 2 -- CodeCracker.VisualBasic.sln | 16 ++++----- CodeCracker.sln | 22 ++++-------- .../CodeCracker.Vsix.Debug.csproj | 11 ++---- .../CodeCracker.Vsix/CodeCracker.Vsix.csproj | 5 --- .../source.extension.vsixmanifest} | 0 .../CodeCracker.Vsix.Debug.csproj | 35 ++++++++----------- .../CodeCracker.Vsix/CodeCracker.Vsix.csproj | 9 ++--- .../source.extension.vsixmanifest} | 0 9 files changed, 33 insertions(+), 67 deletions(-) rename src/CSharp/CodeCracker.Vsix/{source.extension.debug.vsixmanifest => debug/source.extension.vsixmanifest} (100%) rename src/VisualBasic/CodeCracker.Vsix/{source.extension.debug.vsixmanifest => debug/source.extension.vsixmanifest} (100%) diff --git a/CodeCracker.CSharp.sln b/CodeCracker.CSharp.sln index 79a90944e..9090838a1 100644 --- a/CodeCracker.CSharp.sln +++ b/CodeCracker.CSharp.sln @@ -62,7 +62,6 @@ Global {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.Build.0 = Release|Any CPU @@ -95,7 +94,6 @@ Global {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.Build.0 = Debug|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.Build.0 = Release|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution diff --git a/CodeCracker.VisualBasic.sln b/CodeCracker.VisualBasic.sln index d9cc68f85..e4feebe4e 100644 --- a/CodeCracker.VisualBasic.sln +++ b/CodeCracker.VisualBasic.sln @@ -39,7 +39,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Test.Common", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.csproj", "{B7B513B4-0317-4F32-B560-4BFC4FAEC239}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{7F08D429-91E1-4B47-B3B2-A98754C8DFA7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -82,19 +82,15 @@ Global {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {1CD1A3EE-28CE-404B-A59E-AEACF762D938}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.Build.0 = Debug|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.ActiveCfg = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.Build.0 = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.Build.0 = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CodeCracker.sln b/CodeCracker.sln index 223e057b8..0ca6815d1 100644 --- a/CodeCracker.sln +++ b/CodeCracker.sln @@ -55,7 +55,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5584F20-6 test.ps1 = test.ps1 EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\VisualBasic\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{7F08D429-91E1-4B47-B3B2-A98754C8DFA7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeCracker.Vsix.Debug", "src\CSharp\CodeCracker.Vsix\CodeCracker.Vsix.Debug.csproj", "{E3B0C133-B97E-46B9-809D-16BB762EF74F}" EndProject @@ -84,7 +84,6 @@ Global {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {FF1097FB-A890-461B-979E-064697891B96}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6BAC4057-7239-485E-A04B-02E687A83BAA}.Debug|Any CPU.Build.0 = Debug|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.ActiveCfg = Release|Any CPU {6BAC4057-7239-485E-A04B-02E687A83BAA}.Release|Any CPU.Build.0 = Release|Any CPU @@ -106,7 +105,6 @@ Global {41FA4971-D354-4647-A269-4A886DA2EF4C}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {41FA4971-D354-4647-A269-4A886DA2EF4C}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Debug|Any CPU.Build.0 = Debug|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.ActiveCfg = Release|Any CPU {B7B513B4-0317-4F32-B560-4BFC4FAEC239}.Release|Any CPU.Build.0 = Release|Any CPU @@ -127,22 +125,16 @@ Global {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.Release|Any CPU.Build.0 = Release|Any CPU {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Debug|Any CPU.Build.0 = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.ActiveCfg = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.Release|Any CPU.Build.0 = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Debug|Any CPU.Build.0 = Debug|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.DebugNoVsix|Any CPU.ActiveCfg = Debug|Any CPU - {E3B0C133-B97E-46B9-809D-16BB762EF74F}.DebugNoVsix|Any CPU.Build.0 = Debug|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E3B0C133-B97E-46B9-809D-16BB762EF74F}.Release|Any CPU.Build.0 = Release|Any CPU {E3B0C133-B97E-46B9-809D-16BB762EF74F}.ReleaseNoVsix|Any CPU.ActiveCfg = Release|Any CPU - {E3B0C133-B97E-46B9-809D-16BB762EF74F}.ReleaseNoVsix|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -156,7 +148,7 @@ Global {5399E7A8-F8F1-4F2E-A5D2-9C96F3DD2A2D} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} {234973E7-794D-4BC5-8D5F-FB98D8BFA967} = {E1B8ADBF-3442-4EF3-8C6B-146B576340E9} {C5584F20-6E93-4D2D-B6F0-141B977AFC9F} = {E1B8ADBF-3442-4EF3-8C6B-146B576340E9} - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7} = {11473308-7FD9-43CE-84CE-5912EEFDD1DC} {E3B0C133-B97E-46B9-809D-16BB762EF74F} = {90D62FF0-A374-4C14-B827-1FFA8E384E18} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj index b80feb9e7..a16c94bc4 100644 --- a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj +++ b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj @@ -4,11 +4,6 @@ 15.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - 15.0 @@ -34,7 +29,7 @@ true full false - bin\Debug\ + debug\bin\Debug\ DEBUG;TRACE prompt 4 @@ -42,7 +37,7 @@ pdbonly true - bin\Release\ + debug\bin\Release\ TRACE prompt 4 @@ -53,7 +48,7 @@ /rootsuffix Roslyn - + Designer diff --git a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj index 12f744c47..94bd31424 100644 --- a/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj +++ b/src/CSharp/CodeCracker.Vsix/CodeCracker.Vsix.csproj @@ -4,11 +4,6 @@ 15.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - 15.0 diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.debug.vsixmanifest b/src/CSharp/CodeCracker.Vsix/debug/source.extension.vsixmanifest similarity index 100% rename from src/CSharp/CodeCracker.Vsix/source.extension.debug.vsixmanifest rename to src/CSharp/CodeCracker.Vsix/debug/source.extension.vsixmanifest diff --git a/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj b/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj index bee9c5a1c..55bfcbb15 100644 --- a/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj +++ b/src/VisualBasic/CodeCracker.Vsix/CodeCracker.Vsix.Debug.csproj @@ -1,14 +1,9 @@  - + 15.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - 14.0 @@ -16,7 +11,7 @@ AnyCPU 2.0 {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - {47FBCA0A-029D-4D7A-89F0-EF5D85E93F38} + {7F08D429-91E1-4B47-B3B2-A98754C8DFA7} Library Properties CodeCracker @@ -34,7 +29,7 @@ true full false - bin\Debug\ + debug\bin\Debug\ DEBUG;TRACE prompt 4 @@ -42,7 +37,7 @@ pdbonly true - bin\Release\ + debug\bin\Release\ TRACE prompt 4 @@ -53,10 +48,20 @@ /rootsuffix Roslyn - + Designer + + + {753d4757-fcba-43ba-b1be-89201acda192} + CodeCracker.Common + + + {41fa4971-d354-4647-a269-4a886da2ef4c} + CodeCracker + + Always @@ -71,16 +76,6 @@ true - - - {753d4757-fcba-43ba-b1be-89201acda192} - CodeCracker.Common - - - {41fa4971-d354-4647-a269-4a886da2ef4c} - CodeCracker - - - \ No newline at end of file + diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.debug.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/debug/source.extension.vsixmanifest similarity index 100% rename from src/VisualBasic/CodeCracker.Vsix/source.extension.debug.vsixmanifest rename to src/VisualBasic/CodeCracker.Vsix/debug/source.extension.vsixmanifest From 5d086f3e7d16a86dcc8d79a765454e78824c6600 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 01:06:12 -0300 Subject: [PATCH 113/152] Remove branch vnext from appveyor config --- appveyor.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ac50d45ed..a94277ef7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -62,13 +62,6 @@ deploy: skip_symbols: true on: branch: master -- provider: NuGet - server: https://www.myget.org/F/codecrackerbuild/api/v2/package - api_key: - secure: 42eslsnaZIIcMVVaeC9Qu5NI9yjzLzHWYUGl0HLhl0YurivQezpMyJOwgSVjiGmj - skip_symbols: true - on: - branch: vnext - provider: NuGet server: https://www.myget.org/F/codecrackerbuild/api/v2/package api_key: From 1adbd86401318177329c4f806982ef70d31fc5e8 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 01:22:57 -0300 Subject: [PATCH 114/152] Update Nuget key for AppVeyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a94277ef7..362ed41d3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -51,7 +51,7 @@ artifacts: deploy: - provider: NuGet api_key: - secure: s1aIT1sGbIeG5Ccgree7K+k/h7LOSzPfJOrsWcCuzgFGrcuexPZUwX/CfYnU9w4v + secure: CosNPh0GfqQtJs2da/qdtykCGRhaJ1keXXxAcEFR0jNGAmveTtj01kPfqIlLPjFv skip_symbols: true on: appveyor_repo_tag: true From 29f6d1e2c8e99d7ac3e624cc5298c2e7de407488 Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 02:34:26 -0300 Subject: [PATCH 115/152] Update changelog --- CHANGELOG.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b460cecb..38443cb46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,55 @@ ## [Unreleased](https://github.com/code-cracker/code-cracker/tree/HEAD) -[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.3...HEAD) +[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.1.0...HEAD) + +**Fixed bugs:** + +- TernaryOperatorWithReturnCodeFixProvider NullReferenceException [\#906](https://github.com/code-cracker/code-cracker/issues/906) + +- Update VS Code Galley page -- broken link for code-cracker.github.io [\#546](https://github.com/code-cracker/code-cracker/issues/546) +- Is there any way to config inspect severity? Some errors are not necessary but noisy [\#543](https://github.com/code-cracker/code-cracker/issues/543) +- Prefer "Count" to "Count\(\)" [\#489](https://github.com/code-cracker/code-cracker/issues/489) + +## [v1.1.0](https://github.com/code-cracker/code-cracker/tree/v1.1.0) (2018-05-20) +[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.3...v1.1.0) + +**Implemented enhancements:** + +- Create a reusable FixAllProvider based on IntroduceFieldFromConstructorCodeFixProviderAll [\#910](https://github.com/code-cracker/code-cracker/issues/910) +- Enable CodeCracker to work with .NET Core [\#871](https://github.com/code-cracker/code-cracker/issues/871) +- CC0068 \(Remove private method\): ShouldSerializeXXX\(\) and ResetXXX\(\) should not trigger the message [\#762](https://github.com/code-cracker/code-cracker/issues/762) +- Create PropertyChangedEventArgs statically [\#42](https://github.com/code-cracker/code-cracker/issues/42) + +- CC0013 Check for applicability as argument [\#522](https://github.com/code-cracker/code-cracker/issues/522) +- Make readonly \(for complex value types\) [\#808](https://github.com/code-cracker/code-cracker/issues/808) +- CC0120: Suggest default for switch statements \(C\#\) [\#780](https://github.com/code-cracker/code-cracker/issues/780) +- Remove Unnecessary ToString in String Concatenation [\#753](https://github.com/code-cracker/code-cracker/issues/753) +- Check consistency of optional parameter default value [\#575](https://github.com/code-cracker/code-cracker/issues/575) +- Make accessibility consistent \(code fix for CS0050 to CS0061\) [\#381](https://github.com/code-cracker/code-cracker/issues/381) +- Prefer "Any" to "Count\(\) \> 0" [\#490](https://github.com/code-cracker/code-cracker/issues/490) +- Extract Class to a New File [\#382](https://github.com/code-cracker/code-cracker/issues/382) +- Seal member if possible [\#372](https://github.com/code-cracker/code-cracker/issues/372) +- Remove virtual modifier if possible [\#371](https://github.com/code-cracker/code-cracker/issues/371) +- Remove async and return task directly [\#151](https://github.com/code-cracker/code-cracker/issues/151) +- Change from as operator to direct cast or the opposite [\#65](https://github.com/code-cracker/code-cracker/issues/65) +- Convert loop to linq expression [\#22](https://github.com/code-cracker/code-cracker/issues/22) + +**Fixed bugs:** + +- CC0061 shouldn't pop for async Main [\#958](https://github.com/code-cracker/code-cracker/issues/958) +- Bug: CC0061: Implementing interface using async keyword should not raise a diagnostic [\#936](https://github.com/code-cracker/code-cracker/issues/936) +- Bug CC0031 UseInvokeMethodToFireEventAnalyzer false positive in constructor [\#926](https://github.com/code-cracker/code-cracker/issues/926) +- BUG: CC0014 Casting to interface or implicit casts for the ternary operator are fixed wrong [\#911](https://github.com/code-cracker/code-cracker/issues/911) +- BUG: CC0022 failed to show fix with null coalesce operator [\#870](https://github.com/code-cracker/code-cracker/issues/870) +- BUG: CC0118 - Unnecessary '.ToString\(\)' call in string concatenation [\#866](https://github.com/code-cracker/code-cracker/issues/866) + +**Closed issues:** + +- Support Hacktoberfest event adding hacktoberfest tag. [\#949](https://github.com/code-cracker/code-cracker/issues/949) +- Using Extension & NuGet package together causes VS2017 to crash [\#944](https://github.com/code-cracker/code-cracker/issues/944) +- False postives and NullReferenceException when using eventhandler in code behind for UWP apps. [\#916](https://github.com/code-cracker/code-cracker/issues/916) +- Replace getter only properties with backing readonly field with getter-only auto-property [\#881](https://github.com/code-cracker/code-cracker/issues/881) ## [v1.0.3](https://github.com/code-cracker/code-cracker/tree/v1.0.3) (2017-03-20) [Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.2...v1.0.3) @@ -38,6 +86,7 @@ **Implemented enhancements:** +- developmentDependency not added when used with SonarLint [\#829](https://github.com/code-cracker/code-cracker/issues/829) - Auto generated files detection [\#773](https://github.com/code-cracker/code-cracker/issues/773) **Fixed bugs:** @@ -49,7 +98,7 @@ - BUG: GC.SuppressFinalize with arrow methods \(CC0029\) [\#809](https://github.com/code-cracker/code-cracker/issues/809) - Bug: CC0039 False positive when concatenating to loop variable propery/field \(StringBuilderInLoop\) [\#797](https://github.com/code-cracker/code-cracker/issues/797) - Bug: CC0033 appears again after adding 'this' keyword [\#795](https://github.com/code-cracker/code-cracker/issues/795) -- CC0061: Implementing interface using async [\#793](https://github.com/code-cracker/code-cracker/issues/793) +- CC0061: Implementing interface using async pattern [\#793](https://github.com/code-cracker/code-cracker/issues/793) - CC0052 Make field readonly does not take ref out into consideration. [\#788](https://github.com/code-cracker/code-cracker/issues/788) - BUG: CallExtensionMethodAsExtensionAnalyzer threw exception when project language was C\# 5.0 [\#781](https://github.com/code-cracker/code-cracker/issues/781) - Bug: UseInvokeMethodToFireEventAnalyzer \(CC0031\) should not raise a diagnostic when already checked for null with a ternary [\#779](https://github.com/code-cracker/code-cracker/issues/779) @@ -225,6 +274,7 @@ - Update VB Allow Members Ordering to work with Modules [\#440](https://github.com/code-cracker/code-cracker/issues/440) - Provide an equivalence key on all code fix providers [\#417](https://github.com/code-cracker/code-cracker/issues/417) - Unit test methods raises CC0091 - "Make \ method static" [\#404](https://github.com/code-cracker/code-cracker/issues/404) +- Validate color from System.Drawing.ColorTranslator.FromHtml [\#1](https://github.com/code-cracker/code-cracker/issues/1) **Fixed bugs:** From ed8b7ed923fd1f059a6620798153ef7c9d030d0c Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 02:34:44 -0300 Subject: [PATCH 116/152] Add helpers to cound analyzers and update changelog --- default.ps1 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/default.ps1 b/default.ps1 index 35934cb00..da06d79a4 100644 --- a/default.ps1 +++ b/default.ps1 @@ -181,6 +181,30 @@ Task Pack-Nuget-VB-Force { PackNuget "VB" "$rootDir\src\VisualBasic" $nuspecPathVB $nupkgPathVB } +Task Count-Analyzers { + $count = $(ls $rootDir\src\*.cs -Recurse | ? { $_.Name.contains('Analyzer') } | ? { !((cat $_) -match 'abstract class') }).count + Write-Host "Found $count C# Analyzers" + $count = $(ls $rootDir\src\*.cs -Recurse | ? { $_.Name.contains('CodeFix') } | ? { !((cat $_) -match 'abstract class') }).count + Write-Host "Found $count C# Code Fixes" + $count = $(ls $rootDir\src\*.cs -Recurse | ? { $_.Name.contains('FixAll') } | ? { !((cat $_) -match 'abstract class') }).count + Write-Host "Found $count C# Code Fixes All" + $count = $(ls $rootDir\src\*.vb -Recurse | ? { $_.Name.contains('Analyzer') } | ? { !((cat $_) -match 'mustinherit class') }).count + Write-Host "Found $count VB Analyzers" + $count = $(ls $rootDir\src\*.vb -Recurse | ? { $_.Name.contains('CodeFix') } | ? { !((cat $_) -match 'mustinherit class') }).count + Write-Host "Found $count VB Code Fixes" + $count = $(ls $rootDir\src\*.vb -Recurse | ? { $_.Name.contains('FixAll') } | ? { !((cat $_) -match 'mustinherit class') }).count + Write-Host "Found $count VB Code Fixes All" +} + +Task Update-ChangeLog { + # invoke-psake default.ps1 -tasklist update-changelog -parameters @{"token"=""} + echo $token + return + Exec { + github_changelog_generator code-cracker/code-cracker --no-pull-requests --no-issues-wo-labels --exclude-labels "Can't repro","update readme",decision,docs,duplicate,question,invalid,wontfix,Duplicate,Question,Invalid,Wontfix -t $token + } +} + Task Echo { echo echo } function PackNuget($language, $dir, $nuspecFile, $nupkgFile) { From 5a4d7b9f2b36404b1d89416e45fb0749558e01fe Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 02:39:10 -0300 Subject: [PATCH 117/152] Fix changelog --- CHANGELOG.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38443cb46..d44726355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,17 +1,5 @@ # Change Log -## [Unreleased](https://github.com/code-cracker/code-cracker/tree/HEAD) - -[Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.1.0...HEAD) - -**Fixed bugs:** - -- TernaryOperatorWithReturnCodeFixProvider NullReferenceException [\#906](https://github.com/code-cracker/code-cracker/issues/906) - -- Update VS Code Galley page -- broken link for code-cracker.github.io [\#546](https://github.com/code-cracker/code-cracker/issues/546) -- Is there any way to config inspect severity? Some errors are not necessary but noisy [\#543](https://github.com/code-cracker/code-cracker/issues/543) -- Prefer "Count" to "Count\(\)" [\#489](https://github.com/code-cracker/code-cracker/issues/489) - ## [v1.1.0](https://github.com/code-cracker/code-cracker/tree/v1.1.0) (2018-05-20) [Full Changelog](https://github.com/code-cracker/code-cracker/compare/v1.0.3...v1.1.0) @@ -29,6 +17,7 @@ - Check consistency of optional parameter default value [\#575](https://github.com/code-cracker/code-cracker/issues/575) - Make accessibility consistent \(code fix for CS0050 to CS0061\) [\#381](https://github.com/code-cracker/code-cracker/issues/381) - Prefer "Any" to "Count\(\) \> 0" [\#490](https://github.com/code-cracker/code-cracker/issues/490) +- Prefer "Count" to "Count\(\)" [\#489](https://github.com/code-cracker/code-cracker/issues/489) - Extract Class to a New File [\#382](https://github.com/code-cracker/code-cracker/issues/382) - Seal member if possible [\#372](https://github.com/code-cracker/code-cracker/issues/372) - Remove virtual modifier if possible [\#371](https://github.com/code-cracker/code-cracker/issues/371) @@ -42,6 +31,7 @@ - Bug: CC0061: Implementing interface using async keyword should not raise a diagnostic [\#936](https://github.com/code-cracker/code-cracker/issues/936) - Bug CC0031 UseInvokeMethodToFireEventAnalyzer false positive in constructor [\#926](https://github.com/code-cracker/code-cracker/issues/926) - BUG: CC0014 Casting to interface or implicit casts for the ternary operator are fixed wrong [\#911](https://github.com/code-cracker/code-cracker/issues/911) +- TernaryOperatorWithReturnCodeFixProvider NullReferenceException [\#906](https://github.com/code-cracker/code-cracker/issues/906) - BUG: CC0022 failed to show fix with null coalesce operator [\#870](https://github.com/code-cracker/code-cracker/issues/870) - BUG: CC0118 - Unnecessary '.ToString\(\)' call in string concatenation [\#866](https://github.com/code-cracker/code-cracker/issues/866) From 7b3e176a16856ec622bb4f4bbb7e178f04b3f37a Mon Sep 17 00:00:00 2001 From: Giovanni Bassi Date: Sun, 20 May 2018 04:31:34 -0300 Subject: [PATCH 118/152] Update dependencies --- .nuget/packages.config | 4 +- CodeCracker.sln | 2 +- build.ps1 | 4 +- default.ps1 => psakefile.ps1 | 10 ++--- src/CSharp/CodeCracker/CodeCracker.csproj | 5 +-- ...nconsistentAccessibilityCodeFixProvider.cs | 2 + .../CodeCracker/Design/NameOfAnalyzer.cs | 2 + .../Extensions/CSharpAnalyzerExtensions.cs | 9 ++++- .../AddBracesToSwitchSectionsAnalyzer.cs | 2 + ...dEventArgsUnnecessaryAllocationAnalyzer.cs | 2 + .../SplitIntoNestedIfFixAllProvider.cs | 3 +- .../Style/StringFormatFixAllProvider.cs | 3 +- .../SwitchToAutoPropCodeFixAllProvider.cs | 3 +- ...ryToStringInStringConcatenationAnalyzer.cs | 10 ++--- .../Style/UseEmptyStringCodeFixProviderAll.cs | 3 +- .../Style/UseStringEmptyCodeFixProviderAll.cs | 3 +- ...osableVariableNotDisposedFixAllProvider.cs | 3 +- .../RemoveUnreachableCodeFixAllProvider.cs | 3 +- .../UnusedParametersCodeFixAllProvider.cs | 3 +- src/CSharp/CodeCracker/packages.config | 2 +- .../CodeCracker.Common.csproj | 5 +-- .../DocumentCodeFixProviderAll.cs | 3 +- src/Common/CodeCracker.Common/packages.config | 2 +- .../CodeCracker/CodeCracker.vbproj | 5 +-- src/VisualBasic/CodeCracker/packages.config | 2 +- .../CodeCracker.Test/CodeCracker.Test.csproj | 40 ++++++++++--------- .../Refactoring/NumericLiteralTests.cs | 1 + .../ConvertToExpressionBodiedMemberTests.cs | 2 + .../Style/RemoveAsyncFromMethodTests.cs | 4 +- .../Usage/RemoveUnusedVariablesTest.cs | 14 ------- test/CSharp/CodeCracker.Test/packages.config | 20 +++++----- .../CodeCracker.Test.Common.csproj | 38 ++++++++++-------- .../CodeCracker.Test.Common/packages.config | 24 ++++++----- .../CodeCracker.Test/CodeCracker.Test.vbproj | 39 +++++++++--------- .../CodeCracker.Test/packages.config | 20 +++++----- 35 files changed, 164 insertions(+), 133 deletions(-) rename default.ps1 => psakefile.ps1 (97%) diff --git a/.nuget/packages.config b/.nuget/packages.config index 9707f7736..ad3995ace 100644 --- a/.nuget/packages.config +++ b/.nuget/packages.config @@ -1,6 +1,6 @@  - - + + diff --git a/CodeCracker.sln b/CodeCracker.sln index 0ca6815d1..4a19abe95 100644 --- a/CodeCracker.sln +++ b/CodeCracker.sln @@ -42,7 +42,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{234973E7 ProjectSection(SolutionItems) = preProject appveyor.yml = appveyor.yml build.ps1 = build.ps1 - default.ps1 = default.ps1 + psakefile.ps1 = psakefile.ps1 EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5584F20-6E93-4D2D-B6F0-141B977AFC9F}" diff --git a/build.ps1 b/build.ps1 index 27cd8f2d8..a5bf95542 100644 --- a/build.ps1 +++ b/build.ps1 @@ -49,7 +49,7 @@ function Download-Nuget { } function Import-Psake { - $psakeModule = "$PSScriptRoot\packages\psake.4.6.0\tools\psake.psm1" + $psakeModule = "$PSScriptRoot\packages\psake.4.7.0\tools\psake\psake.psm1" if ((Test-Path $psakeModule) -ne $true) { Write-Host "Restoring $PSScriptRoot\.nuget with $script:nugetExe" . "$script:nugetExe" restore $PSScriptRoot\.nuget\packages.config -SolutionDirectory $PSScriptRoot @@ -73,7 +73,7 @@ Get-Nuget Import-Psake Import-ILMerge if ($MyInvocation.UnboundArguments.Count -ne 0) { - Invoke-Expression("Invoke-psake -framework '4.6' $PSScriptRoot\default.ps1 -taskList " + $MyInvocation.UnboundArguments -join " ") + Invoke-Expression("Invoke-psake -framework '4.6' $PSScriptRoot\psakefile.ps1 -taskList " + $MyInvocation.UnboundArguments -join " ") } else { . $PSScriptRoot\build.ps1 Build diff --git a/default.ps1 b/psakefile.ps1 similarity index 97% rename from default.ps1 rename to psakefile.ps1 index da06d79a4..146b33f54 100644 --- a/default.ps1 +++ b/psakefile.ps1 @@ -10,11 +10,11 @@ Properties { $buildNumber = [Convert]::ToInt32($env:APPVEYOR_BUILD_NUMBER).ToString("0000") $nuspecPathCS = "$rootDir\src\CSharp\CodeCracker\CodeCracker.nuspec" $nuspecPathVB = "$rootDir\src\VisualBasic\CodeCracker\CodeCracker.nuspec" - $nugetPackagesExe = "$packagesDir\NuGet.CommandLine.4.1.0\tools\NuGet.exe" + $nugetPackagesExe = "$packagesDir\NuGet.CommandLine.4.6.2\tools\NuGet.exe" $nugetExe = if (Test-Path $nugetPackagesExe) { $nugetPackagesExe } else { 'nuget' } $nupkgPathCS = "$rootDir\src\CSharp\CodeCracker.CSharp.{0}.nupkg" $nupkgPathVB = "$rootDir\src\VisualBasic\CodeCracker.VisualBasic.{0}.nupkg" - $xunitConsoleExe = "$packagesDir\xunit.runner.console.2.2.0\tools\xunit.console.x86.exe" + $xunitConsoleExe = "$packagesDir\xunit.runner.console.2.3.1\tools\net452\xunit.console.x86.exe" $openCoverExe = "$packagesDir\OpenCover.4.6.519\tools\OpenCover.Console.exe" $dllCS = "CodeCracker.CSharp.dll" $dllVB = "CodeCracker.VisualBasic.dll" @@ -31,9 +31,9 @@ Properties { $releaseDirCS = "$projectDirCS\bin\Release" $logDir = "$rootDir\log" $outputXml = "$logDir\CodeCoverageResults.xml" - $reportGeneratorExe = "$packagesDir\ReportGenerator.2.5.6\tools\ReportGenerator.exe" + $reportGeneratorExe = "$packagesDir\ReportGenerator.3.1.2\tools\ReportGenerator.exe" $coverageReportDir = "$logDir\codecoverage\" - $coverallsNetExe = "$packagesDir\coveralls.io.1.3.4\tools\coveralls.net.exe" + $coverallsNetExe = "$packagesDir\coveralls.io.1.4.2\tools\coveralls.net.exe" $ilmergeExe = "$packagesDir\ilmerge.2.14.1208\tools\ILMerge.exe" $isRelease = $isAppVeyor -and (($env:APPVEYOR_REPO_BRANCH -eq "release") -or ($env:APPVEYOR_REPO_TAG -eq "true")) $isPullRequest = $env:APPVEYOR_PULL_REQUEST_NUMBER -ne $null @@ -233,7 +233,7 @@ function UpdateNuspec($nuspecPath, $language) { function RestorePkgs($sln) { Write-Host "Restoring $sln..." -ForegroundColor Green Retry { - . $nugetExe restore "$sln" -MSBuildVersion 14 -NonInteractive -ConfigFile "$rootDir\nuget.config" + . $nugetExe restore "$sln" -NonInteractive -ConfigFile "$rootDir\nuget.config" if ($LASTEXITCODE) { throw "Nuget restore for $sln failed." } } } diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index 22c6e50a0..337211dff 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -1,5 +1,5 @@  - + 11.0 @@ -223,8 +223,7 @@ - - + diff --git a/src/CSharp/CodeCracker/Design/InconsistentAccessibility/InconsistentAccessibilityCodeFixProvider.cs b/src/CSharp/CodeCracker/Design/InconsistentAccessibility/InconsistentAccessibilityCodeFixProvider.cs index d8937aca7..f99e9e991 100644 --- a/src/CSharp/CodeCracker/Design/InconsistentAccessibility/InconsistentAccessibilityCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Design/InconsistentAccessibility/InconsistentAccessibilityCodeFixProvider.cs @@ -72,6 +72,8 @@ private static async Task GetInconsistentAccessib case InconsistentAccessibilityInIndexerParameterCompilerErrorNumber: inconsistentAccessibilityProvider = new InconsistentAccessibilityInIndexerParameter(); break; + default: + break; } return await inconsistentAccessibilityProvider.GetInconsistentAccessibilityInfoAsync(document, diagnostic, cancellationToken).ConfigureAwait(false); diff --git a/src/CSharp/CodeCracker/Design/NameOfAnalyzer.cs b/src/CSharp/CodeCracker/Design/NameOfAnalyzer.cs index 9681645cc..1631dc9f9 100644 --- a/src/CSharp/CodeCracker/Design/NameOfAnalyzer.cs +++ b/src/CSharp/CodeCracker/Design/NameOfAnalyzer.cs @@ -114,6 +114,8 @@ private static string GetParameterNameThatMatchStringLiteral(LiteralExpressionSy break; case SyntaxKind.AttributeList: break; + default: + break; } parameterName = GetParameterWithIdentifierEqualToStringLiteral(stringLiteral, parameters)?.Identifier.Text; } diff --git a/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs b/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs index 0ccb8b5a6..6b79daa2b 100644 --- a/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs +++ b/src/CSharp/CodeCracker/Extensions/CSharpAnalyzerExtensions.cs @@ -317,6 +317,8 @@ private static string GetLastIdentifierValueText(CSharpSyntaxNode node) case SyntaxKind.AliasQualifiedName: result = ((AliasQualifiedNameSyntax)node).Name.Identifier.ValueText; break; + default: + break; } return result; } @@ -336,8 +338,9 @@ public static SyntaxToken GetIdentifier(this BaseMethodDeclarationSyntax method) case SyntaxKind.DestructorDeclaration: result = ((DestructorDeclarationSyntax)method).Identifier; break; + default: + return result; } - return result; } @@ -392,6 +395,8 @@ public static MemberDeclarationSyntax WithModifiers(this MemberDeclarationSyntax case SyntaxKind.EventDeclaration: result = ((EventDeclarationSyntax)declaration).WithModifiers(newModifiers); break; + default: + break; } return result; @@ -428,6 +433,8 @@ public static SyntaxTokenList GetModifiers(this MemberDeclarationSyntax memberDe case SyntaxKind.EventDeclaration: result = ((BasePropertyDeclarationSyntax)memberDeclaration).Modifiers; break; + default: + break; } return result; diff --git a/src/CSharp/CodeCracker/Refactoring/AddBracesToSwitchSectionsAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/AddBracesToSwitchSectionsAnalyzer.cs index 33012a4af..6ef64c506 100644 --- a/src/CSharp/CodeCracker/Refactoring/AddBracesToSwitchSectionsAnalyzer.cs +++ b/src/CSharp/CodeCracker/Refactoring/AddBracesToSwitchSectionsAnalyzer.cs @@ -47,6 +47,8 @@ internal static bool HasBraces(SwitchSectionSyntax section) if (section.Statements.First() is BlockSyntax && section.Statements.Last() is BreakStatementSyntax) return true; break; + default: + break; } return false; } diff --git a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs index e9924b9d3..a3f061c3e 100644 --- a/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs +++ b/src/CSharp/CodeCracker/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationAnalyzer.cs @@ -78,6 +78,8 @@ private static bool IsAlreadyStatic(ObjectCreationExpressionSyntax objectCreatio var fieldDeclaration = (FieldDeclarationSyntax)memberForObjectCreationExpr; result = ContainsStaticModifier(fieldDeclaration.Modifiers); break; + default: + break; } return result; } diff --git a/src/CSharp/CodeCracker/Refactoring/SplitIntoNestedIfFixAllProvider.cs b/src/CSharp/CodeCracker/Refactoring/SplitIntoNestedIfFixAllProvider.cs index 568e8af7c..3ca46c2ef 100644 --- a/src/CSharp/CodeCracker/Refactoring/SplitIntoNestedIfFixAllProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/SplitIntoNestedIfFixAllProvider.cs @@ -25,8 +25,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(SplitIntoNestedIfCodeFixProvider.MessageFormat, ct => GetFixedSolutionAsync(fixAllContext))); + default: + return null; } - return null; } private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) diff --git a/src/CSharp/CodeCracker/Style/StringFormatFixAllProvider.cs b/src/CSharp/CodeCracker/Style/StringFormatFixAllProvider.cs index 1c3416c81..055b0e517 100644 --- a/src/CSharp/CodeCracker/Style/StringFormatFixAllProvider.cs +++ b/src/CSharp/CodeCracker/Style/StringFormatFixAllProvider.cs @@ -26,8 +26,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(Resources.StringFormatCodeFixProvider_Title, ct => GetFixedSolutionAsync(fixAllContext))); + default: + return null; } - return null; } private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) diff --git a/src/CSharp/CodeCracker/Style/SwitchToAutoPropCodeFixAllProvider.cs b/src/CSharp/CodeCracker/Style/SwitchToAutoPropCodeFixAllProvider.cs index 5499d07c8..8fa876860 100644 --- a/src/CSharp/CodeCracker/Style/SwitchToAutoPropCodeFixAllProvider.cs +++ b/src/CSharp/CodeCracker/Style/SwitchToAutoPropCodeFixAllProvider.cs @@ -27,8 +27,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(Resources.SwitchToAutoPropCodeFixProvider_Title, async ct => await GetFixedSolutionAsync(fixAllContext, await GetSolutionWithDocsAsync(fixAllContext, fixAllContext.Solution)))); + default: + return null; } - return null; } private async static Task GetSolutionWithDocsAsync(FixAllContext fixAllContext, Solution solution) diff --git a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs index 23fa9dcbe..20bc013e4 100644 --- a/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/UnnecessaryToStringInStringConcatenationAnalyzer.cs @@ -70,7 +70,7 @@ private static IEnumerable FilterInvocationsThatAreR foreach (var node in invocationExpressionsThatHaveToStringCall) { var toStringReceiver = GetTypeInfoOfReceiverOfToStringCall(node, semanticModel, cancellationToken); - //As long as the underlying type can not be resolved by the compiler (e.g. undefined type) + //As long as the underlying type can not be resolved by the compiler (e.g. undefined type) //removal is not save. if (toStringReceiver == null || toStringReceiver.TypeKind==TypeKind.Error) continue; @@ -115,7 +115,7 @@ private static ITypeSymbol GetTypeInfoOfOtherNode(SyntaxNode toStringNode, Binar private static bool CheckAddOperationOverloadsOfTypes(ITypeSymbol toStringReceiver, ITypeSymbol otherType) { - //If the underlying type has a custom AddOperator this operator will take precedence over everything else + //If the underlying type has a custom AddOperator this operator will take precedence over everything else if (HasTypeCustomAddOperator(toStringReceiver)) { return false; @@ -128,7 +128,7 @@ private static bool CheckAddOperationOverloadsOfTypes(ITypeSymbol toStringReceiv } //If the underlying type is one of the build in types (numeric, datetime and so on) and the other side is not a string, - //the result a removal is hard to predict and might be wrong. + //the result a removal is hard to predict and might be wrong. if (HasAdditionOperator(toStringReceiver)) { return false; @@ -177,11 +177,11 @@ private static bool HasAdditionOperator(ITypeSymbol type) case SpecialType.System_UIntPtr: case SpecialType.System_DateTime: return true; + default: + break; } if (type.TypeKind == TypeKind.Enum) - { return true; - } return false; } diff --git a/src/CSharp/CodeCracker/Style/UseEmptyStringCodeFixProviderAll.cs b/src/CSharp/CodeCracker/Style/UseEmptyStringCodeFixProviderAll.cs index a26d828df..0b0915ee3 100644 --- a/src/CSharp/CodeCracker/Style/UseEmptyStringCodeFixProviderAll.cs +++ b/src/CSharp/CodeCracker/Style/UseEmptyStringCodeFixProviderAll.cs @@ -42,8 +42,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(UseEmptyStringCodeFixProvider.MessageFormat, ct => GetFixedSolutionAsync(fixAllContext.WithCancellationToken(ct)))); + default: + return null; } - return null; } private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) diff --git a/src/CSharp/CodeCracker/Style/UseStringEmptyCodeFixProviderAll.cs b/src/CSharp/CodeCracker/Style/UseStringEmptyCodeFixProviderAll.cs index 0498b21d0..6d7e92057 100644 --- a/src/CSharp/CodeCracker/Style/UseStringEmptyCodeFixProviderAll.cs +++ b/src/CSharp/CodeCracker/Style/UseStringEmptyCodeFixProviderAll.cs @@ -42,8 +42,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(UseStringEmptyCodeFixProvider.MessageFormat, ct => GetFixedSolutionAsync(fixAllContext.WithCancellationToken(ct)))); + default: + return null; } - return null; } private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) diff --git a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedFixAllProvider.cs b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedFixAllProvider.cs index d49053746..d34c097b0 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedFixAllProvider.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedFixAllProvider.cs @@ -25,8 +25,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(DisposableVariableNotDisposedCodeFixProvider.MessageFormat, ct => GetFixedSolutionAsync(fixAllContext))); + default: + return null; } - return null; } private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) diff --git a/src/CSharp/CodeCracker/Usage/RemoveUnreachableCodeFixAllProvider.cs b/src/CSharp/CodeCracker/Usage/RemoveUnreachableCodeFixAllProvider.cs index 936cb1ef5..499cbd6b7 100644 --- a/src/CSharp/CodeCracker/Usage/RemoveUnreachableCodeFixAllProvider.cs +++ b/src/CSharp/CodeCracker/Usage/RemoveUnreachableCodeFixAllProvider.cs @@ -25,8 +25,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(RemoveUnreachableCodeCodeFixProvider.Message, ct => GetFixedSolutionAsync(fixAllContext))); + default: + return null; } - return null; } private async static Task GetFixedSolutionAsync(FixAllContext fixAllContext) diff --git a/src/CSharp/CodeCracker/Usage/UnusedParametersCodeFixAllProvider.cs b/src/CSharp/CodeCracker/Usage/UnusedParametersCodeFixAllProvider.cs index e41a8fa8b..74650b882 100644 --- a/src/CSharp/CodeCracker/Usage/UnusedParametersCodeFixAllProvider.cs +++ b/src/CSharp/CodeCracker/Usage/UnusedParametersCodeFixAllProvider.cs @@ -27,8 +27,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(message, async ct => await GetFixedSolutionAsync(fixAllContext, await GetSolutionWithDocsAsync(fixAllContext, fixAllContext.Solution)))); + default: + return null; } - return null; } private async static Task GetSolutionWithDocsAsync(FixAllContext fixAllContext, Solution solution) diff --git a/src/CSharp/CodeCracker/packages.config b/src/CSharp/CodeCracker/packages.config index fcde436eb..28a6ce22f 100644 --- a/src/CSharp/CodeCracker/packages.config +++ b/src/CSharp/CodeCracker/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj index 34f859b17..f2b05c246 100644 --- a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj +++ b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj @@ -1,5 +1,5 @@  - + 11.0 @@ -72,8 +72,7 @@ - - + diff --git a/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs b/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs index 255dfc074..c74833924 100644 --- a/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs +++ b/src/Common/CodeCracker.Common/FixAllProviders/DocumentCodeFixProviderAll.cs @@ -34,8 +34,9 @@ public override Task GetFixAsync(FixAllContext fixAllContext) case FixAllScope.Solution: return Task.FromResult(CodeAction.Create(CodeFixTitle, ct => GetFixedDocumentsAsync(fixAllContext, fixAllContext.Solution.Projects.SelectMany(p => p.Documents)))); + default: + return null; } - return null; } private async static Task GetFixedDocumentsAsync(FixAllContext fixAllContext, IEnumerable documents) diff --git a/src/Common/CodeCracker.Common/packages.config b/src/Common/CodeCracker.Common/packages.config index 847a13861..324cafb10 100644 --- a/src/Common/CodeCracker.Common/packages.config +++ b/src/Common/CodeCracker.Common/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/VisualBasic/CodeCracker/CodeCracker.vbproj b/src/VisualBasic/CodeCracker/CodeCracker.vbproj index 02045debc..31f867607 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.vbproj +++ b/src/VisualBasic/CodeCracker/CodeCracker.vbproj @@ -1,5 +1,5 @@  - + 11.0 @@ -162,8 +162,7 @@ - - + diff --git a/src/VisualBasic/CodeCracker/packages.config b/src/VisualBasic/CodeCracker/packages.config index bc11241d0..4ce3c94b7 100644 --- a/src/VisualBasic/CodeCracker/packages.config +++ b/src/VisualBasic/CodeCracker/packages.config @@ -1,6 +1,6 @@  - + diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index dcf1020ca..4d186cfbe 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -1,6 +1,7 @@  - - + + + Debug AnyCPU @@ -40,11 +41,8 @@ false - - ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.dll - - - ..\..\..\packages\FluentAssertions.4.19.2\lib\net45\FluentAssertions.Core.dll + + ..\..\..\packages\FluentAssertions.5.3.0\lib\net45\FluentAssertions.dll ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll @@ -61,8 +59,8 @@ ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll - - ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll @@ -93,6 +91,9 @@ ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + + ..\..\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll + @@ -101,14 +102,14 @@ ..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - - ..\..\..\packages\xunit.assert.2.2.0\lib\netstandard1.1\xunit.assert.dll + + ..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll - - ..\..\..\packages\xunit.extensibility.core.2.2.0\lib\netstandard1.1\xunit.core.dll + + ..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll - - ..\..\..\packages\xunit.extensibility.execution.2.2.0\lib\net452\xunit.execution.desktop.dll + + ..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll @@ -227,18 +228,21 @@ - - + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + + + + \ No newline at end of file diff --git a/src/CSharp/CodeCracker/packages.config b/src/CSharp/CodeCracker/packages.config deleted file mode 100644 index 28a6ce22f..000000000 --- a/src/CSharp/CodeCracker/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj index f2b05c246..0ab0253ad 100644 --- a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj +++ b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj @@ -35,6 +35,15 @@ prompt 4 + + win + true + + + + + + @@ -56,11 +65,6 @@ - - - Designer - - ResXFileCodeGenerator @@ -71,51 +75,5 @@ Resources.Designer.cs - - - - - - - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll - False - - - ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - - - \ No newline at end of file diff --git a/src/Common/CodeCracker.Common/packages.config b/src/Common/CodeCracker.Common/packages.config deleted file mode 100644 index 324cafb10..000000000 --- a/src/Common/CodeCracker.Common/packages.config +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker/CodeCracker.vbproj b/src/VisualBasic/CodeCracker/CodeCracker.vbproj index 31f867607..9a425da8f 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.vbproj +++ b/src/VisualBasic/CodeCracker/CodeCracker.vbproj @@ -9,6 +9,7 @@ Library CodeCracker.VisualBasic CodeCracker.VisualBasic + CodeCracker.VisualBasic.NewIdRequiredDueToNuGetBug en-US {14182A97-F7F0-4C62-8B27-98AA8AE2109A};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} Profile7 @@ -54,12 +55,18 @@ On + + win + true + + + + + + - - Designer - PreserveNewest @@ -161,57 +168,5 @@ CodeCracker.Common - - - - - - - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.VisualBasic.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\portable-net45+win8\Microsoft.CodeAnalysis.Workspaces.dll - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll - False - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll - False - - - ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - - - \ No newline at end of file diff --git a/src/VisualBasic/CodeCracker/packages.config b/src/VisualBasic/CodeCracker/packages.config deleted file mode 100644 index 4ce3c94b7..000000000 --- a/src/VisualBasic/CodeCracker/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 4d186cfbe..5eef509d5 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -1,7 +1,5 @@  - - Debug AnyCPU @@ -41,76 +39,19 @@ false - - ..\..\..\packages\FluentAssertions.5.3.0\lib\net45\FluentAssertions.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll - - - ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll - True - - - ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - - - ..\..\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - ..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - - - ..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll - - - ..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll - - - ..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll - + + + + + + @@ -199,9 +140,6 @@ - - Designer - @@ -227,27 +165,5 @@ - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/packages.config b/test/CSharp/CodeCracker.Test/packages.config deleted file mode 100644 index a23582940..000000000 --- a/test/CSharp/CodeCracker.Test/packages.config +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj index 64b167733..0f296cd69 100644 --- a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj +++ b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj @@ -1,7 +1,5 @@  - - Debug @@ -37,82 +35,19 @@ 4 - - ..\..\..\packages\FluentAssertions.5.3.0\lib\net45\FluentAssertions.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.CSharp.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll - - - ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll - True - - - ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - - - ..\..\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - ..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - - - ..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll - - - ..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll - - - ..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll - + + + + + + @@ -125,32 +60,5 @@ - - - Designer - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file diff --git a/test/Common/CodeCracker.Test.Common/packages.config b/test/Common/CodeCracker.Test.Common/packages.config deleted file mode 100644 index eed89eef8..000000000 --- a/test/Common/CodeCracker.Test.Common/packages.config +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj b/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj index c5e096782..e27355417 100644 --- a/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj +++ b/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj @@ -1,7 +1,5 @@  - - Debug @@ -55,73 +53,16 @@ On - - ..\..\..\packages\FluentAssertions.5.3.0\lib\net45\FluentAssertions.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.VisualBasic.Workspaces.1.3.2\lib\net45\Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.dll - - - ..\..\..\packages\Microsoft.CodeAnalysis.Workspaces.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.Workspaces.Desktop.dll - - - ..\..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll - - - ..\..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.AttributedModel.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Convention.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Hosting.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.Runtime.dll - True - - - ..\..\..\packages\Microsoft.Composition.1.0.27\lib\portable-net45+win8+wp8+wpa81\System.Composition.TypedParts.dll - True - - - ..\..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll - - - ..\..\..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll - - - ..\..\..\packages\xunit.abstractions.2.0.1\lib\net35\xunit.abstractions.dll - - - ..\..\..\packages\xunit.assert.2.3.1\lib\netstandard1.1\xunit.assert.dll - - - ..\..\..\packages\xunit.extensibility.core.2.3.1\lib\netstandard1.1\xunit.core.dll - - - ..\..\..\packages\xunit.extensibility.execution.2.3.1\lib\net452\xunit.execution.desktop.dll - + + + + + + @@ -195,9 +136,6 @@ My Settings.Designer.vb - - Designer - @@ -216,26 +154,5 @@ CodeCracker.Test.Common - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/packages.config b/test/VisualBasic/CodeCracker.Test/packages.config deleted file mode 100644 index e47b5ab69..000000000 --- a/test/VisualBasic/CodeCracker.Test/packages.config +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 0ed68e234dd4974239cd2bd963940068a90eb043 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Sun, 9 Sep 2018 23:51:54 -0500 Subject: [PATCH 122/152] Use DiagnosticResult from Microsoft.CodeAnalysis.Testing --- nuget.config | 2 + src/CSharp/CodeCracker/CodeCracker.csproj | 4 +- .../CodeCracker.Common.csproj | 2 +- .../CodeCracker/CodeCracker.vbproj | 4 +- .../CodeCracker.Test/CodeCracker.Test.csproj | 2 +- .../Design/MakeMethodStaticTests.cs | 31 +-- .../CodeCracker.Test/Design/NameOfTests.cs | 11 +- .../Design/StaticConstructorExceptionTests.cs | 11 +- .../Design/UseInvokeMethodToFireEventTests.cs | 201 ++++++------------ .../Maintainability/XmlDocumentationTests.cs | 21 +- .../Performance/EmptyFinalizerTests.cs | 31 +-- ...ocalVariablesConstWhenItIsPossibleTests.cs | 31 +-- .../RemoveWhereWhenItIsPossibleTests.cs | 11 +- .../Performance/SealedAttributeTests.cs | 21 +- .../Performance/StringBuilderInLoopTests.cs | 111 +++------- .../Performance/UseStaticRegexIsMatchTests.cs | 11 +- .../AddBracesToSwitchSectionsTests.cs | 31 +-- .../AllowMembersOrderingAnalyzerTests.cs | 11 +- .../Refactoring/ChangeAnyToAllTests.cs | 41 ++-- .../Refactoring/ComputeExpressionTests.cs | 11 +- .../Refactoring/InvertForTests.cs | 31 +-- .../Refactoring/MergeNestedIfTest.cs | 11 +- .../Refactoring/NumericLiteralTests.cs | 15 +- ...ngedEventArgsUnnecessaryAllocationTests.cs | 18 +- .../ReplaceWithGetterOnlyAutoPropertyTests.cs | 92 ++------ .../Refactoring/SplitIntoNestedIfTests.cs | 11 +- .../Refactoring/StringRepresentationTests.cs | 21 +- .../UseConfigureAwaitFalseTests.cs | 11 +- .../Style/AlwaysUseVarTests.cs | 31 +-- .../Style/ConsoleWriteLineTests.cs | 31 +-- ...nvertLambdaExpressionToMethodGroupTests.cs | 31 +-- .../ConvertToExpressionBodiedMemberTests.cs | 51 ++--- .../Style/ConvertToSwitchTests.cs | 21 +- .../Style/EmptyObjectInitializerTests.cs | 11 +- .../Style/ExistenceOperatorTests.cs | 21 +- .../CodeCracker.Test/Style/ForInArrayTests.cs | 71 ++----- .../Style/InterfaceNameTests.cs | 11 +- .../Style/ObjectInitializerTests.cs | 31 +-- .../Style/PropertyPrivateSetTests.cs | 11 +- .../Style/RemoveAsyncFromMethodTests.cs | 11 +- .../Style/RemoveCommentedCodeTests.cs | 21 +- .../Style/RemoveTrailingWhitespaceTests.cs | 12 +- .../Style/StringFormatTests.cs | 51 ++--- .../Style/SwitchToAutoPropTests.cs | 11 +- .../Style/TaskNameASyncTests.cs | 41 ++-- .../Style/TernaryOperatorTests.cs | 31 +-- .../Style/UnnecessaryParenthesisTests.cs | 11 +- ...ssaryToStringInStringConcatenationTests.cs | 13 +- .../Style/UseEmptyStringTest.cs | 15 +- .../Style/UseStringEmptyTests.cs | 41 ++-- ...stractClassShouldNotHavePublicCtorTests.cs | 11 +- .../Usage/ArgumentExceptionTests.cs | 51 ++--- .../CallExtensionMethodAsExtensionTests.cs | 61 ++---- .../Usage/DisposableFieldNotDisposedTests.cs | 111 +++------- .../DisposableVariableNotDisposedTests.cs | 101 +++------ ...posablesShouldCallSuppressFinalizeTests.cs | 21 +- .../Usage/IPAddressAnalyzerTests.cs | 10 +- .../Usage/IfReturnTrueTests.cs | 21 +- .../Usage/JsonNetAnalyzerTests.cs | 10 +- .../Usage/NoPrivateReadonlyFieldTest.cs | 15 +- .../Usage/ReadonlyFieldTests.cs | 171 +++++---------- .../Usage/RedundantFieldAssignmentTests.cs | 131 ++++-------- .../CodeCracker.Test/Usage/RegexTests.cs | 21 +- ...emovePrivateMethodNeverUsedAnalyzerTest.cs | 15 +- .../Usage/RemoveRedundantElseClauseTests.cs | 21 +- .../Usage/RethrowExceptionTests.cs | 11 +- ...implifyRedundantBooleanComparisonsTests.cs | 11 +- .../Usage/StringFormatArgsTests.cs | 81 +++---- .../Usage/UnusedParametersTests.cs | 11 +- .../Usage/UriAnalyzerTests.cs | 11 +- .../Usage/VirtualMethodOnConstructorTests.cs | 37 ++-- .../CodeCracker.Test.Common.csproj | 2 +- .../Helpers/DiagnosticResult.cs | 86 -------- .../Verifiers/DiagnosticVerifier.cs | 28 +-- .../CodeCracker.Test/CodeCracker.Test.vbproj | 2 +- .../CodeCracker.Test/Design/NameOfTests.vb | 11 +- .../Design/StaticConstructorExceptionTests.vb | 10 +- ...ocalVariablesConstWhenItIsPossibleTests.vb | 31 +-- .../RemoveWhereWhenItIsPossibleTests.vb | 11 +- .../Performance/SealedAttributeTests.vb | 21 +- .../Performance/StringBuilderInLoopTests.vb | 61 ++---- .../AllowMembersOrderingAnalyzerTests.vb | 10 +- .../Refactoring/ChangeAnyToAllTests.vb | 10 +- .../UseConfigureAwaitFalseTests.vb | 10 +- .../Style/InterfaceNameTests.vb | 10 +- .../Style/TernaryOperatorTests.vb | 28 +-- .../Usage/ArgumentExceptionTests.vb | 28 +-- .../Usage/DisposableFieldNotDisposedTests.vb | 111 +++------- ...posablesShouldCallSuppressFinalizeTests.vb | 19 +- .../Usage/IPAddressAnalyzerTests.vb | 9 +- .../Usage/JsonNetAnalyzerTests.vb | 10 +- ...lassShouldNotHavePublicConstructorTests.vb | 10 +- .../Usage/UnusedParametersTests.vb | 10 +- .../Usage/UriAnalyzerTests.vb | 10 +- 94 files changed, 910 insertions(+), 1949 deletions(-) delete mode 100644 test/Common/CodeCracker.Test.Common/Helpers/DiagnosticResult.cs diff --git a/nuget.config b/nuget.config index ffae90ba7..f42466e87 100644 --- a/nuget.config +++ b/nuget.config @@ -4,10 +4,12 @@ + + \ No newline at end of file diff --git a/src/CSharp/CodeCracker/CodeCracker.csproj b/src/CSharp/CodeCracker/CodeCracker.csproj index fdeef9f24..d81e8eee9 100644 --- a/src/CSharp/CodeCracker/CodeCracker.csproj +++ b/src/CSharp/CodeCracker/CodeCracker.csproj @@ -14,7 +14,7 @@ {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Profile7 v4.5 - AD0001 + AD0001,RS1010,RS1016,RS1017,RS1022 true @@ -41,7 +41,7 @@ - + diff --git a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj index 0ab0253ad..8f502cca1 100644 --- a/src/Common/CodeCracker.Common/CodeCracker.Common.csproj +++ b/src/Common/CodeCracker.Common/CodeCracker.Common.csproj @@ -41,7 +41,7 @@ - + diff --git a/src/VisualBasic/CodeCracker/CodeCracker.vbproj b/src/VisualBasic/CodeCracker/CodeCracker.vbproj index 9a425da8f..877bee09b 100644 --- a/src/VisualBasic/CodeCracker/CodeCracker.vbproj +++ b/src/VisualBasic/CodeCracker/CodeCracker.vbproj @@ -14,7 +14,7 @@ {14182A97-F7F0-4C62-8B27-98AA8AE2109A};{F184B08F-C81C-45F6-A57F-5ABD9991F28F} Profile7 v4.5 - AD0001 + AD0001,RS1010,RS1016,RS1017,RS1022 true @@ -61,7 +61,7 @@ - + diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 5eef509d5..87c9508c5 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -49,7 +49,7 @@ - + diff --git a/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs b/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs index 9a1590393..2d8829a4a 100644 --- a/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Design; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -100,13 +101,9 @@ class C : I public async Task WithDiagnostic(string code) { var source = code.WrapInCSharpClass(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.MakeMethodStatic.ToDiagnosticId(), - Message = string.Format(MakeMethodStaticAnalyzer.MessageFormat, "Foo"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 18) } - }; + var expected = new DiagnosticResult(DiagnosticId.MakeMethodStatic.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 18) + .WithMessage(string.Format(MakeMethodStaticAnalyzer.MessageFormat, "Foo")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -1014,13 +1011,9 @@ public void M() } public static void N() { } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.MakeMethodStatic.ToDiagnosticId(), - Message = string.Format(MakeMethodStaticAnalyzer.MessageFormat, "M"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.MakeMethodStatic.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 17) + .WithMessage(string.Format(MakeMethodStaticAnalyzer.MessageFormat, "M")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -1053,13 +1046,9 @@ public void GetEnumerator() public static void N() { } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.MakeMethodStatic.ToDiagnosticId(), - Message = string.Format(MakeMethodStaticAnalyzer.MessageFormat, "GetEnumerator"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.MakeMethodStatic.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 17) + .WithMessage(string.Format(MakeMethodStaticAnalyzer.MessageFormat, "GetEnumerator")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Design/NameOfTests.cs b/test/CSharp/CodeCracker.Test/Design/NameOfTests.cs index 982738bef..819252585 100644 --- a/test/CSharp/CodeCracker.Test/Design/NameOfTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/NameOfTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Design; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -728,13 +729,9 @@ void Foo(TypeName d) private static DiagnosticResult CreateNameofDiagnosticResult(string nameofArgument, int diagnosticLine, int diagnosticColumn, DiagnosticId id = DiagnosticId.NameOf) { - return new DiagnosticResult - { - Id = id.ToDiagnosticId(), - Message = $"Use 'nameof({nameofArgument})' instead of specifying the program element name.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", diagnosticLine, diagnosticColumn) } - }; + return new DiagnosticResult(id.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(diagnosticLine, diagnosticColumn) + .WithMessage($"Use 'nameof({nameofArgument})' instead of specifying the program element name."); } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs b/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs index f6ba9d8a0..a8697697b 100644 --- a/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/StaticConstructorExceptionTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Design; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -19,13 +20,9 @@ static MyClass() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StaticConstructorException.ToDiagnosticId(), - Message = "Don't throw exceptions inside static constructors.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.StaticConstructorException.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 25) + .WithMessage("Don't throw exceptions inside static constructors."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs b/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs index f392107bc..90acb1bdd 100644 --- a/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/UseInvokeMethodToFireEventTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Design; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Design @@ -20,13 +21,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -45,13 +42,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -78,13 +71,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 16, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(16, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -111,13 +100,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 16, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(16, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -144,13 +129,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 16, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(16, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -178,13 +159,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 17, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(17, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -212,13 +189,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 17, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(17, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -237,13 +210,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -267,13 +236,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(13, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -298,13 +263,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(14, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -332,13 +293,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 17, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(17, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -366,13 +323,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 17, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(17, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -410,13 +363,9 @@ public class MyClass public void Execute() => MyEvent(this, System.EventArgs.Empty); }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -460,13 +409,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(13, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -492,13 +437,9 @@ public void Execute() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "MyEvent"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 15, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(15, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "MyEvent")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -548,13 +489,9 @@ public static void Execute(System.Action action) action(); } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "action"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "action")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -571,13 +508,9 @@ public static void Execute(System.Action action) action(); } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "action"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "action")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -593,13 +526,9 @@ public static void Execute(System.Action action) if (action == null) throw new Exception(); } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "action"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 25) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "action")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -683,13 +612,9 @@ public static void Execute(System.Action action) if (null == action) action(); }".WrapInCSharpClass(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "action"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 9) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(12, 9) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "action")); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -799,13 +724,9 @@ public static TReturn Method(System.Func getter) where T { return getter(default(T)); }".WrapInCSharpClass(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), - Message = string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat.ToString(), "getter"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 12) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseInvokeMethodToFireEvent.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(11, 12) + .WithMessage(string.Format(UseInvokeMethodToFireEventAnalyzer.MessageFormat, "getter")); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Maintainability/XmlDocumentationTests.cs b/test/CSharp/CodeCracker.Test/Maintainability/XmlDocumentationTests.cs index 4e060ac36..db37a35fa 100644 --- a/test/CSharp/CodeCracker.Test/Maintainability/XmlDocumentationTests.cs +++ b/test/CSharp/CodeCracker.Test/Maintainability/XmlDocumentationTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Maintainability; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -110,13 +111,9 @@ protected async static Task GetSortedDiagnosticsFromDocumentsAsync } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.XmlDocumentation_MissingInCSharp.ToDiagnosticId(), - Message = "You have missing/unexistent parameters in Xml Docs", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 16) } - }; + var expected = new DiagnosticResult(DiagnosticId.XmlDocumentation_MissingInCSharp.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 16) + .WithMessage("You have missing/unexistent parameters in Xml Docs"); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -141,13 +138,9 @@ public static Project CreateProject(string[] sources, out AdhocWorkspace workspa } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.XmlDocumentation_MissingInXml.ToDiagnosticId(), - Message = "You have missing/unexistent parameters in Xml Docs", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 16) } - }; + var expected = new DiagnosticResult(DiagnosticId.XmlDocumentation_MissingInXml.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 16) + .WithMessage("You have missing/unexistent parameters in Xml Docs"); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Performance/EmptyFinalizerTests.cs b/test/CSharp/CodeCracker.Test/Performance/EmptyFinalizerTests.cs index f86dde304..aef768752 100644 --- a/test/CSharp/CodeCracker.Test/Performance/EmptyFinalizerTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/EmptyFinalizerTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Performance; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -19,13 +20,9 @@ public class MyClass } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.EmptyFinalizer.ToDiagnosticId(), - Message = "Remove Empty Finalizers", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.EmptyFinalizer.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 21) + .WithMessage("Remove Empty Finalizers"); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -42,13 +39,9 @@ public class MyClass } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.EmptyFinalizer.ToDiagnosticId(), - Message = "Remove Empty Finalizers", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.EmptyFinalizer.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 21) + .WithMessage("Remove Empty Finalizers"); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -68,13 +61,9 @@ public class MyClass } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.EmptyFinalizer.ToDiagnosticId(), - Message = "Remove Empty Finalizers", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.EmptyFinalizer.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 21) + .WithMessage("Remove Empty Finalizers"); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs b/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs index e37f52a46..61b2311b3 100644 --- a/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Performance; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -64,13 +65,9 @@ public async Task IgnoresPointerDeclarations() public async Task CreateDiagnosticsWhenAssigningAPotentialConstant() { var test = @"int a = 10;".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), - Message = "This variable can be made const.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 17) + .WithMessage("This variable can be made const."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -79,13 +76,9 @@ public async Task CreateDiagnosticsWhenAssigningAPotentialConstantInAVarDeclarat { var test = @"var a = 10;".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), - Message = "This variable can be made const.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 17) + .WithMessage("This variable can be made const."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -94,13 +87,9 @@ public async Task CreateDiagnosticsWhenAssigningNullToAReferenceType() { var test = @"Foo a = null;".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), - Message = "This variable can be made const.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 17) + .WithMessage("This variable can be made const."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs index c6e4b622a..64de3af7c 100644 --- a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Performance; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -32,13 +33,9 @@ public async Task DoSomething() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), - Message = "You can remove 'Where' moving the predicate to '" + method + "'.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(11, 23) + .WithMessage("You can remove 'Where' moving the predicate to '" + method + "'."); await VerifyCSharpDiagnosticAsync(test, expected); diff --git a/test/CSharp/CodeCracker.Test/Performance/SealedAttributeTests.cs b/test/CSharp/CodeCracker.Test/Performance/SealedAttributeTests.cs index e14f5e926..ce0fe3dfa 100644 --- a/test/CSharp/CodeCracker.Test/Performance/SealedAttributeTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/SealedAttributeTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Performance; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -16,13 +17,9 @@ public class MyAttribute : System.Attribute }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.SealedAttribute.ToDiagnosticId(), - Message = "Mark 'MyAttribute' as sealed.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 2, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.SealedAttribute.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(2, 30) + .WithMessage("Mark 'MyAttribute' as sealed."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -41,13 +38,9 @@ public class OtherAttribute : MyAttribute }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.SealedAttribute.ToDiagnosticId(), - Message = "Mark 'OtherAttribute' as sealed.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.SealedAttribute.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(7, 30) + .WithMessage("Mark 'OtherAttribute' as sealed."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Performance/StringBuilderInLoopTests.cs b/test/CSharp/CodeCracker.Test/Performance/StringBuilderInLoopTests.cs index 9f14bdcb5..75f557017 100644 --- a/test/CSharp/CodeCracker.Test/Performance/StringBuilderInLoopTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/StringBuilderInLoopTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -50,13 +51,9 @@ public async Task WhileWithStringConcatOnLocalVariableCreatesDiagnostic() { myString += """"; }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(14, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -78,13 +75,9 @@ public void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(11, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -107,13 +100,9 @@ public void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "MyString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(11, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "MyString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -128,20 +117,12 @@ public async Task WhileWithStringConcatWithSeveralConcatsOnDifferentVarsCreatesS myString1 += """"; myString2 += """"; }".WrapInCSharpMethod(); - var expected1 = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString1"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 15, 21) } - }; - var expected2 = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString2"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 16, 21) } - }; + var expected1 = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(15, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString1")); + var expected2 = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(16, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString2")); await VerifyCSharpDiagnosticAsync(source, expected1, expected2); } @@ -154,13 +135,9 @@ public async Task WhileWithStringConcatWithSimpleAssignmentCreatesDiagnostic() { myString = myString + """"; }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(14, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -387,13 +364,9 @@ public async Task ForWithStringConcatOnLocalVariableCreatesDiagnostic() { myString += """"; }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(14, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -443,13 +416,9 @@ public async Task ForeachWithtStringConcatOnLocalVariableCreatesDiagnostic() { myString += """"; }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(14, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -483,13 +452,9 @@ public async Task DoWithtStringConcatOnLocalVariableCreatesDiagnostic() { myString += """"; } while (DateTime.Now.Second % 2 == 0);".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(14, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -537,13 +502,9 @@ public void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "someObject.A"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 16, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(16, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "someObject.A")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -570,13 +531,9 @@ public void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), - Message = string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "someObject.A[DateTime.Now.Second]"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 16, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringBuilderInLoop.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(16, 21) + .WithMessage(string.Format(StringBuilderInLoopAnalyzer.MessageFormat, "someObject.A[DateTime.Now.Second]")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Performance/UseStaticRegexIsMatchTests.cs b/test/CSharp/CodeCracker.Test/Performance/UseStaticRegexIsMatchTests.cs index c16424c06..5d4d8f76c 100644 --- a/test/CSharp/CodeCracker.Test/Performance/UseStaticRegexIsMatchTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/UseStaticRegexIsMatchTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Performance; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -26,13 +27,9 @@ public async Task Foo() [Fact] public async Task CreatesDiagnosticsWhenDeclaringALocalRegexAndUsingIsMatch() { - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseStaticRegexIsMatch.ToDiagnosticId(), - Message = UseStaticRegexIsMatchAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseStaticRegexIsMatch.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(12, 17) + .WithMessage(UseStaticRegexIsMatchAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs index eab5fc7bb..9f8dfb62c 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Refactoring @@ -69,13 +70,9 @@ public async Task CreateDiagnosticWhenSingleSwitchSectionHasNoBraces() Foo(); break; }"; - var diagnostic = new DiagnosticResult - { - Id = DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), - Message = "Add braces for each section in this switch", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] {new DiagnosticResultLocation("Test0.cs", 10, 17)} - }; + var diagnostic = new DiagnosticResult(DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 17) + .WithMessage("Add braces for each section in this switch"); await VerifyCSharpDiagnosticAsync(test.WrapInCSharpMethod(), diagnostic); } @@ -98,13 +95,9 @@ public async Task CreateDiagnosticWhenNotAllSwitchSectionsHaveBraces() break; } }"; - var diagnostic = new DiagnosticResult - { - Id = DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), - Message = "Add braces for each section in this switch", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var diagnostic = new DiagnosticResult(DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 17) + .WithMessage("Add braces for each section in this switch"); await VerifyCSharpDiagnosticAsync(test.WrapInCSharpMethod(), diagnostic); } @@ -127,13 +120,9 @@ public async Task CreateDiagnosticWhenDefaultSectionsHasNoBraces() Baz(); break; }"; - var diagnostic = new DiagnosticResult - { - Id = DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), - Message = "Add braces for each section in this switch", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var diagnostic = new DiagnosticResult(DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 17) + .WithMessage("Add braces for each section in this switch"); await VerifyCSharpDiagnosticAsync(test.WrapInCSharpMethod(), diagnostic); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs index 724a2cfd6..bbede299f 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.cs @@ -1,6 +1,7 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Refactoring { @@ -50,13 +51,9 @@ public async void AllowMembersOrderingForMoreThanOneMemberShouldTriggerDiagnosti void car() { } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.AllowMembersOrdering.ToDiagnosticId(), - Message = AllowMembersOrderingAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 2, 14 + typeDeclaration.Length) } - }; + var expected = new DiagnosticResult(DiagnosticId.AllowMembersOrdering.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(2, 14 + typeDeclaration.Length) + .WithMessage(AllowMembersOrderingAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.cs index 5413edb7e..86ca15d52 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -29,13 +30,9 @@ public class ChangeAnyToAllTests : CodeFixVerifier i == 1); }} }}"; - var expected = new DiagnosticResult - { - Id = diagnosticId.ToDiagnosticId(), - Message = diagnosticId == DiagnosticId.ChangeAnyToAll ? ChangeAnyToAllAnalyzer.MessageAny : ChangeAnyToAllAnalyzer.MessageAll, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 43) } - }; + var expected = new DiagnosticResult(diagnosticId.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(13, 43) + .WithMessage(diagnosticId == DiagnosticId.ChangeAnyToAll ? ChangeAnyToAllAnalyzer.MessageAny : ChangeAnyToAllAnalyzer.MessageAll); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -246,13 +239,9 @@ class TypeName private System.Collections.Generic.IList xs; bool Foo() => xs.{methodName}(i => i == 1); }}"; - var expected = new DiagnosticResult - { - Id = diagnosticId.ToDiagnosticId(), - Message = diagnosticId == DiagnosticId.ChangeAnyToAll ? ChangeAnyToAllAnalyzer.MessageAny : ChangeAnyToAllAnalyzer.MessageAll, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 22) } - }; + var expected = new DiagnosticResult(diagnosticId.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(7, 22) + .WithMessage(diagnosticId == DiagnosticId.ChangeAnyToAll ? ChangeAnyToAllAnalyzer.MessageAny : ChangeAnyToAllAnalyzer.MessageAll); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -280,13 +269,9 @@ public async Task NegationWithCoalesceExpressionCreatesDiagnostic(string methodN var source = $@" var ints = new [] {{ 1 }}; var query = !ints?.{methodName}(i => i == 1) ?? true;"; - var expected = new DiagnosticResult - { - Id = diagnosticId.ToDiagnosticId(), - Message = diagnosticId == DiagnosticId.ChangeAnyToAll ? ChangeAnyToAllAnalyzer.MessageAny : ChangeAnyToAllAnalyzer.MessageAll, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 20) } - }; + var expected = new DiagnosticResult(diagnosticId.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(13, 20) + .WithMessage(diagnosticId == DiagnosticId.ChangeAnyToAll ? ChangeAnyToAllAnalyzer.MessageAny : ChangeAnyToAllAnalyzer.MessageAll); await VerifyCSharpDiagnosticAsync(source.WrapInCSharpMethod(usings: "\nusing System.Linq;"), expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs index e7a40762e..64f244a6c 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -38,13 +39,9 @@ public async Task BinaryExpressionWithLiteralOnLeftAndRightCreatesDiagnostic(str { var source = original.WrapInCSharpMethod(); var expression = original.Substring(columnOffset, original.Length - columnOffset - columnRightTrim - 1); - var expected = new DiagnosticResult - { - Id = DiagnosticId.ComputeExpression.ToDiagnosticId(), - Message = string.Format(ComputeExpressionAnalyzer.Message, expression), - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17 + columnOffset) } - }; + var expected = new DiagnosticResult(DiagnosticId.ComputeExpression.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 17 + columnOffset) + .WithMessage(string.Format(ComputeExpressionAnalyzer.Message, expression)); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/InvertForTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/InvertForTests.cs index 89bcb57b9..c46800685 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/InvertForTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/InvertForTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -125,13 +126,9 @@ public async Task CreateDiagnosticsWithForLoopsFrom0ToN() { var test = WrapInCSharpMethod(@"for (var i = 0; i < n; i++){}"); - var expected = new DiagnosticResult - { - Id = DiagnosticId.InvertFor.ToDiagnosticId(), - Message = "Make it a for loop that decrement the counter.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.InvertFor.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 17) + .WithMessage("Make it a for loop that decrement the counter."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -141,13 +138,9 @@ public async Task CreateDiagnosticsWithForLoopsTheUsesAnDeclaredVariableAsCounte { var test = WrapInCSharpMethod(@"int i = 0; for (i = 0; i < n; i++){}"); - var expected = new DiagnosticResult - { - Id = DiagnosticId.InvertFor.ToDiagnosticId(), - Message = "Make it a for loop that decrement the counter.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 28) } - }; + var expected = new DiagnosticResult(DiagnosticId.InvertFor.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 28) + .WithMessage("Make it a for loop that decrement the counter."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -157,13 +150,9 @@ public async Task CreateDiagnosticsWithForLoopsFromNTo0() { var test = WrapInCSharpMethod(@"for (var i = n - 1; i >= 0; i--){}"); - var expected = new DiagnosticResult - { - Id = DiagnosticId.InvertFor.ToDiagnosticId(), - Message = "Make it a for loop that increment the counter.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.InvertFor.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 17) + .WithMessage("Make it a for loop that increment the counter."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/MergeNestedIfTest.cs b/test/CSharp/CodeCracker.Test/Refactoring/MergeNestedIfTest.cs index 1bcda1b72..32911a9f5 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/MergeNestedIfTest.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/MergeNestedIfTest.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -39,13 +40,9 @@ public async Task NestedIfCreatesDiagnostic() var a = 1; } }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.MergeNestedIf.ToDiagnosticId(), - Message = MergeNestedIfAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.MergeNestedIf.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(11, 17) + .WithMessage(MergeNestedIfAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs index 74fce5482..feae0f6f6 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -80,13 +81,11 @@ void Foo() await VerifyCSharpFixAsync(source, fixtest); } - private static DiagnosticResult CreateDiagnosticResult(string literal, bool isDecimal, int row = 10, int col = 25) => - new DiagnosticResult - { - Id = DiagnosticId.NumericLiteral.ToDiagnosticId(), - Message = string.Format(NumericLiteralAnalyzer.Message, literal, isDecimal ? "hexadecimal" : "decimal"), - Severity = DiagnosticSeverity.Hidden, - Locations = new[] {new DiagnosticResultLocation("Test0.cs", row, col)} - }; + private static DiagnosticResult CreateDiagnosticResult(string literal, bool isDecimal, int row = 10, int col = 25) + { + return new DiagnosticResult(DiagnosticId.NumericLiteral.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(row, col) + .WithMessage(string.Format(NumericLiteralAnalyzer.Message, literal, isDecimal ? "hexadecimal" : "decimal")); + } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs index 9e004869e..27fcfbb2f 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/PropertyChangedEventArgsUnnecessaryAllocationTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Collections.Generic; using System.Threading.Tasks; using Xunit; @@ -32,7 +33,7 @@ public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreatio { var source = $"var args = new PropertyChangedEventArgs({ctorArg})"; - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 12)); + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(1, 12)); } [Theory] @@ -57,7 +58,7 @@ public async Task DoesTriggerDiagnosticAtPropertyChangedEventArgsInstanceCreatio { var source = $"object args = new {{ Name = new PropertyChangedEventArgs({ctorArg}) }}"; - await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(0, 28)); + await VerifyCSharpDiagnosticAsync(source, PropertyChangedUnnecessaryAllocationDiagnostic(1, 28)); } [Theory] @@ -148,16 +149,9 @@ public void TestMethod(string propertyName) public static DiagnosticResult PropertyChangedUnnecessaryAllocationDiagnostic(int line, int column) { - return new DiagnosticResult - { - Id = DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId(), - Message = "Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] - { - new DiagnosticResultLocation("Test0.cs", line, column), - } - }; + return new DiagnosticResult(DiagnosticId.PropertyChangedEventArgsUnnecessaryAllocation.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(line, column) + .WithMessage("Create PropertyChangedEventArgs static instance and reuse it to avoid unecessary memory allocation."); } public static IEnumerable SharedDataCodeFix diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs index 072643c56..528ab9f0d 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ReplaceWithGetterOnlyAutoPropertyTests.cs @@ -1,6 +1,7 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -30,16 +31,9 @@ public async Task SimplePropertyGetsTransformed() public string Value { get { return _value; } } ".WrapInCSharpClass(); - var expected = new DiagnosticResult - { - Id = "CC0125", - Message = GetDiagnosticMessage("Value"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 16, 27) - } - }; + var expected = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(16, 27) + .WithMessage(GetDiagnosticMessage("Value")); await VerifyCSharpDiagnosticAsync(test, expected); @@ -83,16 +77,9 @@ public async Task FieldInitializerIsPreserved() public string Value { get { return this.value; } } ".WrapInCSharpClass(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("Value"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 16, 27) - } - }; + var expected = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(16, 27) + .WithMessage(GetDiagnosticMessage("Value")); await VerifyCSharpDiagnosticAsync(test, expected); @@ -125,26 +112,12 @@ public async Task MultiplePropertiesPerClassGetTranformed() public string Value2 { get { return this.value2; } } ".WrapInCSharpClass(); - var expected1 = new DiagnosticResult - { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("Value"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 17, 27) - } - }; - var expected2 = new DiagnosticResult - { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("Value2"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 18, 27) - } - }; + var expected1 = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(17, 27) + .WithMessage(GetDiagnosticMessage("Value")); + var expected2 = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(18, 27) + .WithMessage(GetDiagnosticMessage("Value2")); await VerifyCSharpDiagnosticAsync(test, new DiagnosticResult[] { expected1, expected2 }); @@ -176,26 +149,12 @@ public async Task MultiplePropertiesPerClassWithFieldInitilizerAndUnusedFieldsGe public string Value { get { return this.value; } } public string Value2 { get { return this.value2; } } ".WrapInCSharpClass(); - var expected1 = new DiagnosticResult - { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("Value"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 17, 27) - } - }; - var expected2 = new DiagnosticResult - { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("Value2"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 18, 27) - } - }; + var expected1 = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(17, 27) + .WithMessage(GetDiagnosticMessage("Value")); + var expected2 = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(18, 27) + .WithMessage(GetDiagnosticMessage("Value2")); await VerifyCSharpDiagnosticAsync(test, new DiagnosticResult[] { expected1, expected2 }); @@ -229,16 +188,9 @@ public async Task TypeOfPropertyMustFitTypeOfBackingField() public IEnumerable Value { get { return this.value; } } public IList Value2 { get { return this.value2; } } ".WrapInCSharpClass(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), - Message = GetDiagnosticMessage("Value2"), - Severity = DiagnosticSeverity.Hidden, - Locations = - new[] { - new DiagnosticResultLocation("Test0.cs", 18, 34) - } - }; + var expected = new DiagnosticResult(DiagnosticId.ReplaceWithGetterOnlyAutoProperty.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(18, 34) + .WithMessage(GetDiagnosticMessage("Value2")); await VerifyCSharpDiagnosticAsync(test, expected); diff --git a/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs index bf3507e67..b99818c1c 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -32,13 +33,9 @@ public async Task IfWithElseDoesNotCreateDiagnostic() public async Task IfWithAndCreatesDiagnostic() { var source = "if (true && true) { }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.SplitIntoNestedIf.ToDiagnosticId(), - Message = string.Format(SplitIntoNestedIfAnalyzer.Message), - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.SplitIntoNestedIf.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, 21) + .WithMessage(string.Format(SplitIntoNestedIfAnalyzer.Message)); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/StringRepresentationTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/StringRepresentationTests.cs index 8a97aca6f..d716b7a01 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/StringRepresentationTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/StringRepresentationTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Refactoring; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Xunit; @@ -55,13 +56,9 @@ void M() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringRepresentation_RegularString.ToDiagnosticId(), - Message = "Change to regular string", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringRepresentation_RegularString.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(6, 17) + .WithMessage("Change to regular string"); return VerifyCSharpDiagnosticAsync(source, expected); } @@ -77,13 +74,9 @@ void M() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringRepresentation_VerbatimString.ToDiagnosticId(), - Message = "Change to verbatim string", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringRepresentation_VerbatimString.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(6, 17) + .WithMessage("Change to verbatim string"); return VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs b/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs index b0aaf74ff..c8e981b55 100644 --- a/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs +++ b/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Reliability; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -18,13 +19,9 @@ public async Task WhenAwaitingTaskAnalyzerCreatesDiagnostic(string sample, int c { var test = sample.WrapInCSharpMethod(isAsync: true); - var expected = new DiagnosticResult - { - Id = DiagnosticId.UseConfigureAwaitFalse.ToDiagnosticId(), - Message = "Consider using ConfigureAwait(false) on the awaited task.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, column) } - }; + var expected = new DiagnosticResult(DiagnosticId.UseConfigureAwaitFalse.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(10, column) + .WithMessage("Consider using ConfigureAwait(false) on the awaited task."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/AlwaysUseVarTests.cs b/test/CSharp/CodeCracker.Test/Style/AlwaysUseVarTests.cs index d78489fbc..54f83e00d 100644 --- a/test/CSharp/CodeCracker.Test/Style/AlwaysUseVarTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/AlwaysUseVarTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Style; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -130,13 +131,9 @@ void Foo() dynamic Fee() { return 42; } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.AlwaysUseVar.ToDiagnosticId(), - Message = "Use 'var' instead of specifying the type name.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 9, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.AlwaysUseVar.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(9, 17) + .WithMessage("Use 'var' instead of specifying the type name."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -158,13 +155,9 @@ public async Task Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.AlwaysUseVarOnPrimitives.ToDiagnosticId(), - Message = "Use 'var' instead of specifying the type name.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.AlwaysUseVarOnPrimitives.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 17) + .WithMessage("Use 'var' instead of specifying the type name."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -187,13 +180,9 @@ public async Task Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.AlwaysUseVar.ToDiagnosticId(), - Message = "Use 'var' instead of specifying the type name.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.AlwaysUseVar.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 17) + .WithMessage("Use 'var' instead of specifying the type name."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/ConsoleWriteLineTests.cs b/test/CSharp/CodeCracker.Test/Style/ConsoleWriteLineTests.cs index 1335bc5df..ad678d592 100644 --- a/test/CSharp/CodeCracker.Test/Style/ConsoleWriteLineTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/ConsoleWriteLineTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Style; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -174,13 +175,9 @@ void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConsoleWriteLine.ToDiagnosticId(), - Message = ConsoleWriteLineAnalyzer.MessageFormat.ToString(), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConsoleWriteLine.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(11, 17) + .WithMessage(ConsoleWriteLineAnalyzer.MessageFormat.ToString()); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -200,13 +197,9 @@ void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConsoleWriteLine.ToDiagnosticId(), - Message = ConsoleWriteLineAnalyzer.MessageFormat.ToString(), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConsoleWriteLine.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 17) + .WithMessage(ConsoleWriteLineAnalyzer.MessageFormat.ToString()); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -404,13 +397,9 @@ void Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConsoleWriteLine.ToDiagnosticId(), - Message = ConsoleWriteLineAnalyzer.MessageFormat.ToString(), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConsoleWriteLine.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(11, 17) + .WithMessage(ConsoleWriteLineAnalyzer.MessageFormat.ToString()); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs b/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs index b82e826f1..0a968adf9 100644 --- a/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Style; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -12,13 +13,9 @@ public class ConvertLambdaExpressionToMethodGroupTests public async Task CreateDiagnosticForSimpleLambdaExpression() { const string test = @"var f = a.Where(item => filter(item));"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertLambdaExpressionToMethodGroup.ToDiagnosticId(), - Message = "You should remove the lambda expression and pass just 'filter' instead.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 1, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertLambdaExpressionToMethodGroup.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(1, 17) + .WithMessage("You should remove the lambda expression and pass just 'filter' instead."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -27,13 +24,9 @@ public async Task CreateDiagnosticForSimpleLambdaExpression() public async Task CreateDiagnosticForSimpleLambdaExpressionWithBlockInBody() { const string test = @"var f = a.Where(item => { return filter(item); });"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertLambdaExpressionToMethodGroup.ToDiagnosticId(), - Message = "You should remove the lambda expression and pass just 'filter' instead.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 1, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertLambdaExpressionToMethodGroup.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(1, 17) + .WithMessage("You should remove the lambda expression and pass just 'filter' instead."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -42,13 +35,9 @@ public async Task CreateDiagnosticForSimpleLambdaExpressionWithBlockInBody() public async Task CreateDiagnosticForParenthesizedLambdaExpressionWithBlockInBody() { const string test = @"var f = a.Foo((param1, param2) => { return filter(param1, param2); });"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertLambdaExpressionToMethodGroup.ToDiagnosticId(), - Message = "You should remove the lambda expression and pass just 'filter' instead.", - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 1, 15) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertLambdaExpressionToMethodGroup.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(1, 15) + .WithMessage("You should remove the lambda expression and pass just 'filter' instead."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/ConvertToExpressionBodiedMemberTests.cs b/test/CSharp/CodeCracker.Test/Style/ConvertToExpressionBodiedMemberTests.cs index 331b8282a..ef0170df5 100644 --- a/test/CSharp/CodeCracker.Test/Style/ConvertToExpressionBodiedMemberTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/ConvertToExpressionBodiedMemberTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Style; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -177,13 +178,9 @@ public async Task Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), - Message = ConvertToExpressionBodiedMemberAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 13) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(8, 13) + .WithMessage(ConvertToExpressionBodiedMemberAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -204,13 +201,9 @@ class TypeName } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), - Message = ConvertToExpressionBodiedMemberAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 13) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(8, 13) + .WithMessage(ConvertToExpressionBodiedMemberAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -231,13 +224,9 @@ public static implicit operator string(TypeName n) } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), - Message = ConvertToExpressionBodiedMemberAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 13) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(8, 13) + .WithMessage(ConvertToExpressionBodiedMemberAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -258,13 +247,9 @@ public Foo this[int id] } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), - Message = ConvertToExpressionBodiedMemberAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 13) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(8, 13) + .WithMessage(ConvertToExpressionBodiedMemberAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -285,13 +270,9 @@ public string Foo } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), - Message = ConvertToExpressionBodiedMemberAnalyzer.MessageFormat, - Severity = DiagnosticSeverity.Hidden, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 13) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToExpressionBodiedMember.ToDiagnosticId(), DiagnosticSeverity.Hidden) + .WithLocation(8, 13) + .WithMessage(ConvertToExpressionBodiedMemberAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/ConvertToSwitchTests.cs b/test/CSharp/CodeCracker.Test/Style/ConvertToSwitchTests.cs index b4fb48bf0..bcdb5d47d 100644 --- a/test/CSharp/CodeCracker.Test/Style/ConvertToSwitchTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/ConvertToSwitchTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Style; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -38,13 +39,9 @@ public async Task Foo(string s) } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToSwitch.ToDiagnosticId(), - Message = "You could use 'switch' instead of 'if'.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToSwitch.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 17) + .WithMessage("You could use 'switch' instead of 'if'."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -76,13 +73,9 @@ public async Task Foo(string s) } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ConvertToSwitch.ToDiagnosticId(), - Message = "You could use 'switch' instead of 'if'.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ConvertToSwitch.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 17) + .WithMessage("You could use 'switch' instead of 'if'."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs b/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs index 129824e22..2c978823b 100644 --- a/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/EmptyObjectInitializerTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Style; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -11,13 +12,9 @@ public class EmptyObjectInitializerTests : CodeFixVerifier action = (p) => { throw new ArgumentException(""message"", ""paramName""); }; "); - var expected = new DiagnosticResult - { - Id = DiagnosticId.ArgumentException.ToDiagnosticId(), - Message = "Type argument 'paramName' is not in the argument list.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 9, 82) } - }; + var expected = new DiagnosticResult(DiagnosticId.ArgumentException.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(9, 82) + .WithMessage("Type argument 'paramName' is not in the argument list."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/CallExtensionMethodAsExtensionTests.cs b/test/CSharp/CodeCracker.Test/Usage/CallExtensionMethodAsExtensionTests.cs index 31de8f5c7..07d98a122 100644 --- a/test/CSharp/CodeCracker.Test/Usage/CallExtensionMethodAsExtensionTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/CallExtensionMethodAsExtensionTests.cs @@ -1,6 +1,7 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -64,13 +65,9 @@ public void Bar() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), - Message = "Do not call 'Any' method of class 'Enumerable' as a static method", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 33) + .WithMessage("Do not call 'Any' method of class 'Enumerable' as a static method"); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -91,13 +88,9 @@ public void Bar() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), - Message = "Do not call 'Any' method of class 'Enumerable' as a static method", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 33) + .WithMessage("Do not call 'Any' method of class 'Enumerable' as a static method"); await VerifyCSharpDiagnosticAsync(source, expected, LanguageVersion.CSharp5); } @@ -116,13 +109,9 @@ public static class C { public static string M(this string s) => s; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), - Message = "Do not call 'M' method of class 'C' as a static method", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 9) } - }; + var expected = new DiagnosticResult(DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 9) + .WithMessage("Do not call 'M' method of class 'C' as a static method"); await VerifyCSharpDiagnosticAsync(source, expected, LanguageVersion.CSharp5); } @@ -142,13 +131,9 @@ public void Bar() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), - Message = "Do not call 'Any' method of class 'Enumerable' as a static method", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 9, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(9, 33) + .WithMessage("Do not call 'Any' method of class 'Enumerable' as a static method"); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -358,13 +343,9 @@ public void Bar() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), - Message = "Do not call 'Any' method of class 'Enumerable' as a static method", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 37) } - }; + var expected = new DiagnosticResult(DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(11, 37) + .WithMessage("Do not call 'Any' method of class 'Enumerable' as a static method"); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -383,13 +364,9 @@ public class Foo } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), - Message = "Do not call 'Any' method of class 'Enumerable' as a static method", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 51) } - }; + var expected = new DiagnosticResult(DiagnosticId.CallExtensionMethodAsExtension.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(8, 51) + .WithMessage("Do not call 'Any' method of class 'Enumerable' as a static method"); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs index 1c46e93f2..2337557a8 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -85,13 +86,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -131,20 +128,12 @@ class D : IDisposable public void Dispose() { } } }"; - var expected1 = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field1"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; - var expected2 = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field2"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 41) } - }; + var expected1 = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field1")); + var expected2 = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 41) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field2")); await VerifyCSharpDiagnosticAsync(source, expected1, expected2); } @@ -169,13 +158,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -199,13 +184,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -297,13 +278,9 @@ struct D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -328,13 +305,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -360,13 +333,9 @@ public void Dispose() { } public void Dispose(bool arg) { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -392,13 +361,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -418,13 +383,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(7, 23) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -445,13 +406,9 @@ class D : IDisposable public void Dispose() { } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - Message = string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 33) + .WithMessage(string.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index cb1437596..daad3e39a 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -157,13 +158,9 @@ public async Task IteratorWithIndirectReturnDoesNotCreateDiagnostic() public async Task DisposableVariableCreatesDiagnostic() { var source = "new System.IO.MemoryStream();".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 17) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -178,13 +175,9 @@ public async Task IgnoresDisposableObjectsCreatedWithUsingStatement() public async Task DisposableVariableDeclaredWithAnotherVariableCreatesOnlyOneDiagnostic() { var source = "System.IO.MemoryStream a, b = new System.IO.MemoryStream();".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 47) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 47) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -336,13 +329,9 @@ static void Foo() void Register(System.Action f) { } } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 34) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(7, 34) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -362,13 +351,9 @@ static void Foo() void Register(System.Action f) { } } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 32) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 32) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -388,13 +373,9 @@ static void Foo() void Register(System.Action f) { } } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 32) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 32) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -414,13 +395,9 @@ static void Foo() void Register(System.Action f) { } } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 32) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(8, 32) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -468,13 +445,9 @@ void System.IDisposable.Dispose() { } public async Task DisposableVariablePassedAsParamCreatesDiagnostic() { var source = "string.Format(\"\", new System.IO.MemoryStream());".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 35) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 35) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -483,13 +456,9 @@ public async Task DisposableVariableCallsIncorrectDisposeCreatesDiagnostic() { var source = @"var m = new System.IO.MemoryStream(); m.Dispose(true);".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 25) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -511,13 +480,9 @@ void System.IDisposable.Dispose() { } public void Dispose() { } } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "Disposable"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 33) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "Disposable")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -563,13 +528,9 @@ void System.IDisposable.Dispose() { } void IOtherDisposable.Dispose() { } } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), - Message = string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "Disposable"), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 33) + .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "Disposable")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.cs index 487f2b557..437626d9d 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -57,13 +58,9 @@ public void Dispose() } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), - Message = "'MyType' should call GC.SuppressFinalize inside the Dispose method.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 33) + .WithMessage("'MyType' should call GC.SuppressFinalize inside the Dispose method."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -263,13 +260,9 @@ public void Dispose() ~MyType() {} }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), - Message = "'MyType' should call GC.SuppressFinalize inside the Dispose method.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(4, 33) + .WithMessage("'MyType' should call GC.SuppressFinalize inside the Dispose method."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/IPAddressAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Usage/IPAddressAnalyzerTests.cs index ccf94d7e4..ca83c566c 100644 --- a/test/CSharp/CodeCracker.Test/Usage/IPAddressAnalyzerTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/IPAddressAnalyzerTests.cs @@ -4,6 +4,7 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -78,12 +79,9 @@ public async Task IfAbbreviateParseIdentifierFoundAndParameterIsNotStringLiteral private static DiagnosticResult CreateDiagnosticResult(int line, int column, Action getErrorMessageAction) { - return new DiagnosticResult { - Id = DiagnosticId.IPAddress.ToDiagnosticId(), - Message = GetErrorMessage(getErrorMessageAction), - Severity = DiagnosticSeverity.Error, - Locations = new[] {new DiagnosticResultLocation("Test0.cs", line, column)} - }; + return new DiagnosticResult(DiagnosticId.IPAddress.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(line, column) + .WithMessage(GetErrorMessage(getErrorMessageAction)); } private static string GetErrorMessage(Action action) diff --git a/test/CSharp/CodeCracker.Test/Usage/IfReturnTrueTests.cs b/test/CSharp/CodeCracker.Test/Usage/IfReturnTrueTests.cs index f45326646..27b4ad1f0 100644 --- a/test/CSharp/CodeCracker.Test/Usage/IfReturnTrueTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/IfReturnTrueTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -153,13 +154,9 @@ public int Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.IfReturnTrue.ToDiagnosticId(), - Message = "You should return the boolean directly.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 9, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.IfReturnTrue.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(9, 17) + .WithMessage("You should return the boolean directly."); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -186,13 +183,9 @@ public int Foo() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.IfReturnTrue.ToDiagnosticId(), - Message = "You should return the boolean directly.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 9, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.IfReturnTrue.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(9, 17) + .WithMessage("You should return the boolean directly."); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/JsonNetAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Usage/JsonNetAnalyzerTests.cs index d94b0be0b..32b49198b 100644 --- a/test/CSharp/CodeCracker.Test/Usage/JsonNetAnalyzerTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/JsonNetAnalyzerTests.cs @@ -2,6 +2,7 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -94,12 +95,9 @@ public async Task IfJArrayParseIdentifierFoundAndJsonTextIsCorrectDoesNotCreates } private static DiagnosticResult CreateDiagnosticResult(int line, int column) { - return new DiagnosticResult { - Id = DiagnosticId.JsonNet.ToDiagnosticId(), - Message = "Unexpected end when reading JSON. Path '', line 1, position 3.", - Severity = DiagnosticSeverity.Error, - Locations = new[] {new DiagnosticResultLocation("Test0.cs", line, column)} - }; + return new DiagnosticResult(DiagnosticId.JsonNet.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(line, column) + .WithMessage("Unexpected end when reading JSON. Path '', line 1, position 3."); } protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() => new JsonNetAnalyzer(); diff --git a/test/CSharp/CodeCracker.Test/Usage/NoPrivateReadonlyFieldTest.cs b/test/CSharp/CodeCracker.Test/Usage/NoPrivateReadonlyFieldTest.cs index 2c707711a..f1fb1e715 100644 --- a/test/CSharp/CodeCracker.Test/Usage/NoPrivateReadonlyFieldTest.cs +++ b/test/CSharp/CodeCracker.Test/Usage/NoPrivateReadonlyFieldTest.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Xunit; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; namespace CodeCracker.Test.CSharp.Usage { @@ -10,14 +11,12 @@ public class NoPrivateReadonlyFieldTests : CodeFixVerifier { protected override DiagnosticAnalyzer GetDiagnosticAnalyzer() => new NoPrivateReadonlyFieldAnalyzer(); - static DiagnosticResult CreateExpectedDiagnosticResult(int line, int column, string fieldName = "i") => - new DiagnosticResult - { - Id = DiagnosticId.NoPrivateReadonlyField.ToDiagnosticId(), - Message = string.Format(NoPrivateReadonlyFieldAnalyzer.Message, fieldName), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", line, column) } - }; + static DiagnosticResult CreateExpectedDiagnosticResult(int line, int column, string fieldName = "i") + { + return new DiagnosticResult(DiagnosticId.NoPrivateReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(line, column) + .WithMessage(string.Format(NoPrivateReadonlyFieldAnalyzer.Message, fieldName)); + } [Fact] public async Task PrivateFieldWithAssignmentOnDeclarationCreatesNoDiagnostic() diff --git a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs index e49637973..8639541c5 100644 --- a/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/ReadonlyFieldTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -182,13 +183,9 @@ class TypeName private int i = 1; } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -203,13 +200,9 @@ class TypeName int i = 1; } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 17) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -225,20 +218,12 @@ class TypeName private int j = 1; } }"; - var expected1 = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; - var expected2 = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "j"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 25) } - }; + var expected1 = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); + var expected2 = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "j")); await VerifyCSharpDiagnosticAsync(source, expected1, expected2); } @@ -259,34 +244,18 @@ class TypeName2 private int l = 1; } }"; - var expected1 = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; - var expected2 = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "j"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 25) } - }; - var expected3 = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "k"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 25) } - }; - var expected4 = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "l"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 25) } - }; + var expected1 = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); + var expected2 = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(7, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "j")); + var expected3 = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(11, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "k")); + var expected4 = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(12, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "l")); await VerifyCSharpDiagnosticAsync(source, new[] { expected1, expected2, expected3, expected4 }); } @@ -304,13 +273,9 @@ class TypeName } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 8, 29) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(8, 29) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -325,13 +290,9 @@ struct TypeName private int i = 1; } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -401,13 +362,9 @@ class TypeName } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -426,13 +383,9 @@ class TypeName } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 25) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -491,13 +444,9 @@ class TypeName private int i, j = 1; } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "j"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 28) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 28) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "j")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -747,13 +696,9 @@ static TypeName() } } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 32) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 32) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -768,13 +713,9 @@ class TypeName private static int i = 1; } }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "i"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 32) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 32) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "i")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -953,13 +894,9 @@ private enum VehicleType } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "car"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 33) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "car")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -981,13 +918,9 @@ public Person(string name) } "; - var expected = new DiagnosticResult - { - Id = DiagnosticId.ReadonlyField.ToDiagnosticId(), - Message = string.Format(ReadonlyFieldAnalyzer.Message, "name"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 28) } - }; + var expected = new DiagnosticResult(DiagnosticId.ReadonlyField.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(6, 28) + .WithMessage(string.Format(ReadonlyFieldAnalyzer.Message, "name")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/RedundantFieldAssignmentTests.cs b/test/CSharp/CodeCracker.Test/Usage/RedundantFieldAssignmentTests.cs index 97caea241..f24ccfc5b 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RedundantFieldAssignmentTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RedundantFieldAssignmentTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -170,13 +171,9 @@ class TypeName { private int i = 0; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", 0), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 17) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", 0)); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -188,13 +185,9 @@ class TypeName { private int i = default(int); }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "default(int)"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 17) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "default(int)")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -206,13 +199,9 @@ class TypeName { private string s = null; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "s", "null"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 20) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 20) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "s", "null")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -224,13 +213,9 @@ class TypeName { private long i = 0L; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "0L"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 18) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 18) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "0L")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -242,13 +227,9 @@ class TypeName { private long i = 0; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "0"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 18) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 18) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "0")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -260,13 +241,9 @@ class TypeName { private System.IntPtr i = System.IntPtr.Zero; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "System.IntPtr.Zero"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 27) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 27) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "System.IntPtr.Zero")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -279,13 +256,9 @@ class TypeName { private IntPtr i = IntPtr.Zero; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "IntPtr.Zero"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 5, 20) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(5, 20) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "IntPtr.Zero")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -297,13 +270,9 @@ class TypeName { private System.UIntPtr i = System.UIntPtr.Zero; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "System.UIntPtr.Zero"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 28) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 28) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "i", "System.UIntPtr.Zero")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -315,13 +284,9 @@ class TypeName { private System.DateTime d = System.DateTime.MinValue; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "d", "System.DateTime.MinValue"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 29) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 29) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "d", "System.DateTime.MinValue")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -334,13 +299,9 @@ class TypeName { private E e = 0; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "e", "0"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 5, 15) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(5, 15) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "e", "0")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -353,13 +314,9 @@ class TypeName { private E e = 0.0; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "e", "0.0"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 5, 15) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(5, 15) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "e", "0.0")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -371,13 +328,9 @@ class TypeName { private bool b = false; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "b", "false"), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 18) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 18) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "b", "false")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -389,13 +342,9 @@ class TypeName { private int i, j, k = 0; }"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), - Message = string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "k", 0), - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 23) } - }; + var expected = new DiagnosticResult(DiagnosticId.RedundantFieldAssignment.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(4, 23) + .WithMessage(string.Format(RedundantFieldAssignmentAnalyzer.MessageFormat, "k", 0)); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/RegexTests.cs b/test/CSharp/CodeCracker.Test/Usage/RegexTests.cs index 6ffda204c..8feee163a 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RegexTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RegexTests.cs @@ -1,6 +1,7 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using System; using System.Threading.Tasks; using Xunit; @@ -76,13 +77,9 @@ public async Task Foo() message = e.Message; } - var expected = new DiagnosticResult - { - Id = DiagnosticId.Regex.ToDiagnosticId(), - Message = message, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 64) } - }; + var expected = new DiagnosticResult(DiagnosticId.Regex.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(11, 64) + .WithMessage(message); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -116,13 +113,9 @@ public async Task Foo() message = e.Message; } - var expected = new DiagnosticResult - { - Id = DiagnosticId.Regex.ToDiagnosticId(), - Message = message, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 33) } - }; + var expected = new DiagnosticResult(DiagnosticId.Regex.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(11, 33) + .WithMessage(message); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs b/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs index 3c5383c1e..ee42e29a9 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RemovePrivateMethodNeverUsedAnalyzerTest.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -427,14 +428,12 @@ public int PropertyXXX { await VerifyCSharpHasNoDiagnosticsAsync(source); } - private static DiagnosticResult CreateDiagnosticResult(int line, int column) => - new DiagnosticResult - { - Id = DiagnosticId.RemovePrivateMethodNeverUsed.ToDiagnosticId(), - Locations = new DiagnosticResultLocation[] { new DiagnosticResultLocation("Test0.cs", line, column) }, - Message = RemovePrivateMethodNeverUsedAnalyzer.Message, - Severity = DiagnosticSeverity.Info, - }; + private static DiagnosticResult CreateDiagnosticResult(int line, int column) + { + return new DiagnosticResult(DiagnosticId.RemovePrivateMethodNeverUsed.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(line, column) + .WithMessage(RemovePrivateMethodNeverUsedAnalyzer.Message); + } [Fact] public async void WinFormsPropertyDefaultValueDefinitionMethodsMustHaveCorrectSignature() diff --git a/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs b/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs index 82904f6f5..9849a0655 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -120,13 +121,9 @@ public async Task CreateDiagnosticsWhenEmptyElse() { var test = @"if(1 == 2){ return 1; } else { }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.RemoveRedundantElseClause.ToDiagnosticId(), - Message = "Remove redundant else", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 41) } - }; + var expected = new DiagnosticResult(DiagnosticId.RemoveRedundantElseClause.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 41) + .WithMessage("Remove redundant else"); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -136,13 +133,9 @@ public async Task CreateDiagnosticsWhenEmptyElseWithoutBlockOnIf() { var test = @"if(1 == 2) return 1; else { }".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.RemoveRedundantElseClause.ToDiagnosticId(), - Message = "Remove redundant else", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 38) } - }; + var expected = new DiagnosticResult(DiagnosticId.RemoveRedundantElseClause.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, 38) + .WithMessage("Remove redundant else"); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs b/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs index 4bec3f3fd..f32efd7e2 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RethrowExceptionTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -27,13 +28,9 @@ public void Foo() [Fact] public async Task WhenThrowingOriginalExceptionAnalyzerCreatesDiagnostic() { - var expected = new DiagnosticResult - { - Id = DiagnosticId.RethrowException.ToDiagnosticId(), - Message = "Throwing the same exception that was caught will lose the original stack trace.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 21) } - }; + var expected = new DiagnosticResult(DiagnosticId.RethrowException.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(12, 21) + .WithMessage("Throwing the same exception that was caught will lose the original stack trace."); await VerifyCSharpDiagnosticAsync(sourceWithUsingSystem, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs b/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs index 714e2bc3c..b1fa44b3f 100644 --- a/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -31,13 +32,9 @@ public async Task WhenComparingWithBoolAnalyzerCreatesDiagnostic(string sample, column += 10; // adjust column for added declaration var test = sample.WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.SimplifyRedundantBooleanComparisons.ToDiagnosticId(), - Message = "You can remove this comparison.", - Severity = DiagnosticSeverity.Info, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, column) } - }; + var expected = new DiagnosticResult(DiagnosticId.SimplifyRedundantBooleanComparisons.ToDiagnosticId(), DiagnosticSeverity.Info) + .WithLocation(10, column) + .WithMessage("You can remove this comparison."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs b/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs index 5b6cf0257..b5ffbb6e9 100644 --- a/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs @@ -3,6 +3,7 @@ using Xunit; using Microsoft.CodeAnalysis.Diagnostics; using CodeCracker.CSharp.Usage; +using Microsoft.CodeAnalysis.Testing; namespace CodeCracker.Test.CSharp.Usage { @@ -82,13 +83,9 @@ public async Task IgnoresMethodsCalledWithIncorrectParameterTypes() public async Task NoParametersCreatesError() { var source = @"var result = string.Format(""{0}"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.InvalidArgsReferenceMessage, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(10, 30) + .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -96,13 +93,9 @@ public async Task NoParametersCreatesError() public async Task LessParametersCreatesError() { var source = @"var result = string.Format(""one {0} two {1}"", ""a"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.InvalidArgsReferenceMessage, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(10, 30) + .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -110,13 +103,9 @@ public async Task LessParametersCreatesError() public async Task MoreArgumentsCreatesWarning() { var source = @"var result = string.Format(""one {0} two {1}"", ""a"", ""b"", ""c"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 30) + .WithMessage(StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -145,13 +134,9 @@ public async Task MethodWithParamtersReferencingSingleAndFormatSpecifiersArgumen public async Task TwoParametersReferencingSamePlaceholderCreatesWarning() { var source = @"var result = string.Format(""one {0} two {0}"", ""a"", ""b"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 30) + .WithMessage(StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -183,13 +168,9 @@ public async Task VerbatimStringWithMissingArgCreatesError() var noun = ""Giovanni""; var s = string.Format(@""This {0} is """"{1}""""."", noun);".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.InvalidArgsReferenceMessage, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 12, 25) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(12, 25) + .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -197,13 +178,9 @@ public async Task VerbatimStringWithMissingArgCreatesError() public async Task InvalidArgumentReferenceCreatesError() { var source = @"var result = string.Format(""one {1}"", ""a"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.InvalidArgsReferenceMessage, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(10, 30) + .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -211,13 +188,9 @@ public async Task InvalidArgumentReferenceCreatesError() public async Task NonIntegerPlaceholderCreatesError() { var source = @"var result = string.Format(""one {notZero}"", ""a"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.InvalidArgsReferenceMessage, - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 30) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(10, 30) + .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -225,13 +198,9 @@ public async Task NonIntegerPlaceholderCreatesError() public async Task UnusedArgsCreatesWarning() { var source = @"string.Format(""{0}{1}{3}{5}"", ""a"", ""b"", ""c"", ""d"", ""e"", ""f"");".WrapInCSharpMethod(); - var expected = new DiagnosticResult - { - Id = DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), - Message = StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 17) } - }; + var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(10, 17) + .WithMessage(StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage); await VerifyCSharpDiagnosticAsync(source, expected); } } diff --git a/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs b/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs index 2b08add48..2bee868b0 100644 --- a/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/UnusedParametersTests.cs @@ -1,5 +1,6 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; using System.Threading.Tasks; using Xunit; @@ -330,13 +331,9 @@ await VerifyCSharpDiagnosticAsync(source, public static DiagnosticResult CreateDiagnosticResult(string parameterName, int line, int column) { - return new DiagnosticResult - { - Id = DiagnosticId.UnusedParameters.ToDiagnosticId(), - Message = string.Format(UnusedParametersAnalyzer.Message, parameterName), - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", line, column) } - }; + return new DiagnosticResult(DiagnosticId.UnusedParameters.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(line, column) + .WithMessage(string.Format(UnusedParametersAnalyzer.Message, parameterName)); } [Fact] diff --git a/test/CSharp/CodeCracker.Test/Usage/UriAnalyzerTests.cs b/test/CSharp/CodeCracker.Test/Usage/UriAnalyzerTests.cs index 8a947ea9a..e48b9a1f8 100644 --- a/test/CSharp/CodeCracker.Test/Usage/UriAnalyzerTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/UriAnalyzerTests.cs @@ -3,6 +3,7 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Usage @@ -93,13 +94,9 @@ public void Test() { private static DiagnosticResult CreateDiagnosticResult(int line, int column, Action getErrorMessageAction) { - return new DiagnosticResult - { - Id = DiagnosticId.Uri.ToDiagnosticId(), - Message = GetErrorMessage(getErrorMessageAction), - Severity = DiagnosticSeverity.Error, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", line, column) } - }; + return new DiagnosticResult(DiagnosticId.Uri.ToDiagnosticId(), DiagnosticSeverity.Error) + .WithLocation(line, column) + .WithMessage(GetErrorMessage(getErrorMessageAction)); } private static string GetErrorMessage(Action action) diff --git a/test/CSharp/CodeCracker.Test/Usage/VirtualMethodOnConstructorTests.cs b/test/CSharp/CodeCracker.Test/Usage/VirtualMethodOnConstructorTests.cs index 6d55294df..1c3800de0 100644 --- a/test/CSharp/CodeCracker.Test/Usage/VirtualMethodOnConstructorTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/VirtualMethodOnConstructorTests.cs @@ -2,6 +2,7 @@ using CodeCracker.CSharp.Usage; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using Xunit; namespace CodeCracker.Test.CSharp.Usage { @@ -21,12 +22,9 @@ public virtual void DoFoo(string foo) { } }"; - var expected = new DiagnosticResult { - Id = DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), - Message = VirtualMethodOnConstructorAnalyzer.Message, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 3) } - }; + var expected = new DiagnosticResult(DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 3) + .WithMessage(VirtualMethodOnConstructorAnalyzer.Message); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -45,12 +43,9 @@ public virtual void DoFoo(string foo) { } }"; - var expected = new DiagnosticResult { - Id = DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), - Message = VirtualMethodOnConstructorAnalyzer.Message, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 3) } - }; + var expected = new DiagnosticResult(DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 3) + .WithMessage(VirtualMethodOnConstructorAnalyzer.Message); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -110,18 +105,12 @@ public virtual void DoFoo2(string foo) { } }"; - var expected = new DiagnosticResult { - Id = DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), - Message = VirtualMethodOnConstructorAnalyzer.Message, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 3) } - }; - var expected2 = new DiagnosticResult { - Id = DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), - Message = VirtualMethodOnConstructorAnalyzer.Message, - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 3) } - }; + var expected = new DiagnosticResult(DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(6, 3) + .WithMessage(VirtualMethodOnConstructorAnalyzer.Message); + var expected2 = new DiagnosticResult(DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(), DiagnosticSeverity.Warning) + .WithLocation(7, 3) + .WithMessage(VirtualMethodOnConstructorAnalyzer.Message); await VerifyCSharpDiagnosticAsync(test, expected, expected2); } diff --git a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj index 0f296cd69..db5e82f6f 100644 --- a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj +++ b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj @@ -44,6 +44,7 @@ + @@ -53,7 +54,6 @@ - diff --git a/test/Common/CodeCracker.Test.Common/Helpers/DiagnosticResult.cs b/test/Common/CodeCracker.Test.Common/Helpers/DiagnosticResult.cs deleted file mode 100644 index 46d38366e..000000000 --- a/test/Common/CodeCracker.Test.Common/Helpers/DiagnosticResult.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Microsoft.CodeAnalysis; -using System; - -namespace CodeCracker.Test -{ - /// - /// Location where the diagnostic appears, as determined by path, line number, and column number. - /// - public struct DiagnosticResultLocation - { - public DiagnosticResultLocation(string path, int line, int column) - { - if (line < 0 && column < 0) - { - throw new ArgumentOutOfRangeException("At least one of line and column must be > 0"); - } - if (line < -1 || column < -1) - { - throw new ArgumentOutOfRangeException("Both line and column must be >= -1"); - } - - Path = path; - Line = line; - Column = column; - } - - public string Path { get; set; } - public int Line { get; set; } - public int Column { get; set; } - } - - /// - /// Struct that stores information about a Diagnostic appearing in a source - /// - public struct DiagnosticResult - { - private DiagnosticResultLocation[] locations; - - public DiagnosticResultLocation[] Locations - { - get - { - if (locations == null) - { - locations = new DiagnosticResultLocation[] { }; - } - return locations; - } - - set - { - locations = value; - } - } - - public DiagnosticSeverity Severity { get; set; } - - public string Id { get; set; } - - public string Message { get; set; } - - public string Path - { - get - { - return Locations.Length > 0 ? Locations[0].Path : ""; - } - } - - public int Line - { - get - { - return Locations.Length > 0 ? Locations[0].Line : -1; - } - } - - public int Column - { - get - { - return Locations.Length > 0 ? Locations[0].Column : -1; - } - } - } -} \ No newline at end of file diff --git a/test/Common/CodeCracker.Test.Common/Verifiers/DiagnosticVerifier.cs b/test/Common/CodeCracker.Test.Common/Verifiers/DiagnosticVerifier.cs index 6163123c2..d692a8e10 100644 --- a/test/Common/CodeCracker.Test.Common/Verifiers/DiagnosticVerifier.cs +++ b/test/Common/CodeCracker.Test.Common/Verifiers/DiagnosticVerifier.cs @@ -1,6 +1,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; using System.Collections.Generic; using System.Linq; using System.Text; @@ -113,7 +114,8 @@ protected async Task VerifyBasicDiagnosticAsync(string[] sources, DiagnosticResu private async static Task VerifyDiagnosticsAsync(string[] sources, string language, DiagnosticAnalyzer analyzer, DiagnosticResult[] expected, LanguageVersion languageVersionCSharp, Microsoft.CodeAnalysis.VisualBasic.LanguageVersion languageVersionVB) { var diagnostics = await GetSortedDiagnosticsAsync(sources, language, analyzer, languageVersionCSharp, languageVersionVB).ConfigureAwait(true); - VerifyDiagnosticResults(diagnostics, analyzer, expected); + var defaultFilePath = language == LanguageNames.CSharp ? CSharpDefaultFilePath : VisualBasicDefaultFilePath; + VerifyDiagnosticResults(diagnostics, analyzer, defaultFilePath, expected); } @@ -124,7 +126,7 @@ private async static Task VerifyDiagnosticsAsync(string[] sources, string langua /// The Diagnostics found by the compiler after running the analyzer on the source code /// The analyzer that was being run on the sources /// Diagnsotic Results that should have appeared in the code - private static void VerifyDiagnosticResults(IEnumerable actualResults, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expectedResults) + private static void VerifyDiagnosticResults(IEnumerable actualResults, DiagnosticAnalyzer analyzer, string defaultFilePath, params DiagnosticResult[] expectedResults) { var expectedCount = expectedResults.Length; var actualCount = actualResults.Count(); @@ -139,9 +141,9 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult for (int i = 0; i < expectedResults.Length; i++) { var actual = actualResults.ElementAt(i); - var expected = expectedResults[i]; + var expected = expectedResults[i].WithDefaultPath(defaultFilePath); - if (expected.Line == -1 && expected.Column == -1) + if (!expected.HasLocation) { if (actual.Location != Location.None) { @@ -150,17 +152,17 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult } else { - VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Locations.First()); + VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Spans.First()); var additionalLocations = actual.AdditionalLocations.ToArray(); - if (additionalLocations.Length != expected.Locations.Length - 1) + if (additionalLocations.Length != expected.Spans.Length - 1) { - Assert.True(false, $"Expected {expected.Locations.Length - 1} additional locations but got {additionalLocations.Length} for Diagnostic:\r\n {FormatDiagnostics(analyzer, actual)}\r\n"); + Assert.True(false, $"Expected {expected.Spans.Length - 1} additional locations but got {additionalLocations.Length} for Diagnostic:\r\n {FormatDiagnostics(analyzer, actual)}\r\n"); } for (int j = 0; j < additionalLocations.Length; ++j) { - VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Locations[j + 1]); + VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Spans[j + 1]); } } @@ -182,7 +184,7 @@ private static void VerifyDiagnosticResults(IEnumerable actualResult /// The diagnostic that was found in the code /// The Location of the Diagnostic found in the code /// The DiagnosticResultLocation that should have been found - private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) + private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, FileLinePositionSpan expected) { var actualSpan = actual.GetLineSpan(); @@ -193,13 +195,13 @@ private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagno // Only check line position if there is an actual line in the real diagnostic if (actualLinePosition.Line > 0) - if (actualLinePosition.Line + 1 != expected.Line) - Assert.True(false, $"Expected diagnostic to be on line \"{expected.Line}\" was actually on line \"{actualLinePosition.Line + 1}\"\r\n\r\nDiagnostic:\r\n {FormatDiagnostics(analyzer, diagnostic)}\r\n"); + if (actualLinePosition.Line != expected.StartLinePosition.Line) + Assert.True(false, $"Expected diagnostic to be on line \"{expected.StartLinePosition.Line + 1}\" was actually on line \"{actualLinePosition.Line + 1}\"\r\n\r\nDiagnostic:\r\n {FormatDiagnostics(analyzer, diagnostic)}\r\n"); // Only check column position if there is an actual column position in the real diagnostic if (actualLinePosition.Character > 0) - if (actualLinePosition.Character + 1 != expected.Column) - Assert.True(false, $"Expected diagnostic to start at column \"{expected.Column}\" was actually at column \"{actualLinePosition.Character + 1}\"\r\n\r\nDiagnostic:\r\n {FormatDiagnostics(analyzer, diagnostic)}\r\n"); + if (actualLinePosition.Character != expected.StartLinePosition.Character) + Assert.True(false, $"Expected diagnostic to start at column \"{expected.StartLinePosition.Character + 1}\" was actually at column \"{actualLinePosition.Character + 1}\"\r\n\r\nDiagnostic:\r\n {FormatDiagnostics(analyzer, diagnostic)}\r\n"); } /// diff --git a/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj b/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj index e27355417..7f18764a2 100644 --- a/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj +++ b/test/VisualBasic/CodeCracker.Test/CodeCracker.Test.vbproj @@ -60,7 +60,7 @@ - + diff --git a/test/VisualBasic/CodeCracker.Test/Design/NameOfTests.vb b/test/VisualBasic/CodeCracker.Test/Design/NameOfTests.vb index 641b65c8e..f5b70fa98 100644 --- a/test/VisualBasic/CodeCracker.Test/Design/NameOfTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Design/NameOfTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Design +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Design @@ -591,13 +592,9 @@ End Class" End Function Private Function CreateNameofDiagnosticResult(nameofArgument As String, diagnosticLine As Integer, diagnosticColumn As Integer, Optional id As DiagnosticId = DiagnosticId.NameOf) As DiagnosticResult - Return New DiagnosticResult With - { - .Id = id.ToDiagnosticId(), - .Message = $"Use 'NameOf({nameofArgument})' instead of specifying the program element name.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", diagnosticLine, diagnosticColumn)} - } + Return New DiagnosticResult(id.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(diagnosticLine, diagnosticColumn) _ + .WithMessage($"Use 'NameOf({nameofArgument})' instead of specifying the program element name.") End Function End Class End Namespace \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/Design/StaticConstructorExceptionTests.vb b/test/VisualBasic/CodeCracker.Test/Design/StaticConstructorExceptionTests.vb index 9501ea066..de4131a19 100644 --- a/test/VisualBasic/CodeCracker.Test/Design/StaticConstructorExceptionTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Design/StaticConstructorExceptionTests.vb @@ -1,5 +1,6 @@ Imports CodeCracker.VisualBasic.Design Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports System.IO @@ -18,12 +19,9 @@ Public Class TestClass End Sub End Class" - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.StaticConstructorException.ToDiagnosticId(), - .Message = "Don't throw exceptions inside static constructors.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 4, 9)} - } + Dim expected = New DiagnosticResult(DiagnosticId.StaticConstructorException.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(4, 9) _ + .WithMessage("Don't throw exceptions inside static constructors.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.vb b/test/VisualBasic/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.vb index b1f8d1987..aca8cb0da 100644 --- a/test/VisualBasic/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.vb @@ -1,5 +1,6 @@ Imports CodeCracker.VisualBasic.Performance Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Performance @@ -39,39 +40,27 @@ Namespace Performance Public Async Function CreateDiagnosticsWhenAssigningAPotentialConstant() As Task Dim test = "Dim a As Integer = 10".WrapInVBMethod() - Dim expected = New DiagnosticResult With - { - .Id = MakeLocalVariableConstWhenPossibleAnalyzer.Id, - .Message = "This variable can be made const.", - .Severity = DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 13)} - } + Dim expected = New DiagnosticResult(MakeLocalVariableConstWhenPossibleAnalyzer.Id, DiagnosticSeverity.Info) _ + .WithLocation(6, 13) _ + .WithMessage("This variable can be made const.") Await VerifyBasicDiagnosticAsync(test, expected) End Function Public Async Function CreateDiagnosticsWhenAssigningAPotentialConstantUsingTypeInference() As Task Dim test = "Dim a = 10".WrapInVBMethod() - Dim expected = New DiagnosticResult With - { - .Id = MakeLocalVariableConstWhenPossibleAnalyzer.Id, - .Message = "This variable can be made const.", - .Severity = DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 13)} - } + Dim expected = New DiagnosticResult(MakeLocalVariableConstWhenPossibleAnalyzer.Id, DiagnosticSeverity.Info) _ + .WithLocation(6, 13) _ + .WithMessage("This variable can be made const.") Await VerifyBasicDiagnosticAsync(test, expected) End Function Public Async Function CreateDiagnosticsWhenAssigningNothingToAReferenceType() As Task Dim test = "Dim a As Foo = Nothing".WrapInVBMethod() - Dim expected = New DiagnosticResult With - { - .Id = MakeLocalVariableConstWhenPossibleAnalyzer.Id, - .Message = "This variable can be made const.", - .Severity = DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 13)} - } + Dim expected = New DiagnosticResult(MakeLocalVariableConstWhenPossibleAnalyzer.Id, DiagnosticSeverity.Info) _ + .WithLocation(6, 13) _ + .WithMessage("This variable can be made const.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.vb b/test/VisualBasic/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.vb index ce396c0d5..e4176f42e 100644 --- a/test/VisualBasic/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Performance +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Performance @@ -26,13 +27,9 @@ Namespace Sample End Class End Namespace" - Dim expected = New DiagnosticResult With - { - .Id = RemoveWhereWhenItIsPossibleAnalyzer.Id, - .Message = "You can remove 'Where' moving the predicate to '" + method + "'.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 7, 23)} - } + Dim expected = New DiagnosticResult(RemoveWhereWhenItIsPossibleAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(7, 23) _ + .WithMessage("You can remove 'Where' moving the predicate to '" + method + "'.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Performance/SealedAttributeTests.vb b/test/VisualBasic/CodeCracker.Test/Performance/SealedAttributeTests.vb index ec0f627bb..23c231e93 100644 --- a/test/VisualBasic/CodeCracker.Test/Performance/SealedAttributeTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Performance/SealedAttributeTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Performance +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Performance @@ -12,13 +13,9 @@ Public Class MyAttribute Inherits System.Attribute End Class" - Dim expected = New DiagnosticResult With - { - .Id = SealedAttributeAnalyzer.Id, - .Message = "Mark 'MyAttribute' as NotInheritable.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 2, 14)} - } + Dim expected = New DiagnosticResult(SealedAttributeAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(2, 14) _ + .WithMessage("Mark 'MyAttribute' as NotInheritable.") Await VerifyBasicDiagnosticAsync(test, expected) @@ -35,13 +32,9 @@ Public Class OtherAttribute Inherits MyAttribute End Class" - Dim expected = New DiagnosticResult With - { - .Id = SealedAttributeAnalyzer.Id, - .Message = "Mark 'OtherAttribute' as NotInheritable.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 14)} - } + Dim expected = New DiagnosticResult(SealedAttributeAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(6, 14) _ + .WithMessage("Mark 'OtherAttribute' as NotInheritable.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Performance/StringBuilderInLoopTests.vb b/test/VisualBasic/CodeCracker.Test/Performance/StringBuilderInLoopTests.vb index 02db187a8..01d6f79a7 100644 --- a/test/VisualBasic/CodeCracker.Test/Performance/StringBuilderInLoopTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Performance/StringBuilderInLoopTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Performance +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Performance @@ -75,19 +76,16 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As DiagnosticResult = GetExpected() - expected.Locations(0).Line = 7 - expected.Locations(0).Column = 17 + Dim expected = New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(7, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a")) Await VerifyBasicDiagnosticAsync(source, expected) End Function Private Shared Function GetExpected() As DiagnosticResult - Return New DiagnosticResult With { - .Id = StringBuilderInLoopAnalyzer.Id, - .Message = String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 9, 17)} - } + Return New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(9, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a")) End Function @@ -116,9 +114,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As DiagnosticResult = GetExpected() - expected.Locations(0).Line = 7 - expected.Locations(0).Column = 17 + Dim expected = New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(7, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -134,19 +132,12 @@ End Namespace" Console.WriteLine(myString2) ".WrapInVBMethod() - Dim expected1 As New DiagnosticResult With { - .Id = StringBuilderInLoopAnalyzer.Id, - .Message = String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 10, 17)} - } - - Dim expected2 As New DiagnosticResult With { - .Id = StringBuilderInLoopAnalyzer.Id, - .Message = String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString2"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 11, 17)} - } + Dim expected1 = New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(10, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a")) + Dim expected2 = New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(11, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "myString2")) Await VerifyBasicDiagnosticAsync(source, expected1, expected2) End Function @@ -392,13 +383,9 @@ End Namespace" a += """" Next".WrapInVBMethod - Dim expected As New DiagnosticResult With - { - .Id = StringBuilderInLoopAnalyzer.Id, - .Message = String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 9, 17)} - } + Dim expected = New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(9, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -430,13 +417,9 @@ End Namespace" Loop Until DateTime.Now.Second Mod 2 = 0 ".WrapInVBMethod - Dim expected As New DiagnosticResult With - { - .Id = StringBuilderInLoopAnalyzer.Id, - .Message = String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 9, 17)} - } + Dim expected = New DiagnosticResult(StringBuilderInLoopAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(9, 17) _ + .WithMessage(String.Format(StringBuilderInLoopAnalyzer.MessageFormat, "a")) Await VerifyBasicDiagnosticAsync(source, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.vb b/test/VisualBasic/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.vb index c4ad336f1..2d65a860e 100644 --- a/test/VisualBasic/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Refactoring/AllowMembersOrderingAnalyzerTests.vb @@ -1,6 +1,7 @@ Imports Microsoft.CodeAnalysis.Diagnostics Imports CodeCracker.VisualBasic.Refactoring Imports Xunit +Imports Microsoft.CodeAnalysis.Testing Namespace Refactoring Public Class AllowMembersOrderingAnalyzerTests @@ -43,12 +44,9 @@ End {0}", typeDeclaration) End Sub End {0}", typeDeclaration) - Dim expected = New DiagnosticResult With { - .Id = AllowMembersOrderingAnalyzer.Id, - .Message = AllowMembersOrderingAnalyzer.MessageFormat, - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden, - .Locations = {New DiagnosticResultLocation("Test0.vb", 2, 14 + typeDeclaration.Length)} - } + Dim expected = New DiagnosticResult(AllowMembersOrderingAnalyzer.Id, Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden) _ + .WithLocation(2, 14 + typeDeclaration.Length) _ + .WithMessage(AllowMembersOrderingAnalyzer.MessageFormat) Await VerifyBasicDiagnosticAsync(test, expected) End Function End Class diff --git a/test/VisualBasic/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.vb b/test/VisualBasic/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.vb index feb3b99d3..64856acaf 100644 --- a/test/VisualBasic/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Refactoring/ChangeAnyToAllTests.vb @@ -1,5 +1,6 @@ Imports CodeCracker.VisualBasic.Refactoring Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.Testing Imports System.Threading.Tasks Imports Xunit @@ -29,12 +30,9 @@ Namespace Refactoring Public Async Function AnyAndAllWithLinqCreatesDiagnostic(code As String, column As Integer, diagnosticId As DiagnosticId) As Task Dim source = code.WrapInVBMethod(imports:=" Imports System.Linq") - Dim expected = New DiagnosticResult With { - .Id = diagnosticId.ToDiagnosticId(), - .Message = If(diagnosticId = DiagnosticId.ChangeAnyToAll, ChangeAnyToAllAnalyzer.MessageAny, ChangeAnyToAllAnalyzer.MessageAll), - .Severity = DiagnosticSeverity.Hidden, - .Locations = {New DiagnosticResultLocation("Test0.vb", 9, column)} - } + Dim expected = New DiagnosticResult(diagnosticId.ToDiagnosticId(), DiagnosticSeverity.Hidden) _ + .WithLocation(9, column) _ + .WithMessage(If(diagnosticId = DiagnosticId.ChangeAnyToAll, ChangeAnyToAllAnalyzer.MessageAny, ChangeAnyToAllAnalyzer.MessageAll)) Await VerifyBasicDiagnosticAsync(source, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.vb b/test/VisualBasic/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.vb index f98bc3847..7c03192f9 100644 --- a/test/VisualBasic/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Reliability +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Reliability @@ -14,12 +15,9 @@ Namespace Reliability Public Async Function WhenAwaitingTaskAnalyzerCreatesDiagnostic(sample As String, column As Integer) As Task Dim test = sample.WrapInVBMethod(isAsync:=True) - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.UseConfigureAwaitFalse.ToDiagnosticId(), - .Message = "Consider using ConfigureAwait(False) on the awaited task.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, column)} - } + Dim expected = New DiagnosticResult(DiagnosticId.UseConfigureAwaitFalse.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Hidden) _ + .WithLocation(6, column) _ + .WithMessage("Consider using ConfigureAwait(False) on the awaited task.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Style/InterfaceNameTests.vb b/test/VisualBasic/CodeCracker.Test/Style/InterfaceNameTests.vb index 28adafc53..0c61b24b8 100644 --- a/test/VisualBasic/CodeCracker.Test/Style/InterfaceNameTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Style/InterfaceNameTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Style +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Style @@ -23,12 +24,9 @@ End Namespace" End Interface End Namespace" - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.InterfaceName.ToDiagnosticId(), - .Message = InterfaceNameAnalyzer.MessageFormat, - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 2, 5)} - } + Dim expected = New DiagnosticResult(DiagnosticId.InterfaceName.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(2, 5) _ + .WithMessage(InterfaceNameAnalyzer.MessageFormat) Await VerifyBasicDiagnosticAsync(source, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Style/TernaryOperatorTests.vb b/test/VisualBasic/CodeCracker.Test/Style/TernaryOperatorTests.vb index 4e1c8a3a2..0a956c38a 100644 --- a/test/VisualBasic/CodeCracker.Test/Style/TernaryOperatorTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Style/TernaryOperatorTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Style +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Style @@ -144,12 +145,9 @@ End Namespace" Public Async Function WhenUsingIfAndElseWithDirectReturnAnalyzerCreatesDiagnostic() As Task - Dim expected As New DiagnosticResult With { - .Id = DiagnosticId.TernaryOperator_Assignment.ToDiagnosticId(), - .Message = "You can use a ternary operator.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 8, 13)} - } + Dim expected = New DiagnosticResult(DiagnosticId.TernaryOperator_Assignment.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(8, 13) _ + .WithMessage("You can use a ternary operator.") Await VerifyBasicDiagnosticAsync(sourceAssign, expected) End Function @@ -793,12 +791,9 @@ End Namespace" Public Async Function WhenUsingIfAndElseWithDirectReturnAnalyzerCreatesDiagnostic() As Task - Dim expected As New DiagnosticResult With { - .Id = DiagnosticId.TernaryOperator_Return.ToDiagnosticId(), - .Message = "You can use a ternary operator.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 13)} - } + Dim expected = New DiagnosticResult(DiagnosticId.TernaryOperator_Return.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(6, 13) _ + .WithMessage("You can use a ternary operator.") Await VerifyBasicDiagnosticAsync(sourceReturn, expected) End Function @@ -1005,12 +1000,9 @@ Class MyType End Function End Class" - Dim expected As New DiagnosticResult With { - .Id = DiagnosticId.TernaryOperator_Iif.ToDiagnosticId(), - .Message = "You can use a ternary operator.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 16)} - } + Dim expected = New DiagnosticResult(DiagnosticId.TernaryOperator_Iif.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(5, 16) _ + .WithMessage("You can use a ternary operator.") Await VerifyBasicDiagnosticAsync(source, expected) Await VerifyBasicFixAsync(source, fix) diff --git a/test/VisualBasic/CodeCracker.Test/Usage/ArgumentExceptionTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/ArgumentExceptionTests.vb index 681fe9584..b2ac9db8d 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/ArgumentExceptionTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/ArgumentExceptionTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Usage +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -24,12 +25,9 @@ Public Async Function Foo(a As Integer, b As Integer) As Task End Function ") - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.ArgumentException.ToDiagnosticId(), - .Message = "Type argument 'c' is not in the argument list.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 8, 44)} - } + Dim expected = New DiagnosticResult(DiagnosticId.ArgumentException.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(8, 44) _ + .WithMessage("Type argument 'c' is not in the argument list.") Await VerifyBasicDiagnosticAsync(test, expected) End Function @@ -42,12 +40,9 @@ Public Sub New(a As Integer, b As Integer) End Sub ") - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.ArgumentException.ToDiagnosticId(), - .Message = "Type argument 'c' is not in the argument list.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 8, 44)} - } + Dim expected = New DiagnosticResult(DiagnosticId.ArgumentException.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(8, 44) _ + .WithMessage("Type argument 'c' is not in the argument list.") Await VerifyBasicDiagnosticAsync(test, expected) End Function @@ -147,12 +142,9 @@ End Sub End Set End Property ") - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.ArgumentException.ToDiagnosticId(), - .Message = "Type argument 'paramName' is not in the argument list.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 11, 56)} - } + Dim expected = New DiagnosticResult(DiagnosticId.ArgumentException.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(11, 56) _ + .WithMessage("Type argument 'paramName' is not in the argument list.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.vb index ad742040d..f1f583c6d 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/DisposableFieldNotDisposedTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Usage +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -35,13 +36,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(5, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -83,20 +80,12 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 17)} - } - Dim expected2 As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field2"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(5, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) + Dim expected2 = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(6, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field2")) Await VerifyBasicDiagnosticAsync(source, expected, expected2) End Function @@ -122,13 +111,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(5, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -154,13 +139,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(6, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -208,13 +189,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 7, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(7, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -240,13 +217,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 8, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(8, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -273,13 +246,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(6, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -307,13 +276,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 6, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(6, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -334,13 +299,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Created.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(5, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function @@ -361,13 +322,9 @@ Namespace ConsoleApplication1 End Class End Namespace" - Dim expected As New DiagnosticResult With - { - .Id = DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), - .Message = String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field"), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Info, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 17)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposableFieldNotDisposed_Returned.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Info) _ + .WithLocation(5, 17) _ + .WithMessage(String.Format(DisposableFieldNotDisposedAnalyzer.MessageFormat, "field")) Await VerifyBasicDiagnosticAsync(source, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.vb index ecdd57888..89ea62f97 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/DisposablesShouldCallSuppressFinalizeTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Usage +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -15,12 +16,9 @@ Public Class MyType End Sub End Class " - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), - .Message = "'MyType' should call GC.SuppressFinalize inside the Dispose method.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 16)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(5, 16) _ + .WithMessage("'MyType' should call GC.SuppressFinalize inside the Dispose method.") Await VerifyBasicDiagnosticAsync(test, expected) End Function @@ -109,12 +107,9 @@ Public NotInheritable Class MyType End Class " - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), - .Message = "'MyType' should call GC.SuppressFinalize inside the Dispose method.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 5, 16)} - } + Dim expected = New DiagnosticResult(DiagnosticId.DisposablesShouldCallSuppressFinalize.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(5, 16) _ + .WithMessage("'MyType' should call GC.SuppressFinalize inside the Dispose method.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Usage/IPAddressAnalyzerTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/IPAddressAnalyzerTests.vb index c2c4a62cf..83b260e86 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/IPAddressAnalyzerTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/IPAddressAnalyzerTests.vb @@ -2,6 +2,7 @@ Imports CodeCracker.VisualBasic Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Public Class IPAddressAnalyzerTests @@ -53,11 +54,9 @@ End Namespace" End Function Private Function CreateDiagnosticResult(line As Integer, column As Integer, errorMessageAction As Action) As DiagnosticResult - Return New DiagnosticResult With { - .Id = DiagnosticId.IPAddress.ToDiagnosticId(), - .Message = GetErrorMessage(errorMessageAction), - .Severity = DiagnosticSeverity.Error, - .Locations = {New DiagnosticResultLocation("Test0.vb", line, column)}} + Return New DiagnosticResult(DiagnosticId.IPAddress.ToDiagnosticId(), DiagnosticSeverity.Error) _ + .WithLocation(line, column) _ + .WithMessage(GetErrorMessage(errorMessageAction)) End Function Private Shared Function GetErrorMessage(action As Action) As String diff --git a/test/VisualBasic/CodeCracker.Test/Usage/JsonNetAnalyzerTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/JsonNetAnalyzerTests.vb index a1b921ef7..6b573b250 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/JsonNetAnalyzerTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/JsonNetAnalyzerTests.vb @@ -1,5 +1,6 @@ Imports CodeCracker.VisualBasic.Usage Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -19,12 +20,9 @@ Namespace ConsoleApplication1 End Namespace" Private Shared Function CreateDiagnosticResult(line As Integer, column As Integer) As DiagnosticResult - Return New DiagnosticResult With { - .Id = DiagnosticId.JsonNet.ToDiagnosticId(), - .Message = "Unexpected end when reading JSON. Path '', line 1, position 3.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Error, - .Locations = {New DiagnosticResultLocation("Test0.vb", line, column)} - } + Return New DiagnosticResult(DiagnosticId.JsonNet.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Error) _ + .WithLocation(line, column) _ + .WithMessage("Unexpected end when reading JSON. Path '', line 1, position 3.") End Function Protected Overrides Function GetDiagnosticAnalyzer() As DiagnosticAnalyzer diff --git a/test/VisualBasic/CodeCracker.Test/Usage/MustInheritClassShouldNotHavePublicConstructorTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/MustInheritClassShouldNotHavePublicConstructorTests.vb index 30093ff9e..3ec7ccf1e 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/MustInheritClassShouldNotHavePublicConstructorTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/MustInheritClassShouldNotHavePublicConstructorTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Usage +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -14,12 +15,9 @@ MustInherit Class Foo End Sub End Class" - Dim expected = New DiagnosticResult With { - .Id = DiagnosticId.AbstractClassShouldNotHavePublicCtors.ToDiagnosticId(), - .Message = "Constructor should not be public.", - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", 3, 5)} - } + Dim expected = New DiagnosticResult(DiagnosticId.AbstractClassShouldNotHavePublicCtors.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(3, 5) _ + .WithMessage("Constructor should not be public.") Await VerifyBasicDiagnosticAsync(test, expected) End Function diff --git a/test/VisualBasic/CodeCracker.Test/Usage/UnusedParametersTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/UnusedParametersTests.vb index e6c044c9c..1031f3a59 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/UnusedParametersTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/UnusedParametersTests.vb @@ -1,4 +1,5 @@ Imports CodeCracker.VisualBasic.Usage +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -704,12 +705,9 @@ End Class" End Function Private Function CreateDiagnosticResult(parameterName As String, line As Integer, column As Integer) As DiagnosticResult - Return New DiagnosticResult With { - .Id = DiagnosticId.UnusedParameters.ToDiagnosticId(), - .Message = String.Format(UnusedParametersAnalyzer.Message, parameterName), - .Severity = Microsoft.CodeAnalysis.DiagnosticSeverity.Warning, - .Locations = {New DiagnosticResultLocation("Test0.vb", line, column)} - } + Return New DiagnosticResult(DiagnosticId.UnusedParameters.ToDiagnosticId(), Microsoft.CodeAnalysis.DiagnosticSeverity.Warning) _ + .WithLocation(line, column) _ + .WithMessage(String.Format(UnusedParametersAnalyzer.Message, parameterName)) End Function End Class End Namespace \ No newline at end of file diff --git a/test/VisualBasic/CodeCracker.Test/Usage/UriAnalyzerTests.vb b/test/VisualBasic/CodeCracker.Test/Usage/UriAnalyzerTests.vb index 92978725d..bb54fcd57 100644 --- a/test/VisualBasic/CodeCracker.Test/Usage/UriAnalyzerTests.vb +++ b/test/VisualBasic/CodeCracker.Test/Usage/UriAnalyzerTests.vb @@ -1,6 +1,7 @@ Imports CodeCracker.VisualBasic.Usage Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Diagnostics +Imports Microsoft.CodeAnalysis.Testing Imports Xunit Namespace Usage @@ -78,12 +79,9 @@ End Namespace" End Function Private Shared Function CreateDiagnosticResult(line As Integer, column As Integer, getErrorMessageAction As Action) As DiagnosticResult - Return New DiagnosticResult() With { - .Id = DiagnosticId.Uri.ToDiagnosticId(), - .Message = GetErrorMessage(getErrorMessageAction), - .Severity = DiagnosticSeverity.[Error], - .Locations = New DiagnosticResultLocation() {New DiagnosticResultLocation("Test0.vb", line, column)} - } + Return New DiagnosticResult(DiagnosticId.Uri.ToDiagnosticId(), DiagnosticSeverity.Error) _ + .WithLocation(line, column) _ + .WithMessage(GetErrorMessage(getErrorMessageAction)) End Function Private Shared Function GetErrorMessage(action As Action) As String From 9a6b8fe89672d2cc5f423d313a7eccc6d170e5d4 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Sun, 9 Sep 2018 23:55:08 -0500 Subject: [PATCH 123/152] Add verifier helpers for testing --- .../CSharpCodeFixVerifier`2+Test.cs | 33 +++++++++++++ .../CSharpCodeFixVerifier`2.cs | 49 +++++++++++++++++++ .../CodeCracker.Test.Common.csproj | 6 +++ .../CodeCracker.Test.Common/EmptyAnalyzer.cs | 17 +++++++ .../VisualBasicCodeFixVerifier`2+Test.cs | 33 +++++++++++++ .../VisualBasicCodeFixVerifier`2.cs | 49 +++++++++++++++++++ 6 files changed, 187 insertions(+) create mode 100644 test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2+Test.cs create mode 100644 test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2.cs create mode 100644 test/Common/CodeCracker.Test.Common/EmptyAnalyzer.cs create mode 100644 test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2+Test.cs create mode 100644 test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2.cs diff --git a/test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2+Test.cs b/test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2+Test.cs new file mode 100644 index 000000000..00993b8c5 --- /dev/null +++ b/test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2+Test.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; + +namespace CodeCracker.Test +{ + public static partial class CSharpCodeFixVerifier + { + public class Test : CodeFixTest + { + public override string Language => LanguageNames.CSharp; + + protected override string DefaultFileExt => "cs"; + + protected override CompilationOptions CreateCompilationOptions() + => new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true); + + protected override IEnumerable GetDiagnosticAnalyzers() + { + yield return new TAnalyzer(); + } + + protected override IEnumerable GetCodeFixProviders() + { + yield return new TCodeFix(); + } + } + } +} diff --git a/test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2.cs b/test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2.cs new file mode 100644 index 000000000..7e64e1b0c --- /dev/null +++ b/test/Common/CodeCracker.Test.Common/CSharpCodeFixVerifier`2.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Testing; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; + +namespace CodeCracker.Test +{ + public static partial class CSharpCodeFixVerifier + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodeFix : CodeFixProvider, new() + { + public static DiagnosticResult Diagnostic() + => CSharpCodeFixVerifier.Diagnostic(); + + public static DiagnosticResult Diagnostic(string diagnosticId) + => CSharpCodeFixVerifier.Diagnostic(diagnosticId); + + public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) + => new DiagnosticResult(descriptor); + + public static Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var test = new Test { TestCode = source }; + test.ExpectedDiagnostics.AddRange(expected); + return test.RunAsync(); + } + + public static Task VerifyCodeFixAsync(string source, string fixedSource) + => VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); + + public static Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) + => VerifyCodeFixAsync(source, new[] { expected }, fixedSource); + + public static Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource) + { + var test = new Test + { + TestCode = source, + FixedCode = fixedSource, + }; + + test.ExpectedDiagnostics.AddRange(expected); + return test.RunAsync(); + } + } +} diff --git a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj index db5e82f6f..ee17f57f6 100644 --- a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj +++ b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj @@ -45,6 +45,7 @@ + @@ -52,6 +53,9 @@ + + + @@ -59,6 +63,8 @@ + + \ No newline at end of file diff --git a/test/Common/CodeCracker.Test.Common/EmptyAnalyzer.cs b/test/Common/CodeCracker.Test.Common/EmptyAnalyzer.cs new file mode 100644 index 000000000..0d1f5200e --- /dev/null +++ b/test/Common/CodeCracker.Test.Common/EmptyAnalyzer.cs @@ -0,0 +1,17 @@ +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace CodeCracker.Test +{ + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public class EmptyAnalyzer : DiagnosticAnalyzer + { + public override ImmutableArray SupportedDiagnostics + => ImmutableArray.Empty; + + public override void Initialize(AnalysisContext context) + { + } + } +} diff --git a/test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2+Test.cs b/test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2+Test.cs new file mode 100644 index 000000000..f41652de3 --- /dev/null +++ b/test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2+Test.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; +using Microsoft.CodeAnalysis.VisualBasic; + +namespace CodeCracker.Test +{ + public static partial class VisualBasicCodeFixVerifier + { + public class Test : CodeFixTest + { + public override string Language => LanguageNames.VisualBasic; + + protected override string DefaultFileExt => "vb"; + + protected override CompilationOptions CreateCompilationOptions() + => new VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary); + + protected override IEnumerable GetDiagnosticAnalyzers() + { + yield return new TAnalyzer(); + } + + protected override IEnumerable GetCodeFixProviders() + { + yield return new TCodeFix(); + } + } + } +} diff --git a/test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2.cs b/test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2.cs new file mode 100644 index 000000000..76964fad3 --- /dev/null +++ b/test/Common/CodeCracker.Test.Common/VisualBasicCodeFixVerifier`2.cs @@ -0,0 +1,49 @@ +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Testing.Verifiers; +using Microsoft.CodeAnalysis.VisualBasic.Testing; + +namespace CodeCracker.Test +{ + public static partial class VisualBasicCodeFixVerifier + where TAnalyzer : DiagnosticAnalyzer, new() + where TCodeFix : CodeFixProvider, new() + { + public static DiagnosticResult Diagnostic() + => VisualBasicCodeFixVerifier.Diagnostic(); + + public static DiagnosticResult Diagnostic(string diagnosticId) + => VisualBasicCodeFixVerifier.Diagnostic(diagnosticId); + + public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) + => new DiagnosticResult(descriptor); + + public static Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var test = new Test { TestCode = source }; + test.ExpectedDiagnostics.AddRange(expected); + return test.RunAsync(); + } + + public static Task VerifyCodeFixAsync(string source, string fixedSource) + => VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); + + public static Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) + => VerifyCodeFixAsync(source, new[] { expected }, fixedSource); + + public static Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource) + { + var test = new Test + { + TestCode = source, + FixedCode = fixedSource, + }; + + test.ExpectedDiagnostics.AddRange(expected); + return test.RunAsync(); + } + } +} From 415d5e9409e2ef5b0e383824f33ec3cf9c0698e0 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 10 Sep 2018 00:34:29 -0500 Subject: [PATCH 124/152] Convert CatchEmptyTests to the new test library --- .../Design/CatchEmptyTests.cs | 71 ++++++++++--------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Design/CatchEmptyTests.cs b/test/CSharp/CodeCracker.Test/Design/CatchEmptyTests.cs index 7dd1728bc..cd1582067 100644 --- a/test/CSharp/CodeCracker.Test/Design/CatchEmptyTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/CatchEmptyTests.cs @@ -1,12 +1,13 @@ -using CodeCracker.CSharp.Design; -using System.Threading.Tasks; +using System.Threading.Tasks; +using CodeCracker.CSharp.Design; using Xunit; namespace CodeCracker.Test.CSharp.Design { - public class CatchEmptyTests : CodeFixVerifier - { + using Verify = CSharpCodeFixVerifier; + public class CatchEmptyTests + { [Fact] public async Task CatchEmptyAnalyserCreateDiagnostic() { @@ -17,7 +18,7 @@ namespace ConsoleApplication1 { class TypeName { - public async Task Foo() + public async {|CS0246:Task|} {|CS0161:{|CS1983:Foo|}|}() { try { @@ -31,7 +32,7 @@ public async Task Foo() } }"; - await VerifyCSharpHasNoDiagnosticsAsync(source); + await Verify.VerifyAnalyzerAsync(source); } [Fact] @@ -44,7 +45,7 @@ namespace ConsoleApplication1 { class TypeName { - public async Task Foo() + public async {|CS0246:Task|} {|CS0161:{|CS1983:Foo|}|}() { try { @@ -57,7 +58,7 @@ public async Task Foo() } } }"; - await VerifyCSharpHasNoDiagnosticsAsync(source); + await Verify.VerifyAnalyzerAsync(source); } [Fact] @@ -87,7 +88,7 @@ public void Foo() } } }"; - await VerifyCSharpHasNoDiagnosticsAsync(source); + await Verify.VerifyAnalyzerAsync(source); } [Fact] public async Task NotAllowedToReturnOutOfEmtpyCatchBlock() @@ -106,13 +107,13 @@ public void Foo() { // do something } - catch + [|catch { if (x == 1) throw; else return; - } + }|] } } }"; @@ -129,19 +130,19 @@ public void Foo() { try { - // do something - } - catch (Exception ex) - { - if (x == 1) - throw; - else - return; + // do something } + catch (Exception ex) + { + if (x == 1) + throw; + else + return; } } + } }"; - await VerifyCSharpFixAsync(test, fixtest, 0, allowNewCompilerDiagnostics: true); + await Verify.VerifyCodeFixAsync(test, fixtest); } [Fact] public async Task WhenFindCatchEmptyThenPutExceptionClass() @@ -159,10 +160,10 @@ public void Foo() { // do something } - catch + [|catch { int x = 0; - } + }|] } } }"; @@ -180,14 +181,14 @@ public void Foo() { // do something } - catch (Exception ex) - { - int x = 0; - } + catch (Exception ex) + { + int x = 0; } } + } }"; - await VerifyCSharpFixAsync(test, fixtest, 0, allowNewCompilerDiagnostics: true); + await Verify.VerifyCodeFixAsync(test, fixtest); } [Fact] public async Task AddCatchEvenIfThereIsReturnInBlock() @@ -205,11 +206,11 @@ public void Foo() { // do something } - catch + [|catch { int x = 0; return; - } + }|] } } }"; @@ -227,15 +228,15 @@ public void Foo() { // do something } - catch (Exception ex) - { - int x = 0; - return; - } + catch (Exception ex) + { + int x = 0; + return; } } + } }"; - await VerifyCSharpFixAsync(test, fixtest, 0, allowNewCompilerDiagnostics: true); + await Verify.VerifyCodeFixAsync(test, fixtest); } } } \ No newline at end of file From b50066614aa98a8813d3f79594469c6581a457c9 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 10 Sep 2018 00:50:01 -0500 Subject: [PATCH 125/152] Convert EmptyCatchBlockTests to the new test library --- .../Design/EmptyCatchBlockTests.cs | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Design/EmptyCatchBlockTests.cs b/test/CSharp/CodeCracker.Test/Design/EmptyCatchBlockTests.cs index 0ecab7be1..87ea33784 100644 --- a/test/CSharp/CodeCracker.Test/Design/EmptyCatchBlockTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/EmptyCatchBlockTests.cs @@ -4,7 +4,9 @@ namespace CodeCracker.Test.CSharp.Design { - public class EmptyCatchBlockTests : CodeFixVerifier + using Verify = CSharpCodeFixVerifier; + + public class EmptyCatchBlockTests { readonly string test = @" using System; @@ -20,9 +22,9 @@ public async Task Foo() { // do something } - catch + [|catch { - } + }|] } } }"; @@ -36,7 +38,7 @@ namespace ConsoleApplication1 { class TypeName { - public async Task Foo() + public async {|CS0246:Task|} {|CS0161:{|CS1983:Foo|}|}() { try { @@ -49,7 +51,7 @@ public async Task Foo() } } }"; - await VerifyCSharpHasNoDiagnosticsAsync(test); + await Verify.VerifyAnalyzerAsync(test); } [Fact] @@ -72,7 +74,7 @@ public async Task Foo() } } }"; - await VerifyCSharpFixAsync(test, fixtest, 0, allowNewCompilerDiagnostics: false, formatBeforeCompare: true); + await Verify.VerifyCodeFixAsync(test, fixtest); } [Fact] @@ -88,15 +90,20 @@ class TypeName { public async Task Foo() { - { - // do something - } - //TODO: Consider reading MSDN Documentation about how to use Try...Catch => http://msdn.microsoft.com/en-us/library/0yd65esw.aspx + { + // do something } + //TODO: Consider reading MSDN Documentation about how to use Try...Catch => http://msdn.microsoft.com/en-us/library/0yd65esw.aspx + } } }"; - await VerifyCSharpFixAsync(test, fixtest, 1, allowNewCompilerDiagnostics: false, formatBeforeCompare: true); + await new Verify.Test + { + TestCode = test, + FixedCode = fixtest, + CodeFixIndex = 1, + }.RunAsync(); } [Fact] @@ -116,14 +123,19 @@ public async Task Foo() { // do something } - catch (Exception ex) - { - throw; - } + catch (Exception ex) + { + throw; } } + } }"; - await VerifyCSharpFixAsync(test, fixtest, 2, allowNewCompilerDiagnostics: true, formatBeforeCompare: true); + await new Verify.Test + { + TestCode = test, + FixedCode = fixtest, + CodeFixIndex = 2, + }.RunAsync(); } @@ -137,16 +149,16 @@ namespace ConsoleApplication1 { class TypeName { - public async Task Foo() + public async {|CS0246:Task|} {|CS0161:{|CS1983:Foo|}|}() { int x; try { // do something } - catch (System.ArgumentException ae) + [|catch (System.ArgumentException ae) { - } + }|] catch (System.Exception ex) { x = 1; @@ -162,7 +174,7 @@ namespace ConsoleApplication1 { class TypeName { - public async Task Foo() + public async {|CS0246:Task|} {|CS0161:{|CS1983:Foo|}|}() { int x; try @@ -176,7 +188,7 @@ public async Task Foo() } } }"; - await VerifyCSharpFixAsync(test, fixtest, 0); + await Verify.VerifyCodeFixAsync(test, fixtest); } } } \ No newline at end of file From eba2e8d68bbdf5e07167ff1fce35d4484668ac30 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 10 Sep 2018 01:02:38 -0500 Subject: [PATCH 126/152] Convert InconsistentAccessibilityTests to the new test library --- ...entAccessibilityTests.FieldPropertyType.cs | 25 ++++--- ...cessibilityTests.MethodIndexerParameter.cs | 71 +++++++++---------- ...essibilityTests.MethodIndexerReturnType.cs | 21 +++--- 3 files changed, 61 insertions(+), 56 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.FieldPropertyType.cs b/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.FieldPropertyType.cs index f90adea3e..b7d198c6d 100644 --- a/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.FieldPropertyType.cs +++ b/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.FieldPropertyType.cs @@ -1,16 +1,19 @@ using System.Threading.Tasks; +using CodeCracker.CSharp.Design.InconsistentAccessibility; using Xunit; namespace CodeCracker.Test.CSharp.Design { - public partial class InconsistentAccessibilityTests : CodeFixVerifier + using Verify = CSharpCodeFixVerifier; + + public partial class InconsistentAccessibilityTests { [Fact] public async Task ShouldFixInconsistentAccessibilityErrorInClassFieldTypeAsync() { const string testCode = @"public class Dependent { - public DependedUpon field; + public DependedUpon {|CS0052:field|}; } class DependedUpon @@ -25,7 +28,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -33,7 +36,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInClassFieldTypeWhenQua { const string testCode = @"public class Dependent { - internal Dependent.DependedUpon field; + internal Dependent.DependedUpon {|CS0052:field|}; class DependedUpon { @@ -49,7 +52,7 @@ internal class DependedUpon } }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -57,7 +60,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInStructFieldTypeAsync( { const string testCode = @"public struct Dependent { - public DependedUpon field, field1; + public DependedUpon {|CS0052:field|}, {|CS0052:field1|}; } class DependedUpon @@ -72,7 +75,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -80,7 +83,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInPropertyTypeAsync() { const string testCode = @"public class Dependent { - public DependedUpon Property + public DependedUpon {|CS0053:Property|} { get { return null; } set { } @@ -104,7 +107,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -112,7 +115,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInPropertyTypeWhenUsing { const string testCode = @"public class Dependent { - public DependedUpon Property + public DependedUpon {|CS0053:Property|} { get; set; @@ -136,7 +139,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } } } diff --git a/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerParameter.cs b/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerParameter.cs index 822d16141..34b11d5ef 100644 --- a/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerParameter.cs +++ b/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerParameter.cs @@ -1,11 +1,12 @@ -using CodeCracker.CSharp.Design.InconsistentAccessibility; -using Microsoft.CodeAnalysis.CodeFixes; -using System.Threading.Tasks; +using System.Threading.Tasks; +using CodeCracker.CSharp.Design.InconsistentAccessibility; using Xunit; namespace CodeCracker.Test.CSharp.Design { - public partial class InconsistentAccessibilityTests : CodeFixVerifier + using Verify = CSharpCodeFixVerifier; + + public partial class InconsistentAccessibilityTests { [Theory] [InlineData("class","internal")] @@ -17,11 +18,11 @@ public async Task ShouldChangeAccessibilityWhenErrorInConstructor(string type, s var sourceCode = @" public " + type + @" Dependent { - public Dependent(int a, DependendedUpon d, string b) + public {|CS0051:Dependent|}(int a, DependendedUpon d, string b) { } } -" + dependedUponModfifier + @" class DependendedUpon +" + dependedUponModfifier + (dependedUponModfifier.Length > 0 ? " " : "") + @"class DependendedUpon { }"; @@ -36,7 +37,7 @@ public class DependendedUpon { }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Theory] @@ -49,7 +50,7 @@ public class DependendedUpon [InlineData("protected", "internal /* comment */", "protected /* comment */")] [InlineData("protected", "private", "protected")] [InlineData("protected internal", "", "protected internal")] - [InlineData("protected internal", " protected ", " protected internal ")] + [InlineData("protected internal", " protected ", "protected internal")] [InlineData("protected internal", "internal", "protected internal")] [InlineData("internal protected", "private", "protected internal")] [InlineData("internal", "protected", "internal")] @@ -59,11 +60,11 @@ public async Task ShouldChangeAccessibilityWhenErrrorInMethod(string methodModif var sourceCode = @" public class Dependent { - " + methodModifier + @" void SomeMethod(DependendedUpon d) + " + methodModifier + @" void {|CS0051:SomeMethod|}(DependendedUpon d) { } - " + dependedUponModifier + @" class DependendedUpon + " + dependedUponModifier + (dependedUponModifier.Length > 0 ? " " : "") + @"class DependendedUpon { } }"; @@ -80,7 +81,7 @@ public class Dependent } }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Theory] @@ -91,9 +92,9 @@ public async Task ShouldChangeAccessibilityWhenErrorInInterface(string interface var sourceCode = @" " + interfaceAccessibilityModifier + @" interface Dependent { - void SomeMethod(DependendedUpon d); + void {|CS0051:SomeMethod|}(DependendedUpon d); } -" + dependedUponModifier + @" class DependendedUpon +" + dependedUponModifier + (dependedUponModifier.Length > 0 ? " " : "") + @"class DependendedUpon { }"; @@ -106,7 +107,7 @@ public async Task ShouldChangeAccessibilityWhenErrorInInterface(string interface { }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -115,7 +116,7 @@ public async Task ShouldChangeAccessibilityWhenQualifiedNameIsUsedForParameterTy const string sourceCode = @" public class Dependent { - public Dependent(Dependent.DependendedUpon d) + public {|CS0051:Dependent|}(Dependent.DependendedUpon d) { } @@ -136,7 +137,7 @@ public class DependendedUpon } }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -145,7 +146,7 @@ public async Task ShouldChangeAccessibilityWhenAliasQualifiedNameIsUsedForParame const string sourceCode = @" public class Dependent { - public Dependent(global::DependendedUpon d) + public {|CS0051:Dependent|}(global::DependendedUpon d) { } } @@ -164,7 +165,7 @@ public class DependendedUpon { }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -173,7 +174,7 @@ public async Task ShouldChangeAccessibilityWhenUsingDelegateAsParameter() const string sourceCode = @" public class Dependent { - public Dependent(DependedUpon d) + public {|CS0051:Dependent|}(DependedUpon d) { } } @@ -188,7 +189,7 @@ public Dependent(DependedUpon d) } public delegate void DependedUpon(int a);"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -197,7 +198,7 @@ public async Task ShouldChangeAccessibilityWhenUsingEnumAsParameter() const string sourceCode = @" public class Dependent { - public Dependent(DependedUpon d) + public {|CS0051:Dependent|}(DependedUpon d) { } } @@ -212,7 +213,7 @@ public Dependent(DependedUpon d) } public enum DependedUpon {}"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -221,7 +222,7 @@ public async Task ShouldChangeAccessibilityWhenUsingInterfaceAsParameter() const string sourceCode = @" public class Dependent { - public Dependent(DependedUpon d) + public {|CS0051:Dependent|}(DependedUpon d) { } } @@ -236,7 +237,7 @@ public Dependent(DependedUpon d) } public interface DependedUpon {}"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -245,7 +246,7 @@ public async Task ShouldChangeAccessibilityWhenUsingGenericClassAsParameter() const string sourceCode = @" public class Dependent { - public Dependent(DependedUpon d) + public {|CS0051:Dependent|}(DependedUpon d) { } } @@ -260,7 +261,7 @@ public Dependent(DependedUpon d) } public class DependedUpon {}"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -269,7 +270,7 @@ public async Task ShouldChangeAccessibilityToAllPartialDeclarationsAsync() const string sourceCode = @" public class Dependent { - public Dependent(DependedUpon d) + public {|CS0051:Dependent|}(DependedUpon d) { } } @@ -288,7 +289,7 @@ public partial class DependedUpon {} class SomeClass {} public partial class DependedUpon {}"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -296,7 +297,7 @@ public async Task ShouldChangeAccessibilityWhenErrorInIndexerParameterAsync() { const string sourceCode = @"public class Dependent { - public int this[int idx, DependedUpon dependedUpon] + public int {|CS0055:this|}[int idx, DependedUpon dependedUpon] { get { return 0; } set { } @@ -320,7 +321,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -328,7 +329,7 @@ public async Task ShouldChangeAccessibilityWhenErrorInIndexerParameterUsingQuali { const string sourceCode = @"public class Dependent { - public int this[int idx, Dependent.DependedUpon dependedUpon] + public int {|CS0055:this|}[int idx, Dependent.DependedUpon dependedUpon] { get { return 0; } set { } @@ -352,7 +353,7 @@ public class DependedUpon } }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -360,7 +361,7 @@ public async Task ShouldChangeAccessibilityWhenErrorInMoreThanOneIndexerParamete { const string sourceCode = @"public class Dependent { - public int this[int idx, Dependent.DependedUpon dependedUpon, DependedUpon2 dependedUpon2] + public int {|CS0055:{|CS0055:this|}|}[int idx, Dependent.DependedUpon dependedUpon, DependedUpon2 dependedUpon2] { get { return 0; } set { } @@ -392,9 +393,7 @@ public class DependedUpon2 { }"; - await VerifyCSharpFixAsync(sourceCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(sourceCode, fixedCode).ConfigureAwait(false); } - - protected override CodeFixProvider GetCodeFixProvider() => new InconsistentAccessibilityCodeFixProvider(); } } diff --git a/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerReturnType.cs b/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerReturnType.cs index e397c7a4f..7b5d324a2 100644 --- a/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerReturnType.cs +++ b/test/CSharp/CodeCracker.Test/Design/InconsistentAccessibilityTests.MethodIndexerReturnType.cs @@ -1,16 +1,19 @@ using System.Threading.Tasks; +using CodeCracker.CSharp.Design.InconsistentAccessibility; using Xunit; namespace CodeCracker.Test.CSharp.Design { - public partial class InconsistentAccessibilityTests : CodeFixVerifier + using Verify = CSharpCodeFixVerifier; + + public partial class InconsistentAccessibilityTests { [Fact] public async Task ShouldFixInconsistentAccessibilityErrorInMethodReturnTypeAsync() { const string testCode = @"public class Dependent { - public DependedUpon Method() + public DependedUpon {|CS0050:Method|}() { return null; } @@ -31,7 +34,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -39,7 +42,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInMethodReturnTypeWhenQ { const string testCode = @"public class Dependent { - public Dependent.DependedUpon Method() + public Dependent.DependedUpon {|CS0050:Method|}() { return null; } @@ -60,7 +63,7 @@ public class DependedUpon } }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -68,7 +71,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInIndexerReturnTypeAsyn { const string testCode = @"public class Dependent { - public DependedUpon this[int a] + public DependedUpon {|CS0054:this|}[int a] { get { return null; } set { } @@ -91,7 +94,7 @@ public class DependedUpon { }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } [Fact] @@ -99,7 +102,7 @@ public async Task ShouldFixInconsistentAccessibilityErrorInIndexerReturnTypeWhen { const string testCode = @"public class Dependent { - public Dependent.DependedUpon this[int a] + public Dependent.DependedUpon {|CS0054:this|}[int a] { get { return null; } set { } @@ -122,7 +125,7 @@ public class DependedUpon } }"; - await VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false); + await Verify.VerifyCodeFixAsync(testCode, fixedCode).ConfigureAwait(false); } } } From a6e63422ca8f0081af6896d6c7fad4055e61d4e9 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Mon, 10 Sep 2018 14:02:17 -0500 Subject: [PATCH 127/152] Unindent code in WrapInCSharpClass and WrapInCSharpMethod --- .../Design/MakeMethodStaticTests.cs | 2 +- ...ocalVariablesConstWhenItIsPossibleTests.cs | 6 +-- .../AddBracesToSwitchSectionsTests.cs | 6 +-- .../Refactoring/ComputeExpressionTests.cs | 2 +- .../Refactoring/NumericLiteralTests.cs | 2 +- .../Refactoring/SplitIntoNestedIfTests.cs | 2 +- .../UseConfigureAwaitFalseTests.cs | 12 +++--- .../Style/RemoveCommentedCodeTests.cs | 2 +- .../Style/StringFormatTests.cs | 4 +- ...ssaryToStringInStringConcatenationTests.cs | 2 +- .../Style/UseEmptyStringTest.cs | 4 +- .../Style/UseStringEmptyTests.cs | 4 +- .../DisposableVariableNotDisposedTests.cs | 8 ++-- .../Usage/RemoveRedundantElseClauseTests.cs | 4 +- ...implifyRedundantBooleanComparisonsTests.cs | 32 +++++++-------- .../Usage/StringFormatArgsTests.cs | 14 +++---- .../Helpers/Extensions.cs | 40 ++++++++++++------- 17 files changed, 78 insertions(+), 68 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs b/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs index 2d8829a4a..eb64ea7dc 100644 --- a/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs +++ b/test/CSharp/CodeCracker.Test/Design/MakeMethodStaticTests.cs @@ -102,7 +102,7 @@ public async Task WithDiagnostic(string code) { var source = code.WrapInCSharpClass(); var expected = new DiagnosticResult(DiagnosticId.MakeMethodStatic.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(8, 18) + .WithLocation(8, 14) .WithMessage(string.Format(MakeMethodStaticAnalyzer.MessageFormat, "Foo")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs b/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs index 61b2311b3..5ab66e579 100644 --- a/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/MakeLocalVariablesConstWhenItIsPossibleTests.cs @@ -66,7 +66,7 @@ public async Task CreateDiagnosticsWhenAssigningAPotentialConstant() { var test = @"int a = 10;".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage("This variable can be made const."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -77,7 +77,7 @@ public async Task CreateDiagnosticsWhenAssigningAPotentialConstantInAVarDeclarat var test = @"var a = 10;".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage("This variable can be made const."); await VerifyCSharpDiagnosticAsync(test, expected); } @@ -88,7 +88,7 @@ public async Task CreateDiagnosticsWhenAssigningNullToAReferenceType() var test = @"Foo a = null;".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.MakeLocalVariableConstWhenItIsPossible.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage("This variable can be made const."); await VerifyCSharpDiagnosticAsync(test, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs index 9f8dfb62c..086e7287f 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/AddBracesToSwitchSectionsTests.cs @@ -71,7 +71,7 @@ public async Task CreateDiagnosticWhenSingleSwitchSectionHasNoBraces() break; }"; var diagnostic = new DiagnosticResult(DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage("Add braces for each section in this switch"); await VerifyCSharpDiagnosticAsync(test.WrapInCSharpMethod(), diagnostic); } @@ -96,7 +96,7 @@ public async Task CreateDiagnosticWhenNotAllSwitchSectionsHaveBraces() } }"; var diagnostic = new DiagnosticResult(DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage("Add braces for each section in this switch"); await VerifyCSharpDiagnosticAsync(test.WrapInCSharpMethod(), diagnostic); } @@ -121,7 +121,7 @@ public async Task CreateDiagnosticWhenDefaultSectionsHasNoBraces() break; }"; var diagnostic = new DiagnosticResult(DiagnosticId.AddBracesToSwitchSections.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage("Add braces for each section in this switch"); await VerifyCSharpDiagnosticAsync(test.WrapInCSharpMethod(), diagnostic); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs index 64f244a6c..66f89503c 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/ComputeExpressionTests.cs @@ -40,7 +40,7 @@ public async Task BinaryExpressionWithLiteralOnLeftAndRightCreatesDiagnostic(str var source = original.WrapInCSharpMethod(); var expression = original.Substring(columnOffset, original.Length - columnOffset - columnRightTrim - 1); var expected = new DiagnosticResult(DiagnosticId.ComputeExpression.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 17 + columnOffset) + .WithLocation(10, 13 + columnOffset) .WithMessage(string.Format(ComputeExpressionAnalyzer.Message, expression)); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs index feae0f6f6..00949a8b8 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/NumericLiteralTests.cs @@ -81,7 +81,7 @@ void Foo() await VerifyCSharpFixAsync(source, fixtest); } - private static DiagnosticResult CreateDiagnosticResult(string literal, bool isDecimal, int row = 10, int col = 25) + private static DiagnosticResult CreateDiagnosticResult(string literal, bool isDecimal, int row = 10, int col = 21) { return new DiagnosticResult(DiagnosticId.NumericLiteral.ToDiagnosticId(), DiagnosticSeverity.Hidden) .WithLocation(row, col) diff --git a/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs b/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs index b99818c1c..41da694f2 100644 --- a/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs +++ b/test/CSharp/CodeCracker.Test/Refactoring/SplitIntoNestedIfTests.cs @@ -34,7 +34,7 @@ public async Task IfWithAndCreatesDiagnostic() { var source = "if (true && true) { }".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.SplitIntoNestedIf.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 21) + .WithLocation(10, 17) .WithMessage(string.Format(SplitIntoNestedIfAnalyzer.Message)); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs b/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs index c8e981b55..ef2e99a68 100644 --- a/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs +++ b/test/CSharp/CodeCracker.Test/Reliability/UseConfigureAwaitFalseTests.cs @@ -9,12 +9,12 @@ namespace CodeCracker.Test.CSharp.Reliability public class UseConfigureAwaitFalseTests : CodeFixVerifier { [Theory] - [InlineData("System.Threading.Tasks.Task t; await t;", 48)] - [InlineData("System.Threading.Tasks.Task t; await t.ContinueWith(_ => 42);", 48)] - [InlineData("await System.Threading.Tasks.Task.Delay(1000);", 17)] - [InlineData("await System.Threading.Tasks.Task.FromResult(0);", 17)] - [InlineData("await System.Threading.Tasks.Task.Run(() => {});", 17)] - [InlineData("Func f; await f();", 54)] + [InlineData("System.Threading.Tasks.Task t; await t;", 44)] + [InlineData("System.Threading.Tasks.Task t; await t.ContinueWith(_ => 42);", 44)] + [InlineData("await System.Threading.Tasks.Task.Delay(1000);", 13)] + [InlineData("await System.Threading.Tasks.Task.FromResult(0);", 13)] + [InlineData("await System.Threading.Tasks.Task.Run(() => {});", 13)] + [InlineData("Func f; await f();", 50)] public async Task WhenAwaitingTaskAnalyzerCreatesDiagnostic(string sample, int column) { var test = sample.WrapInCSharpMethod(isAsync: true); diff --git a/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs b/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs index eba8b1ad0..e287e5941 100644 --- a/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/RemoveCommentedCodeTests.cs @@ -27,7 +27,7 @@ public async Task CreateDiagnosticForSingleLineCommentedCode() { var test = @"// a = 10;".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.RemoveCommentedCode.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage(RemoveCommentedCodeAnalyzer.MessageFormat); await VerifyCSharpDiagnosticAsync(test, expected); diff --git a/test/CSharp/CodeCracker.Test/Style/StringFormatTests.cs b/test/CSharp/CodeCracker.Test/Style/StringFormatTests.cs index bab1ee836..fdd944a07 100644 --- a/test/CSharp/CodeCracker.Test/Style/StringFormatTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/StringFormatTests.cs @@ -631,10 +631,10 @@ public async Task NestedStringFormatCreatesDiagnostic() { var source = @"var foo = string.Format(""{0}"", string.Format(""{0}"", 1 ) );".WrapInCSharpMethod(); var expected1 = new DiagnosticResult(DiagnosticId.StringFormat.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 27) + .WithLocation(10, 23) .WithMessage(StringFormatAnalyzer.MessageFormat.ToString()); var expected2 = new DiagnosticResult(DiagnosticId.StringFormat.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 48) + .WithLocation(10, 44) .WithMessage(StringFormatAnalyzer.MessageFormat.ToString()); await VerifyCSharpDiagnosticAsync(source, expected1, expected2); } diff --git a/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs b/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs index 3f049ba98..75af07ac2 100644 --- a/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/UnnecessaryToStringInStringConcatenationTests.cs @@ -30,7 +30,7 @@ public async Task InstantiatingAnStringBuilderAndCallToStringInsideAStringConcat { var source = @"var foo = ""a"" + new System.Text.StringBuilder().ToString();".WrapInCSharpMethod(); - var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(10, 64); + var expected = CreateUnnecessaryToStringInStringConcatenationDiagnosticResult(10, 60); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Style/UseEmptyStringTest.cs b/test/CSharp/CodeCracker.Test/Style/UseEmptyStringTest.cs index 500739bbf..84eb26fdf 100644 --- a/test/CSharp/CodeCracker.Test/Style/UseEmptyStringTest.cs +++ b/test/CSharp/CodeCracker.Test/Style/UseEmptyStringTest.cs @@ -194,8 +194,8 @@ public async Task FixAllInSolutionChangeMethodToStringEmpty() public async Task TwoEmptyStringsGenerateTwoDiagnostics() { var test = "var s = string.Empty + string.Empty;".WrapInCSharpMethod(); - var expected1 = CreateEmptyStringDiagnosticResult(10, 25); - var expected2 = CreateEmptyStringDiagnosticResult(10, 40); + var expected1 = CreateEmptyStringDiagnosticResult(10, 21); + var expected2 = CreateEmptyStringDiagnosticResult(10, 36); await VerifyCSharpDiagnosticAsync(test, expected1, expected2); } diff --git a/test/CSharp/CodeCracker.Test/Style/UseStringEmptyTests.cs b/test/CSharp/CodeCracker.Test/Style/UseStringEmptyTests.cs index 9134c2bca..9e492b404 100644 --- a/test/CSharp/CodeCracker.Test/Style/UseStringEmptyTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/UseStringEmptyTests.cs @@ -187,10 +187,10 @@ public async Task TwoEmptyStringsGenerateTwoDiagnostics() { var test = @"var s = """" + """";".WrapInCSharpMethod(); var expected1 = new DiagnosticResult(DiagnosticId.UseStringEmpty.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 25) + .WithLocation(10, 21) .WithMessage("Use 'String.Empty' instead of \"\""); var expected2 = new DiagnosticResult(DiagnosticId.UseStringEmpty.ToDiagnosticId(), DiagnosticSeverity.Hidden) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage("Use 'String.Empty' instead of \"\""); await VerifyCSharpDiagnosticAsync(test, expected1, expected2); } diff --git a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs index daad3e39a..590f108de 100644 --- a/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/DisposableVariableNotDisposedTests.cs @@ -159,7 +159,7 @@ public async Task DisposableVariableCreatesDiagnostic() { var source = "new System.IO.MemoryStream();".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -176,7 +176,7 @@ public async Task DisposableVariableDeclaredWithAnotherVariableCreatesOnlyOneDia { var source = "System.IO.MemoryStream a, b = new System.IO.MemoryStream();".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 47) + .WithLocation(10, 43) .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -446,7 +446,7 @@ public async Task DisposableVariablePassedAsParamCreatesDiagnostic() { var source = "string.Format(\"\", new System.IO.MemoryStream());".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 35) + .WithLocation(10, 31) .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -457,7 +457,7 @@ public async Task DisposableVariableCallsIncorrectDisposeCreatesDiagnostic() var source = @"var m = new System.IO.MemoryStream(); m.Dispose(true);".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.DisposableVariableNotDisposed.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 25) + .WithLocation(10, 21) .WithMessage(string.Format(DisposableVariableNotDisposedAnalyzer.MessageFormat, "MemoryStream")); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs b/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs index 9849a0655..82a32d51a 100644 --- a/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/RemoveRedundantElseClauseTests.cs @@ -122,7 +122,7 @@ public async Task CreateDiagnosticsWhenEmptyElse() var test = @"if(1 == 2){ return 1; } else { }".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.RemoveRedundantElseClause.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 41) + .WithLocation(10, 37) .WithMessage("Remove redundant else"); await VerifyCSharpDiagnosticAsync(test, expected); @@ -134,7 +134,7 @@ public async Task CreateDiagnosticsWhenEmptyElseWithoutBlockOnIf() var test = @"if(1 == 2) return 1; else { }".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.RemoveRedundantElseClause.ToDiagnosticId(), DiagnosticSeverity.Info) - .WithLocation(10, 38) + .WithLocation(10, 34) .WithMessage("Remove redundant else"); await VerifyCSharpDiagnosticAsync(test, expected); diff --git a/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs b/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs index b1fa44b3f..e5fe06e4d 100644 --- a/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/SimplifyRedundantBooleanComparisonsTests.cs @@ -10,22 +10,22 @@ public class SimplifyRedundantBooleanComparisonsTests : CodeFixVerifier { [Theory] - [InlineData("if (foo == true) {}", 21)] - [InlineData("if (true == foo) {}", 21)] - [InlineData("var fee = (foo == true);", 28)] - [InlineData("var fee = (true == foo);", 28)] - [InlineData("if (foo == false) {}", 21)] - [InlineData("if (false == foo) {}", 21)] - [InlineData("var fee = (foo == false);", 28)] - [InlineData("var fee = (false == foo);", 28)] - [InlineData("if (foo != true) {}", 21)] - [InlineData("if (true != foo) {}", 21)] - [InlineData("var fee = (foo != true);", 28)] - [InlineData("var fee = (true != foo);", 28)] - [InlineData("if (foo != false) {}", 21)] - [InlineData("if (false != foo) {}", 21)] - [InlineData("var fee = (foo != false);", 28)] - [InlineData("var fee = (false != true);", 28)] + [InlineData("if (foo == true) {}", 17)] + [InlineData("if (true == foo) {}", 17)] + [InlineData("var fee = (foo == true);", 24)] + [InlineData("var fee = (true == foo);", 24)] + [InlineData("if (foo == false) {}", 17)] + [InlineData("if (false == foo) {}", 17)] + [InlineData("var fee = (foo == false);", 24)] + [InlineData("var fee = (false == foo);", 24)] + [InlineData("if (foo != true) {}", 17)] + [InlineData("if (true != foo) {}", 17)] + [InlineData("var fee = (foo != true);", 24)] + [InlineData("var fee = (true != foo);", 24)] + [InlineData("if (foo != false) {}", 17)] + [InlineData("if (false != foo) {}", 17)] + [InlineData("var fee = (foo != false);", 24)] + [InlineData("var fee = (false != true);", 24)] public async Task WhenComparingWithBoolAnalyzerCreatesDiagnostic(string sample, int column) { sample = "bool foo; " + sample; // add declaration of foo diff --git a/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs b/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs index b5ffbb6e9..ebd90f4c7 100644 --- a/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs +++ b/test/CSharp/CodeCracker.Test/Usage/StringFormatArgsTests.cs @@ -84,7 +84,7 @@ public async Task NoParametersCreatesError() { var source = @"var result = string.Format(""{0}"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -94,7 +94,7 @@ public async Task LessParametersCreatesError() { var source = @"var result = string.Format(""one {0} two {1}"", ""a"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -104,7 +104,7 @@ public async Task MoreArgumentsCreatesWarning() { var source = @"var result = string.Format(""one {0} two {1}"", ""a"", ""b"", ""c"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage(StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -135,7 +135,7 @@ public async Task TwoParametersReferencingSamePlaceholderCreatesWarning() { var source = @"var result = string.Format(""one {0} two {0}"", ""a"", ""b"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage(StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -179,7 +179,7 @@ public async Task InvalidArgumentReferenceCreatesError() { var source = @"var result = string.Format(""one {1}"", ""a"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -189,7 +189,7 @@ public async Task NonIntegerPlaceholderCreatesError() { var source = @"var result = string.Format(""one {notZero}"", ""a"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_InvalidArgs.ToDiagnosticId(), DiagnosticSeverity.Error) - .WithLocation(10, 30) + .WithLocation(10, 26) .WithMessage(StringFormatArgsAnalyzer.InvalidArgsReferenceMessage); await VerifyCSharpDiagnosticAsync(source, expected); } @@ -199,7 +199,7 @@ public async Task UnusedArgsCreatesWarning() { var source = @"string.Format(""{0}{1}{3}{5}"", ""a"", ""b"", ""c"", ""d"", ""e"", ""f"");".WrapInCSharpMethod(); var expected = new DiagnosticResult(DiagnosticId.StringFormatArgs_ExtraArgs.ToDiagnosticId(), DiagnosticSeverity.Warning) - .WithLocation(10, 17) + .WithLocation(10, 13) .WithMessage(StringFormatArgsAnalyzer.IncorrectNumberOfArgsMessage); await VerifyCSharpDiagnosticAsync(source, expected); } diff --git a/test/Common/CodeCracker.Test.Common/Helpers/Extensions.cs b/test/Common/CodeCracker.Test.Common/Helpers/Extensions.cs index 082843818..7b6e955ab 100644 --- a/test/Common/CodeCracker.Test.Common/Helpers/Extensions.cs +++ b/test/Common/CodeCracker.Test.Common/Helpers/Extensions.cs @@ -4,33 +4,43 @@ public static class Extensions { public static string WrapInCSharpClass(this string code, string typeName = "TypeName", string usings = "") { + if (!code.StartsWith("\r") || code.StartsWith("\n")) + { + code = " " + code; + } + return $@" - using System;{usings} +using System;{usings} - namespace ConsoleApplication1 +namespace ConsoleApplication1 +{{ + class {typeName} {{ - class {typeName} - {{ - {code} - }} - }}"; +{code} + }} +}}"; } public static string WrapInCSharpMethod(this string code, bool isAsync = false, string typeName = "TypeName", string usings = "") { + if (!code.StartsWith("\r") || code.StartsWith("\n")) + { + code = " " + code; + } + return $@" - using System;{usings} +using System;{usings} - namespace ConsoleApplication1 +namespace ConsoleApplication1 +{{ + class {typeName} {{ - class {typeName} + public {(isAsync ? "async " : "")}void Foo() {{ - public {(isAsync ? "async " : "")}void Foo() - {{ - {code} - }} +{code} }} - }}"; + }} +}}"; } public static string WrapInVBClass(this string code, From 0dc53ea33c9cc11daf5694bf290e9ddd10b25dae Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 1 Oct 2018 15:02:23 -0500 Subject: [PATCH 128/152] Fixed many spelling and grammar issues There were tons of spelling errors that I spotted in the code. Along with fixing these, I have provided grammatical fixes as well. --- README.md | 59 ++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index c6e7048ee..bfb59721e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ You can find this document in the following languages [![Brazilian Portuguese](https://img.shields.io/badge/language-brazilan%20portuguese-brightgreen.svg)](https://github.com/code-cracker/code-cracker/blob/master/README.pt.md) -This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this +This is a community project, free and open source. Everyone is invited to contribute, fork, share and use the code. No money shall be charged by this software, nor it will be. Ever. ## Features @@ -30,23 +30,23 @@ Code | Analyzer | Severity | Description -- | -- | -- | -- [CC0003](http://code-cracker.github.io/diagnostics/CC0003.html) | CatchEmptyAnalyzer | Warning | Catch statements with no Exception as an argument is not recommended. Consider adding an Exception class to the catch statement. [CC0004](http://code-cracker.github.io/diagnostics/CC0004.html) | EmptyCatchBlockAnalyzer | Warning | An empty catch block suppress all errors and shouldn’t be used. If the error is expected consider logging it or changing the control flow such that it is explicit. -[CC0016](http://code-cracker.github.io/diagnostics/CC0016.html) | CopyEventToVariableBeforeFireAnalyzer | Warning | Events should always be checked for null before being invoked. As in a multi-threading context it is possible for an event to be unsuscribed between the moment where it is checked to be non-null and the moment it is raised, the event must be copied to a temporary variable before the check. -[CC0021](http://code-cracker.github.io/diagnostics/CC0021.html) | NameOfAnalyzer | Warning | In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produce code that is easier to refactor. -[CC0024](http://code-cracker.github.io/diagnostics/CC0024.html) | StaticConstructorExceptionAnalyzer | Warning | Static constructor are called before the first time a class is used but the caller doesn’t control when exactly. Exception thrown in this context force callers to use ‘try’ block around any useage of the class and should be avoided. -[CC0031](http://code-cracker.github.io/diagnostics/CC0031.html) | UseInvokeMethodToFireEventAnalyzer | Warning | In C#6 a delegate can be invoked using the null-propagating operator (?.) and it’s invoke method to avoid throwing a NullReference exception when there is no method attached to the delegate. +[CC0016](http://code-cracker.github.io/diagnostics/CC0016.html) | CopyEventToVariableBeforeFireAnalyzer | Warning | Events should always be checked for null before being invoked. As in a multi-threading context, it is possible for an event to be unsubscribed between the moment where it is checked to be non-null and the moment it is raised, the event must be copied to a temporary variable before the check. +[CC0021](http://code-cracker.github.io/diagnostics/CC0021.html) | NameOfAnalyzer | Warning | In C#6 the nameof() operator should be used to specify the name of a program element instead of a string literal as it produces code that is easier to refactor. +[CC0024](http://code-cracker.github.io/diagnostics/CC0024.html) | StaticConstructorExceptionAnalyzer | Warning | Static constructor are called before the first time a class is used but the caller doesn’t control when exactly. Exceptions thrown in this context force callers to use ‘try’ block around any usage of the class and should be avoided. +[CC0031](http://code-cracker.github.io/diagnostics/CC0031.html) | UseInvokeMethodToFireEventAnalyzer | Warning | In C#6 a delegate can be invoked using the null-propagating operator (?.) and its invoke method to avoid throwing a NullReference exception when there is no method attached to the delegate. ## Installing -You may use CodeCracker in two ways: as an analyzer library that you install with Nuget into your project or as a Visual Studio extension. +You may use CodeCracker in two ways: as an analyzer library that you install with NuGet into your project, or as a Visual Studio extension. The way you want to use it depends on the scenario you are working on. You most likely want the Nuget package. If you want the analyzers to work during your build, and generate warnings and errors during the build, also on build servers, then you want -to use the Nuget package. The package is available on nuget ([C#](https://www.nuget.org/packages/codecracker.CSharp), +to use the Nuget package. The package is available on NuGet ([C#](https://www.nuget.org/packages/codecracker.CSharp), [VB](https://www.nuget.org/packages/codecracker.VisualBasic)). If you want to be able to configure which analyzers are being used in your project, and which ones you will ignore, and commit those changes to source control and share with your team, then you also want the Nuget package. -To install from Nuget, for the C# version: +To install from NuGet, for the C# version: ```powershell Install-Package CodeCracker.CSharp @@ -62,7 +62,7 @@ Or use the Package Manager in Visual Studio. There is also a version for both named `CodeCracker` only, but it makes no sense to get it, you should search for the C# or VB version. -If you want the alpha builds that build on each push to the repo, add https://www.myget.org/F/codecrackerbuild/ to your Nuget feed. +If you want the alpha builds that build on each push to the repo, add [this](https://www.myget.org/F/codecrackerbuild/) to your NuGet feed. We only push complete releases to Nuget.org, and commit builds go to Myget.org. If you want global analyzers that will work on every project you open in Visual Studio, then you want the Extension. @@ -92,13 +92,13 @@ The main supported IDE for development is Visual Studio 2017. We do not support VS 2015 anymore. Questions, comments, bug reports, and pull requests are all welcome. -Bug reports that include steps-to-reproduce (including code) are +Bug reports that include steps to reproduce (including code) are preferred. Even better, make them in the form of pull requests. Before you start to work on an existing issue, check if it is not assigned to anyone yet, and if it is, talk to that person. -Also check the project [board](https://huboard.com/code-cracker/code-cracker/) +Also, check the project [board](https://huboard.com/code-cracker/code-cracker/) and verify it is not being worked on (it will be tagged with the `Working` tag). -If it is not being worked on, before you start check if the item is `Ready`. +If it is not being worked on, check if the item is `Ready` before you start. If the issue has the `Working` tag (working swimlane on Huboard) and has no Assignee then it is not being worked on by somebody on the core team. Check the issue's description to find out who it is (if it is not there it has to be on the comments). @@ -108,7 +108,7 @@ be assigned to this team. The easiest way to start is looking into the issues that are [up for grabs](https://github.com/code-cracker/code-cracker/labels/up-for-grabs). You -may ask to work on any of them, read below to see how. You can also triage issues which may include reproducing bug reports, or asking for vital information such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to code-cracker on CodeTriage](https://www.codetriage.com/code-cracker/code-cracker). +may ask to work on any of them, read below to see how. You can also triage issues which may include reproducing bug reports or asking for vital information such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to code-cracker on CodeTriage](https://www.codetriage.com/code-cracker/code-cracker). If you are just starting with Roslyn, want to contribute, and feel you are not yet ready to start working on full analyzers or code fixes, you can start helping with areas that are @@ -116,8 +116,7 @@ less demanding. We have identified a few: * Fixing bugs - Still demands knowledge of Roslyn internals but it is easier than coming up with a full - analyzer or code fix. Look for the [bugs that are up for grabs](https://github.com/code-cracker/code-cracker/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Abug+label%3Aup-for-grabs). + Still demands knowledge of Roslyn internals but it is easier than coming up with a full analyzer or code fix. Look for the [bugs that are up for grabs](https://github.com/code-cracker/code-cracker/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Abug+label%3Aup-for-grabs). * Documentation @@ -126,10 +125,8 @@ less demanding. We have identified a few: * Localization/Translation - We are starting to translate the analyzers and code fixes messages to other languages. If you want CodeCracker - on your language feel free to create an issue and start working on it. If you want to help with an ongoing translation, - comment on the existing issue and say you are ready to help. We also need to update existing analyzers, which were - not created ready for localization. + We are starting to translate the analyzers and code fixes messages to other languages. If you want CodeCracker on your language feel free to create an issue and start working on it. If you want to help with an ongoing translation, + comment on the existing issue and say you are ready to help. We also need to update existing analyzers, which were not created ready for localization. ## Issues and task board @@ -145,7 +142,7 @@ defined ready as: 2. If it has an analyzer then 1. The warning level of the analyzer must be in the issue's description (`Hidden`, `Information`, `Warning`, or `Error`) - 2. The diagnostics it provides should already have numeric ids defined formated as `CC0000`. + 2. The diagnostics it provides should already have numeric ids defined formatted as `CC0000`. 3. If it has a code fix then the category should be in the issue's description. The supported categories are listed on the `SupportedCategories.cs` file. 4. Have some of the maintainers verify it (cannot be the same one who wrote the issue and/or test cases) @@ -161,9 +158,9 @@ and [#10](https://github.com/code-cracker/code-cracker/issues/10). These are the 4 severity levels supported on Roslyn and how they are understood on the Code Cracker project: 1. **Hidden**: Only used for refactorings. See #66 (and its comments) to understand why. -2. **Info**: An alternative way (ex: replacing for with foreach). Clearly a matter of opinion and/or current way could be correct, or maybe the new code could be correct. We cannot determine. +2. **Info**: An alternative way (ex: replacing for with foreach). Clearly, a matter of opinion and/or current way could be correct, or maybe the new code could be correct. We cannot determine. 3. **Warning**: Code that could/should be improved. It is a code smell and most likely is wrong, but there are situations where the pattern is acceptable or desired. -4. **Error**: Clearly a mistake (ex: throwing ArgumentException with an non-existent parameter). There is no situation where this code could be correct. There are no differences of opinion. +4. **Error**: Clearly a mistake (ex: throwing ArgumentException with a non-existent parameter). There is no situation where this code could be correct. There are no differences of opinion. You can read [directly on Microsoft's source code](http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis/Diagnostic/DiagnosticSeverity.cs,e70281df673d47f6,references) how they interpret these levels. @@ -182,7 +179,7 @@ The DoD is still evolving. At the present time the checklist is as follows: 5. Code fixes should follow the guidelines for names 1. Always named `CodeFixProvider` - 2. Always use the same diagnostic id added to the `DiagnosticIds.cs` file, unless you are writing a code fix for a diagnostic id raised by the C# compiler itself (staring with `CS`). + 2. Always use the same diagnostic id added to the `DiagnosticIds.cs` file, unless you are writing a code fix for a diagnostic id raised by the C# compiler itself (starting with `CS`). 6. Fix all scenarios (fix all in document, fix all in project and fix all in solution) work. You might need to write a `FixAllProvider`. Check the `DisposableVariableNotDisposedFixAllProvider` as an example. 7. Follow the coding standards present on the project code files. 8. Works in Visual Studio @@ -190,11 +187,11 @@ The DoD is still evolving. At the present time the checklist is as follows: ### Start working -Once it is Ready and agreed on by any one from the core team, just state in +Once it is Ready and agreed on by anyone from the core team, just state in a comment that you intend to start working on that item and mention any/all the maintainers (use @code-cracker/owners) so they can tag it correctly and move it on the board. -If you are not familiar with the way Github works you might want to check the [Github guides](https://guides.github.com/), specially +If you are not familiar with the way Github works you might want to check the [Github guides](https://guides.github.com/), especially the [Github flow](https://guides.github.com/introduction/flow/) one. The [GitHub for the Roslyn Team video](http://channel9.msdn.com/Blogs/dotnet/github-for-the-roslyn-team) might help you as well, and it also explains some Git concepts. @@ -203,7 +200,7 @@ To start working fork the project on Github to your own account and clone it **f from the main CodeCracker repository. Before you start coding create a new branch and name it in a way that makes sense for the issue that you will be working on. Don't work on the `master` branch because that may make things harder if you have to update your pull request or your repository later, assume your `master` branch -is always equals the main repo `master` branch, and code on a different branch. +always equals the main repo `master` branch, and code on a different branch. When you commit, mention the issue number use the pound sign (#). Avoid making a lot of small commits unless they are meaningful. For most analyzers and code fixes a single commit should be enough. If you @@ -239,9 +236,9 @@ git merge master # solve integration conflicts ```` -You can solve the conflicts in your favorite text editor, or, if you are using Visual Studio, you can use it as well. +You can solve the conflicts in your favorite text editor or Visual Studio. Visual Studio actually presents the conflict in a very nice way to solve them. -Also, on the `go back to your working branch` step you can go back to using Visual Studio to control git, if you +Also, on the `go back to your working branch` step you can go back to using Visual Studio to control git if you prefer that. If you know git well, you can rebase your changes instead of merging them. If not, it is ok to merge them. @@ -270,7 +267,7 @@ discussing and fixing they are accepted. Work with the community to get it to be * Your pull requested will be commented by the Coveralls bot. Make sure code coverage has not gone down significantly. Ideally, it should go up. If you work on something that you have not yet discussed with the maintainers -there is a chance the code might be denied because they might find the analyzer/fix is not necessary, or duplicated, or some other reason. +there is a chance the code might be denied because they might find the analyzer/fix is not necessary, duplicated, or some other reason. They are easily reachable through Twitter or on Github. Before you code discuss it with it them. Small code changes or updates outside code files will eventually be made by the core team directly on `master`, without a PR. @@ -284,7 +281,7 @@ Small code changes or updates outside code files will eventually be made by the Contributors can be found at the [contributors](https://github.com/code-cracker/code-cracker/graphs/contributors) page on Github. -### What are the maintainers responsibilities? +### What are the maintainers' responsibilities? The maintainers have to: @@ -307,5 +304,5 @@ Please see our [contact page](http://code-cracker.github.io/contact.html). This software is open source, licensed under the Apache License, Version 2.0. See [LICENSE.txt](https://github.com/code-cracker/code-cracker/blob/master/LICENSE.txt) for details. Check out the terms of the license before you contribute, fork, copy or do anything -with the code. If you decide to contribute you agree to grant copyright of all your contribution to this project, and agree to +with the code. If you decide to contribute you agree to grant copyright of all your contribution to this project and agree to mention clearly if do not agree to these terms. Your work will be licensed with the project at Apache V2, along the rest of the code. From cd95c2f4b39fdd979ae103f4e47b353185769236 Mon Sep 17 00:00:00 2001 From: Manish17292000 <43097382+Manish17292000@users.noreply.github.com> Date: Tue, 2 Oct 2018 19:34:38 +0530 Subject: [PATCH 129/152] Create hello.cpp --- hello.cpp | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 hello.cpp diff --git a/hello.cpp b/hello.cpp new file mode 100644 index 000000000..5df26f4c2 --- /dev/null +++ b/hello.cpp @@ -0,0 +1,7 @@ +#include + +int main() +{ + std::cout << "Hello, World!"; + return 0; +} From 7ad7ad8f1bf9d7af9f08fbee754df73d3bbd0486 Mon Sep 17 00:00:00 2001 From: Carl Troll Date: Sat, 6 Oct 2018 13:19:27 +0200 Subject: [PATCH 130/152] Enhancement for #922 --- .../Style/TaskNameAsyncCodeFixProvider.cs | 29 +++- .../Style/TaskNameASyncTests.cs | 132 ++++++++++++++++++ 2 files changed, 159 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs index 198444fb5..01b9aa6d3 100644 --- a/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/TaskNameAsyncCodeFixProvider.cs @@ -12,7 +12,7 @@ namespace CodeCracker.CSharp.Style { - [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(TaskNameAsyncCodeFixProvider)), Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixProvider)), Shared] public class TaskNameAsyncCodeFixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.TaskNameAsync.ToDiagnosticId()); @@ -46,7 +46,12 @@ private static async Task ChangeMethodNameAsync(Document document, Dia var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var methodStatement = root.FindToken(diagnostic.Location.SourceSpan.Start).Parent.AncestorsAndSelf().OfType().First(); var semanticModel = await document.GetSemanticModelAsync(cancellationToken); - var newName = methodStatement.Identifier.ToString() + "Async"; + var oldName = methodStatement.Identifier.ToString(); + if (HasAsyncCorrectlyInName(oldName)) + { + oldName = oldName.Remove(oldName.IndexOf("Async"), "Async".Length); + } + var newName = oldName + "Async"; var solution = document.Project.Solution; var symbol = semanticModel.GetDeclaredSymbol(methodStatement, cancellationToken); var options = solution.Workspace.Options; @@ -54,5 +59,25 @@ private static async Task ChangeMethodNameAsync(Document document, Dia options, cancellationToken).ConfigureAwait(false); return newSolution; } + + private static bool HasAsyncCorrectlyInName(string name) + { + var index = name.IndexOf("Async"); + if (index < 0) + { + return false; + } + + var postAsyncLetterIndex = index + "Async".Length; + if (postAsyncLetterIndex >= name.Length) + { + return false; + } + + var valueAfterAsync = name[postAsyncLetterIndex]; + return char.IsDigit(valueAfterAsync) + || (char.IsLetter(valueAfterAsync) && char.IsUpper(valueAfterAsync)) + || valueAfterAsync == '_'; + } } } \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs index e897d37b1..8074e4809 100644 --- a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs @@ -262,5 +262,137 @@ Task IBar.Foo() }; await VerifyCSharpDiagnosticAsync(source, expected); } + + [Fact] + public async Task ChangeTaskNameWithAsyncNotAtTheEndWithUpperCaseLetter() + { + const string source = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public class Foo + { + public methodTest() + { + await Test(); + } + + public Task TestAsyncFoo() + { + return true; + } + } + + }"; + const string fixtest = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public class Foo + { + public methodTest() + { + await TestAsync(); + } + + public Task TestFooAsync() + { + return true; + } + } + + }"; + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task ChangeTaskNameWithAsyncNotAtTheEndWithUnderline() + { + const string source = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public class Foo + { + public methodTest() + { + await Test(); + } + + public Task TestAsync_Foo() + { + return true; + } + } + + }"; + const string fixtest = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public class Foo + { + public methodTest() + { + await TestAsync(); + } + + public Task Test_FooAsync() + { + return true; + } + } + + }"; + await VerifyCSharpFixAsync(source, fixtest); + } + + [Fact] + public async Task ChangeTaskNameWithAsyncNotAtTheEndWithDigit() + { + const string source = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public class Foo + { + public methodTest() + { + await Test(); + } + + public Task TestAsync0Foo() + { + return true; + } + } + + }"; + const string fixtest = @" + using System.Threading.Tasks; + + namespace ConsoleApplication1 + { + public class Foo + { + public methodTest() + { + await TestAsync(); + } + + public Task Test0FooAsync() + { + return true; + } + } + + }"; + await VerifyCSharpFixAsync(source, fixtest); + } } } \ No newline at end of file From 8beb4cddaef68c447fab64f79dcd09ef7f61bf62 Mon Sep 17 00:00:00 2001 From: Carl Troll Date: Sat, 6 Oct 2018 14:18:27 +0200 Subject: [PATCH 131/152] #922 test fix --- .../CodeCracker.Test/Style/TaskNameASyncTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs index 8074e4809..44299b862 100644 --- a/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/TaskNameASyncTests.cs @@ -275,7 +275,7 @@ public class Foo { public methodTest() { - await Test(); + await TestAsyncFoo(); } public Task TestAsyncFoo() @@ -294,7 +294,7 @@ public class Foo { public methodTest() { - await TestAsync(); + await TestFooAsync(); } public Task TestFooAsync() @@ -319,7 +319,7 @@ public class Foo { public methodTest() { - await Test(); + await TestAsync_Foo(); } public Task TestAsync_Foo() @@ -338,7 +338,7 @@ public class Foo { public methodTest() { - await TestAsync(); + await Test_FooAsync(); } public Task Test_FooAsync() @@ -363,7 +363,7 @@ public class Foo { public methodTest() { - await Test(); + await TestAsync0Foo(); } public Task TestAsync0Foo() @@ -382,7 +382,7 @@ public class Foo { public methodTest() { - await TestAsync(); + await Test0FooAsync(); } public Task Test0FooAsync() From 9b66639413cbf1afdfe52e2acc107446c6f5b1da Mon Sep 17 00:00:00 2001 From: Carl Troll Date: Mon, 8 Oct 2018 10:16:02 +0200 Subject: [PATCH 132/152] Make CC0011 work with IQueryable and Async methods --- .../RemoveWhereWhenItIsPossibleAnalyzer.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs index aa7fbda5e..a38da9608 100644 --- a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs +++ b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs @@ -25,8 +25,17 @@ public class RemoveWhereWhenItIsPossibleAnalyzer : DiagnosticAnalyzer "Any", "Single", "SingleOrDefault", - "Count" + "Count", + "FirstAsync", + "FirstOrDefaultAsync", + "LastAsync", + "LastOrDefaultAsync", + "AnyAsync", + "SingleAsync", + "SingleOrDefaultAsync", + "CountAsync" }; + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), Title, From 965944d0557db706cab329f576d2e6599c681424 Mon Sep 17 00:00:00 2001 From: carlilord Date: Mon, 8 Oct 2018 10:26:05 +0200 Subject: [PATCH 133/152] Delete RemoveWhereWhenItIsPossibleAnalyzer.cs --- .../RemoveWhereWhenItIsPossibleAnalyzer.cs | 90 ------------------- 1 file changed, 90 deletions(-) delete mode 100644 src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs diff --git a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs deleted file mode 100644 index a38da9608..000000000 --- a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs +++ /dev/null @@ -1,90 +0,0 @@ -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; - -namespace CodeCracker.CSharp.Performance -{ - [DiagnosticAnalyzer(LanguageNames.CSharp)] - public class RemoveWhereWhenItIsPossibleAnalyzer : DiagnosticAnalyzer - { - internal const string Title = "You should remove the 'Where' invocation when it is possible."; - internal const string MessageFormat = "You can remove 'Where' moving the predicate to '{0}'."; - internal const string Category = SupportedCategories.Performance; - const string Description = "When a linq operator support a predicate parameter it should be used instead of " - + "using 'Where' followed by the operator"; - - static readonly string[] supportedMethods = new[] { - "First", - "FirstOrDefault", - "Last", - "LastOrDefault", - "Any", - "Single", - "SingleOrDefault", - "Count", - "FirstAsync", - "FirstOrDefaultAsync", - "LastAsync", - "LastOrDefaultAsync", - "AnyAsync", - "SingleAsync", - "SingleOrDefaultAsync", - "CountAsync" - }; - - internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( - DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), - Title, - MessageFormat, - Category, - DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: Description, - helpLinkUri: HelpLink.ForDiagnostic(DiagnosticId.RemoveWhereWhenItIsPossible)); - - public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(Rule); - - public override void Initialize(AnalysisContext context) => - context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.InvocationExpression); - - private static void AnalyzeNode(SyntaxNodeAnalysisContext context) - { - if (context.IsGenerated()) return; - var whereInvoke = (InvocationExpressionSyntax)context.Node; - var nameOfWhereInvoke = GetNameOfTheInvokedMethod(whereInvoke); - if (nameOfWhereInvoke?.ToString() != "Where") return; - if (ArgumentsDoNotMatch(whereInvoke)) return; - - var nextMethodInvoke = whereInvoke.Parent. - FirstAncestorOrSelf(); - if (nextMethodInvoke == null) return; - - var candidate = GetNameOfTheInvokedMethod(nextMethodInvoke)?.ToString(); - if (!supportedMethods.Contains(candidate)) return; - - if (nextMethodInvoke.ArgumentList.Arguments.Any()) return; - var properties = new Dictionary { { "methodName", candidate } }.ToImmutableDictionary(); - var diagnostic = Diagnostic.Create(Rule, nameOfWhereInvoke.GetLocation(), properties, candidate); - context.ReportDiagnostic(diagnostic); - } - - private static bool ArgumentsDoNotMatch(InvocationExpressionSyntax whereInvoke) - { - var arguments = whereInvoke.ArgumentList.Arguments; - if (arguments.Count != 1) return true; - var expression = arguments.First()?.Expression; - if (expression == null) return true; - if (expression is SimpleLambdaExpressionSyntax) return false; - var parenthesizedLambda = expression as ParenthesizedLambdaExpressionSyntax; - if (parenthesizedLambda == null) return true; - return parenthesizedLambda.ParameterList.Parameters.Count != 1; - } - - private static SimpleNameSyntax GetNameOfTheInvokedMethod(InvocationExpressionSyntax invoke) => - invoke.ChildNodes().OfType().FirstOrDefault()?.Name; - } -} \ No newline at end of file From a6c1d1b93a81efd3da2dfce464963e127a26f16d Mon Sep 17 00:00:00 2001 From: carlilord Date: Mon, 8 Oct 2018 10:28:24 +0200 Subject: [PATCH 134/152] Make CC0011 work with IQueryable and Async methods Fixes #905 --- .../RemoveWhereWhenItIsPossibleAnalyzer.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs index aa7fbda5e..9ba262a53 100644 --- a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs +++ b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs @@ -25,8 +25,17 @@ public class RemoveWhereWhenItIsPossibleAnalyzer : DiagnosticAnalyzer "Any", "Single", "SingleOrDefault", - "Count" + "Count", + "FirstAsync", + "FirstOrDefaultAsync", + "LastAsync", + "LastOrDefaultAsync", + "AnyAsync", + "SingleAsync", + "SingleOrDefaultAsync", + "CountAsync" }; + internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), Title, @@ -78,4 +87,4 @@ private static bool ArgumentsDoNotMatch(InvocationExpressionSyntax whereInvoke) private static SimpleNameSyntax GetNameOfTheInvokedMethod(InvocationExpressionSyntax invoke) => invoke.ChildNodes().OfType().FirstOrDefault()?.Name; } -} \ No newline at end of file +} From ba0b8e496b24497a0b39cde87ce650e754c3547d Mon Sep 17 00:00:00 2001 From: Carl Troll Date: Mon, 8 Oct 2018 10:32:37 +0200 Subject: [PATCH 135/152] Revert --- .../Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs index a38da9608..1332ab9a1 100644 --- a/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs +++ b/src/CSharp/CodeCracker/Performance/RemoveWhereWhenItIsPossibleAnalyzer.cs @@ -25,15 +25,7 @@ public class RemoveWhereWhenItIsPossibleAnalyzer : DiagnosticAnalyzer "Any", "Single", "SingleOrDefault", - "Count", - "FirstAsync", - "FirstOrDefaultAsync", - "LastAsync", - "LastOrDefaultAsync", - "AnyAsync", - "SingleAsync", - "SingleOrDefaultAsync", - "CountAsync" + "Count" }; internal static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor( From 9342e9f804712c7090eccdc11af93d7f3c9f98f3 Mon Sep 17 00:00:00 2001 From: Umang Raval Date: Mon, 8 Oct 2018 20:02:45 +0530 Subject: [PATCH 136/152] corrected grammatical errors --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfb59721e..24b95237a 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ The DoD is still evolving. At the present time the checklist is as follows: 1. Always named `CodeFixProvider` 2. Always use the same diagnostic id added to the `DiagnosticIds.cs` file, unless you are writing a code fix for a diagnostic id raised by the C# compiler itself (starting with `CS`). -6. Fix all scenarios (fix all in document, fix all in project and fix all in solution) work. You might need to write a `FixAllProvider`. Check the `DisposableVariableNotDisposedFixAllProvider` as an example. +6. Fix all scenarios (fix all in a document, fix all in a project and fix all in solution) work. You might need to write a `FixAllProvider`. Check the `DisposableVariableNotDisposedFixAllProvider` as an example. 7. Follow the coding standards present on the project code files. 8. Works in Visual Studio 9. Uses localizable strings From c35c6cb1364267782a66c48e0578ee649dbecf6d Mon Sep 17 00:00:00 2001 From: Isuru40 Date: Sat, 20 Oct 2018 11:30:52 +0530 Subject: [PATCH 137/152] Update Hacktoberfest --- Hacktoberfest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Hacktoberfest b/Hacktoberfest index 316700cd9..28c43036f 100644 --- a/Hacktoberfest +++ b/Hacktoberfest @@ -23,4 +23,4 @@ Create a remote to link the repository on github to your local workspace. use "g Push the commit. For example, type "git push [remote-name] master". Go back to the original repo. Hit "new pull request" and compare between forks. -Confirm the pull request and that's it! +Confirm the pull request and that's it!!! From 9ccc2bb21012d0845156af28fab4e56f15cd8474 Mon Sep 17 00:00:00 2001 From: Neil Bostrom Date: Sun, 18 Nov 2018 22:06:00 +0000 Subject: [PATCH 138/152] Fixes #930 CC0020 cannot be used when types are declared --- ...ertLambdaExpressionToMethodGroupAnalyzer.cs | 8 +++++++- ...onvertLambdaExpressionToMethodGroupTests.cs | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker/Style/ConvertLambdaExpressionToMethodGroupAnalyzer.cs b/src/CSharp/CodeCracker/Style/ConvertLambdaExpressionToMethodGroupAnalyzer.cs index 671e55349..bb335f76d 100644 --- a/src/CSharp/CodeCracker/Style/ConvertLambdaExpressionToMethodGroupAnalyzer.cs +++ b/src/CSharp/CodeCracker/Style/ConvertLambdaExpressionToMethodGroupAnalyzer.cs @@ -65,7 +65,13 @@ internal static InvocationExpressionSyntax GetInvocationIfAny(SyntaxNode node) : (node as ParenthesizedLambdaExpressionSyntax)?.Body; var invocation = body as InvocationExpressionSyntax; - if (invocation != null) return invocation; + + if (invocation != null) + { + if (invocation.Expression is GenericNameSyntax && (((GenericNameSyntax)invocation.Expression).TypeArgumentList.Arguments.Count > 0)) return null; + + return invocation; + } var possibleBlock = body as BlockSyntax; if (possibleBlock == null || possibleBlock.Statements.Count != 1) return null; diff --git a/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs b/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs index 0a968adf9..f26fcd8b9 100644 --- a/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/ConvertLambdaExpressionToMethodGroupTests.cs @@ -598,5 +598,23 @@ public static Task Finally(this Task task, Func(); + xs.Select(x => Func(x)); + } + object Func(object x) => x; +}"; + await VerifyCSharpHasNoDiagnosticsAsync(oldCode); + } + } } \ No newline at end of file From 80f53b29811fdf36a57a8b8119eea8fc33f25456 Mon Sep 17 00:00:00 2001 From: carlilord Date: Fri, 23 Nov 2018 10:08:54 +0100 Subject: [PATCH 139/152] #905 added unit test --- .../CodeCracker.Test/CodeCracker.Test.csproj | 1 + .../Helpers/IQueriableExtensions.cs | 43 +++++ .../RemoveWhereWhenItIsPossibleTests.cs | 160 ++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 test/CSharp/CodeCracker.Test/Helpers/IQueriableExtensions.cs diff --git a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj index 4d186cfbe..7796725c8 100644 --- a/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj +++ b/test/CSharp/CodeCracker.Test/CodeCracker.Test.csproj @@ -120,6 +120,7 @@ + diff --git a/test/CSharp/CodeCracker.Test/Helpers/IQueriableExtensions.cs b/test/CSharp/CodeCracker.Test/Helpers/IQueriableExtensions.cs new file mode 100644 index 000000000..c37c9ebf4 --- /dev/null +++ b/test/CSharp/CodeCracker.Test/Helpers/IQueriableExtensions.cs @@ -0,0 +1,43 @@ +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace CodeCracker.Test.CSharp.Helpers +{ + public static class IQueriableExtensions + { +#pragma warning disable CC0057 // Unused parameters + public static Task FirstAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => null; + + public static Task FirstOrDefaultAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => null; + + public static Task LastAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => null; + + public static Task LastOrDefaultAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => null; + + public static Task AnyAsync(this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => Task.FromResult(false); + + public static Task SingleAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => null; + + public static Task SingleOrDefaultAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => null; + + public static Task CountAsync( + this IQueryable source, + CancellationToken cancellationToken = default(CancellationToken)) => Task.FromResult(0); + +#pragma warning restore CC0057 // Unused parameters + } +} \ No newline at end of file diff --git a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs index c6e4b622a..17222105f 100644 --- a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs @@ -154,6 +154,166 @@ public async Task DoSomething() var expected = @" using System.Linq; +namespace Sample +{ + public class Foo + { + public async Task DoSomething() + { + var a = new int[10]; + var f = a.OrderBy(item => item)." + method + @"(item => item > 10); + } + } +}"; + + await VerifyCSharpFixAsync(test, expected); + + } + + // Async + [Theory] + [InlineData("FirstAsync")] + [InlineData("FirstOrDefaultAsync")] + [InlineData("LastAsync")] + [InlineData("LastOrDefaultAsync")] + [InlineData("AnyAsync")] + [InlineData("SingleAsync")] + [InlineData("SingleOrDefaultAsync")] + [InlineData("CountAsync")] + public async Task CreateDiagnosticWhenUsingWhereWithAsync(string method) + { + var test = @" +using System.Linq; + +namespace Sample +{ + public class Foo + { + public async Task DoSomething() + { + var a = new int[10]; + var f = a.Where(item => item > 10)." + method + @"(); + } + } +}"; + var expected = new DiagnosticResult + { + Id = DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), + Message = "You can remove 'Where' moving the predicate to '" + method + "'.", + Severity = DiagnosticSeverity.Warning, + Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 23) } + }; + + await VerifyCSharpDiagnosticAsync(test, expected); + + } + + [Theory] + [InlineData("FirstAsync")] + [InlineData("FirstOrDefaultAsync")] + [InlineData("LastAsync")] + [InlineData("LastOrDefaultAsync")] + [InlineData("AnyAsync")] + [InlineData("SingleAsync")] + [InlineData("SingleOrDefaultAsync")] + [InlineData("CountAsync")] + public async Task DoNotCreateDiagnosticWhenUsingWhereAndAnotherMethodWithPredicatesAsync(string method) + { + var test = @" +using System.Linq; + +namespace Sample +{ + public class Foo + { + public async Task DoSomething() + { + var a = new int[10]; + var f = a.Where(item => item > 10)." + method + @"(item => item < 50); + } + } +}"; + await VerifyCSharpHasNoDiagnosticsAsync(test); + } + + [Fact] + public async Task DoNotCreateDiagnosticWhenWhereUsesIndexerAsync() + { + var test = @" +var first = Enumerable.Range(1, 10).ToList(); +var second = Enumerable.Range(1, 10); +var isNotMatch = second.Where((t, i) => first[i] != t).Any(); +".WrapInCSharpMethod(usings: "using System.Linq;"); + await VerifyCSharpHasNoDiagnosticsAsync(test); + } + + [Theory] + [InlineData("FirstAsync")] + [InlineData("FirstOrDefaultAsync")] + [InlineData("LastAsync")] + [InlineData("LastOrDefaultAsync")] + [InlineData("AnyAsync")] + [InlineData("SingleAsync")] + [InlineData("SingleOrDefaultAsync")] + [InlineData("CountAsync")] + public async Task FixRemovesWhereMovingPredicateToAsync(string method) + { + var test = @" +namespace Sample +{ + public class Foo + { + public async Task DoSomething() + { + var a = new int[10]; + var f = a.Where((item) => item > 10)." + method + @"(); + } + } +}"; + var expected = @" +namespace Sample +{ + public class Foo + { + public async Task DoSomething() + { + var a = new int[10]; + var f = a." + method + @"((item) => item > 10); + } + } +}"; + await VerifyCSharpFixAsync(test, expected); + } + + [Theory] + [InlineData("FirstAsync")] + [InlineData("FirstOrDefaultAsync")] + [InlineData("LastAsync")] + [InlineData("LastOrDefaultAsync")] + [InlineData("AnyAsync")] + [InlineData("SingleAsync")] + [InlineData("SingleOrDefaultAsync")] + [InlineData("CountAsync")] + public async Task FixRemovesWherePreservingPreviousExpressionsMovingPredicateToAsync(string method) + { + var test = @" +using System.Linq; + +namespace Sample +{ + public class Foo + { + public async Task DoSomething() + { + var a = new int[10]; + var f = a.OrderBy(item => item).Where(item => item > 10)." + method + @"(); + } + } +}"; + + var expected = @" +using System.Linq; + namespace Sample { public class Foo From 1536af459849daac58cd182bfa2131c1ae5461a1 Mon Sep 17 00:00:00 2001 From: carlilord Date: Fri, 23 Nov 2018 10:20:07 +0100 Subject: [PATCH 140/152] build fix --- .../Performance/RemoveWhereWhenItIsPossibleTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs index 17222105f..3d55fa490 100644 --- a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs @@ -170,7 +170,6 @@ public async Task DoSomething() } - // Async [Theory] [InlineData("FirstAsync")] [InlineData("FirstOrDefaultAsync")] From ee521d7400df52b4f3e7734297d44111b0b4c2a9 Mon Sep 17 00:00:00 2001 From: carlilord Date: Fri, 23 Nov 2018 10:23:10 +0100 Subject: [PATCH 141/152] test adaption --- .../RemoveWhereWhenItIsPossibleTests.cs | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs index 3d55fa490..a953a1360 100644 --- a/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs +++ b/test/CSharp/CodeCracker.Test/Performance/RemoveWhereWhenItIsPossibleTests.cs @@ -170,43 +170,6 @@ public async Task DoSomething() } - [Theory] - [InlineData("FirstAsync")] - [InlineData("FirstOrDefaultAsync")] - [InlineData("LastAsync")] - [InlineData("LastOrDefaultAsync")] - [InlineData("AnyAsync")] - [InlineData("SingleAsync")] - [InlineData("SingleOrDefaultAsync")] - [InlineData("CountAsync")] - public async Task CreateDiagnosticWhenUsingWhereWithAsync(string method) - { - var test = @" -using System.Linq; - -namespace Sample -{ - public class Foo - { - public async Task DoSomething() - { - var a = new int[10]; - var f = a.Where(item => item > 10)." + method + @"(); - } - } -}"; - var expected = new DiagnosticResult - { - Id = DiagnosticId.RemoveWhereWhenItIsPossible.ToDiagnosticId(), - Message = "You can remove 'Where' moving the predicate to '" + method + "'.", - Severity = DiagnosticSeverity.Warning, - Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 23) } - }; - - await VerifyCSharpDiagnosticAsync(test, expected); - - } - [Theory] [InlineData("FirstAsync")] [InlineData("FirstOrDefaultAsync")] From 62c719a8526fe68d7c1707ea690d4736c56b3fe1 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 4 Jan 2019 16:22:19 +0100 Subject: [PATCH 142/152] Insert missing link Insert missing link to issue #66 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 24b95237a..d30381db7 100644 --- a/README.md +++ b/README.md @@ -157,7 +157,7 @@ and [#10](https://github.com/code-cracker/code-cracker/issues/10). These are the 4 severity levels supported on Roslyn and how they are understood on the Code Cracker project: -1. **Hidden**: Only used for refactorings. See #66 (and its comments) to understand why. +1. **Hidden**: Only used for refactorings. See [#66](https://github.com/code-cracker/code-cracker/issues/66) (and its comments) to understand why. 2. **Info**: An alternative way (ex: replacing for with foreach). Clearly, a matter of opinion and/or current way could be correct, or maybe the new code could be correct. We cannot determine. 3. **Warning**: Code that could/should be improved. It is a code smell and most likely is wrong, but there are situations where the pattern is acceptable or desired. 4. **Error**: Clearly a mistake (ex: throwing ArgumentException with a non-existent parameter). There is no situation where this code could be correct. There are no differences of opinion. From cda01dbd1c28f8c5bdbc0cfd13bf8cca40aeaa0a Mon Sep 17 00:00:00 2001 From: Matthieu Penant Date: Wed, 3 Apr 2019 11:54:45 -0400 Subject: [PATCH 143/152] VS2019 Support fix the errors on prerequisites --- .../CodeCracker.Vsix/debug/source.extension.vsixmanifest | 4 ++-- src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest | 4 ++-- .../CodeCracker.Vsix/debug/source.extension.vsixmanifest | 4 ++-- .../CodeCracker.Vsix/source.extension.vsixmanifest | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/CSharp/CodeCracker.Vsix/debug/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/debug/source.extension.vsixmanifest index e81a560f6..e0b59f52d 100644 --- a/src/CSharp/CodeCracker.Vsix/debug/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/debug/source.extension.vsixmanifest @@ -28,7 +28,7 @@ This is a community project, free and open source. Everyone is invited to contri - - + + diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest index aa1218012..7931195c2 100644 --- a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest @@ -27,7 +27,7 @@ This is a community project, free and open source. Everyone is invited to contri - - + + diff --git a/src/VisualBasic/CodeCracker.Vsix/debug/source.extension.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/debug/source.extension.vsixmanifest index 6f6ab34bd..0595693d0 100644 --- a/src/VisualBasic/CodeCracker.Vsix/debug/source.extension.vsixmanifest +++ b/src/VisualBasic/CodeCracker.Vsix/debug/source.extension.vsixmanifest @@ -28,7 +28,7 @@ This is a community project, free and open source. Everyone is invited to contri - - + + diff --git a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest index 3de517a30..01fa41c09 100644 --- a/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/VisualBasic/CodeCracker.Vsix/source.extension.vsixmanifest @@ -27,7 +27,7 @@ This is a community project, free and open source. Everyone is invited to contri - - + + From b706ff895d3fbeba106b3146b62d4d84002b5e7c Mon Sep 17 00:00:00 2001 From: Mithilesh Zavar Date: Sat, 6 Apr 2019 19:36:12 +0100 Subject: [PATCH 144/152] BUG: CC0065 "Remove trailing whitespace" bug with pragmas --- .../RemoveTrailingWhitespaceCodeFixProvider.cs | 2 +- .../Style/RemoveTrailingWhitespaceTests.cs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker/Style/RemoveTrailingWhitespaceCodeFixProvider.cs b/src/CSharp/CodeCracker/Style/RemoveTrailingWhitespaceCodeFixProvider.cs index 0190ed41b..b4a94ff25 100644 --- a/src/CSharp/CodeCracker/Style/RemoveTrailingWhitespaceCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Style/RemoveTrailingWhitespaceCodeFixProvider.cs @@ -35,7 +35,7 @@ private static async Task RemoveTrailingWhiteSpaceAsync(Document docum { newRoot = root.ReplaceTrivia(trivia, new SyntaxTrivia[] { }); } - else if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia)) + else if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxKind.MultiLineDocumentationCommentTrivia, SyntaxKind.PragmaWarningDirectiveTrivia)) { var commentText = trivia.ToFullString(); var commentLines = commentText.Split(new[] { Environment.NewLine }, StringSplitOptions.None); diff --git a/test/CSharp/CodeCracker.Test/Style/RemoveTrailingWhitespaceTests.cs b/test/CSharp/CodeCracker.Test/Style/RemoveTrailingWhitespaceTests.cs index de6b62bae..2130d04d4 100644 --- a/test/CSharp/CodeCracker.Test/Style/RemoveTrailingWhitespaceTests.cs +++ b/test/CSharp/CodeCracker.Test/Style/RemoveTrailingWhitespaceTests.cs @@ -135,5 +135,21 @@ class Foo { }"; class Foo { }"; await VerifyCSharpFixAsync(source, expected, formatBeforeCompare: false); } + + [Fact] + public async Task PragmaWithTrailingSpace() + { + const string source = @" +#pragma warning disable CC0072 +#pragma warning restore CC0072 +"; + + const string expected = @" +#pragma warning disable CC0072 +#pragma warning restore CC0072 +"; + + await VerifyCSharpFixAsync(source, expected, formatBeforeCompare: false); + } } } \ No newline at end of file From 5d274c23236037ef02168eef7a27a0d2be169484 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Mon, 27 May 2019 14:19:35 +0200 Subject: [PATCH 145/152] Add property name to ExportCodeFixProviderAttribute. --- .../Design/StaticConstructorExceptionCodeFixProvider.cs | 2 +- .../XmlDocumentationMissingInCSharpCodeFixProvider.cs | 2 +- .../XmlDocumentationMissingInXmlCodeFixProvider.cs | 2 +- .../Refactoring/StringRepresentationCodeFixProvider.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CSharp/CodeCracker/Design/StaticConstructorExceptionCodeFixProvider.cs b/src/CSharp/CodeCracker/Design/StaticConstructorExceptionCodeFixProvider.cs index 38d620ba6..44ff21625 100644 --- a/src/CSharp/CodeCracker/Design/StaticConstructorExceptionCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Design/StaticConstructorExceptionCodeFixProvider.cs @@ -10,7 +10,7 @@ namespace CodeCracker.CSharp.Design { - [ExportCodeFixProvider(LanguageNames.CSharp, nameof(StaticConstructorExceptionCodeFixProvider)), Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(StaticConstructorExceptionCodeFixProvider)), Shared] public class StaticConstructorExceptionCodeFixProvider : CodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds => diff --git a/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInCSharpCodeFixProvider.cs b/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInCSharpCodeFixProvider.cs index 232533605..b0d5f4e9d 100644 --- a/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInCSharpCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInCSharpCodeFixProvider.cs @@ -12,7 +12,7 @@ namespace CodeCracker.CSharp.Maintainability { - [ExportCodeFixProvider(LanguageNames.CSharp, nameof(XmlDocumentationCodeFixProvider)), Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(XmlDocumentationCodeFixProvider)), Shared] public sealed class XmlDocumentationMissingInCSharpCodeFixProvider : XmlDocumentationCodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.XmlDocumentation_MissingInCSharp.ToDiagnosticId()); diff --git a/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInXmlCodeFixProvider.cs b/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInXmlCodeFixProvider.cs index be54bc846..36e268fca 100644 --- a/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInXmlCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Maintainability/XmlDocumentationMissingInXmlCodeFixProvider.cs @@ -12,7 +12,7 @@ namespace CodeCracker.CSharp.Maintainability { - [ExportCodeFixProvider(LanguageNames.CSharp, nameof(XmlDocumentationCodeFixProvider)), Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(XmlDocumentationCodeFixProvider)), Shared] public sealed class XmlDocumentationMissingInXmlCodeFixProvider : XmlDocumentationCodeFixProvider { public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(DiagnosticId.XmlDocumentation_MissingInXml.ToDiagnosticId()); diff --git a/src/CSharp/CodeCracker/Refactoring/StringRepresentationCodeFixProvider.cs b/src/CSharp/CodeCracker/Refactoring/StringRepresentationCodeFixProvider.cs index 3f1934ac1..bd8d714c6 100644 --- a/src/CSharp/CodeCracker/Refactoring/StringRepresentationCodeFixProvider.cs +++ b/src/CSharp/CodeCracker/Refactoring/StringRepresentationCodeFixProvider.cs @@ -13,7 +13,7 @@ namespace CodeCracker.CSharp.Refactoring { - [ExportCodeFixProvider(LanguageNames.CSharp, nameof(StringRepresentationCodeFixProvider)), Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(StringRepresentationCodeFixProvider)), Shared] public class StringRepresentationCodeFixProvider : CodeFixProvider { public const string Id = nameof(StringRepresentationCodeFixProvider); From cf422cc5031c13659250f2ad44a82d1f350ce2b5 Mon Sep 17 00:00:00 2001 From: sunny kumar Date: Tue, 1 Oct 2019 13:10:35 +0530 Subject: [PATCH 146/152] Change : added << endl in hello.cpp --- hello.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hello.cpp b/hello.cpp index 5df26f4c2..378706961 100644 --- a/hello.cpp +++ b/hello.cpp @@ -2,6 +2,6 @@ int main() { - std::cout << "Hello, World!"; + std::cout << "Hello, World!" << endl; return 0; } From 83f23667f3cb5748d979ece4158ef53ce83cccbf Mon Sep 17 00:00:00 2001 From: Carlos dos Santos Date: Thu, 21 Nov 2019 14:26:55 -0300 Subject: [PATCH 147/152] Version 2019 --- src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest index 7931195c2..b3b107180 100644 --- a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest @@ -1,7 +1,7 @@  - + Code Cracker for C# An analyzer library for C# that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. From 5cab9bfd2aabf83e687377ecfdbf9762db9880cd Mon Sep 17 00:00:00 2001 From: Carlos dos Santos Date: Thu, 21 Nov 2019 14:41:30 -0300 Subject: [PATCH 148/152] VSIX 2019 --- src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest index b3b107180..a495c36ac 100644 --- a/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest +++ b/src/CSharp/CodeCracker.Vsix/source.extension.vsixmanifest @@ -2,7 +2,7 @@ - Code Cracker for C# + Code Cracker for C# (2019) An analyzer library for C# that uses Roslyn to produce refactorings, code analysis, and other niceties. Check the official project site on code-cracker.github.io. Build status Nuget count Nuget downloads Issues open From 2e44309a8dd7febcf9e2fb1d85c0ed17734d3082 Mon Sep 17 00:00:00 2001 From: "dsharov@devpark.ru" Date: Tue, 22 Mar 2022 17:39:58 +0600 Subject: [PATCH 149/152] Added parser for inline using --- .../DisposableVariableNotDisposedAnalyzer.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs index 3ed958b5f..83544effa 100644 --- a/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs +++ b/src/CSharp/CodeCracker/Usage/DisposableVariableNotDisposedAnalyzer.cs @@ -78,6 +78,28 @@ private static void AnalyzeObjectCreation(SyntaxNodeAnalysisContext context) var usingStatement = variableDeclaration?.Parent as UsingStatementSyntax; if (usingStatement != null) return; statement = variableDeclaration.Parent as LocalDeclarationStatementSyntax; + if (statement != null) + { + //Check inline using + var isUsing = false; + var isSemicolon = false; + var firstToken = statement.GetFirstToken(); + if (firstToken != null) + { + isUsing = firstToken.Text == "using"; + } + + var lastToken = statement.GetLastToken(); + if (lastToken != null) + { + isSemicolon = lastToken.Text == ";"; + } + + var isVariableDeclaration = statement.ChildNodes().First() is VariableDeclarationSyntax; + + if (isUsing && isVariableDeclaration && isSemicolon) return; + } + if ((statement?.FirstAncestorOrSelf()) == null) return; } else if (topSyntaxNode.Parent.IsAnyKind(SyntaxKind.SimpleLambdaExpression, SyntaxKind.ParenthesizedLambdaExpression)) From a3536314991e0e8958348388a3581526d98b8a9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jun 2022 00:01:24 +0000 Subject: [PATCH 150/152] Bump NuGet.CommandLine from 4.6.2 to 4.9.5 in /.nuget Bumps NuGet.CommandLine from 4.6.2 to 4.9.5. --- updated-dependencies: - dependency-name: NuGet.CommandLine dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .nuget/packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nuget/packages.config b/.nuget/packages.config index b1704a67b..87d34f8af 100644 --- a/.nuget/packages.config +++ b/.nuget/packages.config @@ -1,6 +1,6 @@  - + From 39202fbde4d63a722519cb2847b9b8ba7bb0dc9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Dec 2022 01:35:12 +0000 Subject: [PATCH 151/152] Bump Newtonsoft.Json in /test/Common/CodeCracker.Test.Common Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 11.0.2 to 13.0.2. - [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases) - [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/11.0.2...13.0.2) --- updated-dependencies: - dependency-name: Newtonsoft.Json dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .../CodeCracker.Test.Common/CodeCracker.Test.Common.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj index ee17f57f6..ab8625db9 100644 --- a/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj +++ b/test/Common/CodeCracker.Test.Common/CodeCracker.Test.Common.csproj @@ -48,7 +48,7 @@ - + From 15a265d6e8c1566ad145df8bfcb252753a1c43e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 22:56:09 +0000 Subject: [PATCH 152/152] Bump NuGet.CommandLine from 4.9.5 to 5.11.5 in /.nuget Bumps [NuGet.CommandLine](https://github.com/NuGet/NuGet.Client) from 4.9.5 to 5.11.5. - [Release notes](https://github.com/NuGet/NuGet.Client/releases) - [Commits](https://github.com/NuGet/NuGet.Client/commits) --- updated-dependencies: - dependency-name: NuGet.CommandLine dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .nuget/packages.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.nuget/packages.config b/.nuget/packages.config index 87d34f8af..ac480de76 100644 --- a/.nuget/packages.config +++ b/.nuget/packages.config @@ -1,6 +1,6 @@ - + - +