From 6c6ee9940b48bb13ebc48e9cba336289a47641af Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sun, 15 Oct 2023 18:17:02 +0200 Subject: [PATCH] Enable nullable reference types (#1198) --- ChangeLog.md | 1 + .../Analysis/UseConditionalAccessAnalyzer.cs | 3 + .../CSharp.Workspaces.csproj | 1 + .../CSharp/CSharpSyntaxFactsService.cs | 6 +- .../CSharp/CSharpTypeFactory.cs | 14 +- .../CodeMetrics/CSharpPhysicalLinesWalker.cs | 2 +- .../CSharp/Extensions/WorkspaceExtensions.cs | 31 ++- .../Extensions/WorkspaceSymbolExtensions.cs | 16 +- .../FindSymbols/CSharpFindSymbolService.cs | 2 +- .../CSharp/FindSymbols/LocalSymbolFinder.cs | 22 +- .../Spelling/CSharpSpellingDiagnostic.cs | 2 +- .../CSharp/Spelling/CSharpSpellingService.cs | 8 +- .../CSharp/Spelling/CSharpSpellingWalker.cs | 4 +- .../CSharp/SyntaxInverter.cs | 2 + .../CSharp/SyntaxLogicalInverter.cs | 29 ++- src/CSharp/CSharp.csproj | 1 + src/CSharp/CSharp/BracesAnalysis.cs | 8 +- src/CSharp/CSharp/CSharpFactory.cs | 36 +-- src/CSharp/CSharp/CSharpNameGenerator.cs | 6 +- .../CSharp/CSharpOverriddenSymbolInfo.cs | 18 +- src/CSharp/CSharp/CSharpTypeAnalysis.cs | 58 +++-- src/CSharp/CSharp/CSharpUtility.cs | 125 ++-------- ...ddBaseOrNewDocumentationCommentRewriter.cs | 2 +- .../AddNewDocumentationCommentRewriter.cs | 36 +-- .../DocumentationCommentGenerator.cs | 106 ++++----- .../DocumentationCommentTriviaFactory.cs | 6 +- .../DocumentationCommentTriviaRewriter.cs | 4 +- .../EnumMemberDeclarationValueComparer.cs | 8 +- src/CSharp/CSharp/ExpressionChain.Reversed.cs | 8 +- src/CSharp/CSharp/ExpressionChain.cs | 8 +- .../CSharp/Extensions/CSharpExtensions.cs | 86 +++---- .../CSharp/Extensions/SymbolExtensions.cs | 20 +- .../CSharp/Extensions/SyntaxExtensions.cs | 214 +++++++++--------- src/CSharp/CSharp/IfStatementCascade.cs | 10 +- src/CSharp/CSharp/IfStatementOrElseClause.cs | 20 +- .../CSharp/MemberDeclarationComparer.cs | 2 +- .../CSharp/MemberDeclarationListSelection.cs | 18 +- src/CSharp/CSharp/MethodChain.cs | 16 +- src/CSharp/CSharp/ModifierList.cs | 14 +- src/CSharp/CSharp/ModifierList`1.cs | 6 +- src/CSharp/CSharp/StatementListSelection.cs | 18 +- src/CSharp/CSharp/StringLiteralParser.cs | 8 +- src/CSharp/CSharp/StringLiteralTextBuilder.cs | 2 +- src/CSharp/CSharp/Syntax/AsExpressionInfo.cs | 6 +- .../CSharp/Syntax/AssignmentExpressionInfo.cs | 6 +- .../CSharp/Syntax/BinaryExpressionInfo.cs | 8 +- .../Syntax/ConditionalExpressionInfo.cs | 10 +- .../CSharp/Syntax/ConditionalStatementInfo.cs | 13 +- src/CSharp/CSharp/Syntax/GenericInfo.cs | 32 ++- .../Syntax/HexNumericLiteralExpressionInfo.cs | 4 +- src/CSharp/CSharp/Syntax/IsExpressionInfo.cs | 6 +- .../Syntax/LocalDeclarationStatementInfo.cs | 13 +- .../Syntax/MemberDeclarationListInfo.cs | 16 +- src/CSharp/CSharp/Syntax/ModifierListInfo.cs | 2 +- .../CSharp/Syntax/NullCheckExpressionInfo.cs | 35 +-- src/CSharp/CSharp/Syntax/ParameterInfo.cs | 55 ++--- src/CSharp/CSharp/Syntax/RegionInfo.cs | 4 +- .../Syntax/SimpleAssignmentExpressionInfo.cs | 6 +- .../Syntax/SimpleAssignmentStatementInfo.cs | 9 +- .../CSharp/Syntax/SimpleIfStatementInfo.cs | 4 +- .../SimpleMemberInvocationExpressionInfo.cs | 11 +- .../SimpleMemberInvocationStatementInfo.cs | 3 +- .../SingleLocalDeclarationStatementInfo.cs | 21 +- .../SingleParameterLambdaExpressionInfo.cs | 10 +- src/CSharp/CSharp/Syntax/StatementListInfo.cs | 20 +- .../StringConcatenationExpressionInfo.cs | 5 +- .../Syntax/StringLiteralExpressionInfo.cs | 2 +- src/CSharp/CSharp/Syntax/SyntaxInfoHelpers.cs | 16 +- .../Syntax/TypeParameterConstraintInfo.cs | 21 +- .../CSharp/Syntax/UsingDirectiveListInfo.cs | 8 +- src/CSharp/CSharp/Syntax/XmlElementInfo.cs | 4 +- src/CSharp/CSharp/SyntaxAccessibility.cs | 8 +- src/CSharp/CSharp/SyntaxAccessibility`1.cs | 4 +- src/CSharp/CSharp/SyntaxDebug.cs | 51 +++-- src/CSharp/CSharp/SyntaxInfo.cs | 4 +- src/CSharp/CSharp/SyntaxRefactorings.cs | 16 +- .../BinaryExpressionToMultiLineRewriter.cs | 6 +- .../CSharp/SyntaxRewriters/RenameRewriter.cs | 4 +- .../SyntaxWalkers/ContainsCommentWalker.cs | 4 +- ...ContainsLocalOrParameterReferenceWalker.cs | 12 +- .../SyntaxWalkers/ContainsYieldWalker.cs | 6 +- .../MethodReferencedAsMethodGroupWalker.cs | 20 +- .../CSharp/SyntaxWalkers/StatementWalker.cs | 6 +- .../CSharp/SyntaxWalkers/TriviaWalker.cs | 13 +- src/CSharp/DetermineParameterHelper.cs | 26 +-- src/CSharp/DetermineParameterTypeHelper.cs | 20 +- .../Commands/FindSymbolsCommand.cs | 13 ++ src/Core/Core.csproj | 1 + src/Core/CreateNameFromTypeSymbolHelper.cs | 10 +- src/Core/DiagnosticIdComparer.cs | 20 +- .../DocumentationCommentGeneratorSettings.cs | 6 +- src/Core/EnumFieldSymbolInfo.cs | 2 +- src/Core/EnumSymbolInfo.cs | 8 +- src/Core/EnumUtility.cs | 10 +- src/Core/ExtensionMethodSymbolInfo.cs | 4 +- src/Core/Extensions/DiagnosticsExtensions.cs | 106 +++++---- src/Core/Extensions/ListExtensions.cs | 4 +- .../Extensions/SemanticModelExtensions.cs | 55 ++--- src/Core/Extensions/SymbolExtensions.cs | 136 +++++------ src/Core/Extensions/SyntaxExtensions.cs | 61 ++--- src/Core/Extensions/TextExtensions.cs | 8 +- src/Core/FileSystemHelpers.cs | 4 +- src/Core/GeneratedCodeUtility.cs | 4 +- src/Core/Hash.cs | 16 +- src/Core/MetadataName.cs | 8 +- src/Core/MetadataNameEqualityComparer`1.cs | 6 +- src/Core/NameGenerator.cs | 16 +- src/Core/OneOrMany`1.cs | 10 +- src/Core/SeparatedSyntaxListSelection`1.cs | 8 +- src/Core/StringUtility.cs | 2 +- src/Core/SymbolUtility.cs | 49 ++-- src/Core/SyntaxListSelection`1.cs | 8 +- src/Core/SyntaxUtility.cs | 10 +- src/Core/Text/IndentationChange.cs | 4 +- src/Core/Text/StringBuilderCache.cs | 4 +- src/Core/Text/TextLineCollectionSelection.cs | 8 +- src/Core/XmlTagMapper.cs | 7 +- .../Testing.CSharp.MSTest.csproj | 1 + .../Testing/CSharp/MSTest/MSTestAssert.cs | 10 + .../Testing.CSharp.Xunit.csproj | 1 + .../Testing/CSharp/Xunit/XunitAssert.cs | 10 + .../Testing.CSharp/Testing.CSharp.csproj | 1 + .../Testing/CSharp/CSharpTestOptions.cs | 10 +- .../Extensions/TestExtensions.cs | 9 +- .../RuntimeMetadataReference.cs | 4 +- .../Testing.Common/Testing.Common.csproj | 1 + .../Testing.Common/Testing/AdditionalFile.cs | 4 +- .../Testing.Common/Testing/CodeVerifier.cs | 44 ++-- .../Testing/CompilerDiagnosticFixTestData.cs | 6 +- .../Testing/CompilerDiagnosticFixVerifier.cs | 22 +- .../Testing/DiagnosticTestData.cs | 16 +- .../Testing/DiagnosticVerifier.cs | 62 ++--- .../Testing/ExpectedTestState.cs | 10 +- src/Tests/Testing.Common/Testing/IAssert.cs | 10 + .../Testing/RefactoringTestData.cs | 6 +- .../Testing/RefactoringVerifier.cs | 16 +- src/Tests/Testing.Common/Testing/TestCode.cs | 8 +- .../Testing.Common/Testing/TestOptions.cs | 6 +- .../Testing/Text/TextProcessor.cs | 14 +- .../Testing.VisualBasic.csproj | 1 + .../Testing/VisualBasicTestOptions.cs | 10 +- src/Workspaces.Core/AnalyzerAssembly.cs | 16 +- src/Workspaces.Core/AnalyzerLoader.cs | 2 +- src/Workspaces.Core/AttributeInfo.cs | 2 +- .../CodeActions/CodeActionData.cs | 4 +- src/Workspaces.Core/CodeAnalysisOptions.cs | 8 +- src/Workspaces.Core/CodeFixes/CodeFixer.cs | 65 ++++-- .../CodeFixes/CodeFixerOptions.cs | 20 +- .../CodeFixes/DiagnosticFix.cs | 10 +- .../CodeFixes/DiagnosticFixProvider.cs | 46 ++-- .../CodeFixes/FixAllDiagnosticProvider.cs | 2 +- .../CodeFixes/ProjectFixResult.cs | 6 +- .../CodeMetrics/CodeMetricsOptions.cs | 2 + .../Comparers/SymbolDefinitionComparer.cs | 6 +- src/Workspaces.Core/ConsoleUtility.cs | 2 +- src/Workspaces.Core/DiagnosticFormatter.cs | 6 +- .../Diagnostics/CodeAnalyzer.cs | 26 ++- .../Diagnostics/CodeAnalyzerOptions.cs | 6 +- .../Extensions/CodeFixContextExtensions.cs | 4 +- .../Extensions/CollectionExtensions.cs | 4 +- src/Workspaces.Core/Extensions/Extensions.cs | 28 +-- .../Extensions/WorkspaceExtensions.cs | 83 +++++-- src/Workspaces.Core/FileSystemFilter.cs | 4 +- .../IgnoredAttributeNameFilterRule.cs | 48 +--- .../FindSymbols/SymbolFilterOptions.cs | 8 +- .../FindSymbols/SymbolFinder.cs | 15 +- .../FindSymbols/SymbolFinderOptions.cs | 6 +- .../FindSymbols/WithAttributeFilterRule.cs | 5 +- .../Formatting/CodeFormatter.cs | 38 ++-- .../Formatting/CodeFormatterOptions.cs | 4 +- .../Host/Mef/LanguageMetadata.cs | 4 +- .../Host/Mef/LanguageServiceMetadata.cs | 4 +- .../Host/Mef/MefHostServices.cs | 9 +- .../Host/Mef/MefLanguageServices.cs | 12 +- .../Host/Mef/MefWorkspaceServices.cs | 14 +- src/Workspaces.Core/ISyntaxFactsService.cs | 2 +- src/Workspaces.Core/Logging/LogHelpers.cs | 38 ++-- src/Workspaces.Core/Logging/Logger.cs | 6 +- .../Logging/TextWriterWithVerbosity.cs | 6 +- src/Workspaces.Core/MemberNameGenerator.cs | 2 +- src/Workspaces.Core/PathUtilities.cs | 2 +- src/Workspaces.Core/ProjectOrSolution.cs | 28 +-- src/Workspaces.Core/Rename/DiffTracker.cs | 4 +- .../Rename/FindSymbolService.cs | 2 +- .../Rename/IFindSymbolService.cs | 2 +- src/Workspaces.Core/Rename/SymbolData.cs | 4 +- .../Rename/SymbolListHelpers.cs | 4 +- src/Workspaces.Core/Rename/SymbolProvider.cs | 12 +- .../Rename/SymbolRenameProgress.cs | 4 +- .../Rename/SymbolRenameState.cs | 160 +++++++------ src/Workspaces.Core/Rename/SymbolRenamer.cs | 12 +- .../Rename/SymbolRenamerOptions.cs | 2 +- src/Workspaces.Core/SimpleProjectInfo.cs | 4 +- src/Workspaces.Core/Spelling/Core/FixList.cs | 4 +- .../Spelling/Core/Spellchecker.Identifier.cs | 6 +- .../Spelling/Core/Spellchecker.cs | 12 +- .../Spelling/Core/SpellingCapture.cs | 4 +- .../Spelling/Core/SpellingData.cs | 6 +- .../Spelling/Core/SpellingFixProvider.cs | 22 +- .../Spelling/Core/SpellingMatch.cs | 4 +- .../Spelling/Core/SplitUtility.cs | 2 +- .../Spelling/Core/WordCharMap.cs | 6 +- src/Workspaces.Core/Spelling/Core/WordList.cs | 8 +- .../Spelling/Core/WordListLoader.cs | 34 +-- .../Spelling/SpellcheckAnalyzer.cs | 90 ++++---- .../Spelling/SpellcheckOptions.cs | 2 +- .../Spelling/SpellingAnalysisContext.cs | 12 +- .../Spelling/SpellingDiagnostic.cs | 10 +- .../Spelling/SpellingFixHelpers.cs | 14 +- .../Spelling/SpellingFixResult.cs | 16 +- src/Workspaces.Core/SyntaxFinder.cs | 46 ++-- src/Workspaces.Core/UnusedSymbolUtility.cs | 2 +- src/Workspaces.Core/Workspaces.Core.csproj | 1 + 213 files changed, 1875 insertions(+), 1686 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 06fdfb2329..336e657d71 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add social card ([#1212](https://github.com/dotnet/roslynator/pull/1212)). +- Add nullable annotation to public API ([#1198](https://github.com/JosefPihrt/Roslynator/pull/1198)). ### Changed diff --git a/src/Analyzers/CSharp/Analysis/UseConditionalAccessAnalyzer.cs b/src/Analyzers/CSharp/Analysis/UseConditionalAccessAnalyzer.cs index 2605499c36..9c8eb47639 100644 --- a/src/Analyzers/CSharp/Analysis/UseConditionalAccessAnalyzer.cs +++ b/src/Analyzers/CSharp/Analysis/UseConditionalAccessAnalyzer.cs @@ -69,6 +69,9 @@ private static void AnalyzeIfStatement(SyntaxNodeAnalysisContext context) SimpleMemberInvocationStatementInfo invocationInfo = SyntaxInfo.SimpleMemberInvocationStatementInfo(ifStatement.SingleNonBlockStatementOrDefault()); + if (!invocationInfo.Success) + return; + ExpressionSyntax expression2 = invocationInfo.Expression; if (expression2 is null) diff --git a/src/CSharp.Workspaces/CSharp.Workspaces.csproj b/src/CSharp.Workspaces/CSharp.Workspaces.csproj index 4cc223b92e..f3578ed24e 100644 --- a/src/CSharp.Workspaces/CSharp.Workspaces.csproj +++ b/src/CSharp.Workspaces/CSharp.Workspaces.csproj @@ -8,6 +8,7 @@ $(RoslynatorCoreVersion) $(RoslynatorDllPrefix)Roslynator.CSharp.Workspaces Roslynator + enable diff --git a/src/CSharp.Workspaces/CSharp/CSharpSyntaxFactsService.cs b/src/CSharp.Workspaces/CSharp/CSharpSyntaxFactsService.cs index a174e512d0..e6c3288bcf 100644 --- a/src/CSharp.Workspaces/CSharp/CSharpSyntaxFactsService.cs +++ b/src/CSharp.Workspaces/CSharp/CSharpSyntaxFactsService.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Composition; +using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Host; @@ -59,9 +60,9 @@ public bool AreEquivalent(SyntaxTree oldTree, SyntaxTree newTree) return SyntaxFactory.AreEquivalent(oldTree, newTree, topLevel: false); } - public SyntaxNode GetSymbolDeclaration(SyntaxToken identifier) + public SyntaxNode? GetSymbolDeclaration(SyntaxToken identifier) { - SyntaxNode parent = identifier.Parent; + SyntaxNode? parent = identifier.Parent; if (!identifier.IsKind(SyntaxKind.IdentifierToken)) return null; @@ -109,6 +110,7 @@ public SyntaxNode GetSymbolDeclaration(SyntaxToken identifier) } SyntaxDebug.Fail(parent); + return null; } diff --git a/src/CSharp.Workspaces/CSharp/CSharpTypeFactory.cs b/src/CSharp.Workspaces/CSharp/CSharpTypeFactory.cs index 155134fbf4..6993540cfe 100644 --- a/src/CSharp.Workspaces/CSharp/CSharpTypeFactory.cs +++ b/src/CSharp.Workspaces/CSharp/CSharpTypeFactory.cs @@ -7,13 +7,13 @@ namespace Roslynator.CSharp; internal static class CSharpTypeFactory { - private static TypeSyntax _boolType; - private static TypeSyntax _intType; - private static TypeSyntax _doubleType; - private static TypeSyntax _stringType; - private static TypeSyntax _objectType; - private static TypeSyntax _notImplementedException; - private static TypeSyntax _notSupportedException; + private static TypeSyntax? _boolType; + private static TypeSyntax? _intType; + private static TypeSyntax? _doubleType; + private static TypeSyntax? _stringType; + private static TypeSyntax? _objectType; + private static TypeSyntax? _notImplementedException; + private static TypeSyntax? _notSupportedException; public static TypeSyntax BoolType() { diff --git a/src/CSharp.Workspaces/CSharp/CodeMetrics/CSharpPhysicalLinesWalker.cs b/src/CSharp.Workspaces/CSharp/CodeMetrics/CSharpPhysicalLinesWalker.cs index b81628fe0f..4d0bb1cc73 100644 --- a/src/CSharp.Workspaces/CSharp/CodeMetrics/CSharpPhysicalLinesWalker.cs +++ b/src/CSharp.Workspaces/CSharp/CodeMetrics/CSharpPhysicalLinesWalker.cs @@ -120,7 +120,7 @@ private void VisitBrace(in SyntaxToken braceToken) private void VisitBraceTrivia(in SyntaxToken braceToken) { - SyntaxTree tree = braceToken.SyntaxTree; + SyntaxTree tree = braceToken.SyntaxTree!; if (AnalyzeLeadingTrivia(braceToken.LeadingTrivia) && AnalyzeTrailingTrivia(braceToken.TrailingTrivia)) diff --git a/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceExtensions.cs b/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceExtensions.cs index 63213e1c92..b9feed7f21 100644 --- a/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceExtensions.cs +++ b/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceExtensions.cs @@ -42,7 +42,7 @@ internal static bool SupportsLanguageFeature(this Document document, CSharpLangu internal static bool SupportsLanguageVersion(this Document document, LanguageVersion languageVersion) { - return ((CSharpParseOptions)document.Project.ParseOptions).LanguageVersion >= languageVersion; + return ((CSharpParseOptions?)document.Project.ParseOptions)?.LanguageVersion >= languageVersion; } internal static DefaultSyntaxOptions GetDefaultSyntaxOptions(this Document document, DefaultSyntaxOptions options = DefaultSyntaxOptions.None) @@ -83,7 +83,7 @@ internal static Task RemoveMemberAsync( if (member is null) throw new ArgumentNullException(nameof(member)); - SyntaxNode parent = member.Parent; + SyntaxNode? parent = member.Parent; switch (parent?.Kind()) { @@ -162,7 +162,10 @@ public static async Task RemoveCommentsAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + return document; SyntaxNode newRoot = SyntaxRefactorings.RemoveComments(root, comments) .WithFormatterAnnotation(); @@ -186,7 +189,10 @@ public static async Task RemoveCommentsAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + return document; SyntaxNode newRoot = SyntaxRefactorings.RemoveComments(root, span, comments) .WithFormatterAnnotation(); @@ -208,7 +214,10 @@ public static async Task RemoveTriviaAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + return document; SyntaxNode newRoot = SyntaxRefactorings.RemoveTrivia(root, span); @@ -229,7 +238,10 @@ public static async Task RemovePreprocessorDirectivesAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + return document; SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); @@ -254,7 +266,10 @@ public static async Task RemovePreprocessorDirectivesAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + return document; SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); @@ -400,7 +415,7 @@ internal static Task RemoveSingleLineDocumentationComment( DocumentationCommentTriviaSyntax documentationComment, CancellationToken cancellationToken = default) { - SyntaxNode node = documentationComment.ParentTrivia.Token.Parent; + SyntaxNode node = documentationComment.ParentTrivia.Token.Parent!; SyntaxNode newNode = SyntaxRefactorings.RemoveSingleLineDocumentationComment(node, documentationComment); return document.ReplaceNodeAsync(node, newNode, cancellationToken); diff --git a/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceSymbolExtensions.cs b/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceSymbolExtensions.cs index f6382562cf..b9184ee0fa 100644 --- a/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceSymbolExtensions.cs +++ b/src/CSharp.Workspaces/CSharp/Extensions/WorkspaceSymbolExtensions.cs @@ -19,7 +19,7 @@ public static class WorkspaceSymbolExtensions public static ExpressionSyntax GetDefaultValueSyntax( this ITypeSymbol typeSymbol, DefaultSyntaxOptions options = DefaultSyntaxOptions.None, - SymbolDisplayFormat format = null) + SymbolDisplayFormat? format = null) { return GetDefaultValueSyntax(typeSymbol, options, default(TypeSyntax), format); } @@ -42,8 +42,8 @@ public static ExpressionSyntax GetDefaultValueSyntax( private static ExpressionSyntax GetDefaultValueSyntax( this ITypeSymbol typeSymbol, DefaultSyntaxOptions options = DefaultSyntaxOptions.None, - TypeSyntax type = null, - SymbolDisplayFormat format = null) + TypeSyntax? type = null, + SymbolDisplayFormat? format = null) { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -60,7 +60,7 @@ private static ExpressionSyntax GetDefaultValueSyntax( if (typeSymbol.TypeKind == TypeKind.Enum) { - IFieldSymbol fieldSymbol = CSharpUtility.FindEnumDefaultField((INamedTypeSymbol)typeSymbol); + IFieldSymbol? fieldSymbol = CSharpUtility.FindEnumDefaultField((INamedTypeSymbol)typeSymbol); if (fieldSymbol is not null) return SimpleMemberAccessExpression(GetTypeSyntax(), IdentifierName(fieldSymbol.Name)); @@ -106,7 +106,7 @@ ExpressionSyntax CreateDefault() internal static ExpressionSyntax GetDefaultValueSyntax( this IParameterSymbol parameterSymbol, - SymbolDisplayFormat format = null) + SymbolDisplayFormat? format = null) { if (parameterSymbol is null) throw new ArgumentNullException(nameof(parameterSymbol)); @@ -114,7 +114,7 @@ internal static ExpressionSyntax GetDefaultValueSyntax( if (!parameterSymbol.HasExplicitDefaultValue) throw new ArgumentException("Parameter does not specify default value.", nameof(parameterSymbol)); - object value = parameterSymbol.ExplicitDefaultValue; + object? value = parameterSymbol.ExplicitDefaultValue; ITypeSymbol typeSymbol = parameterSymbol.Type; @@ -123,7 +123,7 @@ internal static ExpressionSyntax GetDefaultValueSyntax( if (value is null) return NullLiteralExpression(); - IFieldSymbol fieldSymbol = FindFieldWithConstantValue(); + IFieldSymbol? fieldSymbol = FindFieldWithConstantValue(); TypeSyntax type = typeSymbol.ToTypeSyntax(format); @@ -145,7 +145,7 @@ internal static ExpressionSyntax GetDefaultValueSyntax( return LiteralExpression(value); - IFieldSymbol FindFieldWithConstantValue() + IFieldSymbol? FindFieldWithConstantValue() { foreach (ISymbol symbol in typeSymbol.GetMembers()) { diff --git a/src/CSharp.Workspaces/CSharp/FindSymbols/CSharpFindSymbolService.cs b/src/CSharp.Workspaces/CSharp/FindSymbols/CSharpFindSymbolService.cs index 12b55f190e..d0bb58270a 100644 --- a/src/CSharp.Workspaces/CSharp/FindSymbols/CSharpFindSymbolService.cs +++ b/src/CSharp.Workspaces/CSharp/FindSymbols/CSharpFindSymbolService.cs @@ -17,7 +17,7 @@ internal class CSharpFindSymbolService : FindSymbolService { public override ISyntaxFactsService SyntaxFacts => CSharpSyntaxFactsService.Instance; - public override SyntaxNode FindDeclaration(SyntaxNode node) + public override SyntaxNode? FindDeclaration(SyntaxNode node) { return node.FirstAncestorOrSelf( n => diff --git a/src/CSharp.Workspaces/CSharp/FindSymbols/LocalSymbolFinder.cs b/src/CSharp.Workspaces/CSharp/FindSymbols/LocalSymbolFinder.cs index e878662ec8..7313707aff 100644 --- a/src/CSharp.Workspaces/CSharp/FindSymbols/LocalSymbolFinder.cs +++ b/src/CSharp.Workspaces/CSharp/FindSymbols/LocalSymbolFinder.cs @@ -31,8 +31,11 @@ public static ImmutableArray FindLocalSymbols( { var eventDeclaration = (EventDeclarationSyntax)node; - foreach (AccessorDeclarationSyntax accessor in eventDeclaration.AccessorList.Accessors) - walker.Visit(accessor.BodyOrExpressionBody()); + if (eventDeclaration.AccessorList is not null) + { + foreach (AccessorDeclarationSyntax accessor in eventDeclaration.AccessorList.Accessors) + walker.Visit(accessor.BodyOrExpressionBody()); + } break; } @@ -40,8 +43,11 @@ public static ImmutableArray FindLocalSymbols( { var indexerDeclaration = (IndexerDeclarationSyntax)node; - foreach (AccessorDeclarationSyntax accessor in indexerDeclaration.AccessorList.Accessors) - walker.Visit(accessor.BodyOrExpressionBody()); + if (indexerDeclaration.AccessorList is not null) + { + foreach (AccessorDeclarationSyntax accessor in indexerDeclaration.AccessorList.Accessors) + walker.Visit(accessor.BodyOrExpressionBody()); + } break; } @@ -57,13 +63,13 @@ public static ImmutableArray FindLocalSymbols( { var propertyDeclaration = (PropertyDeclarationSyntax)node; - ArrowExpressionClauseSyntax expressionBody = propertyDeclaration.ExpressionBody; + ArrowExpressionClauseSyntax? expressionBody = propertyDeclaration.ExpressionBody; if (expressionBody is not null) { walker.Visit(expressionBody); } - else + else if (propertyDeclaration.AccessorList is not null) { foreach (AccessorDeclarationSyntax accessor in propertyDeclaration.AccessorList.Accessors) walker.Visit(accessor.BodyOrExpressionBody()); @@ -75,7 +81,7 @@ public static ImmutableArray FindLocalSymbols( { var declarator = (VariableDeclaratorSyntax)node; - ExpressionSyntax expression = declarator.Initializer?.Value; + ExpressionSyntax? expression = declarator.Initializer?.Value; if (expression is not null) walker.Visit(expression); @@ -133,7 +139,7 @@ public LocalSymbolCollector( public override void VisitLocal(SyntaxNode node) { - ISymbol symbol = SemanticModel.GetDeclaredSymbol(node, CancellationToken); + ISymbol? symbol = SemanticModel.GetDeclaredSymbol(node, CancellationToken); if (symbol is not null) { diff --git a/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingDiagnostic.cs b/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingDiagnostic.cs index cae95e216b..5004befdd3 100644 --- a/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingDiagnostic.cs +++ b/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingDiagnostic.cs @@ -12,7 +12,7 @@ public CSharpSpellingDiagnostic( Diagnostic diagnostic, string value, int valueIndex, - string containingValue, + string? containingValue, int containingValueIndex, SyntaxToken identifier = default) : base(diagnostic, value, valueIndex, containingValue, containingValueIndex, identifier) { diff --git a/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingService.cs b/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingService.cs index c965eb4969..85bfd58f77 100644 --- a/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingService.cs +++ b/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingService.cs @@ -53,15 +53,15 @@ public override ImmutableArray AnalyzeSpelling( public override SpellingDiagnostic CreateSpellingDiagnostic(Diagnostic diagnostic) { Location location = diagnostic.Location; - SyntaxTree syntaxTree = location.SourceTree; + SyntaxTree syntaxTree = location.SourceTree!; SyntaxNode root = syntaxTree.GetRoot(); TextSpan span = location.SourceSpan; - string value = diagnostic.Properties["Value"]; + string value = diagnostic.Properties["Value"]!; int index = location.SourceSpan.Start; - string parent = diagnostic.Properties.GetValueOrDefault("Parent"); + string? parent = diagnostic.Properties.GetValueOrDefault("Parent"); - int parentIndex = (diagnostic.Properties.TryGetValue("ParentIndex", out string parentIndexText)) + int parentIndex = (diagnostic.Properties.TryGetValue("ParentIndex", out string? parentIndexText)) ? int.Parse(parentIndexText) : 0; diff --git a/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingWalker.cs b/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingWalker.cs index a62f2686f4..8943c89610 100644 --- a/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingWalker.cs +++ b/src/CSharp.Workspaces/CSharp/Spelling/CSharpSpellingWalker.cs @@ -61,7 +61,7 @@ public override void VisitTrivia(SyntaxTrivia trivia) case SyntaxKind.MultiLineCommentTrivia: { if (ShouldVisit(SpellingScopeFilter.NonDocumentationComment)) - AnalyzeText(trivia.ToString(), trivia.SyntaxTree, trivia.Span); + AnalyzeText(trivia.ToString(), trivia.SyntaxTree!, trivia.Span); break; } @@ -85,7 +85,7 @@ public override void VisitTrivia(SyntaxTrivia trivia) { Debug.Assert(ShouldVisit(SpellingScopeFilter.Region)); - AnalyzeText(trivia.ToString(), trivia.SyntaxTree, trivia.Span); + AnalyzeText(trivia.ToString(), trivia.SyntaxTree!, trivia.Span); break; } } diff --git a/src/CSharp.Workspaces/CSharp/SyntaxInverter.cs b/src/CSharp.Workspaces/CSharp/SyntaxInverter.cs index 5ba2053baf..cd2d9d2200 100644 --- a/src/CSharp.Workspaces/CSharp/SyntaxInverter.cs +++ b/src/CSharp.Workspaces/CSharp/SyntaxInverter.cs @@ -11,6 +11,8 @@ namespace Roslynator.CSharp; +#nullable disable + /// /// Provides static methods for syntax inversion. /// diff --git a/src/CSharp.Workspaces/CSharp/SyntaxLogicalInverter.cs b/src/CSharp.Workspaces/CSharp/SyntaxLogicalInverter.cs index b45b6f380b..e42d4290c2 100644 --- a/src/CSharp.Workspaces/CSharp/SyntaxLogicalInverter.cs +++ b/src/CSharp.Workspaces/CSharp/SyntaxLogicalInverter.cs @@ -56,7 +56,7 @@ public ExpressionSyntax LogicallyInvert( /// public ExpressionSyntax LogicallyInvert( ExpressionSyntax expression, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken = default) { if (expression is null) @@ -69,11 +69,11 @@ public ExpressionSyntax LogicallyInvert( private ExpressionSyntax LogicallyInvertAndParenthesize( ExpressionSyntax expression, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { if (expression is null) - return null; + throw new ArgumentNullException(nameof(expression)); ExpressionSyntax inverted = LogicallyInvertImpl(expression, semanticModel, cancellationToken); return (inverted.IsKind(SyntaxKind.LogicalNotExpression, SyntaxKind.ParenthesizedExpression)) ? inverted : inverted.Parenthesize(); @@ -81,11 +81,11 @@ private ExpressionSyntax LogicallyInvertAndParenthesize( private ExpressionSyntax LogicallyInvertImpl( ExpressionSyntax expression, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { if (expression is null) - return expression; + throw new ArgumentNullException(nameof(expression)); switch (expression.Kind()) { @@ -127,6 +127,9 @@ private ExpressionSyntax LogicallyInvertImpl( } case SyntaxKind.IsExpression: { + if (semanticModel is null) + return DefaultInvert(expression); + var isExpression = (BinaryExpressionSyntax)expression; var rightTypeSymbol = (ITypeSymbol)semanticModel.GetSymbol(isExpression.Right, cancellationToken)!; @@ -312,7 +315,7 @@ private ExpressionSyntax InvertLessThanGreaterThan( if (conditionalAccess.Expression.Kind() != SyntaxKind.IdentifierName) return DefaultInvert(binaryExpression); - ExpressionSyntax newExpression = TryCreateExpressionWithoutConditionalAccess(conditionalAccess); + ExpressionSyntax? newExpression = TryCreateExpressionWithoutConditionalAccess(conditionalAccess); if (newExpression is null) return DefaultInvert(binaryExpression); @@ -325,7 +328,7 @@ private ExpressionSyntax InvertLessThanGreaterThan( (isLeft) ? otherExpression : newExpression)); } - private static ExpressionSyntax TryCreateExpressionWithoutConditionalAccess(ConditionalAccessExpressionSyntax conditionalAccess) + private static ExpressionSyntax? TryCreateExpressionWithoutConditionalAccess(ConditionalAccessExpressionSyntax conditionalAccess) { switch (conditionalAccess.WhenNotNull) { @@ -397,7 +400,7 @@ static SyntaxKind InvertBinaryOperator(SyntaxKind kind) private BinaryExpressionSyntax InvertBinaryExpression( BinaryExpressionSyntax binaryExpression, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { ExpressionSyntax left = binaryExpression.Left; @@ -451,21 +454,17 @@ private static SyntaxKind InvertBinaryExpressionKind(SyntaxKind kind) private ConditionalExpressionSyntax InvertConditionalExpression( ConditionalExpressionSyntax conditionalExpression, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { ExpressionSyntax whenTrue = conditionalExpression.WhenTrue; ExpressionSyntax whenFalse = conditionalExpression.WhenFalse; - if (whenTrue?.IsKind(SyntaxKind.ThrowExpression) == false) - { + if (!whenTrue.IsKind(SyntaxKind.ThrowExpression)) whenTrue = LogicallyInvertAndParenthesize(whenTrue, semanticModel, cancellationToken); - } - if (whenFalse?.IsKind(SyntaxKind.ThrowExpression) == false) - { + if (!whenFalse.IsKind(SyntaxKind.ThrowExpression)) whenFalse = LogicallyInvertAndParenthesize(whenFalse, semanticModel, cancellationToken); - } ConditionalExpressionSyntax newConditionalExpression = conditionalExpression.Update( conditionalExpression.Condition, diff --git a/src/CSharp/CSharp.csproj b/src/CSharp/CSharp.csproj index 5e1438b842..2a79dbcf2e 100644 --- a/src/CSharp/CSharp.csproj +++ b/src/CSharp/CSharp.csproj @@ -8,6 +8,7 @@ $(RoslynatorCoreVersion) $(RoslynatorDllPrefix)Roslynator.CSharp Roslynator + enable diff --git a/src/CSharp/CSharp/BracesAnalysis.cs b/src/CSharp/CSharp/BracesAnalysis.cs index 65ca0ac795..4570287631 100644 --- a/src/CSharp/CSharp/BracesAnalysis.cs +++ b/src/CSharp/CSharp/BracesAnalysis.cs @@ -57,7 +57,7 @@ public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement) { cnt++; - StatementSyntax statement = ifOrElse.Statement; + StatementSyntax statement = ifOrElse.Statement!; if (!anyHasEmbedded && statement.Kind() != SyntaxKind.Block) @@ -104,7 +104,7 @@ public static BracesAnalysis AnalyzeBraces(IfStatementSyntax ifStatement) static bool SupportsEmbedded(StatementSyntax statement) { if (statement.IsParentKind(SyntaxKind.IfStatement) - && ((IfStatementSyntax)statement.Parent).Condition?.IsMultiLine() == true) + && ((IfStatementSyntax)statement.Parent!).Condition?.IsMultiLine() == true) { return false; } @@ -119,14 +119,14 @@ static bool SupportsEmbedded(StatementSyntax statement) if (!block.CloseBraceToken.LeadingTrivia.IsEmptyOrWhitespace()) return false; - statement = block.Statements.SingleOrDefault(shouldThrow: false); + statement = block.Statements.SingleOrDefault(shouldThrow: false)!; if (statement is null) return false; if (statement.Kind() == SyntaxKind.IfStatement && block.IsParentKind(SyntaxKind.IfStatement) - && ((IfStatementSyntax)block.Parent).Else is not null + && ((IfStatementSyntax)block.Parent!).Else is not null && ((IfStatementSyntax)statement).GetCascadeInfo().EndsWithIf) { return false; diff --git a/src/CSharp/CSharp/CSharpFactory.cs b/src/CSharp/CSharp/CSharpFactory.cs index 0cf2662fa0..69b1af2188 100644 --- a/src/CSharp/CSharp/CSharpFactory.cs +++ b/src/CSharp/CSharp/CSharpFactory.cs @@ -457,7 +457,7 @@ public static ConstructorDeclarationSyntax ConstructorDeclaration(SyntaxTokenLis modifiers, identifier, parameterList, - default(ConstructorInitializerSyntax), + default(ConstructorInitializerSyntax)!, expressionBody, SemicolonToken()); } @@ -495,7 +495,7 @@ public static EnumMemberDeclarationSyntax EnumMemberDeclaration(SyntaxToken iden value); } - public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, TypeSyntax type, string identifier, ExpressionSyntax value = null) + public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, TypeSyntax type, string identifier, ExpressionSyntax? value = null) { return FieldDeclaration( modifiers, @@ -513,7 +513,7 @@ public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, initializer); } - public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, ExpressionSyntax value = null) + public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, ExpressionSyntax? value = null) { return FieldDeclaration( modifiers, @@ -522,7 +522,7 @@ public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, (value is not null) ? EqualsValueClause(value) : default); } - public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax initializer) + public static FieldDeclarationSyntax FieldDeclaration(SyntaxTokenList modifiers, TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax? initializer) { return SyntaxFactory.FieldDeclaration( default(SyntaxList), @@ -740,7 +740,7 @@ public static PropertyDeclarationSyntax PropertyDeclaration( TypeSyntax type, SyntaxToken identifier, AccessorListSyntax accessorList, - ExpressionSyntax value = null) + ExpressionSyntax? value = null) { return SyntaxFactory.PropertyDeclaration( default(SyntaxList), @@ -949,7 +949,7 @@ internal static AccessorDeclarationSyntax AutoAccessorDeclaration(SyntaxKind kin default(SyntaxList), modifiers, Token(AccessorDeclarationKeywordKind(kind)), - default(BlockSyntax), + default(BlockSyntax)!, SemicolonToken()); } @@ -976,12 +976,12 @@ private static SyntaxKind AccessorDeclarationKeywordKind(SyntaxKind kind) #endregion AccessorDeclaration #region Statement - public static LocalDeclarationStatementSyntax LocalDeclarationStatement(TypeSyntax type, string identifier, ExpressionSyntax value = null) + public static LocalDeclarationStatementSyntax LocalDeclarationStatement(TypeSyntax type, string identifier, ExpressionSyntax? value = null) { return LocalDeclarationStatement(type, Identifier(identifier), value); } - public static LocalDeclarationStatementSyntax LocalDeclarationStatement(TypeSyntax type, SyntaxToken identifier, ExpressionSyntax value = null) + public static LocalDeclarationStatementSyntax LocalDeclarationStatement(TypeSyntax type, SyntaxToken identifier, ExpressionSyntax? value = null) { VariableDeclaratorSyntax variableDeclarator = (value is not null) ? VariableDeclarator(identifier, EqualsValueClause(value)) @@ -1016,7 +1016,7 @@ public static YieldStatementSyntax YieldBreakStatement() return YieldStatement(SyntaxKind.YieldBreakStatement); } - public static TryStatementSyntax TryStatement(BlockSyntax block, CatchClauseSyntax @catch, FinallyClauseSyntax @finally = null) + public static TryStatementSyntax TryStatement(BlockSyntax block, CatchClauseSyntax @catch, FinallyClauseSyntax? @finally = null) { return SyntaxFactory.TryStatement(block, SingletonList(@catch), @finally); } @@ -1648,7 +1648,7 @@ public static LiteralExpressionSyntax DefaultLiteralExpression() return SyntaxFactory.LiteralExpression(SyntaxKind.DefaultLiteralExpression); } - public static LiteralExpressionSyntax LiteralExpression(object value) + public static LiteralExpressionSyntax LiteralExpression(object? value) { if (value is null) return NullLiteralExpression(); @@ -1837,17 +1837,17 @@ public static VariableDeclaratorSyntax VariableDeclarator(string identifier, Equ return VariableDeclarator(Identifier(identifier), initializer); } - public static VariableDeclaratorSyntax VariableDeclarator(SyntaxToken identifier, EqualsValueClauseSyntax initializer) + public static VariableDeclaratorSyntax VariableDeclarator(SyntaxToken identifier, EqualsValueClauseSyntax? initializer) { return SyntaxFactory.VariableDeclarator(identifier, default(BracketedArgumentListSyntax), initializer); } - public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, string identifier, ExpressionSyntax value = null) + public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, string identifier, ExpressionSyntax? value = null) { return VariableDeclaration(type, Identifier(identifier), value); } - public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, SyntaxToken identifier, ExpressionSyntax value = null) + public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, SyntaxToken identifier, ExpressionSyntax? value = null) { if (value is not null) { @@ -1859,7 +1859,7 @@ public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, Syn } } - public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax initializer) + public static VariableDeclarationSyntax VariableDeclaration(TypeSyntax type, SyntaxToken identifier, EqualsValueClauseSyntax? initializer) { return VariableDeclaration( type, @@ -1919,12 +1919,12 @@ public static ArgumentSyntax Argument(NameColonSyntax nameColon, ExpressionSynta return SyntaxFactory.Argument(nameColon, default(SyntaxToken), expression); } - public static ParameterSyntax Parameter(TypeSyntax type, string identifier, ExpressionSyntax @default = null) + public static ParameterSyntax Parameter(TypeSyntax type, string identifier, ExpressionSyntax? @default = null) { return Parameter(type, Identifier(identifier), @default); } - public static ParameterSyntax Parameter(TypeSyntax type, SyntaxToken identifier, ExpressionSyntax @default = null) + public static ParameterSyntax Parameter(TypeSyntax type, SyntaxToken identifier, ExpressionSyntax? @default = null) { if (@default is not null) { @@ -1975,7 +1975,7 @@ public static ClassOrStructConstraintSyntax StructConstraint() return ClassOrStructConstraint(SyntaxKind.StructConstraint, Token(SyntaxKind.StructKeyword)); } - public static ConstructorInitializerSyntax BaseConstructorInitializer(ArgumentListSyntax argumentList = null) + public static ConstructorInitializerSyntax BaseConstructorInitializer(ArgumentListSyntax? argumentList = null) { return ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, argumentList); } @@ -1985,7 +1985,7 @@ public static ConstructorInitializerSyntax BaseConstructorInitializer(SyntaxToke return ConstructorInitializer(SyntaxKind.BaseConstructorInitializer, semicolonToken, Token(SyntaxKind.BaseKeyword), argumentList); } - public static ConstructorInitializerSyntax ThisConstructorInitializer(ArgumentListSyntax argumentList = null) + public static ConstructorInitializerSyntax ThisConstructorInitializer(ArgumentListSyntax? argumentList = null) { return ConstructorInitializer(SyntaxKind.ThisConstructorInitializer, argumentList); } diff --git a/src/CSharp/CSharp/CSharpNameGenerator.cs b/src/CSharp/CSharp/CSharpNameGenerator.cs index c26ef8af1c..2dc71b1c83 100644 --- a/src/CSharp/CSharp/CSharpNameGenerator.cs +++ b/src/CSharp/CSharp/CSharpNameGenerator.cs @@ -87,7 +87,7 @@ public static string EnsureUniqueParameterName( return _generator.EnsureUniqueParameterName(baseName, containingSymbol, semanticModel, isCaseSensitive: true, cancellationToken); } - internal static string CreateUniqueLocalName( + internal static string? CreateUniqueLocalName( ITypeSymbol typeSymbol, SemanticModel semanticModel, int position, @@ -96,7 +96,7 @@ internal static string CreateUniqueLocalName( return _generator.CreateUniqueLocalName(typeSymbol, semanticModel, position, isCaseSensitive: true, cancellationToken); } - internal static string CreateUniqueLocalName( + internal static string? CreateUniqueLocalName( ITypeSymbol typeSymbol, string oldName, SemanticModel semanticModel, @@ -106,7 +106,7 @@ internal static string CreateUniqueLocalName( return _generator.CreateUniqueLocalName(typeSymbol, oldName, semanticModel, position, isCaseSensitive: true, cancellationToken); } - internal static string CreateUniqueParameterName( + internal static string? CreateUniqueParameterName( string oldName, IParameterSymbol parameterSymbol, SemanticModel semanticModel, diff --git a/src/CSharp/CSharp/CSharpOverriddenSymbolInfo.cs b/src/CSharp/CSharp/CSharpOverriddenSymbolInfo.cs index 4a79dae720..1e90dcbbc5 100644 --- a/src/CSharp/CSharp/CSharpOverriddenSymbolInfo.cs +++ b/src/CSharp/CSharp/CSharpOverriddenSymbolInfo.cs @@ -72,12 +72,12 @@ private static OverriddenSymbolInfo CreateImpl( SemanticModel semanticModel, CancellationToken cancellationToken) { - IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); + IMethodSymbol? methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); if (methodSymbol is null) return Default; - IMethodSymbol overriddenMethod = methodSymbol.OverriddenMethod; + IMethodSymbol? overriddenMethod = methodSymbol.OverriddenMethod; if (overriddenMethod is null) return Default; @@ -90,12 +90,12 @@ private static OverriddenSymbolInfo CreateImpl( SemanticModel semanticModel, CancellationToken cancellationToken) { - var propertySymbol = (IPropertySymbol)semanticModel.GetDeclaredSymbol(basePropertyDeclaration, cancellationToken); + var propertySymbol = (IPropertySymbol?)semanticModel.GetDeclaredSymbol(basePropertyDeclaration, cancellationToken); if (propertySymbol is null) return Default; - IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty; + IPropertySymbol? overriddenProperty = propertySymbol.OverriddenProperty; if (overriddenProperty is null) return Default; @@ -108,12 +108,12 @@ private static OverriddenSymbolInfo CreateImpl( SemanticModel semanticModel, CancellationToken cancellationToken) { - IEventSymbol eventSymbol = semanticModel.GetDeclaredSymbol(eventDeclaration, cancellationToken); + IEventSymbol? eventSymbol = semanticModel.GetDeclaredSymbol(eventDeclaration, cancellationToken); if (eventSymbol is null) return Default; - IEventSymbol overriddenEvent = eventSymbol.OverriddenEvent; + IEventSymbol? overriddenEvent = eventSymbol.OverriddenEvent; if (overriddenEvent is null) return Default; @@ -135,7 +135,7 @@ private static OverriddenSymbolInfo CreateImpl( if (semanticModel.GetDeclaredSymbol(variableDeclarator, cancellationToken) is not IEventSymbol eventSymbol) return Default; - IEventSymbol overriddenEvent = eventSymbol.OverriddenEvent; + IEventSymbol? overriddenEvent = eventSymbol.OverriddenEvent; if (overriddenEvent is null) return Default; @@ -148,12 +148,12 @@ private static OverriddenSymbolInfo CreateImpl( SemanticModel semanticModel, CancellationToken cancellationToken) { - IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(accessorDeclaration, cancellationToken); + IMethodSymbol? methodSymbol = semanticModel.GetDeclaredSymbol(accessorDeclaration, cancellationToken); if (methodSymbol is null) return Default; - IMethodSymbol overriddenMethod = methodSymbol.OverriddenMethod; + IMethodSymbol? overriddenMethod = methodSymbol.OverriddenMethod; if (overriddenMethod is null) return Default; diff --git a/src/CSharp/CSharp/CSharpTypeAnalysis.cs b/src/CSharp/CSharp/CSharpTypeAnalysis.cs index da35861e82..f04bdd34ec 100644 --- a/src/CSharp/CSharp/CSharpTypeAnalysis.cs +++ b/src/CSharp/CSharp/CSharpTypeAnalysis.cs @@ -34,12 +34,12 @@ public static TypeAnalysis AnalyzeType( if (variableDeclaration.IsParentKind(SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration)) return default; - ExpressionSyntax expression = variables[0].Initializer?.Value?.WalkDownParentheses(); + ExpressionSyntax? expression = variables[0].Initializer?.Value?.WalkDownParentheses(); if (expression is null) return default; - ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); + ITypeSymbol? typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); if (typeSymbol is null) return default; @@ -87,7 +87,7 @@ public static TypeAnalysis AnalyzeType( } case SyntaxKind.SimpleMemberAccessExpression: { - ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); + ISymbol? symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol?.Kind == SymbolKind.Field && symbol.ContainingType?.TypeKind == TypeKind.Enum) @@ -131,7 +131,7 @@ public static bool IsImplicitThatCanBeExplicit( Debug.Assert(variableDeclaration.Variables.Any()); - ExpressionSyntax expression = variableDeclaration + ExpressionSyntax? expression = variableDeclaration .Variables .FirstOrDefault()? .Initializer? @@ -141,7 +141,7 @@ public static bool IsImplicitThatCanBeExplicit( if (expression is null) return false; - ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); + ITypeSymbol? typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); if (typeSymbol is null) return false; @@ -189,7 +189,7 @@ public static bool IsExplicitThatCanBeImplicit( if (type.IsVar) return false; - switch (variableDeclaration.Parent.Kind()) + switch (variableDeclaration.Parent?.Kind()) { case SyntaxKind.FieldDeclaration: case SyntaxKind.EventFieldDeclaration: @@ -203,11 +203,15 @@ public static bool IsExplicitThatCanBeImplicit( break; } + case null: + { + return false; + } } Debug.Assert(variableDeclaration.Variables.Any()); - ExpressionSyntax expression = variableDeclaration + ExpressionSyntax? expression = variableDeclaration .Variables .SingleOrDefault(shouldThrow: false)? .Initializer? @@ -227,7 +231,7 @@ public static bool IsExplicitThatCanBeImplicit( return false; } - ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); + ITypeSymbol? typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); if (typeSymbol is null) return false; @@ -241,7 +245,7 @@ public static bool IsExplicitThatCanBeImplicit( return false; } - ITypeSymbol expressionType = semanticModel.GetTypeSymbol(expression, cancellationToken); + ITypeSymbol? expressionType = semanticModel.GetTypeSymbol(expression, cancellationToken); if (!SymbolEqualityComparer.Default.Equals(typeSymbol, expressionType) || (type.IsKind(SyntaxKind.NullableType) @@ -269,7 +273,7 @@ public static bool IsTypeObvious(ExpressionSyntax expression, SemanticModel sema return IsTypeObvious(expression, typeSymbol: null, includeNullability: false, semanticModel, cancellationToken); } - public static bool IsTypeObvious(ExpressionSyntax expression, ITypeSymbol typeSymbol, bool includeNullability, SemanticModel semanticModel, CancellationToken cancellationToken) + public static bool IsTypeObvious(ExpressionSyntax expression, ITypeSymbol? typeSymbol, bool includeNullability, SemanticModel semanticModel, CancellationToken cancellationToken) { switch (expression.Kind()) { @@ -321,7 +325,7 @@ public static bool IsTypeObvious(ExpressionSyntax expression, ITypeSymbol typeSy } case SyntaxKind.SimpleMemberAccessExpression: { - ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); + ISymbol? symbol = semanticModel.GetSymbol(expression, cancellationToken); return symbol?.Kind == SymbolKind.Field && symbol.ContainingType?.TypeKind == TypeKind.Enum; @@ -333,7 +337,7 @@ public static bool IsTypeObvious(ExpressionSyntax expression, ITypeSymbol typeSy var invocationExpression = (InvocationExpressionSyntax)expression; if (invocationExpression.Expression.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { - ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); + ISymbol? symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol?.IsStatic == true && string.Equals(symbol.Name, "Parse", StringComparison.Ordinal) @@ -343,7 +347,7 @@ public static bool IsTypeObvious(ExpressionSyntax expression, ITypeSymbol typeSy { var simpleMemberAccess = (MemberAccessExpressionSyntax)invocationExpression.Expression; - ISymbol symbol2 = semanticModel.GetSymbol(simpleMemberAccess.Expression, cancellationToken); + ISymbol? symbol2 = semanticModel.GetSymbol(simpleMemberAccess.Expression, cancellationToken); if (SymbolEqualityComparer.Default.Equals(symbol2, typeSymbol) && semanticModel.GetAliasInfo(simpleMemberAccess.Expression, cancellationToken) is null) @@ -510,7 +514,7 @@ public static bool IsExplicitThatCanBeImplicit( static bool AnalyzeArgument(ArgumentSyntax argument, SemanticModel semanticModel, CancellationToken cancellationToken) { - IParameterSymbol parameterSymbol = semanticModel.DetermineParameter(argument, cancellationToken: cancellationToken); + IParameterSymbol? parameterSymbol = semanticModel.DetermineParameter(argument, cancellationToken: cancellationToken); if (parameterSymbol is null) return false; @@ -522,7 +526,7 @@ static bool AnalyzeArgument(ArgumentSyntax argument, SemanticModel semanticModel { ImmutableArray typeParameterList = methodSymbol.TypeArguments; - ITypeParameterSymbol typeParameterSymbol = null; + ITypeParameterSymbol? typeParameterSymbol = null; for (int i = 0; i < typeParameterList.Length; i++) { if (SymbolEqualityComparer.Default.Equals(typeParameterList[i], parameterSymbol.Type)) @@ -581,7 +585,7 @@ public static bool IsExplicitThatCanBeImplicit( TypeAppearance typeAppearance, CancellationToken cancellationToken = default) { - switch (tupleExpression.Parent.Kind()) + switch (tupleExpression.Parent?.Kind()) { case SyntaxKind.SimpleAssignmentExpression: { @@ -615,6 +619,10 @@ public static bool IsExplicitThatCanBeImplicit( return false; } #endif + case null: + { + return false; + } default: { SyntaxDebug.Fail(tupleExpression.Parent); @@ -638,15 +646,15 @@ private static bool IsExplicitThatCanBeImplicit( if (expression.IsKind(SyntaxKind.NullLiteralExpression, SyntaxKind.DefaultLiteralExpression)) return false; - ITypeSymbol tupleTypeSymbol = semanticModel.GetTypeSymbol(tupleExpression, cancellationToken); + ITypeSymbol? tupleTypeSymbol = semanticModel.GetTypeSymbol(tupleExpression, cancellationToken); if (tupleTypeSymbol is null) return false; - ITypeSymbol expressionTypeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); + ITypeSymbol? expressionTypeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (tupleTypeSymbol.IsTupleType - && expressionTypeSymbol.IsTupleType) + && expressionTypeSymbol?.IsTupleType == true) { var tupleNamedTypeSymbol = (INamedTypeSymbol)tupleTypeSymbol; var expressionNamedTypeSymbol = (INamedTypeSymbol)expressionTypeSymbol; @@ -714,7 +722,7 @@ public static TypeAnalysis AnalyzeType(ForEachStatementSyntax forEachStatement, ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); - ITypeSymbol typeSymbol = info.ElementType; + ITypeSymbol? typeSymbol = info.ElementType; if (typeSymbol is null) return default; @@ -801,7 +809,7 @@ public static TypeAnalysis AnalyzeType(ForEachVariableStatementSyntax forEachSta ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); - ITypeSymbol typeSymbol = info.ElementType; + ITypeSymbol? typeSymbol = info.ElementType; if (typeSymbol is null) return default; @@ -843,7 +851,7 @@ public static bool IsImplicitThatCanBeExplicit(ForEachStatementSyntax forEachSta ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); - ITypeSymbol typeSymbol = info.ElementType; + ITypeSymbol? typeSymbol = info.ElementType; if (typeSymbol is null) return false; @@ -870,7 +878,7 @@ public static bool IsImplicitThatCanBeExplicit(ForEachVariableStatementSyntax fo ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); - ITypeSymbol typeSymbol = info.ElementType; + ITypeSymbol? typeSymbol = info.ElementType; if (typeSymbol is null) return false; @@ -895,7 +903,7 @@ public static bool IsExplicitThatCanBeImplicit(ForEachStatementSyntax forEachSta ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); - ITypeSymbol typeSymbol = info.ElementType; + ITypeSymbol? typeSymbol = info.ElementType; if (typeSymbol is null) return false; @@ -945,7 +953,7 @@ private static bool IsExplicitThatCanBeImplicit( ForEachStatementInfo info = semanticModel.GetForEachStatementInfo(forEachStatement); - ITypeSymbol typeSymbol = info.ElementType; + ITypeSymbol? typeSymbol = info.ElementType; if (typeSymbol is null) return false; diff --git a/src/CSharp/CSharp/CSharpUtility.cs b/src/CSharp/CSharp/CSharpUtility.cs index a03d623f73..d0e5e36ba6 100644 --- a/src/CSharp/CSharp/CSharpUtility.cs +++ b/src/CSharp/CSharp/CSharpUtility.cs @@ -18,21 +18,21 @@ public static bool IsNullableReferenceType( { if (type.IsKind(SyntaxKind.NullableType)) { - ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); + ITypeSymbol? typeSymbol = semanticModel.GetTypeSymbol(type, cancellationToken); - return !typeSymbol.IsKind(SymbolKind.ErrorType) + return typeSymbol?.IsKind(SymbolKind.ErrorType) == false && typeSymbol.IsReferenceType; } return false; } - public static string GetCountOrLengthPropertyName( + public static string? GetCountOrLengthPropertyName( ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken = default) { - ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); + ITypeSymbol? typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (typeSymbol is null) return null; @@ -109,7 +109,7 @@ private static bool IsNamespace( { if (name is not null) { - ISymbol symbol = semanticModel.GetSymbol(name, cancellationToken); + ISymbol? symbol = semanticModel.GetSymbol(name, cancellationToken); if (symbol?.Kind == SymbolKind.Namespace) { @@ -199,7 +199,7 @@ public static bool IsEmptyStringExpression( if (memberAccess.Name?.Identifier.ValueText == "Empty") { - ISymbol symbol = semanticModel.GetSymbol(memberAccess, cancellationToken); + ISymbol? symbol = semanticModel.GetSymbol(memberAccess, cancellationToken); if (symbol?.Kind == SymbolKind.Field) { @@ -215,7 +215,7 @@ public static bool IsEmptyStringExpression( } } - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); if (optional.HasValue) { @@ -273,7 +273,7 @@ public static bool IsStringLiteralConcatenation(BinaryExpressionSyntax binaryExp if (binaryExpression.Right?.WalkDownParentheses().Kind() != SyntaxKind.StringLiteralExpression) return false; - ExpressionSyntax left = binaryExpression.Left?.WalkDownParentheses(); + ExpressionSyntax? left = binaryExpression.Left?.WalkDownParentheses(); switch (left?.Kind()) { @@ -366,7 +366,7 @@ public static SyntaxToken GetIdentifier(SyntaxNode node) public static bool IsPartOfExpressionThatMustBeConstant(ExpressionSyntax expression) { - for (SyntaxNode parent = expression.Parent; parent is not null; parent = parent.Parent) + for (SyntaxNode? parent = expression.Parent; parent is not null; parent = parent.Parent) { switch (parent.Kind()) { @@ -472,102 +472,7 @@ public static bool IsPartOfExpressionThatMustBeConstant(ExpressionSyntax express return false; } - public static IEnumerable EnumerateExpressionChain(ExpressionSyntax expression) - { - SyntaxNode e = expression; - - yield return e; - - while (true) - { - ExpressionSyntax last = GetLastChild(e); - - if (last is not null) - { - e = last; - } - else - { - while (e != expression - && IsFirstChild(e)) - { - e = e.Parent; - } - - if (e == expression) - break; - - e = GetPreviousSibling(e); - } - - yield return e; - } - - static ExpressionSyntax GetLastChild(SyntaxNode node) - { - switch (node?.Kind()) - { - case SyntaxKind.ConditionalAccessExpression: - return ((ConditionalAccessExpressionSyntax)node).WhenNotNull; - case SyntaxKind.MemberBindingExpression: - return ((MemberBindingExpressionSyntax)node).Name; - case SyntaxKind.SimpleMemberAccessExpression: - return ((MemberAccessExpressionSyntax)node).Name; - case SyntaxKind.ElementAccessExpression: - return ((ElementAccessExpressionSyntax)node).Expression; - case SyntaxKind.InvocationExpression: - return ((InvocationExpressionSyntax)node).Expression; - } - - return null; - } - - static SyntaxNode GetPreviousSibling(SyntaxNode node) - { - SyntaxNode parent = node.Parent; - - switch (parent.Kind()) - { - case SyntaxKind.ConditionalAccessExpression: - { - var conditionalAccess = (ConditionalAccessExpressionSyntax)parent; - - if (conditionalAccess.WhenNotNull == node) - return conditionalAccess.Expression; - - break; - } - case SyntaxKind.SimpleMemberAccessExpression: - { - var memberAccess = (MemberAccessExpressionSyntax)parent; - - if (memberAccess.Name == node) - return memberAccess.Expression; - - break; - } - } - - return null; - } - - static bool IsFirstChild(SyntaxNode node) - { - SyntaxNode parent = node.Parent; - - switch (parent.Kind()) - { - case SyntaxKind.ConditionalAccessExpression: - return ((ConditionalAccessExpressionSyntax)parent).Expression == node; - case SyntaxKind.SimpleMemberAccessExpression: - return ((MemberAccessExpressionSyntax)parent).Expression == node; - } - - return true; - } - } - - public static ArrowExpressionClauseSyntax GetExpressionBody(SyntaxNode node) + public static ArrowExpressionClauseSyntax? GetExpressionBody(SyntaxNode node) { switch (node.Kind()) { @@ -603,7 +508,7 @@ public static bool IsConditionallyAccessed(SyntaxNode node) { SyntaxNode prev = node; - for (SyntaxNode parent = node.Parent; parent is not null; parent = parent.Parent) + for (SyntaxNode? parent = node.Parent; parent is not null; parent = parent.Parent) { switch (parent.Kind()) { @@ -642,7 +547,7 @@ public static ExpressionSyntax GetTopmostExpressionInCallChain(ExpressionSyntax SyntaxKind.InvocationExpression)); } - internal static IFieldSymbol FindEnumDefaultField(INamedTypeSymbol enumSymbol) + internal static IFieldSymbol? FindEnumDefaultField(INamedTypeSymbol enumSymbol) { if (enumSymbol is null) throw new ArgumentNullException(nameof(enumSymbol)); @@ -667,7 +572,7 @@ internal static IFieldSymbol FindEnumDefaultField(INamedTypeSymbol enumSymbol) return default; } - public static TypeSyntax GetTypeOrReturnType(SyntaxNode node) + public static TypeSyntax? GetTypeOrReturnType(SyntaxNode node) { switch (node.Kind()) { @@ -722,7 +627,7 @@ public static SeparatedSyntaxList GetParameters(SyntaxNode decl return GetParameterList(declaration)?.Parameters ?? default; } - public static BaseParameterListSyntax GetParameterList(SyntaxNode declaration) + public static BaseParameterListSyntax? GetParameterList(SyntaxNode declaration) { switch (declaration.Kind()) { @@ -753,7 +658,7 @@ public static SeparatedSyntaxList GetTypeParameters(SyntaxN return GetTypeParameterList(declaration)?.Parameters ?? default; } - public static TypeParameterListSyntax GetTypeParameterList(SyntaxNode declaration) + public static TypeParameterListSyntax? GetTypeParameterList(SyntaxNode declaration) { switch (declaration.Kind()) { diff --git a/src/CSharp/CSharp/Documentation/AddBaseOrNewDocumentationCommentRewriter.cs b/src/CSharp/CSharp/Documentation/AddBaseOrNewDocumentationCommentRewriter.cs index e66149ee1e..ca6dd090c1 100644 --- a/src/CSharp/CSharp/Documentation/AddBaseOrNewDocumentationCommentRewriter.cs +++ b/src/CSharp/CSharp/Documentation/AddBaseOrNewDocumentationCommentRewriter.cs @@ -9,7 +9,7 @@ namespace Roslynator.CSharp.Documentation; internal class AddBaseOrNewDocumentationCommentRewriter : AddNewDocumentationCommentRewriter { - public AddBaseOrNewDocumentationCommentRewriter(SemanticModel semanticModel, DocumentationCommentGeneratorSettings settings = null, bool skipNamespaceDeclaration = true, CancellationToken cancellationToken = default) + public AddBaseOrNewDocumentationCommentRewriter(SemanticModel semanticModel, DocumentationCommentGeneratorSettings? settings = null, bool skipNamespaceDeclaration = true, CancellationToken cancellationToken = default) : base(settings, skipNamespaceDeclaration) { SemanticModel = semanticModel; diff --git a/src/CSharp/CSharp/Documentation/AddNewDocumentationCommentRewriter.cs b/src/CSharp/CSharp/Documentation/AddNewDocumentationCommentRewriter.cs index d70cdc01f8..1a73c23c9b 100644 --- a/src/CSharp/CSharp/Documentation/AddNewDocumentationCommentRewriter.cs +++ b/src/CSharp/CSharp/Documentation/AddNewDocumentationCommentRewriter.cs @@ -11,7 +11,7 @@ namespace Roslynator.CSharp.Documentation; internal class AddNewDocumentationCommentRewriter : CSharpSyntaxRewriter { - public AddNewDocumentationCommentRewriter(DocumentationCommentGeneratorSettings settings = null, bool skipNamespaceDeclaration = true) + public AddNewDocumentationCommentRewriter(DocumentationCommentGeneratorSettings? settings = null, bool skipNamespaceDeclaration = true) { Settings = settings ?? DocumentationCommentGeneratorSettings.Default; SkipNamespaceDeclaration = skipNamespaceDeclaration; @@ -33,7 +33,7 @@ public override SyntaxNode VisitNamespaceDeclaration(NamespaceDeclarationSyntax throw new ArgumentNullException(nameof(node)); } - node = (NamespaceDeclarationSyntax)base.VisitNamespaceDeclaration(node); + node = (NamespaceDeclarationSyntax)base.VisitNamespaceDeclaration(node)!; if (!SkipNamespaceDeclaration && !node.HasDocumentationComment()) @@ -50,7 +50,7 @@ public override SyntaxNode VisitClassDeclaration(ClassDeclarationSyntax node) { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (ClassDeclarationSyntax)base.VisitClassDeclaration(node); + node = (ClassDeclarationSyntax)base.VisitClassDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -67,7 +67,7 @@ public override SyntaxNode VisitStructDeclaration(StructDeclarationSyntax node) { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (StructDeclarationSyntax)base.VisitStructDeclaration(node); + node = (StructDeclarationSyntax)base.VisitStructDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -84,7 +84,7 @@ public override SyntaxNode VisitInterfaceDeclaration(InterfaceDeclarationSyntax { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (InterfaceDeclarationSyntax)base.VisitInterfaceDeclaration(node); + node = (InterfaceDeclarationSyntax)base.VisitInterfaceDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -101,7 +101,7 @@ public override SyntaxNode VisitEnumDeclaration(EnumDeclarationSyntax node) { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (EnumDeclarationSyntax)base.VisitEnumDeclaration(node); + node = (EnumDeclarationSyntax)base.VisitEnumDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -118,7 +118,7 @@ public override SyntaxNode VisitDelegateDeclaration(DelegateDeclarationSyntax no { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (DelegateDeclarationSyntax)base.VisitDelegateDeclaration(node); + node = (DelegateDeclarationSyntax)base.VisitDelegateDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -135,7 +135,7 @@ public override SyntaxNode VisitEnumMemberDeclaration(EnumMemberDeclarationSynta { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (EnumMemberDeclarationSyntax)base.VisitEnumMemberDeclaration(node); + node = (EnumMemberDeclarationSyntax)base.VisitEnumMemberDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -152,7 +152,7 @@ public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node) { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (FieldDeclarationSyntax)base.VisitFieldDeclaration(node); + node = (FieldDeclarationSyntax)base.VisitFieldDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -169,7 +169,7 @@ public override SyntaxNode VisitEventFieldDeclaration(EventFieldDeclarationSynta { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (EventFieldDeclarationSyntax)base.VisitEventFieldDeclaration(node); + node = (EventFieldDeclarationSyntax)base.VisitEventFieldDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -186,7 +186,7 @@ public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node); + node = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -203,7 +203,7 @@ public override SyntaxNode VisitOperatorDeclaration(OperatorDeclarationSyntax no { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (OperatorDeclarationSyntax)base.VisitOperatorDeclaration(node); + node = (OperatorDeclarationSyntax)base.VisitOperatorDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -220,7 +220,7 @@ public override SyntaxNode VisitConversionOperatorDeclaration(ConversionOperator { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (ConversionOperatorDeclarationSyntax)base.VisitConversionOperatorDeclaration(node); + node = (ConversionOperatorDeclarationSyntax)base.VisitConversionOperatorDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -237,7 +237,7 @@ public override SyntaxNode VisitConstructorDeclaration(ConstructorDeclarationSyn { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (ConstructorDeclarationSyntax)base.VisitConstructorDeclaration(node); + node = (ConstructorDeclarationSyntax)base.VisitConstructorDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -254,7 +254,7 @@ public override SyntaxNode VisitDestructorDeclaration(DestructorDeclarationSynta { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (DestructorDeclarationSyntax)base.VisitDestructorDeclaration(node); + node = (DestructorDeclarationSyntax)base.VisitDestructorDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -271,7 +271,7 @@ public override SyntaxNode VisitPropertyDeclaration(PropertyDeclarationSyntax no { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (PropertyDeclarationSyntax)base.VisitPropertyDeclaration(node); + node = (PropertyDeclarationSyntax)base.VisitPropertyDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -288,7 +288,7 @@ public override SyntaxNode VisitEventDeclaration(EventDeclarationSyntax node) { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (EventDeclarationSyntax)base.VisitEventDeclaration(node); + node = (EventDeclarationSyntax)base.VisitEventDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) @@ -305,7 +305,7 @@ public override SyntaxNode VisitIndexerDeclaration(IndexerDeclarationSyntax node { bool isPubliclyVisible = IsPubliclyVisible(node); - node = (IndexerDeclarationSyntax)base.VisitIndexerDeclaration(node); + node = (IndexerDeclarationSyntax)base.VisitIndexerDeclaration(node)!; if (isPubliclyVisible && !node.HasDocumentationComment()) diff --git a/src/CSharp/CSharp/Documentation/DocumentationCommentGenerator.cs b/src/CSharp/CSharp/Documentation/DocumentationCommentGenerator.cs index 1c28ae15dc..28ac3fecf6 100644 --- a/src/CSharp/CSharp/Documentation/DocumentationCommentGenerator.cs +++ b/src/CSharp/CSharp/Documentation/DocumentationCommentGenerator.cs @@ -21,7 +21,7 @@ internal static class DocumentationCommentGenerator { private static readonly XmlReaderSettings _xmlReaderSettings = new() { ConformanceLevel = ConformanceLevel.Fragment }; - public static SyntaxTriviaList Generate(MemberDeclarationSyntax memberDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(MemberDeclarationSyntax memberDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (memberDeclaration is null) throw new ArgumentNullException(nameof(memberDeclaration)); @@ -70,7 +70,7 @@ public static SyntaxTriviaList Generate(MemberDeclarationSyntax memberDeclaratio } } - public static SyntaxTriviaList Generate(NamespaceDeclarationSyntax namespaceDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(NamespaceDeclarationSyntax namespaceDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (namespaceDeclaration is null) throw new ArgumentNullException(nameof(namespaceDeclaration)); @@ -78,7 +78,7 @@ public static SyntaxTriviaList Generate(NamespaceDeclarationSyntax namespaceDecl return Generate(settings: settings); } - public static SyntaxTriviaList Generate(ClassDeclarationSyntax classDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(ClassDeclarationSyntax classDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (classDeclaration is null) throw new ArgumentNullException(nameof(classDeclaration)); @@ -90,7 +90,7 @@ public static SyntaxTriviaList Generate(ClassDeclarationSyntax classDeclaration, settings: settings); } - public static SyntaxTriviaList Generate(RecordDeclarationSyntax recordDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(RecordDeclarationSyntax recordDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (recordDeclaration is null) throw new ArgumentNullException(nameof(recordDeclaration)); @@ -102,7 +102,7 @@ public static SyntaxTriviaList Generate(RecordDeclarationSyntax recordDeclaratio settings: settings); } - public static SyntaxTriviaList Generate(StructDeclarationSyntax structDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(StructDeclarationSyntax structDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (structDeclaration is null) throw new ArgumentNullException(nameof(structDeclaration)); @@ -114,7 +114,7 @@ public static SyntaxTriviaList Generate(StructDeclarationSyntax structDeclaratio settings: settings); } - public static SyntaxTriviaList Generate(InterfaceDeclarationSyntax interfaceDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(InterfaceDeclarationSyntax interfaceDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (interfaceDeclaration is null) throw new ArgumentNullException(nameof(interfaceDeclaration)); @@ -126,7 +126,7 @@ public static SyntaxTriviaList Generate(InterfaceDeclarationSyntax interfaceDecl settings: settings); } - public static SyntaxTriviaList Generate(EnumDeclarationSyntax enumDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(EnumDeclarationSyntax enumDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (enumDeclaration is null) throw new ArgumentNullException(nameof(enumDeclaration)); @@ -134,7 +134,7 @@ public static SyntaxTriviaList Generate(EnumDeclarationSyntax enumDeclaration, D return Generate(settings: settings); } - public static SyntaxTriviaList Generate(DelegateDeclarationSyntax delegateDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(DelegateDeclarationSyntax delegateDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (delegateDeclaration is null) throw new ArgumentNullException(nameof(delegateDeclaration)); @@ -146,7 +146,7 @@ public static SyntaxTriviaList Generate(DelegateDeclarationSyntax delegateDeclar settings: settings); } - public static SyntaxTriviaList Generate(EnumMemberDeclarationSyntax enumMemberDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(EnumMemberDeclarationSyntax enumMemberDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (enumMemberDeclaration is null) throw new ArgumentNullException(nameof(enumMemberDeclaration)); @@ -154,7 +154,7 @@ public static SyntaxTriviaList Generate(EnumMemberDeclarationSyntax enumMemberDe return Generate(settings: settings); } - public static SyntaxTriviaList Generate(FieldDeclarationSyntax fieldDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(FieldDeclarationSyntax fieldDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (fieldDeclaration is null) throw new ArgumentNullException(nameof(fieldDeclaration)); @@ -162,7 +162,7 @@ public static SyntaxTriviaList Generate(FieldDeclarationSyntax fieldDeclaration, return Generate(settings: settings); } - public static SyntaxTriviaList Generate(EventFieldDeclarationSyntax eventFieldDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(EventFieldDeclarationSyntax eventFieldDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (eventFieldDeclaration is null) throw new ArgumentNullException(nameof(eventFieldDeclaration)); @@ -170,7 +170,7 @@ public static SyntaxTriviaList Generate(EventFieldDeclarationSyntax eventFieldDe return Generate(settings: settings); } - public static SyntaxTriviaList Generate(MethodDeclarationSyntax methodDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(MethodDeclarationSyntax methodDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (methodDeclaration is null) throw new ArgumentNullException(nameof(methodDeclaration)); @@ -182,7 +182,7 @@ public static SyntaxTriviaList Generate(MethodDeclarationSyntax methodDeclaratio settings: settings); } - public static SyntaxTriviaList Generate(OperatorDeclarationSyntax operatorDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(OperatorDeclarationSyntax operatorDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (operatorDeclaration is null) throw new ArgumentNullException(nameof(operatorDeclaration)); @@ -194,7 +194,7 @@ public static SyntaxTriviaList Generate(OperatorDeclarationSyntax operatorDeclar settings: settings); } - public static SyntaxTriviaList Generate(ConversionOperatorDeclarationSyntax conversionOperatorDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(ConversionOperatorDeclarationSyntax conversionOperatorDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (conversionOperatorDeclaration is null) throw new ArgumentNullException(nameof(conversionOperatorDeclaration)); @@ -206,7 +206,7 @@ public static SyntaxTriviaList Generate(ConversionOperatorDeclarationSyntax conv settings: settings); } - public static SyntaxTriviaList Generate(ConstructorDeclarationSyntax constructorDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(ConstructorDeclarationSyntax constructorDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (constructorDeclaration is null) throw new ArgumentNullException(nameof(constructorDeclaration)); @@ -218,7 +218,7 @@ public static SyntaxTriviaList Generate(ConstructorDeclarationSyntax constructor settings: settings); } - public static SyntaxTriviaList Generate(DestructorDeclarationSyntax destructorDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(DestructorDeclarationSyntax destructorDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (destructorDeclaration is null) throw new ArgumentNullException(nameof(destructorDeclaration)); @@ -226,7 +226,7 @@ public static SyntaxTriviaList Generate(DestructorDeclarationSyntax destructorDe return Generate(settings: settings); } - public static SyntaxTriviaList Generate(PropertyDeclarationSyntax propertyDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(PropertyDeclarationSyntax propertyDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (propertyDeclaration is null) throw new ArgumentNullException(nameof(propertyDeclaration)); @@ -234,7 +234,7 @@ public static SyntaxTriviaList Generate(PropertyDeclarationSyntax propertyDeclar return Generate(settings: settings); } - public static SyntaxTriviaList Generate(EventDeclarationSyntax eventDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(EventDeclarationSyntax eventDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (eventDeclaration is null) throw new ArgumentNullException(nameof(eventDeclaration)); @@ -242,7 +242,7 @@ public static SyntaxTriviaList Generate(EventDeclarationSyntax eventDeclaration, return Generate(settings: settings); } - public static SyntaxTriviaList Generate(IndexerDeclarationSyntax indexerDeclaration, DocumentationCommentGeneratorSettings settings = null) + public static SyntaxTriviaList Generate(IndexerDeclarationSyntax indexerDeclaration, DocumentationCommentGeneratorSettings? settings = null) { if (indexerDeclaration is null) throw new ArgumentNullException(nameof(indexerDeclaration)); @@ -255,10 +255,10 @@ public static SyntaxTriviaList Generate(IndexerDeclarationSyntax indexerDeclarat } private static SyntaxTriviaList Generate( - TypeParameterListSyntax typeParameterList, - BaseParameterListSyntax parameterList, + TypeParameterListSyntax? typeParameterList, + BaseParameterListSyntax? parameterList, bool canGenerateReturns = false, - DocumentationCommentGeneratorSettings settings = null) + DocumentationCommentGeneratorSettings? settings = null) { SeparatedSyntaxList typeParameters = typeParameterList?.Parameters ?? default; @@ -271,7 +271,7 @@ private static SyntaxTriviaList Generate( SeparatedSyntaxList typeParameters = default, SeparatedSyntaxList parameters = default, bool canGenerateReturns = false, - DocumentationCommentGeneratorSettings settings = null) + DocumentationCommentGeneratorSettings? settings = null) { settings ??= DocumentationCommentGeneratorSettings.Default; @@ -391,11 +391,11 @@ internal static DocumentationCommentData GenerateFromBase(MethodDeclarationSynta return default; } - IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); + IMethodSymbol? methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); if (methodSymbol?.IsErrorType() == false) { - string xml = GenerateFromOverriddenMethods(methodSymbol, cancellationToken); + string? xml = GenerateFromOverriddenMethods(methodSymbol, cancellationToken); if (xml is not null) return new DocumentationCommentData(xml, DocumentationCommentOrigin.BaseMember); @@ -418,7 +418,7 @@ internal static DocumentationCommentData GenerateFromBase(PropertyDeclarationSyn return default; } - IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken); + IPropertySymbol? propertySymbol = semanticModel.GetDeclaredSymbol(propertyDeclaration, cancellationToken); return GenerateFromBase(propertySymbol, cancellationToken); } @@ -432,16 +432,16 @@ internal static DocumentationCommentData GenerateFromBase(IndexerDeclarationSynt return default; } - IPropertySymbol propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken); + IPropertySymbol? propertySymbol = semanticModel.GetDeclaredSymbol(indexerDeclaration, cancellationToken); return GenerateFromBase(propertySymbol, cancellationToken); } - private static DocumentationCommentData GenerateFromBase(IPropertySymbol propertySymbol, CancellationToken cancellationToken) + private static DocumentationCommentData GenerateFromBase(IPropertySymbol? propertySymbol, CancellationToken cancellationToken) { if (propertySymbol?.IsErrorType() == false) { - string xml = GenerateFromOverriddenProperties(propertySymbol, cancellationToken); + string? xml = GenerateFromOverriddenProperties(propertySymbol, cancellationToken); if (xml is not null) return new DocumentationCommentData(xml, DocumentationCommentOrigin.BaseMember); @@ -464,7 +464,7 @@ internal static DocumentationCommentData GenerateFromBase(EventDeclarationSyntax return default; } - IEventSymbol eventSymbol = semanticModel.GetDeclaredSymbol(eventDeclaration, cancellationToken); + IEventSymbol? eventSymbol = semanticModel.GetDeclaredSymbol(eventDeclaration, cancellationToken); return GenerateFromBase(eventSymbol, cancellationToken); } @@ -477,7 +477,7 @@ internal static DocumentationCommentData GenerateFromBase(EventFieldDeclarationS return default; } - VariableDeclaratorSyntax variableDeclarator = eventFieldDeclaration.Declaration?.Variables.FirstOrDefault(); + VariableDeclaratorSyntax? variableDeclarator = eventFieldDeclaration.Declaration?.Variables.FirstOrDefault(); if (variableDeclarator is not null) { @@ -489,11 +489,11 @@ internal static DocumentationCommentData GenerateFromBase(EventFieldDeclarationS return default; } - private static DocumentationCommentData GenerateFromBase(IEventSymbol eventSymbol, CancellationToken cancellationToken) + private static DocumentationCommentData GenerateFromBase(IEventSymbol? eventSymbol, CancellationToken cancellationToken) { if (eventSymbol?.IsErrorType() == false) { - string xml = GenerateFromOverriddenEvents(eventSymbol, cancellationToken); + string? xml = GenerateFromOverriddenEvents(eventSymbol, cancellationToken); if (xml is not null) return new DocumentationCommentData(xml, DocumentationCommentOrigin.BaseMember); @@ -509,15 +509,15 @@ private static DocumentationCommentData GenerateFromBase(IEventSymbol eventSymbo internal static DocumentationCommentData GenerateFromBase(ConstructorDeclarationSyntax constructorDeclaration, SemanticModel semanticModel, CancellationToken cancellationToken = default) { - ConstructorInitializerSyntax initializer = constructorDeclaration.Initializer; + ConstructorInitializerSyntax? initializer = constructorDeclaration.Initializer; if (initializer?.Kind() == SyntaxKind.BaseConstructorInitializer) { - ISymbol baseConstructor = semanticModel.GetSymbol(initializer, cancellationToken); + ISymbol? baseConstructor = semanticModel.GetSymbol(initializer, cancellationToken); if (baseConstructor?.IsErrorType() == false) { - string xml = GetDocumentationCommentXml(baseConstructor, cancellationToken); + string? xml = GetDocumentationCommentXml(baseConstructor, cancellationToken); if (xml is not null) return new DocumentationCommentData(xml, DocumentationCommentOrigin.BaseMember); @@ -527,11 +527,11 @@ internal static DocumentationCommentData GenerateFromBase(ConstructorDeclaration return default; } - private static string GenerateFromOverriddenMethods(IMethodSymbol methodSymbol, CancellationToken cancellationToken) + private static string? GenerateFromOverriddenMethods(IMethodSymbol methodSymbol, CancellationToken cancellationToken) { - for (IMethodSymbol overriddenMethod = methodSymbol.OverriddenMethod; overriddenMethod is not null; overriddenMethod = overriddenMethod.OverriddenMethod) + for (IMethodSymbol? overriddenMethod = methodSymbol.OverriddenMethod; overriddenMethod is not null; overriddenMethod = overriddenMethod.OverriddenMethod) { - string xml = GetDocumentationCommentXml(overriddenMethod, cancellationToken); + string? xml = GetDocumentationCommentXml(overriddenMethod, cancellationToken); if (xml is not null) return xml; @@ -540,11 +540,11 @@ private static string GenerateFromOverriddenMethods(IMethodSymbol methodSymbol, return null; } - private static string GenerateFromOverriddenProperties(IPropertySymbol propertySymbol, CancellationToken cancellationToken) + private static string? GenerateFromOverriddenProperties(IPropertySymbol propertySymbol, CancellationToken cancellationToken) { - for (IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty; overriddenProperty is not null; overriddenProperty = overriddenProperty.OverriddenProperty) + for (IPropertySymbol? overriddenProperty = propertySymbol.OverriddenProperty; overriddenProperty is not null; overriddenProperty = overriddenProperty.OverriddenProperty) { - string xml = GetDocumentationCommentXml(overriddenProperty, cancellationToken); + string? xml = GetDocumentationCommentXml(overriddenProperty, cancellationToken); if (xml is not null) return xml; @@ -553,11 +553,11 @@ private static string GenerateFromOverriddenProperties(IPropertySymbol propertyS return null; } - private static string GenerateFromOverriddenEvents(IEventSymbol eventSymbol, CancellationToken cancellationToken) + private static string? GenerateFromOverriddenEvents(IEventSymbol eventSymbol, CancellationToken cancellationToken) { - for (IEventSymbol overriddenEvent = eventSymbol.OverriddenEvent; overriddenEvent is not null; overriddenEvent = overriddenEvent.OverriddenEvent) + for (IEventSymbol? overriddenEvent = eventSymbol.OverriddenEvent; overriddenEvent is not null; overriddenEvent = overriddenEvent.OverriddenEvent) { - string xml = GetDocumentationCommentXml(overriddenEvent, cancellationToken); + string? xml = GetDocumentationCommentXml(overriddenEvent, cancellationToken); if (xml is not null) return xml; @@ -566,15 +566,15 @@ private static string GenerateFromOverriddenEvents(IEventSymbol eventSymbol, Can return null; } - private static string GenerateFromInterfaceMember( + private static string? GenerateFromInterfaceMember( ISymbol memberSymbol, CancellationToken cancellationToken) where TInterfaceSymbol : ISymbol { - TInterfaceSymbol interfaceMember = memberSymbol.FindFirstImplementedInterfaceMember(); + TInterfaceSymbol? interfaceMember = memberSymbol.FindFirstImplementedInterfaceMember(); - if (!EqualityComparer.Default.Equals(interfaceMember, default)) + if (!EqualityComparer.Default.Equals(interfaceMember!, default!)) { - return GetDocumentationCommentXml(interfaceMember, cancellationToken); + return GetDocumentationCommentXml(interfaceMember!, cancellationToken); } else { @@ -582,9 +582,9 @@ private static string GenerateFromInterfaceMember( } } - private static string GetDocumentationCommentXml(ISymbol symbol, CancellationToken cancellationToken = default) + private static string? GetDocumentationCommentXml(ISymbol symbol, CancellationToken cancellationToken = default) { - string xml = symbol.GetDocumentationCommentXml(cancellationToken: cancellationToken); + string? xml = symbol.GetDocumentationCommentXml(cancellationToken: cancellationToken); if (xml is null) return null; @@ -626,9 +626,9 @@ private static string GetDocumentationCommentXml(ISymbol symbol, CancellationTok private static bool ContainingTypeHasBaseType(MemberDeclarationSyntax memberDeclaration) { - SyntaxNode parent = memberDeclaration.Parent; + SyntaxNode? parent = memberDeclaration.Parent; - switch (parent.Kind()) + switch (parent?.Kind()) { case SyntaxKind.ClassDeclaration: return ((ClassDeclarationSyntax)parent).BaseList?.Types.Any() == true; diff --git a/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaFactory.cs b/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaFactory.cs index 90f6c411a6..d09947594b 100644 --- a/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaFactory.cs +++ b/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaFactory.cs @@ -24,12 +24,12 @@ public static SyntaxTrivia Parse(string xml, SemanticModel semanticModel, int po SyntaxTrivia trivia = ParseLeadingTrivia(triviaText).Single(); - var commentTrivia = (DocumentationCommentTriviaSyntax)trivia.GetStructure(); + var commentTrivia = (DocumentationCommentTriviaSyntax)trivia.GetStructure()!; var rewriter = new DocumentationCommentTriviaRewriter(position, semanticModel); // Remove T: from cref attribute and replace `1 with {T} - commentTrivia = (DocumentationCommentTriviaSyntax)rewriter.VisitDocumentationCommentTrivia(commentTrivia); + commentTrivia = (DocumentationCommentTriviaSyntax)rewriter.VisitDocumentationCommentTrivia(commentTrivia)!; // Remove element commentTrivia = RemoveFilterPriorityElement(commentTrivia); @@ -64,7 +64,7 @@ private static string AddSlashes(string innerXml) { StringBuilder sb = StringBuilderCache.GetInstance(); - string indent = null; + string? indent = null; using (var sr = new StringReader(innerXml)) { diff --git a/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaRewriter.cs b/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaRewriter.cs index 9d2aa38f27..e8948b2620 100644 --- a/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaRewriter.cs +++ b/src/CSharp/CSharp/Documentation/DocumentationCommentTriviaRewriter.cs @@ -51,12 +51,12 @@ public override SyntaxNode VisitXmlTextAttribute(XmlTextAttributeSyntax node) } } - return base.VisitXmlTextAttribute(node); + return base.VisitXmlTextAttribute(node)!; } private string GetMinimalDisplayString(string metadataName) { - INamedTypeSymbol typeSymbol = _semanticModel.GetTypeByMetadataName(metadataName); + INamedTypeSymbol? typeSymbol = _semanticModel.GetTypeByMetadataName(metadataName); if (typeSymbol is not null) { diff --git a/src/CSharp/CSharp/EnumMemberDeclarationValueComparer.cs b/src/CSharp/CSharp/EnumMemberDeclarationValueComparer.cs index 6797771bd5..e5881d1a10 100644 --- a/src/CSharp/CSharp/EnumMemberDeclarationValueComparer.cs +++ b/src/CSharp/CSharp/EnumMemberDeclarationValueComparer.cs @@ -39,7 +39,7 @@ public int Compare(EnumMemberDeclarationSyntax x, EnumMemberDeclarationSyntax y) _valueComparer); } - private static int Compare(IFieldSymbol fieldSymbol1, IFieldSymbol fieldSymbol2, IComparer comparer) + private static int Compare(IFieldSymbol? fieldSymbol1, IFieldSymbol? fieldSymbol2, IComparer comparer) { if (fieldSymbol1?.HasConstantValue == true && fieldSymbol2?.HasConstantValue == true) @@ -67,15 +67,15 @@ public static bool IsSorted( { if (en.MoveNext()) { - IFieldSymbol fieldSymbol1 = semanticModel.GetDeclaredSymbol(en.Current, cancellationToken); + IFieldSymbol fieldSymbol1 = semanticModel.GetDeclaredSymbol(en.Current, cancellationToken)!; - SpecialType enumSpecialType = fieldSymbol1.ContainingType.EnumUnderlyingType.SpecialType; + SpecialType enumSpecialType = fieldSymbol1.ContainingType.EnumUnderlyingType!.SpecialType; IComparer comparer = EnumValueComparer.GetInstance(enumSpecialType); while (en.MoveNext()) { - IFieldSymbol fieldSymbol2 = semanticModel.GetDeclaredSymbol(en.Current, cancellationToken); + IFieldSymbol fieldSymbol2 = semanticModel.GetDeclaredSymbol(en.Current, cancellationToken)!; if (Compare(fieldSymbol1, fieldSymbol2, comparer) > 0) return false; diff --git a/src/CSharp/CSharp/ExpressionChain.Reversed.cs b/src/CSharp/CSharp/ExpressionChain.Reversed.cs index ca58dc3994..57aed24121 100644 --- a/src/CSharp/CSharp/ExpressionChain.Reversed.cs +++ b/src/CSharp/CSharp/ExpressionChain.Reversed.cs @@ -39,7 +39,7 @@ internal bool IsStringConcatenation( if (!en.MoveNext()) return false; - var binaryExpression = (BinaryExpressionSyntax)en.Current.Parent; + var binaryExpression = (BinaryExpressionSyntax)en.Current.Parent!; if (!en.MoveNext()) return false; @@ -53,7 +53,7 @@ internal bool IsStringConcatenation( if (en.MoveNext()) { - binaryExpression = (BinaryExpressionSyntax)prev.Parent; + binaryExpression = (BinaryExpressionSyntax)prev.Parent!; } else { @@ -119,7 +119,7 @@ public override int GetHashCode() public struct Enumerator { private readonly ExpressionChain _chain; - private ExpressionSyntax _current; + private ExpressionSyntax? _current; private State _state; internal Enumerator(in ExpressionChain chain) @@ -191,7 +191,7 @@ public bool MoveNext() } case State.Right: { - var binaryExpression = (BinaryExpressionSyntax)_current.Parent; + var binaryExpression = (BinaryExpressionSyntax)_current!.Parent!; ExpressionSyntax left = binaryExpression.Left; diff --git a/src/CSharp/CSharp/ExpressionChain.cs b/src/CSharp/CSharp/ExpressionChain.cs index 7907e1eb60..5e92815d29 100644 --- a/src/CSharp/CSharp/ExpressionChain.cs +++ b/src/CSharp/CSharp/ExpressionChain.cs @@ -162,8 +162,8 @@ public override int GetHashCode() public struct Enumerator { private readonly ExpressionChain _chain; - private ExpressionSyntax _last; - private ExpressionSyntax _current; + private ExpressionSyntax? _last; + private ExpressionSyntax? _current; private State _state; internal Enumerator(in ExpressionChain chain) @@ -290,7 +290,7 @@ public bool MoveNext() return false; } - _current = ((BinaryExpressionSyntax)_current.Parent.Parent).Right; + _current = ((BinaryExpressionSyntax)_current!.Parent!.Parent!).Right; return true; } case State.Left: @@ -303,7 +303,7 @@ public bool MoveNext() return false; } - _current = ((BinaryExpressionSyntax)_current.Parent).Right; + _current = ((BinaryExpressionSyntax)_current!.Parent!).Right; _state = State.Right; return true; } diff --git a/src/CSharp/CSharp/Extensions/CSharpExtensions.cs b/src/CSharp/CSharp/Extensions/CSharpExtensions.cs index 7c49bfbe2a..103bacb2d8 100644 --- a/src/CSharp/CSharp/Extensions/CSharpExtensions.cs +++ b/src/CSharp/CSharp/Extensions/CSharpExtensions.cs @@ -20,12 +20,12 @@ public static class CSharpExtensions /// /// /// - internal static IMethodSymbol GetDeclaredSymbol( + internal static IMethodSymbol? GetDeclaredSymbol( this SemanticModel semanticModel, LocalFunctionStatementSyntax localFunction, CancellationToken cancellationToken = default) { - return (IMethodSymbol)ModelExtensions.GetDeclaredSymbol(semanticModel, localFunction, cancellationToken); + return (IMethodSymbol?)ModelExtensions.GetDeclaredSymbol(semanticModel, localFunction, cancellationToken); } /// @@ -34,7 +34,7 @@ internal static IMethodSymbol GetDeclaredSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, AttributeSyntax attribute, CancellationToken cancellationToken = default) @@ -50,7 +50,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, ConstructorInitializerSyntax constructorInitializer, CancellationToken cancellationToken = default) @@ -66,7 +66,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, CrefSyntax cref, CancellationToken cancellationToken = default) @@ -82,7 +82,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken = default) @@ -98,7 +98,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, OrderingSyntax ordering, CancellationToken cancellationToken = default) @@ -114,7 +114,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, SelectOrGroupClauseSyntax selectOrGroupClause, CancellationToken cancellationToken = default) @@ -130,7 +130,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ITypeSymbol GetTypeSymbol( + public static ITypeSymbol? GetTypeSymbol( this SemanticModel semanticModel, AttributeSyntax attribute, CancellationToken cancellationToken = default) @@ -146,7 +146,7 @@ public static ITypeSymbol GetTypeSymbol( /// /// /// - public static ITypeSymbol GetTypeSymbol( + public static ITypeSymbol? GetTypeSymbol( this SemanticModel semanticModel, ConstructorInitializerSyntax constructorInitializer, CancellationToken cancellationToken = default) @@ -162,7 +162,7 @@ public static ITypeSymbol GetTypeSymbol( /// /// /// - public static ITypeSymbol GetTypeSymbol( + public static ITypeSymbol? GetTypeSymbol( this SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken = default) @@ -178,7 +178,7 @@ public static ITypeSymbol GetTypeSymbol( /// /// /// - public static ITypeSymbol GetTypeSymbol( + public static ITypeSymbol? GetTypeSymbol( this SemanticModel semanticModel, SelectOrGroupClauseSyntax selectOrGroupClause, CancellationToken cancellationToken = default) @@ -255,7 +255,7 @@ internal static bool IsImplicitConversion( /// /// /// - public static IParameterSymbol DetermineParameter( + public static IParameterSymbol? DetermineParameter( this SemanticModel semanticModel, ArgumentSyntax argument, bool allowParams = false, @@ -280,7 +280,7 @@ public static IParameterSymbol DetermineParameter( /// /// /// - public static IParameterSymbol DetermineParameter( + public static IParameterSymbol? DetermineParameter( this SemanticModel semanticModel, AttributeArgumentSyntax attributeArgument, bool allowParams = false, @@ -350,7 +350,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Boolean: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is bool value @@ -358,7 +358,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Char: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is char value @@ -366,7 +366,7 @@ public static bool IsDefaultValue( } case SpecialType.System_SByte: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is sbyte value @@ -374,7 +374,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Byte: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is byte value @@ -382,7 +382,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Int16: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is short value @@ -390,7 +390,7 @@ public static bool IsDefaultValue( } case SpecialType.System_UInt16: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is ushort value @@ -398,7 +398,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Int32: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is int value @@ -406,7 +406,7 @@ public static bool IsDefaultValue( } case SpecialType.System_UInt32: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is uint value @@ -414,7 +414,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Int64: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is long value @@ -422,7 +422,7 @@ public static bool IsDefaultValue( } case SpecialType.System_UInt64: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is ulong value @@ -430,7 +430,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Decimal: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is decimal value @@ -438,7 +438,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Single: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is float value @@ -446,7 +446,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Double: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is double value @@ -458,11 +458,11 @@ public static bool IsDefaultValue( { var enumSymbol = (INamedTypeSymbol)typeSymbol; - switch (enumSymbol.EnumUnderlyingType.SpecialType) + switch (enumSymbol.EnumUnderlyingType!.SpecialType) { case SpecialType.System_SByte: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is sbyte value @@ -470,7 +470,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Byte: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is byte value @@ -478,7 +478,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Int16: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is short value @@ -486,7 +486,7 @@ public static bool IsDefaultValue( } case SpecialType.System_UInt16: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is ushort value @@ -494,7 +494,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Int32: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is int value @@ -502,7 +502,7 @@ public static bool IsDefaultValue( } case SpecialType.System_UInt32: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is uint value @@ -510,7 +510,7 @@ public static bool IsDefaultValue( } case SpecialType.System_Int64: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is long value @@ -518,7 +518,7 @@ public static bool IsDefaultValue( } case SpecialType.System_UInt64: { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); return optional.HasValue && optional.Value is ulong value @@ -533,7 +533,7 @@ public static bool IsDefaultValue( if (typeSymbol.IsReferenceTypeOrNullableType()) { - Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); + Optional optional = semanticModel.GetConstantValue(expression, cancellationToken); if (optional.HasValue) return optional.Value is null; @@ -556,7 +556,7 @@ public static ExtensionMethodSymbolInfo GetExtensionMethodInfo( if (GetSymbol(semanticModel, expression, cancellationToken) is IMethodSymbol methodSymbol && methodSymbol.IsExtensionMethod) { - IMethodSymbol reducedFrom = methodSymbol.ReducedFrom; + IMethodSymbol? reducedFrom = methodSymbol.ReducedFrom; if (reducedFrom is not null) return new ExtensionMethodSymbolInfo(reducedFrom, methodSymbol); @@ -581,7 +581,7 @@ public static ExtensionMethodSymbolInfo GetReducedExtensionMethodInfo( if (GetSymbol(semanticModel, expression, cancellationToken) is IMethodSymbol methodSymbol && methodSymbol.IsExtensionMethod) { - IMethodSymbol reducedFrom = methodSymbol.ReducedFrom; + IMethodSymbol? reducedFrom = methodSymbol.ReducedFrom; if (reducedFrom is not null) return new ExtensionMethodSymbolInfo(reducedFrom, methodSymbol); @@ -596,7 +596,7 @@ public static ExtensionMethodSymbolInfo GetReducedExtensionMethodInfo( /// /// /// - public static IMethodSymbol GetMethodSymbol( + public static IMethodSymbol? GetMethodSymbol( this SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken = default) @@ -604,14 +604,14 @@ public static IMethodSymbol GetMethodSymbol( return GetSymbol(semanticModel, expression, cancellationToken) as IMethodSymbol; } - internal static MethodDeclarationSyntax GetOtherPart( + internal static MethodDeclarationSyntax? GetOtherPart( this SemanticModel semanticModel, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken = default) { - IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); + IMethodSymbol? methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); - IMethodSymbol otherSymbol = methodSymbol.PartialDefinitionPart ?? methodSymbol.PartialImplementationPart; + IMethodSymbol? otherSymbol = methodSymbol?.PartialDefinitionPart ?? methodSymbol?.PartialImplementationPart; if (otherSymbol is not null) return (MethodDeclarationSyntax)otherSymbol.GetSyntax(cancellationToken); diff --git a/src/CSharp/CSharp/Extensions/SymbolExtensions.cs b/src/CSharp/CSharp/Extensions/SymbolExtensions.cs index 6ac9f125cc..3f963b2c6a 100644 --- a/src/CSharp/CSharp/Extensions/SymbolExtensions.cs +++ b/src/CSharp/CSharp/Extensions/SymbolExtensions.cs @@ -114,7 +114,7 @@ void AddSpace() /// /// /// - public static TypeSyntax ToTypeSyntax(this INamespaceOrTypeSymbol namespaceOrTypeSymbol, SymbolDisplayFormat format = null) + public static TypeSyntax ToTypeSyntax(this INamespaceOrTypeSymbol namespaceOrTypeSymbol, SymbolDisplayFormat? format = null) { if (namespaceOrTypeSymbol is null) throw new ArgumentNullException(nameof(namespaceOrTypeSymbol)); @@ -136,7 +136,7 @@ public static TypeSyntax ToTypeSyntax(this INamespaceOrTypeSymbol namespaceOrTyp /// /// /// - public static TypeSyntax ToMinimalTypeSyntax(this INamespaceOrTypeSymbol namespaceOrTypeSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat format = null) + public static TypeSyntax ToMinimalTypeSyntax(this INamespaceOrTypeSymbol namespaceOrTypeSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat? format = null) { if (namespaceOrTypeSymbol is null) throw new ArgumentNullException(nameof(namespaceOrTypeSymbol)); @@ -161,7 +161,7 @@ public static TypeSyntax ToMinimalTypeSyntax(this INamespaceOrTypeSymbol namespa /// /// /// - public static TypeSyntax ToTypeSyntax(this INamespaceSymbol namespaceSymbol, SymbolDisplayFormat format = null) + public static TypeSyntax ToTypeSyntax(this INamespaceSymbol namespaceSymbol, SymbolDisplayFormat? format = null) { if (namespaceSymbol is null) throw new ArgumentNullException(nameof(namespaceSymbol)); @@ -178,7 +178,7 @@ public static TypeSyntax ToTypeSyntax(this INamespaceSymbol namespaceSymbol, Sym /// /// /// - public static TypeSyntax ToMinimalTypeSyntax(this INamespaceSymbol namespaceSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat format = null) + public static TypeSyntax ToMinimalTypeSyntax(this INamespaceSymbol namespaceSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat? format = null) { if (namespaceSymbol is null) throw new ArgumentNullException(nameof(namespaceSymbol)); @@ -199,7 +199,7 @@ private static void ThrowIfExplicitDeclarationIsNotSupported(INamespaceSymbol na #endregion INamespaceSymbol #region IParameterSymbol - internal static ExpressionSyntax GetDefaultValueMinimalSyntax(this IParameterSymbol parameterSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat format = null) + internal static ExpressionSyntax GetDefaultValueMinimalSyntax(this IParameterSymbol parameterSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat? format = null) { if (parameterSymbol is null) throw new ArgumentNullException(nameof(parameterSymbol)); @@ -207,7 +207,7 @@ internal static ExpressionSyntax GetDefaultValueMinimalSyntax(this IParameterSym if (!parameterSymbol.HasExplicitDefaultValue) throw new ArgumentException("Parameter does not specify default value.", nameof(parameterSymbol)); - object value = parameterSymbol.ExplicitDefaultValue; + object? value = parameterSymbol.ExplicitDefaultValue; ITypeSymbol typeSymbol = parameterSymbol.Type; @@ -216,7 +216,7 @@ internal static ExpressionSyntax GetDefaultValueMinimalSyntax(this IParameterSym if (value is null) return NullLiteralExpression(); - IFieldSymbol fieldSymbol = FindFieldWithConstantValue(); + IFieldSymbol? fieldSymbol = FindFieldWithConstantValue(); TypeSyntax type = typeSymbol.ToMinimalTypeSyntax(semanticModel, position, format); @@ -238,7 +238,7 @@ internal static ExpressionSyntax GetDefaultValueMinimalSyntax(this IParameterSym return LiteralExpression(value); - IFieldSymbol FindFieldWithConstantValue() + IFieldSymbol? FindFieldWithConstantValue() { foreach (ISymbol symbol in typeSymbol.GetMembers()) { @@ -265,7 +265,7 @@ IFieldSymbol FindFieldWithConstantValue() /// /// /// - public static TypeSyntax ToTypeSyntax(this ITypeSymbol typeSymbol, SymbolDisplayFormat format = null) + public static TypeSyntax ToTypeSyntax(this ITypeSymbol typeSymbol, SymbolDisplayFormat? format = null) { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -282,7 +282,7 @@ public static TypeSyntax ToTypeSyntax(this ITypeSymbol typeSymbol, SymbolDisplay /// /// /// - public static TypeSyntax ToMinimalTypeSyntax(this ITypeSymbol typeSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat format = null) + public static TypeSyntax ToMinimalTypeSyntax(this ITypeSymbol typeSymbol, SemanticModel semanticModel, int position, SymbolDisplayFormat? format = null) { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); diff --git a/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs b/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs index 01348db94c..da35934277 100644 --- a/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs +++ b/src/CSharp/CSharp/Extensions/SyntaxExtensions.cs @@ -40,12 +40,12 @@ public static bool IsAutoImplemented(this AccessorDeclarationSyntax accessorDecl /// Returns accessor body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this AccessorDeclarationSyntax accessorDeclaration) + public static CSharpSyntaxNode? BodyOrExpressionBody(this AccessorDeclarationSyntax accessorDeclaration) { if (accessorDeclaration is null) throw new ArgumentNullException(nameof(accessorDeclaration)); - return accessorDeclaration.Body ?? (CSharpSyntaxNode)accessorDeclaration.ExpressionBody; + return accessorDeclaration.Body ?? (CSharpSyntaxNode?)accessorDeclaration.ExpressionBody; } #endregion AccessorDeclarationSyntax @@ -54,7 +54,7 @@ public static CSharpSyntaxNode BodyOrExpressionBody(this AccessorDeclarationSynt /// Returns a get accessor contained in the specified list. /// /// - public static AccessorDeclarationSyntax Getter(this AccessorListSyntax accessorList) + public static AccessorDeclarationSyntax? Getter(this AccessorListSyntax accessorList) { return Accessor(accessorList, SyntaxKind.GetAccessorDeclaration); } @@ -63,12 +63,12 @@ public static AccessorDeclarationSyntax Getter(this AccessorListSyntax accessorL /// Returns a set accessor contained in the specified list. /// /// - public static AccessorDeclarationSyntax Setter(this AccessorListSyntax accessorList) + public static AccessorDeclarationSyntax? Setter(this AccessorListSyntax accessorList) { return Accessor(accessorList, SyntaxKind.SetAccessorDeclaration, SyntaxKind.InitAccessorDeclaration); } - private static AccessorDeclarationSyntax Accessor(this AccessorListSyntax accessorList, SyntaxKind kind) + private static AccessorDeclarationSyntax? Accessor(this AccessorListSyntax accessorList, SyntaxKind kind) { if (accessorList is null) throw new ArgumentNullException(nameof(accessorList)); @@ -82,7 +82,7 @@ private static AccessorDeclarationSyntax Accessor(this AccessorListSyntax access return null; } - private static AccessorDeclarationSyntax Accessor(this AccessorListSyntax accessorList, SyntaxKind kind1, SyntaxKind kind2) + private static AccessorDeclarationSyntax? Accessor(this AccessorListSyntax accessorList, SyntaxKind kind1, SyntaxKind kind2) { if (accessorList is null) throw new ArgumentNullException(nameof(accessorList)); @@ -98,15 +98,15 @@ private static AccessorDeclarationSyntax Accessor(this AccessorListSyntax access #endregion AccessorListSyntax #region BlockSyntax - internal static StatementSyntax SingleNonBlockStatementOrDefault(this BlockSyntax body, bool recursive = false) + internal static StatementSyntax? SingleNonBlockStatementOrDefault(this BlockSyntax? body, bool recursive = false) { if (recursive) { - StatementSyntax statement; + StatementSyntax? statement; do { - statement = body.Statements.SingleOrDefault(shouldThrow: false); + statement = body?.Statements.SingleOrDefault(shouldThrow: false); body = statement as BlockSyntax; } @@ -116,7 +116,7 @@ internal static StatementSyntax SingleNonBlockStatementOrDefault(this BlockSynta } else { - StatementSyntax statement = body.Statements.SingleOrDefault(shouldThrow: false); + StatementSyntax? statement = body?.Statements.SingleOrDefault(shouldThrow: false); if (statement is not null && statement.Kind() != SyntaxKind.Block) @@ -135,7 +135,7 @@ internal static bool ContainsYield(this BlockSyntax block, bool yieldReturn = tr #endregion BlockSyntax #region BaseArgumentListSyntax - internal static BaseArgumentListSyntax WithArguments(this BaseArgumentListSyntax baseArgumentList, SeparatedSyntaxList arguments) + internal static BaseArgumentListSyntax? WithArguments(this BaseArgumentListSyntax baseArgumentList, SeparatedSyntaxList arguments) { switch (baseArgumentList.Kind()) { @@ -238,7 +238,7 @@ public static TextSpan ParenthesesSpan(this CommonForEachStatementSyntax forEach return TextSpan.FromBounds(forEachStatement.OpenParenToken.SpanStart, forEachStatement.CloseParenToken.Span.End); } - internal static StatementSyntax EmbeddedStatement(this CommonForEachStatementSyntax forEachStatement) + internal static StatementSyntax? EmbeddedStatement(this CommonForEachStatementSyntax forEachStatement) { StatementSyntax statement = forEachStatement.Statement; @@ -295,7 +295,7 @@ public static CompilationUnitSyntax AddUsings(this CompilationUnitSyntax compila && usings.Length > 0 && !compilationUnit.Usings.Any()) { - List topTrivia = null; + List? topTrivia = null; SyntaxTriviaList leadingTrivia = compilationUnit.GetLeadingTrivia(); @@ -380,12 +380,12 @@ internal static TextSpan HeaderSpan(this ConstructorDeclarationSyntax constructo /// Returns constructor body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this ConstructorDeclarationSyntax constructorDeclaration) + public static CSharpSyntaxNode? BodyOrExpressionBody(this ConstructorDeclarationSyntax constructorDeclaration) { if (constructorDeclaration is null) throw new ArgumentNullException(nameof(constructorDeclaration)); - return constructorDeclaration.Body ?? (CSharpSyntaxNode)constructorDeclaration.ExpressionBody; + return constructorDeclaration.Body ?? (CSharpSyntaxNode?)constructorDeclaration.ExpressionBody; } #endregion ConstructorDeclarationSyntax @@ -394,12 +394,12 @@ public static CSharpSyntaxNode BodyOrExpressionBody(this ConstructorDeclarationS /// Returns conversion operator body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this ConversionOperatorDeclarationSyntax conversionOperatorDeclaration) + public static CSharpSyntaxNode? BodyOrExpressionBody(this ConversionOperatorDeclarationSyntax conversionOperatorDeclaration) { if (conversionOperatorDeclaration is null) throw new ArgumentNullException(nameof(conversionOperatorDeclaration)); - return conversionOperatorDeclaration.Body ?? (CSharpSyntaxNode)conversionOperatorDeclaration.ExpressionBody; + return conversionOperatorDeclaration.Body ?? (CSharpSyntaxNode?)conversionOperatorDeclaration.ExpressionBody; } internal static TextSpan HeaderSpan(this ConversionOperatorDeclarationSyntax operatorDeclaration) @@ -451,12 +451,12 @@ public static bool ReturnsVoid(this DelegateDeclarationSyntax delegateDeclaratio /// Returns destructor body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this DestructorDeclarationSyntax destructorDeclaration) + public static CSharpSyntaxNode? BodyOrExpressionBody(this DestructorDeclarationSyntax destructorDeclaration) { if (destructorDeclaration is null) throw new ArgumentNullException(nameof(destructorDeclaration)); - return destructorDeclaration.Body ?? (CSharpSyntaxNode)destructorDeclaration.ExpressionBody; + return destructorDeclaration.Body ?? (CSharpSyntaxNode?)destructorDeclaration.ExpressionBody; } internal static TextSpan HeaderSpan(this DestructorDeclarationSyntax destructorDeclaration) @@ -490,9 +490,9 @@ internal static TextSpan HeaderSpan(this DestructorDeclarationSyntax destructorD /// Returns the next related directive. /// /// - public static DirectiveTriviaSyntax GetNextRelatedDirective(this DirectiveTriviaSyntax directiveTrivia) + public static DirectiveTriviaSyntax? GetNextRelatedDirective(this DirectiveTriviaSyntax directiveTrivia) { - DirectiveTriviaSyntax d = directiveTrivia; + DirectiveTriviaSyntax? d = directiveTrivia; switch (d.Kind()) { @@ -552,9 +552,9 @@ public static DirectiveTriviaSyntax GetNextRelatedDirective(this DirectiveTrivia return null; } - private static DirectiveTriviaSyntax GetNextPossiblyRelatedDirective(this DirectiveTriviaSyntax directiveTrivia) + private static DirectiveTriviaSyntax? GetNextPossiblyRelatedDirective(this DirectiveTriviaSyntax directiveTrivia) { - DirectiveTriviaSyntax d = directiveTrivia; + DirectiveTriviaSyntax? d = directiveTrivia; while (d is not null) { @@ -595,7 +595,7 @@ private static DirectiveTriviaSyntax GetNextPossiblyRelatedDirective(this Direct #endregion DirectiveTriviaSyntax #region DocumentationCommentTriviaSyntax - internal static XmlElementSyntax SummaryElement(this DocumentationCommentTriviaSyntax documentationComment) + internal static XmlElementSyntax? SummaryElement(this DocumentationCommentTriviaSyntax documentationComment) { if (documentationComment is null) throw new ArgumentNullException(nameof(documentationComment)); @@ -651,15 +651,15 @@ internal static IEnumerable Elements(this DocumentationComment internal static bool IsPartOfMemberDeclaration(this DocumentationCommentTriviaSyntax documentationComment) { - SyntaxNode node = documentationComment.ParentTrivia.Token.Parent; + SyntaxNode? node = documentationComment.ParentTrivia.Token.Parent; return node is MemberDeclarationSyntax - || node.Parent is MemberDeclarationSyntax; + || node?.Parent is MemberDeclarationSyntax; } #endregion DocumentationCommentTriviaSyntax #region DoStatementSyntax - internal static StatementSyntax EmbeddedStatement(this DoStatementSyntax doStatement) + internal static StatementSyntax? EmbeddedStatement(this DoStatementSyntax doStatement) { StatementSyntax statement = doStatement.Statement; @@ -668,7 +668,7 @@ internal static StatementSyntax EmbeddedStatement(this DoStatementSyntax doState #endregion DoStatementSyntax #region ElseClauseSyntax - internal static StatementSyntax SingleNonBlockStatementOrDefault(this ElseClauseSyntax elseClause) + internal static StatementSyntax? SingleNonBlockStatementOrDefault(this ElseClauseSyntax elseClause) { return SingleNonBlockStatementOrDefault(elseClause.Statement); } @@ -677,7 +677,7 @@ internal static StatementSyntax SingleNonBlockStatementOrDefault(this ElseClause /// Returns topmost if statement of the if-else cascade the specified else clause is part of. /// /// - public static IfStatementSyntax GetTopmostIf(this ElseClauseSyntax elseClause) + public static IfStatementSyntax? GetTopmostIf(this ElseClauseSyntax elseClause) { if (elseClause is null) throw new ArgumentNullException(nameof(elseClause)); @@ -688,7 +688,7 @@ public static IfStatementSyntax GetTopmostIf(this ElseClauseSyntax elseClause) return null; } - internal static StatementSyntax EmbeddedStatement(this ElseClauseSyntax elseClause, bool allowIfStatement = true) + internal static StatementSyntax? EmbeddedStatement(this ElseClauseSyntax elseClause, bool allowIfStatement = true) { StatementSyntax statement = elseClause.Statement; @@ -715,7 +715,7 @@ internal static StatementSyntax EmbeddedStatement(this ElseClauseSyntax elseClau /// Returns region directive that is related to the specified endregion directive. Returns null if no matching region directive is found. /// /// - public static RegionDirectiveTriviaSyntax GetRegionDirective(this EndRegionDirectiveTriviaSyntax endRegionDirective) + public static RegionDirectiveTriviaSyntax? GetRegionDirective(this EndRegionDirectiveTriviaSyntax endRegionDirective) { if (endRegionDirective is null) throw new ArgumentNullException(nameof(endRegionDirective)); @@ -795,7 +795,7 @@ internal static TextSpan HeaderSpan(this EventDeclarationSyntax eventDeclaration public static ExpressionSyntax WalkUpParentheses(this ExpressionSyntax expression) { while (expression.IsParentKind(SyntaxKind.ParenthesizedExpression)) - expression = (ExpressionSyntax)expression.Parent; + expression = (ExpressionSyntax)expression.Parent!; return expression; } @@ -828,7 +828,7 @@ internal static bool IsNumericLiteralExpression(this ExpressionSyntax expression #endregion ExpressionSyntax #region FixedStatementSyntax - internal static StatementSyntax EmbeddedStatement(this FixedStatementSyntax fixedStatement) + internal static StatementSyntax? EmbeddedStatement(this FixedStatementSyntax fixedStatement) { StatementSyntax statement = fixedStatement.Statement; @@ -849,7 +849,7 @@ public static TextSpan ParenthesesSpan(this ForStatementSyntax forStatement) return TextSpan.FromBounds(forStatement.OpenParenToken.SpanStart, forStatement.CloseParenToken.Span.End); } - internal static StatementSyntax EmbeddedStatement(this ForStatementSyntax forStatement) + internal static StatementSyntax? EmbeddedStatement(this ForStatementSyntax forStatement) { StatementSyntax statement = forStatement.Statement; @@ -858,7 +858,7 @@ internal static StatementSyntax EmbeddedStatement(this ForStatementSyntax forSta #endregion ForStatementSyntax #region IfStatementSyntax - internal static StatementSyntax SingleNonBlockStatementOrDefault(this IfStatementSyntax ifStatement) + internal static StatementSyntax? SingleNonBlockStatementOrDefault(this IfStatementSyntax ifStatement) { return SingleNonBlockStatementOrDefault(ifStatement.Statement); } @@ -885,7 +885,7 @@ public static IfStatementSyntax GetTopmostIf(this IfStatementSyntax ifStatement) while (true) { - IfStatementSyntax parentIf = GetPreviousIf(ifStatement); + IfStatementSyntax? parentIf = GetPreviousIf(ifStatement); if (parentIf is not null) { @@ -909,9 +909,9 @@ public static bool IsTopmostIf(this IfStatementSyntax ifStatement) return ifStatement?.IsParentKind(SyntaxKind.ElseClause) == false; } - internal static IfStatementSyntax GetNextIf(this IfStatementSyntax ifStatement) + internal static IfStatementSyntax? GetNextIf(this IfStatementSyntax ifStatement) { - StatementSyntax statement = ifStatement.Else?.Statement; + StatementSyntax? statement = ifStatement.Else?.Statement; if (statement?.Kind() == SyntaxKind.IfStatement) return (IfStatementSyntax)statement; @@ -919,9 +919,9 @@ internal static IfStatementSyntax GetNextIf(this IfStatementSyntax ifStatement) return null; } - internal static IfStatementSyntax GetPreviousIf(this IfStatementSyntax ifStatement) + internal static IfStatementSyntax? GetPreviousIf(this IfStatementSyntax ifStatement) { - SyntaxNode parent = ifStatement.Parent; + SyntaxNode? parent = ifStatement.Parent; if (parent.IsKind(SyntaxKind.ElseClause)) { @@ -934,7 +934,7 @@ internal static IfStatementSyntax GetPreviousIf(this IfStatementSyntax ifStateme return null; } - internal static StatementSyntax EmbeddedStatement(this IfStatementSyntax ifStatement) + internal static StatementSyntax? EmbeddedStatement(this IfStatementSyntax ifStatement) { StatementSyntax statement = ifStatement.Statement; @@ -1037,7 +1037,7 @@ internal static TextSpan HeaderSpan(this IndexerDeclarationSyntax indexerDeclara /// Returns a get accessor that is contained in the specified indexer declaration. /// /// - public static AccessorDeclarationSyntax Getter(this IndexerDeclarationSyntax indexerDeclaration) + public static AccessorDeclarationSyntax? Getter(this IndexerDeclarationSyntax indexerDeclaration) { if (indexerDeclaration is null) throw new ArgumentNullException(nameof(indexerDeclaration)); @@ -1051,7 +1051,7 @@ public static AccessorDeclarationSyntax Getter(this IndexerDeclarationSyntax ind /// Returns a set accessor that is contained in the specified indexer declaration. /// /// - public static AccessorDeclarationSyntax Setter(this IndexerDeclarationSyntax indexerDeclaration) + public static AccessorDeclarationSyntax? Setter(this IndexerDeclarationSyntax indexerDeclaration) { if (indexerDeclaration is null) throw new ArgumentNullException(nameof(indexerDeclaration)); @@ -1189,12 +1189,12 @@ public static bool IsHexNumericLiteral(this LiteralExpressionSyntax literalExpre /// Returns local function body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this LocalFunctionStatementSyntax localFunctionStatement) + public static CSharpSyntaxNode? BodyOrExpressionBody(this LocalFunctionStatementSyntax localFunctionStatement) { if (localFunctionStatement is null) throw new ArgumentNullException(nameof(localFunctionStatement)); - return localFunctionStatement.Body ?? (CSharpSyntaxNode)localFunctionStatement.ExpressionBody; + return localFunctionStatement.Body ?? (CSharpSyntaxNode?)localFunctionStatement.ExpressionBody; } /// @@ -1229,7 +1229,7 @@ internal static TextSpan HeaderSpan(this LocalFunctionStatementSyntax localFunct #endregion LocalFunctionStatementSyntax #region LockStatementSyntax - internal static StatementSyntax EmbeddedStatement(this LockStatementSyntax lockStatement) + internal static StatementSyntax? EmbeddedStatement(this LockStatementSyntax lockStatement) { StatementSyntax statement = lockStatement.Statement; @@ -1278,12 +1278,12 @@ public static SyntaxTrivia GetDocumentationCommentTrivia(this MemberDeclarationS /// Returns single-line documentation comment syntax that is part of the specified declaration. /// /// - public static DocumentationCommentTriviaSyntax GetSingleLineDocumentationComment(this MemberDeclarationSyntax member) + public static DocumentationCommentTriviaSyntax? GetSingleLineDocumentationComment(this MemberDeclarationSyntax member) { if (member is null) throw new ArgumentNullException(nameof(member)); - SyntaxNode structure = member.GetSingleLineDocumentationCommentTrivia().GetStructure(); + SyntaxNode? structure = member.GetSingleLineDocumentationCommentTrivia().GetStructure(); if (structure.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)) return (DocumentationCommentTriviaSyntax)structure; @@ -1295,7 +1295,7 @@ public static DocumentationCommentTriviaSyntax GetSingleLineDocumentationComment /// Returns documentation comment syntax that is part of the specified declaration. /// /// - public static DocumentationCommentTriviaSyntax GetDocumentationComment(this MemberDeclarationSyntax member) + public static DocumentationCommentTriviaSyntax? GetDocumentationComment(this MemberDeclarationSyntax member) { if (member is null) throw new ArgumentNullException(nameof(member)); @@ -1342,7 +1342,7 @@ public static bool HasDocumentationComment(this MemberDeclarationSyntax member) internal static TMember WithNewSingleLineDocumentationComment( this TMember member, - DocumentationCommentGeneratorSettings settings = null) where TMember : MemberDeclarationSyntax + DocumentationCommentGeneratorSettings? settings = null) where TMember : MemberDeclarationSyntax { if (member is null) throw new ArgumentNullException(nameof(member)); @@ -1363,7 +1363,7 @@ internal static TMember WithNewSingleLineDocumentationComment( internal static TMember WithBaseOrNewSingleLineDocumentationComment( this TMember member, SemanticModel semanticModel, - DocumentationCommentGeneratorSettings settings = null, + DocumentationCommentGeneratorSettings? settings = null, CancellationToken cancellationToken = default) where TMember : MemberDeclarationSyntax { if (member is null) @@ -1452,12 +1452,12 @@ internal static TextSpan HeaderSpan(this MethodDeclarationSyntax methodDeclarati /// Returns method body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this MethodDeclarationSyntax methodDeclaration) + public static CSharpSyntaxNode? BodyOrExpressionBody(this MethodDeclarationSyntax methodDeclaration) { if (methodDeclaration is null) throw new ArgumentNullException(nameof(methodDeclaration)); - return methodDeclaration.Body ?? (CSharpSyntaxNode)methodDeclaration.ExpressionBody; + return methodDeclaration.Body ?? (CSharpSyntaxNode?)methodDeclaration.ExpressionBody; } #endregion MethodDeclarationSyntax @@ -1512,12 +1512,12 @@ public static TextSpan BracesSpan(this NamespaceDeclarationSyntax namespaceDecla /// Returns operator body or an expression body if the body is null. /// /// - public static CSharpSyntaxNode BodyOrExpressionBody(this OperatorDeclarationSyntax operatorDeclaration) + public static CSharpSyntaxNode? BodyOrExpressionBody(this OperatorDeclarationSyntax operatorDeclaration) { if (operatorDeclaration is null) throw new ArgumentNullException(nameof(operatorDeclaration)); - return operatorDeclaration.Body ?? (CSharpSyntaxNode)operatorDeclaration.ExpressionBody; + return operatorDeclaration.Body ?? (CSharpSyntaxNode?)operatorDeclaration.ExpressionBody; } internal static TextSpan HeaderSpan(this OperatorDeclarationSyntax operatorDeclaration) @@ -1586,7 +1586,7 @@ internal static TextSpan HeaderSpan(this PropertyDeclarationSyntax propertyDecla /// Returns property get accessor, if any. /// /// - public static AccessorDeclarationSyntax Getter(this PropertyDeclarationSyntax propertyDeclaration) + public static AccessorDeclarationSyntax? Getter(this PropertyDeclarationSyntax propertyDeclaration) { if (propertyDeclaration is null) throw new ArgumentNullException(nameof(propertyDeclaration)); @@ -1598,7 +1598,7 @@ public static AccessorDeclarationSyntax Getter(this PropertyDeclarationSyntax pr /// Returns property set accessor, if any. /// /// - public static AccessorDeclarationSyntax Setter(this PropertyDeclarationSyntax propertyDeclaration) + public static AccessorDeclarationSyntax? Setter(this PropertyDeclarationSyntax propertyDeclaration) { if (propertyDeclaration is null) throw new ArgumentNullException(nameof(propertyDeclaration)); @@ -1612,7 +1612,7 @@ internal static PropertyDeclarationSyntax ReplaceAccessor( AccessorDeclarationSyntax newAccessor) { return propertyDeclaration.WithAccessorList( - propertyDeclaration.AccessorList.WithAccessors( + propertyDeclaration.AccessorList!.WithAccessors( propertyDeclaration.AccessorList.Accessors.Replace(accessor, newAccessor))); } #endregion PropertyDeclarationSyntax @@ -1668,7 +1668,7 @@ public static TextSpan BracesSpan(this RecordDeclarationSyntax recordDeclaration /// Returns endregion directive that is related to the specified region directive. Returns null if no matching endregion directive is found. /// /// - public static EndRegionDirectiveTriviaSyntax GetEndRegionDirective(this RegionDirectiveTriviaSyntax regionDirective) + public static EndRegionDirectiveTriviaSyntax? GetEndRegionDirective(this RegionDirectiveTriviaSyntax regionDirective) { if (regionDirective is null) throw new ArgumentNullException(nameof(regionDirective)); @@ -1741,7 +1741,7 @@ public static bool Contains(this SeparatedSyntaxList list, SyntaxK /// /// /// - public static TNode Find(this SeparatedSyntaxList list, SyntaxKind kind) where TNode : SyntaxNode + public static TNode? Find(this SeparatedSyntaxList list, SyntaxKind kind) where TNode : SyntaxNode { int index = list.IndexOf(kind); @@ -1974,7 +1974,7 @@ internal static int IndexOf(this SeparatedSyntaxList typePa /// If the specified statement is not contained in the list, or if there is no previous statement, then this method returns null. /// /// - public static StatementSyntax PreviousStatement(this StatementSyntax statement) + public static StatementSyntax? PreviousStatement(this StatementSyntax statement) { if (statement is null) throw new ArgumentNullException(nameof(statement)); @@ -1997,7 +1997,7 @@ public static StatementSyntax PreviousStatement(this StatementSyntax statement) /// If the specified statement is not contained in the list, or if there is no next statement, then this method returns null. /// /// - public static StatementSyntax NextStatement(this StatementSyntax statement) + public static StatementSyntax? NextStatement(this StatementSyntax statement) { if (statement is null) throw new ArgumentNullException(nameof(statement)); @@ -2029,7 +2029,7 @@ public static bool TryGetContainingList(this StatementSyntax statement, out Synt return statements.Any(); } - internal static StatementSyntax SingleNonBlockStatementOrDefault(this StatementSyntax statement, bool recursive = false) + internal static StatementSyntax? SingleNonBlockStatementOrDefault(this StatementSyntax statement, bool recursive = false) { return (statement.Kind() == SyntaxKind.Block) ? SingleNonBlockStatementOrDefault((BlockSyntax)statement, recursive) @@ -2063,7 +2063,7 @@ public static bool IsEmbedded( if (!CSharpFacts.CanBeEmbeddedStatement(kind)) return false; - SyntaxNode parent = statement.Parent; + SyntaxNode? parent = statement.Parent; if (parent is null) return false; @@ -2154,7 +2154,7 @@ internal static SyntaxList GetStatements(this SwitchSectionSynt /// Returns a section that contains default label, or null if the specified switch statement does not contains section with default label. /// /// - public static SwitchSectionSyntax DefaultSection(this SwitchStatementSyntax switchStatement) + public static SwitchSectionSyntax? DefaultSection(this SwitchStatementSyntax switchStatement) { if (switchStatement is null) throw new ArgumentNullException(nameof(switchStatement)); @@ -2198,7 +2198,7 @@ public static bool Contains(this SyntaxList list, SyntaxKind kind) /// /// /// - public static TNode Find(this SyntaxList list, SyntaxKind kind) where TNode : SyntaxNode + public static TNode? Find(this SyntaxList list, SyntaxKind kind) where TNode : SyntaxNode { int index = list.IndexOf(kind); @@ -2259,7 +2259,7 @@ internal static TextSpan GetSpan( GetEndIndex(list.Last(), includeExteriorTrivia, trim)); } - internal static StatementSyntax SingleOrDefault(this SyntaxList statements, bool ignoreLocalFunctions, bool shouldThrow) + internal static StatementSyntax? SingleOrDefault(this SyntaxList statements, bool ignoreLocalFunctions, bool shouldThrow) { return (ignoreLocalFunctions) ? statements.SingleOrDefault(statement => statement.Kind() != SyntaxKind.LocalFunctionStatement, shouldThrow: shouldThrow) @@ -2416,7 +2416,7 @@ public static SyntaxList RemoveRange( return ReplaceRange(list, index, count, Empty.ReadOnlyList()); } - internal static StatementSyntax LastOrDefault(this SyntaxList statements, bool ignoreLocalFunction) + internal static StatementSyntax? LastOrDefault(this SyntaxList statements, bool ignoreLocalFunction) { if (!ignoreLocalFunction) return statements.LastOrDefault(); @@ -2460,12 +2460,12 @@ public static SyntaxList TrimTrivia(this SyntaxList list) w #endregion SyntaxList #region SyntaxNode - internal static IEnumerable DescendantPreprocessorDirectives(this SyntaxNode node, Func predicate = null) + internal static IEnumerable DescendantPreprocessorDirectives(this SyntaxNode node, Func? predicate = null) { return DescendantPreprocessorDirectives(node, node.FullSpan, predicate); } - internal static IEnumerable DescendantPreprocessorDirectives(this SyntaxNode node, TextSpan span, Func predicate = null) + internal static IEnumerable DescendantPreprocessorDirectives(this SyntaxNode node, TextSpan span, Func? predicate = null) { foreach (SyntaxTrivia trivia in node.DescendantTrivia(span: span, descendIntoTrivia: true)) { @@ -2502,7 +2502,7 @@ public static bool IsDescendantOf(this SyntaxNode node, SyntaxKind kind, bool as /// /// /// - public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2) + public static bool IsKind(this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2) { if (node is null) return false; @@ -2520,7 +2520,7 @@ public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kin /// /// /// - public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3) + public static bool IsKind(this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3) { if (node is null) return false; @@ -2540,7 +2540,7 @@ public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kin /// /// /// - public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4) + public static bool IsKind(this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4) { if (node is null) return false; @@ -2562,7 +2562,7 @@ public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kin /// /// /// - public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5) + public static bool IsKind(this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5) { if (node is null) return false; @@ -2586,7 +2586,7 @@ public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kin /// /// /// - public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5, SyntaxKind kind6) + public static bool IsKind(this SyntaxNode? node, SyntaxKind kind1, SyntaxKind kind2, SyntaxKind kind3, SyntaxKind kind4, SyntaxKind kind5, SyntaxKind kind6) { if (node is null) return false; @@ -2606,7 +2606,7 @@ public static bool IsKind(this SyntaxNode node, SyntaxKind kind1, SyntaxKind kin /// /// /// - public static bool IsParentKind(this SyntaxNode node, SyntaxKind kind) + public static bool IsParentKind(this SyntaxNode? node, SyntaxKind kind) { return node?.Parent.IsKind(kind) == true; } @@ -2865,7 +2865,7 @@ internal static TextSpan TrimmedSpan(this SyntaxNode node) /// /// /// - public static SyntaxNode FirstAncestor( + public static SyntaxNode? FirstAncestor( this SyntaxNode node, SyntaxKind kind, bool ascendOutOfTrivia = true) @@ -2880,7 +2880,7 @@ public static SyntaxNode FirstAncestor( /// /// /// - public static SyntaxNode FirstAncestor( + public static SyntaxNode? FirstAncestor( this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, @@ -2897,7 +2897,7 @@ public static SyntaxNode FirstAncestor( /// /// /// - public static SyntaxNode FirstAncestor( + public static SyntaxNode? FirstAncestor( this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, @@ -2913,7 +2913,7 @@ public static SyntaxNode FirstAncestor( /// /// /// - public static SyntaxNode FirstAncestor(this SyntaxNode node, Func predicate, bool ascendOutOfTrivia = true) + public static SyntaxNode? FirstAncestor(this SyntaxNode node, Func predicate, bool ascendOutOfTrivia = true) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -2921,7 +2921,7 @@ public static SyntaxNode FirstAncestor(this SyntaxNode node, Func /// /// - public static SyntaxNode FirstAncestorOrSelf( + public static SyntaxNode? FirstAncestorOrSelf( this SyntaxNode node, SyntaxKind kind, bool ascendOutOfTrivia = true) @@ -2954,7 +2954,7 @@ public static SyntaxNode FirstAncestorOrSelf( /// /// /// - public static SyntaxNode FirstAncestorOrSelf( + public static SyntaxNode? FirstAncestorOrSelf( this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, @@ -2971,7 +2971,7 @@ public static SyntaxNode FirstAncestorOrSelf( /// /// /// - public static SyntaxNode FirstAncestorOrSelf( + public static SyntaxNode? FirstAncestorOrSelf( this SyntaxNode node, SyntaxKind kind1, SyntaxKind kind2, @@ -2987,7 +2987,7 @@ public static SyntaxNode FirstAncestorOrSelf( /// /// /// - public static SyntaxNode FirstAncestorOrSelf(this SyntaxNode node, Func predicate, bool ascendOutOfTrivia = true) + public static SyntaxNode? FirstAncestorOrSelf(this SyntaxNode node, Func predicate, bool ascendOutOfTrivia = true) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -3000,18 +3000,18 @@ public static SyntaxNode FirstAncestorOrSelf(this SyntaxNode node, Func(this TRoot root, SyntaxNode node) where TRoot : SyntaxNode + internal static TRoot? RemoveNode(this TRoot root, SyntaxNode node) where TRoot : SyntaxNode { return SyntaxRefactorings.RemoveNode(root, node); } - internal static TNode RemoveStatement(this TNode node, StatementSyntax statement) where TNode : SyntaxNode + internal static TNode? RemoveStatement(this TNode node, StatementSyntax statement) where TNode : SyntaxNode { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -3039,7 +3039,7 @@ internal static TNode RemoveModifier(this TNode node, SyntaxToken modifie return ModifierList.Remove(node, modifier); } - internal static TNode InsertModifier(this TNode node, SyntaxKind modifierKind, IComparer comparer = null) where TNode : SyntaxNode + internal static TNode InsertModifier(this TNode node, SyntaxKind modifierKind, IComparer? comparer = null) where TNode : SyntaxNode { return ModifierList.Insert(node, modifierKind, comparer); } @@ -3099,7 +3099,7 @@ internal static bool IsPartOfDocumentationComment(this SyntaxNode node) return true; } - node = node.Parent; + node = node.Parent!; } return false; @@ -3116,7 +3116,7 @@ public static bool IsInExpressionTree( SemanticModel semanticModel, CancellationToken cancellationToken = default) { - for (SyntaxNode current = node; current is not null; current = current.Parent) + for (SyntaxNode? current = node; current is not null; current = current.Parent) { switch (current.Kind()) { @@ -3256,7 +3256,7 @@ public static bool IsInExpressionTree( static bool IsMethodThatAcceptsExpressionAsFirstParameter(SymbolInfo info) { - ISymbol symbol = info.Symbol; + ISymbol? symbol = info.Symbol; if (symbol is not null) return IsMethodThatAcceptsExpressionAsFirstParameter2(symbol); @@ -3306,14 +3306,14 @@ public static bool ContainsUnbalancedIfElseDirectives(this SyntaxNode node, Text if (node.ContainsDirectives) { - DirectiveTriviaSyntax first = node.GetFirstDirective(span, f => CSharpFacts.IsIfElseDirective(f.Kind())); + DirectiveTriviaSyntax? first = node.GetFirstDirective(span, f => CSharpFacts.IsIfElseDirective(f.Kind())); if (first is not null) { if (!first.IsKind(SyntaxKind.IfDirectiveTrivia)) return true; - DirectiveTriviaSyntax last = node.GetLastDirective(span, f => CSharpFacts.IsIfElseDirective(f.Kind())); + DirectiveTriviaSyntax? last = node.GetLastDirective(span, f => CSharpFacts.IsIfElseDirective(f.Kind())); if (last == first) return true; @@ -3321,7 +3321,7 @@ public static bool ContainsUnbalancedIfElseDirectives(this SyntaxNode node, Text if (!last.IsKind(SyntaxKind.EndIfDirectiveTrivia)) return true; - DirectiveTriviaSyntax d = first; + DirectiveTriviaSyntax? d = first; do { @@ -3346,9 +3346,9 @@ public static bool ContainsUnbalancedIfElseDirectives(this SyntaxNode node, Text /// /// /// - public static DirectiveTriviaSyntax GetFirstDirective(this SyntaxNode node, TextSpan span, Func predicate = null) + public static DirectiveTriviaSyntax? GetFirstDirective(this SyntaxNode node, TextSpan span, Func? predicate = null) { - DirectiveTriviaSyntax directive = node.GetFirstDirective(predicate); + DirectiveTriviaSyntax? directive = node.GetFirstDirective(predicate); if (directive is null) return null; @@ -3367,9 +3367,9 @@ public static DirectiveTriviaSyntax GetFirstDirective(this SyntaxNode node, Text return directive; } - internal static DirectiveTriviaSyntax GetLastDirective(this SyntaxNode node, TextSpan span, Func predicate = null) + internal static DirectiveTriviaSyntax? GetLastDirective(this SyntaxNode node, TextSpan span, Func? predicate = null) { - DirectiveTriviaSyntax directive = node.GetLastDirective(predicate); + DirectiveTriviaSyntax? directive = node.GetLastDirective(predicate); if (directive is null) return null; @@ -4211,7 +4211,7 @@ public static bool IsVoid(this TypeSyntax type) #endregion TypeSyntax #region UsingDirectiveSyntax - internal static IdentifierNameSyntax GetRootNamespace(this UsingDirectiveSyntax usingDirective) + internal static IdentifierNameSyntax? GetRootNamespace(this UsingDirectiveSyntax usingDirective) { NameSyntax name = usingDirective.Name; @@ -4232,7 +4232,7 @@ internal static IdentifierNameSyntax GetRootNamespace(this UsingDirectiveSyntax if (left is IdentifierNameSyntax identifierName2) return identifierName2; - qualifiedName = left as QualifiedNameSyntax; + qualifiedName = (left as QualifiedNameSyntax)!; } while (qualifiedName is not null); @@ -4252,15 +4252,15 @@ internal static IdentifierNameSyntax GetRootNamespace(this UsingDirectiveSyntax /// Returns using statement's declaration or an expression if the declaration is null. /// /// - public static CSharpSyntaxNode DeclarationOrExpression(this UsingStatementSyntax usingStatement) + public static CSharpSyntaxNode? DeclarationOrExpression(this UsingStatementSyntax usingStatement) { if (usingStatement is null) throw new ArgumentNullException(nameof(usingStatement)); - return usingStatement.Declaration ?? (CSharpSyntaxNode)usingStatement.Expression; + return usingStatement.Declaration ?? (CSharpSyntaxNode?)usingStatement.Expression; } - internal static StatementSyntax EmbeddedStatement(this UsingStatementSyntax usingStatement, bool allowUsingStatement = true) + internal static StatementSyntax? EmbeddedStatement(this UsingStatementSyntax usingStatement, bool allowUsingStatement = true) { StatementSyntax statement = usingStatement.Statement; @@ -4283,7 +4283,7 @@ internal static StatementSyntax EmbeddedStatement(this UsingStatementSyntax usin #endregion UsingStatementSyntax #region WhileStatementSyntax - internal static StatementSyntax EmbeddedStatement(this WhileStatementSyntax whileStatement) + internal static StatementSyntax? EmbeddedStatement(this WhileStatementSyntax whileStatement) { StatementSyntax statement = whileStatement.Statement; @@ -4307,7 +4307,7 @@ internal static bool IsLocalName(this XmlElementSyntax xmlElement, string localN return xmlElement.StartTag?.Name?.IsLocalName(localName, comparison) == true; } - internal static string GetAttributeValue(this XmlElementSyntax element, string attributeName) + internal static string? GetAttributeValue(this XmlElementSyntax element, string attributeName) { XmlElementStartTagSyntax startTag = element.StartTag; @@ -4343,7 +4343,7 @@ internal static XmlElementSyntax UpdateName(this XmlElementSyntax element, strin #endregion XmlElementSyntax #region XmlEmptyElementSyntax - internal static string GetAttributeValue(this XmlEmptyElementSyntax element, string attributeName) + internal static string? GetAttributeValue(this XmlEmptyElementSyntax element, string attributeName) { foreach (XmlAttributeSyntax attribute in element.Attributes) { diff --git a/src/CSharp/CSharp/IfStatementCascade.cs b/src/CSharp/CSharp/IfStatementCascade.cs index 33f189ddda..39adbac832 100644 --- a/src/CSharp/CSharp/IfStatementCascade.cs +++ b/src/CSharp/CSharp/IfStatementCascade.cs @@ -128,7 +128,7 @@ public bool MoveNext() } else if (_ifOrElse.IsIf) { - ElseClauseSyntax elseClause = _ifOrElse.AsIf().Else; + ElseClauseSyntax? elseClause = _ifOrElse.AsIf()!.Else; if (elseClause is not null) { @@ -163,22 +163,22 @@ public void Reset() IfStatementSyntax ifStatement; if (_ifOrElse.IsElse) { - ifStatement = (IfStatementSyntax)_ifOrElse.Parent; + ifStatement = (IfStatementSyntax)_ifOrElse.Parent!; } else { - ifStatement = _ifOrElse.AsIf(); + ifStatement = _ifOrElse.AsIf()!; } count--; while (count >= 0) { - ifStatement = (IfStatementSyntax)ifStatement.Parent.Parent; + ifStatement = (IfStatementSyntax?)ifStatement.Parent!.Parent!; count--; } - _ifOrElse = ifStatement; + _ifOrElse = ifStatement!; } } diff --git a/src/CSharp/CSharp/IfStatementOrElseClause.cs b/src/CSharp/CSharp/IfStatementOrElseClause.cs index 68f20ae41f..c440ff65e3 100644 --- a/src/CSharp/CSharp/IfStatementOrElseClause.cs +++ b/src/CSharp/CSharp/IfStatementOrElseClause.cs @@ -15,8 +15,8 @@ namespace Roslynator.CSharp; [DebuggerDisplay("{DebuggerDisplay,nq}")] public readonly struct IfStatementOrElseClause : IEquatable { - private readonly IfStatementSyntax _ifStatement; - private readonly ElseClauseSyntax _elseClause; + private readonly IfStatementSyntax? _ifStatement; + private readonly ElseClauseSyntax? _elseClause; internal IfStatementOrElseClause(SyntaxNode node) { @@ -53,9 +53,9 @@ public IfStatementOrElseClause(ElseClauseSyntax elseClause) _ifStatement = null; } - internal SyntaxNode Node + internal SyntaxNode? Node { - get { return _ifStatement ?? (SyntaxNode)_elseClause; } + get { return _ifStatement ?? (SyntaxNode?)_elseClause; } } /// @@ -94,7 +94,7 @@ public bool IsElse /// /// Gets or . /// - public StatementSyntax Statement + public StatementSyntax? Statement { get { @@ -111,7 +111,7 @@ public StatementSyntax Statement /// /// The node that contains the underlying node in its collection. /// - public SyntaxNode Parent + public SyntaxNode? Parent { get { return _ifStatement?.Parent ?? _elseClause?.Parent; } } @@ -159,7 +159,7 @@ private string DebuggerDisplay /// /// Returns the underlying if statement if this is wrapping if statement. /// - public IfStatementSyntax AsIf() + public IfStatementSyntax? AsIf() { return _ifStatement; } @@ -167,7 +167,7 @@ public IfStatementSyntax AsIf() /// /// Returns the underlying else clause if this is wrapping else clause. /// - public ElseClauseSyntax AsElse() + public ElseClauseSyntax? AsElse() { return _elseClause; } @@ -226,7 +226,7 @@ public static implicit operator IfStatementOrElseClause(IfStatementSyntax ifStat return new IfStatementOrElseClause(ifStatement); } - public static implicit operator IfStatementSyntax(in IfStatementOrElseClause ifOrElse) + public static implicit operator IfStatementSyntax?(in IfStatementOrElseClause ifOrElse) { return ifOrElse.AsIf(); } @@ -236,7 +236,7 @@ public static implicit operator IfStatementOrElseClause(ElseClauseSyntax elseCla return new IfStatementOrElseClause(elseClause); } - public static implicit operator ElseClauseSyntax(in IfStatementOrElseClause ifOrElse) + public static implicit operator ElseClauseSyntax?(in IfStatementOrElseClause ifOrElse) { return ifOrElse.AsElse(); } diff --git a/src/CSharp/CSharp/MemberDeclarationComparer.cs b/src/CSharp/CSharp/MemberDeclarationComparer.cs index 6e024f1f92..71c3e64925 100644 --- a/src/CSharp/CSharp/MemberDeclarationComparer.cs +++ b/src/CSharp/CSharp/MemberDeclarationComparer.cs @@ -104,7 +104,7 @@ public override int Compare(MemberDeclarationSyntax x, MemberDeclarationSyntax y } } - private static string GetName(MemberDeclarationSyntax member) + private static string? GetName(MemberDeclarationSyntax member) { switch (member.Kind()) { diff --git a/src/CSharp/CSharp/MemberDeclarationListSelection.cs b/src/CSharp/CSharp/MemberDeclarationListSelection.cs index c5dbe0c3ca..5b3c313264 100644 --- a/src/CSharp/CSharp/MemberDeclarationListSelection.cs +++ b/src/CSharp/CSharp/MemberDeclarationListSelection.cs @@ -81,19 +81,19 @@ private static MemberDeclarationListSelection Create(SyntaxNode parent, SyntaxLi /// /// /// True if the specified span contains at least one member; otherwise, false. - public static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, TextSpan span, out MemberDeclarationListSelection selectedMembers) + public static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, TextSpan span, out MemberDeclarationListSelection? selectedMembers) { selectedMembers = Create(namespaceDeclaration, span, 1, int.MaxValue); return selectedMembers is not null; } - internal static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, TextSpan span, int minCount, out MemberDeclarationListSelection selectedMembers) + internal static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, TextSpan span, int minCount, out MemberDeclarationListSelection? selectedMembers) { selectedMembers = Create(namespaceDeclaration, span, minCount, int.MaxValue); return selectedMembers is not null; } - internal static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, TextSpan span, int minCount, int maxCount, out MemberDeclarationListSelection selectedMembers) + internal static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, TextSpan span, int minCount, int maxCount, out MemberDeclarationListSelection? selectedMembers) { selectedMembers = Create(namespaceDeclaration, span, minCount, maxCount); return selectedMembers is not null; @@ -106,25 +106,25 @@ internal static bool TryCreate(NamespaceDeclarationSyntax namespaceDeclaration, /// /// /// True if the specified span contains at least one member; otherwise, false. - public static bool TryCreate(TypeDeclarationSyntax typeDeclaration, TextSpan span, out MemberDeclarationListSelection selectedMembers) + public static bool TryCreate(TypeDeclarationSyntax typeDeclaration, TextSpan span, out MemberDeclarationListSelection? selectedMembers) { selectedMembers = Create(typeDeclaration, span, 1, int.MaxValue); return selectedMembers is not null; } - internal static bool TryCreate(TypeDeclarationSyntax typeDeclaration, TextSpan span, int minCount, out MemberDeclarationListSelection selectedMembers) + internal static bool TryCreate(TypeDeclarationSyntax typeDeclaration, TextSpan span, int minCount, out MemberDeclarationListSelection? selectedMembers) { selectedMembers = Create(typeDeclaration, span, minCount, int.MaxValue); return selectedMembers is not null; } - internal static bool TryCreate(TypeDeclarationSyntax typeDeclaration, TextSpan span, int minCount, int maxCount, out MemberDeclarationListSelection selectedMembers) + internal static bool TryCreate(TypeDeclarationSyntax typeDeclaration, TextSpan span, int minCount, int maxCount, out MemberDeclarationListSelection? selectedMembers) { selectedMembers = Create(typeDeclaration, span, minCount, maxCount); return selectedMembers is not null; } - private static MemberDeclarationListSelection Create(NamespaceDeclarationSyntax declaration, TextSpan span, int minCount, int maxCount) + private static MemberDeclarationListSelection? Create(NamespaceDeclarationSyntax declaration, TextSpan span, int minCount, int maxCount) { if (declaration is null) return null; @@ -132,7 +132,7 @@ private static MemberDeclarationListSelection Create(NamespaceDeclarationSyntax return Create(declaration, declaration.Members, span, minCount, maxCount); } - private static MemberDeclarationListSelection Create(TypeDeclarationSyntax declaration, TextSpan span, int minCount, int maxCount) + private static MemberDeclarationListSelection? Create(TypeDeclarationSyntax declaration, TextSpan span, int minCount, int maxCount) { if (declaration is null) return null; @@ -140,7 +140,7 @@ private static MemberDeclarationListSelection Create(TypeDeclarationSyntax decla return Create(declaration, declaration.Members, span, minCount, maxCount); } - private static MemberDeclarationListSelection Create(MemberDeclarationSyntax declaration, SyntaxList members, TextSpan span, int minCount, int maxCount) + private static MemberDeclarationListSelection? Create(MemberDeclarationSyntax declaration, SyntaxList members, TextSpan span, int minCount, int maxCount) { SelectionResult result = SelectionResult.Create(members, span, minCount, maxCount); diff --git a/src/CSharp/CSharp/MethodChain.cs b/src/CSharp/CSharp/MethodChain.cs index b69dafc3eb..2f0f4a8f8d 100644 --- a/src/CSharp/CSharp/MethodChain.cs +++ b/src/CSharp/CSharp/MethodChain.cs @@ -42,7 +42,7 @@ public Enumerator GetEnumerator() public struct Enumerator { private readonly MethodChain _chain; - private SyntaxNode _current; + private SyntaxNode? _current; internal Enumerator(MethodChain chain) { @@ -59,7 +59,7 @@ public bool MoveNext() return _current is not null; } - ExpressionSyntax last = GetLastChild(_current); + ExpressionSyntax? last = GetLastChild(_current); if (last is not null) { @@ -70,7 +70,7 @@ public bool MoveNext() while (_current != _chain.Expression && IsFirstChild(_current)) { - _current = _current.Parent; + _current = _current.Parent!; } if (_current == _chain.Expression) @@ -85,7 +85,7 @@ public bool MoveNext() return true; } - private static ExpressionSyntax GetLastChild(SyntaxNode node) + private static ExpressionSyntax? GetLastChild(SyntaxNode node) { switch (node?.Kind()) { @@ -104,11 +104,11 @@ private static ExpressionSyntax GetLastChild(SyntaxNode node) return null; } - private static SyntaxNode GetPreviousSibling(SyntaxNode node) + private static SyntaxNode? GetPreviousSibling(SyntaxNode node) { - SyntaxNode parent = node.Parent; + SyntaxNode? parent = node.Parent; - switch (parent.Kind()) + switch (parent?.Kind()) { case SyntaxKind.ConditionalAccessExpression: { @@ -135,7 +135,7 @@ private static SyntaxNode GetPreviousSibling(SyntaxNode node) private static bool IsFirstChild(SyntaxNode node) { - SyntaxNode parent = node.Parent; + SyntaxNode parent = node.Parent!; switch (parent.Kind()) { diff --git a/src/CSharp/CSharp/ModifierList.cs b/src/CSharp/CSharp/ModifierList.cs index 7729b2d13d..4bebb71496 100644 --- a/src/CSharp/CSharp/ModifierList.cs +++ b/src/CSharp/CSharp/ModifierList.cs @@ -20,7 +20,7 @@ public static class ModifierList /// /// /// - public static int GetInsertIndex(SyntaxTokenList tokens, SyntaxToken token, IComparer comparer = null) + public static int GetInsertIndex(SyntaxTokenList tokens, SyntaxToken token, IComparer? comparer = null) { if (comparer is null) comparer = ModifierComparer.Default; @@ -54,7 +54,7 @@ public static int GetInsertIndex(SyntaxTokenList tokens, SyntaxToken token, ICom /// /// /// - public static int GetInsertIndex(SyntaxTokenList tokens, SyntaxKind kind, IComparer comparer = null) + public static int GetInsertIndex(SyntaxTokenList tokens, SyntaxKind kind, IComparer? comparer = null) { if (comparer is null) comparer = ModifierKindComparer.Default; @@ -82,7 +82,7 @@ public static int GetInsertIndex(SyntaxTokenList tokens, SyntaxKind kind, ICompa return index; } - internal static SyntaxNode Insert(SyntaxNode node, Accessibility accessibility, IComparer comparer = null) + internal static SyntaxNode Insert(SyntaxNode node, Accessibility accessibility, IComparer? comparer = null) { switch (accessibility) { @@ -126,7 +126,7 @@ internal static SyntaxNode Insert(SyntaxNode node, Accessibility accessibility, /// /// /// - public static TNode Insert(TNode node, SyntaxKind kind, IComparer comparer = null) where TNode : SyntaxNode + public static TNode Insert(TNode node, SyntaxKind kind, IComparer? comparer = null) where TNode : SyntaxNode { switch (node.Kind()) { @@ -189,7 +189,7 @@ public static TNode Insert(TNode node, SyntaxKind kind, IComparer /// /// - public static TNode Insert(TNode node, SyntaxToken modifier, IComparer comparer = null) where TNode : SyntaxNode + public static TNode Insert(TNode node, SyntaxToken modifier, IComparer? comparer = null) where TNode : SyntaxNode { switch (node.Kind()) { @@ -560,7 +560,7 @@ public static TNode RemoveAll(TNode node) where TNode : SyntaxNode /// /// /// - public static SyntaxTokenList Insert(SyntaxTokenList modifiers, SyntaxKind kind, IComparer comparer = null) + public static SyntaxTokenList Insert(SyntaxTokenList modifiers, SyntaxKind kind, IComparer? comparer = null) { if (!modifiers.Any()) return modifiers.Add(Token(kind)); @@ -574,7 +574,7 @@ public static SyntaxTokenList Insert(SyntaxTokenList modifiers, SyntaxKind kind, /// /// /// - public static SyntaxTokenList Insert(SyntaxTokenList modifiers, SyntaxToken modifier, IComparer comparer = null) + public static SyntaxTokenList Insert(SyntaxTokenList modifiers, SyntaxToken modifier, IComparer? comparer = null) { if (!modifiers.Any()) return modifiers.Add(modifier); diff --git a/src/CSharp/CSharp/ModifierList`1.cs b/src/CSharp/CSharp/ModifierList`1.cs index 886da36ed5..0ab9cac761 100644 --- a/src/CSharp/CSharp/ModifierList`1.cs +++ b/src/CSharp/CSharp/ModifierList`1.cs @@ -106,7 +106,7 @@ private static object GetInstance() /// /// /// - public TNode Insert(TNode node, SyntaxKind kind, IComparer comparer = null) + public TNode Insert(TNode node, SyntaxKind kind, IComparer? comparer = null) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -124,7 +124,7 @@ public TNode Insert(TNode node, SyntaxKind kind, IComparer comparer /// /// /// - public TNode Insert(TNode node, SyntaxToken modifier, IComparer comparer = null) + public TNode Insert(TNode node, SyntaxToken modifier, IComparer? comparer = null) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -149,7 +149,7 @@ private TNode InsertModifier(TNode node, SyntaxTokenList modifiers, SyntaxToken } else { - AttributeListSyntax attributeList = GetAttributeLists(node).LastOrDefault(); + AttributeListSyntax? attributeList = GetAttributeLists(node).LastOrDefault(); if (attributeList is not null) { diff --git a/src/CSharp/CSharp/StatementListSelection.cs b/src/CSharp/CSharp/StatementListSelection.cs index 196bff09f8..4bfd6fcc12 100644 --- a/src/CSharp/CSharp/StatementListSelection.cs +++ b/src/CSharp/CSharp/StatementListSelection.cs @@ -76,25 +76,25 @@ private static StatementListSelection CreateImpl(SyntaxList sta /// /// /// True if the specified span contains at least one statement; otherwise, false. - public static bool TryCreate(BlockSyntax block, TextSpan span, out StatementListSelection selectedStatements) + public static bool TryCreate(BlockSyntax block, TextSpan span, out StatementListSelection? selectedStatements) { selectedStatements = Create(block, span, 1, int.MaxValue); return selectedStatements is not null; } - internal static bool TryCreate(BlockSyntax block, TextSpan span, int minCount, out StatementListSelection selectedStatements) + internal static bool TryCreate(BlockSyntax block, TextSpan span, int minCount, out StatementListSelection? selectedStatements) { selectedStatements = Create(block, span, minCount, int.MaxValue); return selectedStatements is not null; } - internal static bool TryCreate(BlockSyntax block, TextSpan span, int minCount, int maxCount, out StatementListSelection selectedStatements) + internal static bool TryCreate(BlockSyntax block, TextSpan span, int minCount, int maxCount, out StatementListSelection? selectedStatements) { selectedStatements = Create(block, span, minCount, maxCount); return selectedStatements is not null; } - private static StatementListSelection Create(BlockSyntax block, TextSpan span, int minCount, int maxCount) + private static StatementListSelection? Create(BlockSyntax block, TextSpan span, int minCount, int maxCount) { if (block is null) return null; @@ -109,25 +109,25 @@ private static StatementListSelection Create(BlockSyntax block, TextSpan span, i /// /// /// True if the specified span contains at least one statement; otherwise, false. - public static bool TryCreate(SwitchSectionSyntax switchSection, TextSpan span, out StatementListSelection selectedStatements) + public static bool TryCreate(SwitchSectionSyntax switchSection, TextSpan span, out StatementListSelection? selectedStatements) { selectedStatements = Create(switchSection, span, 1, int.MaxValue); return selectedStatements is not null; } - internal static bool TryCreate(SwitchSectionSyntax switchSection, TextSpan span, int minCount, out StatementListSelection selectedStatements) + internal static bool TryCreate(SwitchSectionSyntax switchSection, TextSpan span, int minCount, out StatementListSelection? selectedStatements) { selectedStatements = Create(switchSection, span, minCount, int.MaxValue); return selectedStatements is not null; } - internal static bool TryCreate(SwitchSectionSyntax switchSection, TextSpan span, int minCount, int maxCount, out StatementListSelection selectedStatements) + internal static bool TryCreate(SwitchSectionSyntax switchSection, TextSpan span, int minCount, int maxCount, out StatementListSelection? selectedStatements) { selectedStatements = Create(switchSection, span, minCount, maxCount); return selectedStatements is not null; } - private static StatementListSelection Create(SwitchSectionSyntax switchSection, TextSpan span, int minCount, int maxCount) + private static StatementListSelection? Create(SwitchSectionSyntax switchSection, TextSpan span, int minCount, int maxCount) { if (switchSection is null) return null; @@ -135,7 +135,7 @@ private static StatementListSelection Create(SwitchSectionSyntax switchSection, return Create(switchSection.Statements, span, minCount, maxCount); } - private static StatementListSelection Create(SyntaxList statements, TextSpan span, int minCount, int maxCount) + private static StatementListSelection? Create(SyntaxList statements, TextSpan span, int minCount, int maxCount) { SelectionResult result = SelectionResult.Create(statements, span, minCount, maxCount); diff --git a/src/CSharp/CSharp/StringLiteralParser.cs b/src/CSharp/CSharp/StringLiteralParser.cs index 5161dd75b4..189950fb36 100644 --- a/src/CSharp/CSharp/StringLiteralParser.cs +++ b/src/CSharp/CSharp/StringLiteralParser.cs @@ -14,12 +14,12 @@ internal static class StringLiteralParser private const string MissingEscapeSequenceMessage = "Missing escape sequence."; private const string UnrecognizedEscapeSequenceMessage = "Unrecognized escape sequence."; - public static bool TryParse(string text, bool isVerbatim, bool isInterpolatedText, out string result) + public static bool TryParse(string text, bool isVerbatim, bool isInterpolatedText, out string? result) { return TryParse(text, 0, text.Length, isVerbatim, isInterpolatedText, out result); } - public static bool TryParse(string text, int start, int length, bool isVerbatim, bool isInterpolatedText, out string result) + public static bool TryParse(string text, int start, int length, bool isVerbatim, bool isInterpolatedText, out string? result) { StringLiteralParserResult parseResult = (isVerbatim) ? ParseVerbatim(text, start, length, isInterpolatedText) @@ -54,7 +54,7 @@ private static StringLiteralParserResult ParseRegular( bool throwOnError = false, bool isInterpolatedText = false) { - StringBuilder sb = null; + StringBuilder? sb = null; for (int pos = start; pos < start + length; pos++) { char ch = text[pos]; @@ -248,7 +248,7 @@ private static StringLiteralParserResult ParseVerbatim( bool throwOnError = false, bool isInterpolatedText = false) { - StringBuilder sb = null; + StringBuilder? sb = null; for (int pos = start; pos < start + length; pos++) { diff --git a/src/CSharp/CSharp/StringLiteralTextBuilder.cs b/src/CSharp/CSharp/StringLiteralTextBuilder.cs index 13a6069b8f..6617374b9d 100644 --- a/src/CSharp/CSharp/StringLiteralTextBuilder.cs +++ b/src/CSharp/CSharp/StringLiteralTextBuilder.cs @@ -13,7 +13,7 @@ namespace Roslynator.CSharp; internal class StringLiteralTextBuilder { - public StringLiteralTextBuilder(StringBuilder stringBuilder = null, bool isVerbatim = false, bool isInterpolated = false) + public StringLiteralTextBuilder(StringBuilder? stringBuilder = null, bool isVerbatim = false, bool isInterpolated = false) { StringBuilder = stringBuilder ?? new StringBuilder(); IsVerbatim = isVerbatim; diff --git a/src/CSharp/CSharp/Syntax/AsExpressionInfo.cs b/src/CSharp/CSharp/Syntax/AsExpressionInfo.cs index 760b6a943f..1154aad604 100644 --- a/src/CSharp/CSharp/Syntax/AsExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/AsExpressionInfo.cs @@ -81,14 +81,14 @@ internal static AsExpressionInfo Create( } private static AsExpressionInfo CreateImpl( - BinaryExpressionSyntax binaryExpression, + BinaryExpressionSyntax? binaryExpression, bool walkDownParentheses = true, bool allowMissing = false) { if (binaryExpression?.Kind() != SyntaxKind.AsExpression) return default; - ExpressionSyntax expression = Walk(binaryExpression.Left, walkDownParentheses); + ExpressionSyntax? expression = Walk(binaryExpression.Left, walkDownParentheses); if (!Check(expression, allowMissing)) return default; @@ -98,6 +98,6 @@ private static AsExpressionInfo CreateImpl( if (!Check(type, allowMissing)) return default; - return new AsExpressionInfo(binaryExpression, expression, type); + return new AsExpressionInfo(binaryExpression, expression!, type!); } } diff --git a/src/CSharp/CSharp/Syntax/AssignmentExpressionInfo.cs b/src/CSharp/CSharp/Syntax/AssignmentExpressionInfo.cs index 120d437270..6c5c419dde 100644 --- a/src/CSharp/CSharp/Syntax/AssignmentExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/AssignmentExpressionInfo.cs @@ -78,19 +78,19 @@ internal static AssignmentExpressionInfo Create( } internal static AssignmentExpressionInfo Create( - AssignmentExpressionSyntax assignmentExpression, + AssignmentExpressionSyntax? assignmentExpression, bool walkDownParentheses = true, bool allowMissing = false) { if (assignmentExpression is null) return default; - ExpressionSyntax left = WalkAndCheck(assignmentExpression.Left, walkDownParentheses, allowMissing); + ExpressionSyntax? left = WalkAndCheck(assignmentExpression.Left, walkDownParentheses, allowMissing); if (left is null) return default; - ExpressionSyntax right = WalkAndCheck(assignmentExpression.Right, walkDownParentheses, allowMissing); + ExpressionSyntax? right = WalkAndCheck(assignmentExpression.Right, walkDownParentheses, allowMissing); if (right is null) return default; diff --git a/src/CSharp/CSharp/Syntax/BinaryExpressionInfo.cs b/src/CSharp/CSharp/Syntax/BinaryExpressionInfo.cs index a5a023934e..a2e5e33e53 100644 --- a/src/CSharp/CSharp/Syntax/BinaryExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/BinaryExpressionInfo.cs @@ -97,23 +97,23 @@ internal static BinaryExpressionInfo Create( } private static BinaryExpressionInfo CreateImpl( - BinaryExpressionSyntax binaryExpression, + BinaryExpressionSyntax? binaryExpression, bool walkDownParentheses = true, bool allowMissing = false) { if (binaryExpression is null) return default; - ExpressionSyntax left = Walk(binaryExpression.Left, walkDownParentheses); + ExpressionSyntax? left = Walk(binaryExpression.Left, walkDownParentheses); if (!Check(left, allowMissing)) return default; - ExpressionSyntax right = Walk(binaryExpression.Right, walkDownParentheses); + ExpressionSyntax? right = Walk(binaryExpression.Right, walkDownParentheses); if (!Check(right, allowMissing)) return default; - return new BinaryExpressionInfo(binaryExpression, left, right); + return new BinaryExpressionInfo(binaryExpression, left!, right!); } } diff --git a/src/CSharp/CSharp/Syntax/ConditionalExpressionInfo.cs b/src/CSharp/CSharp/Syntax/ConditionalExpressionInfo.cs index 72ef62bedd..053ccf6e34 100644 --- a/src/CSharp/CSharp/Syntax/ConditionalExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/ConditionalExpressionInfo.cs @@ -28,7 +28,7 @@ private ConditionalExpressionInfo( /// public ConditionalExpressionSyntax ConditionalExpression { - get { return (ConditionalExpressionSyntax)Condition?.WalkUpParentheses().Parent; } + get { return (ConditionalExpressionSyntax)Condition?.WalkUpParentheses().Parent!; } } /// @@ -77,24 +77,24 @@ private string DebuggerDisplay } internal static ConditionalExpressionInfo Create( - ConditionalExpressionSyntax conditionalExpression, + ConditionalExpressionSyntax? conditionalExpression, bool walkDownParentheses = true, bool allowMissing = false) { if (conditionalExpression is null) return default; - ExpressionSyntax condition = WalkAndCheck(conditionalExpression.Condition, walkDownParentheses, allowMissing); + ExpressionSyntax? condition = WalkAndCheck(conditionalExpression.Condition, walkDownParentheses, allowMissing); if (condition is null) return default; - ExpressionSyntax whenTrue = WalkAndCheck(conditionalExpression.WhenTrue, walkDownParentheses, allowMissing); + ExpressionSyntax? whenTrue = WalkAndCheck(conditionalExpression.WhenTrue, walkDownParentheses, allowMissing); if (whenTrue is null) return default; - ExpressionSyntax whenFalse = WalkAndCheck(conditionalExpression.WhenFalse, walkDownParentheses, allowMissing); + ExpressionSyntax? whenFalse = WalkAndCheck(conditionalExpression.WhenFalse, walkDownParentheses, allowMissing); if (whenFalse is null) return default; diff --git a/src/CSharp/CSharp/Syntax/ConditionalStatementInfo.cs b/src/CSharp/CSharp/Syntax/ConditionalStatementInfo.cs index 22c7a61834..f708f08968 100644 --- a/src/CSharp/CSharp/Syntax/ConditionalStatementInfo.cs +++ b/src/CSharp/CSharp/Syntax/ConditionalStatementInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -51,7 +52,7 @@ private ConditionalStatementInfo( /// public ElseClauseSyntax Else { - get { return IfStatement?.Else; } + get { return IfStatement?.Else ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -69,19 +70,19 @@ private string DebuggerDisplay } internal static ConditionalStatementInfo Create( - IfStatementSyntax ifStatement, + IfStatementSyntax? ifStatement, bool walkDownParentheses = true, bool allowMissing = false) { if (ifStatement?.IsParentKind(SyntaxKind.ElseClause) != false) return default; - StatementSyntax whenTrue = ifStatement.Statement.SingleNonBlockStatementOrDefault(); + StatementSyntax? whenTrue = ifStatement.Statement.SingleNonBlockStatementOrDefault(); if (!Check(whenTrue, allowMissing)) return default; - StatementSyntax whenFalse = ifStatement.Else?.Statement.SingleNonBlockStatementOrDefault(); + StatementSyntax? whenFalse = ifStatement.Else?.Statement.SingleNonBlockStatementOrDefault(); if (!Check(whenFalse, allowMissing)) return default; @@ -89,11 +90,11 @@ internal static ConditionalStatementInfo Create( if (whenFalse.IsKind(SyntaxKind.IfStatement)) return default; - ExpressionSyntax condition = WalkAndCheck(ifStatement.Condition, walkDownParentheses, allowMissing); + ExpressionSyntax? condition = WalkAndCheck(ifStatement.Condition, walkDownParentheses, allowMissing); if (condition is null) return default; - return new ConditionalStatementInfo(ifStatement, condition, whenTrue, whenFalse); + return new ConditionalStatementInfo(ifStatement, condition, whenTrue!, whenFalse!); } } diff --git a/src/CSharp/CSharp/Syntax/GenericInfo.cs b/src/CSharp/CSharp/Syntax/GenericInfo.cs index cfd392a4d2..da7ef8ce57 100644 --- a/src/CSharp/CSharp/Syntax/GenericInfo.cs +++ b/src/CSharp/CSharp/Syntax/GenericInfo.cs @@ -36,7 +36,7 @@ private GenericInfo(MethodDeclarationSyntax methodDeclaration) private GenericInfo( SyntaxNode declaration, - TypeParameterListSyntax typeParameterList, + TypeParameterListSyntax? typeParameterList, SyntaxList constraintClauses) { Node = declaration; @@ -60,7 +60,7 @@ public SyntaxKind Kind /// /// The type parameter list. /// - public TypeParameterListSyntax TypeParameterList { get; } + public TypeParameterListSyntax? TypeParameterList { get; } /// /// A list of type parameters. @@ -79,7 +79,7 @@ public SeparatedSyntaxList TypeParameters /// Searches for a type parameter with the specified name and returns the first occurrence within the type parameters. /// /// - public TypeParameterSyntax FindTypeParameter(string name) + public TypeParameterSyntax? FindTypeParameter(string name) { foreach (TypeParameterSyntax typeParameter in TypeParameters) { @@ -94,7 +94,7 @@ public TypeParameterSyntax FindTypeParameter(string name) /// Searches for a constraint clause with the specified type parameter name and returns the first occurrence within the constraint clauses. /// /// - public TypeParameterConstraintClauseSyntax FindConstraintClause(string typeParameterName) + public TypeParameterConstraintClauseSyntax? FindConstraintClause(string typeParameterName) { foreach (TypeParameterConstraintClauseSyntax constraintClause in ConstraintClauses) { @@ -124,7 +124,7 @@ private string DebuggerDisplay } } - internal static GenericInfo Create(SyntaxNode node) + internal static GenericInfo Create(SyntaxNode? node) { if (node is null) return default; @@ -176,7 +176,7 @@ internal static GenericInfo Create(TypeParameterConstraintSyntax typeParameterCo return Create(typeParameterConstraint?.Parent as TypeParameterConstraintClauseSyntax); } - internal static GenericInfo Create(TypeParameterConstraintClauseSyntax constraintClause) + internal static GenericInfo Create(TypeParameterConstraintClauseSyntax? constraintClause) { return Create(constraintClause?.Parent); } @@ -186,7 +186,7 @@ internal static GenericInfo Create(TypeParameterSyntax typeParameter) return Create(typeParameter?.Parent as TypeParameterListSyntax); } - internal static GenericInfo Create(TypeParameterListSyntax typeParameterList) + internal static GenericInfo Create(TypeParameterListSyntax? typeParameterList) { return Create(typeParameterList?.Parent); } @@ -286,13 +286,21 @@ public GenericInfo RemoveTypeParameter(TypeParameterSyntax typeParameter) SyntaxDebug.Fail(self.Node); return this; - TypeParameterListSyntax RemoveTypeParameter() + TypeParameterListSyntax? RemoveTypeParameter() { - SeparatedSyntaxList parameters = self.TypeParameters; + TypeParameterListSyntax? typeParameterList = self.TypeParameterList; - return (parameters.Count == 1) - ? default - : self.TypeParameterList.WithParameters(parameters.Remove(typeParameter)); + if (typeParameterList is null) + throw new InvalidOperationException("Cannot remove type parameter. Declaration does not have type parameter list."); + + SeparatedSyntaxList parameters = typeParameterList.Parameters; + + int index = parameters.IndexOf(typeParameter); + + if (index == -1) + throw new InvalidOperationException("Cannot remove type parameter. Type parameter is not contained in the type parameter list."); + + return typeParameterList.WithParameters(parameters.RemoveAt(index)); } } diff --git a/src/CSharp/CSharp/Syntax/HexNumericLiteralExpressionInfo.cs b/src/CSharp/CSharp/Syntax/HexNumericLiteralExpressionInfo.cs index 2dab69c060..d65dfbadcb 100644 --- a/src/CSharp/CSharp/Syntax/HexNumericLiteralExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/HexNumericLiteralExpressionInfo.cs @@ -32,7 +32,7 @@ public string ValueText get { return Token.ValueText; } } - public object Value + public object? Value { get { return Token.Value; } } @@ -99,7 +99,7 @@ internal static HexNumericLiteralExpressionInfo Create(SyntaxNode node, bool wal return Create(Walk(node, walkDownParentheses) as LiteralExpressionSyntax); } - internal static HexNumericLiteralExpressionInfo Create(LiteralExpressionSyntax literalExpression) + internal static HexNumericLiteralExpressionInfo Create(LiteralExpressionSyntax? literalExpression) { if (literalExpression is null) return default; diff --git a/src/CSharp/CSharp/Syntax/IsExpressionInfo.cs b/src/CSharp/CSharp/Syntax/IsExpressionInfo.cs index 710ac52258..d3b7257926 100644 --- a/src/CSharp/CSharp/Syntax/IsExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/IsExpressionInfo.cs @@ -81,14 +81,14 @@ internal static IsExpressionInfo Create( } private static IsExpressionInfo CreateImpl( - BinaryExpressionSyntax binaryExpression, + BinaryExpressionSyntax? binaryExpression, bool walkDownParentheses = true, bool allowMissing = false) { if (binaryExpression?.Kind() != SyntaxKind.IsExpression) return default; - ExpressionSyntax expression = Walk(binaryExpression.Left, walkDownParentheses); + ExpressionSyntax? expression = Walk(binaryExpression.Left, walkDownParentheses); if (!Check(expression, allowMissing)) return default; @@ -98,6 +98,6 @@ private static IsExpressionInfo CreateImpl( if (!Check(type, allowMissing)) return default; - return new IsExpressionInfo(binaryExpression, expression, type); + return new IsExpressionInfo(binaryExpression, expression!, type!); } } diff --git a/src/CSharp/CSharp/Syntax/LocalDeclarationStatementInfo.cs b/src/CSharp/CSharp/Syntax/LocalDeclarationStatementInfo.cs index a70a87ab47..435069d013 100644 --- a/src/CSharp/CSharp/Syntax/LocalDeclarationStatementInfo.cs +++ b/src/CSharp/CSharp/Syntax/LocalDeclarationStatementInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -37,7 +38,7 @@ public SyntaxTokenList Modifiers /// public TypeSyntax Type { - get { return Statement?.Declaration.Type; } + get { return Statement?.Declaration.Type ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -45,7 +46,7 @@ public TypeSyntax Type /// public VariableDeclarationSyntax Declaration { - get { return Statement?.Declaration; } + get { return Statement?.Declaration ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -82,12 +83,12 @@ internal static LocalDeclarationStatementInfo Create( LocalDeclarationStatementSyntax localDeclarationStatement, bool allowMissing = false) { - VariableDeclarationSyntax variableDeclaration = localDeclarationStatement?.Declaration; + VariableDeclarationSyntax? variableDeclaration = localDeclarationStatement?.Declaration; if (!Check(variableDeclaration, allowMissing)) return default; - TypeSyntax type = variableDeclaration.Type; + TypeSyntax? type = variableDeclaration!.Type; if (!Check(type, allowMissing)) return default; @@ -95,14 +96,14 @@ internal static LocalDeclarationStatementInfo Create( if (!variableDeclaration.Variables.Any()) return default; - return new LocalDeclarationStatementInfo(localDeclarationStatement); + return new LocalDeclarationStatementInfo(localDeclarationStatement!); } internal static LocalDeclarationStatementInfo Create( ExpressionSyntax value, bool allowMissing = false) { - SyntaxNode node = value?.WalkUpParentheses().Parent; + SyntaxNode? node = value?.WalkUpParentheses().Parent; if (!node.IsKind(SyntaxKind.EqualsValueClause)) return default; diff --git a/src/CSharp/CSharp/Syntax/MemberDeclarationListInfo.cs b/src/CSharp/CSharp/Syntax/MemberDeclarationListInfo.cs index 12eb8fdaad..3dbef3f831 100644 --- a/src/CSharp/CSharp/Syntax/MemberDeclarationListInfo.cs +++ b/src/CSharp/CSharp/Syntax/MemberDeclarationListInfo.cs @@ -281,39 +281,39 @@ public MemberDeclarationListInfo RemoveNode(SyntaxNode node, SyntaxRemoveOptions case SyntaxKind.CompilationUnit: { var compilationUnit = (CompilationUnitSyntax)Parent; - compilationUnit = compilationUnit.RemoveNode(node, options); + compilationUnit = compilationUnit.RemoveNode(node, options)!; return new MemberDeclarationListInfo(compilationUnit, compilationUnit.Members); } case SyntaxKind.NamespaceDeclaration: case SyntaxKind.FileScopedNamespaceDeclaration: { var declaration = (BaseNamespaceDeclarationSyntax)Parent; - declaration = declaration.RemoveNode(node, options); + declaration = declaration.RemoveNode(node, options)!; return new MemberDeclarationListInfo(declaration, declaration.Members); } case SyntaxKind.ClassDeclaration: { var declaration = (ClassDeclarationSyntax)Parent; - declaration = declaration.RemoveNode(node, options); + declaration = declaration.RemoveNode(node, options)!; return new MemberDeclarationListInfo(declaration, declaration.Members); } case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: { var declaration = (RecordDeclarationSyntax)Parent; - declaration = declaration.RemoveNode(node, options); + declaration = declaration.RemoveNode(node, options)!; return new MemberDeclarationListInfo(declaration, declaration.Members); } case SyntaxKind.StructDeclaration: { var declaration = (StructDeclarationSyntax)Parent; - declaration = declaration.RemoveNode(node, options); + declaration = declaration.RemoveNode(node, options)!; return new MemberDeclarationListInfo(declaration, declaration.Members); } case SyntaxKind.InterfaceDeclaration: { var declaration = (InterfaceDeclarationSyntax)Parent; - declaration = declaration.RemoveNode(node, options); + declaration = declaration.RemoveNode(node, options)!; return new MemberDeclarationListInfo(declaration, declaration.Members); } } @@ -412,7 +412,7 @@ public MemberDeclarationSyntax First() /// /// The first member in the list or null if the list is empty. /// - public MemberDeclarationSyntax FirstOrDefault() + public MemberDeclarationSyntax? FirstOrDefault() { return Members.FirstOrDefault(); } @@ -466,7 +466,7 @@ public MemberDeclarationSyntax Last() /// /// The last member in the list or null if the list is empty. /// - public MemberDeclarationSyntax LastOrDefault() + public MemberDeclarationSyntax? LastOrDefault() { return Members.LastOrDefault(); } diff --git a/src/CSharp/CSharp/Syntax/ModifierListInfo.cs b/src/CSharp/CSharp/Syntax/ModifierListInfo.cs index 5be1b5149f..b04a23533b 100644 --- a/src/CSharp/CSharp/Syntax/ModifierListInfo.cs +++ b/src/CSharp/CSharp/Syntax/ModifierListInfo.cs @@ -375,7 +375,7 @@ public ModifierListInfo WithoutExplicitAccessibility() /// /// /// - public ModifierListInfo WithExplicitAccessibility(Accessibility newAccessibility, IComparer comparer = null) + public ModifierListInfo WithExplicitAccessibility(Accessibility newAccessibility, IComparer? comparer = null) { ThrowInvalidOperationIfNotInitialized(); diff --git a/src/CSharp/CSharp/Syntax/NullCheckExpressionInfo.cs b/src/CSharp/CSharp/Syntax/NullCheckExpressionInfo.cs index 3a06b3c112..4d771e7ec5 100644 --- a/src/CSharp/CSharp/Syntax/NullCheckExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/NullCheckExpressionInfo.cs @@ -107,13 +107,13 @@ internal static NullCheckExpressionInfo Create( private static NullCheckExpressionInfo CreateImpl( SyntaxNode node, - SemanticModel semanticModel, + SemanticModel? semanticModel, NullCheckStyles allowedStyles, bool walkDownParentheses, bool allowMissing, CancellationToken cancellationToken) { - ExpressionSyntax expression = WalkAndCheck(node, walkDownParentheses, allowMissing); + ExpressionSyntax? expression = WalkAndCheck(node, walkDownParentheses, allowMissing); if (expression is null) return default; @@ -127,12 +127,12 @@ private static NullCheckExpressionInfo CreateImpl( { var binaryExpression = (BinaryExpressionSyntax)expression; - ExpressionSyntax left = WalkAndCheck(binaryExpression.Left, walkDownParentheses, allowMissing); + ExpressionSyntax? left = WalkAndCheck(binaryExpression.Left, walkDownParentheses, allowMissing); if (left is null) break; - ExpressionSyntax right = WalkAndCheck(binaryExpression.Right, walkDownParentheses, allowMissing); + ExpressionSyntax? right = WalkAndCheck(binaryExpression.Right, walkDownParentheses, allowMissing); if (right is null) break; @@ -153,6 +153,9 @@ private static NullCheckExpressionInfo CreateImpl( if ((allowedStyles & NullCheckStyles.HasValue) == 0) break; + if (semanticModel is null) + break; + var memberAccessExpression = (MemberAccessExpressionSyntax)expression; if (!IsPropertyOfNullableOfT(memberAccessExpression.Name, "HasValue", semanticModel, cancellationToken)) @@ -189,7 +192,7 @@ private static NullCheckExpressionInfo CreateImpl( if (!constantPattern.Expression.IsKind(SyntaxKind.NullLiteralExpression)) break; - ExpressionSyntax e = WalkAndCheck(isPatternExpression.Expression, walkDownParentheses, allowMissing); + ExpressionSyntax? e = WalkAndCheck(isPatternExpression.Expression, walkDownParentheses, allowMissing); if (e is null) break; @@ -209,7 +212,7 @@ private static NullCheckExpressionInfo CreateImpl( var logicalNotExpression = (PrefixUnaryExpressionSyntax)expression; - ExpressionSyntax operand = WalkAndCheck(logicalNotExpression.Operand, walkDownParentheses, allowMissing); + ExpressionSyntax? operand = WalkAndCheck(logicalNotExpression.Operand, walkDownParentheses, allowMissing); if (operand is null) break; @@ -221,6 +224,9 @@ private static NullCheckExpressionInfo CreateImpl( if (!isNotHasValueAllowed) break; + if (semanticModel is null) + break; + var memberAccessExpression = (MemberAccessExpressionSyntax)operand; if (!IsPropertyOfNullableOfT(memberAccessExpression.Name, "HasValue", semanticModel, cancellationToken)) @@ -241,7 +247,7 @@ private static NullCheckExpressionInfo CreateImpl( if (!constantPattern.Expression.IsKind(SyntaxKind.NullLiteralExpression)) break; - ExpressionSyntax e = WalkAndCheck(isPatternExpression.Expression, walkDownParentheses, allowMissing); + ExpressionSyntax? e = WalkAndCheck(isPatternExpression.Expression, walkDownParentheses, allowMissing); if (e is null) break; @@ -264,7 +270,7 @@ private static NullCheckExpressionInfo Create( ExpressionSyntax expression2, NullCheckStyles allowedStyles, bool allowMissing, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { switch (expression1.Kind()) @@ -323,12 +329,15 @@ private static NullCheckExpressionInfo Create( NullCheckStyles style, NullCheckStyles allowedStyles, bool allowMissing, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { if ((allowedStyles & (NullCheckStyles.HasValueProperty)) == 0) return default; + if (semanticModel is null) + return default; + if (expression is not MemberAccessExpressionSyntax memberAccessExpression) return default; @@ -363,7 +372,7 @@ private static bool IsPropertyOfNullableOfT( private static bool IsNullOrDefault( ExpressionSyntax left, ExpressionSyntax right, - SemanticModel semanticModel, + SemanticModel? semanticModel, CancellationToken cancellationToken) { switch (right?.Kind()) @@ -377,19 +386,19 @@ private static bool IsNullOrDefault( if (semanticModel is null) return false; - ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(left, cancellationToken); + ITypeSymbol? typeSymbol = semanticModel.GetTypeSymbol(left, cancellationToken); if (typeSymbol?.IsReferenceType != true) return false; - ITypeSymbol typeSymbol2 = semanticModel.GetTypeSymbol(right, cancellationToken); + ITypeSymbol? typeSymbol2 = semanticModel.GetTypeSymbol(right, cancellationToken); return SymbolEqualityComparer.Default.Equals(typeSymbol, typeSymbol2); } case SyntaxKind.DefaultLiteralExpression: { return semanticModel? - .GetTypeSymbol(left, cancellationToken) + .GetTypeSymbol(left, cancellationToken)? .IsReferenceType == true; } default: diff --git a/src/CSharp/CSharp/Syntax/ParameterInfo.cs b/src/CSharp/CSharp/Syntax/ParameterInfo.cs index 50731019b4..de5320591c 100644 --- a/src/CSharp/CSharp/Syntax/ParameterInfo.cs +++ b/src/CSharp/CSharp/Syntax/ParameterInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -14,9 +15,9 @@ internal readonly struct ParameterInfo public ParameterInfo(ParameterSyntax parameter, CSharpSyntaxNode body) { Parameter = parameter; - ParameterList = default; + ParameterList = null; Body = body; - TypeParameterList = default; + TypeParameterList = null; } public ParameterInfo(BaseParameterListSyntax parameterList, CSharpSyntaxNode body) @@ -24,36 +25,36 @@ public ParameterInfo(BaseParameterListSyntax parameterList, CSharpSyntaxNode bod { } - public ParameterInfo(BaseParameterListSyntax parameterList, TypeParameterListSyntax typeParameterList, CSharpSyntaxNode body) + public ParameterInfo(BaseParameterListSyntax parameterList, TypeParameterListSyntax? typeParameterList, CSharpSyntaxNode? body) { ParameterList = parameterList; - Parameter = default; + Parameter = null; Body = body; TypeParameterList = typeParameterList; } public SyntaxNode Node { - get { return ParameterList?.Parent ?? Parameter?.Parent; } + get { return ParameterList?.Parent ?? Parameter?.Parent ?? throw new InvalidOperationException("Object is not initialized."); } } - public TypeParameterListSyntax TypeParameterList { get; } + public TypeParameterListSyntax? TypeParameterList { get; } public SeparatedSyntaxList TypeParameters { get { return TypeParameterList?.Parameters ?? default; } } - public ParameterSyntax Parameter { get; } + public ParameterSyntax? Parameter { get; } - public BaseParameterListSyntax ParameterList { get; } + public BaseParameterListSyntax? ParameterList { get; } public SeparatedSyntaxList Parameters { get { return ParameterList?.Parameters ?? default; } } - public CSharpSyntaxNode Body { get; } + public CSharpSyntaxNode? Body { get; } public bool Success { @@ -63,7 +64,7 @@ public bool Success [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay { - get { return SyntaxInfoHelpers.ToDebugString(Success, this, ParameterList ?? (SyntaxNode)Parameter); } + get { return SyntaxInfoHelpers.ToDebugString(Success, this, ParameterList ?? (SyntaxNode?)Parameter); } } internal static ParameterInfo Create(ConstructorDeclarationSyntax constructorDeclaration, bool allowMissing = false) @@ -73,12 +74,12 @@ internal static ParameterInfo Create(ConstructorDeclarationSyntax constructorDec if (!CheckParameterList(parameterList, allowMissing)) return default; - CSharpSyntaxNode body = constructorDeclaration.BodyOrExpressionBody(); + CSharpSyntaxNode? body = constructorDeclaration.BodyOrExpressionBody(); if (!Check(body, allowMissing)) return default; - return new ParameterInfo(parameterList, body); + return new ParameterInfo(parameterList, body!); } internal static ParameterInfo Create(MethodDeclarationSyntax methodDeclaration, bool allowMissing = false) @@ -93,7 +94,7 @@ internal static ParameterInfo Create(MethodDeclarationSyntax methodDeclaration, if (!CheckParameters(parameters, allowMissing)) return default; - TypeParameterListSyntax typeParameterList = methodDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = methodDeclaration.TypeParameterList; SeparatedSyntaxList typeParameters = typeParameterList?.Parameters ?? default; if (!CheckTypeParameters(typeParameters, allowMissing)) @@ -105,7 +106,7 @@ internal static ParameterInfo Create(MethodDeclarationSyntax methodDeclaration, return default; } - CSharpSyntaxNode body = methodDeclaration.BodyOrExpressionBody(); + CSharpSyntaxNode? body = methodDeclaration.BodyOrExpressionBody(); if (!Check(body, allowMissing)) return default; @@ -120,12 +121,12 @@ internal static ParameterInfo Create(OperatorDeclarationSyntax operatorDeclarati if (!CheckParameterList(parameterList, allowMissing)) return default; - CSharpSyntaxNode body = operatorDeclaration.BodyOrExpressionBody(); + CSharpSyntaxNode? body = operatorDeclaration.BodyOrExpressionBody(); if (!Check(body, allowMissing)) return default; - return new ParameterInfo(parameterList, body); + return new ParameterInfo(parameterList, body!); } internal static ParameterInfo Create(ConversionOperatorDeclarationSyntax conversionOperatorDeclaration, bool allowMissing = false) @@ -135,12 +136,12 @@ internal static ParameterInfo Create(ConversionOperatorDeclarationSyntax convers if (!CheckParameterList(parameterList, allowMissing)) return default; - CSharpSyntaxNode body = conversionOperatorDeclaration.BodyOrExpressionBody(); + CSharpSyntaxNode? body = conversionOperatorDeclaration.BodyOrExpressionBody(); if (!Check(body, allowMissing)) return default; - return new ParameterInfo(parameterList, body); + return new ParameterInfo(parameterList, body!); } internal static ParameterInfo Create(DelegateDeclarationSyntax delegateDeclaration, bool allowMissing = false) @@ -155,7 +156,7 @@ internal static ParameterInfo Create(DelegateDeclarationSyntax delegateDeclarati if (!CheckParameters(parameters, allowMissing)) return default; - TypeParameterListSyntax typeParameterList = delegateDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = delegateDeclaration.TypeParameterList; SeparatedSyntaxList typeParameters = typeParameterList?.Parameters ?? default; if (!CheckTypeParameters(typeParameters, allowMissing)) @@ -182,7 +183,7 @@ internal static ParameterInfo Create(LocalFunctionStatementSyntax localFunction, if (!CheckParameters(parameters, allowMissing)) return default; - TypeParameterListSyntax typeParameterList = localFunction.TypeParameterList; + TypeParameterListSyntax? typeParameterList = localFunction.TypeParameterList; SeparatedSyntaxList typeParameters = typeParameterList?.Parameters ?? default; if (!CheckTypeParameters(typeParameters, allowMissing)) @@ -194,7 +195,7 @@ internal static ParameterInfo Create(LocalFunctionStatementSyntax localFunction, return default; } - CSharpSyntaxNode body = localFunction.BodyOrExpressionBody(); + CSharpSyntaxNode? body = localFunction.BodyOrExpressionBody(); if (!Check(body, allowMissing)) return default; @@ -209,12 +210,12 @@ internal static ParameterInfo Create(IndexerDeclarationSyntax indexerDeclaration if (!CheckParameterList(parameterList, allowMissing)) return default; - CSharpSyntaxNode body = indexerDeclaration.AccessorList ?? (CSharpSyntaxNode)indexerDeclaration.ExpressionBody; + CSharpSyntaxNode? body = indexerDeclaration.AccessorList ?? (CSharpSyntaxNode?)indexerDeclaration.ExpressionBody; if (!Check(body, allowMissing)) return default; - return new ParameterInfo(parameterList, body); + return new ParameterInfo(parameterList, body!); } internal static ParameterInfo Create(SimpleLambdaExpressionSyntax simpleLambda, bool allowMissing = false) @@ -249,7 +250,7 @@ internal static ParameterInfo Create(ParenthesizedLambdaExpressionSyntax parenth internal static ParameterInfo Create(AnonymousMethodExpressionSyntax anonymousMethod, bool allowMissing = false) { - ParameterListSyntax parameterList = anonymousMethod.ParameterList; + ParameterListSyntax? parameterList = anonymousMethod.ParameterList; if (!CheckParameterList(parameterList, allowMissing)) return default; @@ -259,15 +260,15 @@ internal static ParameterInfo Create(AnonymousMethodExpressionSyntax anonymousMe if (!Check(body, allowMissing)) return default; - return new ParameterInfo(parameterList, body); + return new ParameterInfo(parameterList!, body); } - private static bool CheckParameterList(BaseParameterListSyntax parameterList, bool allowMissing) + private static bool CheckParameterList(BaseParameterListSyntax? parameterList, bool allowMissing) { if (!Check(parameterList, allowMissing)) return false; - SeparatedSyntaxList parameters = parameterList.Parameters; + SeparatedSyntaxList parameters = parameterList!.Parameters; if (!parameters.Any()) return false; diff --git a/src/CSharp/CSharp/Syntax/RegionInfo.cs b/src/CSharp/CSharp/Syntax/RegionInfo.cs index 418dd33153..7cef739118 100644 --- a/src/CSharp/CSharp/Syntax/RegionInfo.cs +++ b/src/CSharp/CSharp/Syntax/RegionInfo.cs @@ -88,7 +88,7 @@ private string DebuggerDisplay get { return SyntaxInfoHelpers.ToDebugString(Success, this, Directive); } } - private static EndRegionDirectiveTriviaSyntax FindEndRegionDirective(SyntaxTriviaList list, int index) + private static EndRegionDirectiveTriviaSyntax? FindEndRegionDirective(SyntaxTriviaList list, int index) { for (int i = index + 1; i < list.Count; i++) { @@ -104,7 +104,7 @@ private static EndRegionDirectiveTriviaSyntax FindEndRegionDirective(SyntaxTrivi case SyntaxKind.EndRegionDirectiveTrivia: { if (trivia.HasStructure) - return (EndRegionDirectiveTriviaSyntax)trivia.GetStructure(); + return (EndRegionDirectiveTriviaSyntax)trivia.GetStructure()!; return null; } diff --git a/src/CSharp/CSharp/Syntax/SimpleAssignmentExpressionInfo.cs b/src/CSharp/CSharp/Syntax/SimpleAssignmentExpressionInfo.cs index f910d04c66..56244293ac 100644 --- a/src/CSharp/CSharp/Syntax/SimpleAssignmentExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/SimpleAssignmentExpressionInfo.cs @@ -70,19 +70,19 @@ internal static SimpleAssignmentExpressionInfo Create( } internal static SimpleAssignmentExpressionInfo Create( - AssignmentExpressionSyntax assignmentExpression, + AssignmentExpressionSyntax? assignmentExpression, bool walkDownParentheses = true, bool allowMissing = false) { if (assignmentExpression?.Kind() != SyntaxKind.SimpleAssignmentExpression) return default; - ExpressionSyntax left = WalkAndCheck(assignmentExpression.Left, walkDownParentheses, allowMissing); + ExpressionSyntax? left = WalkAndCheck(assignmentExpression.Left, walkDownParentheses, allowMissing); if (left is null) return default; - ExpressionSyntax right = WalkAndCheck(assignmentExpression.Right, walkDownParentheses, allowMissing); + ExpressionSyntax? right = WalkAndCheck(assignmentExpression.Right, walkDownParentheses, allowMissing); if (right is null) return default; diff --git a/src/CSharp/CSharp/Syntax/SimpleAssignmentStatementInfo.cs b/src/CSharp/CSharp/Syntax/SimpleAssignmentStatementInfo.cs index f6e8669c26..fbfc69182d 100644 --- a/src/CSharp/CSharp/Syntax/SimpleAssignmentStatementInfo.cs +++ b/src/CSharp/CSharp/Syntax/SimpleAssignmentStatementInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -46,7 +47,7 @@ private SimpleAssignmentStatementInfo(in SimpleAssignmentExpressionInfo info) /// public ExpressionStatementSyntax Statement { - get { return (ExpressionStatementSyntax)AssignmentExpression?.Parent; } + get { return (ExpressionStatementSyntax?)AssignmentExpression?.Parent ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -69,11 +70,11 @@ internal static SimpleAssignmentStatementInfo Create( } internal static SimpleAssignmentStatementInfo Create( - ExpressionStatementSyntax expressionStatement, + ExpressionStatementSyntax? expressionStatement, bool walkDownParentheses = true, bool allowMissing = false) { - ExpressionSyntax expression = expressionStatement?.Expression; + ExpressionSyntax? expression = expressionStatement?.Expression; if (Check(expression, allowMissing)) return CreateImpl(expression as AssignmentExpressionSyntax, walkDownParentheses, allowMissing); @@ -93,7 +94,7 @@ internal static SimpleAssignmentStatementInfo Create( } private static SimpleAssignmentStatementInfo CreateImpl( - AssignmentExpressionSyntax assignmentExpression, + AssignmentExpressionSyntax? assignmentExpression, bool walkDownParentheses = true, bool allowMissing = false) { diff --git a/src/CSharp/CSharp/Syntax/SimpleIfStatementInfo.cs b/src/CSharp/CSharp/Syntax/SimpleIfStatementInfo.cs index 0beed7c79b..ea92db137a 100644 --- a/src/CSharp/CSharp/Syntax/SimpleIfStatementInfo.cs +++ b/src/CSharp/CSharp/Syntax/SimpleIfStatementInfo.cs @@ -62,14 +62,14 @@ internal static SimpleIfStatementInfo Create( } internal static SimpleIfStatementInfo Create( - IfStatementSyntax ifStatement, + IfStatementSyntax? ifStatement, bool walkDownParentheses = true, bool allowMissing = false) { if (ifStatement?.IsSimpleIf() != true) return default; - ExpressionSyntax condition = WalkAndCheck(ifStatement.Condition, walkDownParentheses, allowMissing); + ExpressionSyntax? condition = WalkAndCheck(ifStatement.Condition, walkDownParentheses, allowMissing); if (condition is null) return default; diff --git a/src/CSharp/CSharp/Syntax/SimpleMemberInvocationExpressionInfo.cs b/src/CSharp/CSharp/Syntax/SimpleMemberInvocationExpressionInfo.cs index 29d715d482..8e4846363a 100644 --- a/src/CSharp/CSharp/Syntax/SimpleMemberInvocationExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/SimpleMemberInvocationExpressionInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -37,7 +38,7 @@ private SimpleMemberInvocationExpressionInfo( /// public ExpressionSyntax Expression { - get { return MemberAccessExpression?.Expression; } + get { return MemberAccessExpression?.Expression ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -45,7 +46,7 @@ public ExpressionSyntax Expression /// public SimpleNameSyntax Name { - get { return MemberAccessExpression?.Name; } + get { return MemberAccessExpression?.Name ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -53,7 +54,7 @@ public SimpleNameSyntax Name /// public ArgumentListSyntax ArgumentList { - get { return InvocationExpression?.ArgumentList; } + get { return InvocationExpression?.ArgumentList ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -77,7 +78,7 @@ public SyntaxToken OperatorToken /// public string NameText { - get { return Name?.Identifier.ValueText; } + get { return Name?.Identifier.ValueText ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -112,7 +113,7 @@ internal static SimpleMemberInvocationExpressionInfo Create( } private static SimpleMemberInvocationExpressionInfo CreateImpl( - InvocationExpressionSyntax invocationExpression, + InvocationExpressionSyntax? invocationExpression, bool allowMissing = false) { if (invocationExpression?.Expression is not MemberAccessExpressionSyntax memberAccessExpression) diff --git a/src/CSharp/CSharp/Syntax/SimpleMemberInvocationStatementInfo.cs b/src/CSharp/CSharp/Syntax/SimpleMemberInvocationStatementInfo.cs index 11d13ab823..0067087716 100644 --- a/src/CSharp/CSharp/Syntax/SimpleMemberInvocationStatementInfo.cs +++ b/src/CSharp/CSharp/Syntax/SimpleMemberInvocationStatementInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -60,7 +61,7 @@ private SimpleMemberInvocationStatementInfo(in SimpleMemberInvocationExpressionI /// public ExpressionStatementSyntax Statement { - get { return (ExpressionStatementSyntax)InvocationExpression?.Parent; } + get { return (ExpressionStatementSyntax?)InvocationExpression?.Parent ?? throw new InvalidOperationException("Object is not initialized."); } } /// diff --git a/src/CSharp/CSharp/Syntax/SingleLocalDeclarationStatementInfo.cs b/src/CSharp/CSharp/Syntax/SingleLocalDeclarationStatementInfo.cs index dc4245bca2..e8a12f467f 100644 --- a/src/CSharp/CSharp/Syntax/SingleLocalDeclarationStatementInfo.cs +++ b/src/CSharp/CSharp/Syntax/SingleLocalDeclarationStatementInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -37,13 +38,13 @@ private SingleLocalDeclarationStatementInfo( /// public VariableDeclarationSyntax Declaration { - get { return Statement?.Declaration; } + get { return Statement?.Declaration ?? throw new InvalidOperationException("Object is not initialized."); } } /// /// The variable initializer, if any. /// - public EqualsValueClauseSyntax Initializer + public EqualsValueClauseSyntax? Initializer { get { return Declarator?.Initializer; } } @@ -51,7 +52,7 @@ public EqualsValueClauseSyntax Initializer /// /// The initialized value, if any. /// - public ExpressionSyntax Value + public ExpressionSyntax? Value { get { return Initializer?.Value; } } @@ -69,7 +70,7 @@ public SyntaxTokenList Modifiers /// public TypeSyntax Type { - get { return Statement?.Declaration.Type; } + get { return Statement?.Declaration.Type ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -132,17 +133,17 @@ internal static SingleLocalDeclarationStatementInfo Create( LocalDeclarationStatementSyntax localDeclarationStatement, bool allowMissing = false) { - VariableDeclarationSyntax variableDeclaration = localDeclarationStatement?.Declaration; + VariableDeclarationSyntax? variableDeclaration = localDeclarationStatement?.Declaration; if (!Check(variableDeclaration, allowMissing)) return default; - VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false); + VariableDeclaratorSyntax? variableDeclarator = variableDeclaration!.Variables.SingleOrDefault(shouldThrow: false); if (!Check(variableDeclarator, allowMissing)) return default; - return new SingleLocalDeclarationStatementInfo(localDeclarationStatement, variableDeclarator); + return new SingleLocalDeclarationStatementInfo(localDeclarationStatement!, variableDeclarator!); } internal static SingleLocalDeclarationStatementInfo Create( @@ -155,17 +156,17 @@ internal static SingleLocalDeclarationStatementInfo Create( if (variableDeclaration.Parent is not LocalDeclarationStatementSyntax localDeclarationStatement) return default; - VariableDeclaratorSyntax variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false); + VariableDeclaratorSyntax? variableDeclarator = variableDeclaration.Variables.SingleOrDefault(shouldThrow: false); if (!Check(variableDeclarator, allowMissing)) return default; - return new SingleLocalDeclarationStatementInfo(localDeclarationStatement, variableDeclarator); + return new SingleLocalDeclarationStatementInfo(localDeclarationStatement, variableDeclarator!); } internal static SingleLocalDeclarationStatementInfo Create(ExpressionSyntax value) { - SyntaxNode node = value?.WalkUpParentheses().Parent; + SyntaxNode? node = value?.WalkUpParentheses().Parent; if (!node.IsKind(SyntaxKind.EqualsValueClause)) return default; diff --git a/src/CSharp/CSharp/Syntax/SingleParameterLambdaExpressionInfo.cs b/src/CSharp/CSharp/Syntax/SingleParameterLambdaExpressionInfo.cs index 972c9e2752..c0788f3174 100644 --- a/src/CSharp/CSharp/Syntax/SingleParameterLambdaExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/SingleParameterLambdaExpressionInfo.cs @@ -42,9 +42,9 @@ private SingleParameterLambdaExpressionInfo( /// /// The parameter list that contains the parameter. /// - public ParameterListSyntax ParameterList + public ParameterListSyntax? ParameterList { - get { return (IsParenthesizedLambda) ? (ParameterListSyntax)Parameter.Parent : null; } + get { return (IsParenthesizedLambda) ? (ParameterListSyntax?)Parameter.Parent : null; } } /// @@ -93,7 +93,7 @@ internal static SingleParameterLambdaExpressionInfo Create( } private static SingleParameterLambdaExpressionInfo CreateImpl( - LambdaExpressionSyntax lambdaExpression, + LambdaExpressionSyntax? lambdaExpression, bool allowMissing = false) { switch (lambdaExpression?.Kind()) @@ -118,7 +118,7 @@ private static SingleParameterLambdaExpressionInfo CreateImpl( { var parenthesizedLambda = (ParenthesizedLambdaExpressionSyntax)lambdaExpression; - ParameterSyntax parameter = parenthesizedLambda + ParameterSyntax? parameter = parenthesizedLambda .ParameterList? .Parameters .SingleOrDefault(shouldThrow: false); @@ -131,7 +131,7 @@ private static SingleParameterLambdaExpressionInfo CreateImpl( if (!Check(body, allowMissing)) break; - return new SingleParameterLambdaExpressionInfo(parenthesizedLambda, parameter, body); + return new SingleParameterLambdaExpressionInfo(parenthesizedLambda, parameter!, body); } } diff --git a/src/CSharp/CSharp/Syntax/StatementListInfo.cs b/src/CSharp/CSharp/Syntax/StatementListInfo.cs index 8c55d2c4c0..cab90be791 100644 --- a/src/CSharp/CSharp/Syntax/StatementListInfo.cs +++ b/src/CSharp/CSharp/Syntax/StatementListInfo.cs @@ -19,16 +19,12 @@ namespace Roslynator.CSharp.Syntax; { internal StatementListInfo(BlockSyntax block) { - Debug.Assert(block is not null); - Parent = block; Statements = block.Statements; } internal StatementListInfo(SwitchSectionSyntax switchSection) { - Debug.Assert(switchSection is not null); - Parent = switchSection; Statements = switchSection.Statements; } @@ -62,7 +58,7 @@ public bool IsParentSwitchSection /// /// Gets a block that contains the statements. Returns null if the statements are not contained in a block. /// - public BlockSyntax ParentAsBlock + public BlockSyntax? ParentAsBlock { get { @@ -74,7 +70,7 @@ public BlockSyntax ParentAsBlock /// /// Gets a switch section that contains the statements. Returns null if the statements are not contained in a switch section. /// - public SwitchSectionSyntax ParentAsSwitchSection + public SwitchSectionSyntax? ParentAsSwitchSection { get { @@ -133,12 +129,12 @@ public SyntaxList.Enumerator GetEnumerator() return Statements.GetEnumerator(); } - internal static StatementListInfo Create(StatementSyntax statementInList) + internal static StatementListInfo Create(StatementSyntax? statementInList) { if (statementInList is null) return default; - SyntaxNode parent = statementInList.Parent; + SyntaxNode? parent = statementInList.Parent; switch (parent?.Kind()) { @@ -193,9 +189,9 @@ public StatementListInfo RemoveNode(SyntaxNode node, SyntaxRemoveOptions options SyntaxNode parent = Parent; if (parent.IsKind(SyntaxKind.Block)) - return new StatementListInfo(((BlockSyntax)parent).RemoveNode(node, options)); + return new StatementListInfo(((BlockSyntax)parent).RemoveNode(node, options)!); - return new StatementListInfo(((SwitchSectionSyntax)parent).RemoveNode(node, options)); + return new StatementListInfo(((SwitchSectionSyntax)parent).RemoveNode(node, options)!); } /// @@ -252,7 +248,7 @@ public StatementSyntax First() /// /// The first statement in the list or null if the list is empty. /// - public StatementSyntax FirstOrDefault() + public StatementSyntax? FirstOrDefault() { return Statements.FirstOrDefault(); } @@ -306,7 +302,7 @@ public StatementSyntax Last() /// /// The last statement in the list or null if the list is empty. /// - public StatementSyntax LastOrDefault() + public StatementSyntax? LastOrDefault() { return Statements.LastOrDefault(); } diff --git a/src/CSharp/CSharp/Syntax/StringConcatenationExpressionInfo.cs b/src/CSharp/CSharp/Syntax/StringConcatenationExpressionInfo.cs index d34fea4207..0c92911d3d 100644 --- a/src/CSharp/CSharp/Syntax/StringConcatenationExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/StringConcatenationExpressionInfo.cs @@ -72,10 +72,13 @@ internal static StringConcatenationExpressionInfo Create( } internal static StringConcatenationExpressionInfo Create( - BinaryExpressionSyntax binaryExpression, + BinaryExpressionSyntax? binaryExpression, SemanticModel semanticModel, CancellationToken cancellationToken = default) { + if (binaryExpression is null) + return default; + ExpressionChain chain = binaryExpression.AsChain(); if (!chain.Reverse().IsStringConcatenation(semanticModel, cancellationToken)) diff --git a/src/CSharp/CSharp/Syntax/StringLiteralExpressionInfo.cs b/src/CSharp/CSharp/Syntax/StringLiteralExpressionInfo.cs index d33493ac11..21b5682562 100644 --- a/src/CSharp/CSharp/Syntax/StringLiteralExpressionInfo.cs +++ b/src/CSharp/CSharp/Syntax/StringLiteralExpressionInfo.cs @@ -141,7 +141,7 @@ internal static StringLiteralExpressionInfo Create( return Create(Walk(node, walkDownParentheses) as LiteralExpressionSyntax); } - internal static StringLiteralExpressionInfo Create(LiteralExpressionSyntax literalExpression) + internal static StringLiteralExpressionInfo Create(LiteralExpressionSyntax? literalExpression) { if (literalExpression?.Kind() != SyntaxKind.StringLiteralExpression) return default; diff --git a/src/CSharp/CSharp/Syntax/SyntaxInfoHelpers.cs b/src/CSharp/CSharp/Syntax/SyntaxInfoHelpers.cs index 8200830025..38caa9d7dc 100644 --- a/src/CSharp/CSharp/Syntax/SyntaxInfoHelpers.cs +++ b/src/CSharp/CSharp/Syntax/SyntaxInfoHelpers.cs @@ -8,41 +8,41 @@ namespace Roslynator.CSharp.Syntax; internal static class SyntaxInfoHelpers { - public static ExpressionSyntax Walk(SyntaxNode node, bool walkDownParentheses) + public static ExpressionSyntax? Walk(SyntaxNode node, bool walkDownParentheses) { return Walk(node as ExpressionSyntax, walkDownParentheses); } - public static ExpressionSyntax Walk(ExpressionSyntax expression, bool walkDownParentheses) + public static ExpressionSyntax? Walk(ExpressionSyntax? expression, bool walkDownParentheses) { return expression?.WalkDownParenthesesIf(walkDownParentheses); } - public static ExpressionSyntax WalkAndCheck(SyntaxNode node, bool walkDownParentheses, bool allowMissing) + public static ExpressionSyntax? WalkAndCheck(SyntaxNode node, bool walkDownParentheses, bool allowMissing) { return WalkAndCheck(Walk(node, walkDownParentheses), allowMissing); } - public static ExpressionSyntax WalkAndCheck(ExpressionSyntax expression, bool walkDownParentheses, bool allowMissing) + public static ExpressionSyntax? WalkAndCheck(ExpressionSyntax expression, bool walkDownParentheses, bool allowMissing) { return WalkAndCheck(Walk(expression, walkDownParentheses), allowMissing); } - private static ExpressionSyntax WalkAndCheck(ExpressionSyntax expression, bool allowMissing) + private static ExpressionSyntax? WalkAndCheck(ExpressionSyntax? expression, bool allowMissing) { return (Check(expression, allowMissing)) ? expression : null; } - public static bool Check(SyntaxNode node, bool allowMissing) + public static bool Check(SyntaxNode? node, bool allowMissing) { return node is not null && (allowMissing || !node.IsMissing); } - public static string ToDebugString(bool success, TInfo info, SyntaxNode node, string text = null) where TInfo : struct + public static string ToDebugString(bool success, TInfo info, SyntaxNode? node, string? text = null) where TInfo : struct { return (success) - ? $"{info.GetType().Name} {node.Kind()} {text ?? node.ToString()}" + ? $"{info.GetType().Name} {node!.Kind()} {text ?? node!.ToString()}" : "Uninitialized"; } diff --git a/src/CSharp/CSharp/Syntax/TypeParameterConstraintInfo.cs b/src/CSharp/CSharp/Syntax/TypeParameterConstraintInfo.cs index 234a97ce08..72b4676213 100644 --- a/src/CSharp/CSharp/Syntax/TypeParameterConstraintInfo.cs +++ b/src/CSharp/CSharp/Syntax/TypeParameterConstraintInfo.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -45,7 +46,7 @@ public SeparatedSyntaxList Constraints /// public IdentifierNameSyntax Name { - get { return ConstraintClause?.Name; } + get { return ConstraintClause?.Name ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -53,7 +54,7 @@ public IdentifierNameSyntax Name /// public string NameText { - get { return Name?.Identifier.ValueText; } + get { return Name?.Identifier.ValueText ?? throw new InvalidOperationException("Object is not initialized."); } } /// @@ -114,7 +115,7 @@ internal static TypeParameterConstraintInfo Create( if (!Check(name, allowMissing)) return default; - SyntaxNode parent = constraintClause.Parent; + SyntaxNode? parent = constraintClause.Parent; switch (parent?.Kind()) { @@ -122,7 +123,7 @@ internal static TypeParameterConstraintInfo Create( { var classDeclaration = (ClassDeclarationSyntax)parent; - TypeParameterListSyntax typeParameterList = classDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = classDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; @@ -133,7 +134,7 @@ internal static TypeParameterConstraintInfo Create( { var delegateDeclaration = (DelegateDeclarationSyntax)parent; - TypeParameterListSyntax typeParameterList = delegateDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = delegateDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; @@ -144,7 +145,7 @@ internal static TypeParameterConstraintInfo Create( { var interfaceDeclaration = (InterfaceDeclarationSyntax)parent; - TypeParameterListSyntax typeParameterList = interfaceDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = interfaceDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; @@ -155,7 +156,7 @@ internal static TypeParameterConstraintInfo Create( { var localFunctionStatement = (LocalFunctionStatementSyntax)parent; - TypeParameterListSyntax typeParameterList = localFunctionStatement.TypeParameterList; + TypeParameterListSyntax? typeParameterList = localFunctionStatement.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; @@ -166,7 +167,7 @@ internal static TypeParameterConstraintInfo Create( { var methodDeclaration = (MethodDeclarationSyntax)parent; - TypeParameterListSyntax typeParameterList = methodDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = methodDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; @@ -178,7 +179,7 @@ internal static TypeParameterConstraintInfo Create( { var recordDeclaration = (RecordDeclarationSyntax)parent; - TypeParameterListSyntax typeParameterList = recordDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = recordDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; @@ -189,7 +190,7 @@ internal static TypeParameterConstraintInfo Create( { var structDeclaration = (StructDeclarationSyntax)parent; - TypeParameterListSyntax typeParameterList = structDeclaration.TypeParameterList; + TypeParameterListSyntax? typeParameterList = structDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) return default; diff --git a/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs b/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs index 8b96866dc5..0d9e65089c 100644 --- a/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs +++ b/src/CSharp/CSharp/Syntax/UsingDirectiveListInfo.cs @@ -178,12 +178,12 @@ public UsingDirectiveListInfo RemoveNode(SyntaxNode node, SyntaxRemoveOptions op { case CompilationUnitSyntax compilationUnit: { - compilationUnit = compilationUnit.RemoveNode(node, options); + compilationUnit = compilationUnit.RemoveNode(node, options)!; return new UsingDirectiveListInfo(compilationUnit, compilationUnit.Usings); } case NamespaceDeclarationSyntax declaration: { - declaration = declaration.RemoveNode(node, options); + declaration = declaration.RemoveNode(node, options)!; return new UsingDirectiveListInfo(declaration, declaration.Usings); } } @@ -254,7 +254,7 @@ public UsingDirectiveSyntax First() /// /// The first using directive in the list or null if the list is empty. /// - public UsingDirectiveSyntax FirstOrDefault() + public UsingDirectiveSyntax? FirstOrDefault() { return Usings.FirstOrDefault(); } @@ -308,7 +308,7 @@ public UsingDirectiveSyntax Last() /// /// The last using directive in the list or null if the list is empty. /// - public UsingDirectiveSyntax LastOrDefault() + public UsingDirectiveSyntax? LastOrDefault() { return Usings.LastOrDefault(); } diff --git a/src/CSharp/CSharp/Syntax/XmlElementInfo.cs b/src/CSharp/CSharp/Syntax/XmlElementInfo.cs index fe56befef6..dd42432de4 100644 --- a/src/CSharp/CSharp/Syntax/XmlElementInfo.cs +++ b/src/CSharp/CSharp/Syntax/XmlElementInfo.cs @@ -115,7 +115,7 @@ internal static XmlElementInfo Create(XmlNodeSyntax node) { case XmlElementSyntax element: { - string localName = element.StartTag?.Name?.LocalName.ValueText; + string? localName = element.StartTag?.Name?.LocalName.ValueText; if (localName is null) return default; @@ -124,7 +124,7 @@ internal static XmlElementInfo Create(XmlNodeSyntax node) } case XmlEmptyElementSyntax element: { - string localName = element.Name?.LocalName.ValueText; + string? localName = element.Name?.LocalName.ValueText; if (localName is null) return default; diff --git a/src/CSharp/CSharp/SyntaxAccessibility.cs b/src/CSharp/CSharp/SyntaxAccessibility.cs index d5dc6919fc..10415e2da6 100644 --- a/src/CSharp/CSharp/SyntaxAccessibility.cs +++ b/src/CSharp/CSharp/SyntaxAccessibility.cs @@ -345,7 +345,7 @@ public static bool IsPubliclyVisible(MemberDeclarationSyntax declaration) return false; } - SyntaxNode parent = declaration.Parent; + SyntaxNode? parent = declaration.Parent; if (parent is null) return true; @@ -355,7 +355,7 @@ public static bool IsPubliclyVisible(MemberDeclarationSyntax declaration) SyntaxDebug.Assert(parent is MemberDeclarationSyntax, parent); - declaration = parent as MemberDeclarationSyntax; + declaration = (parent as MemberDeclarationSyntax)!; } while (declaration is not null); @@ -382,7 +382,7 @@ public static TNode WithoutExplicitAccessibility(TNode node) where TNode public static TNode WithExplicitAccessibility( TNode node, Accessibility newAccessibility, - IComparer comparer = null) where TNode : SyntaxNode + IComparer? comparer = null) where TNode : SyntaxNode { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -541,7 +541,7 @@ bool CheckProtectedInStaticOrSealedClass(SyntaxNode declaration) .ContainsAny(SyntaxKind.StaticKeyword, SyntaxKind.SealedKeyword) != true; } - bool CheckAccessorAccessibility(AccessorListSyntax accessorList) + bool CheckAccessorAccessibility(AccessorListSyntax? accessorList) { if (accessorList is not null) { diff --git a/src/CSharp/CSharp/SyntaxAccessibility`1.cs b/src/CSharp/CSharp/SyntaxAccessibility`1.cs index 49622825e7..7bff80d4c0 100644 --- a/src/CSharp/CSharp/SyntaxAccessibility`1.cs +++ b/src/CSharp/CSharp/SyntaxAccessibility`1.cs @@ -110,7 +110,7 @@ public override Accessibility GetDefaultAccessibility(AccessorDeclarationSyntax if (declaration is null) throw new ArgumentNullException(nameof(declaration)); - SyntaxNode containingDeclaration = declaration.Parent?.Parent; + SyntaxNode? containingDeclaration = declaration.Parent?.Parent; switch (containingDeclaration?.Kind()) { @@ -134,7 +134,7 @@ public override Accessibility GetAccessibility(AccessorDeclarationSyntax declara Accessibility accessibility = SyntaxAccessibility.GetExplicitAccessibility(declaration.Modifiers); - SyntaxNode containingDeclaration = declaration.Parent?.Parent; + SyntaxNode? containingDeclaration = declaration.Parent?.Parent; if (containingDeclaration is null) return accessibility; diff --git a/src/CSharp/CSharp/SyntaxDebug.cs b/src/CSharp/CSharp/SyntaxDebug.cs index 68e6c0679a..d939fffc20 100644 --- a/src/CSharp/CSharp/SyntaxDebug.cs +++ b/src/CSharp/CSharp/SyntaxDebug.cs @@ -11,7 +11,7 @@ namespace Roslynator.CSharp; internal static class SyntaxDebug { [Conditional("DEBUG")] - internal static void Assert(bool condition, SyntaxNode node) + internal static void Assert(bool condition, SyntaxNode? node) { if (!condition) Fail(node); @@ -32,8 +32,14 @@ internal static void Assert(bool condition, SyntaxTrivia trivia) } [Conditional("DEBUG")] - internal static void Fail(SyntaxNode node) + internal static void Fail(SyntaxNode? node) { + if (node is null) + { + Debug.Fail(""); + return; + } + TextSpan span = node.Span; SyntaxTriviaList leadingTrivia = node.GetLeadingTrivia(); SyntaxTriviaList trailingTrivia = node.GetTrailingTrivia(); @@ -73,7 +79,7 @@ private static void Fail( string text, TextSpan span, SyntaxKind kind, - SyntaxTree syntaxTree) + SyntaxTree? syntaxTree) { int maxLength = 300; int lineCount = 1; @@ -95,20 +101,31 @@ private static void Fail( if (text.Length > maxLength) text = text.Remove(maxLength) + "....." + Environment.NewLine + ""; - FileLinePositionSpan lineSpan = syntaxTree.GetLineSpan(span); - LinePosition startSpan = lineSpan.StartLinePosition; - LinePosition endSpan = lineSpan.EndLinePosition; - - string message = $"Path: {syntaxTree.FilePath}" - + Environment.NewLine - + $"Kind: {kind}" - + Environment.NewLine - + $"Start L: {startSpan.Line + 1} CH: {startSpan.Character + 1}" - + Environment.NewLine - + $"End L: {endSpan.Line + 1} CH: {endSpan.Character + 1}" - + Environment.NewLine - + Environment.NewLine - + text; + string message; + if (syntaxTree is not null) + { + FileLinePositionSpan lineSpan = syntaxTree.GetLineSpan(span); + LinePosition startSpan = lineSpan.StartLinePosition; + LinePosition endSpan = lineSpan.EndLinePosition; + + message = $"Path: {syntaxTree.FilePath}" + + Environment.NewLine + + $"Kind: {kind}" + + Environment.NewLine + + $"Start L: {startSpan.Line + 1} CH: {startSpan.Character + 1}" + + Environment.NewLine + + $"End L: {endSpan.Line + 1} CH: {endSpan.Character + 1}" + + Environment.NewLine + + Environment.NewLine + + text; + } + else + { + message = $"Kind: {kind}" + + Environment.NewLine + + Environment.NewLine + + text; + } Debug.Fail(message); } diff --git a/src/CSharp/CSharp/SyntaxInfo.cs b/src/CSharp/CSharp/SyntaxInfo.cs index 35f3899c92..664b587f2c 100644 --- a/src/CSharp/CSharp/SyntaxInfo.cs +++ b/src/CSharp/CSharp/SyntaxInfo.cs @@ -132,7 +132,7 @@ public static ConditionalExpressionInfo ConditionalExpressionInfo( /// /// public static ConditionalExpressionInfo ConditionalExpressionInfo( - ConditionalExpressionSyntax conditionalExpression, + ConditionalExpressionSyntax? conditionalExpression, bool walkDownParentheses = true, bool allowMissing = false) { @@ -166,7 +166,7 @@ internal static ConditionalStatementInfo ConditionalStatementInfo( /// /// internal static ConditionalStatementInfo ConditionalStatementInfo( - IfStatementSyntax ifStatement, + IfStatementSyntax? ifStatement, bool walkDownParentheses = true, bool allowMissing = false) { diff --git a/src/CSharp/CSharp/SyntaxRefactorings.cs b/src/CSharp/CSharp/SyntaxRefactorings.cs index d7e50ffdfe..1d15b6fba9 100644 --- a/src/CSharp/CSharp/SyntaxRefactorings.cs +++ b/src/CSharp/CSharp/SyntaxRefactorings.cs @@ -122,7 +122,7 @@ private static T AddAttributeLists( return addAttributeLists(node, attributeLists); } - public static TRoot RemoveNode(TRoot root, SyntaxNode node) where TRoot : SyntaxNode + public static TRoot? RemoveNode(TRoot root, SyntaxNode node) where TRoot : SyntaxNode { return root.RemoveNode(node, GetRemoveOptions(node)); } @@ -212,7 +212,7 @@ internal static TNode RemoveSingleLineDocumentationComment(TNode node, Do return node.ReplaceToken(token, newToken); } - return node.RemoveNode(documentationComment, SyntaxRemoveOptions.KeepNoTrivia); + return node.RemoveNode(documentationComment, SyntaxRemoveOptions.KeepNoTrivia)!; } public static TNode RemoveComments(TNode node, CommentFilter comments) where TNode : SyntaxNode @@ -228,7 +228,7 @@ public static TNode RemoveComments(TNode node, TextSpan span, CommentFilt if (node is null) throw new ArgumentNullException(nameof(node)); - List commentsToRemove = null; + List? commentsToRemove = null; foreach (SyntaxTrivia trivia in node.DescendantTrivia(span, descendIntoTrivia: true)) { @@ -397,7 +397,7 @@ public static CompilationUnitSyntax RemoveMember(CompilationUnitSyntax compilati compilationUnit = compilationUnit.WithMembers(compilationUnit.Members.ReplaceAt(index, newMember)); - return compilationUnit.RemoveNode(compilationUnit.Members[index], GetRemoveOptions(newMember)); + return compilationUnit.RemoveNode(compilationUnit.Members[index], GetRemoveOptions(newMember))!; } public static InterfaceDeclarationSyntax RemoveMember(InterfaceDeclarationSyntax interfaceDeclaration, MemberDeclarationSyntax member) @@ -433,7 +433,7 @@ public static BaseNamespaceDeclarationSyntax RemoveMember(BaseNamespaceDeclarati if (namespaceDeclaration.IsKind(SyntaxKind.FileScopedNamespaceDeclaration)) { - return namespaceDeclaration.RemoveNode(namespaceDeclaration.Members[index], GetRemoveOptions(newMember)); + return namespaceDeclaration.RemoveNode(namespaceDeclaration.Members[index], GetRemoveOptions(newMember))!; } else { @@ -500,7 +500,7 @@ private static T RemoveNode( { SyntaxList members = getMembers(declaration); - T newDeclaration = declaration.RemoveNode(members[index], removeOptions); + T newDeclaration = declaration.RemoveNode(members[index], removeOptions)!; if (index == 0 && index < members.Count - 1) @@ -665,7 +665,7 @@ string GetCharacterLiteralText() public static ForStatementSyntax ConvertWhileStatementToForStatement( WhileStatementSyntax whileStatement, - VariableDeclarationSyntax declaration = default, + VariableDeclarationSyntax? declaration = default, SeparatedSyntaxList initializers = default) { var incrementors = default(SeparatedSyntaxList); @@ -726,7 +726,7 @@ public static ForStatementSyntax ConvertWhileStatementToForStatement( } } - ExpressionSyntax condition = whileStatement.Condition; + ExpressionSyntax? condition = whileStatement.Condition; if (condition.IsKind(SyntaxKind.TrueLiteralExpression)) condition = null; diff --git a/src/CSharp/CSharp/SyntaxRewriters/BinaryExpressionToMultiLineRewriter.cs b/src/CSharp/CSharp/SyntaxRewriters/BinaryExpressionToMultiLineRewriter.cs index ccf0760b4e..c47d4d1cb9 100644 --- a/src/CSharp/CSharp/SyntaxRewriters/BinaryExpressionToMultiLineRewriter.cs +++ b/src/CSharp/CSharp/SyntaxRewriters/BinaryExpressionToMultiLineRewriter.cs @@ -10,7 +10,7 @@ internal class BinaryExpressionToMultiLineRewriter : CSharpSyntaxRewriter { private readonly SyntaxTriviaList _leadingTrivia; - private BinaryExpressionSyntax _previous; + private BinaryExpressionSyntax? _previous; public BinaryExpressionToMultiLineRewriter(SyntaxTriviaList leadingTrivia) { @@ -23,12 +23,12 @@ public override SyntaxNode VisitBinaryExpression(BinaryExpressionSyntax node) || (_previous.Equals(node.Parent) && node.IsKind(_previous.Kind()))) { node = node - .WithLeft(node.Left?.TrimTrivia()) + .WithLeft(node.Left.TrimTrivia()) .WithOperatorToken(node.OperatorToken.WithLeadingTrivia(_leadingTrivia)); _previous = node; } - return base.VisitBinaryExpression(node); + return base.VisitBinaryExpression(node)!; } } diff --git a/src/CSharp/CSharp/SyntaxRewriters/RenameRewriter.cs b/src/CSharp/CSharp/SyntaxRewriters/RenameRewriter.cs index 9ad138415e..2eb4421387 100644 --- a/src/CSharp/CSharp/SyntaxRewriters/RenameRewriter.cs +++ b/src/CSharp/CSharp/SyntaxRewriters/RenameRewriter.cs @@ -38,13 +38,13 @@ public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) { if (string.Equals(node.Identifier.ValueText, _name, StringComparison.Ordinal)) { - ISymbol symbol = SemanticModel.GetSymbol(node, CancellationToken); + ISymbol? symbol = SemanticModel.GetSymbol(node, CancellationToken); if (SymbolEqualityComparer.Default.Equals(Symbol, symbol)) return Rename(node); } - return base.VisitIdentifierName(node); + return base.VisitIdentifierName(node)!; } protected virtual SyntaxNode Rename(IdentifierNameSyntax node) diff --git a/src/CSharp/CSharp/SyntaxWalkers/ContainsCommentWalker.cs b/src/CSharp/CSharp/SyntaxWalkers/ContainsCommentWalker.cs index c62031d542..a737671b65 100644 --- a/src/CSharp/CSharp/SyntaxWalkers/ContainsCommentWalker.cs +++ b/src/CSharp/CSharp/SyntaxWalkers/ContainsCommentWalker.cs @@ -10,7 +10,7 @@ namespace Roslynator.CSharp.SyntaxWalkers; internal sealed class ContainsCommentWalker : CSharpSyntaxWalker { [ThreadStatic] - private static ContainsCommentWalker _cachedInstance; + private static ContainsCommentWalker? _cachedInstance; public ContainsCommentWalker(TextSpan span) : base(SyntaxWalkerDepth.Trivia) @@ -59,7 +59,7 @@ public static bool ContainsComment(SyntaxNode node, TextSpan span) public static ContainsCommentWalker GetInstance(TextSpan span) { - ContainsCommentWalker walker = _cachedInstance; + ContainsCommentWalker? walker = _cachedInstance; if (walker is not null) { diff --git a/src/CSharp/CSharp/SyntaxWalkers/ContainsLocalOrParameterReferenceWalker.cs b/src/CSharp/CSharp/SyntaxWalkers/ContainsLocalOrParameterReferenceWalker.cs index 068bd815c2..f08426c737 100644 --- a/src/CSharp/CSharp/SyntaxWalkers/ContainsLocalOrParameterReferenceWalker.cs +++ b/src/CSharp/CSharp/SyntaxWalkers/ContainsLocalOrParameterReferenceWalker.cs @@ -11,7 +11,7 @@ namespace Roslynator.CSharp.SyntaxWalkers; internal sealed class ContainsLocalOrParameterReferenceWalker : LocalOrParameterReferenceWalker { [ThreadStatic] - private static ContainsLocalOrParameterReferenceWalker _cachedInstance; + private static ContainsLocalOrParameterReferenceWalker? _cachedInstance; public ContainsLocalOrParameterReferenceWalker( ISymbol symbol, @@ -25,9 +25,9 @@ public ContainsLocalOrParameterReferenceWalker( public bool Result { get; set; } - public ISymbol Symbol { get; private set; } + public ISymbol? Symbol { get; private set; } - public SemanticModel SemanticModel { get; private set; } + public SemanticModel? SemanticModel { get; private set; } public CancellationToken CancellationToken { get; private set; } @@ -40,8 +40,8 @@ public override void VisitIdentifierName(IdentifierNameSyntax node) { CancellationToken.ThrowIfCancellationRequested(); - if (string.Equals(node.Identifier.ValueText, Symbol.Name, StringComparison.Ordinal) - && SymbolEqualityComparer.Default.Equals(SemanticModel.GetSymbol(node, CancellationToken), Symbol)) + if (string.Equals(node.Identifier.ValueText, Symbol!.Name, StringComparison.Ordinal) + && SymbolEqualityComparer.Default.Equals(SemanticModel!.GetSymbol(node, CancellationToken), Symbol)) { Result = true; } @@ -124,7 +124,7 @@ public static ContainsLocalOrParameterReferenceWalker GetInstance( SemanticModel semanticModel, CancellationToken cancellationToken = default) { - ContainsLocalOrParameterReferenceWalker walker = _cachedInstance; + ContainsLocalOrParameterReferenceWalker? walker = _cachedInstance; if (walker is not null) { diff --git a/src/CSharp/CSharp/SyntaxWalkers/ContainsYieldWalker.cs b/src/CSharp/CSharp/SyntaxWalkers/ContainsYieldWalker.cs index 47f2937685..ca10ee2927 100644 --- a/src/CSharp/CSharp/SyntaxWalkers/ContainsYieldWalker.cs +++ b/src/CSharp/CSharp/SyntaxWalkers/ContainsYieldWalker.cs @@ -10,7 +10,7 @@ namespace Roslynator.CSharp.SyntaxWalkers; internal sealed class ContainsYieldWalker : StatementWalker { [ThreadStatic] - private static ContainsYieldWalker _cachedInstance; + private static ContainsYieldWalker? _cachedInstance; public ContainsYieldWalker( bool searchForYieldBreak = true, @@ -29,7 +29,7 @@ public override bool ShouldVisit public bool SearchForYieldReturn { get; private set; } - public YieldStatementSyntax YieldStatement { get; private set; } + public YieldStatementSyntax? YieldStatement { get; private set; } public static bool ContainsYield(StatementSyntax statement, bool searchForYieldReturn = true, bool searchForYieldBreak = true) { @@ -73,7 +73,7 @@ public override void VisitLocalFunctionStatement(LocalFunctionStatementSyntax no public static ContainsYieldWalker GetInstance() { - ContainsYieldWalker walker = _cachedInstance; + ContainsYieldWalker? walker = _cachedInstance; if (walker is not null) { diff --git a/src/CSharp/CSharp/SyntaxWalkers/MethodReferencedAsMethodGroupWalker.cs b/src/CSharp/CSharp/SyntaxWalkers/MethodReferencedAsMethodGroupWalker.cs index 5c47311930..4cdc70601d 100644 --- a/src/CSharp/CSharp/SyntaxWalkers/MethodReferencedAsMethodGroupWalker.cs +++ b/src/CSharp/CSharp/SyntaxWalkers/MethodReferencedAsMethodGroupWalker.cs @@ -12,13 +12,13 @@ namespace Roslynator.CSharp.SyntaxWalkers; internal class MethodReferencedAsMethodGroupWalker : CSharpSyntaxNodeWalker { [ThreadStatic] - private static MethodReferencedAsMethodGroupWalker _cachedInstance; + private static MethodReferencedAsMethodGroupWalker? _cachedInstance; public bool Result { get; set; } - public IMethodSymbol Symbol { get; set; } + public IMethodSymbol? Symbol { get; set; } - public SemanticModel SemanticModel { get; set; } + public SemanticModel? SemanticModel { get; set; } public CancellationToken CancellationToken { get; set; } @@ -28,16 +28,16 @@ public override void VisitIdentifierName(IdentifierNameSyntax node) { CancellationToken.ThrowIfCancellationRequested(); - if (string.Equals(Symbol.Name, node.Identifier.ValueText, StringComparison.Ordinal) + if (string.Equals(Symbol!.Name, node.Identifier.ValueText, StringComparison.Ordinal) && !IsInvoked(node) - && SymbolEqualityComparer.Default.Equals(SemanticModel.GetSymbol(node, CancellationToken), Symbol)) + && SymbolEqualityComparer.Default.Equals(SemanticModel!.GetSymbol(node, CancellationToken), Symbol)) { Result = true; } static bool IsInvoked(IdentifierNameSyntax identifierName) { - SyntaxNode parent = identifierName.Parent; + SyntaxNode parent = identifierName.Parent!; switch (parent.Kind()) { @@ -65,7 +65,7 @@ public static bool IsReferencedAsMethodGroup( SemanticModel semanticModel, CancellationToken cancellationToken = default) { - var typeDeclaration = (TypeDeclarationSyntax)methodDeclaration.Parent; + var typeDeclaration = (TypeDeclarationSyntax)methodDeclaration.Parent!; return IsReferencedAsMethodGroup(typeDeclaration, methodSymbol, semanticModel, cancellationToken); } @@ -76,7 +76,7 @@ public static bool IsReferencedAsMethodGroup( SemanticModel semanticModel, CancellationToken cancellationToken = default) { - MemberDeclarationSyntax memberDeclaration = localFunction.FirstAncestor(); + MemberDeclarationSyntax? memberDeclaration = localFunction.FirstAncestor()!; return IsReferencedAsMethodGroup(memberDeclaration, methodSymbol, semanticModel, cancellationToken); } @@ -89,7 +89,7 @@ public static bool IsReferencedAsMethodGroup( { var result = false; - MethodReferencedAsMethodGroupWalker walker = null; + MethodReferencedAsMethodGroupWalker? walker = null; try { @@ -114,7 +114,7 @@ public static bool IsReferencedAsMethodGroup( private static MethodReferencedAsMethodGroupWalker GetInstance() { - MethodReferencedAsMethodGroupWalker walker = _cachedInstance; + MethodReferencedAsMethodGroupWalker? walker = _cachedInstance; if (walker is not null) { diff --git a/src/CSharp/CSharp/SyntaxWalkers/StatementWalker.cs b/src/CSharp/CSharp/SyntaxWalkers/StatementWalker.cs index 07f48d4404..a6f52e21f2 100644 --- a/src/CSharp/CSharp/SyntaxWalkers/StatementWalker.cs +++ b/src/CSharp/CSharp/SyntaxWalkers/StatementWalker.cs @@ -136,7 +136,7 @@ public override void VisitTryStatement(TryStatementSyntax node) foreach (CatchClauseSyntax catchClause in node.Catches) VisitBlockIfNotNull(catchClause.Block); - FinallyClauseSyntax finallyClause = node.Finally; + FinallyClauseSyntax? finallyClause = node.Finally; if (finallyClause is not null) VisitBlockIfNotNull(finallyClause.Block); @@ -161,7 +161,7 @@ public override void VisitYieldStatement(YieldStatementSyntax node) { } - private void VisitBlockIfNotNull(BlockSyntax node) + private void VisitBlockIfNotNull(BlockSyntax? node) { if (node is not null && ShouldVisit) @@ -170,7 +170,7 @@ private void VisitBlockIfNotNull(BlockSyntax node) } } - private void VisitStatementIfNotNull(StatementSyntax node) + private void VisitStatementIfNotNull(StatementSyntax? node) { if (node is not null && ShouldVisit) diff --git a/src/CSharp/CSharp/SyntaxWalkers/TriviaWalker.cs b/src/CSharp/CSharp/SyntaxWalkers/TriviaWalker.cs index b8b8bd3940..40932c1b48 100644 --- a/src/CSharp/CSharp/SyntaxWalkers/TriviaWalker.cs +++ b/src/CSharp/CSharp/SyntaxWalkers/TriviaWalker.cs @@ -29,10 +29,13 @@ public static bool ContainsOnlyWhitespaceOrEndOfLineTrivia(SyntaxNode node, Text return result; } - public override void Visit(SyntaxNode node) + public override void Visit(SyntaxNode? node) { - if (IsInSpan(node.FullSpan)) + if (node is not null + && IsInSpan(node.FullSpan)) + { base.Visit(node); + } } private bool IsInSpan(TextSpan span) @@ -80,7 +83,7 @@ public override void VisitTrivia(SyntaxTrivia trivia) private sealed class ContainsOnlyWhitespaceOrEndOfLineTriviaWalker : TriviaWalker { [ThreadStatic] - private static ContainsOnlyWhitespaceOrEndOfLineTriviaWalker _cachedInstance; + private static ContainsOnlyWhitespaceOrEndOfLineTriviaWalker? _cachedInstance; public bool Result { get; private set; } = true; @@ -88,7 +91,7 @@ public ContainsOnlyWhitespaceOrEndOfLineTriviaWalker(TextSpan span) : base(span) { } - public override void Visit(SyntaxNode node) + public override void Visit(SyntaxNode? node) { if (Result) base.Visit(node); @@ -102,7 +105,7 @@ protected override void VisitTriviaCore(SyntaxTrivia trivia) public static ContainsOnlyWhitespaceOrEndOfLineTriviaWalker GetInstance(TextSpan span) { - ContainsOnlyWhitespaceOrEndOfLineTriviaWalker walker = _cachedInstance; + ContainsOnlyWhitespaceOrEndOfLineTriviaWalker? walker = _cachedInstance; if (walker is not null) { diff --git a/src/CSharp/DetermineParameterHelper.cs b/src/CSharp/DetermineParameterHelper.cs index 5bde01cb14..b44ad55f89 100644 --- a/src/CSharp/DetermineParameterHelper.cs +++ b/src/CSharp/DetermineParameterHelper.cs @@ -12,7 +12,7 @@ namespace Roslynator.CSharp; internal static class DetermineParameterHelper { - public static IParameterSymbol DetermineParameter( + public static IParameterSymbol? DetermineParameter( ArgumentSyntax argument, SemanticModel semanticModel, bool allowParams = false, @@ -25,7 +25,7 @@ public static IParameterSymbol DetermineParameter( if (argumentList.Parent is null) return null; - ISymbol symbol = GetSymbol(argumentList.Parent, allowCandidate, semanticModel, cancellationToken); + ISymbol? symbol = GetSymbol(argumentList.Parent, allowCandidate, semanticModel, cancellationToken); if (symbol is null) return null; @@ -40,13 +40,13 @@ public static IParameterSymbol DetermineParameter( return DetermineParameter(argument, argumentList.Arguments, parameters, allowParams); } - internal static IParameterSymbol DetermineParameter( + internal static IParameterSymbol? DetermineParameter( ArgumentSyntax argument, SeparatedSyntaxList arguments, ImmutableArray parameters, bool allowParams = false) { - string name = argument.NameColon?.Name?.Identifier.ValueText; + string? name = argument.NameColon?.Name?.Identifier.ValueText; if (name is not null) { @@ -68,7 +68,7 @@ internal static IParameterSymbol DetermineParameter( if (allowParams) { - IParameterSymbol lastParameter = parameters.LastOrDefault(); + IParameterSymbol? lastParameter = parameters.LastOrDefault(); if (lastParameter?.IsParams == true) return lastParameter; @@ -78,7 +78,7 @@ internal static IParameterSymbol DetermineParameter( return null; } - public static IParameterSymbol DetermineParameter( + public static IParameterSymbol? DetermineParameter( AttributeArgumentSyntax attributeArgument, SemanticModel semanticModel, bool allowParams = false, @@ -88,7 +88,7 @@ public static IParameterSymbol DetermineParameter( if (attributeArgument.NameEquals is not null) return null; - SyntaxNode parent = attributeArgument.Parent; + SyntaxNode? parent = attributeArgument.Parent; if (parent is not AttributeArgumentListSyntax argumentList) return null; @@ -96,7 +96,7 @@ public static IParameterSymbol DetermineParameter( if (argumentList.Parent is not AttributeSyntax attribute) return null; - ISymbol symbol = GetSymbol(attribute, allowCandidate, semanticModel, cancellationToken); + ISymbol? symbol = GetSymbol(attribute, allowCandidate, semanticModel, cancellationToken); if (symbol is null) return null; @@ -111,13 +111,13 @@ public static IParameterSymbol DetermineParameter( return DetermineParameter(attributeArgument, argumentList.Arguments, parameters, allowParams); } - internal static IParameterSymbol DetermineParameter( + internal static IParameterSymbol? DetermineParameter( AttributeArgumentSyntax attributeArgument, SeparatedSyntaxList arguments, ImmutableArray parameters, bool allowParams = false) { - string name = attributeArgument.NameColon?.Name?.Identifier.ValueText; + string? name = attributeArgument.NameColon?.Name?.Identifier.ValueText; if (name is not null) { @@ -139,7 +139,7 @@ internal static IParameterSymbol DetermineParameter( if (allowParams) { - IParameterSymbol lastParameter = parameters.LastOrDefault(); + IParameterSymbol? lastParameter = parameters.LastOrDefault(); if (lastParameter?.IsParams == true) return lastParameter; @@ -149,11 +149,11 @@ internal static IParameterSymbol DetermineParameter( return null; } - private static ISymbol GetSymbol(SyntaxNode node, bool allowCandidate, SemanticModel semanticModel, CancellationToken cancellationToken) + private static ISymbol? GetSymbol(SyntaxNode node, bool allowCandidate, SemanticModel semanticModel, CancellationToken cancellationToken) { SymbolInfo symbolInfo = GetSymbolInfo(node, semanticModel, cancellationToken); - ISymbol symbol = symbolInfo.Symbol; + ISymbol? symbol = symbolInfo.Symbol; if (symbol is null && allowCandidate) diff --git a/src/CSharp/DetermineParameterTypeHelper.cs b/src/CSharp/DetermineParameterTypeHelper.cs index 7f017202c5..85ed539cf6 100644 --- a/src/CSharp/DetermineParameterTypeHelper.cs +++ b/src/CSharp/DetermineParameterTypeHelper.cs @@ -20,28 +20,28 @@ public static ImmutableArray DetermineParameterTypes( { if (argument.Parent is BaseArgumentListSyntax argumentList) { - SyntaxNode parent = argumentList.Parent; + SyntaxNode? parent = argumentList.Parent; if (parent is not null) { SymbolInfo symbolInfo = GetSymbolInfo(parent, semanticModel, cancellationToken); - ISymbol symbol = symbolInfo.Symbol; + ISymbol? symbol = symbolInfo.Symbol; if (symbol is not null) { - ITypeSymbol typeSymbol = DetermineParameterType(symbol, argument, argumentList); + ITypeSymbol? typeSymbol = DetermineParameterType(symbol, argument, argumentList); if (typeSymbol?.IsErrorType() == false) return ImmutableArray.Create(typeSymbol); } else { - HashSet typeSymbols = null; + HashSet? typeSymbols = null; foreach (ISymbol candidateSymbol in symbolInfo.CandidateSymbols) { - ITypeSymbol typeSymbol = DetermineParameterType(candidateSymbol, argument, argumentList); + ITypeSymbol? typeSymbol = DetermineParameterType(candidateSymbol, argument, argumentList); if (typeSymbol?.IsErrorType() == false) { @@ -69,12 +69,12 @@ private static SymbolInfo GetSymbolInfo(SyntaxNode node, SemanticModel semanticM return default; } - private static ITypeSymbol DetermineParameterType( + private static ITypeSymbol? DetermineParameterType( ISymbol symbol, ArgumentSyntax argument, BaseArgumentListSyntax argumentList) { - IParameterSymbol parameterSymbol = DetermineParameterSymbol(symbol, argument, argumentList); + IParameterSymbol? parameterSymbol = DetermineParameterSymbol(symbol, argument, argumentList); if (parameterSymbol is null) return null; @@ -103,7 +103,7 @@ private static ITypeSymbol DetermineParameterType( return typeSymbol; } - private static IParameterSymbol DetermineParameterSymbol( + private static IParameterSymbol? DetermineParameterSymbol( ISymbol symbol, ArgumentSyntax argument, BaseArgumentListSyntax argumentList) @@ -115,7 +115,7 @@ private static IParameterSymbol DetermineParameterSymbol( if (parameters.IsDefault) return null; - string name = argument.NameColon?.Name?.Identifier.ValueText; + string? name = argument.NameColon?.Name?.Identifier.ValueText; if (name is not null) return parameters.FirstOrDefault(f => f.Name == name); @@ -128,7 +128,7 @@ private static IParameterSymbol DetermineParameterSymbol( return parameters[index]; } - IParameterSymbol lastParameter = parameters.LastOrDefault(); + IParameterSymbol? lastParameter = parameters.LastOrDefault(); if (lastParameter?.IsParams == true) return lastParameter; diff --git a/src/CommandLine/Commands/FindSymbolsCommand.cs b/src/CommandLine/Commands/FindSymbolsCommand.cs index 68960808e8..3579e352a5 100644 --- a/src/CommandLine/Commands/FindSymbolsCommand.cs +++ b/src/CommandLine/Commands/FindSymbolsCommand.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Roslynator.FindSymbols; +using Roslynator.Host.Mef; using static Roslynator.Logger; namespace Roslynator.CommandLine; @@ -161,6 +162,18 @@ private static Task> AnalyzeProject( IFindSymbolsProgress progress, CancellationToken cancellationToken) { + if (!project.SupportsCompilation) + { + WriteLine(" Project does not support compilation", Verbosity.Normal); + return Task.FromResult(ImmutableArray.Empty); + } + + if (!MefWorkspaceServices.Default.SupportedLanguages.Contains(project.Language)) + { + WriteLine($" Language '{project.Language}' is not supported", Verbosity.Normal); + return Task.FromResult(ImmutableArray.Empty); + } + return SymbolFinder.FindSymbolsAsync(project, options, progress, cancellationToken); } diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index 7c5fccc521..3a63456453 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -8,6 +8,7 @@ $(RoslynatorCoreVersion) $(RoslynatorDllPrefix)Roslynator.Core Roslynator + enable diff --git a/src/Core/CreateNameFromTypeSymbolHelper.cs b/src/Core/CreateNameFromTypeSymbolHelper.cs index 56f3dce90d..c2bf6f99a7 100644 --- a/src/Core/CreateNameFromTypeSymbolHelper.cs +++ b/src/Core/CreateNameFromTypeSymbolHelper.cs @@ -9,7 +9,7 @@ namespace Roslynator; internal static class CreateNameFromTypeSymbolHelper { - public static string CreateName(ITypeSymbol typeSymbol) + public static string? CreateName(ITypeSymbol typeSymbol) { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -21,19 +21,19 @@ public static string CreateName(ITypeSymbol typeSymbol) ITypeSymbol typeSymbol3 = ExtractFromArrayOrGenericCollection(typeSymbol2); - string name = GetName(typeSymbol3); + string? name = GetName(typeSymbol3); if (string.IsNullOrEmpty(name)) return null; if (typeSymbol3.TypeKind == TypeKind.Interface - && name.Length > 1 + && name!.Length > 1 && name[0] == 'I') { name = name.Substring(1); } - if (name.Length >= 8 + if (name!.Length >= 8 && name.EndsWith("Syntax", StringComparison.Ordinal) && typeSymbol.EqualsOrInheritsFrom(MetadataNames.Microsoft_CodeAnalysis_SyntaxNode)) { @@ -145,7 +145,7 @@ private static bool UsePlural(ITypeSymbol typeSymbol) return false; } - private static string GetName(ITypeSymbol typeSymbol) + private static string? GetName(ITypeSymbol typeSymbol) { if (typeSymbol.Kind == SymbolKind.TypeParameter) { diff --git a/src/Core/DiagnosticIdComparer.cs b/src/Core/DiagnosticIdComparer.cs index 49fa373f0d..4be29324cb 100644 --- a/src/Core/DiagnosticIdComparer.cs +++ b/src/Core/DiagnosticIdComparer.cs @@ -10,13 +10,13 @@ internal abstract class DiagnosticIdComparer : IComparer, IEqualityCompa { public static DiagnosticIdComparer Prefix { get; } = new DiagnosticIdPrefixComparer(); - public abstract int Compare(string x, string y); + public abstract int Compare(string? x, string? y); - public abstract bool Equals(string x, string y); + public abstract bool Equals(string? x, string? y); - public abstract int GetHashCode(string obj); + public abstract int GetHashCode(string? obj); - public int Compare(object x, object y) + public int Compare(object? x, object? y) { if (x == y) return 0; @@ -36,7 +36,7 @@ public int Compare(object x, object y) throw new ArgumentException("", nameof(x)); } - new public bool Equals(object x, object y) + new public bool Equals(object? x, object? y) { if (x == y) return true; @@ -56,7 +56,7 @@ public int Compare(object x, object y) throw new ArgumentException("", nameof(x)); } - public int GetHashCode(object obj) + public int GetHashCode(object? obj) { if (obj is null) return 0; @@ -69,7 +69,7 @@ public int GetHashCode(object obj) private class DiagnosticIdPrefixComparer : DiagnosticIdComparer { - public override int Compare(string x, string y) + public override int Compare(string? x, string? y) { if (object.ReferenceEquals(x, y)) return 0; @@ -96,7 +96,7 @@ public override int Compare(string x, string y) return length1.CompareTo(length2); } - public override bool Equals(string x, string y) + public override bool Equals(string? x, string? y) { if (object.ReferenceEquals(x, y)) return true; @@ -114,10 +114,10 @@ public override bool Equals(string x, string y) && string.Compare(x, 0, y, 0, length1, StringComparison.Ordinal) == 0; } - public override int GetHashCode(string obj) + public override int GetHashCode(string? obj) { if (obj is null) - throw new ArgumentNullException(nameof(obj)); + return 0; int length = DiagnosticIdPrefix.GetPrefixLength(obj); diff --git a/src/Core/Documentation/DocumentationCommentGeneratorSettings.cs b/src/Core/Documentation/DocumentationCommentGeneratorSettings.cs index 5340745b9b..bf89bd29b0 100644 --- a/src/Core/Documentation/DocumentationCommentGeneratorSettings.cs +++ b/src/Core/Documentation/DocumentationCommentGeneratorSettings.cs @@ -8,9 +8,9 @@ namespace Roslynator.Documentation; internal class DocumentationCommentGeneratorSettings { public DocumentationCommentGeneratorSettings( - IEnumerable summary = null, - IEnumerable ignoredTags = null, - string indentation = null, + IEnumerable? summary = null, + IEnumerable? ignoredTags = null, + string? indentation = null, bool singleLineSummary = false) { Summary = (summary is not null) ? ImmutableArray.CreateRange(summary) : ImmutableArray.Empty; diff --git a/src/Core/EnumFieldSymbolInfo.cs b/src/Core/EnumFieldSymbolInfo.cs index 918a442980..fd376a1dd3 100644 --- a/src/Core/EnumFieldSymbolInfo.cs +++ b/src/Core/EnumFieldSymbolInfo.cs @@ -20,7 +20,7 @@ public EnumFieldSymbolInfo(IFieldSymbol symbol, ulong value) public bool HasValue => Symbol?.HasConstantValue == true; - public string Name => Symbol?.Name; + public string? Name => Symbol?.Name; public static EnumFieldSymbolInfo Create(IFieldSymbol fieldSymbol) { diff --git a/src/Core/EnumSymbolInfo.cs b/src/Core/EnumSymbolInfo.cs index bf236b377b..8c7c582089 100644 --- a/src/Core/EnumSymbolInfo.cs +++ b/src/Core/EnumSymbolInfo.cs @@ -15,7 +15,7 @@ private EnumSymbolInfo(ImmutableArray fields) Fields = fields; } - public INamedTypeSymbol Symbol => (!Fields.IsDefault) ? Fields.FirstOrDefault().Symbol?.ContainingType : default; + public INamedTypeSymbol? Symbol => (!Fields.IsDefault) ? Fields.FirstOrDefault().Symbol?.ContainingType : default; public ImmutableArray Fields { get; } @@ -35,14 +35,14 @@ public bool Contains(ulong value) return false; } - public List Decompose(in EnumFieldSymbolInfo fieldInfo) + public List? Decompose(in EnumFieldSymbolInfo fieldInfo) { return Decompose(fieldInfo.Value); } - public List Decompose(ulong value) + public List? Decompose(ulong value) { - List values = null; + List? values = null; int i = Fields.Length - 1; diff --git a/src/Core/EnumUtility.cs b/src/Core/EnumUtility.cs index a4ff8ebccb..44dc433d8c 100644 --- a/src/Core/EnumUtility.cs +++ b/src/Core/EnumUtility.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Immutable; using System.Diagnostics; using Microsoft.CodeAnalysis; @@ -27,7 +28,7 @@ public static OneOrMany GetConstituentFields(ulong value, i { ImmutableArray fields = enumInfo.Fields; - ImmutableArray.Builder builder = null; + ImmutableArray.Builder? builder = null; ulong result = value; @@ -71,7 +72,10 @@ public static ImmutableArray GetMinimalConstituentFields(IF if (!fieldSymbol.HasConstantValue) return ImmutableArray.Empty; - ulong value = SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumInfo.Symbol); + if (enumInfo.IsDefault) + throw new ArgumentException($"'{nameof(enumInfo)}' is not initialized.", nameof(enumInfo)); + + ulong value = SymbolUtility.GetEnumValueAsUInt64(fieldSymbol.ConstantValue, enumInfo.Symbol!); return GetMinimalConstituentFields(value, enumInfo); } @@ -83,7 +87,7 @@ public static ImmutableArray GetMinimalConstituentFields(ul ImmutableArray fields = enumInfo.Fields; - ImmutableArray.Builder builder = null; + ImmutableArray.Builder? builder = null; ulong result = value; diff --git a/src/Core/ExtensionMethodSymbolInfo.cs b/src/Core/ExtensionMethodSymbolInfo.cs index 3cb004d9a1..54b4800ecd 100644 --- a/src/Core/ExtensionMethodSymbolInfo.cs +++ b/src/Core/ExtensionMethodSymbolInfo.cs @@ -13,7 +13,7 @@ namespace Roslynator; [DebuggerDisplay("{DebuggerDisplay,nq}")] public readonly struct ExtensionMethodSymbolInfo : IEquatable { - internal ExtensionMethodSymbolInfo(IMethodSymbol symbol, IMethodSymbol reducedSymbol) + internal ExtensionMethodSymbolInfo(IMethodSymbol symbol, IMethodSymbol? reducedSymbol) { Symbol = symbol; ReducedSymbol = reducedSymbol; @@ -22,7 +22,7 @@ internal ExtensionMethodSymbolInfo(IMethodSymbol symbol, IMethodSymbol reducedSy /// /// The definition of extension method from which this symbol was reduced, or null, if the symbol was not reduced. /// - public IMethodSymbol ReducedSymbol { get; } + public IMethodSymbol? ReducedSymbol { get; } /// /// The extension method symbol. diff --git a/src/Core/Extensions/DiagnosticsExtensions.cs b/src/Core/Extensions/DiagnosticsExtensions.cs index 2b138504d0..217fd57d9b 100644 --- a/src/Core/Extensions/DiagnosticsExtensions.cs +++ b/src/Core/Extensions/DiagnosticsExtensions.cs @@ -26,7 +26,7 @@ public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxNode node, - params object[] messageArgs) + params object?[]? messageArgs) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -49,7 +49,7 @@ public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxToken token, - params object[] messageArgs) + params object?[]? messageArgs) { ReportDiagnostic( context: context, @@ -69,7 +69,7 @@ public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxTrivia trivia, - params object[] messageArgs) + params object?[]? messageArgs) { ReportDiagnostic( context: context, @@ -88,8 +88,8 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, - params object[] messageArgs) + Location? location, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -108,9 +108,9 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, + Location? location, IEnumerable additionalLocations, - params object[] messageArgs) + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -130,9 +130,9 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, - ImmutableDictionary properties, - params object[] messageArgs) + Location? location, + ImmutableDictionary? properties, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -153,10 +153,10 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SymbolAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, + Location? location, IEnumerable additionalLocations, - ImmutableDictionary properties, - params object[] messageArgs) + ImmutableDictionary? properties, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -179,7 +179,7 @@ public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxNode node, - params object[] messageArgs) + params object?[]? messageArgs) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -202,7 +202,7 @@ public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxToken token, - params object[] messageArgs) + params object?[]? messageArgs) { ReportDiagnostic( context: context, @@ -222,7 +222,7 @@ public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxTrivia trivia, - params object[] messageArgs) + params object?[]? messageArgs) { ReportDiagnostic( context: context, @@ -241,8 +241,8 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, - params object[] messageArgs) + Location? location, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -261,9 +261,9 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, + Location? location, IEnumerable additionalLocations, - params object[] messageArgs) + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -283,9 +283,9 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, - ImmutableDictionary properties, - params object[] messageArgs) + Location? location, + ImmutableDictionary? properties, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -306,10 +306,10 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, + Location? location, IEnumerable additionalLocations, - ImmutableDictionary properties, - params object[] messageArgs) + ImmutableDictionary? properties, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -332,7 +332,7 @@ public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxNode node, - params object[] messageArgs) + params object?[]? messageArgs) { if (node is null) throw new ArgumentNullException(nameof(node)); @@ -355,7 +355,7 @@ public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxToken token, - params object[] messageArgs) + params object?[]? messageArgs) { ReportDiagnostic( context: context, @@ -375,7 +375,7 @@ public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, SyntaxTrivia trivia, - params object[] messageArgs) + params object?[]? messageArgs) { ReportDiagnostic( context: context, @@ -394,8 +394,8 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, - params object[] messageArgs) + Location? location, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -414,9 +414,9 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, + Location? location, IEnumerable additionalLocations, - params object[] messageArgs) + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -436,9 +436,9 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, - ImmutableDictionary properties, - params object[] messageArgs) + Location? location, + ImmutableDictionary? properties, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -459,10 +459,10 @@ public static void ReportDiagnostic( public static void ReportDiagnostic( this SyntaxTreeAnalysisContext context, DiagnosticDescriptor descriptor, - Location location, + Location? location, IEnumerable additionalLocations, - ImmutableDictionary properties, - params object[] messageArgs) + ImmutableDictionary? properties, + params object?[]? messageArgs) { context.ReportDiagnostic(Diagnostic.Create( descriptor: descriptor, @@ -531,7 +531,7 @@ internal static bool IsEffective(this DiagnosticDescriptor descriptor, SymbolAna { return IsEffective( descriptor, - context.Symbol.Locations[0].SourceTree, + context.Symbol.Locations[0].SourceTree!, context.Compilation.Options, context.CancellationToken); } @@ -551,7 +551,7 @@ internal static bool IsEffective( CompilationOptions compilationOptions, CancellationToken cancellationToken = default) { - SyntaxTreeOptionsProvider provider = compilationOptions.SyntaxTreeOptionsProvider; + SyntaxTreeOptionsProvider? provider = compilationOptions.SyntaxTreeOptionsProvider; if (provider?.TryGetDiagnosticValue(syntaxTree, descriptor.Id, cancellationToken, out ReportDiagnostic reportDiagnostic) != true && !compilationOptions.SpecificDiagnosticOptions.TryGetValue(descriptor.Id, out reportDiagnostic)) @@ -569,20 +569,26 @@ internal static bool IsEffective( internal static ReportDiagnostic GetEffectiveSeverity( this DiagnosticDescriptor descriptor, - SyntaxTree syntaxTree, - CompilationOptions compilationOptions, + SyntaxTree? syntaxTree, + CompilationOptions? compilationOptions, CancellationToken cancellationToken = default) { - SyntaxTreeOptionsProvider provider = compilationOptions.SyntaxTreeOptionsProvider; + if (compilationOptions is not null) + { + SyntaxTreeOptionsProvider? provider = compilationOptions.SyntaxTreeOptionsProvider; - if (provider?.TryGetDiagnosticValue(syntaxTree, descriptor.Id, cancellationToken, out ReportDiagnostic treeReportDiagnostic) == true) - return treeReportDiagnostic; + if (syntaxTree is not null + && provider?.TryGetDiagnosticValue(syntaxTree, descriptor.Id, cancellationToken, out ReportDiagnostic treeReportDiagnostic) == true) + { + return treeReportDiagnostic; + } - if (compilationOptions.SpecificDiagnosticOptions.TryGetValue(descriptor.Id, out ReportDiagnostic reportDiagnostic)) - return reportDiagnostic; + if (compilationOptions.SpecificDiagnosticOptions.TryGetValue(descriptor.Id, out ReportDiagnostic reportDiagnostic)) + return reportDiagnostic; - if (provider?.TryGetGlobalDiagnosticValue(descriptor.Id, cancellationToken, out ReportDiagnostic globalReportDiagnostic) == true) - return globalReportDiagnostic; + if (provider?.TryGetGlobalDiagnosticValue(descriptor.Id, cancellationToken, out ReportDiagnostic globalReportDiagnostic) == true) + return globalReportDiagnostic; + } return (descriptor.IsEnabledByDefault) ? descriptor.DefaultSeverity.ToReportDiagnostic() diff --git a/src/Core/Extensions/ListExtensions.cs b/src/Core/Extensions/ListExtensions.cs index cd7fec36eb..ef3f85a133 100644 --- a/src/Core/Extensions/ListExtensions.cs +++ b/src/Core/Extensions/ListExtensions.cs @@ -8,7 +8,7 @@ namespace Roslynator; internal static class ListExtensions { - public static T SingleOrDefault(this IReadOnlyList list, bool shouldThrow) + public static T? SingleOrDefault(this IReadOnlyList list, bool shouldThrow) { if (list is null) throw new ArgumentNullException(nameof(list)); @@ -23,7 +23,7 @@ public static T SingleOrDefault(this IReadOnlyList list, bool shouldThrow) } } - public static T SingleOrDefault(this IReadOnlyList list, Func predicate, bool shouldThrow) + public static T? SingleOrDefault(this IReadOnlyList list, Func predicate, bool shouldThrow) { if (list is null) throw new ArgumentNullException(nameof(list)); diff --git a/src/Core/Extensions/SemanticModelExtensions.cs b/src/Core/Extensions/SemanticModelExtensions.cs index 5bf4f013ce..c5aabc686a 100644 --- a/src/Core/Extensions/SemanticModelExtensions.cs +++ b/src/Core/Extensions/SemanticModelExtensions.cs @@ -14,7 +14,7 @@ namespace Roslynator; /// public static class SemanticModelExtensions { - internal static Diagnostic GetDiagnostic( + internal static Diagnostic? GetDiagnostic( this SemanticModel semanticModel, string id, TextSpan? span = null, @@ -40,7 +40,7 @@ internal static Diagnostic GetDiagnostic( /// /// /// - public static INamedTypeSymbol GetEnclosingNamedType( + public static INamedTypeSymbol? GetEnclosingNamedType( this SemanticModel semanticModel, int position, CancellationToken cancellationToken = default) @@ -55,7 +55,7 @@ public static INamedTypeSymbol GetEnclosingNamedType( /// /// /// - public static TSymbol GetEnclosingSymbol( + public static TSymbol? GetEnclosingSymbol( this SemanticModel semanticModel, int position, CancellationToken cancellationToken = default) where TSymbol : ISymbol @@ -63,7 +63,7 @@ public static TSymbol GetEnclosingSymbol( if (semanticModel is null) throw new ArgumentNullException(nameof(semanticModel)); - ISymbol symbol = semanticModel.GetEnclosingSymbol(position, cancellationToken); + ISymbol? symbol = semanticModel.GetEnclosingSymbol(position, cancellationToken); while (symbol is not null) { @@ -82,7 +82,7 @@ public static TSymbol GetEnclosingSymbol( /// /// /// - public static ISymbol GetSymbol( + public static ISymbol? GetSymbol( this SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken = default) @@ -96,7 +96,7 @@ public static ISymbol GetSymbol( /// /// /// - public static ITypeSymbol GetTypeSymbol( + public static ITypeSymbol? GetTypeSymbol( this SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken = default) @@ -109,7 +109,7 @@ public static ITypeSymbol GetTypeSymbol( /// /// /// - public static INamedTypeSymbol GetTypeByMetadataName(this SemanticModel semanticModel, string fullyQualifiedMetadataName) + public static INamedTypeSymbol? GetTypeByMetadataName(this SemanticModel semanticModel, string fullyQualifiedMetadataName) { if (semanticModel is null) throw new ArgumentNullException(nameof(semanticModel)); @@ -119,7 +119,7 @@ public static INamedTypeSymbol GetTypeByMetadataName(this SemanticModel semantic .GetTypeByMetadataName(fullyQualifiedMetadataName); } - internal static IMethodSymbol GetSpeculativeMethodSymbol( + internal static IMethodSymbol? GetSpeculativeMethodSymbol( this SemanticModel semanticModel, int position, SyntaxNode expression) @@ -139,7 +139,7 @@ internal static ImmutableArray GetSymbolsDeclaredInEnclosingSymbol( bool excludeAnonymousTypeProperty = false, CancellationToken cancellationToken = default) { - SyntaxNode node = GetEnclosingSymbolSyntax(semanticModel, position, cancellationToken); + SyntaxNode? node = GetEnclosingSymbolSyntax(semanticModel, position, cancellationToken); if (node is not null) return GetDeclaredSymbols(semanticModel, node, excludeAnonymousTypeProperty, cancellationToken); @@ -147,29 +147,32 @@ internal static ImmutableArray GetSymbolsDeclaredInEnclosingSymbol( return ImmutableArray.Empty; } - internal static SyntaxNode GetEnclosingSymbolSyntax( + internal static SyntaxNode? GetEnclosingSymbolSyntax( this SemanticModel semanticModel, int position, CancellationToken cancellationToken = default) { - ISymbol enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken); + ISymbol? enclosingSymbol = semanticModel.GetEnclosingSymbol(position, cancellationToken); - ImmutableArray syntaxReferences = enclosingSymbol.DeclaringSyntaxReferences; - - if (syntaxReferences.Length == 1) - { - return syntaxReferences[0].GetSyntax(cancellationToken); - } - else + if (enclosingSymbol is not null) { - foreach (SyntaxReference syntaxReference in syntaxReferences) - { - SyntaxNode node = syntaxReference.GetSyntax(cancellationToken); + ImmutableArray syntaxReferences = enclosingSymbol.DeclaringSyntaxReferences; - if (node.SyntaxTree == semanticModel.SyntaxTree - && node.FullSpan.Contains(position)) + if (syntaxReferences.Length == 1) + { + return syntaxReferences[0].GetSyntax(cancellationToken); + } + else + { + foreach (SyntaxReference syntaxReference in syntaxReferences) { - return node; + SyntaxNode node = syntaxReference.GetSyntax(cancellationToken); + + if (node.SyntaxTree == semanticModel.SyntaxTree + && node.FullSpan.Contains(position)) + { + return node; + } } } } @@ -183,11 +186,11 @@ internal static ImmutableArray GetDeclaredSymbols( bool excludeAnonymousTypeProperty = false, CancellationToken cancellationToken = default) { - HashSet symbols = null; + HashSet? symbols = null; foreach (SyntaxNode node in container.DescendantNodesAndSelf()) { - ISymbol symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken); + ISymbol? symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken); if (symbol is not null) { diff --git a/src/Core/Extensions/SymbolExtensions.cs b/src/Core/Extensions/SymbolExtensions.cs index 2a20dcb5a1..fafcacf682 100644 --- a/src/Core/Extensions/SymbolExtensions.cs +++ b/src/Core/Extensions/SymbolExtensions.cs @@ -49,7 +49,7 @@ IEnumerable Iterator() } } - internal static ISymbol FindFirstImplementedInterfaceMember(this ISymbol symbol, bool allInterfaces = false) + internal static ISymbol? FindFirstImplementedInterfaceMember(this ISymbol symbol, bool allInterfaces = false) { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); @@ -57,7 +57,7 @@ internal static ISymbol FindFirstImplementedInterfaceMember(this ISymbol symbol, return FindFirstImplementedInterfaceMemberImpl(symbol, null, allInterfaces); } - internal static ISymbol FindImplementedInterfaceMember(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces = false) + internal static ISymbol? FindImplementedInterfaceMember(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces = false) { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); @@ -68,7 +68,7 @@ internal static ISymbol FindImplementedInterfaceMember(this ISymbol symbol, INam return FindFirstImplementedInterfaceMemberImpl(symbol, interfaceSymbol, allInterfaces); } - private static ISymbol FindFirstImplementedInterfaceMemberImpl(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces) + private static ISymbol? FindFirstImplementedInterfaceMemberImpl(this ISymbol symbol, INamedTypeSymbol? interfaceSymbol, bool allInterfaces) { INamedTypeSymbol containingType = symbol.ContainingType; @@ -116,7 +116,7 @@ public static bool ImplementsInterfaceMember(this ISymbol symbol, INamedTypeSymb return FindImplementedInterfaceMember(symbol, interfaceSymbol, allInterfaces) is not null; } - internal static TSymbol FindFirstImplementedInterfaceMember(this ISymbol symbol, bool allInterfaces = false) where TSymbol : ISymbol + internal static TSymbol? FindFirstImplementedInterfaceMember(this ISymbol symbol, bool allInterfaces = false) where TSymbol : ISymbol { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); @@ -124,7 +124,7 @@ internal static TSymbol FindFirstImplementedInterfaceMember(this ISymbo return FindFirstImplementedInterfaceMemberImpl(symbol, null, allInterfaces); } - internal static TSymbol FindFirstImplementedInterfaceMember(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces = false) where TSymbol : ISymbol + internal static TSymbol? FindFirstImplementedInterfaceMember(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces = false) where TSymbol : ISymbol { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); @@ -135,7 +135,7 @@ internal static TSymbol FindFirstImplementedInterfaceMember(this ISymbo return FindFirstImplementedInterfaceMemberImpl(symbol, interfaceSymbol, allInterfaces); } - private static TSymbol FindFirstImplementedInterfaceMemberImpl(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces = false) where TSymbol : ISymbol + private static TSymbol? FindFirstImplementedInterfaceMemberImpl(this ISymbol symbol, INamedTypeSymbol? interfaceSymbol, bool allInterfaces = false) where TSymbol : ISymbol { INamedTypeSymbol containingType = symbol.ContainingType; @@ -174,8 +174,8 @@ private static TSymbol FindFirstImplementedInterfaceMemberImpl(this ISy public static bool ImplementsInterfaceMember(this ISymbol symbol, bool allInterfaces = false) where TSymbol : ISymbol { return !EqualityComparer.Default.Equals( - FindFirstImplementedInterfaceMember(symbol, allInterfaces), - default(TSymbol)); + FindFirstImplementedInterfaceMember(symbol, allInterfaces)!, + default(TSymbol)!); } /// @@ -188,8 +188,8 @@ public static bool ImplementsInterfaceMember(this ISymbol symbol, bool public static bool ImplementsInterfaceMember(this ISymbol symbol, INamedTypeSymbol interfaceSymbol, bool allInterfaces = false) where TSymbol : ISymbol { return !EqualityComparer.Default.Equals( - FindFirstImplementedInterfaceMember(symbol, interfaceSymbol, allInterfaces), - default(TSymbol)); + FindFirstImplementedInterfaceMember(symbol, interfaceSymbol, allInterfaces)!, + default(TSymbol)!); } /// @@ -197,7 +197,7 @@ public static bool ImplementsInterfaceMember(this ISymbol symbol, IName /// /// /// - public static bool IsKind(this ISymbol symbol, SymbolKind kind) + public static bool IsKind(this ISymbol? symbol, SymbolKind kind) { return symbol?.Kind == kind; } @@ -208,7 +208,7 @@ public static bool IsKind(this ISymbol symbol, SymbolKind kind) /// /// /// - public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind2) + public static bool IsKind(this ISymbol? symbol, SymbolKind kind1, SymbolKind kind2) { if (symbol is null) return false; @@ -226,7 +226,7 @@ public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind /// /// /// - public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind2, SymbolKind kind3) + public static bool IsKind(this ISymbol? symbol, SymbolKind kind1, SymbolKind kind2, SymbolKind kind3) { if (symbol is null) return false; @@ -246,7 +246,7 @@ public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind /// /// /// - public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind2, SymbolKind kind3, SymbolKind kind4) + public static bool IsKind(this ISymbol? symbol, SymbolKind kind1, SymbolKind kind2, SymbolKind kind3, SymbolKind kind4) { if (symbol is null) return false; @@ -268,7 +268,7 @@ public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind /// /// /// - public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind2, SymbolKind kind3, SymbolKind kind4, SymbolKind kind5) + public static bool IsKind(this ISymbol? symbol, SymbolKind kind1, SymbolKind kind2, SymbolKind kind3, SymbolKind kind4, SymbolKind kind5) { if (symbol is null) return false; @@ -286,7 +286,7 @@ public static bool IsKind(this ISymbol symbol, SymbolKind kind1, SymbolKind kind /// Returns true if the symbol represents an error. /// /// - public static bool IsErrorType(this ISymbol symbol) + public static bool IsErrorType(this ISymbol? symbol) { return symbol?.Kind == SymbolKind.ErrorType; } @@ -295,7 +295,7 @@ public static bool IsErrorType(this ISymbol symbol) /// Returns true if the symbol is an async method. /// /// - public static bool IsAsyncMethod(this ISymbol symbol) + public static bool IsAsyncMethod(this ISymbol? symbol) { return symbol?.Kind == SymbolKind.Method && ((IMethodSymbol)symbol).IsAsync; @@ -321,7 +321,7 @@ internal static Task GetSyntaxAsync(this ISymbol symbol, Cancellatio .GetSyntaxAsync(cancellationToken); } - internal static SyntaxNode GetSyntaxOrDefault(this ISymbol symbol, CancellationToken cancellationToken = default) + internal static SyntaxNode? GetSyntaxOrDefault(this ISymbol symbol, CancellationToken cancellationToken = default) { return symbol .DeclaringSyntaxReferences @@ -334,7 +334,7 @@ internal static SyntaxNode GetSyntaxOrDefault(this ISymbol symbol, CancellationT /// /// /// - public static AttributeData GetAttribute(this ISymbol symbol, INamedTypeSymbol attributeClass) + public static AttributeData? GetAttribute(this ISymbol symbol, INamedTypeSymbol attributeClass) { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); @@ -358,14 +358,14 @@ public static AttributeData GetAttribute(this ISymbol symbol, INamedTypeSymbol a /// /// /// - public static AttributeData GetAttribute(this ISymbol symbol, in MetadataName attributeName) + public static AttributeData? GetAttribute(this ISymbol symbol, in MetadataName attributeName) { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); foreach (AttributeData attributeData in symbol.GetAttributes()) { - if (attributeData.AttributeClass.HasMetadataName(attributeName)) + if (attributeData.AttributeClass?.HasMetadataName(attributeName) == true) return attributeData; } @@ -393,7 +393,7 @@ public static bool HasAttribute(this ITypeSymbol typeSymbol, INamedTypeSymbol at if (!includeBaseTypes) return HasAttribute(typeSymbol, attributeClass); - ITypeSymbol t = typeSymbol; + ITypeSymbol? t = typeSymbol; do { @@ -429,7 +429,7 @@ public static bool HasAttribute(this ITypeSymbol typeSymbol, in MetadataName att if (!includeBaseTypes) return HasAttribute(typeSymbol, attributeName); - ITypeSymbol t = typeSymbol; + ITypeSymbol? t = typeSymbol; do { @@ -460,7 +460,7 @@ internal static ImmutableArray ParametersOrDefault(this ISymbo } } - internal static ISymbol OverriddenSymbol(this ISymbol symbol) + internal static ISymbol? OverriddenSymbol(this ISymbol symbol) { switch (symbol.Kind) { @@ -475,7 +475,7 @@ internal static ISymbol OverriddenSymbol(this ISymbol symbol) return null; } - internal static ISymbol BaseOverriddenSymbol(this ISymbol symbol) + internal static ISymbol? BaseOverriddenSymbol(this ISymbol symbol) { if (symbol is null) throw new ArgumentNullException(nameof(symbol)); @@ -681,7 +681,7 @@ internal static ImmutableArray GetParameters(this ISymbol symb return ImmutableArray.Empty; } - internal static INamespaceSymbol GetRootNamespace(this ISymbol symbol) + internal static INamespaceSymbol? GetRootNamespace(this ISymbol symbol) { INamespaceSymbol n = symbol.ContainingNamespace; @@ -703,7 +703,7 @@ internal static INamespaceSymbol GetRootNamespace(this ISymbol symbol) #endregion ISymbol #region IAssemblySymbol - internal static ImmutableArray GetTypes(this IAssemblySymbol assemblySymbol, Func predicate = null) + internal static ImmutableArray GetTypes(this IAssemblySymbol assemblySymbol, Func? predicate = null) { ImmutableArray.Builder builder = ImmutableArray.CreateBuilder(); @@ -729,7 +729,7 @@ void GetTypes(INamespaceOrTypeSymbol namespaceOrTypeSymbol) } } - internal static ImmutableArray GetNamespaces(this IAssemblySymbol assemblySymbol, Func predicate = null) + internal static ImmutableArray GetNamespaces(this IAssemblySymbol assemblySymbol, Func? predicate = null) { ImmutableArray.Builder builder = ImmutableArray.CreateBuilder(); @@ -749,19 +749,19 @@ void GetNamespaces(INamespaceSymbol namespaceSymbol) #endregion IAssemblySymbol #region IEventSymbol - internal static IEventSymbol BaseOverriddenEvent(this IEventSymbol eventSymbol) + internal static IEventSymbol? BaseOverriddenEvent(this IEventSymbol eventSymbol) { if (eventSymbol is null) throw new ArgumentNullException(nameof(eventSymbol)); - IEventSymbol overriddenEvent = eventSymbol.OverriddenEvent; + IEventSymbol? overriddenEvent = eventSymbol.OverriddenEvent; if (overriddenEvent is null) return null; while (true) { - IEventSymbol symbol = overriddenEvent.OverriddenEvent; + IEventSymbol? symbol = overriddenEvent.OverriddenEvent; if (symbol is null) return overriddenEvent; @@ -1068,19 +1068,19 @@ public static bool HasConstantValue(this IFieldSymbol fieldSymbol, string value) #endregion IFieldSymbol #region IMethodSymbol - internal static IMethodSymbol BaseOverriddenMethod(this IMethodSymbol methodSymbol) + internal static IMethodSymbol? BaseOverriddenMethod(this IMethodSymbol methodSymbol) { if (methodSymbol is null) throw new ArgumentNullException(nameof(methodSymbol)); - IMethodSymbol overriddenMethod = methodSymbol.OverriddenMethod; + IMethodSymbol? overriddenMethod = methodSymbol.OverriddenMethod; if (overriddenMethod is null) return null; while (true) { - IMethodSymbol symbol = overriddenMethod.OverriddenMethod; + IMethodSymbol? symbol = overriddenMethod.OverriddenMethod; if (symbol is null) return overriddenMethod; @@ -1093,7 +1093,7 @@ internal static IMethodSymbol BaseOverriddenMethod(this IMethodSymbol methodSymb /// If this method is a reduced extension method, returns the definition of extension method from which this was reduced. Otherwise, returns this symbol. /// /// - public static IMethodSymbol ReducedFromOrSelf(this IMethodSymbol methodSymbol) + public static IMethodSymbol? ReducedFromOrSelf(this IMethodSymbol? methodSymbol) { return methodSymbol?.ReducedFrom ?? methodSymbol; } @@ -1212,19 +1212,19 @@ public static bool IsRefOrOut(this IParameterSymbol parameterSymbol) #endregion IParameterSymbol #region IPropertySymbol - internal static IPropertySymbol BaseOverriddenProperty(this IPropertySymbol propertySymbol) + internal static IPropertySymbol? BaseOverriddenProperty(this IPropertySymbol propertySymbol) { if (propertySymbol is null) throw new ArgumentNullException(nameof(propertySymbol)); - IPropertySymbol overriddenProperty = propertySymbol.OverriddenProperty; + IPropertySymbol? overriddenProperty = propertySymbol.OverriddenProperty; if (overriddenProperty is null) return null; while (true) { - IPropertySymbol symbol = overriddenProperty.OverriddenProperty; + IPropertySymbol? symbol = overriddenProperty.OverriddenProperty; if (symbol is null) return overriddenProperty; @@ -1264,7 +1264,7 @@ public static bool IsNullableOf(this INamedTypeSymbol namedTypeSymbol, ITypeSymb /// /// /// - public static TSymbol FindMember( + public static TSymbol? FindMember( this INamedTypeSymbol typeSymbol, Func predicate, bool includeBaseTypes = false) where TSymbol : ISymbol @@ -1286,10 +1286,10 @@ public static TSymbol FindMember( /// /// /// - public static TSymbol FindMember( + public static TSymbol? FindMember( this INamedTypeSymbol typeSymbol, string name, - Func predicate = null, + Func? predicate = null, bool includeBaseTypes = false) where TSymbol : ISymbol { if (typeSymbol is null) @@ -1298,10 +1298,10 @@ public static TSymbol FindMember( return FindMemberImpl(typeSymbol, name, predicate, includeBaseTypes); } - private static TSymbol FindMemberImpl( + private static TSymbol? FindMemberImpl( this INamedTypeSymbol typeSymbol, - string name, - Func predicate = null, + string? name, + Func? predicate = null, bool includeBaseTypes = false) where TSymbol : ISymbol { ImmutableArray members; @@ -1312,7 +1312,7 @@ private static TSymbol FindMemberImpl( ? typeSymbol.GetMembers(name) : typeSymbol.GetMembers(); - TSymbol symbol = FindMemberImpl(members, predicate); + TSymbol? symbol = FindMemberImpl(members, predicate); if (symbol is not null) return symbol; @@ -1320,7 +1320,7 @@ private static TSymbol FindMemberImpl( if (!includeBaseTypes) break; - typeSymbol = typeSymbol.BaseType; + typeSymbol = typeSymbol.BaseType!; } while (typeSymbol is not null); @@ -1333,7 +1333,7 @@ private static TSymbol FindMemberImpl( /// /// /// - public static INamedTypeSymbol FindTypeMember( + public static INamedTypeSymbol? FindTypeMember( this INamedTypeSymbol typeSymbol, Func predicate, bool includeBaseTypes = false) @@ -1354,10 +1354,10 @@ public static INamedTypeSymbol FindTypeMember( /// /// /// - public static INamedTypeSymbol FindTypeMember( + public static INamedTypeSymbol? FindTypeMember( this INamedTypeSymbol typeSymbol, string name, - Func predicate = null, + Func? predicate = null, bool includeBaseTypes = false) { if (typeSymbol is null) @@ -1377,11 +1377,11 @@ public static INamedTypeSymbol FindTypeMember( /// /// /// - public static INamedTypeSymbol FindTypeMember( + public static INamedTypeSymbol? FindTypeMember( this INamedTypeSymbol typeSymbol, string name, int arity, - Func predicate = null, + Func? predicate = null, bool includeBaseTypes = false) { if (typeSymbol is null) @@ -1393,11 +1393,11 @@ public static INamedTypeSymbol FindTypeMember( return FindTypeMemberImpl(typeSymbol, name, arity, predicate, includeBaseTypes); } - private static INamedTypeSymbol FindTypeMemberImpl( + private static INamedTypeSymbol? FindTypeMemberImpl( this INamedTypeSymbol typeSymbol, - string name, + string? name, int? arity, - Func predicate = null, + Func? predicate = null, bool includeBaseTypes = false) { ImmutableArray members; @@ -1420,7 +1420,7 @@ private static INamedTypeSymbol FindTypeMemberImpl( members = typeSymbol.GetTypeMembers(); } - INamedTypeSymbol symbol = FindMemberImpl(members, predicate); + INamedTypeSymbol? symbol = FindMemberImpl(members, predicate); if (symbol is not null) return symbol; @@ -1428,7 +1428,7 @@ private static INamedTypeSymbol FindTypeMemberImpl( if (!includeBaseTypes) break; - typeSymbol = typeSymbol.BaseType; + typeSymbol = typeSymbol.BaseType!; } while (typeSymbol is not null); @@ -1497,7 +1497,7 @@ public static IEnumerable BaseTypes(this ITypeSymbol type) IEnumerable BaseTypesIterator() { - INamedTypeSymbol baseType = type.BaseType; + INamedTypeSymbol? baseType = type.BaseType; while (baseType is not null) { @@ -1520,7 +1520,7 @@ public static IEnumerable BaseTypesAndSelf(this ITypeSymbol typeSym IEnumerable BaseTypesAndSelfIterator() { - ITypeSymbol current = typeSymbol; + ITypeSymbol? current = typeSymbol; while (current is not null) { @@ -1740,7 +1740,7 @@ public static bool InheritsFrom(this ITypeSymbol type, ITypeSymbol baseType, boo if (baseType is null) return false; - INamedTypeSymbol t = type.BaseType; + INamedTypeSymbol? t = type.BaseType; while (t is not null) { @@ -1776,7 +1776,7 @@ public static bool InheritsFrom(this ITypeSymbol type, in MetadataName baseTypeN if (type is null) throw new ArgumentNullException(nameof(type)); - INamedTypeSymbol baseType = type.BaseType; + INamedTypeSymbol? baseType = type.BaseType; while (baseType is not null) { @@ -1834,7 +1834,7 @@ public static bool EqualsOrInheritsFrom(this ITypeSymbol type, in MetadataName b /// /// /// - public static TSymbol FindMember(this ITypeSymbol typeSymbol, Func predicate = null) where TSymbol : ISymbol + public static TSymbol? FindMember(this ITypeSymbol typeSymbol, Func? predicate = null) where TSymbol : ISymbol { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -1849,7 +1849,7 @@ public static TSymbol FindMember(this ITypeSymbol typeSymbol, Func /// /// - public static TSymbol FindMember(this ITypeSymbol typeSymbol, string name, Func predicate = null) where TSymbol : ISymbol + public static TSymbol? FindMember(this ITypeSymbol typeSymbol, string name, Func? predicate = null) where TSymbol : ISymbol { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -1857,7 +1857,7 @@ public static TSymbol FindMember(this ITypeSymbol typeSymbol, string na return FindMemberImpl(typeSymbol.GetMembers(name), predicate); } - private static TSymbol FindMemberImpl(ImmutableArray members, Func predicate) + private static TSymbol? FindMemberImpl(ImmutableArray members, Func? predicate) where TSymbol : ISymbol where TMemberSymbol : ISymbol { @@ -1890,7 +1890,7 @@ private static TSymbol FindMemberImpl(ImmutableArray /// /// - internal static bool ContainsMember(this ITypeSymbol typeSymbol, Func predicate = null) where TSymbol : ISymbol + internal static bool ContainsMember(this ITypeSymbol typeSymbol, Func? predicate = null) where TSymbol : ISymbol { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -1905,7 +1905,7 @@ internal static bool ContainsMember(this ITypeSymbol typeSymbol, Func /// /// - internal static bool ContainsMember(this ITypeSymbol typeSymbol, string name, Func predicate = null) where TSymbol : ISymbol + internal static bool ContainsMember(this ITypeSymbol typeSymbol, string name, Func? predicate = null) where TSymbol : ISymbol { if (typeSymbol is null) throw new ArgumentNullException(nameof(typeSymbol)); @@ -1942,17 +1942,17 @@ public static bool IsIEnumerableOrIEnumerableOfT(this ITypeSymbol typeSymbol) /// Returns true if the type is a reference type or a nullable type. /// /// - public static bool IsReferenceTypeOrNullableType(this ITypeSymbol typeSymbol) + public static bool IsReferenceTypeOrNullableType(this ITypeSymbol? typeSymbol) { return typeSymbol?.IsReferenceType == true - || typeSymbol.IsNullableType(); + || IsNullableType(typeSymbol); } /// /// Returns true if the type is a nullable type. /// /// - public static bool IsNullableType(this ITypeSymbol typeSymbol) + public static bool IsNullableType(this ITypeSymbol? typeSymbol) { return typeSymbol?.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T; } diff --git a/src/Core/Extensions/SyntaxExtensions.cs b/src/Core/Extensions/SyntaxExtensions.cs index 240849df29..ab80a96f1c 100644 --- a/src/Core/Extensions/SyntaxExtensions.cs +++ b/src/Core/Extensions/SyntaxExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis; @@ -102,12 +103,12 @@ public static bool Contains(this SeparatedSyntaxList list, TNode n return list.IndexOf(node) != -1; } - internal static TNode SingleOrDefault(this SeparatedSyntaxList list, bool shouldThrow) where TNode : SyntaxNode + internal static TNode? SingleOrDefault(this SeparatedSyntaxList list, bool shouldThrow) where TNode : SyntaxNode { return (shouldThrow) ? list.SingleOrDefault() : (list.Count == 1) ? list[0] : default; } - internal static TNode SingleOrDefault(this SeparatedSyntaxList list, Func predicate, bool shouldThrow) where TNode : SyntaxNode + internal static TNode? SingleOrDefault(this SeparatedSyntaxList list, Func predicate, bool shouldThrow) where TNode : SyntaxNode { if (shouldThrow) return list.SingleOrDefault(predicate); @@ -138,7 +139,7 @@ internal static TNode LastButOne(this SeparatedSyntaxList list) wh return list[list.Count - 2]; } - internal static TNode LastButOneOrDefault(this SeparatedSyntaxList list) where TNode : SyntaxNode + internal static TNode? LastButOneOrDefault(this SeparatedSyntaxList list) where TNode : SyntaxNode { return (list.Count > 1) ? list.LastButOne() : default; } @@ -352,12 +353,12 @@ public static bool Contains(this SyntaxList list, TNode node) wher return list.IndexOf(node) != -1; } - internal static TNode SingleOrDefault(this SyntaxList list, bool shouldThrow) where TNode : SyntaxNode + internal static TNode? SingleOrDefault(this SyntaxList list, bool shouldThrow) where TNode : SyntaxNode { return (shouldThrow) ? list.SingleOrDefault() : ((list.Count == 1) ? list[0] : default); } - internal static TNode SingleOrDefault(this SyntaxList list, Func predicate, bool shouldThrow) where TNode : SyntaxNode + internal static TNode? SingleOrDefault(this SyntaxList list, Func predicate, bool shouldThrow) where TNode : SyntaxNode { if (shouldThrow) return list.SingleOrDefault(predicate); @@ -408,7 +409,7 @@ internal static TNode LastButOne(this SyntaxList list) where TNode return list[list.Count - 2]; } - internal static TNode LastButOneOrDefault(this SyntaxList list) where TNode : SyntaxNode + internal static TNode? LastButOneOrDefault(this SyntaxList list) where TNode : SyntaxNode { return (list.Count > 1) ? list.LastButOne() : default; } @@ -447,7 +448,7 @@ public static SyntaxList WithTriviaFrom(this SyntaxList lis /// public static IEnumerable DescendantTrivia( this SyntaxList list, - Func descendIntoChildren = null, + Func? descendIntoChildren = null, bool descendIntoTrivia = false) where TNode : SyntaxNode { foreach (TNode node in list) @@ -470,7 +471,7 @@ public static IEnumerable DescendantTrivia( public static IEnumerable DescendantTrivia( this SyntaxList list, TextSpan span, - Func descendIntoChildren = null, + Func? descendIntoChildren = null, bool descendIntoTrivia = false) where TNode : SyntaxNode { foreach (TNode node in list) @@ -748,9 +749,9 @@ internal static int GetFullSpanEndLine(this SyntaxNode node, CancellationToken c /// /// /// - public static TNode FirstAncestor( + public static TNode? FirstAncestor( this SyntaxNode node, - Func predicate = null, + Func? predicate = null, bool ascendOutOfTrivia = true) where TNode : SyntaxNode { if (node is null) @@ -810,9 +811,9 @@ internal static TextSpan TrailingTriviaSpan(this SyntaxNode node) /// /// /// - public static TNode FirstDescendant( + public static TNode? FirstDescendant( this SyntaxNode node, - Func descendIntoChildren = null, + Func? descendIntoChildren = null, bool descendIntoTrivia = false) where TNode : SyntaxNode { foreach (SyntaxNode descendant in node.DescendantNodes(descendIntoChildren: descendIntoChildren, descendIntoTrivia: descendIntoTrivia)) @@ -832,10 +833,10 @@ public static TNode FirstDescendant( /// /// /// - public static TNode FirstDescendant( + public static TNode? FirstDescendant( this SyntaxNode node, TextSpan span, - Func descendIntoChildren = null, + Func? descendIntoChildren = null, bool descendIntoTrivia = false) where TNode : SyntaxNode { foreach (SyntaxNode descendant in node.DescendantNodes(span, descendIntoChildren: descendIntoChildren, descendIntoTrivia: descendIntoTrivia)) @@ -854,9 +855,9 @@ public static TNode FirstDescendant( /// /// /// - public static TNode FirstDescendantOrSelf( + public static TNode? FirstDescendantOrSelf( this SyntaxNode node, - Func descendIntoChildren = null, + Func? descendIntoChildren = null, bool descendIntoTrivia = false) where TNode : SyntaxNode { foreach (SyntaxNode descendant in node.DescendantNodesAndSelf(descendIntoChildren: descendIntoChildren, descendIntoTrivia: descendIntoTrivia)) @@ -876,10 +877,10 @@ public static TNode FirstDescendantOrSelf( /// /// /// - public static TNode FirstDescendantOrSelf( + public static TNode? FirstDescendantOrSelf( this SyntaxNode node, TextSpan span, - Func descendIntoChildren = null, + Func? descendIntoChildren = null, bool descendIntoTrivia = false) where TNode : SyntaxNode { foreach (SyntaxNode descendant in node.DescendantNodesAndSelf(span, descendIntoChildren: descendIntoChildren, descendIntoTrivia: descendIntoTrivia)) @@ -891,9 +892,9 @@ public static TNode FirstDescendantOrSelf( return default; } - internal static SyntaxNode GetParent(this SyntaxNode node, bool ascendOutOfTrivia) + internal static SyntaxNode? GetParent(this SyntaxNode node, bool ascendOutOfTrivia) { - SyntaxNode parent = node.Parent; + SyntaxNode? parent = node.Parent; if (parent is null && ascendOutOfTrivia @@ -909,7 +910,7 @@ internal static SyntaxNode WalkUp(this SyntaxNode node, Func p { while (true) { - SyntaxNode parent = node.Parent; + SyntaxNode? parent = node.Parent; if (parent is not null && predicate(parent)) @@ -935,7 +936,7 @@ public static SyntaxNodeOrToken WithoutTrivia(this SyntaxNodeOrToken nodeOrToken { if (nodeOrToken.IsNode) { - return nodeOrToken.AsNode().WithoutTrivia(); + return nodeOrToken.AsNode()!.WithoutTrivia(); } else { @@ -951,7 +952,7 @@ public static SyntaxNodeOrToken WithoutLeadingTrivia(this SyntaxNodeOrToken node { if (nodeOrToken.IsNode) { - return nodeOrToken.AsNode().WithoutLeadingTrivia(); + return nodeOrToken.AsNode()!.WithoutLeadingTrivia(); } else { @@ -967,7 +968,7 @@ public static SyntaxNodeOrToken WithoutTrailingTrivia(this SyntaxNodeOrToken nod { if (nodeOrToken.IsNode) { - return nodeOrToken.AsNode().WithoutTrailingTrivia(); + return nodeOrToken.AsNode()!.WithoutTrailingTrivia(); } else { @@ -1094,22 +1095,26 @@ public static SyntaxTriviaList LeadingAndTrailingTrivia(this SyntaxToken token) internal static int GetSpanStartLine(this SyntaxToken token, CancellationToken cancellationToken = default) { - return token.SyntaxTree.GetLineSpan(token.Span, cancellationToken).StartLine(); + return token.SyntaxTree?.GetLineSpan(token.Span, cancellationToken).StartLine() + ?? throw new InvalidOperationException("Token is not contained in a syntax tree."); } internal static int GetFullSpanStartLine(this SyntaxToken token, CancellationToken cancellationToken = default) { - return token.SyntaxTree.GetLineSpan(token.FullSpan, cancellationToken).StartLine(); + return token.SyntaxTree?.GetLineSpan(token.FullSpan, cancellationToken).StartLine() + ?? throw new InvalidOperationException("Token is not contained in a syntax tree."); } internal static int GetSpanEndLine(this SyntaxToken token, CancellationToken cancellationToken = default) { - return token.SyntaxTree.GetLineSpan(token.Span, cancellationToken).EndLine(); + return token.SyntaxTree?.GetLineSpan(token.Span, cancellationToken).EndLine() + ?? throw new InvalidOperationException("Token is not contained in a syntax tree."); } internal static int GetFullSpanEndLine(this SyntaxToken token, CancellationToken cancellationToken = default) { - return token.SyntaxTree.GetLineSpan(token.FullSpan, cancellationToken).EndLine(); + return token.SyntaxTree?.GetLineSpan(token.FullSpan, cancellationToken).EndLine() + ?? throw new InvalidOperationException("Token is not contained in a syntax tree."); } /// diff --git a/src/Core/Extensions/TextExtensions.cs b/src/Core/Extensions/TextExtensions.cs index 8d5deacc38..0d64ede5ff 100644 --- a/src/Core/Extensions/TextExtensions.cs +++ b/src/Core/Extensions/TextExtensions.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Collections.Immutable; using Microsoft.CodeAnalysis.Text; @@ -35,9 +36,14 @@ public static bool IsEmptyOrWhiteSpace(this TextLine textLine) public static bool IsEmptyOrWhiteSpace(this TextLine textLine, TextSpan span) { + SourceText? text = textLine.Text; + + if (text is null) + throw new ArgumentException("Text line is not part of a source text.", nameof(textLine)); + for (int i = span.Start; i < span.End; i++) { - if (!char.IsWhiteSpace(textLine.Text[i])) + if (!char.IsWhiteSpace(text[i])) return false; } diff --git a/src/Core/FileSystemHelpers.cs b/src/Core/FileSystemHelpers.cs index 9e4199b23d..6787e9b0d5 100644 --- a/src/Core/FileSystemHelpers.cs +++ b/src/Core/FileSystemHelpers.cs @@ -37,12 +37,12 @@ public static bool IsDirectorySeparator(char ch) || ch == Path.AltDirectorySeparatorChar; } - public static bool TryGetNormalizedFullPath(string path, out string result) + public static bool TryGetNormalizedFullPath(string path, out string? result) { return TryGetNormalizedFullPath(path, basePath: null, out result); } - public static bool TryGetNormalizedFullPath(string path, string basePath, out string result) + public static bool TryGetNormalizedFullPath(string path, string? basePath, out string? result) { try { diff --git a/src/Core/GeneratedCodeUtility.cs b/src/Core/GeneratedCodeUtility.cs index 4eb1d8e7fc..197b2d7043 100644 --- a/src/Core/GeneratedCodeUtility.cs +++ b/src/Core/GeneratedCodeUtility.cs @@ -45,12 +45,12 @@ public static bool IsGeneratedCode( return false; } - public static bool IsGeneratedCodeFile(string filePath) + public static bool IsGeneratedCodeFile(string? filePath) { if (string.IsNullOrEmpty(filePath)) return false; - int directorySeparatorIndex = filePath.LastIndexOfAny(_separators); + int directorySeparatorIndex = filePath!.LastIndexOfAny(_separators); if (string.Compare("TemporaryGeneratedFile_", 0, filePath, directorySeparatorIndex + 1, "TemporaryGeneratedFile_".Length, StringComparison.OrdinalIgnoreCase) == 0) return true; diff --git a/src/Core/Hash.cs b/src/Core/Hash.cs index a6fba55a62..c284078c87 100644 --- a/src/Core/Hash.cs +++ b/src/Core/Hash.cs @@ -24,7 +24,7 @@ public static int Create(bool value) return (value) ? 1 : 0; } - public static int Create(T value) where T : class + public static int Create(T? value) where T : class { return Combine(value, OffsetBasis); } @@ -39,14 +39,14 @@ public static int Combine(bool value, int hash) return Combine(hash, (value) ? 1 : 0); } - public static int Combine(T value, int hash) where T : class + public static int Combine(T? value, int hash) where T : class { hash = unchecked(hash * Prime); return (value is not null) ? unchecked(hash + value.GetHashCode()) : hash; } - public static int CombineValues(IEnumerable values, IEqualityComparer comparer = null, int maxItemsToHash = int.MaxValue) + public static int CombineValues(IEnumerable values, IEqualityComparer? comparer = null, int maxItemsToHash = int.MaxValue) { if (values is null) return 0; @@ -62,7 +62,7 @@ public static int CombineValues(IEnumerable values, IEqualityComparer c if (count >= maxItemsToHash) break; - if (!comparer.Equals(value, default(T))) + if (!comparer.Equals(value, default(T)!)) hash = Combine(comparer.GetHashCode(value), hash); count++; @@ -71,7 +71,7 @@ public static int CombineValues(IEnumerable values, IEqualityComparer c return hash; } - public static int CombineValues(T[] values, IEqualityComparer comparer = null, int maxItemsToHash = int.MaxValue) + public static int CombineValues(T[] values, IEqualityComparer? comparer = null, int maxItemsToHash = int.MaxValue) { if (values is null) return 0; @@ -87,14 +87,14 @@ public static int CombineValues(T[] values, IEqualityComparer comparer = n { T value = values[i]; - if (!comparer.Equals(value, default(T))) + if (!comparer.Equals(value, default(T)!)) hash = Combine(comparer.GetHashCode(value), hash); } return hash; } - public static int CombineValues(ImmutableArray values, IEqualityComparer comparer = null, int maxItemsToHash = int.MaxValue) + public static int CombineValues(ImmutableArray values, IEqualityComparer? comparer = null, int maxItemsToHash = int.MaxValue) { if (values.IsDefaultOrEmpty) return 0; @@ -110,7 +110,7 @@ public static int CombineValues(ImmutableArray values, IEqualityComparer.Builder containingNamespaces = (containingNamespaceCount > 0) + ImmutableArray.Builder? containingNamespaces = (containingNamespaceCount > 0) ? ImmutableArray.CreateBuilder(containingNamespaceCount) : null; - ImmutableArray.Builder containingTypes = (containingTypeCount > 1) + ImmutableArray.Builder? containingTypes = (containingTypeCount > 1) ? ImmutableArray.CreateBuilder(containingTypeCount) : null; @@ -405,7 +405,7 @@ private static MetadataName Parse(string name, bool shouldThrow) { string n = name.Substring(prevIndex, i - prevIndex); - containingNamespaces.Add(n); + containingNamespaces!.Add(n); prevIndex = i + 1; } diff --git a/src/Core/MetadataNameEqualityComparer`1.cs b/src/Core/MetadataNameEqualityComparer`1.cs index 37a571c155..730af8848f 100644 --- a/src/Core/MetadataNameEqualityComparer`1.cs +++ b/src/Core/MetadataNameEqualityComparer`1.cs @@ -112,10 +112,10 @@ public override bool Equals(TSymbol x, TSymbol y) if (object.ReferenceEquals(x, y)) return true; - if (Default.Equals(x, default(TSymbol))) + if (Default.Equals(x, default(TSymbol)!)) return false; - if (Default.Equals(y, default(TSymbol))) + if (Default.Equals(y, default(TSymbol)!)) return false; if (!StringComparer.Ordinal.Equals(x.MetadataName, y.MetadataName)) @@ -171,7 +171,7 @@ public override int GetHashCode(TSymbol obj) if (obj is null) throw new ArgumentNullException(nameof(obj)); - if (Default.Equals(obj, default(TSymbol))) + if (Default.Equals(obj, default(TSymbol)!)) return 0; int hashCode = Hash.Create(MetadataName.GetHashCode(obj.MetadataName)); diff --git a/src/Core/NameGenerator.cs b/src/Core/NameGenerator.cs index 9d86b0af6e..ca7957d615 100644 --- a/src/Core/NameGenerator.cs +++ b/src/Core/NameGenerator.cs @@ -244,9 +244,9 @@ public static bool IsUniqueName(string name, IEnumerable reservedNames, /// /// /// - public static string CreateName(ITypeSymbol typeSymbol, bool firstCharToLower = false) + public static string? CreateName(ITypeSymbol typeSymbol, bool firstCharToLower = false) { - string name = CreateNameFromTypeSymbolHelper.CreateName(typeSymbol); + string? name = CreateNameFromTypeSymbolHelper.CreateName(typeSymbol); if (name is not null && firstCharToLower) @@ -257,7 +257,7 @@ public static string CreateName(ITypeSymbol typeSymbol, bool firstCharToLower = return name; } - internal string CreateUniqueLocalName( + internal string? CreateUniqueLocalName( ITypeSymbol typeSymbol, SemanticModel semanticModel, int position, @@ -266,7 +266,7 @@ internal string CreateUniqueLocalName( { if (typeSymbol is not null) { - string name = CreateName(typeSymbol, firstCharToLower: true); + string? name = CreateName(typeSymbol, firstCharToLower: true); if (name is not null) return EnsureUniqueLocalName(name, semanticModel, position, isCaseSensitive, cancellationToken); @@ -275,7 +275,7 @@ internal string CreateUniqueLocalName( return null; } - internal string CreateUniqueLocalName( + internal string? CreateUniqueLocalName( ITypeSymbol typeSymbol, string oldName, SemanticModel semanticModel, @@ -283,7 +283,7 @@ internal string CreateUniqueLocalName( bool isCaseSensitive = true, CancellationToken cancellationToken = default) { - string newName = CreateName(typeSymbol, firstCharToLower: true); + string? newName = CreateName(typeSymbol, firstCharToLower: true); if (newName is not null && !string.Equals(oldName, newName, StringComparison.Ordinal)) @@ -297,14 +297,14 @@ internal string CreateUniqueLocalName( return null; } - internal string CreateUniqueParameterName( + internal string? CreateUniqueParameterName( string oldName, IParameterSymbol parameterSymbol, SemanticModel semanticModel, bool isCaseSensitive = true, CancellationToken cancellationToken = default) { - string newName = CreateName(parameterSymbol.Type, firstCharToLower: true); + string? newName = CreateName(parameterSymbol.Type, firstCharToLower: true); if (newName is not null && !string.Equals(oldName, newName, StringComparison.Ordinal)) diff --git a/src/Core/OneOrMany`1.cs b/src/Core/OneOrMany`1.cs index 7b55b773db..26bff2a9c7 100644 --- a/src/Core/OneOrMany`1.cs +++ b/src/Core/OneOrMany`1.cs @@ -11,7 +11,7 @@ namespace Roslynator; internal readonly struct OneOrMany : IReadOnlyList, IEquatable> { private readonly State _state; - private readonly T _value; + private readonly T? _value; private readonly ImmutableArray _values; internal OneOrMany(T value) @@ -39,7 +39,7 @@ public T this[int index] case State.One: { if (index == 0) - return _value; + return _value!; break; } @@ -108,7 +108,7 @@ public bool Equals(OneOrMany other) case State.One: { return other._state == State.One - && EqualityComparer.Default.Equals(_value, other._value); + && EqualityComparer.Default.Equals(_value!, other._value!); } case State.Many: { @@ -125,7 +125,7 @@ public override int GetHashCode() int hashCode = Hash.Create((int)_state); if (_state == State.One) - return Hash.Combine(EqualityComparer.Default.GetHashCode(_value), hashCode); + return Hash.Combine(EqualityComparer.Default.GetHashCode(_value!), hashCode); if (_state == State.Many) return Hash.Combine(_values.GetHashCode(), hashCode); @@ -186,7 +186,7 @@ internal EnumeratorImpl(in OneOrMany oneOrMany) public T Current => _en.Current; - object IEnumerator.Current => _en.Current; + object? IEnumerator.Current => _en.Current; public bool MoveNext() => _en.MoveNext(); diff --git a/src/Core/SeparatedSyntaxListSelection`1.cs b/src/Core/SeparatedSyntaxListSelection`1.cs index 773207d894..9e2f9e1b3d 100644 --- a/src/Core/SeparatedSyntaxListSelection`1.cs +++ b/src/Core/SeparatedSyntaxListSelection`1.cs @@ -133,25 +133,25 @@ public static SeparatedSyntaxListSelection Create(SeparatedSyntaxList /// /// True if the specified span contains at least one node; otherwise, false. - public static bool TryCreate(SeparatedSyntaxList list, TextSpan span, out SeparatedSyntaxListSelection selection) + public static bool TryCreate(SeparatedSyntaxList list, TextSpan span, out SeparatedSyntaxListSelection? selection) { selection = Create(list, span, 1, int.MaxValue); return selection is not null; } - internal static bool TryCreate(SeparatedSyntaxList list, TextSpan span, int minCount, out SeparatedSyntaxListSelection selection) + internal static bool TryCreate(SeparatedSyntaxList list, TextSpan span, int minCount, out SeparatedSyntaxListSelection? selection) { selection = Create(list, span, minCount, int.MaxValue); return selection is not null; } - internal static bool TryCreate(SeparatedSyntaxList list, TextSpan span, int minCount, int maxCount, out SeparatedSyntaxListSelection selection) + internal static bool TryCreate(SeparatedSyntaxList list, TextSpan span, int minCount, int maxCount, out SeparatedSyntaxListSelection? selection) { selection = Create(list, span, minCount, maxCount); return selection is not null; } - private static SeparatedSyntaxListSelection Create(SeparatedSyntaxList list, TextSpan span, int minCount, int maxCount) + private static SeparatedSyntaxListSelection? Create(SeparatedSyntaxList list, TextSpan span, int minCount, int maxCount) { SelectionResult result = SelectionResult.Create(list, span, minCount, maxCount); diff --git a/src/Core/StringUtility.cs b/src/Core/StringUtility.cs index 145d56202c..7fdf96038b 100644 --- a/src/Core/StringUtility.cs +++ b/src/Core/StringUtility.cs @@ -8,7 +8,7 @@ namespace Roslynator; internal static class StringUtility { - internal static bool IsNullOrEquals(string s, string value) + internal static bool IsNullOrEquals(string? s, string value) { return s is null || Equals(s, value); diff --git a/src/Core/SymbolUtility.cs b/src/Core/SymbolUtility.cs index f586059440..166b7fea9e 100644 --- a/src/Core/SymbolUtility.cs +++ b/src/Core/SymbolUtility.cs @@ -9,7 +9,7 @@ namespace Roslynator; internal static class SymbolUtility { - public static bool IsPublicStaticReadOnly(IFieldSymbol fieldSymbol, string name = null) + public static bool IsPublicStaticReadOnly(IFieldSymbol fieldSymbol, string? name = null) { return fieldSymbol?.DeclaredAccessibility == Accessibility.Public && fieldSymbol.IsStatic @@ -17,7 +17,7 @@ public static bool IsPublicStaticReadOnly(IFieldSymbol fieldSymbol, string name && StringUtility.IsNullOrEquals(name, fieldSymbol.Name); } - public static bool IsPublicStaticNonGeneric(IMethodSymbol methodSymbol, string name = null) + public static bool IsPublicStaticNonGeneric(IMethodSymbol methodSymbol, string? name = null) { return methodSymbol?.DeclaredAccessibility == Accessibility.Public && methodSymbol.IsStatic @@ -25,7 +25,7 @@ public static bool IsPublicStaticNonGeneric(IMethodSymbol methodSymbol, string n && StringUtility.IsNullOrEquals(name, methodSymbol.Name); } - public static bool IsPublicInstanceNonGeneric(IMethodSymbol methodSymbol, string name = null) + public static bool IsPublicInstanceNonGeneric(IMethodSymbol methodSymbol, string? name = null) { return methodSymbol?.DeclaredAccessibility == Accessibility.Public && !methodSymbol.IsStatic @@ -33,14 +33,14 @@ public static bool IsPublicInstanceNonGeneric(IMethodSymbol methodSymbol, string && StringUtility.IsNullOrEquals(name, methodSymbol.Name); } - public static bool IsPublicInstance(IPropertySymbol propertySymbol, string name = null) + public static bool IsPublicInstance(IPropertySymbol propertySymbol, string? name = null) { return propertySymbol?.DeclaredAccessibility == Accessibility.Public && !propertySymbol.IsStatic && StringUtility.IsNullOrEquals(name, propertySymbol.Name); } - public static bool IsStringAdditionOperator(IMethodSymbol methodSymbol) + public static bool IsStringAdditionOperator(IMethodSymbol? methodSymbol) { return methodSymbol?.MethodKind == MethodKind.BuiltinOperator && methodSymbol.Name == WellKnownMemberNames.AdditionOperatorName @@ -155,7 +155,7 @@ public static bool HasAccessibleIndexer( } } - public static string GetCountOrLengthPropertyName( + public static string? GetCountOrLengthPropertyName( ITypeSymbol typeSymbol, SemanticModel semanticModel, int position) @@ -168,7 +168,7 @@ public static string GetCountOrLengthPropertyName( if (kind == SymbolKind.ArrayType) return "Length"; - string propertyName = GetCountOrLengthPropertyName(typeSymbol.SpecialType); + string? propertyName = GetCountOrLengthPropertyName(typeSymbol.SpecialType); if (propertyName is not null) return (propertyName.Length > 0) ? propertyName : null; @@ -212,13 +212,13 @@ public static string GetCountOrLengthPropertyName( } } - typeSymbol = typeSymbol.BaseType; + typeSymbol = typeSymbol.BaseType!; } } return null; - static string GetCountOrLengthPropertyName(SpecialType specialType) + static string? GetCountOrLengthPropertyName(SpecialType specialType) { switch (specialType) { @@ -275,7 +275,7 @@ public static bool IsPredicateFunc(ISymbol symbol, ITypeSymbol parameter1, IType && typeArguments[2].SpecialType == SpecialType.System_Boolean; } - internal static bool IsPropertyOfNullableOfT(ISymbol symbol, string name) + internal static bool IsPropertyOfNullableOfT(ISymbol? symbol, string name) { return symbol?.Kind == SymbolKind.Property && symbol.ContainingType?.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T @@ -385,7 +385,7 @@ internal static bool IsLinqOfType(IMethodSymbol methodSymbol) internal static bool IsLinqExtensionOfIEnumerableOfT( IMethodSymbol methodSymbol, - string name = null, + string? name = null, int parameterCount = 1, bool allowImmutableArrayExtension = false) { @@ -401,7 +401,7 @@ internal static bool IsLinqExtensionOfIEnumerableOfT( internal static bool IsLinqExtensionOfIEnumerableOfT( IMethodSymbol methodSymbol, - string name, + string? name, Interval interval, bool allowImmutableArrayExtension = false) { @@ -440,7 +440,7 @@ internal static bool IsLinqExtensionOfIEnumerableOfT( internal static bool IsLinqExtensionOfIEnumerableOfTWithPredicate( IMethodSymbol methodSymbol, - string name = null, + string? name = null, bool allowImmutableArrayExtension = false) { return IsLinqExtensionOfIEnumerableOfTWithPredicate(methodSymbol, name, parameterCount: 2, allowImmutableArrayExtension: allowImmutableArrayExtension); @@ -448,7 +448,7 @@ internal static bool IsLinqExtensionOfIEnumerableOfTWithPredicate( private static bool IsLinqExtensionOfIEnumerableOfTWithPredicate( IMethodSymbol methodSymbol, - string name, + string? name, int parameterCount, bool allowImmutableArrayExtension = false) { @@ -575,27 +575,32 @@ public static bool CanBeEntryPoint(IMethodSymbol methodSymbol) public static ulong GetEnumValueAsUInt64(object value, INamedTypeSymbol enumType) { - return ConvertHelpers.ConvertToUInt64(value, enumType.EnumUnderlyingType.SpecialType); + INamedTypeSymbol? enumUnderlyingType = enumType.EnumUnderlyingType; + + if (enumUnderlyingType is null) + throw new InvalidOperationException($"Type is not an enum: {enumType.ToDisplayString(SymbolDisplayFormats.FullName)}"); + + return ConvertHelpers.ConvertToUInt64(value, enumUnderlyingType.SpecialType); } - public static IMethodSymbol FindMethodThatRaisePropertyChanged(INamedTypeSymbol typeSymbol, int position, SemanticModel semanticModel) + public static IMethodSymbol? FindMethodThatRaisePropertyChanged(INamedTypeSymbol typeSymbol, int position, SemanticModel semanticModel) { do { - IMethodSymbol methodSymbol = FindMethod(typeSymbol.GetMembers("RaisePropertyChanged")) + IMethodSymbol? methodSymbol = FindMethod(typeSymbol.GetMembers("RaisePropertyChanged")) ?? FindMethod(typeSymbol.GetMembers("OnPropertyChanged")); if (methodSymbol is not null) return methodSymbol; - typeSymbol = typeSymbol.BaseType; + typeSymbol = typeSymbol.BaseType!; } while (typeSymbol is not null && typeSymbol.SpecialType != SpecialType.System_Object); return null; - IMethodSymbol FindMethod(ImmutableArray symbols) + IMethodSymbol? FindMethod(ImmutableArray symbols) { foreach (ISymbol symbol in symbols) { @@ -617,7 +622,7 @@ IMethodSymbol FindMethod(ImmutableArray symbols) public static bool IsAwaitable(ITypeSymbol typeSymbol, bool shouldCheckWindowsRuntimeTypes = false) { - INamedTypeSymbol namedTypeSymbol = GetPossiblyAwaitableType(typeSymbol); + INamedTypeSymbol? namedTypeSymbol = GetPossiblyAwaitableType(typeSymbol); if (namedTypeSymbol is null) return false; @@ -664,13 +669,13 @@ public static bool IsAwaitable(ITypeSymbol typeSymbol, bool shouldCheckWindowsRu return false; } - internal static INamedTypeSymbol GetPossiblyAwaitableType(ITypeSymbol typeSymbol) + internal static INamedTypeSymbol? GetPossiblyAwaitableType(ITypeSymbol typeSymbol) { if (typeSymbol.Kind == SymbolKind.TypeParameter) { var typeParameterSymbol = (ITypeParameterSymbol)typeSymbol; - typeSymbol = typeParameterSymbol.ConstraintTypes.SingleOrDefault(f => f.TypeKind == TypeKind.Class, shouldThrow: false); + typeSymbol = typeParameterSymbol.ConstraintTypes.SingleOrDefault(f => f.TypeKind == TypeKind.Class, shouldThrow: false)!; if (typeSymbol is null) return null; diff --git a/src/Core/SyntaxListSelection`1.cs b/src/Core/SyntaxListSelection`1.cs index 0b279daefe..0d3a03e342 100644 --- a/src/Core/SyntaxListSelection`1.cs +++ b/src/Core/SyntaxListSelection`1.cs @@ -133,25 +133,25 @@ public static SyntaxListSelection Create(SyntaxList list, TextSpan /// /// /// True if the specified span contains at least one node; otherwise, false. - public static bool TryCreate(SyntaxList list, TextSpan span, out SyntaxListSelection selection) + public static bool TryCreate(SyntaxList list, TextSpan span, out SyntaxListSelection? selection) { selection = Create(list, span, 1, int.MaxValue); return selection is not null; } - internal static bool TryCreate(SyntaxList list, TextSpan span, int minCount, out SyntaxListSelection selection) + internal static bool TryCreate(SyntaxList list, TextSpan span, int minCount, out SyntaxListSelection? selection) { selection = Create(list, span, minCount, int.MaxValue); return selection is not null; } - internal static bool TryCreate(SyntaxList list, TextSpan span, int minCount, int maxCount, out SyntaxListSelection selection) + internal static bool TryCreate(SyntaxList list, TextSpan span, int minCount, int maxCount, out SyntaxListSelection? selection) { selection = Create(list, span, minCount, maxCount); return selection is not null; } - private static SyntaxListSelection Create(SyntaxList list, TextSpan span, int minCount, int maxCount) + private static SyntaxListSelection? Create(SyntaxList list, TextSpan span, int minCount, int maxCount) { SelectionResult result = SelectionResult.Create(list, span, minCount, maxCount); diff --git a/src/Core/SyntaxUtility.cs b/src/Core/SyntaxUtility.cs index 28767ea05d..8849709377 100644 --- a/src/Core/SyntaxUtility.cs +++ b/src/Core/SyntaxUtility.cs @@ -13,7 +13,7 @@ public static bool IsPropertyOfNullableOfT( SemanticModel semanticModel, CancellationToken cancellationToken = default) { - ISymbol symbol = semanticModel.GetSymbol(node, cancellationToken); + ISymbol? symbol = semanticModel.GetSymbol(node, cancellationToken); return SymbolUtility.IsPropertyOfNullableOfT(symbol, name); } @@ -23,15 +23,15 @@ public static bool IsCompositeEnumValue( SemanticModel semanticModel, CancellationToken cancellationToken = default) { - var enumTypeSymbol = (INamedTypeSymbol)semanticModel.GetTypeSymbol(node, cancellationToken); + var enumTypeSymbol = (INamedTypeSymbol?)semanticModel.GetTypeSymbol(node, cancellationToken); - if (enumTypeSymbol.EnumUnderlyingType is not null) + if (enumTypeSymbol?.EnumUnderlyingType is not null) { - Optional constantValue = semanticModel.GetConstantValue(node, cancellationToken); + Optional constantValue = semanticModel.GetConstantValue(node, cancellationToken); if (constantValue.HasValue) { - ulong value = SymbolUtility.GetEnumValueAsUInt64(constantValue.Value, enumTypeSymbol); + ulong value = SymbolUtility.GetEnumValueAsUInt64(constantValue.Value!, enumTypeSymbol); return FlagsUtility.Instance.IsComposite(value); } diff --git a/src/Core/Text/IndentationChange.cs b/src/Core/Text/IndentationChange.cs index aca2db64ac..f91c095b07 100644 --- a/src/Core/Text/IndentationChange.cs +++ b/src/Core/Text/IndentationChange.cs @@ -9,7 +9,7 @@ namespace Roslynator.Text; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal readonly struct IndentationChange : IEquatable { - public IndentationChange(ImmutableArray indentations, string replacement) + public IndentationChange(ImmutableArray indentations, string? replacement) { Indentations = indentations; Replacement = replacement; @@ -19,7 +19,7 @@ public IndentationChange(ImmutableArray indentations, string re public ImmutableArray Indentations { get; } - public string Replacement { get; } + public string? Replacement { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay diff --git a/src/Core/Text/StringBuilderCache.cs b/src/Core/Text/StringBuilderCache.cs index 1f86c9525d..7c1ebbf0ac 100644 --- a/src/Core/Text/StringBuilderCache.cs +++ b/src/Core/Text/StringBuilderCache.cs @@ -11,13 +11,13 @@ internal static class StringBuilderCache private const int DefaultCapacity = 16; [ThreadStatic] - private static StringBuilder _cachedInstance; + private static StringBuilder? _cachedInstance; public static StringBuilder GetInstance(int capacity = DefaultCapacity) { if (capacity <= MaxSize) { - StringBuilder sb = _cachedInstance; + StringBuilder? sb = _cachedInstance; if (sb is not null && capacity <= sb.Capacity) diff --git a/src/Core/Text/TextLineCollectionSelection.cs b/src/Core/Text/TextLineCollectionSelection.cs index 6643bbb93a..049776abe6 100644 --- a/src/Core/Text/TextLineCollectionSelection.cs +++ b/src/Core/Text/TextLineCollectionSelection.cs @@ -131,25 +131,25 @@ public static TextLineCollectionSelection Create(TextLineCollection lines, TextS /// /// /// True if the specified span contains at least one line; otherwise, false. - public static bool TryCreate(TextLineCollection lines, TextSpan span, out TextLineCollectionSelection selectedLines) + public static bool TryCreate(TextLineCollection lines, TextSpan span, out TextLineCollectionSelection? selectedLines) { selectedLines = Create(lines, span, 1, int.MaxValue); return selectedLines is not null; } - internal static bool TryCreate(TextLineCollection lines, TextSpan span, int minCount, out TextLineCollectionSelection selectedLines) + internal static bool TryCreate(TextLineCollection lines, TextSpan span, int minCount, out TextLineCollectionSelection? selectedLines) { selectedLines = Create(lines, span, minCount, int.MaxValue); return selectedLines is not null; } - internal static bool TryCreate(TextLineCollection lines, TextSpan span, int minCount, int maxCount, out TextLineCollectionSelection selectedLines) + internal static bool TryCreate(TextLineCollection lines, TextSpan span, int minCount, int maxCount, out TextLineCollectionSelection? selectedLines) { selectedLines = Create(lines, span, minCount, maxCount); return selectedLines is not null; } - private static TextLineCollectionSelection Create(TextLineCollection lines, TextSpan span, int minCount, int maxCount) + private static TextLineCollectionSelection? Create(TextLineCollection lines, TextSpan span, int minCount, int maxCount) { if (lines is null) return null; diff --git a/src/Core/XmlTagMapper.cs b/src/Core/XmlTagMapper.cs index 9254858b0a..774be98ac8 100644 --- a/src/Core/XmlTagMapper.cs +++ b/src/Core/XmlTagMapper.cs @@ -40,10 +40,13 @@ private static ImmutableDictionary CreateMap() }); } - public static XmlTag GetTagOrDefault(string name) + public static XmlTag GetTagOrDefault(string? name) { - if (_map.TryGetValue(name, out XmlTag kind)) + if (name is not null + && _map.TryGetValue(name, out XmlTag kind)) + { return kind; + } return XmlTag.None; } diff --git a/src/Tests/Testing.CSharp.MSTest/Testing.CSharp.MSTest.csproj b/src/Tests/Testing.CSharp.MSTest/Testing.CSharp.MSTest.csproj index 90f42b5e72..b7cc26deed 100644 --- a/src/Tests/Testing.CSharp.MSTest/Testing.CSharp.MSTest.csproj +++ b/src/Tests/Testing.CSharp.MSTest/Testing.CSharp.MSTest.csproj @@ -5,6 +5,7 @@ $(RoslynatorTestingVersion) Roslynator.Testing.CSharp.MSTest Roslynator.Testing.CSharp.MSTest + enable diff --git a/src/Tests/Testing.CSharp.MSTest/Testing/CSharp/MSTest/MSTestAssert.cs b/src/Tests/Testing.CSharp.MSTest/Testing/CSharp/MSTest/MSTestAssert.cs index 2a25467156..28175f3072 100644 --- a/src/Tests/Testing.CSharp.MSTest/Testing/CSharp/MSTest/MSTestAssert.cs +++ b/src/Tests/Testing.CSharp.MSTest/Testing/CSharp/MSTest/MSTestAssert.cs @@ -15,4 +15,14 @@ public void True(bool condition, string userMessage) { global::Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(condition, userMessage); } + + public void Null(object? value) + { + global::Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(value); + } + + public void NotNull(object? value) + { + global::Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(value); + } } diff --git a/src/Tests/Testing.CSharp.Xunit/Testing.CSharp.Xunit.csproj b/src/Tests/Testing.CSharp.Xunit/Testing.CSharp.Xunit.csproj index 03c44cf9c7..38b5602635 100644 --- a/src/Tests/Testing.CSharp.Xunit/Testing.CSharp.Xunit.csproj +++ b/src/Tests/Testing.CSharp.Xunit/Testing.CSharp.Xunit.csproj @@ -5,6 +5,7 @@ $(RoslynatorTestingVersion) Roslynator.Testing.CSharp.Xunit Roslynator.Testing.CSharp.Xunit + enable diff --git a/src/Tests/Testing.CSharp.Xunit/Testing/CSharp/Xunit/XunitAssert.cs b/src/Tests/Testing.CSharp.Xunit/Testing/CSharp/Xunit/XunitAssert.cs index 0496bb8c8e..52d32c1494 100644 --- a/src/Tests/Testing.CSharp.Xunit/Testing/CSharp/Xunit/XunitAssert.cs +++ b/src/Tests/Testing.CSharp.Xunit/Testing/CSharp/Xunit/XunitAssert.cs @@ -15,4 +15,14 @@ public void True(bool condition, string userMessage) { global::Xunit.Assert.True(condition, userMessage); } + + public void Null(object? value) + { + global::Xunit.Assert.Null(value); + } + + public void NotNull(object? value) + { + global::Xunit.Assert.NotNull(value); + } } diff --git a/src/Tests/Testing.CSharp/Testing.CSharp.csproj b/src/Tests/Testing.CSharp/Testing.CSharp.csproj index 4f27f24950..72de147317 100644 --- a/src/Tests/Testing.CSharp/Testing.CSharp.csproj +++ b/src/Tests/Testing.CSharp/Testing.CSharp.csproj @@ -5,6 +5,7 @@ $(RoslynatorTestingVersion) Roslynator.Testing.CSharp Roslynator.Testing.CSharp + enable diff --git a/src/Tests/Testing.CSharp/Testing/CSharp/CSharpTestOptions.cs b/src/Tests/Testing.CSharp/Testing/CSharp/CSharpTestOptions.cs index 81aca55a73..b0c6ea0c1d 100644 --- a/src/Tests/Testing.CSharp/Testing/CSharp/CSharpTestOptions.cs +++ b/src/Tests/Testing.CSharp/Testing/CSharp/CSharpTestOptions.cs @@ -26,12 +26,12 @@ public sealed class CSharpTestOptions : TestOptions /// /// public CSharpTestOptions( - CSharpCompilationOptions compilationOptions = null, - CSharpParseOptions parseOptions = null, - IEnumerable metadataReferences = null, - IEnumerable allowedCompilerDiagnosticIds = null, + CSharpCompilationOptions? compilationOptions = null, + CSharpParseOptions? parseOptions = null, + IEnumerable? metadataReferences = null, + IEnumerable? allowedCompilerDiagnosticIds = null, DiagnosticSeverity allowedCompilerDiagnosticSeverity = DiagnosticSeverity.Info, - IEnumerable> configOptions = null) + IEnumerable>? configOptions = null) : base(metadataReferences, allowedCompilerDiagnosticIds, allowedCompilerDiagnosticSeverity, configOptions) { CompilationOptions = compilationOptions ?? new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary); diff --git a/src/Tests/Testing.Common/Extensions/TestExtensions.cs b/src/Tests/Testing.Common/Extensions/TestExtensions.cs index ec70cea5b5..920d276fd4 100644 --- a/src/Tests/Testing.Common/Extensions/TestExtensions.cs +++ b/src/Tests/Testing.Common/Extensions/TestExtensions.cs @@ -13,7 +13,7 @@ namespace Roslynator; internal static class TestExtensions { - public static async Task GetSyntaxRootAsync( + public static async Task GetSyntaxRootAsync( this Document document, bool simplify, bool format, @@ -22,10 +22,13 @@ public static async Task GetSyntaxRootAsync( if (simplify) document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, cancellationToken: cancellationToken); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken); - if (format) + if (root is not null + && format) + { root = Formatter.Format(root, Formatter.Annotation, document.Project.Solution.Workspace, cancellationToken: cancellationToken); + } return root; } diff --git a/src/Tests/Testing.Common/RuntimeMetadataReference.cs b/src/Tests/Testing.Common/RuntimeMetadataReference.cs index 1b2f6513cd..b724785f9f 100644 --- a/src/Tests/Testing.Common/RuntimeMetadataReference.cs +++ b/src/Tests/Testing.Common/RuntimeMetadataReference.cs @@ -14,8 +14,8 @@ internal static class RuntimeMetadataReference { internal static readonly MetadataReference CorLibReference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location); - private static ImmutableDictionary _trustedPlatformAssemblyMap; - private static ImmutableDictionary _metadataReferences; + private static ImmutableDictionary? _trustedPlatformAssemblyMap; + private static ImmutableDictionary? _metadataReferences; internal static ImmutableDictionary TrustedPlatformAssemblyMap { diff --git a/src/Tests/Testing.Common/Testing.Common.csproj b/src/Tests/Testing.Common/Testing.Common.csproj index 46ca863b96..cb900665a0 100644 --- a/src/Tests/Testing.Common/Testing.Common.csproj +++ b/src/Tests/Testing.Common/Testing.Common.csproj @@ -5,6 +5,7 @@ $(RoslynatorTestingVersion) Roslynator.Testing.Common Roslynator.Testing + enable diff --git a/src/Tests/Testing.Common/Testing/AdditionalFile.cs b/src/Tests/Testing.Common/Testing/AdditionalFile.cs index 4f5b278472..352ce641cf 100644 --- a/src/Tests/Testing.Common/Testing/AdditionalFile.cs +++ b/src/Tests/Testing.Common/Testing/AdditionalFile.cs @@ -19,7 +19,7 @@ public readonly struct AdditionalFile /// /// /// - public AdditionalFile(string source, string expectedSource = null) + public AdditionalFile(string source, string? expectedSource = null) { Source = source ?? throw new ArgumentNullException(nameof(source)); ExpectedSource = expectedSource; @@ -33,7 +33,7 @@ public AdditionalFile(string source, string expectedSource = null) /// /// Gets expected source code. /// - public string ExpectedSource { get; } + public string? ExpectedSource { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => Source; diff --git a/src/Tests/Testing.Common/Testing/CodeVerifier.cs b/src/Tests/Testing.Common/Testing/CodeVerifier.cs index 7130442ab6..238a2c129e 100644 --- a/src/Tests/Testing.Common/Testing/CodeVerifier.cs +++ b/src/Tests/Testing.Common/Testing/CodeVerifier.cs @@ -57,7 +57,7 @@ internal void Fail(string userMessage, IEnumerable diagnostics) Fail(userMessage + $"{NewLine}{NewLine}Diagnostics:{NewLine}{s}{NewLine}"); } - internal void Fail(string userMessage, IEnumerable codeActions) + internal void Fail(string userMessage, IEnumerable? codeActions) { var s = ""; @@ -128,11 +128,15 @@ internal async Task VerifyAdditionalDocumentsAsync( { foreach (ExpectedDocument expectedDocument in expectedDocuments) { - Document document = project.GetDocument(expectedDocument.Id); + Document? document = project.GetDocument(expectedDocument.Id); - SyntaxNode root = await document.GetSyntaxRootAsync(simplify: true, format: true, cancellationToken); + Assert.NotNull(document); - string actual = root.ToFullString(); + SyntaxNode? root = await document!.GetSyntaxRootAsync(simplify: true, format: true, cancellationToken); + + Assert.NotNull(root); + + string actual = root!.ToFullString(); Assert.Equal(expectedDocument.Text, actual); } @@ -141,18 +145,22 @@ internal async Task VerifyAdditionalDocumentsAsync( internal async Task VerifyAndApplyCodeActionAsync( Document document, CodeAction codeAction, - string title) + string? title) { if (title is not null) Assert.Equal(title, codeAction.Title); ImmutableArray operations = await codeAction.GetOperationsAsync(CancellationToken.None); - return operations + Document? newDocument = operations .OfType() .Single() .ChangedSolution .GetDocument(document.Id); + + Assert.NotNull(newDocument); + + return newDocument!; } internal void VerifySupportedDiagnostics( @@ -182,9 +190,11 @@ internal async Task VerifyExpectedDocument( Document document, CancellationToken cancellationToken) { - SyntaxNode root = await document.GetSyntaxRootAsync(simplify: true, format: true, cancellationToken); + SyntaxNode? root = await document.GetSyntaxRootAsync(simplify: true, format: true, cancellationToken); + + Assert.NotNull(root); - string actual = root.ToFullString(); + string actual = root!.ToFullString(); Assert.Equal(expected.Source, actual); @@ -248,7 +258,7 @@ private void VerifyAnnotations( if (expectedSpan != actualSpan) { - string message = VerifyLinePositionSpan( + string? message = VerifyLinePositionSpan( expectedSpan.ToLinePositionSpan(source), actualSpan.ToLinePositionSpan(source)); @@ -258,13 +268,13 @@ private void VerifyAnnotations( } } - internal static string VerifyLinePositionSpan(LinePositionSpan expected, LinePositionSpan actual) + internal static string? VerifyLinePositionSpan(LinePositionSpan expected, LinePositionSpan actual) { return VerifyLinePosition(expected.Start, actual.Start, "start") ?? VerifyLinePosition(expected.End, actual.End, "end"); } - private static string VerifyLinePosition( + private static string? VerifyLinePosition( LinePosition expected, LinePosition actual, string startOrEnd) @@ -285,7 +295,7 @@ private static string VerifyLinePosition( } internal static (Document document, ImmutableArray expectedDocuments) - CreateDocument(Solution solution, string source, ImmutableArray additionalFiles, TestOptions options, DiagnosticDescriptor descriptor = null) + CreateDocument(Solution solution, string source, ImmutableArray additionalFiles, TestOptions options, DiagnosticDescriptor? descriptor = null) { const string DefaultProjectName = "TestProject"; @@ -303,7 +313,7 @@ internal static (Document document, ImmutableArray expectedDoc Project project = solution .AddProject(projectInfo) - .GetProject(projectId); + .GetProject(projectId)!; string directoryPath = (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) ? "z:" @@ -333,7 +343,7 @@ internal static (Document document, ImmutableArray expectedDoc if (descriptor is not null) { - CompilationOptions newCompilationOptions = project.CompilationOptions.EnsureDiagnosticEnabled(descriptor); + CompilationOptions newCompilationOptions = project.CompilationOptions!.EnsureDiagnosticEnabled(descriptor); project = project.WithCompilationOptions(newCompilationOptions); } @@ -343,7 +353,7 @@ internal static (Document document, ImmutableArray expectedDoc SourceText.From(source), filePath: Path.Combine(directoryPath, options.DocumentName)); - ImmutableArray.Builder expectedDocuments = null; + ImmutableArray.Builder? expectedDocuments = null; if (!additionalFiles.IsEmpty) { @@ -359,7 +369,7 @@ internal static (Document document, ImmutableArray expectedDoc SourceText.From(additionalFiles[i].Source), filePath: Path.Combine(directoryPath, documentName)); - string expectedSource = additionalFiles[i].ExpectedSource; + string? expectedSource = additionalFiles[i].ExpectedSource; if (expectedSource is not null) expectedDocuments.Add(new ExpectedDocument(additionalDocument.Id, expectedSource)); @@ -367,7 +377,7 @@ internal static (Document document, ImmutableArray expectedDoc project = additionalDocument.Project; } - document = project.GetDocument(document.Id); + document = project.GetDocument(document.Id)!; } return (document, expectedDocuments?.ToImmutableArray() ?? ImmutableArray.Empty); diff --git a/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixTestData.cs b/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixTestData.cs index b4b4269f09..b2e6f7718c 100644 --- a/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixTestData.cs +++ b/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixTestData.cs @@ -23,8 +23,8 @@ public sealed class CompilerDiagnosticFixTestData public CompilerDiagnosticFixTestData( string diagnosticId, string source, - IEnumerable additionalFiles = null, - string equivalenceKey = null) + IEnumerable? additionalFiles = null, + string? equivalenceKey = null) { DiagnosticId = diagnosticId ?? throw new ArgumentNullException(nameof(diagnosticId)); Source = source ?? throw new ArgumentNullException(nameof(source)); @@ -59,7 +59,7 @@ internal CompilerDiagnosticFixTestData(CompilerDiagnosticFixTestData other) /// /// Gets code action's equivalence key. /// - public string EquivalenceKey { get; } + public string? EquivalenceKey { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => $"{DiagnosticId} {Source}"; diff --git a/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixVerifier.cs b/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixVerifier.cs index cefadef0f4..96295ba2bf 100644 --- a/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixVerifier.cs +++ b/src/Tests/Testing.Common/Testing/CompilerDiagnosticFixVerifier.cs @@ -32,7 +32,7 @@ internal CompilerDiagnosticFixVerifier(IAssert assert) : base(assert) public async Task VerifyFixAsync( CompilerDiagnosticFixTestData data, ExpectedTestState expected, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -55,7 +55,7 @@ public async Task VerifyFixAsync( Project project = document.Project; - document = project.GetDocument(document.Id); + document = project.GetDocument(document.Id)!; ImmutableArray previousDiagnostics = ImmutableArray.Empty; @@ -65,7 +65,7 @@ public async Task VerifyFixAsync( { cancellationToken.ThrowIfCancellationRequested(); - Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken); + Compilation compilation = (await document.Project.GetCompilationAsync(cancellationToken))!; ImmutableArray diagnostics = compilation.GetDiagnostics(cancellationToken: cancellationToken); @@ -85,7 +85,7 @@ public async Task VerifyFixAsync( if (DiagnosticDeepEqualityComparer.Equals(diagnostics, previousDiagnostics)) Fail("Same diagnostics returned before and after the fix was applied.", diagnostics); - Diagnostic diagnostic = FindDiagnosticToFix(diagnostics); + Diagnostic? diagnostic = FindDiagnosticToFix(diagnostics); if (diagnostic is null) { @@ -95,8 +95,8 @@ public async Task VerifyFixAsync( break; } - CodeAction action = null; - List candidateActions = null; + CodeAction? action = null; + List? candidateActions = null; var context = new CodeFixContext( document, @@ -126,7 +126,7 @@ public async Task VerifyFixAsync( fixRegistered = true; - document = await VerifyAndApplyCodeActionAsync(document, action, expected.CodeActionTitle); + document = await VerifyAndApplyCodeActionAsync(document, action!, expected.CodeActionTitle); previousDiagnostics = diagnostics; } @@ -137,9 +137,9 @@ public async Task VerifyFixAsync( await VerifyAdditionalDocumentsAsync(document.Project, expectedDocuments, cancellationToken); } - Diagnostic FindDiagnosticToFix(ImmutableArray diagnostics) + Diagnostic? FindDiagnosticToFix(ImmutableArray diagnostics) { - Diagnostic match = null; + Diagnostic? match = null; foreach (Diagnostic diagnostic in diagnostics) { @@ -165,7 +165,7 @@ Diagnostic FindDiagnosticToFix(ImmutableArray diagnostics) /// public async Task VerifyNoFixAsync( CompilerDiagnosticFixTestData data, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -182,7 +182,7 @@ public async Task VerifyNoFixAsync( { (Document document, ImmutableArray _) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options); - Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken); + Compilation compilation = (await document.Project.GetCompilationAsync(cancellationToken))!; foreach (Diagnostic diagnostic in compilation.GetDiagnostics(cancellationToken: cancellationToken)) { diff --git a/src/Tests/Testing.Common/Testing/DiagnosticTestData.cs b/src/Tests/Testing.Common/Testing/DiagnosticTestData.cs index 2d70370f5c..bcce15c84a 100644 --- a/src/Tests/Testing.Common/Testing/DiagnosticTestData.cs +++ b/src/Tests/Testing.Common/Testing/DiagnosticTestData.cs @@ -32,11 +32,11 @@ public DiagnosticTestData( DiagnosticDescriptor descriptor, string source, IEnumerable spans, - IEnumerable additionalSpans = null, - IEnumerable additionalFiles = null, - string diagnosticMessage = null, - IFormatProvider formatProvider = null, - string equivalenceKey = null, + IEnumerable? additionalSpans = null, + IEnumerable? additionalFiles = null, + string? diagnosticMessage = null, + IFormatProvider? formatProvider = null, + string? equivalenceKey = null, bool alwaysVerifyAdditionalLocations = false) { Descriptor = descriptor ?? throw new ArgumentNullException(nameof(descriptor)); @@ -98,17 +98,17 @@ internal DiagnosticTestData(DiagnosticTestData other) /// /// Gets diagnostic's message /// - public string DiagnosticMessage { get; } + public string? DiagnosticMessage { get; } /// /// Gets format provider to be used to format diagnostic's message. /// - public IFormatProvider FormatProvider { get; } + public IFormatProvider? FormatProvider { get; } /// /// Gets code action's equivalence key. /// - public string EquivalenceKey { get; } + public string? EquivalenceKey { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => $"{Descriptor.Id} {Source}"; diff --git a/src/Tests/Testing.Common/Testing/DiagnosticVerifier.cs b/src/Tests/Testing.Common/Testing/DiagnosticVerifier.cs index f082723aed..1c1ee4b141 100644 --- a/src/Tests/Testing.Common/Testing/DiagnosticVerifier.cs +++ b/src/Tests/Testing.Common/Testing/DiagnosticVerifier.cs @@ -33,7 +33,7 @@ internal DiagnosticVerifier(IAssert assert) : base(assert) /// public async Task VerifyDiagnosticAsync( DiagnosticTestData data, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -50,13 +50,13 @@ public async Task VerifyDiagnosticAsync( { (Document document, ImmutableArray expectedDocuments) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options, data.Descriptor); - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken); + SyntaxTree tree = (await document.GetSyntaxTreeAsync(cancellationToken))!; ImmutableArray expectedDiagnostics = data.GetDiagnostics(tree); VerifySupportedDiagnostics(analyzer, expectedDiagnostics); - Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken); + Compilation compilation = (await document.Project.GetCompilationAsync(cancellationToken))!; ImmutableArray compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); @@ -108,7 +108,7 @@ static IEnumerable FilterDiagnostics( /// public async Task VerifyNoDiagnosticAsync( DiagnosticTestData data, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -124,13 +124,13 @@ public async Task VerifyNoDiagnosticAsync( { (Document document, ImmutableArray _) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options, data.Descriptor); - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken); + SyntaxTree tree = (await document.GetSyntaxTreeAsync(cancellationToken))!; ImmutableArray expectedDiagnostics = data.GetDiagnostics(tree); VerifySupportedDiagnostics(analyzer, expectedDiagnostics); - Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken); + Compilation compilation = (await document.Project.GetCompilationAsync(cancellationToken))!; ImmutableArray compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); @@ -157,7 +157,7 @@ public async Task VerifyNoDiagnosticAsync( public async Task VerifyDiagnosticAndFixAsync( DiagnosticTestData data, ExpectedTestState expected, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { await VerifyDiagnosticAsync(data, options, cancellationToken); @@ -172,7 +172,7 @@ public async Task VerifyDiagnosticAndFixAsync( /// public async Task VerifyDiagnosticAndNoFixAsync( DiagnosticTestData data, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { await VerifyDiagnosticAsync(data, options, cancellationToken); @@ -182,7 +182,7 @@ public async Task VerifyDiagnosticAndNoFixAsync( private async Task VerifyFixAsync( DiagnosticTestData data, ExpectedTestState expected, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -206,7 +206,7 @@ private async Task VerifyFixAsync( Project project = document.Project; - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken); + SyntaxTree tree = (await document.GetSyntaxTreeAsync(cancellationToken))!; ImmutableArray expectedDiagnostics = data.GetDiagnostics(tree); @@ -215,7 +215,7 @@ private async Task VerifyFixAsync( VerifySupportedDiagnostics(analyzer, expectedDiagnostics); - Compilation compilation = await project.GetCompilationAsync(cancellationToken); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken))!; ImmutableArray compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); @@ -249,9 +249,9 @@ private async Task VerifyFixAsync( if (DiagnosticDeepEqualityComparer.Equals(diagnostics, previousPreviousDiagnostics)) Fail("Infinite loop detected: Reported diagnostics have been previously fixed.", diagnostics); - Diagnostic diagnostic = FindDiagnosticToFix(diagnostics, expectedDiagnostics); + Diagnostic? diagnostic = FindDiagnosticToFix(diagnostics, expectedDiagnostics); - static Diagnostic FindDiagnosticToFix( + static Diagnostic? FindDiagnosticToFix( ImmutableArray diagnostics, ImmutableArray expectedDiagnostics) { @@ -275,8 +275,8 @@ static Diagnostic FindDiagnosticToFix( break; } - CodeAction action = null; - List candidateActions = null; + CodeAction? action = null; + List? candidateActions = null; var context = new CodeFixContext( document, @@ -306,8 +306,8 @@ static Diagnostic FindDiagnosticToFix( fixRegistered = true; - document = await VerifyAndApplyCodeActionAsync(document, action, expected.CodeActionTitle); - compilation = await document.Project.GetCompilationAsync(cancellationToken); + document = await VerifyAndApplyCodeActionAsync(document, action!, expected.CodeActionTitle); + compilation = (await document.Project.GetCompilationAsync(cancellationToken))!; ImmutableArray newCompilerDiagnostics = compilation.GetDiagnostics(cancellationToken); @@ -327,7 +327,7 @@ static Diagnostic FindDiagnosticToFix( private async Task VerifyNoFixAsync( DiagnosticTestData data, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -347,9 +347,9 @@ private async Task VerifyNoFixAsync( { (Document document, ImmutableArray _) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options, data.Descriptor); - Compilation compilation = await document.Project.GetCompilationAsync(cancellationToken); + Compilation compilation = (await document.Project.GetCompilationAsync(cancellationToken))!; - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken); + SyntaxTree tree = (await document.GetSyntaxTreeAsync(cancellationToken))!; ImmutableArray expectedDiagnostics = data.GetDiagnostics(tree); @@ -462,8 +462,8 @@ void ReportMismatch(IEnumerable actualDiagnostics, int actualCount, private void VerifyDiagnostic( Diagnostic expectedDiagnostic, Diagnostic actualDiagnostic, - string message, - IFormatProvider formatProvider, + string? message, + IFormatProvider? formatProvider, bool verifyAdditionalLocations = false) { if (expectedDiagnostic.Id != actualDiagnostic.Id) @@ -525,7 +525,7 @@ void VerifyFileLinePositionSpan( if (expected.Path != actual.Path) Fail($"Diagnostic expected to be in file \"{expected.Path}\", actual: \"{actual.Path}\"{GetMessage()}"); - string message = VerifyLinePositionSpan(expected.Span, actual.Span); + string? message = VerifyLinePositionSpan(expected.Span, actual.Span); if (message is not null) Fail($"Diagnostic{message}{GetMessage()}"); @@ -541,7 +541,7 @@ private Task> GetAnalyzerDiagnosticsAsync( Compilation compilation, DiagnosticAnalyzer analyzer, AnalyzerOptions options, - IComparer comparer = null, + IComparer? comparer = null, CancellationToken cancellationToken = default) { return GetAnalyzerDiagnosticsAsync( @@ -556,11 +556,11 @@ private async Task> GetAnalyzerDiagnosticsAsync( Compilation compilation, ImmutableArray analyzers, AnalyzerOptions options, - IComparer comparer = null, + IComparer? comparer = null, CancellationToken cancellationToken = default) { - Exception exception = null; - DiagnosticAnalyzer analyzer = null; + Exception? exception = null; + DiagnosticAnalyzer? analyzer = null; var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( options: options, @@ -579,7 +579,13 @@ private async Task> GetAnalyzerDiagnosticsAsync( ImmutableArray diagnostics = await compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync(cancellationToken); if (exception is not null) - Fail($"An exception occurred in analyzer '{analyzer.GetType()}'.{Environment.NewLine}{exception}"); + { + string message = (analyzer is not null) + ? $"An exception occurred in analyzer '{analyzer.GetType()}'.{Environment.NewLine}{exception}" + : exception.ToString(); + + Fail(message); + } return (comparer is not null) ? diagnostics.Sort(comparer) diff --git a/src/Tests/Testing.Common/Testing/ExpectedTestState.cs b/src/Tests/Testing.Common/Testing/ExpectedTestState.cs index 45ab581ac9..2ada90b115 100644 --- a/src/Tests/Testing.Common/Testing/ExpectedTestState.cs +++ b/src/Tests/Testing.Common/Testing/ExpectedTestState.cs @@ -17,7 +17,7 @@ namespace Roslynator.Testing; [DebuggerDisplay("{DebuggerDisplay,nq}")] public sealed class ExpectedTestState { - private ImmutableDictionary> _annotationsByKind; + private ImmutableDictionary>? _annotationsByKind; /// /// Initializes a new instance of . @@ -28,9 +28,9 @@ public sealed class ExpectedTestState /// public ExpectedTestState( string source, - string codeActionTitle = null, - IEnumerable<(string, TextSpan)> annotations = null, - IEnumerable alwaysVerifyAnnotations = null) + string? codeActionTitle = null, + IEnumerable<(string, TextSpan)>? annotations = null, + IEnumerable? alwaysVerifyAnnotations = null) { Source = source ?? throw new ArgumentNullException(nameof(source)); CodeActionTitle = codeActionTitle; @@ -46,7 +46,7 @@ public ExpectedTestState( /// /// Gets expected code action's title. /// - public string CodeActionTitle { get; } + public string? CodeActionTitle { get; } /// /// Gets expected annotations. diff --git a/src/Tests/Testing.Common/Testing/IAssert.cs b/src/Tests/Testing.Common/Testing/IAssert.cs index b9225ccfca..ba40229386 100644 --- a/src/Tests/Testing.Common/Testing/IAssert.cs +++ b/src/Tests/Testing.Common/Testing/IAssert.cs @@ -17,4 +17,14 @@ internal interface IAssert /// /// void True(bool condition, string userMessage); + + /// + /// Throws an error if is not null. + /// + void Null(object? value); + + /// + /// Throws an error if is null. + /// + void NotNull(object? value); } diff --git a/src/Tests/Testing.Common/Testing/RefactoringTestData.cs b/src/Tests/Testing.Common/Testing/RefactoringTestData.cs index 5001fbbbea..47dc839db5 100644 --- a/src/Tests/Testing.Common/Testing/RefactoringTestData.cs +++ b/src/Tests/Testing.Common/Testing/RefactoringTestData.cs @@ -24,8 +24,8 @@ public sealed class RefactoringTestData public RefactoringTestData( string source, IEnumerable spans, - IEnumerable additionalFiles = null, - string equivalenceKey = null) + IEnumerable? additionalFiles = null, + string? equivalenceKey = null) { Source = source ?? throw new ArgumentNullException(nameof(source)); Spans = spans?.ToImmutableArray() ?? ImmutableArray.Empty; @@ -51,7 +51,7 @@ public RefactoringTestData( /// /// Gets code action's equivalence key. /// - public string EquivalenceKey { get; } + public string? EquivalenceKey { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => Source; diff --git a/src/Tests/Testing.Common/Testing/RefactoringVerifier.cs b/src/Tests/Testing.Common/Testing/RefactoringVerifier.cs index 94855ec8d1..761d170681 100644 --- a/src/Tests/Testing.Common/Testing/RefactoringVerifier.cs +++ b/src/Tests/Testing.Common/Testing/RefactoringVerifier.cs @@ -33,7 +33,7 @@ internal RefactoringVerifier(IAssert assert) : base(assert) public async Task VerifyRefactoringAsync( RefactoringTestData data, ExpectedTestState expected, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -57,14 +57,14 @@ public async Task VerifyRefactoringAsync( { (Document document, ImmutableArray expectedDocuments) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken); + SemanticModel semanticModel = (await document.GetSemanticModelAsync(cancellationToken))!; ImmutableArray compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); VerifyCompilerDiagnostics(compilerDiagnostics, options); - CodeAction action = null; - List candidateActions = null; + CodeAction? action = null; + List? candidateActions = null; var context = new CodeRefactoringContext( document, @@ -91,8 +91,8 @@ public async Task VerifyRefactoringAsync( if (action is null) Fail("No code refactoring has been registered.", candidateActions); - document = await VerifyAndApplyCodeActionAsync(document, action, expected.CodeActionTitle); - semanticModel = await document.GetSemanticModelAsync(cancellationToken); + document = await VerifyAndApplyCodeActionAsync(document, action!, expected.CodeActionTitle); + semanticModel = (await document.GetSemanticModelAsync(cancellationToken))!; ImmutableArray newCompilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); @@ -115,7 +115,7 @@ public async Task VerifyRefactoringAsync( /// public async Task VerifyNoRefactoringAsync( RefactoringTestData data, - TestOptions options = null, + TestOptions? options = null, CancellationToken cancellationToken = default) { if (data is null) @@ -134,7 +134,7 @@ public async Task VerifyNoRefactoringAsync( { (Document document, ImmutableArray _) = CreateDocument(workspace.CurrentSolution, data.Source, data.AdditionalFiles, options); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken); + SemanticModel semanticModel = (await document.GetSemanticModelAsync(cancellationToken))!; ImmutableArray compilerDiagnostics = semanticModel.GetDiagnostics(cancellationToken: cancellationToken); diff --git a/src/Tests/Testing.Common/Testing/TestCode.cs b/src/Tests/Testing.Common/Testing/TestCode.cs index 9215050415..fd2b651e5d 100644 --- a/src/Tests/Testing.Common/Testing/TestCode.cs +++ b/src/Tests/Testing.Common/Testing/TestCode.cs @@ -19,7 +19,7 @@ internal TestCode(string value, ImmutableArray spans, ImmutableArray spans, ImmutableArray additionalSpans) + internal TestCode(string value, string? expectedValue, ImmutableArray spans, ImmutableArray additionalSpans) { Value = value ?? throw new ArgumentNullException(nameof(value)); ExpectedValue = expectedValue; @@ -36,7 +36,7 @@ internal TestCode(string value, string expectedValue, ImmutableArray s /// /// Gets a source code after a code fix or a refactoring was applied. /// - public string ExpectedValue { get; } + public string? ExpectedValue { get; } /// /// Gets a collection of spans that represent selected text. @@ -76,7 +76,7 @@ public static TestCode Parse(string value) public static TestCode Parse( string value, string replacement1, - string replacement2 = null) + string? replacement2 = null) { if (value is null) throw new ArgumentNullException(nameof(value)); @@ -84,7 +84,7 @@ public static TestCode Parse( if (replacement1 is null) throw new ArgumentNullException(nameof(replacement1)); - (string source, string expected, ImmutableArray spans) = FindSpansAndReplace(value, replacement1, replacement2); + (string source, string? expected, ImmutableArray spans) = FindSpansAndReplace(value, replacement1, replacement2); (string source2, ImmutableArray additionalSpans) = FindAnnotatedSpansAndRemove(source, "a"); diff --git a/src/Tests/Testing.Common/Testing/TestOptions.cs b/src/Tests/Testing.Common/Testing/TestOptions.cs index a6bdbc4c8c..80fcfe08c0 100644 --- a/src/Tests/Testing.Common/Testing/TestOptions.cs +++ b/src/Tests/Testing.Common/Testing/TestOptions.cs @@ -19,10 +19,10 @@ public abstract class TestOptions /// /// internal TestOptions( - IEnumerable metadataReferences = null, - IEnumerable allowedCompilerDiagnosticIds = null, + IEnumerable? metadataReferences = null, + IEnumerable? allowedCompilerDiagnosticIds = null, DiagnosticSeverity allowedCompilerDiagnosticSeverity = DiagnosticSeverity.Info, - IEnumerable> configOptions = null) + IEnumerable>? configOptions = null) { MetadataReferences = metadataReferences?.ToImmutableArray() ?? ImmutableArray.Empty; AllowedCompilerDiagnosticIds = allowedCompilerDiagnosticIds?.ToImmutableArray() ?? ImmutableArray.Empty; diff --git a/src/Tests/Testing.Common/Testing/Text/TextProcessor.cs b/src/Tests/Testing.Common/Testing/Text/TextProcessor.cs index ffc2815d66..d0c4264093 100644 --- a/src/Tests/Testing.Common/Testing/Text/TextProcessor.cs +++ b/src/Tests/Testing.Common/Testing/Text/TextProcessor.cs @@ -29,7 +29,7 @@ public static (string source, ImmutableArray<(string kind, TextSpan span)> annot private static (string source, ImmutableArray<(string kind, TextSpan span)> annotations) FindAnnotatedSpansAndRemoveImpl( string text, - string annotationIdentifier = null) + string? annotationIdentifier = null) { int offset = 0; int lastPos = 0; @@ -41,7 +41,7 @@ private static (string source, ImmutableArray<(string kind, TextSpan span)> anno StringBuilder sb = StringBuilderCache.GetInstance(text.Length); - ImmutableArray<(string, TextSpan)>.Builder annotations = null; + ImmutableArray<(string, TextSpan)>.Builder? annotations = null; do { @@ -80,8 +80,8 @@ public static (string, ImmutableArray) FindSpansAndRemove(string text) var startPending = false; LinePositionInfo start = default; - Stack stack = null; - List spans = null; + Stack? stack = null; + List? spans = null; int lastPos = 0; @@ -225,10 +225,10 @@ void CloseSpan() } } - public static (string source, string expected, ImmutableArray spans) FindSpansAndReplace( + public static (string source, string? expected, ImmutableArray spans) FindSpansAndReplace( string input, string replacement1, - string replacement2 = null) + string? replacement2 = null) { (string source, ImmutableArray spans) = FindSpansAndRemove(input); @@ -238,7 +238,7 @@ public static (string source, string expected, ImmutableArray spans) F if (spans.Length > 1) throw new InvalidOperationException("Text contains more than one span."); - string expected = (replacement2 is not null) + string? expected = (replacement2 is not null) ? source.Remove(spans[0].Start) + replacement2 + source.Substring(spans[0].End) : null; diff --git a/src/Tests/Testing.VisualBasic/Testing.VisualBasic.csproj b/src/Tests/Testing.VisualBasic/Testing.VisualBasic.csproj index 84b064ebe3..d75ba09823 100644 --- a/src/Tests/Testing.VisualBasic/Testing.VisualBasic.csproj +++ b/src/Tests/Testing.VisualBasic/Testing.VisualBasic.csproj @@ -8,6 +8,7 @@ $(RoslynatorTestingVersion) Roslynator.Testing.VisualBasic Roslynator.Testing + enable diff --git a/src/Tests/Testing.VisualBasic/VisualBasic/Testing/VisualBasicTestOptions.cs b/src/Tests/Testing.VisualBasic/VisualBasic/Testing/VisualBasicTestOptions.cs index cb890275a0..f8912b7dcd 100644 --- a/src/Tests/Testing.VisualBasic/VisualBasic/Testing/VisualBasicTestOptions.cs +++ b/src/Tests/Testing.VisualBasic/VisualBasic/Testing/VisualBasicTestOptions.cs @@ -12,12 +12,12 @@ namespace Roslynator.Testing; public sealed class VisualBasicTestOptions : TestOptions { public VisualBasicTestOptions( - VisualBasicCompilationOptions compilationOptions = null, - VisualBasicParseOptions parseOptions = null, - IEnumerable metadataReferences = null, - IEnumerable allowedCompilerDiagnosticIds = null, + VisualBasicCompilationOptions? compilationOptions = null, + VisualBasicParseOptions? parseOptions = null, + IEnumerable? metadataReferences = null, + IEnumerable? allowedCompilerDiagnosticIds = null, DiagnosticSeverity allowedCompilerDiagnosticSeverity = DiagnosticSeverity.Info, - IEnumerable> configOptions = null) + IEnumerable>? configOptions = null) : base(metadataReferences, allowedCompilerDiagnosticIds, allowedCompilerDiagnosticSeverity, configOptions) { CompilationOptions = compilationOptions ?? new VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary); diff --git a/src/Workspaces.Core/AnalyzerAssembly.cs b/src/Workspaces.Core/AnalyzerAssembly.cs index b54c3eb237..3e1e4062fa 100644 --- a/src/Workspaces.Core/AnalyzerAssembly.cs +++ b/src/Workspaces.Core/AnalyzerAssembly.cs @@ -63,14 +63,14 @@ public static AnalyzerAssembly Load( Assembly analyzerAssembly, bool loadAnalyzers = true, bool loadFixers = true, - string language = null) + string? language = null) { Debug.Assert(loadAnalyzers || loadFixers); - Dictionary.Builder> analyzers = null; - Dictionary.Builder> fixers = null; + Dictionary.Builder>? analyzers = null; + Dictionary.Builder>? fixers = null; - TypeInfo[] types = null; + TypeInfo[]? types = null; try { types = analyzerAssembly.DefinedTypes.ToArray(); @@ -101,7 +101,7 @@ public static AnalyzerAssembly Load( if (attribute is not null) { - DiagnosticAnalyzer analyzer = CreateInstanceAndCatchIfThrows(typeInfo); + DiagnosticAnalyzer? analyzer = CreateInstanceAndCatchIfThrows(typeInfo); if (analyzer is not null) { @@ -130,7 +130,7 @@ public static AnalyzerAssembly Load( if (attribute is not null) { - CodeFixProvider fixer = CreateInstanceAndCatchIfThrows(typeInfo); + CodeFixProvider? fixer = CreateInstanceAndCatchIfThrows(typeInfo); if (fixer is not null) { @@ -159,7 +159,7 @@ public static AnalyzerAssembly Load( fixers?.ToImmutableDictionary(f => f.Key, f => f.Value.ToImmutableArray()) ?? ImmutableDictionary>.Empty); } - private static T CreateInstanceAndCatchIfThrows(TypeInfo typeInfo) + private static T? CreateInstanceAndCatchIfThrows(TypeInfo typeInfo) { try { @@ -184,7 +184,7 @@ public override bool Equals(object obj) return Equals(obj as AnalyzerAssembly); } - public bool Equals(AnalyzerAssembly other) + public bool Equals(AnalyzerAssembly? other) { return other is not null && StringComparer.Ordinal.Equals(FullName, other.FullName); diff --git a/src/Workspaces.Core/AnalyzerLoader.cs b/src/Workspaces.Core/AnalyzerLoader.cs index 3d77c33231..89dd38c142 100644 --- a/src/Workspaces.Core/AnalyzerLoader.cs +++ b/src/Workspaces.Core/AnalyzerLoader.cs @@ -43,7 +43,7 @@ public AnalyzerLoader(IEnumerable defaultAssemblies, CodeAnaly public CodeAnalysisOptions Options { get; } - public event EventHandler AnalyzerAssemblyAdded; + public event EventHandler? AnalyzerAssemblyAdded; protected virtual void OnAnalyzerAssemblyAdded(AnalyzerAssemblyEventArgs e) { diff --git a/src/Workspaces.Core/AttributeInfo.cs b/src/Workspaces.Core/AttributeInfo.cs index d7c490c427..a3567119e6 100644 --- a/src/Workspaces.Core/AttributeInfo.cs +++ b/src/Workspaces.Core/AttributeInfo.cs @@ -19,7 +19,7 @@ public AttributeInfo(ISymbol target, AttributeData attributeData) public AttributeData AttributeData { get; } - public INamedTypeSymbol AttributeClass + public INamedTypeSymbol? AttributeClass { get { return AttributeData?.AttributeClass; } } diff --git a/src/Workspaces.Core/CodeActions/CodeActionData.cs b/src/Workspaces.Core/CodeActions/CodeActionData.cs index cf08a97c9a..b8aa38355a 100644 --- a/src/Workspaces.Core/CodeActions/CodeActionData.cs +++ b/src/Workspaces.Core/CodeActions/CodeActionData.cs @@ -10,7 +10,7 @@ namespace Roslynator.CodeActions; internal readonly struct CodeActionData { - public CodeActionData(string title, string equivalenceKey = null) + public CodeActionData(string title, string? equivalenceKey = null) { Title = title ?? throw new ArgumentNullException(nameof(title)); EquivalenceKey = equivalenceKey; @@ -18,7 +18,7 @@ public CodeActionData(string title, string equivalenceKey = null) public string Title { get; } - public string EquivalenceKey { get; } + public string? EquivalenceKey { get; } public bool IsDefault => Title is null; diff --git a/src/Workspaces.Core/CodeAnalysisOptions.cs b/src/Workspaces.Core/CodeAnalysisOptions.cs index d94aab073d..c500ca27e0 100644 --- a/src/Workspaces.Core/CodeAnalysisOptions.cs +++ b/src/Workspaces.Core/CodeAnalysisOptions.cs @@ -11,12 +11,12 @@ namespace Roslynator; internal abstract class CodeAnalysisOptions { internal CodeAnalysisOptions( - FileSystemFilter fileSystemFilter = null, + FileSystemFilter? fileSystemFilter = null, DiagnosticSeverity severityLevel = DiagnosticSeverity.Info, bool ignoreAnalyzerReferences = false, bool concurrentAnalysis = true, - IEnumerable supportedDiagnosticIds = null, - IEnumerable ignoredDiagnosticIds = null) + IEnumerable? supportedDiagnosticIds = null, + IEnumerable? ignoredDiagnosticIds = null) { if (supportedDiagnosticIds?.Any() == true && ignoredDiagnosticIds?.Any() == true) @@ -42,7 +42,7 @@ internal CodeAnalysisOptions( public ImmutableHashSet IgnoredDiagnosticIds { get; } - public FileSystemFilter FileSystemFilter { get; } + public FileSystemFilter? FileSystemFilter { get; } internal bool IsSupportedDiagnosticId(string diagnosticId) { diff --git a/src/Workspaces.Core/CodeFixes/CodeFixer.cs b/src/Workspaces.Core/CodeFixes/CodeFixer.cs index 630a690c14..ec838dde07 100644 --- a/src/Workspaces.Core/CodeFixes/CodeFixer.cs +++ b/src/Workspaces.Core/CodeFixes/CodeFixer.cs @@ -25,8 +25,8 @@ internal class CodeFixer public CodeFixer( Solution solution, AnalyzerLoader analyzerLoader, - IFormatProvider formatProvider = null, - CodeFixerOptions options = null) + IFormatProvider? formatProvider = null, + CodeFixerOptions? options = null) { _analyzerLoader = analyzerLoader; @@ -39,7 +39,7 @@ public CodeFixer( public CodeFixerOptions Options { get; } - public IFormatProvider FormatProvider { get; } + public IFormatProvider? FormatProvider { get; } private Solution CurrentSolution => Workspace.CurrentSolution; @@ -60,7 +60,7 @@ public async Task> FixSolutionAsync(Func FixProjectAsync(Project project, Cancellatio FixResult fixResult = await FixProjectAsync(project, analyzers, fixers, cancellationToken).ConfigureAwait(false); - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + if (!project.SupportsCompilation) + { + WriteLine($" Project '{project.Name}' does not support compilation", Verbosity.Normal); + return ProjectFixResult.Skipped; + } + + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; Dictionary> fixersById = fixers .SelectMany(f => f.FixableDiagnosticIds.Select(id => (id, fixer: f))) @@ -130,12 +136,12 @@ public async Task FixProjectAsync(Project project, Cancellatio int numberOfAddedFileBanners = 0; if (Options.FileBannerLines.Any()) - numberOfAddedFileBanners = await AddFileBannerAsync(CurrentSolution.GetProject(project.Id), Options.FileBannerLines, cancellationToken).ConfigureAwait(false); + numberOfAddedFileBanners = await AddFileBannerAsync(CurrentSolution.GetProject(project.Id)!, Options.FileBannerLines, cancellationToken).ConfigureAwait(false); ImmutableArray formattedDocuments = ImmutableArray.Empty; if (Options.Format) - formattedDocuments = await FormatProjectAsync(CurrentSolution.GetProject(project.Id), cancellationToken).ConfigureAwait(false); + formattedDocuments = await FormatProjectAsync(CurrentSolution.GetProject(project.Id)!, cancellationToken).ConfigureAwait(false); var result = new ProjectFixResult( kind: fixResult.Kind, @@ -201,11 +207,11 @@ private async Task FixProjectAsync( { cancellationToken.ThrowIfCancellationRequested(); - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; WriteLine($" Compile '{project.Name}'{((iterationCount > 1) ? $" iteration {iterationCount}" : "")}", Verbosity.Normal); - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; ImmutableArray compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); @@ -258,7 +264,7 @@ private async Task FixProjectAsync( ? default : analyzersById[diagnosticId], fixersById[diagnosticId], - CurrentSolution.GetProject(project.Id), + CurrentSolution.GetProject(project.Id)!, cancellationToken) .ConfigureAwait(false); @@ -329,7 +335,7 @@ private async Task FixDiagnosticsAsync( while (true) { - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; ImmutableArray compilerDiagnostics = compilation.GetDiagnostics(cancellationToken); @@ -389,7 +395,7 @@ private async Task FixDiagnosticsAsync( if (Options.FixAllScope == FixAllScope.Document) { - foreach (IGrouping grouping in diagnostics + foreach (IGrouping grouping in diagnostics .GroupBy(f => f.Location.SourceTree) .OrderByDescending(f => f.Count())) { @@ -424,7 +430,7 @@ private async Task FixDiagnosticsAsync( previousDiagnosticsToFix = diagnostics; - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; } fixedDiagnostics.AddRange(previousDiagnosticsToFix.Except(diagnostics, DiagnosticDeepEqualityComparer.Instance)); @@ -456,7 +462,7 @@ private async Task FixDiagnosticsAsync( if (diagnosticFix.FixProvider2 is not null) return DiagnosticFixKind.MultipleFixers; - CodeAction fix = diagnosticFix.CodeAction; + CodeAction? fix = diagnosticFix.CodeAction; if (fix is not null) { @@ -466,7 +472,7 @@ private async Task FixDiagnosticsAsync( { operations[0].Apply(Workspace, cancellationToken); - return (diagnostics.Length != 1 && diagnosticFix.FixProvider.GetFixAllProvider() is null) + return (diagnostics.Length != 1 && diagnosticFix.FixProvider!.GetFixAllProvider() is null) ? DiagnosticFixKind.PartiallyFixed : DiagnosticFixKind.Success; } @@ -535,7 +541,7 @@ private async Task> GetDiagnosticsAsync( if (diagnostic.IsEffective(Options, compilation.Options) && analyzersById.ContainsKey(diagnostic.Id)) { - SyntaxTree tree = diagnostic.Location.SourceTree; + SyntaxTree? tree = diagnostic.Location.SourceTree; if (tree is null || Options.FileSystemFilter?.IsMatch(tree.FilePath) != false) { @@ -560,14 +566,20 @@ private async Task AddFileBannerAsync( foreach (DocumentId documentId in project.DocumentIds) { - Document document = project.GetDocument(documentId); + Document document = project.GetDocument(documentId)!; if (GeneratedCodeUtility.IsGeneratedCodeFile(document.FilePath)) continue; - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + continue; + + ISyntaxFactsService? syntaxFacts = MefWorkspaceServices.Default.GetService(project.Language); - ISyntaxFactsService syntaxFacts = MefWorkspaceServices.Default.GetService(project.Language); + if (syntaxFacts is null) + continue; if (syntaxFacts.BeginsWithAutoGeneratedComment(root)) continue; @@ -586,7 +598,7 @@ private async Task AddFileBannerAsync( Document newDocument = document.WithSyntaxRoot(newRoot); - WriteLine($" Add banner to '{PathUtilities.TrimStart(document.FilePath, solutionDirectory)}'", ConsoleColors.DarkGray, Verbosity.Detailed); + WriteLine($" Add banner to '{PathUtilities.TrimStart(document.FilePath!, solutionDirectory)}'", ConsoleColors.DarkGray, Verbosity.Detailed); project = newDocument.Project; @@ -607,7 +619,10 @@ private async Task> FormatProjectAsync(Project projec { WriteLine($" Format '{project.Name}'", Verbosity.Normal); - ISyntaxFactsService syntaxFacts = MefWorkspaceServices.Default.GetService(project.Language); + ISyntaxFactsService? syntaxFacts = MefWorkspaceServices.Default.GetService(project.Language); + + if (syntaxFacts is null) + return ImmutableArray.Empty; Project newProject = await CodeFormatter.FormatProjectAsync(project, syntaxFacts, cancellationToken).ConfigureAwait(false); @@ -651,9 +666,9 @@ private class FixResult internal FixResult( ProjectFixKind kind, - IEnumerable fixedDiagnostics = default, - IEnumerable unfixedDiagnostics = default, - IEnumerable unfixableDiagnostics = default, + IEnumerable? fixedDiagnostics = default, + IEnumerable? unfixedDiagnostics = default, + IEnumerable? unfixableDiagnostics = default, int numberOfFormattedDocuments = -1, int numberOfAddedFileBanners = -1) { diff --git a/src/Workspaces.Core/CodeFixes/CodeFixerOptions.cs b/src/Workspaces.Core/CodeFixes/CodeFixerOptions.cs index 4e8cbbe697..d089b06ba1 100644 --- a/src/Workspaces.Core/CodeFixes/CodeFixerOptions.cs +++ b/src/Workspaces.Core/CodeFixes/CodeFixerOptions.cs @@ -17,19 +17,19 @@ internal class CodeFixerOptions : CodeAnalysisOptions public static CodeFixerOptions Default { get; } = new(); public CodeFixerOptions( - FileSystemFilter fileSystemFilter = null, + FileSystemFilter? fileSystemFilter = null, DiagnosticSeverity severityLevel = DiagnosticSeverity.Info, bool ignoreCompilerErrors = false, bool ignoreAnalyzerReferences = false, bool concurrentAnalysis = true, - IEnumerable supportedDiagnosticIds = null, - IEnumerable ignoredDiagnosticIds = null, - IEnumerable ignoredCompilerDiagnosticIds = null, - IEnumerable diagnosticIdsFixableOneByOne = null, - IEnumerable> diagnosticFixMap = null, - IEnumerable> diagnosticFixerMap = null, + IEnumerable? supportedDiagnosticIds = null, + IEnumerable? ignoredDiagnosticIds = null, + IEnumerable? ignoredCompilerDiagnosticIds = null, + IEnumerable? diagnosticIdsFixableOneByOne = null, + IEnumerable>? diagnosticFixMap = null, + IEnumerable>? diagnosticFixerMap = null, FixAllScope fixAllScope = FixAllScope.Project, - string fileBanner = null, + string? fileBanner = null, int maxIterations = -1, int batchSize = -1, bool format = false) : base( @@ -79,7 +79,7 @@ public CodeFixerOptions( public HashSet IgnoredCompilerDiagnosticIds { get; } = new(); - public string FileBanner { get; } + public string? FileBanner { get; } public ImmutableArray FileBannerLines { @@ -93,7 +93,7 @@ public ImmutableArray FileBannerLines using (var sr = new StringReader(FileBanner)) { - string line = null; + string? line = null; while ((line = sr.ReadLine()) is not null) { lines.Add(line); diff --git a/src/Workspaces.Core/CodeFixes/DiagnosticFix.cs b/src/Workspaces.Core/CodeFixes/DiagnosticFix.cs index e42b76cd3d..21bb1ad3ea 100644 --- a/src/Workspaces.Core/CodeFixes/DiagnosticFix.cs +++ b/src/Workspaces.Core/CodeFixes/DiagnosticFix.cs @@ -8,7 +8,7 @@ namespace Roslynator.CodeFixes; internal readonly struct DiagnosticFix { - public DiagnosticFix(CodeAction codeAction, Document document, CodeFixProvider fixProvider, CodeFixProvider fixProvider2) + public DiagnosticFix(CodeAction? codeAction, Document? document, CodeFixProvider? fixProvider, CodeFixProvider? fixProvider2) { CodeAction = codeAction; Document = document; @@ -16,11 +16,11 @@ public DiagnosticFix(CodeAction codeAction, Document document, CodeFixProvider f FixProvider2 = fixProvider2; } - public CodeAction CodeAction { get; } + public CodeAction? CodeAction { get; } - public Document Document { get; } + public Document? Document { get; } - public CodeFixProvider FixProvider { get; } + public CodeFixProvider? FixProvider { get; } - public CodeFixProvider FixProvider2 { get; } + public CodeFixProvider? FixProvider2 { get; } } diff --git a/src/Workspaces.Core/CodeFixes/DiagnosticFixProvider.cs b/src/Workspaces.Core/CodeFixes/DiagnosticFixProvider.cs index 5377fe4c19..34de6cc04d 100644 --- a/src/Workspaces.Core/CodeFixes/DiagnosticFixProvider.cs +++ b/src/Workspaces.Core/CodeFixes/DiagnosticFixProvider.cs @@ -23,18 +23,18 @@ public static async Task GetFixAsync( ImmutableArray fixers, Project project, CodeFixerOptions options, - IFormatProvider formatProvider = null, + IFormatProvider? formatProvider = null, CancellationToken cancellationToken = default) { - CodeFixProvider fixer = null; - CodeAction fix = null; - Document document = null; + CodeFixProvider? fixer = null; + CodeAction? fix = null; + Document? document = null; for (int i = 0; i < fixers.Length; i++) { cancellationToken.ThrowIfCancellationRequested(); - (CodeAction fixCandidate, Document documentCandidate) = await GetFixAsync( + (CodeAction? fixCandidate, Document documentCandidate) = await GetFixAsync( diagnostics, descriptor, fixers[i], @@ -49,7 +49,7 @@ public static async Task GetFixAsync( if (fix is null) { if (options.DiagnosticFixerMap.IsEmpty - || !options.DiagnosticFixerMap.TryGetValue(descriptor.Id, out string fullTypeName) + || !options.DiagnosticFixerMap.TryGetValue(descriptor.Id, out string? fullTypeName) || string.Equals(fixers[i].GetType().FullName, fullTypeName, StringComparison.Ordinal)) { fix = fixCandidate; @@ -60,7 +60,7 @@ public static async Task GetFixAsync( else if (options.DiagnosticFixerMap.IsEmpty || !options.DiagnosticFixerMap.ContainsKey(descriptor.Id)) { - LogHelpers.WriteMultipleFixersSummary(descriptor.Id, fixer, fixers[i]); + LogHelpers.WriteMultipleFixersSummary(descriptor.Id, fixer!, fixers[i]); return new DiagnosticFix(null, null, fixer, fixers[i]); } } @@ -69,19 +69,19 @@ public static async Task GetFixAsync( return new DiagnosticFix(fix, document, fixer, null); } - private static async Task<(CodeAction, Document)> GetFixAsync( + private static async Task<(CodeAction?, Document)> GetFixAsync( ImmutableArray diagnostics, DiagnosticDescriptor descriptor, CodeFixProvider fixer, Project project, CodeFixerOptions options, - IFormatProvider formatProvider = null, + IFormatProvider? formatProvider = null, CancellationToken cancellationToken = default) { if (diagnostics.Length == 1) return await GetFixAsync(diagnostics[0], fixer, project, options, formatProvider, cancellationToken).ConfigureAwait(false); - FixAllProvider fixAllProvider = fixer.GetFixAllProvider(); + FixAllProvider? fixAllProvider = fixer.GetFixAllProvider(); if (fixAllProvider is null) { @@ -115,12 +115,12 @@ public static async Task GetFixAsync( if (!diagnostic.Location.IsInSource) continue; - Document document = project.GetDocument(diagnostic.Location.SourceTree); + Document? document = project.GetDocument(diagnostic.Location.SourceTree); if (document is null) continue; - CodeAction fix = await GetFixAsync(diagnostic, fixer, document, multipleFixesInfos, equivalenceKeys, cancellationToken).ConfigureAwait(false); + CodeAction? fix = await GetFixAsync(diagnostic, fixer, document, multipleFixesInfos, equivalenceKeys, cancellationToken).ConfigureAwait(false); if (fix is null) continue; @@ -134,7 +134,7 @@ public static async Task GetFixAsync( new FixAllDiagnosticProvider(diagnostics), cancellationToken); - CodeAction fixAll = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); + CodeAction? fixAll = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false); if (fixAll is not null) { @@ -155,18 +155,18 @@ public static async Task GetFixAsync( return default; } - private static async Task<(CodeAction, Document)> GetFixAsync( + private static async Task<(CodeAction?, Document)> GetFixAsync( Diagnostic diagnostic, CodeFixProvider fixer, Project project, CodeFixerOptions options, - IFormatProvider formatProvider, + IFormatProvider? formatProvider, CancellationToken cancellationToken) { if (!diagnostic.Location.IsInSource) return default; - Document document = project.GetDocument(diagnostic.Location.SourceTree); + Document? document = project.GetDocument(diagnostic.Location.SourceTree); Debug.Assert(document is not null, ""); @@ -175,7 +175,7 @@ public static async Task GetFixAsync( options.DiagnosticFixMap.TryGetValue(diagnostic.Id, out ImmutableArray equivalenceKeys); - CodeAction action = await GetFixAsync(diagnostic, fixer, document, multipleFixesInfos: default, equivalenceKeys, cancellationToken).ConfigureAwait(false); + CodeAction? action = await GetFixAsync(diagnostic, fixer, document, multipleFixesInfos: default, equivalenceKeys, cancellationToken).ConfigureAwait(false); if (action is null) { @@ -186,15 +186,15 @@ public static async Task GetFixAsync( return (action, document); } - private static async Task GetFixAsync( + private static async Task GetFixAsync( Diagnostic diagnostic, CodeFixProvider fixer, Document document, - HashSet multipleFixesInfos, + HashSet? multipleFixesInfos, ImmutableArray equivalenceKeys, CancellationToken cancellationToken) { - CodeAction action = null; + CodeAction? action = null; var context = new CodeFixContext( document, @@ -240,7 +240,7 @@ private static void WriteMultipleActionsSummary(in MultipleFixesInfo info) private readonly struct MultipleFixesInfo : IEquatable { - public MultipleFixesInfo(string diagnosticId, CodeFixProvider fixer, string equivalenceKey1, string equivalenceKey2) + public MultipleFixesInfo(string diagnosticId, CodeFixProvider fixer, string? equivalenceKey1, string? equivalenceKey2) { DiagnosticId = diagnosticId; Fixer = fixer; @@ -252,9 +252,9 @@ public MultipleFixesInfo(string diagnosticId, CodeFixProvider fixer, string equi public CodeFixProvider Fixer { get; } - public string EquivalenceKey1 { get; } + public string? EquivalenceKey1 { get; } - public string EquivalenceKey2 { get; } + public string? EquivalenceKey2 { get; } public override bool Equals(object obj) { diff --git a/src/Workspaces.Core/CodeFixes/FixAllDiagnosticProvider.cs b/src/Workspaces.Core/CodeFixes/FixAllDiagnosticProvider.cs index ebdfc63971..efc339f30e 100644 --- a/src/Workspaces.Core/CodeFixes/FixAllDiagnosticProvider.cs +++ b/src/Workspaces.Core/CodeFixes/FixAllDiagnosticProvider.cs @@ -26,7 +26,7 @@ public override Task> GetAllDiagnosticsAsync(Project pro public override async Task> GetDocumentDiagnosticsAsync(Document document, CancellationToken cancellationToken) { - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + SyntaxTree tree = (await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false))!; return GetDocumentDiagnostics(); diff --git a/src/Workspaces.Core/CodeFixes/ProjectFixResult.cs b/src/Workspaces.Core/CodeFixes/ProjectFixResult.cs index 7bc90c1b4a..bd6570913a 100644 --- a/src/Workspaces.Core/CodeFixes/ProjectFixResult.cs +++ b/src/Workspaces.Core/CodeFixes/ProjectFixResult.cs @@ -11,9 +11,9 @@ internal class ProjectFixResult internal ProjectFixResult( ProjectFixKind kind, - IEnumerable fixedDiagnostics = default, - IEnumerable unfixedDiagnostics = default, - IEnumerable unfixableDiagnostics = default, + IEnumerable? fixedDiagnostics = default, + IEnumerable? unfixedDiagnostics = default, + IEnumerable? unfixableDiagnostics = default, int numberOfFormattedDocuments = -1, int numberOfAddedFileBanners = -1) { diff --git a/src/Workspaces.Core/CodeMetrics/CodeMetricsOptions.cs b/src/Workspaces.Core/CodeMetrics/CodeMetricsOptions.cs index 00731a0207..edc60a0d7b 100644 --- a/src/Workspaces.Core/CodeMetrics/CodeMetricsOptions.cs +++ b/src/Workspaces.Core/CodeMetrics/CodeMetricsOptions.cs @@ -4,6 +4,8 @@ namespace Roslynator.CodeMetrics; internal class CodeMetricsOptions { + public static CodeMetricsOptions Default { get; } = new(); + public CodeMetricsOptions( bool includeGenerated = false, bool includeWhitespace = false, diff --git a/src/Workspaces.Core/Comparers/SymbolDefinitionComparer.cs b/src/Workspaces.Core/Comparers/SymbolDefinitionComparer.cs index 7008ccc7be..94e583fd92 100644 --- a/src/Workspaces.Core/Comparers/SymbolDefinitionComparer.cs +++ b/src/Workspaces.Core/Comparers/SymbolDefinitionComparer.cs @@ -161,9 +161,9 @@ public static int CompareName(ISymbol symbol1, ISymbol symbol2) private class DefaultSymbolDefinitionComparer : SymbolDefinitionComparer { - private IComparer _namespaceComparer; - private IComparer _typeComparer; - private IComparer _memberComparer; + private IComparer? _namespaceComparer; + private IComparer? _typeComparer; + private IComparer? _memberComparer; internal DefaultSymbolDefinitionComparer(SymbolDefinitionSortOptions options = SymbolDefinitionSortOptions.None) : base(options) diff --git a/src/Workspaces.Core/ConsoleUtility.cs b/src/Workspaces.Core/ConsoleUtility.cs index 5d60ca8e4f..59d01456f0 100644 --- a/src/Workspaces.Core/ConsoleUtility.cs +++ b/src/Workspaces.Core/ConsoleUtility.cs @@ -9,7 +9,7 @@ namespace Roslynator; internal static class ConsoleUtility { - public static string ReadUserInput(string defaultValue, string prompt = null) + public static string ReadUserInput(string defaultValue, string? prompt = null) { bool treatControlCAsInput = Console.TreatControlCAsInput; diff --git a/src/Workspaces.Core/DiagnosticFormatter.cs b/src/Workspaces.Core/DiagnosticFormatter.cs index 01e88ae8e9..b6d54d398a 100644 --- a/src/Workspaces.Core/DiagnosticFormatter.cs +++ b/src/Workspaces.Core/DiagnosticFormatter.cs @@ -12,8 +12,8 @@ internal static class DiagnosticFormatter { public static string FormatDiagnostic( Diagnostic diagnostic, - string baseDirectoryPath = null, - IFormatProvider formatProvider = null) + string? baseDirectoryPath = null, + IFormatProvider? formatProvider = null) { StringBuilder sb = StringBuilderCache.GetInstance(); @@ -33,7 +33,7 @@ public static string FormatDiagnostic( internal static void FormatLocation( Location location, - string baseDirectoryPath, + string? baseDirectoryPath, ref StringBuilder sb) { switch (location.Kind) diff --git a/src/Workspaces.Core/Diagnostics/CodeAnalyzer.cs b/src/Workspaces.Core/Diagnostics/CodeAnalyzer.cs index 2bc140db4c..bd6ca18ab8 100644 --- a/src/Workspaces.Core/Diagnostics/CodeAnalyzer.cs +++ b/src/Workspaces.Core/Diagnostics/CodeAnalyzer.cs @@ -24,8 +24,8 @@ internal class CodeAnalyzer public CodeAnalyzer( AnalyzerLoader analyzerLoader, - IFormatProvider formatProvider = null, - CodeAnalyzerOptions options = null) + IFormatProvider? formatProvider = null, + CodeAnalyzerOptions? options = null) { _analyzerLoader = analyzerLoader; @@ -33,7 +33,7 @@ public CodeAnalyzer( Options = options ?? CodeAnalyzerOptions.Default; } - public IFormatProvider FormatProvider { get; } + public IFormatProvider? FormatProvider { get; } public CodeAnalyzerOptions Options { get; } @@ -62,7 +62,7 @@ public async Task> AnalyzeSolutionAsync( { cancellationToken.ThrowIfCancellationRequested(); - Project project = solution.GetProject(projectIds[i]); + Project project = solution.GetProject(projectIds[i])!; if (predicate is null || predicate(project)) { @@ -109,6 +109,18 @@ public async Task AnalyzeProjectAsync(Project project, Ca private async Task AnalyzeProjectCoreAsync(Project project, CancellationToken cancellationToken = default) { + if (!MefWorkspaceServices.Default.SupportedLanguages.Contains(project.Language)) + { + WriteLine($" Language '{project.Language}' is not supported.", ConsoleColors.DarkGray, Verbosity.Normal); + ProjectAnalysisResult.Create(project); + } + + if (!project.SupportsCompilation) + { + WriteLine(" Project does not support compilation", ConsoleColors.DarkGray, Verbosity.Normal); + ProjectAnalysisResult.Create(project); + } + ImmutableArray analyzers = _analyzerLoader.GetAnalyzers(project: project); if (!analyzers.Any()) @@ -129,7 +141,7 @@ private async Task AnalyzeProjectCoreAsync(Project projec cancellationToken.ThrowIfCancellationRequested(); - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; ImmutableArray compilerDiagnostics = (Options.IgnoreCompilerDiagnostics) ? ImmutableArray.Empty @@ -198,13 +210,13 @@ private IEnumerable FilterDiagnostics(IEnumerable diagno { Debug.Assert(diagnostic.Id.StartsWith("CS", "VB", StringComparison.Ordinal), diagnostic.Id); - SyntaxTree tree = diagnostic.Location.SourceTree; + SyntaxTree? tree = diagnostic.Location.SourceTree; if (tree is null || Options.FileSystemFilter?.IsMatch(tree.FilePath) != false) { if (tree is null - || !GeneratedCodeUtility.IsGeneratedCode(tree, f => MefWorkspaceServices.Default.GetService(tree.Options.Language).IsComment(f), cancellationToken)) + || !GeneratedCodeUtility.IsGeneratedCode(tree, f => MefWorkspaceServices.Default.GetService(tree.Options.Language)!.IsComment(f), cancellationToken)) { yield return diagnostic; } diff --git a/src/Workspaces.Core/Diagnostics/CodeAnalyzerOptions.cs b/src/Workspaces.Core/Diagnostics/CodeAnalyzerOptions.cs index 1a971075c1..2c790ef632 100644 --- a/src/Workspaces.Core/Diagnostics/CodeAnalyzerOptions.cs +++ b/src/Workspaces.Core/Diagnostics/CodeAnalyzerOptions.cs @@ -10,7 +10,7 @@ internal class CodeAnalyzerOptions : CodeAnalysisOptions public static CodeAnalyzerOptions Default { get; } = new(); public CodeAnalyzerOptions( - FileSystemFilter fileSystemFilter = null, + FileSystemFilter? fileSystemFilter = null, bool ignoreAnalyzerReferences = false, bool ignoreCompilerDiagnostics = false, bool reportNotConfigurable = false, @@ -18,8 +18,8 @@ public CodeAnalyzerOptions( bool logAnalyzerExecutionTime = false, bool concurrentAnalysis = true, DiagnosticSeverity severityLevel = DiagnosticSeverity.Info, - IEnumerable supportedDiagnosticIds = null, - IEnumerable ignoredDiagnosticIds = null) : base( + IEnumerable? supportedDiagnosticIds = null, + IEnumerable? ignoredDiagnosticIds = null) : base( fileSystemFilter: fileSystemFilter, severityLevel: severityLevel, ignoreAnalyzerReferences: ignoreAnalyzerReferences, diff --git a/src/Workspaces.Core/Extensions/CodeFixContextExtensions.cs b/src/Workspaces.Core/Extensions/CodeFixContextExtensions.cs index 14e251b5ff..8e9b8d9dc4 100644 --- a/src/Workspaces.Core/Extensions/CodeFixContextExtensions.cs +++ b/src/Workspaces.Core/Extensions/CodeFixContextExtensions.cs @@ -8,12 +8,12 @@ namespace Roslynator; internal static class CodeFixContextExtensions { - public static Task GetSyntaxRootAsync(this CodeFixContext context) + public static Task GetSyntaxRootAsync(this CodeFixContext context) { return context.Document.GetSyntaxRootAsync(context.CancellationToken); } - public static Task GetSemanticModelAsync(this CodeFixContext context) + public static Task GetSemanticModelAsync(this CodeFixContext context) { return context.Document.GetSemanticModelAsync(context.CancellationToken); } diff --git a/src/Workspaces.Core/Extensions/CollectionExtensions.cs b/src/Workspaces.Core/Extensions/CollectionExtensions.cs index a90c09d55d..7ed9c5b2b8 100644 --- a/src/Workspaces.Core/Extensions/CollectionExtensions.cs +++ b/src/Workspaces.Core/Extensions/CollectionExtensions.cs @@ -8,7 +8,7 @@ namespace Roslynator; internal static class CollectionExtensions { - public static T SingleOrDefault(this IReadOnlyCollection values, bool shouldThrow) + public static T? SingleOrDefault(this IReadOnlyCollection values, bool shouldThrow) { if (values is null) throw new ArgumentNullException(nameof(values)); @@ -23,7 +23,7 @@ public static T SingleOrDefault(this IReadOnlyCollection values, bool shou } } - public static T SingleOrDefault( + public static T? SingleOrDefault( this IReadOnlyCollection list, Func predicate, bool shouldThrow) diff --git a/src/Workspaces.Core/Extensions/Extensions.cs b/src/Workspaces.Core/Extensions/Extensions.cs index 1351cfb720..6cb8d4dbd7 100644 --- a/src/Workspaces.Core/Extensions/Extensions.cs +++ b/src/Workspaces.Core/Extensions/Extensions.cs @@ -18,11 +18,11 @@ namespace Roslynator; internal static class Extensions { - public static bool IsMatch(this Matcher matcher, ISymbol symbol, string rootDirectoryPath) + public static bool IsMatch(this Matcher matcher, ISymbol symbol, string? rootDirectoryPath) { foreach (Location location in symbol.Locations) { - SyntaxTree tree = location.SourceTree; + SyntaxTree? tree = location.SourceTree; if (tree is not null) { @@ -254,7 +254,7 @@ public static string GetPluralText(this SymbolGroup symbolGroup) return ""; } - public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key) + public static TValue? GetValueOrDefault(this IDictionary dictionary, TKey key) { if (dictionary.TryGetValue(key, out TValue value)) return value; @@ -318,7 +318,7 @@ public static async Task CountLinesAsync( Project project, LinesOfCodeKind kind, FileSystemFilter fileSystemFilter, - CodeMetricsOptions options = null, + CodeMetricsOptions? options = null, CancellationToken cancellationToken = default) { CodeMetricsInfo codeMetrics = default; @@ -328,7 +328,7 @@ public static async Task CountLinesAsync( if (!document.SupportsSyntaxTree) continue; - string filePath = document.FilePath; + string? filePath = document.FilePath; if (filePath is not null && fileSystemFilter?.IsMatch(filePath) == false) @@ -348,14 +348,16 @@ public static async Task CountLinesAsync( this ICodeMetricsService service, Document document, LinesOfCodeKind kind, - CodeMetricsOptions options = null, + CodeMetricsOptions? options = null, CancellationToken cancellationToken = default) { - SyntaxTree tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); + SyntaxTree? tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (tree is null) return default; + options ??= CodeMetricsOptions.Default; + if (!options.IncludeGeneratedCode && GeneratedCodeUtility.IsGeneratedCode(tree, f => service.SyntaxFacts.IsComment(f), cancellationToken)) { @@ -377,9 +379,9 @@ public static async Task CountLinesAsync( } } - public static OperationCanceledException GetOperationCanceledException(this AggregateException aggregateException) + public static OperationCanceledException? GetOperationCanceledException(this AggregateException aggregateException) { - OperationCanceledException operationCanceledException = null; + OperationCanceledException? operationCanceledException = null; foreach (Exception ex in aggregateException.InnerExceptions) { @@ -435,7 +437,7 @@ public static ConsoleColors GetColors(this WorkspaceDiagnosticKind kind) public static bool IsEffective( this Diagnostic diagnostic, CodeAnalysisOptions codeAnalysisOptions, - CompilationOptions compilationOptions, + CompilationOptions? compilationOptions, CancellationToken cancellationToken = default) { if (!codeAnalysisOptions.IsSupportedDiagnosticId(diagnostic.Id)) @@ -444,11 +446,9 @@ public static bool IsEffective( if (diagnostic.Descriptor.CustomTags.Contains(WellKnownDiagnosticTags.Compiler)) return true; - SyntaxTree tree = diagnostic.Location.SourceTree; + SyntaxTree? tree = diagnostic.Location.SourceTree; - ReportDiagnostic reportDiagnostic = (tree is not null) - ? diagnostic.Descriptor.GetEffectiveSeverity(tree, compilationOptions, cancellationToken) - : diagnostic.Descriptor.GetEffectiveSeverity(compilationOptions); + ReportDiagnostic reportDiagnostic = diagnostic.Descriptor.GetEffectiveSeverity(tree, compilationOptions, cancellationToken); return reportDiagnostic != ReportDiagnostic.Suppress && reportDiagnostic.ToDiagnosticSeverity() >= codeAnalysisOptions.SeverityLevel; diff --git a/src/Workspaces.Core/Extensions/WorkspaceExtensions.cs b/src/Workspaces.Core/Extensions/WorkspaceExtensions.cs index e7bc06e554..95a5058942 100644 --- a/src/Workspaces.Core/Extensions/WorkspaceExtensions.cs +++ b/src/Workspaces.Core/Extensions/WorkspaceExtensions.cs @@ -109,7 +109,10 @@ public static async Task ReplaceNodeAsync( if (newNode is null) throw new ArgumentNullException(nameof(newNode)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceNode(oldNode, newNode); @@ -138,7 +141,10 @@ public static async Task ReplaceNodeAsync( if (newNodes is null) throw new ArgumentNullException(nameof(newNodes)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceNode(oldNode, newNodes); @@ -168,7 +174,10 @@ public static async Task ReplaceNodesAsync( if (computeReplacementNode is null) throw new ArgumentNullException(nameof(computeReplacementNode)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceNodes(nodes, computeReplacementNode); @@ -191,7 +200,10 @@ public static async Task ReplaceTokenAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceToken(oldToken, newToken); @@ -217,7 +229,10 @@ public static async Task ReplaceTokenAsync( if (newTokens is null) throw new ArgumentNullException(nameof(newTokens)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceToken(oldToken, newTokens); @@ -240,7 +255,10 @@ public static async Task ReplaceTriviaAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceTrivia(oldTrivia, newTrivia); @@ -266,7 +284,10 @@ public static async Task ReplaceTriviaAsync( if (newTrivia is null) throw new ArgumentNullException(nameof(newTrivia)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceTrivia(oldTrivia, newTrivia); @@ -314,7 +335,10 @@ public static async Task InsertNodesBeforeAsync( if (newNodes is null) throw new ArgumentNullException(nameof(newNodes)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.InsertNodesBefore(nodeInList, newNodes); @@ -362,7 +386,10 @@ public static async Task InsertNodesAfterAsync( if (newNodes is null) throw new ArgumentNullException(nameof(newNodes)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.InsertNodesAfter(nodeInList, newNodes); @@ -388,11 +415,14 @@ public static async Task RemoveNodeAsync( if (node is null) throw new ArgumentNullException(nameof(node)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - SyntaxNode newRoot = root.RemoveNode(node, options); + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); - return document.WithSyntaxRoot(newRoot); + SyntaxNode? newRoot = root.RemoveNode(node, options); + + return document.WithSyntaxRoot(newRoot!); } /// @@ -414,11 +444,14 @@ public static async Task RemoveNodesAsync( if (nodes is null) throw new ArgumentNullException(nameof(nodes)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - SyntaxNode newRoot = root.RemoveNodes(nodes, options); + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); - return document.WithSyntaxRoot(newRoot); + SyntaxNode? newRoot = root.RemoveNodes(nodes, options); + + return document.WithSyntaxRoot(newRoot!); } internal static Solution Solution(this Document document) @@ -451,9 +484,15 @@ public static async Task ReplaceNodeAsync( if (newNode is null) throw new ArgumentNullException(nameof(newNode)); - Document document = solution.GetDocument(oldNode.SyntaxTree); + Document? document = solution.GetDocument(oldNode.SyntaxTree); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + if (document is null) + throw new InvalidOperationException($"Document not found for syntax tree '{oldNode.SyntaxTree.FilePath}'."); + + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceNode(oldNode, newNode); @@ -487,9 +526,15 @@ public static async Task ReplaceNodesAsync( foreach (IGrouping grouping in nodes.GroupBy(f => f.SyntaxTree)) { - Document document = solution.GetDocument(grouping.Key); + Document? document = solution.GetDocument(grouping.Key); + + if (document is null) + throw new InvalidOperationException($"Document not found for syntax tree '{grouping.Key.FilePath}'."); + + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + if (root is null) + throw new InvalidOperationException("Document does not support syntax tree."); SyntaxNode newRoot = root.ReplaceNodes(grouping, computeReplacementNodes); diff --git a/src/Workspaces.Core/FileSystemFilter.cs b/src/Workspaces.Core/FileSystemFilter.cs index 10d7b79f1b..286ca1688e 100644 --- a/src/Workspaces.Core/FileSystemFilter.cs +++ b/src/Workspaces.Core/FileSystemFilter.cs @@ -22,9 +22,9 @@ private FileSystemFilter(Matcher matcher) public Matcher Matcher { get; } - public string RootDirectoryPath { get; set; } + public string? RootDirectoryPath { get; set; } - public static FileSystemFilter CreateOrDefault( + public static FileSystemFilter? CreateOrDefault( IEnumerable include, IEnumerable exclude) { diff --git a/src/Workspaces.Core/FindSymbols/IgnoredAttributeNameFilterRule.cs b/src/Workspaces.Core/FindSymbols/IgnoredAttributeNameFilterRule.cs index a9815e049f..f4d524966f 100644 --- a/src/Workspaces.Core/FindSymbols/IgnoredAttributeNameFilterRule.cs +++ b/src/Workspaces.Core/FindSymbols/IgnoredAttributeNameFilterRule.cs @@ -32,49 +32,14 @@ public override bool IsApplicable(AttributeInfo value) public override bool IsMatch(AttributeInfo attributeInfo) { - return !AttributeNames.Contains(attributeInfo.AttributeClass); + return attributeInfo.AttributeClass is null + || !AttributeNames.Contains(attributeInfo.AttributeClass); } private class DefaultIgnoredAttributeNameFilterRule : IgnoredAttributeNameFilterRule { private static readonly MetadataName _defaultMemberAttribute = MetadataName.Parse("System.Reflection.DefaultMemberAttribute"); -#if DEBUG - //private static readonly MetadataNameSet _knownVisibleAttributes = new(new[] - // { - // "Microsoft.CodeAnalysis.CommitHashAttribute", - // "System.AttributeUsageAttribute", - // "System.CLSCompliantAttribute", - // "System.ComVisibleAttribute", - // "System.FlagsAttribute", - // "System.ObsoleteAttribute", - // "System.ComponentModel.DefaultValueAttribute", - // "System.ComponentModel.EditorBrowsableAttribute", - // "System.Composition.MetadataAttributeAttribute", - // "System.Reflection.AssemblyCompanyAttribute", - // "System.Reflection.AssemblyConfigurationAttribute", - // "System.Reflection.AssemblyCopyrightAttribute", - // "System.Reflection.AssemblyDescriptionAttribute", - // "System.Reflection.AssemblyFileVersionAttribute", - // "System.Reflection.AssemblyInformationalVersionAttribute", - // "System.Reflection.AssemblyMetadataAttribute", - // "System.Reflection.AssemblyProductAttribute", - // "System.Reflection.AssemblyTitleAttribute", - // "System.Reflection.AssemblyTrademarkAttribute", - // "System.Reflection.AssemblyVersionAttribute", - // "System.Resources.NeutralResourcesLanguageAttribute", - // "System.Runtime.CompilerServices.InternalsVisibleToAttribute", - // "System.Runtime.CompilerServices.InternalImplementationOnlyAttribute", - // "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute", - // "System.Runtime.InteropServices.GuidAttribute", - // "System.Runtime.Versioning.TargetFrameworkAttribute", - // "System.Xml.Serialization.XmlArrayItemAttribute", - // "System.Xml.Serialization.XmlAttributeAttribute", - // "System.Xml.Serialization.XmlElementAttribute", - // "System.Xml.Serialization.XmlRootAttribute", - // }); -#endif - public static DefaultIgnoredAttributeNameFilterRule Instance { get; } = new(GetIgnoredAttributes().Select(f => MetadataName.Parse(f)).ToImmutableArray()); public DefaultIgnoredAttributeNameFilterRule(IEnumerable values) @@ -84,7 +49,10 @@ public DefaultIgnoredAttributeNameFilterRule(IEnumerable values) public override bool IsMatch(AttributeInfo attributeInfo) { - INamedTypeSymbol attributeClass = attributeInfo.AttributeClass; + INamedTypeSymbol? attributeClass = attributeInfo.AttributeClass; + + if (attributeClass is null) + return true; if (AttributeNames.Contains(attributeClass)) return false; @@ -99,9 +67,7 @@ public override bool IsMatch(AttributeInfo attributeInfo) if (namedType.GetMembers().Any(f => f.IsKind(SymbolKind.Property) && ((IPropertySymbol)f).IsIndexer)) return false; } -#if DEBUG - //Debug.Assert(_knownVisibleAttributes.Contains(attributeClass), attributeClass.ToDisplayString()); -#endif + return true; } diff --git a/src/Workspaces.Core/FindSymbols/SymbolFilterOptions.cs b/src/Workspaces.Core/FindSymbols/SymbolFilterOptions.cs index 5c115441ac..55793d2d31 100644 --- a/src/Workspaces.Core/FindSymbols/SymbolFilterOptions.cs +++ b/src/Workspaces.Core/FindSymbols/SymbolFilterOptions.cs @@ -14,11 +14,11 @@ internal class SymbolFilterOptions public static SymbolFilterOptions Default { get; } = new(); internal SymbolFilterOptions( - FileSystemFilter fileSystemFilter = null, + FileSystemFilter? fileSystemFilter = null, VisibilityFilter visibility = VisibilityFilter.All, SymbolGroupFilter symbolGroups = SymbolGroupFilter.TypeOrMember, - IEnumerable rules = null, - IEnumerable attributeRules = null) + IEnumerable? rules = null, + IEnumerable? attributeRules = null) { FileSystemFilter = fileSystemFilter; Visibility = visibility; @@ -28,7 +28,7 @@ internal SymbolFilterOptions( AttributeRules = attributeRules?.ToImmutableArray() ?? ImmutableArray.Empty; } - public FileSystemFilter FileSystemFilter { get; } + public FileSystemFilter? FileSystemFilter { get; } public VisibilityFilter Visibility { get; } diff --git a/src/Workspaces.Core/FindSymbols/SymbolFinder.cs b/src/Workspaces.Core/FindSymbols/SymbolFinder.cs index 5e8e6215be..765d7d0167 100644 --- a/src/Workspaces.Core/FindSymbols/SymbolFinder.cs +++ b/src/Workspaces.Core/FindSymbols/SymbolFinder.cs @@ -14,15 +14,17 @@ internal static class SymbolFinder { internal static async Task> FindSymbolsAsync( Project project, - SymbolFinderOptions options = null, - IFindSymbolsProgress progress = null, + SymbolFinderOptions? options = null, + IFindSymbolsProgress? progress = null, CancellationToken cancellationToken = default) { - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + options ??= SymbolFinderOptions.Default; - INamedTypeSymbol generatedCodeAttribute = compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute"); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; - ImmutableArray.Builder symbols = null; + INamedTypeSymbol? generatedCodeAttribute = compilation.GetTypeByMetadataName("System.CodeDom.Compiler.GeneratedCodeAttribute"); + + ImmutableArray.Builder? symbols = null; var namespaceOrTypeSymbols = new Stack(); @@ -60,7 +62,8 @@ internal static async Task> FindSymbolsAsync( case SymbolFilterReason.None: { if (options.IgnoreGeneratedCode - && GeneratedCodeUtility.IsGeneratedCode(symbol, generatedCodeAttribute, f => MefWorkspaceServices.Default.GetService(compilation.Language).IsComment(f), cancellationToken)) + && generatedCodeAttribute is not null + && GeneratedCodeUtility.IsGeneratedCode(symbol, generatedCodeAttribute, f => MefWorkspaceServices.Default.GetService(compilation.Language)!.IsComment(f), cancellationToken)) { continue; } diff --git a/src/Workspaces.Core/FindSymbols/SymbolFinderOptions.cs b/src/Workspaces.Core/FindSymbols/SymbolFinderOptions.cs index 90337f73a1..13a0d1bb22 100644 --- a/src/Workspaces.Core/FindSymbols/SymbolFinderOptions.cs +++ b/src/Workspaces.Core/FindSymbols/SymbolFinderOptions.cs @@ -7,11 +7,11 @@ namespace Roslynator.FindSymbols; internal class SymbolFinderOptions : SymbolFilterOptions { internal SymbolFinderOptions( - FileSystemFilter fileSystemFilter = null, + FileSystemFilter? fileSystemFilter = null, VisibilityFilter visibility = VisibilityFilter.All, SymbolGroupFilter symbolGroups = SymbolGroupFilter.TypeOrMember, - IEnumerable rules = null, - IEnumerable attributeRules = null, + IEnumerable? rules = null, + IEnumerable? attributeRules = null, bool ignoreGeneratedCode = false, bool unusedOnly = false) : base(fileSystemFilter, visibility, symbolGroups, rules, attributeRules) { diff --git a/src/Workspaces.Core/FindSymbols/WithAttributeFilterRule.cs b/src/Workspaces.Core/FindSymbols/WithAttributeFilterRule.cs index 52b9b24871..7209c879a7 100644 --- a/src/Workspaces.Core/FindSymbols/WithAttributeFilterRule.cs +++ b/src/Workspaces.Core/FindSymbols/WithAttributeFilterRule.cs @@ -30,8 +30,11 @@ public override bool IsMatch(ISymbol value) { foreach (AttributeData attribute in value.GetAttributes()) { - if (AttributeNames.Contains(attribute.AttributeClass)) + if (attribute.AttributeClass is not null + && AttributeNames.Contains(attribute.AttributeClass)) + { return true; + } } return false; diff --git a/src/Workspaces.Core/Formatting/CodeFormatter.cs b/src/Workspaces.Core/Formatting/CodeFormatter.cs index 161b17e95d..7c29a20d04 100644 --- a/src/Workspaces.Core/Formatting/CodeFormatter.cs +++ b/src/Workspaces.Core/Formatting/CodeFormatter.cs @@ -25,7 +25,7 @@ public static Task FormatProjectAsync( public static async Task FormatProjectAsync( Project project, ISyntaxFactsService syntaxFacts, - CodeFormatterOptions options, + CodeFormatterOptions? options, CancellationToken cancellationToken = default) { if (options is null) @@ -33,23 +33,27 @@ public static async Task FormatProjectAsync( foreach (DocumentId documentId in project.DocumentIds) { - Document document = project.GetDocument(documentId); + Document document = project.GetDocument(documentId)!; - if (options.FileSystemFilter?.IsMatch(document.FilePath) != false) + if (document.FilePath is null + || options.FileSystemFilter?.IsMatch(document.FilePath) != false) { if (options.IncludeGeneratedCode || !GeneratedCodeUtility.IsGeneratedCodeFile(document.FilePath)) { - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - if (options.IncludeGeneratedCode - || !syntaxFacts.BeginsWithAutoGeneratedComment(root)) + if (root is not null) { - DocumentOptionSet optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); + if (options.IncludeGeneratedCode + || !syntaxFacts.BeginsWithAutoGeneratedComment(root)) + { + DocumentOptionSet optionSet = await document.GetOptionsAsync(cancellationToken).ConfigureAwait(false); - Document newDocument = await Formatter.FormatAsync(document, optionSet, cancellationToken).ConfigureAwait(false); + Document newDocument = await Formatter.FormatAsync(document, optionSet, cancellationToken).ConfigureAwait(false); - project = newDocument.Project; + project = newDocument.Project; + } } } } @@ -64,20 +68,20 @@ internal static async Task> GetFormattedDocumentsAsyn Project newProject, ISyntaxFactsService syntaxFacts) { - ImmutableArray.Builder builder = null; + ImmutableArray.Builder? builder = null; //TODO: GetChangedDocuments(onlyGetDocumentsWithTextChanges: true) foreach (DocumentId documentId in newProject .GetChanges(project) .GetChangedDocuments()) { - Document document = newProject.GetDocument(documentId); + Document document = newProject.GetDocument(documentId)!; // https://github.com/dotnet/roslyn/issues/30674 - if ((await document.GetTextChangesAsync(project.GetDocument(documentId)).ConfigureAwait(false)).Any()) + if ((await document.GetTextChangesAsync(project.GetDocument(documentId)!).ConfigureAwait(false)).Any()) { #if DEBUG - bool success = await VerifySyntaxEquivalenceAsync(project.GetDocument(document.Id), document, syntaxFacts).ConfigureAwait(false); + bool success = await VerifySyntaxEquivalenceAsync(project.GetDocument(document.Id)!, document, syntaxFacts).ConfigureAwait(false); #endif (builder ??= ImmutableArray.CreateBuilder()).Add(document.Id); } @@ -94,8 +98,8 @@ private static async Task VerifySyntaxEquivalenceAsync( CancellationToken cancellationToken = default) { if (!string.Equals( - (await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)).NormalizeWhitespace("", false).ToFullString(), - (await oldDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false)).NormalizeWhitespace("", false).ToFullString(), + (await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!.NormalizeWhitespace("", false).ToFullString(), + (await oldDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!.NormalizeWhitespace("", false).ToFullString(), StringComparison.Ordinal)) { WriteLine($"Syntax roots with normalized white-space are not equivalent '{oldDocument.FilePath}'", ConsoleColors.Magenta); @@ -103,8 +107,8 @@ private static async Task VerifySyntaxEquivalenceAsync( } if (!syntaxFacts.AreEquivalent( - await newDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false), - await oldDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false))) + (await newDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false))!, + (await oldDocument.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false))!)) { WriteLine($"Syntax trees are not equivalent '{oldDocument.FilePath}'", ConsoleColors.Magenta); return false; diff --git a/src/Workspaces.Core/Formatting/CodeFormatterOptions.cs b/src/Workspaces.Core/Formatting/CodeFormatterOptions.cs index d9dc16592d..595bfacbf7 100644 --- a/src/Workspaces.Core/Formatting/CodeFormatterOptions.cs +++ b/src/Workspaces.Core/Formatting/CodeFormatterOptions.cs @@ -7,14 +7,14 @@ internal class CodeFormatterOptions public static CodeFormatterOptions Default { get; } = new(); public CodeFormatterOptions( - FileSystemFilter fileSystemFilter = null, + FileSystemFilter? fileSystemFilter = null, bool includeGeneratedCode = false) { FileSystemFilter = fileSystemFilter; IncludeGeneratedCode = includeGeneratedCode; } - public FileSystemFilter FileSystemFilter { get; } + public FileSystemFilter? FileSystemFilter { get; } public bool IncludeGeneratedCode { get; } } diff --git a/src/Workspaces.Core/Host/Mef/LanguageMetadata.cs b/src/Workspaces.Core/Host/Mef/LanguageMetadata.cs index 9be9ebb2a0..441e439aa9 100644 --- a/src/Workspaces.Core/Host/Mef/LanguageMetadata.cs +++ b/src/Workspaces.Core/Host/Mef/LanguageMetadata.cs @@ -6,11 +6,11 @@ namespace Roslynator.Host.Mef; internal class LanguageMetadata { - public string Language { get; } + public string? Language { get; } public LanguageMetadata(IDictionary data) { - Language = (string)data.GetValueOrDefault("Language"); + Language = (string?)data.GetValueOrDefault("Language"); } public LanguageMetadata(string language) diff --git a/src/Workspaces.Core/Host/Mef/LanguageServiceMetadata.cs b/src/Workspaces.Core/Host/Mef/LanguageServiceMetadata.cs index 6769b97272..5462a41e63 100644 --- a/src/Workspaces.Core/Host/Mef/LanguageServiceMetadata.cs +++ b/src/Workspaces.Core/Host/Mef/LanguageServiceMetadata.cs @@ -6,13 +6,13 @@ namespace Roslynator.Host.Mef; internal class LanguageServiceMetadata : LanguageMetadata { - public string ServiceType { get; } + public string? ServiceType { get; } public IReadOnlyDictionary Data { get; } public LanguageServiceMetadata(IDictionary data) : base(data) { - ServiceType = (string)data.GetValueOrDefault("ServiceType"); + ServiceType = (string?)data.GetValueOrDefault("ServiceType"); Data = (IReadOnlyDictionary)data; } diff --git a/src/Workspaces.Core/Host/Mef/MefHostServices.cs b/src/Workspaces.Core/Host/Mef/MefHostServices.cs index 7f4696afcb..bc4e5096c0 100644 --- a/src/Workspaces.Core/Host/Mef/MefHostServices.cs +++ b/src/Workspaces.Core/Host/Mef/MefHostServices.cs @@ -15,7 +15,7 @@ namespace Roslynator.Host.Mef; internal class MefHostServices { - private static MefHostServices _default; + private static MefHostServices? _default; private static ImmutableArray _defaultAssemblies; private readonly CompositionContext _compositionContext; @@ -75,6 +75,7 @@ private static ImmutableArray LoadDefaultAssemblies() return GetAssemblyNames() .Select(f => TryLoadAssembly(f)) .Where(f => f is not null) + .Cast() .ToImmutableArray(); static IEnumerable GetAssemblyNames() @@ -90,7 +91,7 @@ static IEnumerable GetAssemblyNames() } } - private static Assembly TryLoadAssembly(string assemblyName) + private static Assembly? TryLoadAssembly(string assemblyName) { try { @@ -107,7 +108,7 @@ public IEnumerable> GetExports() return _compositionContext.GetExports().Select(e => new Lazy(() => e)); } - public IEnumerable> GetExports() + public IEnumerable>? GetExports() { var importer = new WithMetadataImporter(); _compositionContext.SatisfyImports(importer); @@ -117,6 +118,6 @@ public IEnumerable> GetExports { [ImportMany] - public IEnumerable> Exports { get; set; } + public IEnumerable>? Exports { get; set; } } } diff --git a/src/Workspaces.Core/Host/Mef/MefLanguageServices.cs b/src/Workspaces.Core/Host/Mef/MefLanguageServices.cs index 3eb79a2412..ba01be647d 100644 --- a/src/Workspaces.Core/Host/Mef/MefLanguageServices.cs +++ b/src/Workspaces.Core/Host/Mef/MefLanguageServices.cs @@ -11,8 +11,8 @@ internal class MefLanguageServices { private readonly ImmutableArray> _services; - private ImmutableDictionary> _serviceMap - = ImmutableDictionary>.Empty; + private ImmutableDictionary?> _serviceMap + = ImmutableDictionary?>.Empty; public MefLanguageServices( MefWorkspaceServices workspaceServices, @@ -32,11 +32,11 @@ public MefLanguageServices( public bool HasServices => _services.Length > 0; - public TLanguageService GetService() + public TLanguageService? GetService() { - if (TryGetService(typeof(TLanguageService), out Lazy service)) + if (TryGetService(typeof(TLanguageService), out Lazy? service)) { - return (TLanguageService)service.Value; + return (TLanguageService)service!.Value; } else { @@ -44,7 +44,7 @@ public TLanguageService GetService() } } - internal bool TryGetService(Type serviceType, out Lazy service) + internal bool TryGetService(Type serviceType, out Lazy? service) { if (!_serviceMap.TryGetValue(serviceType, out service)) { diff --git a/src/Workspaces.Core/Host/Mef/MefWorkspaceServices.cs b/src/Workspaces.Core/Host/Mef/MefWorkspaceServices.cs index ca05120b8d..c8ccfeee29 100644 --- a/src/Workspaces.Core/Host/Mef/MefWorkspaceServices.cs +++ b/src/Workspaces.Core/Host/Mef/MefWorkspaceServices.cs @@ -11,9 +11,9 @@ namespace Roslynator.Host.Mef; internal class MefWorkspaceServices { - private static MefWorkspaceServices _default; + private static MefWorkspaceServices? _default; private readonly MefHostServices _mefServices; - private IEnumerable _languages; + private IEnumerable? _languages; private ImmutableDictionary _languageServicesMap = ImmutableDictionary.Empty; @@ -45,6 +45,8 @@ private IEnumerable GetSupportedLanguages() { ImmutableArray languages = _mefServices.GetExports() .Select(lazy => lazy.Metadata.Language) + .Where(f => f is not null) + .Cast() .Distinct() .ToImmutableArray(); @@ -60,7 +62,7 @@ public MefLanguageServices GetLanguageServices(string languageName) { ImmutableDictionary languageServicesMap = _languageServicesMap; - if (!languageServicesMap.TryGetValue(languageName, out MefLanguageServices languageServices)) + if (!languageServicesMap.TryGetValue(languageName, out MefLanguageServices? languageServices)) { languageServices = ImmutableInterlocked.GetOrAdd( ref _languageServicesMap, @@ -74,12 +76,12 @@ public MefLanguageServices GetLanguageServices(string languageName) return languageServices; } - internal bool TryGetLanguageServices(string languageName, out MefLanguageServices languageServices) + internal bool TryGetLanguageServices(string languageName, out MefLanguageServices? languageServices) { return _languageServicesMap.TryGetValue(languageName, out languageServices); } - internal TLanguageService GetService(string languageName) + internal TLanguageService? GetService(string languageName) { return GetLanguageServices(languageName).GetService(); } @@ -89,7 +91,7 @@ internal IEnumerable> GetExports() return _mefServices.GetExports(); } - internal IEnumerable> GetExports() + internal IEnumerable>? GetExports() { return _mefServices.GetExports(); } diff --git a/src/Workspaces.Core/ISyntaxFactsService.cs b/src/Workspaces.Core/ISyntaxFactsService.cs index ef8566db6d..e888a3a21a 100644 --- a/src/Workspaces.Core/ISyntaxFactsService.cs +++ b/src/Workspaces.Core/ISyntaxFactsService.cs @@ -25,7 +25,7 @@ internal interface ISyntaxFactsService : ILanguageService bool BeginsWithAutoGeneratedComment(SyntaxNode root); - SyntaxNode GetSymbolDeclaration(SyntaxToken identifier); + SyntaxNode? GetSymbolDeclaration(SyntaxToken identifier); bool IsValidIdentifier(string name); } diff --git a/src/Workspaces.Core/Logging/LogHelpers.cs b/src/Workspaces.Core/Logging/LogHelpers.cs index e2e74d09ec..c795fc49db 100644 --- a/src/Workspaces.Core/Logging/LogHelpers.cs +++ b/src/Workspaces.Core/Logging/LogHelpers.cs @@ -32,9 +32,9 @@ internal static class LogHelpers public static void WriteDiagnostic( Diagnostic diagnostic, - string baseDirectoryPath = null, - IFormatProvider formatProvider = null, - string indentation = null, + string? baseDirectoryPath = null, + IFormatProvider? formatProvider = null, + string? indentation = null, Verbosity verbosity = Verbosity.Diagnostic) { string text = DiagnosticFormatter.FormatDiagnostic(diagnostic, baseDirectoryPath, formatProvider); @@ -45,9 +45,9 @@ public static void WriteDiagnostic( public static void WriteDiagnostics( ImmutableArray diagnostics, - string baseDirectoryPath = null, - IFormatProvider formatProvider = null, - string indentation = null, + string? baseDirectoryPath = null, + IFormatProvider? formatProvider = null, + string? indentation = null, int maxCount = int.MaxValue, Verbosity verbosity = Verbosity.None) { @@ -169,10 +169,10 @@ public static void WriteFixSummary( IEnumerable fixedDiagnostics, IEnumerable unfixedDiagnostics, IEnumerable unfixableDiagnostics, - string baseDirectoryPath = null, - string indentation = null, + string? baseDirectoryPath = null, + string? indentation = null, bool addEmptyLine = false, - IFormatProvider formatProvider = null, + IFormatProvider? formatProvider = null, Verbosity verbosity = Verbosity.None) { WriteDiagnosticRules(unfixableDiagnostics, "Unfixable diagnostics:"); @@ -215,7 +215,7 @@ void WriteDiagnosticRules( } } - public static void WriteInfiniteLoopSummary(ImmutableArray diagnostics, ImmutableArray previousDiagnostics, Project project, IFormatProvider formatProvider = null) + public static void WriteInfiniteLoopSummary(ImmutableArray diagnostics, ImmutableArray previousDiagnostics, Project project, IFormatProvider? formatProvider = null) { WriteLine(" Infinite loop detected: Reported diagnostics have been previously fixed", ConsoleColors.Yellow, Verbosity.Normal); @@ -234,14 +234,14 @@ public static void WriteFormattedDocuments(ImmutableArray documentId { foreach (DocumentId documentId in documentIds) { - Document document = project.GetDocument(documentId); - WriteLine($" Format '{PathUtilities.TrimStart(document.FilePath, solutionDirectory)}'", ConsoleColors.DarkGray, Verbosity.Detailed); + Document document = project.GetDocument(documentId)!; + WriteLine($" Format '{PathUtilities.TrimStart(document.FilePath!, solutionDirectory)}'", ConsoleColors.DarkGray, Verbosity.Detailed); } } public static void WriteUsedAnalyzers( ImmutableArray analyzers, - Func predicate, + Func? predicate, CodeAnalysisOptions options, ConsoleColors colors, Verbosity verbosity) @@ -368,8 +368,8 @@ public static void WriteMultipleOperationsSummary(CodeAction fix) public static void WriteSymbolDefinition( ISymbol symbol, - string baseDirectoryPath = null, - string indentation = null, + string? baseDirectoryPath = null, + string? indentation = null, Verbosity verbosity = Verbosity.Diagnostic) { StringBuilder sb = StringBuilderCache.GetInstance(); @@ -476,10 +476,10 @@ static string GetSymbolTitle(ISymbol symbol) public static int WriteCompilerErrors( ImmutableArray diagnostics, - string baseDirectoryPath = null, - HashSet ignoredCompilerDiagnosticIds = null, - IFormatProvider formatProvider = null, - string indentation = null, + string? baseDirectoryPath = null, + HashSet? ignoredCompilerDiagnosticIds = null, + IFormatProvider? formatProvider = null, + string? indentation = null, int limit = 1000) { IEnumerable filteredDiagnostics = diagnostics.Where(f => f.Severity == DiagnosticSeverity.Error); diff --git a/src/Workspaces.Core/Logging/Logger.cs b/src/Workspaces.Core/Logging/Logger.cs index c670f7ab93..62b01ec000 100644 --- a/src/Workspaces.Core/Logging/Logger.cs +++ b/src/Workspaces.Core/Logging/Logger.cs @@ -8,7 +8,7 @@ internal static class Logger { public static ConsoleWriter ConsoleOut { get; } = ConsoleWriter.Instance; - public static TextWriterWithVerbosity Out { get; set; } + public static TextWriterWithVerbosity? Out { get; set; } public static void Write(char value) { @@ -94,13 +94,13 @@ public static void Write(decimal value) Out?.Write(value); } - public static void Write(string value) + public static void Write(string? value) { ConsoleOut.Write(value); Out?.Write(value); } - public static void Write(string value, Verbosity verbosity) + public static void Write(string? value, Verbosity verbosity) { ConsoleOut.Write(value, verbosity: verbosity); Out?.Write(value, verbosity: verbosity); diff --git a/src/Workspaces.Core/Logging/TextWriterWithVerbosity.cs b/src/Workspaces.Core/Logging/TextWriterWithVerbosity.cs index de9bd3aa92..9415442756 100644 --- a/src/Workspaces.Core/Logging/TextWriterWithVerbosity.cs +++ b/src/Workspaces.Core/Logging/TextWriterWithVerbosity.cs @@ -80,17 +80,17 @@ public override void Write(float value) Writer.Write(value); } - public override void Write(string value) + public override void Write(string? value) { Writer.Write(value); } - public void Write(string value, Verbosity verbosity) + public void Write(string? value, Verbosity verbosity) { WriteIf(ShouldWrite(verbosity), value); } - public void WriteIf(bool condition, string value) + public void WriteIf(bool condition, string? value) { if (condition) Write(value); diff --git a/src/Workspaces.Core/MemberNameGenerator.cs b/src/Workspaces.Core/MemberNameGenerator.cs index 54a0a89bf7..851c3b739b 100644 --- a/src/Workspaces.Core/MemberNameGenerator.cs +++ b/src/Workspaces.Core/MemberNameGenerator.cs @@ -68,7 +68,7 @@ private static async Task> GetReservedNamesAsync( if (!referenceLocation.IsImplicit && !referenceLocation.IsCandidateLocation) { - SemanticModel semanticModel = await referenceLocation.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + SemanticModel semanticModel = (await referenceLocation.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; foreach (ISymbol symbol in semanticModel.LookupSymbols(referenceLocation.Location.SourceSpan.Start)) { diff --git a/src/Workspaces.Core/PathUtilities.cs b/src/Workspaces.Core/PathUtilities.cs index 3430a46e69..6f89f92a93 100644 --- a/src/Workspaces.Core/PathUtilities.cs +++ b/src/Workspaces.Core/PathUtilities.cs @@ -7,7 +7,7 @@ namespace Roslynator; internal static class PathUtilities { - internal static string TrimStart(string path, string basePath, bool trimLeadingDirectorySeparator = true) + internal static string TrimStart(string path, string? basePath, bool trimLeadingDirectorySeparator = true) { if (basePath is not null) { diff --git a/src/Workspaces.Core/ProjectOrSolution.cs b/src/Workspaces.Core/ProjectOrSolution.cs index 1ea8bd55ca..451230aa65 100644 --- a/src/Workspaces.Core/ProjectOrSolution.cs +++ b/src/Workspaces.Core/ProjectOrSolution.cs @@ -7,8 +7,8 @@ namespace Roslynator; internal readonly struct ProjectOrSolution : IEquatable { - private readonly Project _project; - private readonly Solution _solution; + private readonly Project? _project; + private readonly Solution? _solution; internal ProjectOrSolution(Project project) { @@ -28,19 +28,19 @@ internal ProjectOrSolution(Solution solution) public bool IsDefault => _project is null && _solution is null; - public string FilePath => (IsProject) ? _project.FilePath : _solution?.FilePath; + public string? FilePath => (IsProject) ? _project!.FilePath : _solution?.FilePath; - public VersionStamp Version => (IsProject) ? _project.Version : (_solution?.Version ?? default); + public VersionStamp Version => (IsProject) ? _project!.Version : (_solution?.Version ?? default); - public Workspace Workspace => (IsProject) ? _project.Solution.Workspace : _solution?.Workspace; + public Workspace? Workspace => (IsProject) ? _project!.Solution.Workspace : _solution?.Workspace; - public Project AsProject() => _project; + public Project? AsProject() => _project; - public Solution AsSolution() => _solution; + public Solution? AsSolution() => _solution; - public override string ToString() + public override string? ToString() { - return (_project ?? (object)_solution)?.ToString(); + return (_project ?? (object?)_solution)?.ToString(); } public override bool Equals(object obj) @@ -65,7 +65,7 @@ public bool Equals(ProjectOrSolution other) public override int GetHashCode() { - return (_project ?? (object)_solution)?.GetHashCode() ?? 0; + return (_project ?? (object?)_solution)?.GetHashCode() ?? 0; } public static bool operator ==(in ProjectOrSolution left, in ProjectOrSolution right) @@ -83,9 +83,9 @@ public static implicit operator ProjectOrSolution(Project project) return new ProjectOrSolution(project); } - public static implicit operator Project(in ProjectOrSolution ifOrElse) + public static implicit operator Project?(in ProjectOrSolution projectOrSolution) { - return ifOrElse.AsProject(); + return projectOrSolution.AsProject(); } public static implicit operator ProjectOrSolution(Solution solution) @@ -93,8 +93,8 @@ public static implicit operator ProjectOrSolution(Solution solution) return new ProjectOrSolution(solution); } - public static implicit operator Solution(in ProjectOrSolution ifOrElse) + public static implicit operator Solution?(in ProjectOrSolution projectOrSolution) { - return ifOrElse.AsSolution(); + return projectOrSolution.AsSolution(); } } diff --git a/src/Workspaces.Core/Rename/DiffTracker.cs b/src/Workspaces.Core/Rename/DiffTracker.cs index eaff594cd2..5715c62592 100644 --- a/src/Workspaces.Core/Rename/DiffTracker.cs +++ b/src/Workspaces.Core/Rename/DiffTracker.cs @@ -19,7 +19,7 @@ public bool TryGetValue(DocumentId documentId, out List spans) return _dic.TryGetValue(documentId, out spans); } - internal static TextSpan GetCurrentSpan(TextSpan span, DocumentId documentId, DiffTracker diffTracker) + internal static TextSpan GetCurrentSpan(TextSpan span, DocumentId documentId, DiffTracker? diffTracker) { return diffTracker?.GetCurrentSpan(span, documentId) ?? span; } @@ -80,7 +80,7 @@ public void AddLocations( int diff, Solution solution) { - foreach (IGrouping grouping in locations.GroupBy(f => solution.GetDocument(f.SourceTree).Id)) + foreach (IGrouping grouping in locations.GroupBy(f => solution.GetDocument(f.SourceTree)!.Id)) { DocumentId documentId = grouping.Key; diff --git a/src/Workspaces.Core/Rename/FindSymbolService.cs b/src/Workspaces.Core/Rename/FindSymbolService.cs index 57a1d9eb3b..945e9cddfe 100644 --- a/src/Workspaces.Core/Rename/FindSymbolService.cs +++ b/src/Workspaces.Core/Rename/FindSymbolService.cs @@ -10,7 +10,7 @@ internal abstract class FindSymbolService : IFindSymbolService { public abstract ISyntaxFactsService SyntaxFacts { get; } - public abstract SyntaxNode FindDeclaration(SyntaxNode node); + public abstract SyntaxNode? FindDeclaration(SyntaxNode node); public abstract bool CanBeRenamed(SyntaxToken token); diff --git a/src/Workspaces.Core/Rename/IFindSymbolService.cs b/src/Workspaces.Core/Rename/IFindSymbolService.cs index f53656edb3..fa15b9930b 100644 --- a/src/Workspaces.Core/Rename/IFindSymbolService.cs +++ b/src/Workspaces.Core/Rename/IFindSymbolService.cs @@ -11,7 +11,7 @@ internal interface IFindSymbolService : ILanguageService { ISyntaxFactsService SyntaxFacts { get; } - SyntaxNode FindDeclaration(SyntaxNode node); + SyntaxNode? FindDeclaration(SyntaxNode node); bool CanBeRenamed(SyntaxToken token); diff --git a/src/Workspaces.Core/Rename/SymbolData.cs b/src/Workspaces.Core/Rename/SymbolData.cs index 998d92b431..2479e57b12 100644 --- a/src/Workspaces.Core/Rename/SymbolData.cs +++ b/src/Workspaces.Core/Rename/SymbolData.cs @@ -8,7 +8,7 @@ namespace Roslynator.Rename; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal readonly struct SymbolData { - public SymbolData(ISymbol symbol, string id, DocumentId documentId) + public SymbolData(ISymbol symbol, string? id, DocumentId documentId) { Symbol = symbol; Id = id; @@ -17,7 +17,7 @@ public SymbolData(ISymbol symbol, string id, DocumentId documentId) public ISymbol Symbol { get; } - public string Id { get; } + public string? Id { get; } public DocumentId DocumentId { get; } diff --git a/src/Workspaces.Core/Rename/SymbolListHelpers.cs b/src/Workspaces.Core/Rename/SymbolListHelpers.cs index d80e9cb4cb..0544553e16 100644 --- a/src/Workspaces.Core/Rename/SymbolListHelpers.cs +++ b/src/Workspaces.Core/Rename/SymbolListHelpers.cs @@ -28,7 +28,7 @@ public static List SortTypeSymbols(IEnumerable symbols) #if DEBUG baseTypeSymbols.Sort((x, y) => StringComparer.Ordinal.Compare(x.ToDisplayString(SymbolDisplayFormats.Test), y.ToDisplayString(SymbolDisplayFormats.Test))); #endif - INamedTypeSymbol baseType = null; + INamedTypeSymbol? baseType = null; for (int i = 0; i < baseTypeSymbols.Count; i++) { @@ -42,7 +42,7 @@ void AnalyzeSymbol() results.Add(baseType); - IMethodSymbol delegateMethodSymbol = baseType.DelegateInvokeMethod; + IMethodSymbol? delegateMethodSymbol = baseType.DelegateInvokeMethod; if (delegateMethodSymbol is not null) results.AddRange(delegateMethodSymbol.Parameters); diff --git a/src/Workspaces.Core/Rename/SymbolProvider.cs b/src/Workspaces.Core/Rename/SymbolProvider.cs index 2ccb677928..b3038d3dec 100644 --- a/src/Workspaces.Core/Rename/SymbolProvider.cs +++ b/src/Workspaces.Core/Rename/SymbolProvider.cs @@ -20,9 +20,9 @@ internal class SymbolProvider { public bool IncludeGeneratedCode { get; init; } - public Matcher FileSystemMatcher { get; init; } + public Matcher? FileSystemMatcher { get; init; } - public string RootDirectoryPath { get; init; } + public string? RootDirectoryPath { get; init; } public async Task> GetSymbolsAsync( Project project, @@ -32,13 +32,13 @@ public async Task> GetSymbolsAsync( cancellationToken.ThrowIfCancellationRequested(); var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( - options: default(AnalyzerOptions), + options: default(AnalyzerOptions)!, onAnalyzerException: default(Action), concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; ImmutableArray symbolKinds = scope switch { @@ -91,9 +91,9 @@ private class Analyzer : DiagnosticAnalyzer public bool IncludeGeneratedCode { get; init; } - public Matcher FileSystemMatcher { get; init; } + public Matcher? FileSystemMatcher { get; init; } - public string RootDirectoryPath { get; init; } + public string? RootDirectoryPath { get; init; } public override void Initialize(AnalysisContext context) { diff --git a/src/Workspaces.Core/Rename/SymbolRenameProgress.cs b/src/Workspaces.Core/Rename/SymbolRenameProgress.cs index 01ba17adc4..e45419fb49 100644 --- a/src/Workspaces.Core/Rename/SymbolRenameProgress.cs +++ b/src/Workspaces.Core/Rename/SymbolRenameProgress.cs @@ -23,7 +23,7 @@ internal SymbolRenameProgress( ISymbol symbol, string newName, SymbolRenameResult result, - Exception exception = null) + Exception? exception = null) { Symbol = symbol; NewName = newName; @@ -49,7 +49,7 @@ internal SymbolRenameProgress( /// /// Exception that occurred during renaming. May be null. /// - public Exception Exception { get; } + public Exception? Exception { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => Symbol.ToDisplayString(SymbolDisplayFormats.FullName); diff --git a/src/Workspaces.Core/Rename/SymbolRenameState.cs b/src/Workspaces.Core/Rename/SymbolRenameState.cs index 1fcf1618d6..35550c9208 100644 --- a/src/Workspaces.Core/Rename/SymbolRenameState.cs +++ b/src/Workspaces.Core/Rename/SymbolRenameState.cs @@ -24,8 +24,8 @@ public SymbolRenameState( Solution solution, Func predicate, Func getNewName, - SymbolRenamerOptions options = null, - IProgress progress = null) + SymbolRenamerOptions? options = null, + IProgress? progress = null) { Workspace = solution.Workspace; @@ -41,7 +41,7 @@ public SymbolRenameState( public SymbolRenamerOptions Options { get; } - protected IProgress Progress { get; } + protected IProgress? Progress { get; } protected Func GetNewName { get; } @@ -49,7 +49,7 @@ public SymbolRenameState( private bool DryRun => Options.DryRun; - protected string CurrentDirectoryPath { get; set; } + protected string? CurrentDirectoryPath { get; set; } public Task RenameSymbolsAsync(CancellationToken cancellationToken = default) { @@ -87,7 +87,7 @@ protected virtual async Task RenameSymbolsAsync( { cancellationToken.ThrowIfCancellationRequested(); - Project project = CurrentSolution.GetProject(projects[j]); + Project project = CurrentSolution.GetProject(projects[j])!; if (!isSolution) CurrentDirectoryPath = Path.GetDirectoryName(project.FilePath); @@ -128,9 +128,9 @@ protected async Task AnalyzeProjectAsync( RenameScope scope, CancellationToken cancellationToken = default) { - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; - IFindSymbolService findSymbolService = MefWorkspaceServices.Default.GetService(project.Language); + IFindSymbolService? findSymbolService = MefWorkspaceServices.Default.GetService(project.Language); if (findSymbolService is null) throw new InvalidOperationException($"Language '{project.Language}' not supported."); @@ -170,7 +170,7 @@ protected async Task AnalyzeProjectAsync( } ImmutableArray symbolData = symbols - .Select(symbol => new SymbolData(symbol, GetSymbolId(symbol), project.GetDocumentId(symbol.Locations[0].SourceTree))) + .Select(symbol => new SymbolData(symbol, GetSymbolId(symbol), project.GetDocumentId(symbol.Locations[0].SourceTree)!)) .ToImmutableArray(); int length = symbolData.Length; @@ -191,11 +191,11 @@ protected async Task AnalyzeProjectAsync( } ImmutableArray symbolData2 = symbolData - .Where(f => !ignoreSymbolIds.Contains(f.Id) + .Where(f => (f.Id is null || !ignoreSymbolIds.Contains(f.Id)) && Predicate?.Invoke(f.Symbol) != false) .ToImmutableArray(); - List ignoredSymbolIds = await RenameSymbolsAsync( + List? ignoredSymbolIds = await RenameSymbolsAsync( symbolData2, findSymbolService, cancellationToken) @@ -203,31 +203,31 @@ protected async Task AnalyzeProjectAsync( if (DryRun || scope == RenameScope.Local - || symbolData2.Length == ignoredSymbolIds.Count) + || symbolData2.Length == ignoredSymbolIds!.Count) { break; } - foreach (string symbolId in ignoredSymbolIds) + foreach (string symbolId in ignoredSymbolIds!) { Debug.Assert(!ignoreSymbolIds.Contains(symbolId), symbolId); ignoreSymbolIds.Add(symbolId); } previousPreviousIds = previousIds; - previousIds = ImmutableArray.CreateRange(symbolData, f => f.Id); + previousIds = symbolData.Select(f => f.Id).Where(f => f is not null).Cast().ToImmutableArray(); - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; } } - private async Task> RenameSymbolsAsync( + private async Task?> RenameSymbolsAsync( IEnumerable symbols, IFindSymbolService findSymbolService, CancellationToken cancellationToken) { - List ignoredSymbolIds = null; - DiffTracker diffTracker = null; + List? ignoredSymbolIds = null; + DiffTracker? diffTracker = null; if (!DryRun) { @@ -240,12 +240,12 @@ private async Task> RenameSymbolsAsync( cancellationToken.ThrowIfCancellationRequested(); ISymbol symbol = symbolData.Symbol; - Document document = CurrentSolution.GetDocument(symbolData.DocumentId); + Document document = CurrentSolution.GetDocument(symbolData.DocumentId)!; if (document is null) throw new InvalidOperationException($"Cannot find document for symbol '{symbol.ToDisplayString(SymbolDisplayFormats.FullName)}'."); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + SemanticModel semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; TextSpan span = DiffTracker.GetCurrentSpan(symbol.Locations[0].SourceSpan, document.Id, diffTracker); @@ -278,8 +278,8 @@ private async Task RenameLocalSymbolsAsync( { cancellationToken.ThrowIfCancellationRequested(); - Document document = CurrentSolution.GetDocument(grouping.Key); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + Document document = CurrentSolution.GetDocument(grouping.Key)!; + SemanticModel semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; foreach (SyntaxReference syntaxReference in grouping .OrderByDescending(f => f.Span.Start)) @@ -287,9 +287,9 @@ private async Task RenameLocalSymbolsAsync( cancellationToken.ThrowIfCancellationRequested(); SyntaxNode node = await syntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false); - DiffTracker diffTracker = (DryRun) ? null : new DiffTracker(); - HashSet localFunctionIndexes = null; - HashSet localSymbolIndexes = null; + DiffTracker? diffTracker = (DryRun) ? null : new DiffTracker(); + HashSet? localFunctionIndexes = null; + HashSet? localSymbolIndexes = null; int i = 0; foreach (ISymbol symbol in findSymbolService.FindLocalSymbols(node, semanticModel, cancellationToken) @@ -345,7 +345,7 @@ private async Task RenameLocalFunctionsAndItsParametersAsync( SyntaxNode node, DocumentId documentId, HashSet indexes, - DiffTracker diffTracker, + DiffTracker? diffTracker, IFindSymbolService findSymbolService, CancellationToken cancellationToken) { @@ -353,8 +353,8 @@ private async Task RenameLocalFunctionsAndItsParametersAsync( { cancellationToken.ThrowIfCancellationRequested(); - Document document = CurrentSolution.GetDocument(documentId); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + Document document = CurrentSolution.GetDocument(documentId)!; + SyntaxNode root = (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; TextSpan span = DiffTracker.GetCurrentSpan(node.Span, documentId, diffTracker); @@ -374,18 +374,18 @@ private async Task RenameLocalFunctionsAndItsParametersAsync( } int i = 0; - DiffTracker diffTracker2 = (DryRun) ? null : new DiffTracker(); - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + DiffTracker? diffTracker2 = (DryRun) ? null : new DiffTracker(); + SemanticModel? semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - foreach (ISymbol symbol in findSymbolService.FindLocalSymbols(currentNode, semanticModel, cancellationToken) + foreach (ISymbol symbol in findSymbolService.FindLocalSymbols(currentNode, semanticModel!, cancellationToken) .OrderBy(f => f, LocalSymbolComparer.Instance)) { if (indexes.Contains(i)) { if (semanticModel is null) { - document = CurrentSolution.GetDocument(documentId); - semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + document = CurrentSolution.GetDocument(documentId)!; + semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; } var symbolData = new SymbolData(symbol, GetSymbolId(symbol), documentId); @@ -433,7 +433,7 @@ private async Task RenameLocalsAndLambdaParametersAsync( SyntaxNode node, DocumentId documentId, HashSet indexes, - DiffTracker diffTracker, + DiffTracker? diffTracker, IFindSymbolService findSymbolService, CancellationToken cancellationToken) { @@ -441,8 +441,8 @@ private async Task RenameLocalsAndLambdaParametersAsync( { cancellationToken.ThrowIfCancellationRequested(); - Document document = CurrentSolution.GetDocument(documentId); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + Document document = CurrentSolution.GetDocument(documentId)!; + SyntaxNode root = (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; TextSpan span = DiffTracker.GetCurrentSpan(node.Span, documentId, diffTracker); @@ -461,7 +461,7 @@ private async Task RenameLocalsAndLambdaParametersAsync( break; } - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + SemanticModel semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; int i = 0; foreach (ISymbol symbol in findSymbolService.FindLocalSymbols(currentNode, semanticModel, cancellationToken) @@ -497,14 +497,14 @@ private async Task RenameSymbolAsync( Document document, SemanticModel semanticModel, IFindSymbolService findSymbolService, - DiffTracker diffTracker, - List ignoreIds, + DiffTracker? diffTracker, + List? ignoreIds, CancellationToken cancellationToken) { - ISymbol symbol = symbolData.Symbol; - string symbolId = symbolData.Id; + ISymbol? symbol = symbolData.Symbol; + string? symbolId = symbolData.Id; - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode root = (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; if (!root.FullSpan.Contains(span)) { @@ -516,32 +516,35 @@ private async Task RenameSymbolAsync( Debug.Assert(span == identifier.Span, $"{span}\n{identifier.Span}"); - SyntaxNode node = findSymbolService.FindDeclaration(identifier.Parent); + SyntaxNode? node = findSymbolService.FindDeclaration(identifier.Parent!); + + if (node is null) + throw new InvalidOperationException($"Cannot find declaration for symbol '{symbol.ToDisplayString(SymbolDisplayFormats.FullName)}'."); if (!string.Equals(symbol.Name, identifier.ValueText, StringComparison.Ordinal)) return false; - semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; - ISymbol currentSymbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) + ISymbol? currentSymbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) ?? semanticModel.GetSymbol(node, cancellationToken); if (currentSymbol is null) { Debug.Fail(symbolId); - ignoreIds?.Add(symbolId); + IgnoreSymbolId(symbolId, ignoreIds); return false; } if (diffTracker is not null && _diffTracker.SpanExists(span, document.Id)) { - ignoreIds?.Add(GetSymbolId(currentSymbol)); + IgnoreSymbol(currentSymbol, ignoreIds); return false; } - string currentSymbolId = GetSymbolId(currentSymbol); + string? currentSymbolId = GetSymbolId(currentSymbol); if (currentSymbolId is not null) { @@ -581,9 +584,9 @@ private async Task RenameSymbolAsync( HashSet locations = await GetLocationsAsync(referencedSymbols, symbol).ConfigureAwait(false); - document = CurrentSolution.GetDocument(symbolData.DocumentId); - semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); - root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + document = CurrentSolution.GetDocument(symbolData.DocumentId)!; + semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; + root = (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; Location oldLocation = symbol.Locations[0]; TextSpan oldSpan = oldLocation.SourceSpan; @@ -627,10 +630,10 @@ private async Task RenameSymbolAsync( Debug.Assert(string.Equals(newName, newIdentifier.ValueText, StringComparison.Ordinal), $"{newName}\n{newIdentifier.ValueText}"); foreach (IGrouping grouping in locations - .GroupBy(f => newSolution.GetDocument(oldSolution.GetDocumentId(f.SourceTree)).Id)) + .GroupBy(f => newSolution.GetDocument(oldSolution.GetDocumentId(f.SourceTree))!.Id)) { DocumentId documentId = grouping.Key; - Document newDocument = newSolution.GetDocument(documentId); + Document newDocument = newSolution.GetDocument(documentId)!; int offset = 0; foreach (TextSpan span2 in grouping @@ -638,7 +641,7 @@ private async Task RenameSymbolAsync( .OrderBy(f => f.Start)) { var s = new TextSpan(span2.Start + offset, span2.Length + diff); - SyntaxNode r = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode r = (await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; SyntaxToken t = r.FindToken(s.Start, findInsideTrivia: true); // C# string literal token (inside SuppressMessageAttribute) @@ -661,20 +664,23 @@ private async Task RenameSymbolAsync( if (string.Equals(newName, newIdentifier.ValueText, StringComparison.Ordinal) && ignoreIds is not null) { - SyntaxNode newNode = findSymbolService.FindDeclaration(newIdentifier.Parent); + SyntaxNode? newNode = findSymbolService.FindDeclaration(newIdentifier.Parent!); + + if (newNode is null) + throw new InvalidOperationException($"Cannot find declaration for symbol '{symbol.ToDisplayString(SymbolDisplayFormats.FullName)}'."); symbol = semanticModel.GetDeclaredSymbol(newNode, cancellationToken) ?? semanticModel.GetSymbol(newNode, cancellationToken); - Debug.Assert(symbol is not null, GetSymbolId(symbol)); + Debug.Assert(symbol is not null); if (symbol is not null) - ignoreIds.Add(GetSymbolId(symbol)); + IgnoreSymbol(symbol, ignoreIds); } return true; - async Task> GetLocationsAsync(IEnumerable referencedSymbols, ISymbol symbol = null) + async Task> GetLocationsAsync(IEnumerable referencedSymbols, ISymbol? symbol = null) { var locations = new HashSet(); @@ -688,7 +694,7 @@ async Task> GetLocationsAsync(IEnumerable re if (symbol.Name.Length == 4 || symbol.Name.Length != span.Length) { - SyntaxNode root = await location.SourceTree.GetRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode root = await location.SourceTree!.GetRootAsync(cancellationToken).ConfigureAwait(false); SyntaxToken token = root.FindToken(span.Start, findInsideTrivia: true); Debug.Assert(token.Span == span); @@ -729,14 +735,14 @@ IEnumerable GetLocations() protected virtual async Task<(string NewName, Solution NewSolution)> RenameSymbolAsync( ISymbol symbol, - string symbolId, - List ignoreIds, + string? symbolId, + List? ignoreIds, IFindSymbolService findSymbolService, TextSpan span, Document document, CancellationToken cancellationToken) { - Solution newSolution = null; + Solution? newSolution = null; string newName = GetNewName(symbol); if (!findSymbolService.SyntaxFacts.IsValidIdentifier(newName)) @@ -768,7 +774,7 @@ IEnumerable GetLocations() { Report(symbol, newName, SymbolRenameResult.Error, ex); - ignoreIds?.Add(symbolId); + IgnoreSymbolId(symbolId, ignoreIds); return default; } @@ -776,8 +782,8 @@ IEnumerable GetLocations() if (resolution != CompilationErrorResolution.Ignore) { - Project newProject = newSolution.GetDocument(document.Id).Project; - Compilation compilation = await newProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Project newProject = newSolution.GetDocument(document.Id)!.Project; + Compilation compilation = (await newProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; foreach (Diagnostic diagnostic in compilation.GetDiagnostics(cancellationToken)) { @@ -787,7 +793,7 @@ IEnumerable GetLocations() if (resolution == CompilationErrorResolution.Skip) { - ignoreIds?.Add(symbolId); + IgnoreSymbolId(symbolId, ignoreIds); return default; } else if (resolution == CompilationErrorResolution.Throw) @@ -811,12 +817,12 @@ private void Report( ISymbol symbol, string newName, SymbolRenameResult result, - Exception exception = null) + Exception? exception = null) { Progress?.Report(new SymbolRenameProgress(symbol, newName, result, exception)); } - private static string GetSymbolId(ISymbol symbol) + private static string? GetSymbolId(ISymbol symbol) { string id; @@ -877,4 +883,24 @@ private static string GetSymbolId(ISymbol symbol) return symbol.GetDocumentationCommentId(); } + + private static void IgnoreSymbol(ISymbol symbol, List? ignoreIds) + { + if (ignoreIds is not null) + { + string? id = GetSymbolId(symbol); + + if (id is not null) + ignoreIds.Add(id); + } + } + + private static void IgnoreSymbolId(string? symbolId, List? ignoreIds) + { + if (symbolId is not null + && ignoreIds is not null) + { + ignoreIds.Add(symbolId); + } + } } diff --git a/src/Workspaces.Core/Rename/SymbolRenamer.cs b/src/Workspaces.Core/Rename/SymbolRenamer.cs index ef776dacc5..9baebecb10 100644 --- a/src/Workspaces.Core/Rename/SymbolRenamer.cs +++ b/src/Workspaces.Core/Rename/SymbolRenamer.cs @@ -27,8 +27,8 @@ public static async Task RenameSymbolsAsync( Solution solution, Func predicate, Func getNewName, - SymbolRenamerOptions options = null, - IProgress progress = null, + SymbolRenamerOptions? options = null, + IProgress? progress = null, CancellationToken cancellationToken = default) { var renamer = new SymbolRenameState(solution, predicate, getNewName, options, progress); @@ -52,8 +52,8 @@ public static async Task RenameSymbolsAsync( IEnumerable projects, Func predicate, Func getNewName, - SymbolRenamerOptions options = null, - IProgress progress = null, + SymbolRenamerOptions? options = null, + IProgress? progress = null, CancellationToken cancellationToken = default) { if (projects is null) @@ -107,8 +107,8 @@ public static async Task RenameSymbolsAsync( Project project, Func predicate, Func getNewName, - SymbolRenamerOptions options = null, - IProgress progress = null, + SymbolRenamerOptions? options = null, + IProgress? progress = null, CancellationToken cancellationToken = default) { var renamer = new SymbolRenameState(project.Solution, predicate, getNewName, options, progress); diff --git a/src/Workspaces.Core/Rename/SymbolRenamerOptions.cs b/src/Workspaces.Core/Rename/SymbolRenamerOptions.cs index ed4dbafce5..90c5619a70 100644 --- a/src/Workspaces.Core/Rename/SymbolRenamerOptions.cs +++ b/src/Workspaces.Core/Rename/SymbolRenamerOptions.cs @@ -65,5 +65,5 @@ public class SymbolRenamerOptions public bool RenameFile { get; set; } //TODO: SymbolRenameOptions.FileSystemMatcher - internal Matcher FileSystemMatcher { get; set; } + internal Matcher? FileSystemMatcher { get; set; } } diff --git a/src/Workspaces.Core/SimpleProjectInfo.cs b/src/Workspaces.Core/SimpleProjectInfo.cs index 983e42d387..fce5f98521 100644 --- a/src/Workspaces.Core/SimpleProjectInfo.cs +++ b/src/Workspaces.Core/SimpleProjectInfo.cs @@ -8,7 +8,7 @@ namespace Roslynator; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal readonly struct SimpleProjectInfo { - public SimpleProjectInfo(string name, string filePath) + public SimpleProjectInfo(string name, string? filePath) { Name = name; FilePath = filePath; @@ -16,7 +16,7 @@ public SimpleProjectInfo(string name, string filePath) public string Name { get; } - public string FilePath { get; } + public string? FilePath { get; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] private string DebuggerDisplay => $"{Name} {FilePath}"; diff --git a/src/Workspaces.Core/Spelling/Core/FixList.cs b/src/Workspaces.Core/Spelling/Core/FixList.cs index a4c02d59be..ed250f65ee 100644 --- a/src/Workspaces.Core/Spelling/Core/FixList.cs +++ b/src/Workspaces.Core/Spelling/Core/FixList.cs @@ -31,7 +31,7 @@ public FixList(ImmutableDictionary> values public bool ContainsKey(string key) => Items.ContainsKey(key); - public bool TryGetValue(string key, out ImmutableHashSet value) + public bool TryGetValue(string key, out ImmutableHashSet? value) { return Items.TryGetValue(key, out value); } @@ -43,7 +43,7 @@ public bool TryGetKey(string equalKey, out string actualKey) public FixList Add(string key, SpellingFix fix) { - if (Items.TryGetValue(key, out ImmutableHashSet fixes)) + if (Items.TryGetValue(key, out ImmutableHashSet? fixes)) { if (fixes.Contains(fix)) return this; diff --git a/src/Workspaces.Core/Spelling/Core/Spellchecker.Identifier.cs b/src/Workspaces.Core/Spelling/Core/Spellchecker.Identifier.cs index 5e6f8ac57c..a12c6818e7 100644 --- a/src/Workspaces.Core/Spelling/Core/Spellchecker.Identifier.cs +++ b/src/Workspaces.Core/Spelling/Core/Spellchecker.Identifier.cs @@ -22,7 +22,7 @@ internal ImmutableArray AnalyzeIdentifier(string value, int prefi return ImmutableArray.Empty; } - ImmutableArray.Builder builder = null; + ImmutableArray.Builder? builder = null; Match match = _splitIdentifierRegex.Match(value, prefixLength); @@ -68,8 +68,8 @@ internal ImmutableArray AnalyzeIdentifier(string value, int prefi private void AnalyzeIdentifierValue( string value, int valueIndex, - string parentValue, - ref ImmutableArray.Builder builder) + string? parentValue, + ref ImmutableArray.Builder? builder) { if (IsMatch(value)) { diff --git a/src/Workspaces.Core/Spelling/Core/Spellchecker.cs b/src/Workspaces.Core/Spelling/Core/Spellchecker.cs index b8c086f209..a854e7bce7 100644 --- a/src/Workspaces.Core/Spelling/Core/Spellchecker.cs +++ b/src/Workspaces.Core/Spelling/Core/Spellchecker.cs @@ -53,7 +53,7 @@ internal partial class Spellchecker public Spellchecker( SpellingData data, - SpellcheckerOptions options = null) + SpellcheckerOptions? options = null) { Data = data; Options = options ?? SpellcheckerOptions.Default; @@ -61,7 +61,7 @@ public Spellchecker( public ImmutableArray AnalyzeText(string value) { - ImmutableArray.Builder builder = null; + ImmutableArray.Builder? builder = null; int prevEnd = 0; @@ -85,7 +85,7 @@ private void AnalyzeTextSegment( string value, int startIndex, int length, - ref ImmutableArray.Builder builder) + ref ImmutableArray.Builder? builder) { int sequenceEndIndex = -1; @@ -125,7 +125,7 @@ private void AnalyzeWord( string input, string value, int index, - ref ImmutableArray.Builder builder) + ref ImmutableArray.Builder? builder) { Match match = _splitRegex.Match(value); @@ -154,9 +154,9 @@ private void AnalyzeWordPart( string input, string value, int index, - string parentValue, + string? parentValue, int parentIndex, - ref ImmutableArray.Builder builder) + ref ImmutableArray.Builder? builder) { if (IsMatch(value) && !IsContainedInNonWord(input, value, index, Data.WordList) diff --git a/src/Workspaces.Core/Spelling/Core/SpellingCapture.cs b/src/Workspaces.Core/Spelling/Core/SpellingCapture.cs index 2b74424fb6..e5457b5635 100644 --- a/src/Workspaces.Core/Spelling/Core/SpellingCapture.cs +++ b/src/Workspaces.Core/Spelling/Core/SpellingCapture.cs @@ -7,7 +7,7 @@ namespace Roslynator.Spelling; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal class SpellingCapture { - public SpellingCapture(string value, int index, string containingValue = null, int containingValueIndex = -1) + public SpellingCapture(string value, int index, string? containingValue = null, int containingValueIndex = -1) { Value = value; Index = index; @@ -21,7 +21,7 @@ public SpellingCapture(string value, int index, string containingValue = null, i public int Length => Value.Length; - public string ContainingValue { get; } + public string? ContainingValue { get; } public int ContainingValueIndex { get; } diff --git a/src/Workspaces.Core/Spelling/Core/SpellingData.cs b/src/Workspaces.Core/Spelling/Core/SpellingData.cs index 45a39055f2..5fa373437b 100644 --- a/src/Workspaces.Core/Spelling/Core/SpellingData.cs +++ b/src/Workspaces.Core/Spelling/Core/SpellingData.cs @@ -11,9 +11,9 @@ namespace Roslynator.Spelling; internal class SpellingData { - private WordCharMap _charIndexMap; - private WordCharMap _reversedCharIndexMap; - private ImmutableDictionary> _charMap; + private WordCharMap? _charIndexMap; + private WordCharMap? _reversedCharIndexMap; + private ImmutableDictionary>? _charMap; public SpellingData( WordList words, diff --git a/src/Workspaces.Core/Spelling/Core/SpellingFixProvider.cs b/src/Workspaces.Core/Spelling/Core/SpellingFixProvider.cs index dc721f613d..b044c235e6 100644 --- a/src/Workspaces.Core/Spelling/Core/SpellingFixProvider.cs +++ b/src/Workspaces.Core/Spelling/Core/SpellingFixProvider.cs @@ -19,7 +19,7 @@ public static ImmutableArray Fuzzy( if (length <= 3) return ImmutableArray.Empty; - ImmutableHashSet.Builder matches = null; + ImmutableHashSet.Builder? matches = null; WordCharMap map = spellingData.CharIndexMap; WordCharMap reversedMap = spellingData.ReversedCharIndexMap; var intersects = new ImmutableHashSet[length]; @@ -29,12 +29,12 @@ public static ImmutableArray Fuzzy( { cancellationToken.ThrowIfCancellationRequested(); - if (!map.TryGetValue(value, i, out ImmutableHashSet values)) + if (!map.TryGetValue(value, i, out ImmutableHashSet? values)) break; ImmutableHashSet intersect = (i == 0) - ? values - : intersects[i - 1].Intersect(values); + ? values! + : intersects[i - 1].Intersect(values!); if (i == length - 2) { @@ -59,12 +59,12 @@ public static ImmutableArray Fuzzy( { cancellationToken.ThrowIfCancellationRequested(); - if (!reversedMap.TryGetValue(value[j], length - j - 1, out ImmutableHashSet values)) + if (!reversedMap.TryGetValue(value[j], length - j - 1, out ImmutableHashSet? values)) break; ImmutableHashSet intersect = (j == length - 1) - ? values - : values.Intersect(intersects[j + 1]); + ? values! + : values!.Intersect(intersects[j + 1]); if (j == 1) { @@ -108,7 +108,7 @@ public static ImmutableArray Fuzzy( private static bool TryAddMatches( ImmutableHashSet values, int requiredLength, - ref ImmutableHashSet.Builder matches) + ref ImmutableHashSet.Builder? matches) { return TryAddMatches(values, requiredLength, requiredLength, ref matches); } @@ -117,7 +117,7 @@ private static bool TryAddMatches( ImmutableHashSet values, int minRequiredLength, int maxRequiredLength, - ref ImmutableHashSet.Builder matches) + ref ImmutableHashSet.Builder? matches) { var success = false; @@ -143,7 +143,7 @@ public static ImmutableArray SwapLetters(string value, SpellingData spel if (length < 4) return ImmutableArray.Empty; - ImmutableArray.Builder fixes = null; + ImmutableArray.Builder? fixes = null; char[] arr = value.ToCharArray(); @@ -151,7 +151,7 @@ public static ImmutableArray SwapLetters(string value, SpellingData spel var key = new string(arr); - if (!spellingData.CharMap.TryGetValue(key, out ImmutableHashSet values)) + if (!spellingData.CharMap.TryGetValue(key, out ImmutableHashSet? values)) return ImmutableArray.Empty; int maxCharDiff = (length <= 6) ? 2 : 3; diff --git a/src/Workspaces.Core/Spelling/Core/SpellingMatch.cs b/src/Workspaces.Core/Spelling/Core/SpellingMatch.cs index a9972c4de4..4cfa71adba 100644 --- a/src/Workspaces.Core/Spelling/Core/SpellingMatch.cs +++ b/src/Workspaces.Core/Spelling/Core/SpellingMatch.cs @@ -7,7 +7,7 @@ namespace Roslynator.Spelling; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal readonly struct SpellingMatch { - public SpellingMatch(string value, int index, string parent = null, int parentIndex = 0) + public SpellingMatch(string value, int index, string? parent = null, int parentIndex = 0) { Value = value; Index = index; @@ -19,7 +19,7 @@ public SpellingMatch(string value, int index, string parent = null, int parentIn public int Index { get; } - public string Parent { get; } + public string? Parent { get; } public int ParentIndex { get; } diff --git a/src/Workspaces.Core/Spelling/Core/SplitUtility.cs b/src/Workspaces.Core/Spelling/Core/SplitUtility.cs index 34b19e774f..6d324f55bf 100644 --- a/src/Workspaces.Core/Spelling/Core/SplitUtility.cs +++ b/src/Workspaces.Core/Spelling/Core/SplitUtility.cs @@ -33,7 +33,7 @@ internal static class SplitUtility "-|" + _splitCasePattern, RegexOptions.IgnorePatternWhitespace); - public static Regex GetSplitRegex(SplitMode splitMode) + public static Regex? GetSplitRegex(SplitMode splitMode) { return splitMode switch { diff --git a/src/Workspaces.Core/Spelling/Core/WordCharMap.cs b/src/Workspaces.Core/Spelling/Core/WordCharMap.cs index 49161ae2d1..fcc000b4b7 100644 --- a/src/Workspaces.Core/Spelling/Core/WordCharMap.cs +++ b/src/Workspaces.Core/Spelling/Core/WordCharMap.cs @@ -28,17 +28,17 @@ private WordCharMap(WordList list, ImmutableDictionary value) + public bool TryGetValue(WordChar wordChar, out ImmutableHashSet? value) { return Map.TryGetValue(wordChar, out value); } - public bool TryGetValue(string word, int index, out ImmutableHashSet value) + public bool TryGetValue(string word, int index, out ImmutableHashSet? value) { return Map.TryGetValue(WordChar.Create(word, index), out value); } - public bool TryGetValue(char ch, int index, out ImmutableHashSet value) + public bool TryGetValue(char ch, int index, out ImmutableHashSet? value) { return Map.TryGetValue(new WordChar(ch, index), out value); } diff --git a/src/Workspaces.Core/Spelling/Core/WordList.cs b/src/Workspaces.Core/Spelling/Core/WordList.cs index 89049c75b0..cb0f70a5b0 100644 --- a/src/Workspaces.Core/Spelling/Core/WordList.cs +++ b/src/Workspaces.Core/Spelling/Core/WordList.cs @@ -18,15 +18,15 @@ internal class WordList public static WordList Default { get; } = new(null, DefaultComparison); - public WordList(IEnumerable values, StringComparison? comparison = null) + public WordList(IEnumerable? values, StringComparison? comparison = null) : this(values, null, ImmutableArray.Empty, comparison) { } public WordList( - IEnumerable words, - IEnumerable nonWords, - IEnumerable sequences, + IEnumerable? words, + IEnumerable? nonWords, + IEnumerable? sequences, StringComparison? comparison = null) { Comparer = StringComparerUtility.FromComparison(comparison ?? DefaultComparison); diff --git a/src/Workspaces.Core/Spelling/Core/WordListLoader.cs b/src/Workspaces.Core/Spelling/Core/WordListLoader.cs index 0c74ad12a9..1a5c99ce4d 100644 --- a/src/Workspaces.Core/Spelling/Core/WordListLoader.cs +++ b/src/Workspaces.Core/Spelling/Core/WordListLoader.cs @@ -36,7 +36,7 @@ public static WordListLoaderResult Load( foreach (string word in state.Words) fixes.Remove(word); - List caseSensitiveWords = state.CaseSensitiveWords; + List? caseSensitiveWords = state.CaseSensitiveWords; if (caseSensitiveWords is not null) { @@ -104,11 +104,11 @@ private static void LoadFile( LoadState state) { List words = state.Words; - List nonWords = state.NonWords; - List caseSensitiveWords = state.CaseSensitiveWords; - List caseSensitiveNonWords = state.CaseSensitiveNonWords; + List? nonWords = state.NonWords; + List? caseSensitiveWords = state.CaseSensitiveWords; + List? caseSensitiveNonWords = state.CaseSensitiveNonWords; List sequences = state.Sequences; - List caseSensitiveSequences = state.CaseSensitiveSequences; + List? caseSensitiveSequences = state.CaseSensitiveSequences; Dictionary> fixes = state.Fixes; foreach (string line in File.ReadLines(path)) @@ -267,11 +267,11 @@ private class LoadState { private LoadState( List words, - List nonWords, - List caseSensitiveWords, - List caseSensitiveNonWords, + List? nonWords, + List? caseSensitiveWords, + List? caseSensitiveNonWords, List sequences, - List caseSensitiveSequences, + List? caseSensitiveSequences, Dictionary> fixes) { Words = words; @@ -289,10 +289,10 @@ public static LoadState Create(WordListLoadOptions options) var sequences = new List(); var fixes = new Dictionary>(WordList.DefaultComparer); - List nonWords = null; - List caseSensitiveWords = null; - List caseSensitiveNonWords = null; - List caseSensitiveSequences = null; + List? nonWords = null; + List? caseSensitiveWords = null; + List? caseSensitiveNonWords = null; + List? caseSensitiveSequences = null; if ((options & WordListLoadOptions.DetectNonWords) != 0) nonWords = new List(); @@ -311,15 +311,15 @@ public static LoadState Create(WordListLoadOptions options) public List Words { get; } - public List NonWords { get; } + public List? NonWords { get; } - public List CaseSensitiveWords { get; } + public List? CaseSensitiveWords { get; } - public List CaseSensitiveNonWords { get; } + public List? CaseSensitiveNonWords { get; } public List Sequences { get; } - public List CaseSensitiveSequences { get; } + public List? CaseSensitiveSequences { get; } public Dictionary> Fixes { get; } } diff --git a/src/Workspaces.Core/Spelling/SpellcheckAnalyzer.cs b/src/Workspaces.Core/Spelling/SpellcheckAnalyzer.cs index f5c3b0d826..052ee1ca07 100644 --- a/src/Workspaces.Core/Spelling/SpellcheckAnalyzer.cs +++ b/src/Workspaces.Core/Spelling/SpellcheckAnalyzer.cs @@ -35,8 +35,8 @@ internal class SpellcheckAnalyzer public SpellcheckAnalyzer( Solution solution, SpellingData spellingData, - IFormatProvider formatProvider = null, - SpellcheckOptions options = null) + IFormatProvider? formatProvider = null, + SpellcheckOptions? options = null) { Workspace = solution.Workspace; @@ -49,7 +49,7 @@ public SpellcheckAnalyzer( public SpellingData SpellingData { get; private set; } - public IFormatProvider FormatProvider { get; } + public IFormatProvider? FormatProvider { get; } public SpellcheckOptions Options { get; } @@ -72,7 +72,7 @@ public async Task> FixSolutionAsync(Func> FixProjectAsync( Project project, CancellationToken cancellationToken = default) { - project = CurrentSolution.GetProject(project.Id); + if (project is null) + throw new ArgumentNullException(nameof(project)); - ISpellingService service = MefWorkspaceServices.Default.GetService(project.Language); + if (!project.SupportsCompilation) + return ImmutableArray.Empty; + + project = CurrentSolution.GetProject(project.Id)!; + + ISpellingService? service = MefWorkspaceServices.Default.GetService(project.Language); if (service is null) return ImmutableArray.Empty; @@ -124,13 +130,13 @@ public async Task> FixProjectAsync( cancellationToken.ThrowIfCancellationRequested(); var compilationWithAnalyzersOptions = new CompilationWithAnalyzersOptions( - options: default(AnalyzerOptions), + options: default(AnalyzerOptions)!, onAnalyzerException: default(Action), concurrentAnalysis: true, logAnalyzerExecutionTime: false, reportSuppressedDiagnostics: false); - Compilation compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Compilation compilation = (await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false))!; DiagnosticAnalyzer analyzer = service.CreateAnalyzer(SpellingData, Options); @@ -216,7 +222,7 @@ public async Task> FixProjectAsync( if (Options.DryRun) break; - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; previousPreviousDiagnostics = previousDiagnostics; previousDiagnostics = diagnostics; @@ -236,20 +242,20 @@ private async Task> FixCommentsAsync( var applyChanges = false; - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; - foreach (IGrouping grouping in commentDiagnostics + foreach (IGrouping grouping in commentDiagnostics .GroupBy(f => f.SyntaxTree)) { cancellationToken.ThrowIfCancellationRequested(); - Document document = project.GetDocument(grouping.Key); + Document document = project.GetDocument(grouping.Key)!; SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - string sourceTextText = (ShouldWrite(Verbosity.Detailed)) ? sourceText.ToString() : null; + string? sourceTextText = (ShouldWrite(Verbosity.Detailed)) ? sourceText.ToString() : null; - List textChanges = null; + List? textChanges = null; foreach (SpellingDiagnostic diagnostic in grouping.OrderBy(f => f.Span.Start)) { @@ -315,13 +321,13 @@ private async Task> FixCommentsAsync( var results = new List(); var allIgnored = true; - List<(SyntaxToken identifier, List diagnostics, DocumentId documentId)> symbolDiagnostics = spellingDiagnostics + List<(SyntaxToken identifier, List diagnostics, DocumentId documentId)> symbolDiagnostics = spellingDiagnostics .Where(f => f.IsSymbol) .GroupBy(f => f.Identifier) .Select(f => ( identifier: f.Key, - diagnostics: f.OrderBy(f => f.Span.Start).ToList(), - documentId: project.GetDocument(f.Key.SyntaxTree).Id)) + diagnostics: f.OrderBy(f => f.Span.Start).Cast().ToList(), + documentId: project.GetDocument(f.Key.SyntaxTree)!.Id)) .OrderBy(f => f.documentId.Id) .ThenByDescending(f => f.identifier.SpanStart) .ToList(); @@ -330,11 +336,11 @@ private async Task> FixCommentsAsync( { cancellationToken.ThrowIfCancellationRequested(); - (SyntaxToken identifier, List diagnostics, DocumentId documentId) = symbolDiagnostics[i]; + (SyntaxToken identifier, List diagnostics, DocumentId documentId) = symbolDiagnostics[i]; - SyntaxNode node = null; + SyntaxNode? node = null; - foreach (SpellingDiagnostic diagnostic in diagnostics) + foreach (SpellingDiagnostic? diagnostic in diagnostics) { if (diagnostic is not null) { @@ -346,7 +352,7 @@ private async Task> FixCommentsAsync( if (node is null) continue; - Document document = project.GetDocument(documentId); + Document document = project.GetDocument(documentId)!; if (document is null) { @@ -356,7 +362,7 @@ private async Task> FixCommentsAsync( continue; } - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode root = (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; if (identifier.SyntaxTree != root.SyntaxTree) { @@ -369,13 +375,13 @@ private async Task> FixCommentsAsync( continue; } - SyntaxNode node2 = identifier2.Parent; + SyntaxNode node2 = identifier2.Parent!; - SyntaxNode n = identifier.Parent; + SyntaxNode n = identifier.Parent!; while (n != node) { - node2 = node2.Parent; - n = n.Parent; + node2 = node2.Parent!; + n = n.Parent!; } identifier = identifier2; @@ -384,23 +390,23 @@ private async Task> FixCommentsAsync( SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); - string sourceTextText = null; + string? sourceTextText = null; - SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); + SemanticModel semanticModel = (await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false))!; - ISymbol symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) + ISymbol? symbol = semanticModel.GetDeclaredSymbol(node, cancellationToken) ?? semanticModel.GetSymbol(node, cancellationToken); if (symbol is null) { // 8925 - C# tuple element - Debug.Assert(identifier.Parent.RawKind == 8925, identifier.ToString()); + Debug.Assert(identifier.Parent?.RawKind == 8925, identifier.ToString()); if (ShouldWrite(Verbosity.Detailed)) { string message = $" Cannot find symbol for '{identifier.ValueText}'"; - string locationText = GetLocationText(identifier.GetLocation(), project); + string? locationText = GetLocationText(identifier.GetLocation(), project); if (locationText is not null) message += $" at {locationText}"; @@ -425,7 +431,7 @@ private async Task> FixCommentsAsync( for (int j = 0; j < diagnostics.Count; j++) { - SpellingDiagnostic diagnostic = diagnostics[j]; + SpellingDiagnostic? diagnostic = diagnostics[j]; if (diagnostic is null) continue; @@ -450,11 +456,11 @@ private async Task> FixCommentsAsync( { for (int k = 0; k < symbolDiagnostics.Count; k++) { - List diagnostics2 = symbolDiagnostics[k].diagnostics; + List diagnostics2 = symbolDiagnostics[k].diagnostics; for (int l = 0; l < diagnostics2.Count; l++) { - if (SpellingData.IgnoredValues.KeyComparer.Equals(diagnostics2[l]?.Value, diagnostic.Value)) + if (SpellingData.IgnoredValues.KeyComparer.Equals(diagnostics2[l]?.Value!, diagnostic.Value)) diagnostics2[l] = null; } } @@ -472,7 +478,7 @@ private async Task> FixCommentsAsync( if (string.Equals(identifier.Text, newName, StringComparison.Ordinal)) continue; - Solution newSolution = null; + Solution? newSolution = null; if (!Options.DryRun) { WriteLine($" Rename '{identifier.ValueText}' to '{newName}'", ConsoleColors.Green, Verbosity.Minimal); @@ -497,7 +503,9 @@ private async Task> FixCommentsAsync( { WriteLine($" Cannot rename '{symbol.Name}'", ConsoleColors.Yellow, Verbosity.Normal); #if DEBUG - WriteLine(document.FilePath); + if (document.FilePath is not null) + WriteLine(document.FilePath); + WriteLine(identifier.ValueText); WriteLine(ex.ToString()); #endif @@ -509,7 +517,7 @@ private async Task> FixCommentsAsync( { if (Workspace.TryApplyChanges(newSolution)) { - project = CurrentSolution.GetProject(project.Id); + project = CurrentSolution.GetProject(project.Id)!; } else { @@ -534,7 +542,7 @@ static void AddResult( SpellingDiagnostic diagnostic, SpellingFix fix, SourceText sourceText, - ref string sourceTextText) + ref string? sourceTextText) { if (sourceTextText is null) sourceTextText = (ShouldWrite(Verbosity.Detailed)) ? sourceText.ToString() : ""; @@ -557,9 +565,9 @@ private SpellingFix GetFix(SpellingDiagnostic diagnostic) TextCasing textCasing = TextUtility.GetTextCasing(value); if (textCasing != TextCasing.Undefined - && SpellingData.Fixes.TryGetValue(value, out ImmutableHashSet possibleFixes)) + && SpellingData.Fixes.TryGetValue(value, out ImmutableHashSet? possibleFixes)) { - SpellingFix fix = possibleFixes.SingleOrDefault( + SpellingFix fix = possibleFixes!.SingleOrDefault( f => (TextUtility.GetTextCasing(f.Value) != TextCasing.Undefined || string.Equals(value, f.Value, StringComparison.OrdinalIgnoreCase)) && diagnostic.IsApplicableFix(f.Value), @@ -631,7 +639,7 @@ private void AddIgnoredValue(SpellingDiagnostic diagnostic) SpellingData = SpellingData.AddIgnoredValue(diagnostic.Value); } - private static string GetLocationText(Location location, Project project) + private static string? GetLocationText(Location location, Project project) { if (location.Kind == LocationKind.SourceFile || location.Kind == LocationKind.XmlFile diff --git a/src/Workspaces.Core/Spelling/SpellcheckOptions.cs b/src/Workspaces.Core/Spelling/SpellcheckOptions.cs index a1205222b3..b46b70ae0b 100644 --- a/src/Workspaces.Core/Spelling/SpellcheckOptions.cs +++ b/src/Workspaces.Core/Spelling/SpellcheckOptions.cs @@ -6,7 +6,7 @@ internal class SpellcheckOptions { public static SpellcheckOptions Default { get; } = new(); - public FileSystemFilter FileSystemFilter { get; init; } + public FileSystemFilter? FileSystemFilter { get; init; } public SpellingScopeFilter ScopeFilter { get; init; } = SpellingScopeFilter.All; diff --git a/src/Workspaces.Core/Spelling/SpellingAnalysisContext.cs b/src/Workspaces.Core/Spelling/SpellingAnalysisContext.cs index b200558e05..513222d064 100644 --- a/src/Workspaces.Core/Spelling/SpellingAnalysisContext.cs +++ b/src/Workspaces.Core/Spelling/SpellingAnalysisContext.cs @@ -50,7 +50,7 @@ public void AnalyzeIdentifier( { ImmutableArray matches = _spellchecker.AnalyzeIdentifier(identifier.ValueText, prefixLength); - ProcessMatches(matches, identifier.Span, identifier.SyntaxTree); + ProcessMatches(matches, identifier.Span, identifier.SyntaxTree!); } private void ProcessMatches( @@ -62,22 +62,22 @@ private void ProcessMatches( { int index = span.Start + match.Index; - ImmutableDictionary properties; + ImmutableDictionary properties; if (match.Parent is not null) { properties = ImmutableDictionary.CreateRange(new[] { - new KeyValuePair("Value", match.Value), - new KeyValuePair("Parent", match.Parent), - new KeyValuePair("ParentIndex", (span.Start + match.ParentIndex).ToString(CultureInfo.InvariantCulture)), + new KeyValuePair("Value", match.Value), + new KeyValuePair("Parent", match.Parent), + new KeyValuePair("ParentIndex", (span.Start + match.ParentIndex).ToString(CultureInfo.InvariantCulture)), }); } else { properties = ImmutableDictionary.CreateRange(new[] { - new KeyValuePair("Value", match.Value) + new KeyValuePair("Value", match.Value) }); } diff --git a/src/Workspaces.Core/Spelling/SpellingDiagnostic.cs b/src/Workspaces.Core/Spelling/SpellingDiagnostic.cs index c4219c61aa..73fd61bfd4 100644 --- a/src/Workspaces.Core/Spelling/SpellingDiagnostic.cs +++ b/src/Workspaces.Core/Spelling/SpellingDiagnostic.cs @@ -10,14 +10,14 @@ namespace Roslynator.Spelling; [DebuggerDisplay("{DebuggerDisplay,nq}")] internal abstract class SpellingDiagnostic { - private string _valueLower; + private string? _valueLower; private TextCasing? _casing; protected SpellingDiagnostic( Diagnostic diagnostic, string value, int index, - string parent, + string? parent, int parentIndex, SyntaxToken identifier = default) { @@ -39,7 +39,7 @@ protected SpellingDiagnostic( public int EndIndex => Index + Value.Length; - public string Parent { get; } + public string? Parent { get; } public int ParentIndex { get; } @@ -47,9 +47,9 @@ protected SpellingDiagnostic( public Location Location => Diagnostic.Location; - public SyntaxTree SyntaxTree => Location.SourceTree; + public SyntaxTree? SyntaxTree => Location.SourceTree; - public string FilePath => SyntaxTree?.FilePath; + public string? FilePath => SyntaxTree?.FilePath; public TextSpan Span => Location.SourceSpan; diff --git a/src/Workspaces.Core/Spelling/SpellingFixHelpers.cs b/src/Workspaces.Core/Spelling/SpellingFixHelpers.cs index d45bc3752a..3f1e1d7fb1 100644 --- a/src/Workspaces.Core/Spelling/SpellingFixHelpers.cs +++ b/src/Workspaces.Core/Spelling/SpellingFixHelpers.cs @@ -131,7 +131,7 @@ private void WriteSuggestion( bool interactive) { string value = diagnostic.Value; - string containingValue = diagnostic.Parent; + string? containingValue = diagnostic.Parent; if (index == 0) { @@ -187,7 +187,7 @@ private static bool TryReadSuggestion(out int index) { Write(" Enter number of a suggestion: "); - string text = Console.ReadLine()?.Trim(); + string? text = Console.ReadLine()?.Trim(); if (text?.Length == 1) { @@ -224,7 +224,7 @@ private static ImmutableArray GetSplitIndexes( string value = diagnostic.Value; int length = value.Length; - ImmutableArray.Builder splitIndexes = null; + ImmutableArray.Builder? splitIndexes = null; if (length >= 4) { @@ -253,10 +253,10 @@ private static ImmutableArray GetSplitIndexes( { cancellationToken.ThrowIfCancellationRequested(); - if (!map.TryGetValue(value, i, out ImmutableHashSet values2)) + if (!map.TryGetValue(value, i, out ImmutableHashSet? values2)) break; - values = (i == 0) ? values2 : values.Intersect(values2); + values = (i == 0) ? values2! : values.Intersect(values2!); if (values.Count == 0) break; @@ -273,10 +273,10 @@ private static ImmutableArray GetSplitIndexes( for (int j = i + 1; j < length; j++) { - if (!map.TryGetValue(value[j], j - i - 1, out ImmutableHashSet values4)) + if (!map.TryGetValue(value[j], j - i - 1, out ImmutableHashSet? values4)) break; - values3 = (j == i + 1) ? values4 : values3.Intersect(values4); + values3 = (j == i + 1) ? values4! : values3.Intersect(values4!); if (values3.Count == 0) break; diff --git a/src/Workspaces.Core/Spelling/SpellingFixResult.cs b/src/Workspaces.Core/Spelling/SpellingFixResult.cs index eb3065f721..33ead671a3 100644 --- a/src/Workspaces.Core/Spelling/SpellingFixResult.cs +++ b/src/Workspaces.Core/Spelling/SpellingFixResult.cs @@ -1,5 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; @@ -13,7 +14,7 @@ internal sealed class SpellingFixResult private int _lineEndIndex = -1; private SpellingFixResult( - string sourceText, + string? sourceText, SpellingCapture capture, TextSpan span, SpellingFix fix, @@ -26,12 +27,12 @@ private SpellingFixResult( LineSpan = lineSpan; } - public static SpellingFixResult Create(string sourceText, SpellingDiagnostic diagnostic) + public static SpellingFixResult Create(string? sourceText, SpellingDiagnostic diagnostic) { return Create(sourceText, diagnostic, default); } - public static SpellingFixResult Create(string sourceText, SpellingDiagnostic diagnostic, SpellingFix fix) + public static SpellingFixResult Create(string? sourceText, SpellingDiagnostic diagnostic, SpellingFix fix) { return new SpellingFixResult( sourceText, @@ -41,7 +42,7 @@ public static SpellingFixResult Create(string sourceText, SpellingDiagnostic dia diagnostic.Location.GetMappedLineSpan()); } - public string SourceText { get; } + public string? SourceText { get; } public SpellingCapture Capture { get; } @@ -51,7 +52,7 @@ public static SpellingFixResult Create(string sourceText, SpellingDiagnostic dia public int Length => Capture.Length; - public string ContainingValue => Capture.ContainingValue; + public string? ContainingValue => Capture.ContainingValue; public int ContainingValueIndex => Capture.ContainingValueIndex; @@ -90,7 +91,12 @@ public int LineEndIndex get { if (_lineEndIndex == -1) + { + if (SourceText is null) + throw new InvalidOperationException("Source text is not provided."); + _lineEndIndex = TextUtility.GetLineEndIndex(SourceText, Index + Length); + } return _lineEndIndex; } diff --git a/src/Workspaces.Core/SyntaxFinder.cs b/src/Workspaces.Core/SyntaxFinder.cs index 7067b1e10e..e0834d2f86 100644 --- a/src/Workspaces.Core/SyntaxFinder.cs +++ b/src/Workspaces.Core/SyntaxFinder.cs @@ -26,7 +26,7 @@ public static Task> FindReferencesAsync( public static async Task> FindReferencesAsync( ISymbol symbol, Solution solution, - IImmutableSet documents, + IImmutableSet? documents, bool allowCandidate = false, CancellationToken cancellationToken = default) { @@ -36,7 +36,7 @@ public static async Task> FindReferencesAsync( if (solution is null) throw new ArgumentNullException(nameof(solution)); - List nodes = null; + List? nodes = null; foreach (ReferencedSymbol referencedSymbol in await SymbolFinder.FindReferencesAsync( symbol, @@ -49,9 +49,10 @@ public static async Task> FindReferencesAsync( { Document document = grouping.Key; - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - FindReferences(grouping, root, allowCandidate, ref nodes); + if (root is not null) + FindReferences(grouping, root, allowCandidate, ref nodes); } } @@ -70,7 +71,7 @@ public static Task> FindReferencesByDocume public static async Task> FindReferencesByDocumentAsync( ISymbol symbol, Solution solution, - IImmutableSet documents, + IImmutableSet? documents, bool allowCandidate = false, CancellationToken cancellationToken = default) { @@ -80,7 +81,7 @@ public static async Task> FindReferencesBy if (solution is null) throw new ArgumentNullException(nameof(solution)); - List infos = null; + List? infos = null; foreach (ReferencedSymbol referencedSymbol in await SymbolFinder.FindReferencesAsync( symbol, @@ -93,17 +94,20 @@ public static async Task> FindReferencesBy { Document document = grouping.Key; - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + SyntaxNode? root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); - List nodes = null; + if (root is not null) + { + List? nodes = null; - FindReferences(grouping, root, allowCandidate, ref nodes); + FindReferences(grouping, root, allowCandidate, ref nodes); - if (nodes is not null) - { - var info = new DocumentReferenceInfo(document, root, nodes.ToImmutableArray()); + if (nodes is not null) + { + var info = new DocumentReferenceInfo(document, root, nodes.ToImmutableArray()); - (infos ??= new List()).Add(info); + (infos ??= new List()).Add(info); + } } } } @@ -123,9 +127,12 @@ public static async Task> FindReferencesAsync( if (document is null) throw new ArgumentNullException(nameof(document)); - SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + if (!document.SupportsSyntaxTree) + throw new ArgumentException("Document does not support syntax tree.", nameof(document)); + + SyntaxNode root = (await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false))!; - List nodes = null; + List? nodes = null; foreach (ReferencedSymbol referencedSymbol in await SymbolFinder.FindReferencesAsync( symbol, @@ -144,7 +151,7 @@ private static void FindReferences( IEnumerable referenceLocations, SyntaxNode root, bool allowCandidate, - ref List nodes) + ref List? nodes) { foreach (ReferenceLocation referenceLocation in referenceLocations) { @@ -155,9 +162,10 @@ private static void FindReferences( if (location.IsInSource) { - SyntaxNode node = root.FindNode(location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true); + SyntaxNode? node = root.FindNode(location.SourceSpan, findInsideTrivia: true, getInnermostNodeForTie: true); - Debug.Assert(node is not null); + if (node is null) + throw new InvalidOperationException("Syntax node was not found."); (nodes ??= new List()).Add(node); } @@ -165,7 +173,7 @@ private static void FindReferences( } } - private static ImmutableArray ToImmutableArray(IEnumerable nodes) + private static ImmutableArray ToImmutableArray(IEnumerable? nodes) { if (nodes is not null) { diff --git a/src/Workspaces.Core/UnusedSymbolUtility.cs b/src/Workspaces.Core/UnusedSymbolUtility.cs index a39c875076..ee5019a8c4 100644 --- a/src/Workspaces.Core/UnusedSymbolUtility.cs +++ b/src/Workspaces.Core/UnusedSymbolUtility.cs @@ -196,7 +196,7 @@ private static bool IsReferencedInDebuggerDisplayAttribute(ISymbol symbol) if (symbol.DeclaredAccessibility == Accessibility.Private && CanBeReferencedInDebuggerDisplayAttribute()) { - string value = symbol.ContainingType + string? value = symbol.ContainingType .GetAttribute(MetadataNames.System_Diagnostics_DebuggerDisplayAttribute)? .ConstructorArguments .SingleOrDefault(shouldThrow: false) diff --git a/src/Workspaces.Core/Workspaces.Core.csproj b/src/Workspaces.Core/Workspaces.Core.csproj index 7935c38e7e..aa578f3915 100644 --- a/src/Workspaces.Core/Workspaces.Core.csproj +++ b/src/Workspaces.Core/Workspaces.Core.csproj @@ -8,6 +8,7 @@ $(RoslynatorCoreVersion) $(RoslynatorDllPrefix)Roslynator.Workspaces.Core Roslynator + enable