未验证 提交 1c30027a 编写于 作者: M Maksym Koshovyi 提交者: GitHub

[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
上级 be918580
......@@ -10,22 +10,22 @@ public partial struct FilePatternMatch : System.IEquatable<Microsoft.Extensions.
{
private object _dummy;
private int _dummyPrimitive;
public FilePatternMatch(string path, string stem) { throw null; }
public FilePatternMatch(string path, string? stem) { throw null; }
public readonly string Path { get { throw null; } }
public readonly string Stem { get { throw null; } }
public readonly string? Stem { get { throw null; } }
public bool Equals(Microsoft.Extensions.FileSystemGlobbing.FilePatternMatch other) { 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 partial class InMemoryDirectoryInfo : Microsoft.Extensions.FileSystemGlobbing.Abstractions.DirectoryInfoBase
{
public InMemoryDirectoryInfo(string rootDir, System.Collections.Generic.IEnumerable<string> files) { }
public InMemoryDirectoryInfo(string rootDir, System.Collections.Generic.IEnumerable<string>? 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<Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileSystemInfoBase> 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<string>[] excludePatternsGroups) { }
public static void AddIncludePatterns(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, params System.Collections.Generic.IEnumerable<string>[] includePatternsGroups) { }
public static System.Collections.Generic.IEnumerable<string> 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<string> files) { throw null; }
public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, System.Collections.Generic.IEnumerable<string>? 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<string> files) { throw null; }
public static Microsoft.Extensions.FileSystemGlobbing.PatternMatchingResult Match(this Microsoft.Extensions.FileSystemGlobbing.Matcher matcher, string rootDir, System.Collections.Generic.IEnumerable<string>? 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<Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileSystemInfoBase> 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<Microsoft.Extensions.FileSystemGlobbing.Abstractions.FileSystemInfoBase> 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<string> StemItems { get { throw null; } }
}
}
......@@ -232,7 +232,7 @@ public partial struct FrameData
public System.Collections.Generic.IList<Microsoft.Extensions.FileSystemGlobbing.Internal.IPathSegment> SegmentGroup;
public int SegmentGroupIndex;
public int SegmentIndex;
public string Stem { get { throw null; } }
public string? Stem { get { throw null; } }
public System.Collections.Generic.IList<string> StemItems { get { throw null; } }
}
}
......@@ -249,12 +249,12 @@ public partial class PatternContextRaggedInclude : Microsoft.Extensions.FileSyst
}
public abstract partial class PatternContext<TFrame> : Microsoft.Extensions.FileSystemGlobbing.Internal.IPatternContext
{
protected TFrame Frame;
protected TFrame? Frame;
protected PatternContext() { }
public virtual void Declare(System.Action<Microsoft.Extensions.FileSystemGlobbing.Internal.IPathSegment, bool> 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);
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<Compile Include="Microsoft.Extensions.FileSystemGlobbing.cs" />
......
......@@ -21,13 +21,13 @@ public abstract class DirectoryInfoBase : FileSystemInfoBase
/// </summary>
/// <param name="path">The directory name</param>
/// <returns>Instance of <see cref="DirectoryInfoBase" /> even if directory does not exist</returns>
public abstract DirectoryInfoBase GetDirectory(string path);
public abstract DirectoryInfoBase? GetDirectory(string path);
/// <summary>
/// Returns an instance of <see cref="FileInfoBase" /> that represents a file in the directory
/// </summary>
/// <param name="path">The file name</param>
/// <returns>Instance of <see cref="FileInfoBase" /> even if file does not exist</returns>
public abstract FileInfoBase GetFile(string path);
public abstract FileInfoBase? GetFile(string path);
}
}
......@@ -47,8 +47,7 @@ public override IEnumerable<FileSystemInfoBase> 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<FileSystemInfoBase> EnumerateFileSystemInfos()
/// </remarks>
/// <param name="name">The directory name</param>
/// <returns>The directory</returns>
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)
/// <remarks>
/// Equals the value of <seealso cref="System.IO.DirectoryInfo.Parent" />.
/// </remarks>
public override DirectoryInfoBase ParentDirectory
=> new DirectoryInfoWrapper(_directoryInfo.Parent);
public override DirectoryInfoBase? ParentDirectory
=> new DirectoryInfoWrapper(_directoryInfo.Parent!);
}
}
// 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
/// <param name="fileInfo">The <see cref="System.IO.FileInfo" /></param>
public FileInfoWrapper(FileInfo fileInfo)
{
_fileInfo = fileInfo;
_fileInfo = fileInfo ?? throw new ArgumentNullException(nameof(fileInfo));
}
/// <summary>
......@@ -43,6 +44,7 @@ public FileInfoWrapper(FileInfo fileInfo)
/// <remarks>
/// Equals the value of <see cref="System.IO.FileInfo.Directory" />.
/// </remarks>
public override DirectoryInfoBase ParentDirectory => new DirectoryInfoWrapper(_fileInfo.Directory);
public override DirectoryInfoBase? ParentDirectory
=> new DirectoryInfoWrapper(_fileInfo.Directory!);
}
}
......@@ -21,6 +21,6 @@ public abstract class FileSystemInfoBase
/// <summary>
/// The parent directory for the current file or directory
/// </summary>
public abstract DirectoryInfoBase ParentDirectory { get; }
public abstract DirectoryInfoBase? ParentDirectory { get; }
}
}
......@@ -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<FilePatternMatch>
/// If the matcher searched for "src/Project/**/*.cs" and the pattern matcher found "src/Project/Interfaces/IFile.cs",
/// then <see cref="Stem" /> = "Interfaces/IFile.cs" and <see cref="Path" /> = "src/Project/Interfaces/IFile.cs".
/// </remarks>
public string Stem { get; }
public string? Stem { get; }
/// <summary>
/// Initializes new instance of <see cref="FilePatternMatch" />
/// </summary>
/// <param name="path">The path to the file matched, relative to the beginning of the matching search pattern.</param>
/// <param name="stem">The subpath to the file matched, relative to the first wildcard in the matching search pattern.</param>
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)
/// </summary>
/// <param name="obj">The object to be compared</param>
/// <returns>True when <see cref="Equals(FilePatternMatch)" /></returns>
public override bool Equals(object obj)
{
return Equals((FilePatternMatch) obj);
}
public override bool Equals([NotNullWhen(true)] object? obj) =>
obj is FilePatternMatch match && Equals(match);
/// <summary>
/// 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;
}
}
......@@ -23,22 +23,19 @@ public class InMemoryDirectoryInfo : DirectoryInfoBase
/// </summary>
/// <param name="rootDir">The root directory that this FileSystem will use.</param>
/// <param name="files">Collection of file names. If relative paths <paramref name="rootDir"/> will be prepended to the paths.</param>
public InMemoryDirectoryInfo(string rootDir, IEnumerable<string> files)
public InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files)
: this(rootDir, files, false)
{
}
private InMemoryDirectoryInfo(string rootDir, IEnumerable<string> files, bool normalized)
private InMemoryDirectoryInfo(string rootDir, IEnumerable<string>? files, bool normalized)
{
if (string.IsNullOrEmpty(rootDir))
{
throw new ArgumentNullException(nameof(rootDir));
}
if (files == null)
{
files = new List<string>();
}
files ??= new List<string>();
Name = Path.GetFileName(rootDir);
if (normalized)
......@@ -69,13 +66,8 @@ private InMemoryDirectoryInfo(string rootDir, IEnumerable<string> files, bool no
public override string Name { get; }
/// <inheritdoc />
public override DirectoryInfoBase ParentDirectory
{
get
{
return new InMemoryDirectoryInfo(Path.GetDirectoryName(FullName), _files, true);
}
}
public override DirectoryInfoBase? ParentDirectory =>
new InMemoryDirectoryInfo(Path.GetDirectoryName(FullName)!, _files, true);
/// <inheritdoc />
public override IEnumerable<FileSystemInfoBase> EnumerateFileSystemInfos()
......@@ -99,8 +91,7 @@ public override IEnumerable<FileSystemInfoBase> EnumerateFileSystemInfos()
else
{
string name = file.Substring(0, endSegment);
List<string> list;
if (!dict.TryGetValue(name, out list))
if (!dict.TryGetValue(name, out List<string>? list))
{
dict[name] = new List<string> { file };
}
......@@ -145,7 +136,7 @@ public override DirectoryInfoBase GetDirectory(string path)
/// </summary>
/// <param name="path">The filename.</param>
/// <returns>Instance of <see cref="FileInfoBase"/> if the file exists, null otherwise.</returns>
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)
......
......@@ -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;
}
}
......@@ -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<FileSystemInfoBase>();
var entities = new List<FileSystemInfoBase?>();
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<DirectoryInfoBase>();
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))
{
......
......@@ -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;
}
}
......@@ -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);
}
......
......@@ -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)
{
......
......@@ -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;
}
}
......@@ -17,9 +17,9 @@ public class WildcardPathSegment : IPathSegment
public WildcardPathSegment(string beginsWith, List<string> 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;
}
......
......@@ -9,8 +9,8 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal.PatternContexts
{
public abstract class PatternContext<TFrame> : IPatternContext
{
private Stack<TFrame> _stack = new Stack<TFrame>();
protected TFrame Frame;
private Stack<TFrame?> _stack = new();
protected TFrame? Frame;
public virtual void Declare(Action<IPathSegment, bool> 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;
......
......@@ -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<string> _stemItems;
private IList<string>? _stemItems;
public IList<string> StemItems
{
get { return _stemItems ?? (_stemItems = new List<string>()); }
}
public IList<string> StemItems => _stemItems ??= new List<string>();
public string Stem
{
get { return _stemItems == null ? null : string.Join("/", _stemItems); }
}
public string? Stem => _stemItems == null ? null : string.Join("/", _stemItems);
}
protected ILinearPattern Pattern { get; }
......
......@@ -11,7 +11,7 @@ public abstract class PatternContextRagged : PatternContext<PatternContextRagged
{
public PatternContextRagged(IRaggedPattern pattern)
{
Pattern = pattern;
Pattern = pattern ?? throw new ArgumentNullException(nameof(pattern));
}
public override PatternTestResult Test(FileInfoBase file)
......@@ -122,17 +122,11 @@ public struct FrameData
public bool InStem;
private IList<string> _stemItems;
private IList<string>? _stemItems;
public IList<string> StemItems
{
get { return _stemItems ?? (_stemItems = new List<string>()); }
}
public IList<string> StemItems => _stemItems ??= new List<string>();
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;
}
......
......@@ -9,18 +9,18 @@ namespace Microsoft.Extensions.FileSystemGlobbing.Internal
/// </summary>
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);
}
......
......@@ -44,9 +44,9 @@ public IPattern Build(string pattern)
var allSegments = new List<IPathSegment>();
bool isParentSegmentLegal = true;
IList<IPathSegment> segmentsPatternStartsWith = null;
IList<IList<IPathSegment>> segmentsPatternContains = null;
IList<IPathSegment> segmentsPatternEndsWith = null;
IList<IPathSegment>? segmentsPatternStartsWith = null;
IList<IList<IPathSegment>>? segmentsPatternContains = null;
IList<IPathSegment>? 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<IPathSegment>();
segmentsPatternContains = new List<IList<IPathSegment>>();
}
else if (segmentsPatternEndsWith.Count != 0)
else if (segmentsPatternEndsWith!.Count != 0)
{
segmentsPatternContains.Add(segmentsPatternEndsWith);
segmentsPatternContains!.Add(segmentsPatternEndsWith);
segmentsPatternEndsWith = new List<IPathSegment>();
}
}
......@@ -205,7 +205,7 @@ public IPattern Build(string pattern)
}
else
{
return new RaggedPattern(allSegments, segmentsPatternStartsWith, segmentsPatternEndsWith, segmentsPatternContains);
return new RaggedPattern(allSegments, segmentsPatternStartsWith, segmentsPatternEndsWith!, segmentsPatternContains!);
}
}
......
......@@ -159,9 +159,14 @@ public virtual Matcher AddExclude(string pattern)
/// Searches the directory specified for all files matching patterns added to this instance of <see cref="Matcher" />
/// </summary>
/// <param name="directoryInfo">The root directory for the search</param>
/// <returns>Always returns instance of <see cref="PatternMatchingResult" />, even if not files were matched</returns>
/// <returns>Always returns instance of <see cref="PatternMatchingResult" />, even if no files were matched</returns>
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();
}
......
......@@ -86,7 +86,7 @@ public static PatternMatchingResult Match(this Matcher matcher, string rootDir,
/// <param name="matcher">The matcher that holds the patterns and pattern matching type.</param>
/// <param name="files">The files to run the matcher against.</param>
/// <returns>The match results.</returns>
public static PatternMatchingResult Match(this Matcher matcher, IEnumerable<string> files)
public static PatternMatchingResult Match(this Matcher matcher, IEnumerable<string>? files)
{
return Match(matcher, Directory.GetCurrentDirectory(), files);
}
......@@ -98,7 +98,7 @@ public static PatternMatchingResult Match(this Matcher matcher, IEnumerable<stri
/// <param name="rootDir">The root directory for the matcher to match the files from.</param>
/// <param name="files">The files to run the matcher against.</param>
/// <returns>The match results.</returns>
public static PatternMatchingResult Match(this Matcher matcher, string rootDir, IEnumerable<string> files)
public static PatternMatchingResult Match(this Matcher matcher, string rootDir, IEnumerable<string>? files)
{
if (matcher == null)
{
......
......@@ -2,7 +2,10 @@
<PropertyGroup>
<TargetFrameworks>$(NetCoreAppCurrent);$(NetCoreAppMinimum);netstandard2.0;$(NetFrameworkMinimum)</TargetFrameworks>
<Nullable>enable</Nullable>
<EnableDefaultItems>true</EnableDefaultItems>
<!-- Use targeting pack references instead of granular ones in the project file. -->
<DisableImplicitAssemblyReferences>false</DisableImplicitAssemblyReferences>
<PackageDescription>File system globbing to find files matching a specified pattern.</PackageDescription>
</PropertyGroup>
......@@ -10,10 +13,5 @@
<Compile Include="$(CoreLibSharedDir)\System\Numerics\Hashing\HashHelpers.cs"
Link="System\Numerics\Hashing\HashHelpers.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
<Reference Include="System.Collections" />
<Reference Include="System.Linq" />
<Reference Include="System.Runtime" />
</ItemGroup>
</Project>
// 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<FilePatternMatch> files)
/// <param name="hasMatches">A value that determines if <see cref="PatternMatchingResult"/> has any matches.</param>
public PatternMatchingResult(IEnumerable<FilePatternMatch> files, bool hasMatches)
{
Files = files;
Files = files ?? throw new ArgumentNullException(nameof(files));
HasMatches = hasMatches;
}
......
......@@ -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))
};
}
}
......@@ -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);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册