From 1c30027a9d789bbe3fce5a7da3da8113e942114e Mon Sep 17 00:00:00 2001 From: Maksym Koshovyi Date: Wed, 6 Oct 2021 23:56:06 +0300 Subject: [PATCH] [Group 1] Enable nullable annotations for `Microsoft.Extensions.FileSystemGlobbing` (#57398) * Annotate src * Annotate ref * Null check for directoryInfo * Nullcheck for PatternMatchingResult.Files * ParentDirectory cannot be null ! need to be addressed * Update PatternBuilder.cs * Use expression body in segments * Update ref * DisableImplicitAssemblyReferences * Fix doc * TestMatchingGroup nonnull * ParentDirectory can be null * Update TestGetHashCodeWithNull * Update FilePatternMatchTests.cs * Update FilePatternMatchTests.cs * Remove TestGetHashCodeWithNull * InMemoryFileInfo.ParentDirectory is not null --- ...Microsoft.Extensions.FileSystemGlobbing.cs | 42 +++++++++---------- ...osoft.Extensions.FileSystemGlobbing.csproj | 1 + .../src/Abstractions/DirectoryInfoBase.cs | 4 +- .../src/Abstractions/DirectoryInfoWrapper.cs | 9 ++-- .../src/Abstractions/FileInfoWrapper.cs | 6 ++- .../src/Abstractions/FileSystemInfoBase.cs | 2 +- .../src/FilePatternMatch.cs | 15 ++++--- .../src/InMemoryDirectoryInfo.cs | 23 ++++------ .../src/Internal/InMemoryFileInfo.cs | 8 +--- .../src/Internal/MatcherContext.cs | 17 ++++---- .../PathSegments/CurrentPathSegment.cs | 7 +--- .../PathSegments/LiteralPathSegment.cs | 16 +++---- .../PathSegments/ParentPathSegment.cs | 2 +- .../PathSegments/RecursiveWildcardSegment.cs | 7 +--- .../PathSegments/WildcardPathSegment.cs | 6 +-- .../PatternContexts/PatternContext.cs | 6 +-- .../PatternContexts/PatternContextLinear.cs | 14 ++----- .../PatternContexts/PatternContextRagged.cs | 18 +++----- .../src/Internal/PatternTestResult.cs | 8 ++-- .../src/Internal/Patterns/PatternBuilder.cs | 16 +++---- .../src/Matcher.cs | 7 +++- .../src/MatcherExtensions.cs | 4 +- ...osoft.Extensions.FileSystemGlobbing.csproj | 10 ++--- .../src/PatternMatchingResult.cs | 3 +- .../src/Util/StringComparisonHelper.cs | 28 ++++--------- .../tests/FilePatternMatchTests.cs | 13 ------ 26 files changed, 116 insertions(+), 176 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.cs index 3ff755ae723e3c..84065adee229ce 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.cs @@ -10,22 +10,22 @@ public partial struct FilePatternMatch : System.IEquatable files) { } + public InMemoryDirectoryInfo(string rootDir, System.Collections.Generic.IEnumerable? files) { } public override string FullName { get { throw null; } } public override string Name { get { throw null; } } - public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase ParentDirectory { get { throw null; } } + public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase? ParentDirectory { get { throw null; } } public override System.Collections.Generic.IEnumerable EnumerateFileSystemInfos() { throw null; } public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase GetDirectory(string path) { throw null; } - public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileInfoBase GetFile(string path) { throw null; } + public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileInfoBase? GetFile(string path) { throw null; } } public partial class Matcher { @@ -40,9 +40,9 @@ public static partial class MatcherExtensions public static void AddExcludePatterns(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, params System.Collections.Generic.IEnumerable[] excludePatternsGroups) { } public static void AddIncludePatterns(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, params System.Collections.Generic.IEnumerable[] includePatternsGroups) { } public static System.Collections.Generic.IEnumerable GetResultsInFullPath(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, string directoryPath) { throw null; } - public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, System.Collections.Generic.IEnumerable files) { throw null; } + public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, System.Collections.Generic.IEnumerable? files) { throw null; } public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, string file) { throw null; } - public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, string rootDir, System.Collections.Generic.IEnumerable files) { throw null; } + public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, string rootDir, System.Collections.Generic.IEnumerable? files) { throw null; } public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, string rootDir, string file) { throw null; } } public partial class PatternMatchingResult @@ -59,17 +59,17 @@ public abstract partial class DirectoryInfoBase : Microsoft.Extensions.FileSyste { protected DirectoryInfoBase() { } public abstract System.Collections.Generic.IEnumerable EnumerateFileSystemInfos(); - public abstract Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase GetDirectory(string path); - public abstract Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileInfoBase GetFile(string path); + public abstract Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase? GetDirectory(string path); + public abstract Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileInfoBase? GetFile(string path); } public partial class DirectoryInfoWrapper : Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase { public DirectoryInfoWrapper(System.IO.DirectoryInfo directoryInfo) { } public override string FullName { get { throw null; } } public override string Name { get { throw null; } } - public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase ParentDirectory { get { throw null; } } + public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase? ParentDirectory { get { throw null; } } public override System.Collections.Generic.IEnumerable EnumerateFileSystemInfos() { throw null; } - public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase GetDirectory(string name) { throw null; } + public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase? GetDirectory(string name) { throw null; } public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileInfoBase GetFile(string name) { throw null; } } public abstract partial class FileInfoBase : Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileSystemInfoBase @@ -81,14 +81,14 @@ public partial class FileInfoWrapper : Microsoft.Extensions.FileSystemGlobbing.A public FileInfoWrapper(System.IO.FileInfo fileInfo) { } public override string FullName { get { throw null; } } public override string Name { get { throw null; } } - public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase ParentDirectory { get { throw null; } } + public override Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase? ParentDirectory { get { throw null; } } } public abstract partial class FileSystemInfoBase { protected FileSystemInfoBase() { } public abstract string FullName { get; } public abstract string Name { get; } - public abstract Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase ParentDirectory { get; } + public abstract Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase? ParentDirectory { get; } } } namespace Microsoft.Extensions.FileSystemGlobbing.Internal @@ -133,8 +133,8 @@ public partial struct PatternTestResult private int _dummyPrimitive; public static readonly Microsoft.Extensions.FileSystemGlobbing.Internal.PatternTestResult Failed; public readonly bool IsSuccessful { get { throw null; } } - public readonly string Stem { get { throw null; } } - public static Microsoft.Extensions.FileSystemGlobbing.Internal.PatternTestResult Success(string stem) { throw null; } + public readonly string? Stem { get { throw null; } } + public static Microsoft.Extensions.FileSystemGlobbing.Internal.PatternTestResult Success(string? stem) { throw null; } } } namespace Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments @@ -150,7 +150,7 @@ public partial class LiteralPathSegment : Microsoft.Extensions.FileSystemGlobbin public LiteralPathSegment(string value, System.StringComparison comparisonType) { } public bool CanProduceStem { get { throw null; } } public string Value { get { throw null; } } - public override bool Equals(object obj) { throw null; } + public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public override int GetHashCode() { throw null; } public bool Match(string value) { throw null; } } @@ -195,7 +195,7 @@ public partial struct FrameData public bool InStem; public bool IsNotApplicable; public int SegmentIndex; - public string Stem { get { throw null; } } + public string? Stem { get { throw null; } } public System.Collections.Generic.IList StemItems { get { throw null; } } } } @@ -232,7 +232,7 @@ public partial struct FrameData public System.Collections.Generic.IList SegmentGroup; public int SegmentGroupIndex; public int SegmentIndex; - public string Stem { get { throw null; } } + public string? Stem { get { throw null; } } public System.Collections.Generic.IList StemItems { get { throw null; } } } } @@ -249,12 +249,12 @@ public override void Declare(System.Action : Microsoft.Extensions.FileSystemGlobbing.Internal.IPatternContext { - protected TFrame Frame; + protected TFrame? Frame; protected PatternContext() { } public virtual void Declare(System.Action declare) { } protected bool IsStackEmpty() { throw null; } public virtual void PopDirectory() { } - protected void PushDataFrame(TFrame frame) { } + protected void PushDataFrame(TFrame? frame) { } public abstract void PushDirectory(Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase directory); public abstract bool Test(Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase directory); public abstract Microsoft.Extensions.FileSystemGlobbing.Internal.PatternTestResult Test(Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileInfoBase file); diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj index c2d428aae02abc..6777e099720efc 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/ref/Microsoft.Extensions.FileSystemGlobbing.csproj @@ -1,6 +1,7 @@ $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) + enable diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoBase.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoBase.cs index f520c2a6276562..6b5e61b0ad1c32 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoBase.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoBase.cs @@ -21,13 +21,13 @@ public abstract class DirectoryInfoBase : FileSystemInfoBase /// /// The directory name /// Instance of even if directory does not exist - public abstract DirectoryInfoBase GetDirectory(string path); + public abstract DirectoryInfoBase? GetDirectory(string path); /// /// Returns an instance of that represents a file in the directory /// /// The file name /// Instance of even if file does not exist - public abstract FileInfoBase GetFile(string path); + public abstract FileInfoBase? GetFile(string path); } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoWrapper.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoWrapper.cs index 884c887aa55564..a0b4489a5f399c 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoWrapper.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/DirectoryInfoWrapper.cs @@ -47,8 +47,7 @@ public override IEnumerable EnumerateFileSystemInfos() foreach (FileSystemInfo fileSystemInfo in fileSystemInfos) { - var directoryInfo = fileSystemInfo as DirectoryInfo; - if (directoryInfo != null) + if (fileSystemInfo is DirectoryInfo directoryInfo) { yield return new DirectoryInfoWrapper(directoryInfo); } @@ -68,7 +67,7 @@ public override IEnumerable EnumerateFileSystemInfos() /// /// The directory name /// The directory - public override DirectoryInfoBase GetDirectory(string name) + public override DirectoryInfoBase? GetDirectory(string name) { bool isParentPath = string.Equals(name, "..", StringComparison.Ordinal); @@ -120,7 +119,7 @@ public override FileInfoBase GetFile(string name) /// /// Equals the value of . /// - public override DirectoryInfoBase ParentDirectory - => new DirectoryInfoWrapper(_directoryInfo.Parent); + public override DirectoryInfoBase? ParentDirectory + => new DirectoryInfoWrapper(_directoryInfo.Parent!); } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileInfoWrapper.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileInfoWrapper.cs index 9ef3a911a0e162..3967a31da9c265 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileInfoWrapper.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileInfoWrapper.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.IO; namespace Microsoft.Extensions.FileSystemGlobbing.Abstractions @@ -18,7 +19,7 @@ public class FileInfoWrapper : FileInfoBase /// The public FileInfoWrapper(FileInfo fileInfo) { - _fileInfo = fileInfo; + _fileInfo = fileInfo ?? throw new ArgumentNullException(nameof(fileInfo)); } /// @@ -43,6 +44,7 @@ public FileInfoWrapper(FileInfo fileInfo) /// /// Equals the value of . /// - public override DirectoryInfoBase ParentDirectory => new DirectoryInfoWrapper(_fileInfo.Directory); + public override DirectoryInfoBase? ParentDirectory + => new DirectoryInfoWrapper(_fileInfo.Directory!); } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileSystemInfoBase.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileSystemInfoBase.cs index fc50849ad00e2c..8f6f8bf3a2aa58 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileSystemInfoBase.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Abstractions/FileSystemInfoBase.cs @@ -21,6 +21,6 @@ public abstract class FileSystemInfoBase /// /// The parent directory for the current file or directory /// - public abstract DirectoryInfoBase ParentDirectory { get; } + public abstract DirectoryInfoBase? ParentDirectory { get; } } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs index 21d291a2434160..79390d6fd6bffb 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/FilePatternMatch.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using System.Numerics.Hashing; namespace Microsoft.Extensions.FileSystemGlobbing @@ -27,16 +28,16 @@ public struct FilePatternMatch : IEquatable /// If the matcher searched for "src/Project/**/*.cs" and the pattern matcher found "src/Project/Interfaces/IFile.cs", /// then = "Interfaces/IFile.cs" and = "src/Project/Interfaces/IFile.cs". /// - public string Stem { get; } + public string? Stem { get; } /// /// Initializes new instance of /// /// The path to the file matched, relative to the beginning of the matching search pattern. /// The subpath to the file matched, relative to the first wildcard in the matching search pattern. - public FilePatternMatch(string path, string stem) + public FilePatternMatch(string path, string? stem) { - Path = path; + Path = path ?? throw new ArgumentNullException(nameof(path)); Stem = stem; } @@ -56,10 +57,8 @@ public bool Equals(FilePatternMatch other) /// /// The object to be compared /// True when - public override bool Equals(object obj) - { - return Equals((FilePatternMatch) obj); - } + public override bool Equals([NotNullWhen(true)] object? obj) => + obj is FilePatternMatch match && Equals(match); /// /// Gets a hash for the file pattern match. @@ -68,7 +67,7 @@ public override bool Equals(object obj) public override int GetHashCode() => HashHelpers.Combine(GetHashCode(Path), GetHashCode(Stem)); - private static int GetHashCode(string value) => + private static int GetHashCode(string? value) => value != null ? StringComparer.OrdinalIgnoreCase.GetHashCode(value) : 0; } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/InMemoryDirectoryInfo.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/InMemoryDirectoryInfo.cs index 55688a8baf4d52..9f0c95f2d55f3b 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/InMemoryDirectoryInfo.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/InMemoryDirectoryInfo.cs @@ -23,22 +23,19 @@ public class InMemoryDirectoryInfo : DirectoryInfoBase /// /// The root directory that this FileSystem will use. /// Collection of file names. If relative paths will be prepended to the paths. - public InMemoryDirectoryInfo(string rootDir, IEnumerable files) + public InMemoryDirectoryInfo(string rootDir, IEnumerable? files) : this(rootDir, files, false) { } - private InMemoryDirectoryInfo(string rootDir, IEnumerable files, bool normalized) + private InMemoryDirectoryInfo(string rootDir, IEnumerable? files, bool normalized) { if (string.IsNullOrEmpty(rootDir)) { throw new ArgumentNullException(nameof(rootDir)); } - if (files == null) - { - files = new List(); - } + files ??= new List(); Name = Path.GetFileName(rootDir); if (normalized) @@ -69,13 +66,8 @@ private InMemoryDirectoryInfo(string rootDir, IEnumerable files, bool no public override string Name { get; } /// - public override DirectoryInfoBase ParentDirectory - { - get - { - return new InMemoryDirectoryInfo(Path.GetDirectoryName(FullName), _files, true); - } - } + public override DirectoryInfoBase? ParentDirectory => + new InMemoryDirectoryInfo(Path.GetDirectoryName(FullName)!, _files, true); /// public override IEnumerable EnumerateFileSystemInfos() @@ -99,8 +91,7 @@ public override IEnumerable EnumerateFileSystemInfos() else { string name = file.Substring(0, endSegment); - List list; - if (!dict.TryGetValue(name, out list)) + if (!dict.TryGetValue(name, out List? list)) { dict[name] = new List { file }; } @@ -145,7 +136,7 @@ public override DirectoryInfoBase GetDirectory(string path) /// /// The filename. /// Instance of if the file exists, null otherwise. - public override FileInfoBase GetFile(string path) + public override FileInfoBase? GetFile(string path) { string normPath = Path.GetFullPath(path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar)); foreach (string file in _files) diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/InMemoryFileInfo.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/InMemoryFileInfo.cs index 90f3f83bb77d70..93f870373b7908 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/InMemoryFileInfo.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/InMemoryFileInfo.cs @@ -21,12 +21,6 @@ public InMemoryFileInfo(string file, InMemoryDirectoryInfo parent) public override string Name { get; } - public override DirectoryInfoBase ParentDirectory - { - get - { - return _parent; - } - } + public override DirectoryInfoBase ParentDirectory => _parent; } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs index bd3ad94cfaebc6..470d9860cd0483 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/MatcherContext.cs @@ -55,13 +55,13 @@ public PatternMatchingResult Execute() return new PatternMatchingResult(_files, _files.Count > 0); } - private void Match(DirectoryInfoBase directory, string parentRelativePath) + private void Match(DirectoryInfoBase directory, string? parentRelativePath) { // Request all the including and excluding patterns to push current directory onto their status stack. PushDirectory(directory); Declare(); - var entities = new List(); + var entities = new List(); if (_declaredWildcardPathSegment || _declaredLiteralFileSegments.Any()) { entities.AddRange(directory.EnumerateFileSystemInfos()); @@ -85,10 +85,9 @@ private void Match(DirectoryInfoBase directory, string parentRelativePath) // collect files and sub directories var subDirectories = new List(); - foreach (FileSystemInfoBase entity in entities) + foreach (FileSystemInfoBase? entity in entities) { - var fileInfo = entity as FileInfoBase; - if (fileInfo != null) + if (entity is FileInfoBase fileInfo) { PatternTestResult result = MatchPatternContexts(fileInfo, (pattern, file) => pattern.Test(file)); if (result.IsSuccessful) @@ -101,8 +100,7 @@ private void Match(DirectoryInfoBase directory, string parentRelativePath) continue; } - var directoryInfo = entity as DirectoryInfoBase; - if (directoryInfo != null) + if (entity is DirectoryInfoBase directoryInfo) { if (MatchPatternContexts(directoryInfo, (pattern, dir) => pattern.Test(dir))) { @@ -140,8 +138,7 @@ private void Declare() private void DeclareInclude(IPathSegment patternSegment, bool isLastSegment) { - var literalSegment = patternSegment as LiteralPathSegment; - if (literalSegment != null) + if (patternSegment is LiteralPathSegment literalSegment) { if (isLastSegment) { @@ -163,7 +160,7 @@ private void DeclareInclude(IPathSegment patternSegment, bool isLastSegment) } } - internal static string CombinePath(string left, string right) + internal static string CombinePath(string? left, string right) { if (string.IsNullOrEmpty(left)) { diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/CurrentPathSegment.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/CurrentPathSegment.cs index b5f1ab15eac0d2..3898d2d26048a5 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/CurrentPathSegment.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/CurrentPathSegment.cs @@ -7,11 +7,8 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments { public class CurrentPathSegment : IPathSegment { - public bool CanProduceStem { get { return false; } } + public bool CanProduceStem => false; - public bool Match(string value) - { - return false; - } + public bool Match(string value) => false; } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/LiteralPathSegment.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/LiteralPathSegment.cs index 7b58c3c03a2ec7..d5f69305ced259 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/LiteralPathSegment.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/LiteralPathSegment.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.FileSystemGlobbing.Util; namespace Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments @@ -10,16 +11,11 @@ public class LiteralPathSegment : IPathSegment { private readonly StringComparison _comparisonType; - public bool CanProduceStem { get { return false; } } + public bool CanProduceStem => false; public LiteralPathSegment(string value, StringComparison comparisonType) { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - Value = value; + Value = value ?? throw new ArgumentNullException(nameof(value)); _comparisonType = comparisonType; } @@ -31,11 +27,9 @@ public bool Match(string value) return string.Equals(Value, value, _comparisonType); } - public override bool Equals(object obj) + public override bool Equals([NotNullWhen(true)] object? obj) { - var other = obj as LiteralPathSegment; - - return other != null && + return obj is LiteralPathSegment other && _comparisonType == other._comparisonType && string.Equals(other.Value, Value, _comparisonType); } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/ParentPathSegment.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/ParentPathSegment.cs index ce66a8c77c2848..0f184cd9c1683d 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/ParentPathSegment.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/ParentPathSegment.cs @@ -9,7 +9,7 @@ public class ParentPathSegment : IPathSegment { private const string LiteralParent = ".."; - public bool CanProduceStem { get { return false; } } + public bool CanProduceStem => false; public bool Match(string value) { diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/RecursiveWildcardSegment.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/RecursiveWildcardSegment.cs index 6573228c38a79f..eba104a248e4a0 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/RecursiveWildcardSegment.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/RecursiveWildcardSegment.cs @@ -7,11 +7,8 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal.PathSegments { public class RecursiveWildcardSegment : IPathSegment { - public bool CanProduceStem { get { return true; } } + public bool CanProduceStem => true; - public bool Match(string value) - { - return false; - } + public bool Match(string value) => false; } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/WildcardPathSegment.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/WildcardPathSegment.cs index dec7476f0fd0a9..a8de519f761a26 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/WildcardPathSegment.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PathSegments/WildcardPathSegment.cs @@ -17,9 +17,9 @@ public class WildcardPathSegment : IPathSegment public WildcardPathSegment(string beginsWith, List contains, string endsWith, StringComparison comparisonType) { - BeginsWith = beginsWith; - Contains = contains; - EndsWith = endsWith; + BeginsWith = beginsWith ?? throw new ArgumentNullException(nameof(beginsWith)); + Contains = contains ?? throw new ArgumentNullException(nameof(contains)); + EndsWith = endsWith ?? throw new ArgumentNullException(nameof(endsWith)); _comparisonType = comparisonType; } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContext.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContext.cs index 7e62c8203803d0..c196d527c704ee 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContext.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContext.cs @@ -9,8 +9,8 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal.PatternContexts { public abstract class PatternContext : IPatternContext { - private Stack _stack = new Stack(); - protected TFrame Frame; + private Stack _stack = new(); + protected TFrame? Frame; public virtual void Declare(Action declare) { } @@ -25,7 +25,7 @@ public virtual void PopDirectory() Frame = _stack.Pop(); } - protected void PushDataFrame(TFrame frame) + protected void PushDataFrame(TFrame? frame) { _stack.Push(Frame); Frame = frame; diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs index 8a8d7cfacbcf8f..b03621d46aa685 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs @@ -12,7 +12,7 @@ public abstract class PatternContextLinear { public PatternContextLinear(ILinearPattern pattern) { - Pattern = pattern; + Pattern = pattern ?? throw new ArgumentNullException(nameof(pattern)); } public override PatternTestResult Test(FileInfoBase file) @@ -67,17 +67,11 @@ public struct FrameData public bool IsNotApplicable; public int SegmentIndex; public bool InStem; - private IList _stemItems; + private IList? _stemItems; - public IList StemItems - { - get { return _stemItems ?? (_stemItems = new List()); } - } + public IList StemItems => _stemItems ??= new List(); - public string Stem - { - get { return _stemItems == null ? null : string.Join("/", _stemItems); } - } + public string? Stem => _stemItems == null ? null : string.Join("/", _stemItems); } protected ILinearPattern Pattern { get; } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextRagged.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextRagged.cs index ec4940fa3a192d..06df2db3b968e0 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextRagged.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextRagged.cs @@ -11,7 +11,7 @@ public abstract class PatternContextRagged : PatternContext _stemItems; + private IList? _stemItems; - public IList StemItems - { - get { return _stemItems ?? (_stemItems = new List()); } - } + public IList StemItems => _stemItems ??= new List(); - public string Stem - { - get { return _stemItems == null ? null : string.Join("/", _stemItems); } - } + public string? Stem => _stemItems == null ? null : string.Join("/", _stemItems); } protected IRaggedPattern Pattern { get; } @@ -165,11 +159,11 @@ protected bool TestMatchingGroup(FileSystemInfoBase value) return false; } - FileSystemInfoBase scan = value; + FileSystemInfoBase? scan = value; for (int index = 0; index != groupLength; ++index) { IPathSegment segment = Frame.SegmentGroup[groupLength - index - 1]; - if (!segment.Match(scan.Name)) + if (scan == null || !segment.Match(scan.Name)) { return false; } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs index d8e2bf8879c739..d1067b28574e41 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternTestResult.cs @@ -9,18 +9,18 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal /// public struct PatternTestResult { - public static readonly PatternTestResult Failed = new PatternTestResult(isSuccessful: false, stem: null); + public static readonly PatternTestResult Failed = new(isSuccessful: false, stem: null); public bool IsSuccessful { get; } - public string Stem { get; } + public string? Stem { get; } - private PatternTestResult(bool isSuccessful, string stem) + private PatternTestResult(bool isSuccessful, string? stem) { IsSuccessful = isSuccessful; Stem = stem; } - public static PatternTestResult Success(string stem) + public static PatternTestResult Success(string? stem) { return new PatternTestResult(isSuccessful: true, stem: stem); } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/Patterns/PatternBuilder.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/Patterns/PatternBuilder.cs index 6b577ee66801ae..eca50420795bb5 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/Patterns/PatternBuilder.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/Patterns/PatternBuilder.cs @@ -44,9 +44,9 @@ public IPattern Build(string pattern) var allSegments = new List(); bool isParentSegmentLegal = true; - IList segmentsPatternStartsWith = null; - IList> segmentsPatternContains = null; - IList segmentsPatternEndsWith = null; + IList? segmentsPatternStartsWith = null; + IList>? segmentsPatternContains = null; + IList? segmentsPatternEndsWith = null; int endPattern = pattern.Length; for (int scanPattern = 0; scanPattern < endPattern;) @@ -54,7 +54,7 @@ public IPattern Build(string pattern) int beginSegment = scanPattern; int endSegment = NextIndex(pattern, _slashes, scanPattern, endPattern); - IPathSegment segment = null; + IPathSegment? segment = null; if (segment == null && endSegment - beginSegment == 3) { @@ -163,7 +163,7 @@ public IPattern Build(string pattern) } } - if (!(segment is ParentPathSegment)) + if (segment is not ParentPathSegment) { isParentSegmentLegal = false; } @@ -182,9 +182,9 @@ public IPattern Build(string pattern) segmentsPatternEndsWith = new List(); segmentsPatternContains = new List>(); } - else if (segmentsPatternEndsWith.Count != 0) + else if (segmentsPatternEndsWith!.Count != 0) { - segmentsPatternContains.Add(segmentsPatternEndsWith); + segmentsPatternContains!.Add(segmentsPatternEndsWith); segmentsPatternEndsWith = new List(); } } @@ -205,7 +205,7 @@ public IPattern Build(string pattern) } else { - return new RaggedPattern(allSegments, segmentsPatternStartsWith, segmentsPatternEndsWith, segmentsPatternContains); + return new RaggedPattern(allSegments, segmentsPatternStartsWith, segmentsPatternEndsWith!, segmentsPatternContains!); } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Matcher.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Matcher.cs index f6ef47bb061b11..e87333e109b4e3 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Matcher.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Matcher.cs @@ -159,9 +159,14 @@ public virtual Matcher AddExclude(string pattern) /// Searches the directory specified for all files matching patterns added to this instance of /// /// The root directory for the search - /// Always returns instance of , even if not files were matched + /// Always returns instance of , even if no files were matched public virtual PatternMatchingResult Execute(DirectoryInfoBase directoryInfo) { + if (directoryInfo is null) + { + throw new ArgumentNullException(nameof(directoryInfo)); + } + var context = new MatcherContext(_includePatterns, _excludePatterns, directoryInfo, _comparison); return context.Execute(); } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs index d6c68347c3be1f..91204a08f6a70b 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/MatcherExtensions.cs @@ -86,7 +86,7 @@ public static PatternMatchingResult Match(this Matcher matcher, string rootDir, /// The matcher that holds the patterns and pattern matching type. /// The files to run the matcher against. /// The match results. - public static PatternMatchingResult Match(this Matcher matcher, IEnumerable files) + public static PatternMatchingResult Match(this Matcher matcher, IEnumerable? files) { return Match(matcher, Directory.GetCurrentDirectory(), files); } @@ -98,7 +98,7 @@ public static PatternMatchingResult Match(this Matcher matcher, IEnumerableThe root directory for the matcher to match the files from. /// The files to run the matcher against. /// The match results. - public static PatternMatchingResult Match(this Matcher matcher, string rootDir, IEnumerable files) + public static PatternMatchingResult Match(this Matcher matcher, string rootDir, IEnumerable? files) { if (matcher == null) { diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj index 10b3beca84586b..d6cf9c374979d2 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Microsoft.Extensions.FileSystemGlobbing.csproj @@ -2,7 +2,10 @@ $(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum) + enable true + + false File system globbing to find files matching a specified pattern. @@ -10,10 +13,5 @@ - - - - - - + diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PatternMatchingResult.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PatternMatchingResult.cs index 4642e8aa45f1e7..c907984daa6f52 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PatternMatchingResult.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/PatternMatchingResult.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; using System.Collections.Generic; using System.Linq; @@ -28,7 +29,7 @@ public PatternMatchingResult(IEnumerable files) /// A value that determines if has any matches. public PatternMatchingResult(IEnumerable files, bool hasMatches) { - Files = files; + Files = files ?? throw new ArgumentNullException(nameof(files)); HasMatches = hasMatches; } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Util/StringComparisonHelper.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Util/StringComparisonHelper.cs index fed66763c82069..444d26b7be7304 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Util/StringComparisonHelper.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Util/StringComparisonHelper.cs @@ -7,25 +7,15 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Util { internal static class StringComparisonHelper { - public static StringComparer GetStringComparer(StringComparison comparisonType) + public static StringComparer GetStringComparer(StringComparison comparisonType) => comparisonType switch { - switch (comparisonType) - { - case StringComparison.CurrentCulture: - return StringComparer.CurrentCulture; - case StringComparison.CurrentCultureIgnoreCase: - return StringComparer.CurrentCultureIgnoreCase; - case StringComparison.Ordinal: - return StringComparer.Ordinal; - case StringComparison.OrdinalIgnoreCase: - return StringComparer.OrdinalIgnoreCase; - case StringComparison.InvariantCulture: - return StringComparer.InvariantCulture; - case StringComparison.InvariantCultureIgnoreCase: - return StringComparer.InvariantCultureIgnoreCase; - default: - throw new InvalidOperationException(SR.Format(SR.UnexpectedStringComparisonType, comparisonType)); - } - } + StringComparison.CurrentCulture => StringComparer.CurrentCulture, + StringComparison.CurrentCultureIgnoreCase => StringComparer.CurrentCultureIgnoreCase, + StringComparison.Ordinal => StringComparer.Ordinal, + StringComparison.OrdinalIgnoreCase => StringComparer.OrdinalIgnoreCase, + StringComparison.InvariantCulture => StringComparer.InvariantCulture, + StringComparison.InvariantCultureIgnoreCase => StringComparer.InvariantCultureIgnoreCase, + _ => throw new InvalidOperationException(SR.Format(SR.UnexpectedStringComparisonType, comparisonType)) + }; } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs index 25296f838f1481..c16e991e3b111c 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/tests/FilePatternMatchTests.cs @@ -24,18 +24,5 @@ public void TestGetHashCode() FilePatternMatch matchCase2 = new FilePatternMatch("sub/sub2/bar/baz/three.txt", "Sub2/bar/baz/thrEE.txt"); Assert.Equal(matchCase1.GetHashCode(), matchCase2.GetHashCode()); } - - [Fact] - public void TestGetHashCodeWithNull() - { - FilePatternMatch match = new FilePatternMatch(null, null); - Assert.Equal(0, match.GetHashCode()); - - int hash1 = new FilePatternMatch("non null", null).GetHashCode(); - int hash2 = new FilePatternMatch(null, "non null").GetHashCode(); - Assert.NotEqual(0, hash1); - Assert.NotEqual(0, hash2); - Assert.NotEqual(hash1, hash2); - } } }