diff --git a/Directory.Build.props b/Directory.Build.props index f8045abc..3328ec27 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,5 +2,6 @@ true 14.0 + enable \ No newline at end of file diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AsyncVoid.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AsyncVoid.cs index 8bc67541..c30547d3 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AsyncVoid.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AsyncVoid.cs @@ -26,13 +26,21 @@ public sealed override FixAllProvider GetFixAllProvider() public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { - SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + SyntaxNode? root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + if (root is null) + { + return; + } Diagnostic diagnostic = context.Diagnostics.First(); Microsoft.CodeAnalysis.Text.TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; // Find the type declaration identified by the diagnostic. var declaration = root.FindToken(diagnosticSpan.Start).Parent as MethodDeclarationSyntax; + if (declaration is null) + { + return; + } // Register a code action that will invoke the fix. context.RegisterCodeFix( @@ -45,7 +53,8 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) private static async Task MakeReturnTask(Document document, MethodDeclarationSyntax declaration, CancellationToken cancellationToken) { - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) + ?? throw new System.InvalidOperationException("Could not get syntax root"); SyntaxNode newRoot = root.ReplaceNode(declaration.ReturnType, SyntaxFactory.ParseTypeName(typeof(Task).Name).WithTrailingTrivia(SyntaxFactory.Space)); return document.WithSyntaxRoot(newRoot); } diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AttributesOnSeparateLines.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AttributesOnSeparateLines.cs index bbdd2971..ec3548a9 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AttributesOnSeparateLines.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/AttributesOnSeparateLines.cs @@ -29,7 +29,11 @@ public sealed override FixAllProvider GetFixAllProvider() public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { - SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + SyntaxNode? root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + if (root is null) + { + return; + } Diagnostic diagnostic = context.Diagnostics.First(); Microsoft.CodeAnalysis.Text.TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; @@ -38,14 +42,17 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) SyntaxToken declaration = root.FindToken(diagnosticSpan.Start); // Find the enclosing AttributeList - SyntaxNode attributeList = declaration.Parent; - while (!attributeList.IsKind(SyntaxKind.AttributeList)) + SyntaxNode? attributeList = declaration.Parent; + while (attributeList is not null && !attributeList.IsKind(SyntaxKind.AttributeList)) { attributeList = attributeList.Parent; } // Get the class, method or property adjacent to the AttributeList - SyntaxNode parentDeclaration = attributeList.Parent; + if (attributeList?.Parent is not SyntaxNode parentDeclaration) + { + return; + } // Register a code action that will invoke the fix. context.RegisterCodeFix( @@ -78,7 +85,8 @@ private static async Task PutOnSeparateLine(Document document, SyntaxN .WithAdditionalAnnotations(Formatter.Annotation); // Replace the old local declaration with the new local declaration. - SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) + ?? throw new InvalidOperationException("Could not get syntax root"); SyntaxNode newRoot = oldRoot.ReplaceNode(parentDeclaration, newNode); return document.WithSyntaxRoot(newRoot); diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingFieldPascalUnderscore.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingFieldPascalUnderscore.cs index db34911b..691bad77 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingFieldPascalUnderscore.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingFieldPascalUnderscore.cs @@ -27,7 +27,11 @@ public sealed override FixAllProvider GetFixAllProvider() public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { - SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + SyntaxNode? root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + if (root is null) + { + return; + } Diagnostic diagnostic = context.Diagnostics.First(); TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; @@ -50,8 +54,16 @@ private static async Task MakePascalWithUnderscore(Document document, string nameWithoutUnderscore = nameOfField.TrimStart('_'); string newName = "_" + char.ToUpper(nameWithoutUnderscore.First()) + nameWithoutUnderscore.Substring(1); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - ISymbol symbol = semanticModel.GetDeclaredSymbol(declaration.Parent, cancellationToken); + SemanticModel? semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + if (semanticModel is null || declaration.Parent is null) + { + return document.Project.Solution; + } + ISymbol? symbol = semanticModel.GetDeclaredSymbol(declaration.Parent, cancellationToken); + if (symbol is null) + { + return document.Project.Solution; + } Solution solution = document.Project.Solution; SymbolRenameOptions options = new() { diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingIdentifierPascal.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingIdentifierPascal.cs index d1b317fa..85026a4b 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingIdentifierPascal.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.CodeFixes/NamingIdentifierPascal.cs @@ -27,7 +27,11 @@ public sealed override FixAllProvider GetFixAllProvider() public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { - SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + SyntaxNode? root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + if (root is null) + { + return; + } Diagnostic diagnostic = context.Diagnostics.First(); TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; @@ -49,8 +53,16 @@ private static async Task MakePascal(Document document, SyntaxToken de string nameOfField = declaration.ValueText; string newName = char.ToUpper(nameOfField.First()) + nameOfField.Substring(1); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - ISymbol symbol = semanticModel.GetDeclaredSymbol(declaration.Parent, cancellationToken); + SemanticModel? semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + if (semanticModel is null || declaration.Parent is null) + { + return document.Project.Solution; + } + ISymbol? symbol = semanticModel.GetDeclaredSymbol(declaration.Parent, cancellationToken); + if (symbol is null) + { + return document.Project.Solution; + } Solution solution = document.Project.Solution; SymbolRenameOptions options = new() { diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Integration.Tests/AnalyzerTests.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Integration.Tests/AnalyzerTests.cs index 8705f45f..f7b98c28 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Integration.Tests/AnalyzerTests.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Integration.Tests/AnalyzerTests.cs @@ -34,7 +34,9 @@ public static async Task ProcessProject(FileInfo projectFile) using var workspace = MSBuildWorkspace.Create(); Project project = await workspace.OpenProjectAsync(projectFile.FullName).ConfigureAwait(false); - CompilationWithAnalyzers compilationWithAnalyzers = (await project.GetCompilationAsync().ConfigureAwait(false)) + Compilation compilation = await project.GetCompilationAsync().ConfigureAwait(false) + ?? throw new InvalidOperationException("Could not get compilation"); + CompilationWithAnalyzers compilationWithAnalyzers = compilation .WithAnalyzers(ImmutableArray.Create(GetAnalyzers().ToArray())); ImmutableArray diags = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().ConfigureAwait(false); diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs index 3bc42ae9..e2e47dcd 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/CodeFixVerifier.Helper.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -26,7 +27,8 @@ private static async Task ApplyFix(Document document, CodeAction codeA { System.Collections.Immutable.ImmutableArray operations = await codeAction.GetOperationsAsync(CancellationToken.None); Solution solution = operations.OfType().Single().ChangedSolution; - return solution.GetDocument(document.Id); + return solution.GetDocument(document.Id) + ?? throw new InvalidOperationException("Could not get document from solution"); } /// @@ -66,7 +68,8 @@ private static IEnumerable GetNewDiagnostics(IEnumerable /// The compiler diagnostics that were found in the code private static IEnumerable GetCompilerDiagnostics(Document document) { - return document.GetSemanticModelAsync().Result.GetDiagnostics(); + return (document.GetSemanticModelAsync().Result + ?? throw new InvalidOperationException("Could not get semantic model")).GetDiagnostics(); } /// @@ -77,7 +80,8 @@ private static IEnumerable GetCompilerDiagnostics(Document document) private static string GetStringFromDocument(Document document) { Document simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result; - SyntaxNode root = simplifiedDoc.GetSyntaxRootAsync().Result; + SyntaxNode root = simplifiedDoc.GetSyntaxRootAsync().Result + ?? throw new InvalidOperationException("Could not get syntax root"); root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace); return root.GetText().ToString(); } diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs index 555e025c..53f81201 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Helpers/DiagnosticVerifier.Helper.cs @@ -61,7 +61,9 @@ protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyz var diagnostics = new List(); foreach (Project project in projects) { - CompilationWithAnalyzers compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer)); + CompilationWithAnalyzers compilationWithAnalyzers = (project.GetCompilationAsync().Result + ?? throw new InvalidOperationException("Could not get compilation")) + .WithAnalyzers(ImmutableArray.Create(analyzer)); ImmutableArray diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result; foreach (Diagnostic diag in diags) { @@ -74,7 +76,7 @@ protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyz for (int i = 0; i < documents.Length; i++) { Document document = documents[i]; - SyntaxTree tree = document.GetSyntaxTreeAsync().Result; + SyntaxTree? tree = document.GetSyntaxTreeAsync().Result; if (tree == diag.Location.SourceTree) { diagnostics.Add(diag); @@ -173,7 +175,8 @@ private static Project CreateProject(string[] sources, string language = Languag count++; } - return solution.GetProject(projectId); + return solution.GetProject(projectId) + ?? throw new InvalidOperationException("Could not get project from solution"); } #endregion } diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/CodeFixVerifier.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/CodeFixVerifier.cs index 253c7b60..0f0b2bdb 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/CodeFixVerifier.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/CodeFixVerifier.cs @@ -22,7 +22,7 @@ public abstract partial class CodeFixVerifier : DiagnosticVerifier /// Returns the codefix being tested (C#) - to be implemented in non-abstract class /// /// The CodeFixProvider to be used for CSharp code - protected virtual CodeFixProvider GetCSharpCodeFixProvider() + protected virtual CodeFixProvider? GetCSharpCodeFixProvider() { return null; } @@ -31,7 +31,7 @@ protected virtual CodeFixProvider GetCSharpCodeFixProvider() /// Returns the codefix being tested (VB) - to be implemented in non-abstract class /// /// The CodeFixProvider to be used for VisualBasic code - protected virtual CodeFixProvider GetBasicCodeFixProvider() + protected virtual CodeFixProvider? GetBasicCodeFixProvider() { return null; } @@ -73,8 +73,10 @@ protected async Task VerifyBasicFix(string oldSource, string newSource, int? cod /// A class in the form of a string after the CodeFix was applied to it /// Index determining which codefix to apply if there are multiple /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied - private static async Task VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) + private static async Task VerifyFix(string language, DiagnosticAnalyzer? analyzer, CodeFixProvider? codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) { + ArgumentNullException.ThrowIfNull(analyzer); + ArgumentNullException.ThrowIfNull(codeFixProvider); Document document = CreateDocument(oldSource, language); Diagnostic[] analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, [document]); IEnumerable compilerDiagnostics = GetCompilerDiagnostics(document); @@ -106,11 +108,11 @@ private static async Task VerifyFix(string language, DiagnosticAnalyzer analyzer if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) { // Format and get the compiler diagnostics again so that the locations make sense in the output - document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace)); + document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result!, Formatter.Annotation, document.Project.Solution.Workspace)); newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)); Assert.Fail($"Fix introduced new compiler diagnostics:{string.Join(Environment.NewLine, newCompilerDiagnostics.Select(d => d.ToString()))}" + - $"{Environment.NewLine}{Environment.NewLine}New document:{Environment.NewLine}{document.GetSyntaxRootAsync().Result.ToFullString()}{Environment.NewLine}"); + $"{Environment.NewLine}{Environment.NewLine}New document:{Environment.NewLine}{document.GetSyntaxRootAsync().Result!.ToFullString()}{Environment.NewLine}"); } //check if there are analyzer diagnostics left after the code fix diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/DiagnosticVerifier.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/DiagnosticVerifier.cs index 134d643f..83f4e4a9 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/DiagnosticVerifier.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer.Test/Verifiers/DiagnosticVerifier.cs @@ -17,7 +17,7 @@ public abstract partial class DiagnosticVerifier /// /// Get the CSharp analyzer being tested - to be implemented in non-abstract class /// - protected virtual DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() + protected virtual DiagnosticAnalyzer? GetCSharpDiagnosticAnalyzer() { return null; } @@ -25,7 +25,7 @@ protected virtual DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() /// /// Get the Visual Basic analyzer being tested (C#) - to be implemented in non-abstract class /// - protected virtual DiagnosticAnalyzer GetBasicDiagnosticAnalyzer() + protected virtual DiagnosticAnalyzer? GetBasicDiagnosticAnalyzer() { return null; } @@ -85,8 +85,9 @@ protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[] /// The language of the classes represented by the source strings /// The analyzer to be run on the source code /// DiagnosticResults that should appear after the analyzer is run on the sources - private static void VerifyDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expected) + private static void VerifyDiagnostics(string[] sources, string language, DiagnosticAnalyzer? analyzer, params DiagnosticResult[] expected) { + ArgumentNullException.ThrowIfNull(analyzer); Diagnostic[] diagnostics = GetSortedDiagnostics(sources, language, analyzer); VerifyDiagnosticResults(diagnostics, analyzer, expected); } @@ -213,7 +214,7 @@ private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diag Assert.IsTrue(location.IsInSource, $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}{Environment.NewLine}"); - string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs", StringComparison.Ordinal) ? "GetCSharpResultAt" : "GetBasicResultAt"; + string resultMethodName = diagnostics[i].Location.SourceTree!.FilePath.EndsWith(".cs", StringComparison.Ordinal) ? "GetCSharpResultAt" : "GetBasicResultAt"; Microsoft.CodeAnalysis.Text.LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition; builder.AppendFormat("{0}({1}, {2}, {3}.{4})", diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer/AnalyzerBlockMixins.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer/AnalyzerBlockMixins.cs index 95554c2b..8bb6a772 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer/AnalyzerBlockMixins.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer/AnalyzerBlockMixins.cs @@ -5,17 +5,17 @@ namespace IntelliTect.Analyzer { public static class AnalyzerBlockMixins { - private static string GetEnumAttributeValue(Enum value, Func valueAccessor) + private static string? GetEnumAttributeValue(Enum value, Func valueAccessor) where TAttribute : Attribute { - FieldInfo fi = value.GetType().GetRuntimeField(value.ToString()); + FieldInfo? fi = value.GetType().GetRuntimeField(value.ToString()); - var attributes = (TAttribute[])fi?.GetCustomAttributes(typeof(TAttribute), false); + TAttribute[]? attributes = (TAttribute[]?)fi?.GetCustomAttributes(typeof(TAttribute), false); return attributes?.Length > 0 ? valueAccessor(attributes[0]) : null; } - public static string GetDescription(this AnalyzerBlock value) + public static string? GetDescription(this AnalyzerBlock value) { if (value == AnalyzerBlock.None) { diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AsyncVoid.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AsyncVoid.cs index 8ed2eb58..ee214227 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AsyncVoid.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AsyncVoid.cs @@ -35,7 +35,10 @@ public override void Initialize(AnalysisContext context) private static void AnalyzeSymbol(SymbolAnalysisContext context) { - var methodSymbol = context.Symbol as IMethodSymbol; + if (context.Symbol is not IMethodSymbol methodSymbol) + { + return; + } if (methodSymbol.IsAsync && methodSymbol.ReturnsVoid) { diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AttributesOnSeparateLines.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AttributesOnSeparateLines.cs index 7a9e6422..61314ec1 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AttributesOnSeparateLines.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/AttributesOnSeparateLines.cs @@ -43,7 +43,11 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context) Dictionary lineDictionary = []; foreach (AttributeData attribute in namedTypeSymbol.GetAttributes()) { - SyntaxReference applicationSyntaxReference = attribute.ApplicationSyntaxReference; + SyntaxReference? applicationSyntaxReference = attribute.ApplicationSyntaxReference; + if (applicationSyntaxReference is null) + { + continue; + } Microsoft.CodeAnalysis.Text.TextSpan textSpan = applicationSyntaxReference.Span; SyntaxTree syntaxTree = applicationSyntaxReference.SyntaxTree; FileLinePositionSpan lineSpan = syntaxTree.GetLineSpan(textSpan); @@ -56,7 +60,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context) if (lineDictionary.ContainsKey(attributeLineNo) || symbolLineNumbers.Contains(attributeLineNo)) { Location location = syntaxTree.GetLocation(textSpan); - Diagnostic diagnostic = Diagnostic.Create(_Rule, location, attribute.AttributeClass.Name); + Diagnostic diagnostic = Diagnostic.Create(_Rule, location, attribute.AttributeClass?.Name); context.ReportDiagnostic(diagnostic); } diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs index 303e11f1..728d3521 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/BanImplicitDateTimeToDateTimeOffsetConversion.cs @@ -42,7 +42,7 @@ private void AnalyzeInvocation(OperationAnalysisContext context) if (conversionOperation.Conversion.IsImplicit && conversionOperation.Conversion.MethodSymbol is object && conversionOperation.Conversion.MethodSymbol.ContainingType is object) { INamedTypeSymbol containingType = conversionOperation.Conversion.MethodSymbol.ContainingType; - INamedTypeSymbol dateTimeOffsetType = context.Compilation.GetTypeByMetadataName("System.DateTimeOffset"); + INamedTypeSymbol? dateTimeOffsetType = context.Compilation.GetTypeByMetadataName("System.DateTimeOffset"); if (SymbolEqualityComparer.Default.Equals(containingType, dateTimeOffsetType)) { context.ReportDiagnostic(Diagnostic.Create(_Rule202, conversionOperation.Syntax.GetLocation())); diff --git a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/UnusedLocalVariable.cs b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/UnusedLocalVariable.cs index dfffffcc..484cc580 100644 --- a/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/UnusedLocalVariable.cs +++ b/IntelliTect.Analyzer/IntelliTect.Analyzer/Analyzers/UnusedLocalVariable.cs @@ -39,7 +39,11 @@ private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) { if (context.Node is MethodDeclarationSyntax method && method.Body != null) { - DataFlowAnalysis dataFlow = context.SemanticModel.AnalyzeDataFlow(method.Body); + DataFlowAnalysis? dataFlow = context.SemanticModel.AnalyzeDataFlow(method.Body); + if (dataFlow is null) + { + return; + } ImmutableArray variablesDeclared = dataFlow.VariablesDeclared; IEnumerable variablesRead = dataFlow.ReadInside.Union(dataFlow.ReadOutside,