├── .gitignore
├── EnumeratorCallAnalyzer
├── EnumeratorCallAnalyzer.Test
│ ├── TestFile.cs
│ ├── Verifiers
│ │ ├── VisualBasicCodeRefactoringVerifier`1+Test.cs
│ │ ├── VisualBasicAnalyzerVerifier`1+Test.cs
│ │ ├── VisualBasicCodeFixVerifier`2+Test.cs
│ │ ├── CSharpAnalyzerVerifier`1+Test.cs
│ │ ├── CSharpCodeRefactoringVerifier`1+Test.cs
│ │ ├── CSharpCodeFixVerifier`2+Test.cs
│ │ ├── CSharpCodeRefactoringVerifier`1.cs
│ │ ├── VisualBasicCodeRefactoringVerifier`1.cs
│ │ ├── CSharpVerifierHelper.cs
│ │ ├── CSharpAnalyzerVerifier`1.cs
│ │ ├── VisualBasicAnalyzerVerifier`1.cs
│ │ ├── CSharpCodeFixVerifier`2.cs
│ │ └── VisualBasicCodeFixVerifier`2.cs
│ ├── EnumeratorCallAnalyzer.Test.csproj
│ └── EnumeratorCallAnalyzerUnitTests.cs
├── EnumeratorCallAnalyzer
│ ├── EnumeratorCallAnalyzer.csproj
│ ├── EnumeratorCallAnalyzerAnalyzer.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── EnumeratorCallAnalyzer.CodeFixes
│ ├── EnumeratorCallAnalyzer.CodeFixes.csproj
│ ├── CodeFixResources.Designer.cs
│ ├── EnumeratorCallAnalyzerCodeFixProvider.cs
│ └── CodeFixResources.resx
├── EnumeratorCallAnalyzer.Vsix
│ ├── source.extension.vsixmanifest
│ └── EnumeratorCallAnalyzer.Vsix.csproj
└── EnumeratorCallAnalyzer.Package
│ ├── EnumeratorCallAnalyzer.Package.csproj
│ └── tools
│ ├── install.ps1
│ └── uninstall.ps1
├── checker.gif
├── NuGet.config
├── README.md
└── EnumeratorCallAnalyzer.sln
/.gitignore:
--------------------------------------------------------------------------------
1 | *.user
2 | bin
3 | obj
4 | .vs
5 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/TestFile.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/checker.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wappenull/EnumeratorCallAnalyzer/master/checker.gif
--------------------------------------------------------------------------------
/NuGet.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/VisualBasicCodeRefactoringVerifier`1+Test.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CodeRefactorings;
2 | using Microsoft.CodeAnalysis.Testing.Verifiers;
3 | using Microsoft.CodeAnalysis.VisualBasic.Testing;
4 |
5 | namespace EnumeratorCallAnalyzer.Test
6 | {
7 | public static partial class VisualBasicCodeRefactoringVerifier
8 | where TCodeRefactoring : CodeRefactoringProvider, new()
9 | {
10 | public class Test : VisualBasicCodeRefactoringTest
11 | {
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/VisualBasicAnalyzerVerifier`1+Test.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.Diagnostics;
2 | using Microsoft.CodeAnalysis.Testing.Verifiers;
3 | using Microsoft.CodeAnalysis.VisualBasic.Testing;
4 |
5 | namespace EnumeratorCallAnalyzer.Test
6 | {
7 | public static partial class VisualBasicAnalyzerVerifier
8 | where TAnalyzer : DiagnosticAnalyzer, new()
9 | {
10 | public class Test : VisualBasicAnalyzerTest
11 | {
12 | public Test( )
13 | {
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/VisualBasicCodeFixVerifier`2+Test.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CodeFixes;
2 | using Microsoft.CodeAnalysis.Diagnostics;
3 | using Microsoft.CodeAnalysis.Testing.Verifiers;
4 | using Microsoft.CodeAnalysis.VisualBasic.Testing;
5 |
6 | namespace EnumeratorCallAnalyzer.Test
7 | {
8 | public static partial class VisualBasicCodeFixVerifier
9 | where TAnalyzer : DiagnosticAnalyzer, new()
10 | where TCodeFix : CodeFixProvider, new()
11 | {
12 | public class Test : VisualBasicCodeFixTest
13 | {
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 |
7 |
8 | *$(MSBuildProjectFullPath)*
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.CodeFixes/EnumeratorCallAnalyzer.CodeFixes.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 | EnumeratorCallAnalyzer
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpAnalyzerVerifier`1+Test.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CSharp.Testing;
2 | using Microsoft.CodeAnalysis.Diagnostics;
3 | using Microsoft.CodeAnalysis.Testing.Verifiers;
4 |
5 | namespace EnumeratorCallAnalyzer.Test
6 | {
7 | public static partial class CSharpAnalyzerVerifier
8 | where TAnalyzer : DiagnosticAnalyzer, new()
9 | {
10 | public class Test : CSharpAnalyzerTest
11 | {
12 | public Test( )
13 | {
14 | SolutionTransforms.Add( ( solution, projectId ) =>
15 | {
16 | var compilationOptions = solution.GetProject(projectId).CompilationOptions;
17 | compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(
18 | compilationOptions.SpecificDiagnosticOptions.SetItems( CSharpVerifierHelper.NullableWarnings ) );
19 | solution = solution.WithProjectCompilationOptions( projectId, compilationOptions );
20 |
21 | return solution;
22 | } );
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpCodeRefactoringVerifier`1+Test.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CodeRefactorings;
2 | using Microsoft.CodeAnalysis.CSharp.Testing;
3 | using Microsoft.CodeAnalysis.Testing.Verifiers;
4 |
5 | namespace EnumeratorCallAnalyzer.Test
6 | {
7 | public static partial class CSharpCodeRefactoringVerifier
8 | where TCodeRefactoring : CodeRefactoringProvider, new()
9 | {
10 | public class Test : CSharpCodeRefactoringTest
11 | {
12 | public Test( )
13 | {
14 | SolutionTransforms.Add( ( solution, projectId ) =>
15 | {
16 | var compilationOptions = solution.GetProject(projectId).CompilationOptions;
17 | compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(
18 | compilationOptions.SpecificDiagnosticOptions.SetItems( CSharpVerifierHelper.NullableWarnings ) );
19 | solution = solution.WithProjectCompilationOptions( projectId, compilationOptions );
20 |
21 | return solution;
22 | } );
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpCodeFixVerifier`2+Test.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CodeFixes;
2 | using Microsoft.CodeAnalysis.CSharp.Testing;
3 | using Microsoft.CodeAnalysis.Diagnostics;
4 | using Microsoft.CodeAnalysis.Testing.Verifiers;
5 |
6 | namespace EnumeratorCallAnalyzer.Test
7 | {
8 | public static partial class CSharpCodeFixVerifier
9 | where TAnalyzer : DiagnosticAnalyzer, new()
10 | where TCodeFix : CodeFixProvider, new()
11 | {
12 | public class Test : CSharpCodeFixTest
13 | {
14 | public Test( )
15 | {
16 | SolutionTransforms.Add( ( solution, projectId ) =>
17 | {
18 | var compilationOptions = solution.GetProject(projectId).CompilationOptions;
19 | compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(
20 | compilationOptions.SpecificDiagnosticOptions.SetItems( CSharpVerifierHelper.NullableWarnings ) );
21 | solution = solution.WithProjectCompilationOptions( projectId, compilationOptions );
22 |
23 | return solution;
24 | } );
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # EnumeratorCallAnalyzer
2 | A Roslyn analyzer that catch wrong Unity coroutine call.
3 |
4 | It will catch a coroutine call without yield return similar to:
5 |
6 | Coroutine( );
7 |
8 | Suppose `Coroutine` is a function defined with:
9 |
10 | IEnumerator Coroutine( ) { ... }
11 |
12 | And will attempt to change to
13 |
14 | yield return Coroutine( );
15 |
16 | 
17 |
18 | - Solution file is created with VS2019
19 | - The solution will output VSIX for install with Visual Studio.
20 | - Roslyn SDK required to compile, see guide below.
21 | - It could serve as starting point for making more convenient analyzer to suit developer's need.
22 |
23 | It was created with the help of
24 | - [Roslyn Analyzers and how to use them with Unity][3] (This article also show more practical examples on how to use analyzer to enforce coding style)
25 | - [Writing a Roslyn analyzer][4]
26 | - [How to write a Roslyn Analyzer][5]
27 |
28 | Repo was created by inspration from discussion of https://stackoverflow.com/questions/67820221 (Thanks everyone!)
29 |
30 | (I always got dupe hammer in SO whenever I started a new question, this time it was not too bad, I guess)
31 |
32 | [3]: https://arztsamuel.github.io/en/blogs/2019/Roslyn-Analyzers-and-Unity.html
33 | [4]: https://www.meziantou.net/writing-a-roslyn-analyzer.htm
34 | [5]: https://devblogs.microsoft.com/dotnet/how-to-write-a-roslyn-analyzer/
35 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/EnumeratorCallAnalyzer.Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.0
5 |
6 | true
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpCodeRefactoringVerifier`1.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CodeRefactorings;
2 | using Microsoft.CodeAnalysis.Testing;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace EnumeratorCallAnalyzer.Test
7 | {
8 | public static partial class CSharpCodeRefactoringVerifier
9 | where TCodeRefactoring : CodeRefactoringProvider, new()
10 | {
11 | ///
12 | public static async Task VerifyRefactoringAsync( string source, string fixedSource )
13 | {
14 | await VerifyRefactoringAsync( source, DiagnosticResult.EmptyDiagnosticResults, fixedSource );
15 | }
16 |
17 | ///
18 | public static async Task VerifyRefactoringAsync( string source, DiagnosticResult expected, string fixedSource )
19 | {
20 | await VerifyRefactoringAsync( source, new[] { expected }, fixedSource );
21 | }
22 |
23 | ///
24 | public static async Task VerifyRefactoringAsync( string source, DiagnosticResult[] expected, string fixedSource )
25 | {
26 | var test = new Test
27 | {
28 | TestCode = source,
29 | FixedCode = fixedSource,
30 | };
31 |
32 | test.ExpectedDiagnostics.AddRange( expected );
33 | await test.RunAsync( CancellationToken.None );
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/VisualBasicCodeRefactoringVerifier`1.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.CodeRefactorings;
2 | using Microsoft.CodeAnalysis.Testing;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace EnumeratorCallAnalyzer.Test
7 | {
8 | public static partial class VisualBasicCodeRefactoringVerifier
9 | where TCodeRefactoring : CodeRefactoringProvider, new()
10 | {
11 | ///
12 | public static async Task VerifyRefactoringAsync( string source, string fixedSource )
13 | {
14 | await VerifyRefactoringAsync( source, DiagnosticResult.EmptyDiagnosticResults, fixedSource );
15 | }
16 |
17 | ///
18 | public static async Task VerifyRefactoringAsync( string source, DiagnosticResult expected, string fixedSource )
19 | {
20 | await VerifyRefactoringAsync( source, new[] { expected }, fixedSource );
21 | }
22 |
23 | ///
24 | public static async Task VerifyRefactoringAsync( string source, DiagnosticResult[] expected, string fixedSource )
25 | {
26 | var test = new Test
27 | {
28 | TestCode = source,
29 | FixedCode = fixedSource,
30 | };
31 |
32 | test.ExpectedDiagnostics.AddRange( expected );
33 | await test.RunAsync( CancellationToken.None );
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpVerifierHelper.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CSharp;
3 | using System;
4 | using System.Collections.Immutable;
5 |
6 | namespace EnumeratorCallAnalyzer.Test
7 | {
8 | internal static class CSharpVerifierHelper
9 | {
10 | ///
11 | /// By default, the compiler reports diagnostics for nullable reference types at
12 | /// , and the analyzer test framework defaults to only validating
13 | /// diagnostics at . This map contains all compiler diagnostic IDs
14 | /// related to nullability mapped to , which is then used to enable all
15 | /// of these warnings for default validation during analyzer and code fix tests.
16 | ///
17 | internal static ImmutableDictionary NullableWarnings { get; } = GetNullableWarningsFromCompiler( );
18 |
19 | private static ImmutableDictionary GetNullableWarningsFromCompiler( )
20 | {
21 | string[] args = { "/warnaserror:nullable" };
22 | var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory);
23 | var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions;
24 |
25 | // Workaround for https://github.com/dotnet/roslyn/issues/41610
26 | nullableWarnings = nullableWarnings
27 | .SetItem( "CS8632", ReportDiagnostic.Error )
28 | .SetItem( "CS8669", ReportDiagnostic.Error );
29 |
30 | return nullableWarnings;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpAnalyzerVerifier`1.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CSharp.Testing;
3 | using Microsoft.CodeAnalysis.Diagnostics;
4 | using Microsoft.CodeAnalysis.Testing;
5 | using Microsoft.CodeAnalysis.Testing.Verifiers;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace EnumeratorCallAnalyzer.Test
10 | {
11 | public static partial class CSharpAnalyzerVerifier
12 | where TAnalyzer : DiagnosticAnalyzer, new()
13 | {
14 | ///
15 | public static DiagnosticResult Diagnostic( )
16 | => CSharpAnalyzerVerifier.Diagnostic( );
17 |
18 | ///
19 | public static DiagnosticResult Diagnostic( string diagnosticId )
20 | => CSharpAnalyzerVerifier.Diagnostic( diagnosticId );
21 |
22 | ///
23 | public static DiagnosticResult Diagnostic( DiagnosticDescriptor descriptor )
24 | => CSharpAnalyzerVerifier.Diagnostic( descriptor );
25 |
26 | ///
27 | public static async Task VerifyAnalyzerAsync( string source, params DiagnosticResult[] expected )
28 | {
29 | var test = new Test
30 | {
31 | TestCode = source,
32 | };
33 |
34 | test.ExpectedDiagnostics.AddRange( expected );
35 | await test.RunAsync( CancellationToken.None );
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/VisualBasicAnalyzerVerifier`1.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.Diagnostics;
3 | using Microsoft.CodeAnalysis.Testing;
4 | using Microsoft.CodeAnalysis.Testing.Verifiers;
5 | using Microsoft.CodeAnalysis.VisualBasic.Testing;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace EnumeratorCallAnalyzer.Test
10 | {
11 | public static partial class VisualBasicAnalyzerVerifier
12 | where TAnalyzer : DiagnosticAnalyzer, new()
13 | {
14 | ///
15 | public static DiagnosticResult Diagnostic( )
16 | => VisualBasicAnalyzerVerifier.Diagnostic( );
17 |
18 | ///
19 | public static DiagnosticResult Diagnostic( string diagnosticId )
20 | => VisualBasicAnalyzerVerifier.Diagnostic( diagnosticId );
21 |
22 | ///
23 | public static DiagnosticResult Diagnostic( DiagnosticDescriptor descriptor )
24 | => VisualBasicAnalyzerVerifier.Diagnostic( descriptor );
25 |
26 | ///
27 | public static async Task VerifyAnalyzerAsync( string source, params DiagnosticResult[] expected )
28 | {
29 | var test = new Test
30 | {
31 | TestCode = source,
32 | };
33 |
34 | test.ExpectedDiagnostics.AddRange( expected );
35 | await test.RunAsync( CancellationToken.None );
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Vsix/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | EnumeratorCallAnalyzer
6 | This is a sample diagnostic extension for the .NET Compiler Platform ("Roslyn").
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Vsix/EnumeratorCallAnalyzer.Vsix.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | net472
7 | EnumeratorCallAnalyzer.Vsix
8 | EnumeratorCallAnalyzer.Vsix
9 |
10 |
11 |
12 | false
13 | false
14 | false
15 | false
16 | false
17 | false
18 | Roslyn
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Program
27 | $(DevEnvDir)devenv.exe
28 | /rootsuffix $(VSSDKTargetPlatformRegRootSuffix)
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Package/EnumeratorCallAnalyzer.Package.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | false
6 | true
7 | true
8 |
9 |
10 |
11 | EnumeratorCallAnalyzer
12 | 1.0.0.0
13 | Wappen
14 | http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE
15 | http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE
16 | http://ICON_URL_HERE_OR_DELETE_THIS_LINE
17 | http://REPOSITORY_URL_HERE_OR_DELETE_THIS_LINE
18 | false
19 | EnumeratorCallAnalyzer
20 | Summary of changes made in this release of the package.
21 | Copyright
22 | EnumeratorCallAnalyzer, analyzers
23 | true
24 |
25 | $(TargetsForTfmSpecificContentInPackage);_AddAnalyzersToOutput
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/EnumeratorCallAnalyzerUnitTests.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis.Testing;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using System.Threading.Tasks;
4 | using VerifyCS = EnumeratorCallAnalyzer.Test.CSharpCodeFixVerifier<
5 | EnumeratorCallAnalyzer.EnumeratorCallAnalyzerAnalyzer,
6 | EnumeratorCallAnalyzer.EnumeratorCallAnalyzerCodeFixProvider>;
7 |
8 | namespace EnumeratorCallAnalyzer.Test
9 | {
10 | [TestClass]
11 | public class EnumeratorCallAnalyzerUnitTest
12 | {
13 | const string BadCase = @"
14 | using System;
15 | using System.Collections;
16 | public class Test
17 | {
18 | IEnumerator CallingSite()
19 | {
20 | // Comment before
21 | [|Coroutine();|] // Comment after
22 | yield return null;
23 | }
24 |
25 | IEnumerator Coroutine()
26 | {
27 | yield return null;
28 | }
29 | }";
30 |
31 | //No diagnostics expected to show up
32 | [TestMethod]
33 | public async Task BareCase_Diagnostic( )
34 | {
35 | await VerifyCS.VerifyAnalyzerAsync( BadCase );
36 | }
37 |
38 | [TestMethod]
39 | public async Task GoodCase_NoDiagnostic( )
40 | {
41 | var test = @"
42 | using System;
43 | using System.Collections;
44 | public class Test
45 | {
46 | IEnumerator CallingSite()
47 | {
48 | // Good calls
49 | yield return Coroutine();
50 | var generator = Coroutine();
51 | }
52 |
53 | IEnumerator Coroutine()
54 | {
55 | yield return null;
56 | }
57 | }";
58 | await VerifyCS.VerifyAnalyzerAsync( test );
59 | }
60 |
61 | //Diagnostic and CodeFix both triggered and checked for
62 | [TestMethod]
63 | public async Task CodeFixText( )
64 | {
65 | var expectedFix = @"
66 | using System;
67 | using System.Collections;
68 | public class Test
69 | {
70 | IEnumerator CallingSite()
71 | {
72 | // Comment before
73 | yield return Coroutine(); // Comment after
74 | yield return null;
75 | }
76 |
77 | IEnumerator Coroutine()
78 | {
79 | yield return null;
80 | }
81 | }";
82 |
83 | await VerifyCS.VerifyCodeFixAsync( BadCase, expectedFix );
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/CSharpCodeFixVerifier`2.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CodeFixes;
3 | using Microsoft.CodeAnalysis.CSharp.Testing;
4 | using Microsoft.CodeAnalysis.Diagnostics;
5 | using Microsoft.CodeAnalysis.Testing;
6 | using Microsoft.CodeAnalysis.Testing.Verifiers;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace EnumeratorCallAnalyzer.Test
11 | {
12 | public static partial class CSharpCodeFixVerifier
13 | where TAnalyzer : DiagnosticAnalyzer, new()
14 | where TCodeFix : CodeFixProvider, new()
15 | {
16 | ///
17 | public static DiagnosticResult Diagnostic( )
18 | => CSharpCodeFixVerifier.Diagnostic( );
19 |
20 | ///
21 | public static DiagnosticResult Diagnostic( string diagnosticId )
22 | => CSharpCodeFixVerifier.Diagnostic( diagnosticId );
23 |
24 | ///
25 | public static DiagnosticResult Diagnostic( DiagnosticDescriptor descriptor )
26 | => CSharpCodeFixVerifier.Diagnostic( descriptor );
27 |
28 | ///
29 | public static async Task VerifyAnalyzerAsync( string source, params DiagnosticResult[] expected )
30 | {
31 | var test = new Test
32 | {
33 | TestCode = source,
34 | };
35 |
36 | test.ExpectedDiagnostics.AddRange( expected );
37 | await test.RunAsync( CancellationToken.None );
38 | }
39 |
40 | ///
41 | public static async Task VerifyCodeFixAsync( string source, string fixedSource )
42 | => await VerifyCodeFixAsync( source, DiagnosticResult.EmptyDiagnosticResults, fixedSource );
43 |
44 | ///
45 | public static async Task VerifyCodeFixAsync( string source, DiagnosticResult expected, string fixedSource )
46 | => await VerifyCodeFixAsync( source, new[] { expected }, fixedSource );
47 |
48 | ///
49 | public static async Task VerifyCodeFixAsync( string source, DiagnosticResult[] expected, string fixedSource )
50 | {
51 | var test = new Test
52 | {
53 | TestCode = source,
54 | FixedCode = fixedSource,
55 | };
56 |
57 | test.ExpectedDiagnostics.AddRange( expected );
58 | await test.RunAsync( CancellationToken.None );
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Test/Verifiers/VisualBasicCodeFixVerifier`2.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CodeFixes;
3 | using Microsoft.CodeAnalysis.Diagnostics;
4 | using Microsoft.CodeAnalysis.Testing;
5 | using Microsoft.CodeAnalysis.Testing.Verifiers;
6 | using Microsoft.CodeAnalysis.VisualBasic.Testing;
7 | using System.Threading;
8 | using System.Threading.Tasks;
9 |
10 | namespace EnumeratorCallAnalyzer.Test
11 | {
12 | public static partial class VisualBasicCodeFixVerifier
13 | where TAnalyzer : DiagnosticAnalyzer, new()
14 | where TCodeFix : CodeFixProvider, new()
15 | {
16 | ///
17 | public static DiagnosticResult Diagnostic( )
18 | => VisualBasicCodeFixVerifier.Diagnostic( );
19 |
20 | ///
21 | public static DiagnosticResult Diagnostic( string diagnosticId )
22 | => VisualBasicCodeFixVerifier.Diagnostic( diagnosticId );
23 |
24 | ///
25 | public static DiagnosticResult Diagnostic( DiagnosticDescriptor descriptor )
26 | => VisualBasicCodeFixVerifier.Diagnostic( descriptor );
27 |
28 | ///
29 | public static async Task VerifyAnalyzerAsync( string source, params DiagnosticResult[] expected )
30 | {
31 | var test = new Test
32 | {
33 | TestCode = source,
34 | };
35 |
36 | test.ExpectedDiagnostics.AddRange( expected );
37 | await test.RunAsync( CancellationToken.None );
38 | }
39 |
40 | ///
41 | public static async Task VerifyCodeFixAsync( string source, string fixedSource )
42 | => await VerifyCodeFixAsync( source, DiagnosticResult.EmptyDiagnosticResults, fixedSource );
43 |
44 | ///
45 | public static async Task VerifyCodeFixAsync( string source, DiagnosticResult expected, string fixedSource )
46 | => await VerifyCodeFixAsync( source, new[] { expected }, fixedSource );
47 |
48 | ///
49 | public static async Task VerifyCodeFixAsync( string source, DiagnosticResult[] expected, string fixedSource )
50 | {
51 | var test = new Test
52 | {
53 | TestCode = source,
54 | FixedCode = fixedSource,
55 | };
56 |
57 | test.ExpectedDiagnostics.AddRange( expected );
58 | await test.RunAsync( CancellationToken.None );
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.CodeFixes/CodeFixResources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EnumeratorCallAnalyzer {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class CodeFixResources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal CodeFixResources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EnumeratorCallAnalyzer.CodeFixResources", typeof(CodeFixResources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Insert yield return.
65 | ///
66 | internal static string CodeFixTitle {
67 | get {
68 | return ResourceManager.GetString("CodeFixTitle", resourceCulture);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31205.134
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnumeratorCallAnalyzer", "EnumeratorCallAnalyzer\EnumeratorCallAnalyzer\EnumeratorCallAnalyzer.csproj", "{F54196DF-CCAC-4FE2-9027-6C5F5B18F8DE}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnumeratorCallAnalyzer.CodeFixes", "EnumeratorCallAnalyzer\EnumeratorCallAnalyzer.CodeFixes\EnumeratorCallAnalyzer.CodeFixes.csproj", "{915E9239-B3D1-4930-99EC-AC7200D00C91}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnumeratorCallAnalyzer.Package", "EnumeratorCallAnalyzer\EnumeratorCallAnalyzer.Package\EnumeratorCallAnalyzer.Package.csproj", "{74D94A8D-3551-4E10-9B0B-590D86B410A6}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnumeratorCallAnalyzer.Test", "EnumeratorCallAnalyzer\EnumeratorCallAnalyzer.Test\EnumeratorCallAnalyzer.Test.csproj", "{EE083175-37C3-4746-8C6A-69FC0D29314A}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnumeratorCallAnalyzer.Vsix", "EnumeratorCallAnalyzer\EnumeratorCallAnalyzer.Vsix\EnumeratorCallAnalyzer.Vsix.csproj", "{7AC5FA1A-82DB-485B-8A14-5BA56192E138}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|Any CPU = Debug|Any CPU
19 | Release|Any CPU = Release|Any CPU
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {F54196DF-CCAC-4FE2-9027-6C5F5B18F8DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {F54196DF-CCAC-4FE2-9027-6C5F5B18F8DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {F54196DF-CCAC-4FE2-9027-6C5F5B18F8DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {F54196DF-CCAC-4FE2-9027-6C5F5B18F8DE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {915E9239-B3D1-4930-99EC-AC7200D00C91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {915E9239-B3D1-4930-99EC-AC7200D00C91}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {915E9239-B3D1-4930-99EC-AC7200D00C91}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {915E9239-B3D1-4930-99EC-AC7200D00C91}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {74D94A8D-3551-4E10-9B0B-590D86B410A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {74D94A8D-3551-4E10-9B0B-590D86B410A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {74D94A8D-3551-4E10-9B0B-590D86B410A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {74D94A8D-3551-4E10-9B0B-590D86B410A6}.Release|Any CPU.Build.0 = Release|Any CPU
34 | {EE083175-37C3-4746-8C6A-69FC0D29314A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 | {EE083175-37C3-4746-8C6A-69FC0D29314A}.Debug|Any CPU.Build.0 = Debug|Any CPU
36 | {EE083175-37C3-4746-8C6A-69FC0D29314A}.Release|Any CPU.ActiveCfg = Release|Any CPU
37 | {EE083175-37C3-4746-8C6A-69FC0D29314A}.Release|Any CPU.Build.0 = Release|Any CPU
38 | {7AC5FA1A-82DB-485B-8A14-5BA56192E138}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
39 | {7AC5FA1A-82DB-485B-8A14-5BA56192E138}.Debug|Any CPU.Build.0 = Debug|Any CPU
40 | {7AC5FA1A-82DB-485B-8A14-5BA56192E138}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 | {7AC5FA1A-82DB-485B-8A14-5BA56192E138}.Release|Any CPU.Build.0 = Release|Any CPU
42 | EndGlobalSection
43 | GlobalSection(SolutionProperties) = preSolution
44 | HideSolutionNode = FALSE
45 | EndGlobalSection
46 | GlobalSection(ExtensibilityGlobals) = postSolution
47 | SolutionGuid = {BA451AF2-0A31-46FE-A699-3941663BF6EA}
48 | EndGlobalSection
49 | EndGlobal
50 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer/EnumeratorCallAnalyzerAnalyzer.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CSharp;
3 | using Microsoft.CodeAnalysis.CSharp.Syntax;
4 | using Microsoft.CodeAnalysis.Diagnostics;
5 | using System;
6 | using System.Collections;
7 | using System.Collections.Generic;
8 | using System.Collections.Immutable;
9 | using System.Linq;
10 | using System.Threading;
11 |
12 | namespace EnumeratorCallAnalyzer
13 | {
14 | [DiagnosticAnalyzer( LanguageNames.CSharp )]
15 | public class EnumeratorCallAnalyzerAnalyzer : DiagnosticAnalyzer
16 | {
17 | public const string DiagnosticId = "EnumeratorCallAnalyzer";
18 |
19 | private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.AnalyzerTitle), Resources.ResourceManager, typeof(Resources));
20 | private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.AnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
21 | private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.AnalyzerDescription), Resources.ResourceManager, typeof(Resources));
22 | private const string Category = "Usage";
23 |
24 | private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
25 |
26 | public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create( Rule ); } }
27 |
28 | public override void Initialize( AnalysisContext context )
29 | {
30 | context.EnableConcurrentExecution( );
31 | context.ConfigureGeneratedCodeAnalysis( GeneratedCodeAnalysisFlags.Analyze|GeneratedCodeAnalysisFlags.ReportDiagnostics );
32 |
33 | // The AnalyzeNode method will be called for each InvocationExpression of the Syntax tree
34 | context.RegisterSyntaxNodeAction( _CheckCoroutineCall, SyntaxKind.InvocationExpression );
35 | }
36 |
37 | private void _CheckCoroutineCall( SyntaxNodeAnalysisContext context )
38 | {
39 | var fcall = (InvocationExpressionSyntax)context.Node;
40 |
41 | // Filter only bare function call
42 | // like: Coroutine( );
43 | // not: yield return Coroutine( );
44 | // not: var generator = Coroutine( );
45 | var parent = fcall.Parent;
46 |
47 | // The bare call will only have
48 | // - ExpressionStatementSyntax
49 | // - InvocationExpressionSyntax
50 | // - SemicolonToken
51 | bool isBareCall = (parent is ExpressionStatementSyntax) && parent.ChildNodes( ).Count( ) == 1;
52 | if( !isBareCall )
53 | return; // Skip, it is not bare
54 |
55 | // Check if function has returning type of something based off IEnumerator
56 | var invokedMethod = context.SemanticModel.GetSymbolInfo( fcall ).Symbol as IMethodSymbol; // Since this is in InvocationExpressionSyntax, it is pretty sure a IMethodSymbol
57 | if( invokedMethod == null )
58 | return;
59 |
60 | // Lucky that IEnumerator can be checked with SpecialType.System_Collections_IEnumerator. No crazy type crawling here.
61 | if( invokedMethod.ReturnType.SpecialType == SpecialType.System_Collections_IEnumerator )
62 | {
63 | var diagnostic = Diagnostic.Create(Rule, fcall.Parent.GetLocation(), invokedMethod.Name ); // messageArg will fill the '{0}' part in analyzer format
64 | context.ReportDiagnostic( diagnostic );
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.CodeFixes/EnumeratorCallAnalyzerCodeFixProvider.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.CodeActions;
3 | using Microsoft.CodeAnalysis.CodeFixes;
4 | using Microsoft.CodeAnalysis.CSharp;
5 | using Microsoft.CodeAnalysis.CSharp.Syntax;
6 | using Microsoft.CodeAnalysis.Formatting;
7 | using Microsoft.CodeAnalysis.Rename;
8 | using Microsoft.CodeAnalysis.Text;
9 | using System;
10 | using System.Collections.Generic;
11 | using System.Collections.Immutable;
12 | using System.Composition;
13 | using System.Linq;
14 | using System.Threading;
15 | using System.Threading.Tasks;
16 |
17 | namespace EnumeratorCallAnalyzer
18 | {
19 | [ExportCodeFixProvider( LanguageNames.CSharp, Name = nameof( EnumeratorCallAnalyzerCodeFixProvider ) ), Shared]
20 | public class EnumeratorCallAnalyzerCodeFixProvider : CodeFixProvider
21 | {
22 | public sealed override ImmutableArray FixableDiagnosticIds
23 | {
24 | get { return ImmutableArray.Create( EnumeratorCallAnalyzerAnalyzer.DiagnosticId ); }
25 | }
26 |
27 | public sealed override FixAllProvider GetFixAllProvider( )
28 | {
29 | // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers
30 | return WellKnownFixAllProviders.BatchFixer;
31 | }
32 |
33 | public sealed override async Task RegisterCodeFixesAsync( CodeFixContext context )
34 | {
35 | var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
36 |
37 | var diagnostic = context.Diagnostics.First();
38 | var diagnosticSpan = diagnostic.Location.SourceSpan;
39 |
40 | // Find the type declaration identified by the diagnostic.
41 | var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First();
42 |
43 | // Register a code action that will invoke the fix.
44 | context.RegisterCodeFix(
45 | CodeAction.Create(
46 | title: CodeFixResources.CodeFixTitle,
47 | createChangedDocument: c => PrependYieldReturnAsync( context.Document, root, declaration, c ),
48 | equivalenceKey: nameof( CodeFixResources.CodeFixTitle ) ),
49 | diagnostic );
50 | }
51 |
52 | private Task PrependYieldReturnAsync( Document document, SyntaxNode root, InvocationExpressionSyntax invocationExpr, CancellationToken cancellationToken )
53 | {
54 | // document in this context is what code span reported from analyzer
55 | // It would be 'StatementSyntax' level on top of InvocationExpressionSyntax
56 |
57 | // From:
58 | // Coroutine( );
59 | // - ExpressionStatementSyntax <- replacingPart
60 | // - InvocationExpressionSyntax <- invocationExpr
61 | // - SemicolonToken
62 |
63 | // We want:
64 | // yield return Coroutine( );
65 | // - YieldReturnStatementSyntax
66 | // - InvocationExpressionSyntax <- invocationExpr
67 | // - SemicolonToken
68 |
69 | var replacingPart = invocationExpr.Parent;
70 |
71 | YieldStatementSyntax yieldRoot = SyntaxFactory.YieldStatement( SyntaxKind.YieldReturnStatement, invocationExpr.WithoutTrivia( ) )
72 | .WithLeadingTrivia( invocationExpr.GetLeadingTrivia( ) ) // These are required to retain leading/trailing comments
73 | .WithTrailingTrivia( replacingPart.GetTrailingTrivia( ) );
74 |
75 | yieldRoot = yieldRoot.WithAdditionalAnnotations( Formatter.Annotation );
76 | var newRoot = root.ReplaceNode( replacingPart, yieldRoot ); // Finally substitution
77 | return Task.FromResult( document.WithSyntaxRoot( newRoot ) );
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace EnumeratorCallAnalyzer {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("EnumeratorCallAnalyzer.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Enumerator function call should use with yield return.
65 | ///
66 | internal static string AnalyzerDescription {
67 | get {
68 | return ResourceManager.GetString("AnalyzerDescription", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to Enumerator function '{0}' should use with yield return.
74 | ///
75 | internal static string AnalyzerMessageFormat {
76 | get {
77 | return ResourceManager.GetString("AnalyzerMessageFormat", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to Enumerator function call check.
83 | ///
84 | internal static string AnalyzerTitle {
85 | get {
86 | return ResourceManager.GetString("AnalyzerTitle", resourceCulture);
87 | }
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.CodeFixes/CodeFixResources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Insert yield return
122 | The title of the code fix.
123 |
124 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Enumerator function call should use with yield return
122 | An optional longer localizable description of the diagnostic.
123 |
124 |
125 | Enumerator function '{0}' should use with yield return
126 | The format-able message the diagnostic displays.
127 |
128 |
129 | Enumerator function call check
130 | The title of the diagnostic.
131 |
132 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Package/tools/install.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | if($project.Object.SupportsPackageDependencyResolution)
4 | {
5 | if($project.Object.SupportsPackageDependencyResolution())
6 | {
7 | # Do not install analyzers via install.ps1, instead let the project system handle it.
8 | return
9 | }
10 | }
11 |
12 | $analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve
13 |
14 | foreach($analyzersPath in $analyzersPaths)
15 | {
16 | if (Test-Path $analyzersPath)
17 | {
18 | # Install the language agnostic analyzers.
19 | foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll)
20 | {
21 | if($project.Object.AnalyzerReferences)
22 | {
23 | $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
24 | }
25 | }
26 | }
27 | }
28 |
29 | # $project.Type gives the language name like (C# or VB.NET)
30 | $languageFolder = ""
31 | if($project.Type -eq "C#")
32 | {
33 | $languageFolder = "cs"
34 | }
35 | if($project.Type -eq "VB.NET")
36 | {
37 | $languageFolder = "vb"
38 | }
39 | if($languageFolder -eq "")
40 | {
41 | return
42 | }
43 |
44 | foreach($analyzersPath in $analyzersPaths)
45 | {
46 | # Install language specific analyzers.
47 | $languageAnalyzersPath = join-path $analyzersPath $languageFolder
48 | if (Test-Path $languageAnalyzersPath)
49 | {
50 | foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll)
51 | {
52 | if($project.Object.AnalyzerReferences)
53 | {
54 | $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName)
55 | }
56 | }
57 | }
58 | }
59 | # SIG # Begin signature block
60 | # MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor
61 | # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
62 | # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA/i+qRUHsWzI0s
63 | # FVk99zLgt/HOEQ33uvkFsWtHTHZgf6CCDYEwggX/MIID56ADAgECAhMzAAABh3IX
64 | # chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
65 | # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
66 | # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
67 | # bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw
68 | # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
69 | # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
70 | # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
71 | # AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB
72 | # znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH
73 | # sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d
74 | # weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ
75 | # itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV
76 | # Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
77 | # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw
78 | # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
79 | # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu
80 | # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
81 | # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
82 | # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
83 | # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
84 | # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy
85 | # S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K
86 | # NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV
87 | # BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr
88 | # qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx
89 | # zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe
90 | # yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g
91 | # yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf
92 | # AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI
93 | # 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5
94 | # GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea
95 | # jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS
96 | # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
97 | # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
98 | # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
99 | # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
100 | # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
101 | # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
102 | # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
103 | # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
104 | # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
105 | # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
106 | # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
107 | # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
108 | # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
109 | # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
110 | # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
111 | # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
112 | # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
113 | # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
114 | # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
115 | # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
116 | # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
117 | # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
118 | # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
119 | # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
120 | # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
121 | # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
122 | # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
123 | # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
124 | # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
125 | # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
126 | # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
127 | # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
128 | # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
129 | # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
130 | # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
131 | # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
132 | # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
133 | # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
134 | # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
135 | # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG
136 | # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
137 | # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
138 | # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
139 | # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
140 | # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgRjg7DcI6
141 | # uhYfXWwAQ6hK0mPW7iyr2tzHR0DHSDJkscIwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
142 | # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
143 | # BgkqhkiG9w0BAQEFAASCAQCMjRK3YvDB0Sy30hadcXmGkSLrq7U7R+bkBh+FsWz8
144 | # CLSdV9Sh1z6mmVlEk6jHf7h3fiMEZwXGSvBEH4dc+equuU9KhYkhfTTfd3SSCER6
145 | # swWv/vqzQgz7WZOzuDuOrMc4lqCc3qUeLCeFnZEjfDKgymUi7UaTDofM0HNZtYA1
146 | # f2kLORo2CzvvZLHK+xQYvefFFrCsHSiNFvH5zM9142c1aMpGVgyuB6cBxL3johS/
147 | # 7i4myLHr9LB7GcSmEYqDH5q4mxgNNtunYqEyK0V0b/UI0b9q1p50KJPag9zh/HB0
148 | # Q+fY1t8guPwGoxkO+hqDV6k1R3tJBHG5c8kDSCVR/CbVoYIS8TCCEu0GCisGAQQB
149 | # gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME
150 | # AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
151 | # MDEwDQYJYIZIAWUDBAIBBQAEIHQWatv8aXHB68pc0SETnr9LF64Haou9lbLES5Og
152 | # 6ES0AgZgDz5A4W0YEzIwMjEwMTI4MTM1MzExLjc1N1owBIACAfSggdSkgdEwgc4x
153 | # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
154 | # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p
155 | # Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg
156 | # VFNTIEVTTjo2MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
157 | # U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABJt+6SyK5goIHAAAA
158 | # AAEmMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
159 | # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
160 | # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
161 | # MB4XDTE5MTIxOTAxMTQ1OVoXDTIxMDMxNzAxMTQ1OVowgc4xCzAJBgNVBAYTAlVT
162 | # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
163 | # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy
164 | # YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2MEJD
165 | # LUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
166 | # ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ4wvoacTvMNlXQTtfF/
167 | # Cx5Ol3X0fcjUNMvjLgTmO5+WHYJFbp725P3+qvFKDRQHWEI1Sz0gB24urVDIjXjB
168 | # h5NVNJVMQJI2tltv7M4/4IbhZJb3xzQW7LolEoZYUZanBTUuyly9osCg4o5joViT
169 | # 2GtmyxK+Fv5kC20l2opeaeptd/E7ceDAFRM87hiNCsK/KHyC+8+swnlg4gTOey6z
170 | # QqhzgNsG6HrjLBuDtDs9izAMwS2yWT0T52QA9h3Q+B1C9ps2fMKMe+DHpG+0c61D
171 | # 94Yh6cV2XHib4SBCnwIFZAeZE2UJ4qPANSYozI8PH+E5rCT3SVqYvHou97HsXvP2
172 | # I3MCAwEAAaOCARswggEXMB0GA1UdDgQWBBRJq6wfF7B+mEKN0VimX8ajNA5hQTAf
173 | # BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH
174 | # hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU
175 | # aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
176 | # BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0
177 | # YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG
178 | # AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBAlvudaOlv9Cfzv56bnX41czF6tLtH
179 | # LB46l6XUch+qNN45ZmOTFwLot3JjwSrn4oycQ9qTET1TFDYd1QND0LiXmKz9OqBX
180 | # ai6S8XdyCQEZvfL82jIAs9pwsAQ6XvV9jNybPStRgF/sOAM/Deyfmej9Tg9FcRwX
181 | # ank2qgzdZZNb8GoEze7f1orcTF0Q89IUXWIlmwEwQFYF1wjn87N4ZxL9Z/xA2m/R
182 | # 1zizFylWP/mpamCnVfZZLkafFLNUNVmcvc+9gM7vceJs37d3ydabk4wR6ObR34sW
183 | # aLppmyPlsI1Qq5Lu6bJCWoXzYuWpkoK6oEep1gML6SRC3HKVS3UscZhtMIIGcTCC
184 | # BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC
185 | # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
186 | # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv
187 | # b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN
188 | # MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
189 | # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
190 | # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw
191 | # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0
192 | # VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw
193 | # RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe
194 | # dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx
195 | # Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G
196 | # kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA
197 | # AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7
198 | # fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
199 | # AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
200 | # zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
201 | # cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
202 | # KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
203 | # b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g
204 | # AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93
205 | # d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB
206 | # BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA
207 | # bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh
208 | # IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS
209 | # +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK
210 | # kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon
211 | # /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi
212 | # PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/
213 | # fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII
214 | # YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0
215 | # cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a
216 | # KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ
217 | # cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+
218 | # NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT
219 | # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
220 | # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
221 | # cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo2
222 | # MEJDLUUzODMtMjYzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
223 | # dmljZaIjCgEBMAcGBSsOAwIaAxUACmcyOWmZxErpq06B8dy6oMZ6//yggYMwgYCk
224 | # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
225 | # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
226 | # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
227 | # AOO8XzYwIhgPMjAyMTAxMjgwMTUyNTRaGA8yMDIxMDEyOTAxNTI1NFowdzA9Bgor
228 | # BgEEAYRZCgQBMS8wLTAKAgUA47xfNgIBADAKAgEAAgIbLwIB/zAHAgEAAgITKTAK
229 | # AgUA472wtgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB
230 | # AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAC77bUsJUEVTSYlY
231 | # wKFpNKL8dbjlzb8EutPbxa952QSEIxgMUycq0Db9t3QSPfWd919JnobZ+0PCoE2A
232 | # Pu4Os73CDKVzF+bwFgLRnttBccwAsgy7d1pWtQcfyIh9O+l/HislSXsFH5zawEs5
233 | # 9uvH8UtGX1jExKlXKnmQriZYTlTCMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC
234 | # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
235 | # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
236 | # bWUtU3RhbXAgUENBIDIwMTACEzMAAAEm37pLIrmCggcAAAAAASYwDQYJYIZIAWUD
237 | # BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B
238 | # CQQxIgQgfLtPMEgO0BfdMeIvsY3gSnjcAKLOUnkiV89CXQ7fmqkwgfoGCyqGSIb3
239 | # DQEJEAIvMYHqMIHnMIHkMIG9BCA2/c/vnr1ecAzvapOWZ2xGfAkzrkfpGcrvMW07
240 | # CQl1DzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
241 | # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
242 | # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB
243 | # Jt+6SyK5goIHAAAAAAEmMCIEILgdbWcIe050A6mMuy1I+6mT4dgtx0U15aTsUnn0
244 | # tfP4MA0GCSqGSIb3DQEBCwUABIIBAI2O4PAlewLHuXky0KYOlR03qPHYvVDSIZWv
245 | # ydszjrgdE02PX1qWo6ZyiuPuyM+ssKiHImpy/wCt2aQk/PPAOIgJVhyhsyc2N0h/
246 | # Hb1cBDGdpwfDndZquf5pwrqfNm2KM9tk7nDkKa0O0C7VpfOgSdamThZiaOZDJVhp
247 | # A3pTsR1LhA17Wih8bgDRsZRCiEPhrfeWBMb3nMjyox3zg+XL0yFmvfcyOWkn/I3o
248 | # 4jj8KKqJ2SwJTJqRWqNg036ilkaayzpFA2XX55s2cdAmPpVh8VuTRLrKVx00/TXS
249 | # hGHM1fgii3urBBNUn8TSXTcUZFpnb9dWJFbxi0aHcHq8iq0J90g=
250 | # SIG # End signature block
251 |
--------------------------------------------------------------------------------
/EnumeratorCallAnalyzer/EnumeratorCallAnalyzer.Package/tools/uninstall.ps1:
--------------------------------------------------------------------------------
1 | param($installPath, $toolsPath, $package, $project)
2 |
3 | if($project.Object.SupportsPackageDependencyResolution)
4 | {
5 | if($project.Object.SupportsPackageDependencyResolution())
6 | {
7 | # Do not uninstall analyzers via uninstall.ps1, instead let the project system handle it.
8 | return
9 | }
10 | }
11 |
12 | $analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve
13 |
14 | foreach($analyzersPath in $analyzersPaths)
15 | {
16 | # Uninstall the language agnostic analyzers.
17 | if (Test-Path $analyzersPath)
18 | {
19 | foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll)
20 | {
21 | if($project.Object.AnalyzerReferences)
22 | {
23 | $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName)
24 | }
25 | }
26 | }
27 | }
28 |
29 | # $project.Type gives the language name like (C# or VB.NET)
30 | $languageFolder = ""
31 | if($project.Type -eq "C#")
32 | {
33 | $languageFolder = "cs"
34 | }
35 | if($project.Type -eq "VB.NET")
36 | {
37 | $languageFolder = "vb"
38 | }
39 | if($languageFolder -eq "")
40 | {
41 | return
42 | }
43 |
44 | foreach($analyzersPath in $analyzersPaths)
45 | {
46 | # Uninstall language specific analyzers.
47 | $languageAnalyzersPath = join-path $analyzersPath $languageFolder
48 | if (Test-Path $languageAnalyzersPath)
49 | {
50 | foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll)
51 | {
52 | if($project.Object.AnalyzerReferences)
53 | {
54 | try
55 | {
56 | $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName)
57 | }
58 | catch
59 | {
60 |
61 | }
62 | }
63 | }
64 | }
65 | }
66 | # SIG # Begin signature block
67 | # MIIjkgYJKoZIhvcNAQcCoIIjgzCCI38CAQExDzANBglghkgBZQMEAgEFADB5Bgor
68 | # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
69 | # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDC68wb97fg0QGL
70 | # yXrxJhYfmibzcOh8caqC0uZprfczDaCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
71 | # chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
72 | # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
73 | # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
74 | # bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw
75 | # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
76 | # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
77 | # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
78 | # AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB
79 | # znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH
80 | # sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d
81 | # weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ
82 | # itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV
83 | # Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
84 | # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw
85 | # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
86 | # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu
87 | # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
88 | # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
89 | # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
90 | # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
91 | # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy
92 | # S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K
93 | # NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV
94 | # BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr
95 | # qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx
96 | # zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe
97 | # yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g
98 | # yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf
99 | # AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI
100 | # 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5
101 | # GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea
102 | # jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS
103 | # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
104 | # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
105 | # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
106 | # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
107 | # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
108 | # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
109 | # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
110 | # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
111 | # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
112 | # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
113 | # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
114 | # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
115 | # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
116 | # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
117 | # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
118 | # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
119 | # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
120 | # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
121 | # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
122 | # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
123 | # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
124 | # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
125 | # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
126 | # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
127 | # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
128 | # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
129 | # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
130 | # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
131 | # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
132 | # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
133 | # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
134 | # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
135 | # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
136 | # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
137 | # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
138 | # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
139 | # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
140 | # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
141 | # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
142 | # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZzCCFWMCAQEwgZUwfjELMAkG
143 | # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
144 | # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
145 | # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
146 | # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
147 | # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgF1ypFyzl
148 | # AvvWGVCeXczrfpXmJNm9vpyjcwd4y4ivfqowQgYKKwYBBAGCNwIBDDE0MDKgFIAS
149 | # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
150 | # BgkqhkiG9w0BAQEFAASCAQAlvp3kobQ3njGrv7T9mKm8viQ7IsK06yFq43ZwDIob
151 | # rkxRRMZKKJfaJ2pkkTtMun/wzMjQ7hqbULUO22lywwNy3t7uNINETfPReIYNIG9p
152 | # KZ3t8zI1T+7B9Vpm5t9LC9hQp1yrj88LcA1QAaFcvjn1sxUOGlLFK2jsa2AUcrwr
153 | # QpiVDX+OOdExw+EJTUBil/kvAtXHdCT1qkH3JzzSBYiCLGq2pW4AuVvlL0iiRKeT
154 | # /AW6TY9SuOUoG0aOZZzLAuCp6qA7ovKqRAGoFpcAaGXQokWRLU4se3/2meBksksu
155 | # ZlP1paBMHbT1ZLJP095SzhwYfsw7IDkC0Zt1OLq7IdwwoYIS8TCCEu0GCisGAQQB
156 | # gjcDAwExghLdMIIS2QYJKoZIhvcNAQcCoIISyjCCEsYCAQMxDzANBglghkgBZQME
157 | # AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
158 | # MDEwDQYJYIZIAWUDBAIBBQAEIMdwQTCmst1vtKyhKIg+hpE9VQEH7XzRp1eSg9au
159 | # tOz7AgZgEAenLh4YEzIwMjEwMTI4MTM1MzExLjM0N1owBIACAfSggdSkgdEwgc4x
160 | # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
161 | # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p
162 | # Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg
163 | # VFNTIEVTTjo0NjJGLUUzMTktM0YyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
164 | # U3RhbXAgU2VydmljZaCCDkQwggT1MIID3aADAgECAhMzAAABJMvNAqEXcFyaAAAA
165 | # AAEkMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
166 | # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
167 | # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
168 | # MB4XDTE5MTIxOTAxMTQ1N1oXDTIxMDMxNzAxMTQ1N1owgc4xCzAJBgNVBAYTAlVT
169 | # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
170 | # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy
171 | # YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo0NjJG
172 | # LUUzMTktM0YyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
173 | # ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJCbKjgNnhjvMlnRNAtx
174 | # 7X3N5ZZkSfUFULyWsVJ1pnyMsSITimg1q3OQ1Ikf0/3gg8UG5TIRm7wH8sjBtoB3
175 | # nuzFz11CegIFcanYnt050JvnrUTKeAPUR5pLpTeP3QEgL+CWOc4lTg/XxjnQv01F
176 | # D7TTn9DEuO3kp0GQ87Mjd5ssxK0K1q4IWNFAyRpx5n8Vm3Vm1iiVL5FMDUKsl5G/
177 | # SqQdiEDn8cqYbqWMVzWH94PdKdw1mIHToBRCNsR9BHHWzNkSS+R0WRipBSSorKT7
178 | # cuLlEBYhDo8AY3uMGlv0kLRLHASZ+sz2nfkpW2CVt+bHhVmM6/5qiu2f7eYoTYJu
179 | # cFECAwEAAaOCARswggEXMB0GA1UdDgQWBBS7HdFyrGKIhDxvypLA1lD/wGRSsDAf
180 | # BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH
181 | # hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU
182 | # aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
183 | # BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0
184 | # YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG
185 | # AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBo3QzNuNRgzdflwA4U7f3e2CcGlwdg
186 | # 6ii498cBiSrTpWKO3qqz5pvgHAk4hh6y/FLY80R59inLwcVuyD24S3JEdSie4y1t
187 | # C5JptweR1qlxRJCRM4vG7nPtIC4eAMKcXgovu0mTFv7xpFAVpRuvuepR91gIde32
188 | # 8lv1HTTJCV/LBBk83Xi7nCGPF59FxeIrcE32xt4YJgEpEAikeMqvWCTMyPqlmvx9
189 | # J92fxU3cQcw2j2EWwqOD5T3Nz2HWfPV80sihD1A6Y5HhjpS9taDPs7CI58I211F3
190 | # ysegNyOesG3MTrSJHyPMLKYFDxcG1neV0liktv+TW927sUOVczcSUhQLMIIGcTCC
191 | # BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC
192 | # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
193 | # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv
194 | # b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN
195 | # MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
196 | # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
197 | # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw
198 | # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0
199 | # VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw
200 | # RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe
201 | # dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx
202 | # Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G
203 | # kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA
204 | # AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7
205 | # fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
206 | # AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
207 | # zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
208 | # cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
209 | # KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
210 | # b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g
211 | # AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93
212 | # d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB
213 | # BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA
214 | # bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh
215 | # IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS
216 | # +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK
217 | # kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon
218 | # /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi
219 | # PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/
220 | # fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII
221 | # YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0
222 | # cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a
223 | # KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ
224 | # cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+
225 | # NR4Iuto229Nfj950iEkSoYIC0jCCAjsCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT
226 | # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
227 | # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
228 | # cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo0
229 | # NjJGLUUzMTktM0YyMDElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
230 | # dmljZaIjCgEBMAcGBSsOAwIaAxUAlwPlNCq+Un54UfxLe/wKS1Xc4nqggYMwgYCk
231 | # fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
232 | # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
233 | # Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
234 | # AOO9KO8wIhgPMjAyMTAxMjgxNjEzMzVaGA8yMDIxMDEyOTE2MTMzNVowdzA9Bgor
235 | # BgEEAYRZCgQBMS8wLTAKAgUA470o7wIBADAKAgEAAgIdzgIB/zAHAgEAAgITSTAK
236 | # AgUA4756bwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB
237 | # AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAEiUh4QVb7vaceUo
238 | # /TtRAhp98XfrRN5mZ4KyZDuNDYKfBaGx8hnyD2BgIjkQ59KzIVNfkv8PBXhLaQK7
239 | # u7k4S23kUWQ/zsRYm5EutcKXB3zrW4Ym0TpwiMTJ8arMFj3BIYjZCMFqUxdAxiH/
240 | # CD+FIK0vvPSTRZ00KPqi5idqCj3TMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMC
241 | # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
242 | # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
243 | # bWUtU3RhbXAgUENBIDIwMTACEzMAAAEky80CoRdwXJoAAAAAASQwDQYJYIZIAWUD
244 | # BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B
245 | # CQQxIgQgrLzvm34azoh15/K+sBdmMol8NxD/FT4rQfDgBXN/atwwgfoGCyqGSIb3
246 | # DQEJEAIvMYHqMIHnMIHkMIG9BCBiOOHoohqL+X7Xa/25jp1wTrQxYlYGLszis/nA
247 | # TirjIDCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
248 | # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
249 | # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB
250 | # JMvNAqEXcFyaAAAAAAEkMCIEILvfBT5GpMSMrQo5TU1VuEC6URcoooi2maNoHgLo
251 | # yvsvMA0GCSqGSIb3DQEBCwUABIIBAIxWH4gHkyfHcF3w9aW9L1OaBOjv/Zmq7V1R
252 | # pj4tkkyuQKPqIi9gdq4wMxToI1m4IM/9I8FwLI1LH/6AWBLTfdkFr4mOMFyflO5v
253 | # gya84Pij48E/37XOOBG5S454c4Sgj6OQcZb1Ljb+QNf+6JovAhUdLL4ZLmdvuK5X
254 | # amv+cjYVV3jSJYMSx8d0w22rPmJVB25h1NZlJvPKZdKGc28ub2IxnvALF6SYaR5u
255 | # AQVzIzltI+lm1Owqt9JAuuif6YYhh/P4Z4PfXWtY/2xsIqYHbQwizlu/3Hs9UK60
256 | # VE+jyR89LdWrWqCW0orWrNwUFBiYIuupntcRH/1LMk6Tr/CJa64=
257 | # SIG # End signature block
258 |
--------------------------------------------------------------------------------