diff --git a/Benchmarks/Benchmarks.csproj b/Benchmarks/Benchmarks.csproj index 690eeea..fe47b2f 100644 --- a/Benchmarks/Benchmarks.csproj +++ b/Benchmarks/Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net6.0 true diff --git a/Benchmarks/EnumBench.cs b/Benchmarks/EnumBench.cs index 1911ada..d99542e 100644 --- a/Benchmarks/EnumBench.cs +++ b/Benchmarks/EnumBench.cs @@ -463,6 +463,77 @@ public DaysOfWeek EnumTransformer() return current; } } + + /* .NET Core 3.1.22 (CoreCLR 4.700.21.56803, CoreFX 4.700.21.57101), X64 RyuJIT +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------- |---------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:| +| EnumTransformer | 2.859 us | 0.0462 us | 0.0409 us | 1.00 | 0.00 | - | - | - | - | +| Generated | 3.161 us | 0.0523 us | 0.0489 us | 1.11 | 0.02 | - | - | - | - | + + .NET Core 6.0.1 (CoreCLR 6.0.121.56705, CoreFX 6.0.121.56705), X64 RyuJIT +| Method | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------- |---------:|----------:|----------:|------:|------:|------:|------:|----------:| +| EnumTransformer | 2.648 us | 0.0419 us | 0.0392 us | 1.00 | - | - | - | - | +| Generated | 2.226 us | 0.0144 us | 0.0128 us | 0.84 | - | - | - | - |*/ + [MemoryDiagnoser] + public class EnumParserBenchNonFlagGenerated + { + public enum DayOfWeek : byte + { + None , + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday, + Sunday, + } + + public static string[] AllEnums = + Enumerable.Range(0, 50).Select(i => ((DayOfWeek)i).ToString("G").Replace(" ", "")).ToArray(); + + private static readonly ITransformer _parser = TextTransformer.Default.GetTransformer(); + + + [Benchmark(Baseline = true)] + public DayOfWeek EnumTransformer() + { + DayOfWeek current = default; + for (int i = AllEnums.Length - 1; i >= 0; i--) + { + var text = AllEnums[i]; + current = _parser.Parse(text.AsSpan()); + } + return current; + } + + [Benchmark] + public DayOfWeek Generated() + { + DayOfWeek current = default; + for (int i = AllEnums.Length - 1; i >= 0; i--) + { + var text = AllEnums[i]; + current = ParseIgnoreCase(text); + } + return current; + } + + private static DayOfWeek ParseIgnoreCase(string text) => + text switch + { + { } s when s.Equals(nameof(DayOfWeek.None), StringComparison.OrdinalIgnoreCase) => DayOfWeek.None, + { } s when s.Equals(nameof(DayOfWeek.Monday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Monday, + { } s when s.Equals(nameof(DayOfWeek.Tuesday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Tuesday, + { } s when s.Equals(nameof(DayOfWeek.Wednesday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Wednesday, + { } s when s.Equals(nameof(DayOfWeek.Thursday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Thursday, + { } s when s.Equals(nameof(DayOfWeek.Friday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Friday, + { } s when s.Equals(nameof(DayOfWeek.Saturday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Saturday, + { } s when s.Equals(nameof(DayOfWeek.Sunday), StringComparison.OrdinalIgnoreCase) => DayOfWeek.Sunday, + _ => Enum.Parse(text, true) + }; + } [MemoryDiagnoser] public class ToEnumBench @@ -665,6 +736,12 @@ public DaysOfWeek ExternTest() }*/ } + /* NET Core 3.1 +| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | +|----------------- |----------:|----------:|----------:|------:|--------:|------:|------:|------:|----------:| +| HasFlag_Native | 0.2376 ns | 0.0026 ns | 0.0023 ns | 0.98 | 0.03 | - | - | - | - | +| HasFlags_Dynamic | 5.4291 ns | 0.1069 ns | 0.2183 ns | 22.68 | 1.01 | - | - | - | - | +| HasFlags_Bitwise | 0.2407 ns | 0.0043 ns | 0.0059 ns | 1.00 | 0.00 | - | - | - | - | */ [MemoryDiagnoser] [SimpleJob(RuntimeMoniker.Net47)] [SimpleJob(RuntimeMoniker.NetCoreApp31)] diff --git a/Nemesis.TextParsers.Tests/RecordsTests.cs b/Nemesis.TextParsers.Tests/RecordsTests.cs index f0affb8..bd3283a 100644 --- a/Nemesis.TextParsers.Tests/RecordsTests.cs +++ b/Nemesis.TextParsers.Tests/RecordsTests.cs @@ -4,12 +4,12 @@ using NUnit.Framework; #if !NET -using NotNull = JetBrains.Annotations.NotNullAttribute; + using NotNull = JetBrains.Annotations.NotNullAttribute; #else -using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; -// ReSharper disable NotAccessedPositionalProperty.Local + using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; #endif +// ReSharper disable NotAccessedPositionalProperty.Local namespace Nemesis.TextParsers.Tests { @@ -51,13 +51,12 @@ public void ShouldBeAbleToReparseComplexRecords() Assert.That(parsed.Animals[1].Name, Is.EqualTo("Lizard")); } - [System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "UnusedMember.Local")] - enum Habitat { Terrestrial, Aquatic, Amphibian } - [System.Diagnostics.CodeAnalysis.SuppressMessage("ReSharper", "UnusedMember.Local")] - enum Diet { Carnivorous, Herbivorous, Omnivorous } + enum Habitat { Terrestrial/*, Aquatic, Amphibian*/ } + enum Diet { Carnivorous/*, Herbivorous, Omnivorous*/ } record Vertebrate(string Name) { + [JetBrains.Annotations.UsedImplicitly] public Vertebrate() : this("") { } } diff --git a/Nemesis.TextParsers/01_Contracts.cs b/Nemesis.TextParsers/01_Contracts.cs index bf7572d..8a57e51 100644 --- a/Nemesis.TextParsers/01_Contracts.cs +++ b/Nemesis.TextParsers/01_Contracts.cs @@ -6,6 +6,7 @@ namespace Nemesis.TextParsers { + //TODO support nullable NRT [PublicAPI] public interface ITransformer { diff --git a/Nemesis.TextParsers/Parsers/03a_KeyValuePair.cs b/Nemesis.TextParsers/Parsers/03a_KeyValuePair.cs index b37aa54..71c5ac6 100644 --- a/Nemesis.TextParsers/Parsers/03a_KeyValuePair.cs +++ b/Nemesis.TextParsers/Parsers/03a_KeyValuePair.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Reflection; + using JetBrains.Annotations; + using Nemesis.TextParsers.Runtime; using Nemesis.TextParsers.Settings; using Nemesis.TextParsers.Utils; @@ -29,7 +31,7 @@ public ITransformer CreateTransformer() var m = _createTransformerCoreMethod.MakeGenericMethod(keyType, valueType); - return (ITransformer) m.Invoke(this, null); + return (ITransformer)m.Invoke(this, null); } private static readonly MethodInfo _createTransformerCoreMethod = Method.OfExpression< @@ -95,11 +97,7 @@ public override string Format(KeyValuePair element) } } - public override KeyValuePair GetEmpty() => - new KeyValuePair( - _keyTransformer.GetEmpty(), - _valueTransformer.GetEmpty() - ); + public override KeyValuePair GetEmpty() => new(_keyTransformer.GetEmpty(), _valueTransformer.GetEmpty()); } public bool CanHandle(Type type) => diff --git a/Nemesis.TextParsers/Parsers/03b_ValueTuple.cs b/Nemesis.TextParsers/Parsers/03b_ValueTuple.cs index d768d65..a532269 100644 --- a/Nemesis.TextParsers/Parsers/03b_ValueTuple.cs +++ b/Nemesis.TextParsers/Parsers/03b_ValueTuple.cs @@ -76,8 +76,7 @@ private ConstructorInfo GetConstructor(Type transformerType, in int arity, Type[ private bool IsSupported(Type type, out Type[] elementTypes) => TypeMeta.TryGetValueTupleElements(type, out elementTypes) && - elementTypes != null && - elementTypes.Length is { } arity && arity <= MAX_ARITY && arity >= 1 && + elementTypes is {Length: <= MAX_ARITY and >= 1} && elementTypes.All(t => _transformerStore.IsSupportedForTransformation(t)); public sbyte Priority => 12; diff --git a/Nemesis.TextParsers/Parsers/04_FactoryMethods.cs b/Nemesis.TextParsers/Parsers/04_FactoryMethods.cs index 9ef44fa..1d8289d 100644 --- a/Nemesis.TextParsers/Parsers/04_FactoryMethods.cs +++ b/Nemesis.TextParsers/Parsers/04_FactoryMethods.cs @@ -96,27 +96,19 @@ private ITransformer GetTransformer() return methodInputType == typeof(string) ? new StringFactoryTransformer(body, inputParameter, formatter, emptyValueProvider, nullValueProvider) - : (ITransformer) - new SpanFactoryTransformer(body, inputParameter, formatter, emptyValueProvider, nullValueProvider); + : new SpanFactoryTransformer(body, inputParameter, formatter, emptyValueProvider, nullValueProvider); MethodInfo FindMethodWithParameterType(Type paramType) => conversionMethods.FirstOrDefault(m => - m.GetParameters() is { } @params && @params.Length == 1 && - @params[0].ParameterType == paramType); + m.GetParameters() is {Length: 1} @params && @params[0].ParameterType == paramType); } - private static bool FactoryMethodPredicate(MethodInfo m, Type returnType, string factoryMethodName) => m.Name == factoryMethodName && - m.GetParameters() is { } @params && @params.Length == 1 && - @params[0].ParameterType is { } firstParamType && - ( - firstParamType == typeof(string) - || - firstParamType == typeof(ReadOnlySpan) - ) - && + m.GetParameters() is {Length: 1} @params && + @params[0].ParameterType is { } firstParamType && + (firstParamType == typeof(string) || firstParamType == typeof(ReadOnlySpan)) && ( m.ReturnType == returnType || diff --git a/Nemesis.TextParsers/Parsers/05_Enums.cs b/Nemesis.TextParsers/Parsers/05_Enums.cs index 3d93fa9..d26ea20 100644 --- a/Nemesis.TextParsers/Parsers/05_Enums.cs +++ b/Nemesis.TextParsers/Parsers/05_Enums.cs @@ -5,20 +5,18 @@ using System.Reflection; using System.Runtime.CompilerServices; -using JetBrains.Annotations; - using Nemesis.TextParsers.Runtime; using Nemesis.TextParsers.Settings; #if !NET -using NotNull = JetBrains.Annotations.NotNullAttribute; + using NotNull = JetBrains.Annotations.NotNullAttribute; #else -using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; + using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; #endif namespace Nemesis.TextParsers.Parsers { - [UsedImplicitly] + [JetBrains.Annotations.UsedImplicitly] public sealed class EnumTransformerCreator : ICanCreateTransformer { private readonly EnumSettings _settings; @@ -86,7 +84,7 @@ public sealed class EnumTransformer : Transf private readonly EnumTransformerHelper.ParserDelegate _elementParser; // ReSharper disable once RedundantVerbatimPrefix - public EnumTransformer([@NotNull] TNumberHandler numberHandler, EnumSettings settings) + public EnumTransformer([NotNull] TNumberHandler numberHandler, EnumSettings settings) { _numberHandler = numberHandler ?? throw new ArgumentNullException(nameof(numberHandler)); _settings = settings; @@ -124,8 +122,8 @@ private TUnderlying ParseElement(ReadOnlySpan input) if (_settings.AllowParsingNumerics) { - bool isNumeric = input.Length > 0 && input[0] is { } first && - (char.IsDigit(first) || first == '-' || first == '+'); + bool isNumeric = input.Length > 0 && input[0] is var first && + (char.IsDigit(first) || first is '-' or '+'); return isNumeric && _numberHandler.TryParse(in input, out var number) ? number @@ -222,7 +220,7 @@ internal static class EnumTransformerHelper private static Expression IfThenElseJoin(IReadOnlyList<(Expression Condition, TResult value)> expressionList, Expression lastElse, LabelTarget exitTarget) { - if (expressionList != null && expressionList.Count > 0) + if (expressionList is {Count: > 0}) { Expression @else = lastElse; diff --git a/Nemesis.TextParsers/Parsers/09_Collection.cs b/Nemesis.TextParsers/Parsers/09_Collection.cs index 04acb2c..248d74c 100644 --- a/Nemesis.TextParsers/Parsers/09_Collection.cs +++ b/Nemesis.TextParsers/Parsers/09_Collection.cs @@ -105,13 +105,13 @@ protected override TCollection ParseCore(in ReadOnlySpan input) case CollectionKind.SortedSet: { ISet result = _kind == CollectionKind.HashSet - ? (ISet)new HashSet( + ? new HashSet( #if NETSTANDARD2_0 || NETFRAMEWORK #else - capacity + capacity #endif - ) + ) : new SortedSet(); foreach (var part in stream) diff --git a/Nemesis.TextParsers/Parsers/10_Deconstructable.cs b/Nemesis.TextParsers/Parsers/10_Deconstructable.cs index a78ab63..208730a 100644 --- a/Nemesis.TextParsers/Parsers/10_Deconstructable.cs +++ b/Nemesis.TextParsers/Parsers/10_Deconstructable.cs @@ -9,9 +9,9 @@ using Builder = Nemesis.TextParsers.Parsers.DeconstructionTransformerBuilder; using PublicAPI = JetBrains.Annotations.PublicAPIAttribute; #if !NET -using NotNull = JetBrains.Annotations.NotNullAttribute; + using NotNull = JetBrains.Annotations.NotNullAttribute; #else -using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; + using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; #endif @@ -33,8 +33,7 @@ public ITransformer CreateTransformer() public bool CanHandle(Type type) => Builder.TryGetDefaultDeconstruct(type, out _, out var ctor) && - ctor.GetParameters() is { } cp && cp.Length > 0 && - cp.All(pi => _transformerStore.IsSupportedForTransformation(pi.ParameterType)) + ctor.GetParameters() is {Length: > 0} cp && cp.All(pi => _transformerStore.IsSupportedForTransformation(pi.ParameterType)) ; public sbyte Priority => 110; @@ -55,7 +54,6 @@ public enum DeconstructionMethod : byte ProvidedDeconstructMethod = 1, } - //TODO rework as record + WithBorders + WithoutBorders methods public sealed class DeconstructionTransformerBuilder { private readonly ITransformerStore _transformerStore; @@ -88,7 +86,7 @@ public static Builder GetDefault(ITransformerStore transformerStore) } public static Builder FromSettings(DeconstructableSettings settings, ITransformerStore transformerStore) => - new Builder(transformerStore, + new(transformerStore, settings.Delimiter, settings.NullElementMarker, settings.EscapingSequenceStart, @@ -470,9 +468,7 @@ Expression GetConvertedSource() { var decoSourceType = deconstruct.GetParameters()[0].ParameterType; - return element.Type == decoSourceType - ? (Expression)element - : Expression.Convert(element, decoSourceType); + return element.Type == decoSourceType ? element : Expression.Convert(element, decoSourceType); } var expressions = new List(7 + 2 * arity) diff --git a/Nemesis.TextParsers/ParsingPairSequence.cs b/Nemesis.TextParsers/ParsingPairSequence.cs index 9df4181..41d29d2 100644 --- a/Nemesis.TextParsers/ParsingPairSequence.cs +++ b/Nemesis.TextParsers/ParsingPairSequence.cs @@ -26,7 +26,7 @@ public ParsingPairSequence(in TokenSequence tokenSource, char escapingSequ } #endregion - public ParsingPairSequenceEnumerator GetEnumerator() => new ParsingPairSequenceEnumerator(_tokenSource, + public ParsingPairSequenceEnumerator GetEnumerator() => new(_tokenSource, _escapingSequenceStart, _nullElementMarker, _dictionaryPairsDelimiter, _dictionaryKeyValueDelimiter); public ref struct ParsingPairSequenceEnumerator diff --git a/Nemesis.TextParsers/ParsingSequence.cs b/Nemesis.TextParsers/ParsingSequence.cs index 07708c1..3ae4844 100644 --- a/Nemesis.TextParsers/ParsingSequence.cs +++ b/Nemesis.TextParsers/ParsingSequence.cs @@ -22,7 +22,7 @@ namespace Nemesis.TextParsers _sequenceDelimiter = sequenceDelimiter; } - public ParsingSequenceEnumerator GetEnumerator() => new ParsingSequenceEnumerator(_tokenSource, _escapingSequenceStart, _nullElementMarker, _sequenceDelimiter); + public ParsingSequenceEnumerator GetEnumerator() => new(_tokenSource, _escapingSequenceStart, _nullElementMarker, _sequenceDelimiter); public ref struct ParsingSequenceEnumerator { @@ -121,12 +121,11 @@ public void Deconstruct(out bool isDefault, out ReadOnlySpan text) text = Text; } - public static ParserInput FromDefault() => new ParserInput(true, default); + public static ParserInput FromDefault() => new(true, default); - public static ParserInput FromText(ReadOnlySpan text) => new ParserInput(false, text); + public static ParserInput FromText(ReadOnlySpan text) => new(false, text); - public T ParseWith(ITransformer transformer) - => IsDefault ? default : transformer.Parse(Text); + public T ParseWith(ITransformer transformer) => IsDefault ? default : transformer.Parse(Text); public override string ToString() => IsDefault ? "" : Text.ToString(); } diff --git a/Nemesis.TextParsers/SpanParserHelper.cs b/Nemesis.TextParsers/SpanParserHelper.cs index a861408..fa3ae12 100644 --- a/Nemesis.TextParsers/SpanParserHelper.cs +++ b/Nemesis.TextParsers/SpanParserHelper.cs @@ -10,12 +10,12 @@ public static class SpanParserHelper public static TokenSequence Tokenize(this in ReadOnlySpan sequence, T separator, T escapingElement, bool emptySequenceYieldsEmpty) where T : IEquatable => - new TokenSequence(sequence, separator, escapingElement, emptySequenceYieldsEmpty); + new(sequence, separator, escapingElement, emptySequenceYieldsEmpty); [PureMethod] public static ParsingSequence PreParse(this in TokenSequence tokenSource, char escapingElement, char nullElement, char sequenceDelimiter) => - new ParsingSequence(tokenSource, escapingElement, nullElement, sequenceDelimiter); + new(tokenSource, escapingElement, nullElement, sequenceDelimiter); diff --git a/Nemesis.TextParsers/SpanSplit.cs b/Nemesis.TextParsers/SpanSplit.cs index 31bac2e..5cbcff3 100644 --- a/Nemesis.TextParsers/SpanSplit.cs +++ b/Nemesis.TextParsers/SpanSplit.cs @@ -19,7 +19,7 @@ public Enumerable1(ReadOnlySpan sequence, T separator, bool emptySequenceYiel private readonly T _separator; private readonly bool _emptySequenceYieldsEmpty; - public Enumerator1 GetEnumerator() => new Enumerator1(_sequence, _separator, _emptySequenceYieldsEmpty); + public Enumerator1 GetEnumerator() => new(_sequence, _separator, _emptySequenceYieldsEmpty); } public readonly ref struct Enumerable2 where T : IEquatable @@ -37,7 +37,7 @@ public Enumerable2(ReadOnlySpan sequence, T separator1, T separator2, bool em private readonly T _separator2; private readonly bool _emptySequenceYieldsEmpty; - public Enumerator2 GetEnumerator() => new Enumerator2(_sequence, _separator1, _separator2, _emptySequenceYieldsEmpty); + public Enumerator2 GetEnumerator() => new(_sequence, _separator1, _separator2, _emptySequenceYieldsEmpty); } public readonly ref struct Enumerable3 where T : IEquatable @@ -57,7 +57,7 @@ public Enumerable3(ReadOnlySpan sequence, T separator1, T separator2, T separ private readonly T _separator3; private readonly bool _emptySequenceYieldsEmpty; - public Enumerator3 GetEnumerator() => new Enumerator3(_sequence, _separator1, _separator2, _separator3, _emptySequenceYieldsEmpty); + public Enumerator3 GetEnumerator() => new(_sequence, _separator1, _separator2, _separator3, _emptySequenceYieldsEmpty); } public readonly ref struct EnumerableN where T : IEquatable @@ -73,7 +73,7 @@ public EnumerableN(ReadOnlySpan sequence, ReadOnlySpan separators, bool em private readonly ReadOnlySpan _separators; private readonly bool _emptySequenceYieldsEmpty; - public EnumeratorN GetEnumerator() => new EnumeratorN(_sequence, _separators, _emptySequenceYieldsEmpty); + public EnumeratorN GetEnumerator() => new(_sequence, _separators, _emptySequenceYieldsEmpty); } @@ -288,19 +288,19 @@ public bool MoveNext() #region Extensions [PureMethod] public static Enumerable1 Split(this ReadOnlySpan span, T separator, bool emptySequenceYieldsEmpty = false) - where T : IEquatable => new Enumerable1(span, separator, emptySequenceYieldsEmpty); + where T : IEquatable => new(span, separator, emptySequenceYieldsEmpty); [PureMethod] public static Enumerable2 Split(this ReadOnlySpan span, T separator1, T separator2, bool emptySequenceYieldsEmpty = false) - where T : IEquatable => new Enumerable2(span, separator1, separator2, emptySequenceYieldsEmpty); + where T : IEquatable => new(span, separator1, separator2, emptySequenceYieldsEmpty); [PureMethod] public static Enumerable3 Split(this ReadOnlySpan span, T separator1, T separator2, T separator3, bool emptySequenceYieldsEmpty = false) - where T : IEquatable => new Enumerable3(span, separator1, separator2, separator3, emptySequenceYieldsEmpty); + where T : IEquatable => new(span, separator1, separator2, separator3, emptySequenceYieldsEmpty); [PureMethod] public static EnumerableN Split(this ReadOnlySpan span, ReadOnlySpan values, bool emptySequenceYieldsEmpty = false) - where T : IEquatable => new EnumerableN(span, values, emptySequenceYieldsEmpty); + where T : IEquatable => new(span, values, emptySequenceYieldsEmpty); #endregion } } diff --git a/Nemesis.TextParsers/TokenSequence.cs b/Nemesis.TextParsers/TokenSequence.cs index e185d59..65410f2 100644 --- a/Nemesis.TextParsers/TokenSequence.cs +++ b/Nemesis.TextParsers/TokenSequence.cs @@ -21,7 +21,7 @@ public TokenSequence(ReadOnlySpan sequence, TElement separator, TEleme private readonly TElement _escapingElement; private readonly bool _emptySequenceYieldsEmpty; - public TokenSequenceEnumerator GetEnumerator() => new TokenSequenceEnumerator(_sequence, _separator, _escapingElement, _emptySequenceYieldsEmpty); + public TokenSequenceEnumerator GetEnumerator() => new(_sequence, _separator, _escapingElement, _emptySequenceYieldsEmpty); public ref struct TokenSequenceEnumerator { diff --git a/Nemesis.TextParsers/Utils/CollectionMeta.cs b/Nemesis.TextParsers/Utils/CollectionMeta.cs index 17671a6..85332ec 100644 --- a/Nemesis.TextParsers/Utils/CollectionMeta.cs +++ b/Nemesis.TextParsers/Utils/CollectionMeta.cs @@ -194,7 +194,7 @@ private static Type GetElementType(Type collectionType) return genericInterfaceType.GenericTypeArguments[0]; } - private static readonly HashSet _supportedCollectionTypes = new HashSet() + private static readonly HashSet _supportedCollectionTypes = new() { typeof(IEnumerable<>), typeof(ICollection<>), diff --git a/Nemesis.TextParsers/Utils/DictionaryMeta.cs b/Nemesis.TextParsers/Utils/DictionaryMeta.cs index 6c6faee..9bbff61 100644 --- a/Nemesis.TextParsers/Utils/DictionaryMeta.cs +++ b/Nemesis.TextParsers/Utils/DictionaryMeta.cs @@ -6,7 +6,9 @@ using System.Globalization; using System.Reflection; using System.Runtime.Serialization; + using JetBrains.Annotations; + using Nemesis.TextParsers.Runtime; namespace Nemesis.TextParsers.Utils @@ -150,7 +152,7 @@ public static DictionaryMeta GetDictionaryMeta(Type dictType) kind != DictionaryKind.Unknown ) { - (Type keyType, Type valueType) = GetPairType(dictType); + var (keyType, valueType) = GetPairType(dictType); return new(kind, keyType, valueType); } @@ -203,7 +205,7 @@ private static (Type keyType, Type valueType) GetPairType(Type dictType) }; public static bool IsTypeSupported(Type dictType) => - dictType is {IsGenericType: true} && dictType.GetGenericTypeDefinition() is { } definition && + dictType is { IsGenericType: true } && dictType.GetGenericTypeDefinition() is { } definition && _supportedDictionaryTypes.Contains(definition); } diff --git a/Nemesis.TextParsers/Utils/ReflectionUtils.cs b/Nemesis.TextParsers/Utils/ReflectionUtils.cs index 604040d..5f60fa2 100644 --- a/Nemesis.TextParsers/Utils/ReflectionUtils.cs +++ b/Nemesis.TextParsers/Utils/ReflectionUtils.cs @@ -8,7 +8,7 @@ internal static class ReflectionUtils public static object GetInstanceOrCreate(Type type, Type returnType) { const BindingFlags PUB_STAT_FLAGS = BindingFlags.Public | BindingFlags.Static; - + if (type.GetProperty("Instance", PUB_STAT_FLAGS) is { } singletonProperty && singletonProperty.GetMethod != null && returnType.IsAssignableFrom(singletonProperty.PropertyType) diff --git a/appveyor.yml b/appveyor.yml index afe813f..9c067d8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -51,7 +51,7 @@ artifacts: deploy: - provider: NuGet api_key: - secure: aF+qruFVt2BBQnO+WSureAZyQLkaGoHkY6AkXKuNP0uy8T20hpoCokx7SGBk0Gxf + secure: Py3oG4T4UplJdmxTR87wmv8IPUFwesWwsimx1XkAZYxxf/dkhi16viOWk/DXk8Ox on: branch: master APPVEYOR_REPO_TAG: true \ No newline at end of file