Skip to content

Commit

Permalink
Switch to C# 9.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan Ivon committed Mar 5, 2021
1 parent a78720a commit 6b00dd6
Show file tree
Hide file tree
Showing 28 changed files with 174 additions and 174 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,17 @@ Everything is string. Because there is no data type info in CSV files, this is b
However, driver provides few extension methods providing easy conversion from string to nullable of common types:

```csharp
int? ToInt(CultureInfo cultureInfo = null);
long? ToLong(CultureInfo cultureInfo = null);
double? ToDouble(CultureInfo cultureInfo = null);
decimal? ToDecimal(CultureInfo cultureInfo = null);
DateTime? ToDateTime(DateTimeStyles dateTimeStyles = DateTimeStyles.None, CultureInfo cultureInfo = null);
DateTime? ToDateTime(string format, DateTimeStyles dateTimeStyles = DateTimeStyles.None, CultureInfo cultureInfo = null);
DateTime? ToDateTime(string[] formats, DateTimeStyles dateTimeStyles = DateTimeStyles.None, CultureInfo cultureInfo = null);
TimeSpan? ToTimeSpan(CultureInfo cultureInfo = null);
TimeSpan? ToTimeSpan(string format, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None, CultureInfo cultureInfo = null);
TimeSpan? ToTimeSpan(string[] formats, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None, CultureInfo cultureInfo = null);
bool? ToBool(CultureInfo cultureInfo = null);
int? ToInt(CultureInfo? cultureInfo = null);
long? ToLong(CultureInfo? cultureInfo = null);
double? ToDouble(CultureInfo? cultureInfo = null);
decimal? ToDecimal(CultureInfo? cultureInfo = null);
DateTime? ToDateTime(DateTimeStyles dateTimeStyles = DateTimeStyles.None, CultureInfo? cultureInfo = null);
DateTime? ToDateTime(string format, DateTimeStyles dateTimeStyles = DateTimeStyles.None, CultureInfo? cultureInfo = null);
DateTime? ToDateTime(string[] formats, DateTimeStyles dateTimeStyles = DateTimeStyles.None, CultureInfo? cultureInfo = null);
TimeSpan? ToTimeSpan(CultureInfo? cultureInfo = null);
TimeSpan? ToTimeSpan(string format, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None, CultureInfo? cultureInfo = null);
TimeSpan? ToTimeSpan(string[] formats, TimeSpanStyles timeSpanStyles = TimeSpanStyles.None, CultureInfo? cultureInfo = null);
bool? ToBool(CultureInfo? cultureInfo = null);
```

Known Issues
Expand Down
14 changes: 7 additions & 7 deletions Src/CsvLINQPadDriver/CodeGen/CsvCSharpCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class CsvCSharpCodeGenerator
private readonly string _contextNameSpace;
private readonly string _contextTypeName;

public CsvCSharpCodeGenerator(string contextNameSpace, string contextTypeName, ICsvDataContextDriverProperties properties)
private CsvCSharpCodeGenerator(string contextNameSpace, string contextTypeName, ICsvDataContextDriverProperties properties)
{
_contextNameSpace = contextNameSpace;
_contextTypeName = contextTypeName;
Expand All @@ -40,7 +40,7 @@ private string GenerateSrcFile(CsvDatabase csvDatabase) =>
namespace {_contextNameSpace}
{{
/// <summary>CSV Data Context</summary>
public class {_contextTypeName} : {typeof(CsvDataContextBase).GetCodeTypeClassName()}
public class {_contextTypeName} : {typeof(CsvDataContextBase).GetCodeTypeClassName()}
{{ {string.Join(string.Empty, csvDatabase.Tables.Select(table => $@"
/// <summary>File: {SecurityElement.Escape(table.FilePath)}</summary>
public {typeof(CsvTableBase<>).GetCodeTypeClassName(table.GetCodeRowClassName())} {table.CodeName} {{ get; private set; }}")
Expand All @@ -50,11 +50,11 @@ public class {_contextTypeName} : {typeof(CsvDataContextBase).GetCodeTypeClassNa
{{
//Init tables data {string.Join(string.Empty, csvDatabase.Tables.Select(table => $@"
this.{table.CodeName} = {typeof(CsvTableFactory).GetCodeTypeClassName()}.CreateTable<{table.GetCodeRowClassName()}>(
{(_properties.IsStringInternEnabled ? "true" : "false")},
{(_properties.IsCacheEnabled ? "true" : "false")},
{table.CsvSeparator.AsValidCSharpCode()},
{(_properties.IsStringInternEnabled ? "true" : "false")},
{(_properties.IsCacheEnabled ? "true" : "false")},
{table.CsvSeparator.AsValidCSharpCode()},
{table.FilePath.AsValidCSharpCode()},
new {typeof(CsvColumnInfoList<>).GetCodeTypeClassName(table.GetCodeRowClassName())}() {{
new {typeof(CsvColumnInfoList<>).GetCodeTypeClassName(table.GetCodeRowClassName())}() {{
{string.Join(string.Empty, table.Columns.Select(c => $@"{{ {c.CsvColumnIndex}, x => x.{c.CodeName} }}, "))}
}},
r => {{ {string.Join(string.Empty, table.Relations.Select(csvRelation => $@"
Expand All @@ -66,7 +66,7 @@ public class {_contextTypeName} : {typeof(CsvDataContextBase).GetCodeTypeClassNa
}}
}}//context class
//Data types {string.Join(string.Empty, csvDatabase.Tables.Select(table => GenerateTableRowDataTypeClass(table, _properties.HideRelationsFromDump)))}
//Data types {string.Join(string.Empty, csvDatabase.Tables.Select(table => GenerateTableRowDataTypeClass(table, _properties.HideRelationsFromDump)))}
}}//namespace
";

Expand Down
6 changes: 1 addition & 5 deletions Src/CsvLINQPadDriver/CodeGen/CsvColumnInfo.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
namespace CsvLINQPadDriver.CodeGen
{
public class CsvColumnInfo
{
public int CsvColumnIndex { get; set; }
public string PropertyName { get; set; }
}
public record CsvColumnInfo(int CsvColumnIndex, string PropertyName);
}
8 changes: 1 addition & 7 deletions Src/CsvLINQPadDriver/CodeGen/CsvColumnInfoList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@ public void Add(int csvColumnIndex, Expression<Func<TRow, string>> propertyExpre
var memberExpression = propertyExpression.Body as MemberExpression ??
throw new ArgumentException($"{nameof(propertyExpression)} expression must be only property access", nameof(propertyExpression));

var propertyName = memberExpression.Member.Name;

Add(new CsvColumnInfo
{
CsvColumnIndex = csvColumnIndex,
PropertyName = propertyName
});
Add(new CsvColumnInfo(csvColumnIndex, memberExpression.Member.Name));
}
}
}
10 changes: 5 additions & 5 deletions Src/CsvLINQPadDriver/CodeGen/CsvRowMappingBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ namespace CsvLINQPadDriver.CodeGen
public class CsvRowMappingBase<TRow>
where TRow : ICsvRowBase, new()
{
private readonly Action<TRow, string[]> _propertiesInit;
private readonly Action<TRow> _relationsInit;
private readonly Action<TRow, string?[]> _propertiesInit;
private readonly Action<TRow>? _relationsInit;

public CsvRowMappingBase(IEnumerable<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit = null)
public CsvRowMappingBase(IEnumerable<CsvColumnInfo> propertiesInfo, Action<TRow>? relationsInit = null)
{
_relationsInit = relationsInit;

var paramRow = Parameter(typeof(TRow));
var paramValues = Parameter(typeof(string[]));

_propertiesInit =
Lambda<Action<TRow, string[]>>(
Lambda<Action<TRow, string?[]>>(
Block(propertiesInfo.Select(property =>
Assign(
PropertyOrField(paramRow, property.PropertyName),
Expand All @@ -35,7 +35,7 @@ public CsvRowMappingBase(IEnumerable<CsvColumnInfo> propertiesInfo, Action<TRow>
).Compile();
}

public TRow InitRowObject(string[] data)
public TRow InitRowObject(string?[] data)
{
var row = new TRow();

Expand Down
13 changes: 7 additions & 6 deletions Src/CsvLINQPadDriver/CodeGen/CsvTableBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@ public class CsvTableBase

internal bool IsStringInternEnabled { get; }

public CsvTableBase(bool isStringInternEnabled) =>
protected CsvTableBase(bool isStringInternEnabled) =>
IsStringInternEnabled = isStringInternEnabled;
}

public abstract class CsvTableBase<TRow> : CsvTableBase, IEnumerable<TRow>
where TRow : ICsvRowBase, new()
{
private static CsvRowMappingBase<TRow> _cachedCsvRowMappingBase;
private static CsvRowMappingBase<TRow>? _cachedCsvRowMappingBase;

public char CsvSeparator { get; }
public string FilePath { get; }
private char CsvSeparator { get; }

protected CsvTableBase(bool isStringInternEnabled, char csvSeparator, string filePath, ICollection<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit)
protected string FilePath { get; }

protected CsvTableBase(bool isStringInternEnabled, char csvSeparator, string filePath, IEnumerable<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit)
: base(isStringInternEnabled)
{
CsvSeparator = csvSeparator;
Expand All @@ -34,7 +35,7 @@ protected CsvTableBase(bool isStringInternEnabled, char csvSeparator, string fil
}

protected IEnumerable<TRow> ReadData() =>
FileUtils.CsvReadRows(FilePath, CsvSeparator, IsStringInternEnabled, _cachedCsvRowMappingBase);
FileUtils.CsvReadRows(FilePath, CsvSeparator, IsStringInternEnabled, _cachedCsvRowMappingBase!);

// ReSharper disable once UnusedMember.Global
public abstract IEnumerable<TRow> WhereIndexed(Func<TRow, string> getProperty, string propertyName, params string[] values);
Expand Down
2 changes: 1 addition & 1 deletion Src/CsvLINQPadDriver/CodeGen/CsvTableEnumerable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace CsvLINQPadDriver.CodeGen
internal class CsvTableEnumerable<TRow> : CsvTableBase<TRow>
where TRow : ICsvRowBase, new()
{
public CsvTableEnumerable(bool isStringInternEnabled, char csvSeparator, string filePath, ICollection<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit)
public CsvTableEnumerable(bool isStringInternEnabled, char csvSeparator, string filePath, IEnumerable<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit)
: base(isStringInternEnabled, csvSeparator, filePath, propertiesInfo, relationsInit)
{
}
Expand Down
2 changes: 1 addition & 1 deletion Src/CsvLINQPadDriver/CodeGen/CsvTableFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static CsvTableBase<TRow> CreateTable<TRow>(
bool isCacheEnabled,
char csvSeparator,
string filePath,
ICollection<CsvColumnInfo> propertiesInfo,
IEnumerable<CsvColumnInfo> propertiesInfo,
Action<TRow> relationsInit)
where TRow : ICsvRowBase, new() =>
isCacheEnabled
Expand Down
4 changes: 2 additions & 2 deletions Src/CsvLINQPadDriver/CodeGen/CsvTableList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ internal class CsvTableList<TRow> : CsvTableBase<TRow>, IList<TRow>
private readonly IDictionary<string, ILookup<string, TRow>> _indices = new Dictionary<string, ILookup<string, TRow>>();
private readonly Lazy<IList<TRow>> _dataCache;

public CsvTableList(bool isStringInternEnabled, char csvSeparator, string filePath, ICollection<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit)
public CsvTableList(bool isStringInternEnabled, char csvSeparator, string filePath, IEnumerable<CsvColumnInfo> propertiesInfo, Action<TRow> relationsInit)
: base(isStringInternEnabled, csvSeparator, filePath, propertiesInfo, relationsInit) =>
_dataCache = new Lazy<IList<TRow>>(() => ReadData().Cache($"{typeof(TRow).Name}:{FilePath}"));

protected IList<TRow> DataCache =>
private IList<TRow> DataCache =>
_dataCache.Value;

public override IEnumerator<TRow> GetEnumerator() =>
Expand Down
4 changes: 2 additions & 2 deletions Src/CsvLINQPadDriver/CodeGen/ICsvRowBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public string ToString() =>
.GetProperties()
.Where(propertyInfo => propertyInfo.PropertyType == typeof(string))
.Select(propertyInfo => propertyInfo.GetGetMethod())
.Where(methodInfo => methodInfo != null)
.Select(methodInfo => methodInfo.Invoke(this, null))
.Where(methodInfo => methodInfo is not null)
.Select(methodInfo => methodInfo!.Invoke(this, null))
.OfType<string>());
}
}
11 changes: 7 additions & 4 deletions Src/CsvLINQPadDriver/CsvDataContextDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@

namespace CsvLINQPadDriver
{
// ReSharper disable once ClassNeverInstantiated.Global
public class CsvDataContextDriver : DynamicDataContextDriver
{
public override string Name =>
"CSV Context Driver";

public override Version Version =>
Assembly.GetExecutingAssembly().GetName().Version;
Assembly.GetExecutingAssembly().GetName().Version!;

[SuppressMessage("ReSharper", "StringLiteralTypo")]
public override string Author =>
Expand Down Expand Up @@ -53,8 +54,10 @@ public override ICustomMemberProvider GetCustomDisplayMemberProvider(object obje
CsvRowMemberProvider.GetCsvRowMemberProvider(objectToWrite) ??
base.GetCustomDisplayMemberProvider(objectToWrite);

public override IEnumerable<string> GetNamespacesToAdd(IConnectionInfo cxInfo) =>
new [] { typeof(StringExtensions).Namespace };
public override IEnumerable<string> GetNamespacesToAdd(IConnectionInfo cxInfo)
{
yield return typeof(StringExtensions).Namespace!;
}

public override List<ExplorerItem> GetSchemaAndBuildAssembly(IConnectionInfo cxInfo, AssemblyName assemblyToBuild, ref string nameSpace, ref string typeName) =>
SchemaBuilder.GetSchemaAndBuildAssembly(
Expand All @@ -63,7 +66,7 @@ public override List<ExplorerItem> GetSchemaAndBuildAssembly(IConnectionInfo cxI
ref nameSpace,
ref typeName);

internal static void WriteToLog(string additionalInfo, Exception exception = null)
internal static void WriteToLog(string additionalInfo, Exception? exception = null)
{
const string logFileName = nameof(CsvLINQPadDriver) + ".txt";

Expand Down
20 changes: 10 additions & 10 deletions Src/CsvLINQPadDriver/CsvDataContextDriverProperties.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -29,20 +30,19 @@ public bool Persist

public string Files
{
get => GetValue(string.Empty);
get => GetValue(string.Empty)!;
set => SetValue(value);
}

public string[] ParsedFiles =>
public IEnumerable<string> ParsedFiles =>
Regex.Split(Files, @"[\r\n]+")
.Select(fileName => fileName.Trim())
.Where(fileName => !string.IsNullOrEmpty(fileName))
.Distinct(StringComparer.InvariantCultureIgnoreCase)
.ToArray();
.Distinct(StringComparer.InvariantCultureIgnoreCase);

public string CsvSeparator
{
get => GetValue(string.Empty);
get => GetValue(string.Empty)!;
set => SetValue(value);
}

Expand Down Expand Up @@ -108,16 +108,16 @@ public bool IsCacheEnabled
set => SetValue(value);
}

private T GetValue<T>(Func<string, T> convert, T defaultValue, [CallerMemberName] string callerMemberName = default) =>
private T GetValue<T>(Func<string?, T> convert, T defaultValue, [CallerMemberName] string callerMemberName = "") =>
convert(_driverData.Element(callerMemberName)?.Value) ?? defaultValue;

private bool GetValue(bool defaultValue, [CallerMemberName] string callerMemberName = default) =>
private bool GetValue(bool defaultValue, [CallerMemberName] string callerMemberName = "") =>
GetValue(v => v.ToBool(), defaultValue, callerMemberName)!.Value;

private string GetValue(string defaultValue, [CallerMemberName] string callerMemberName = default) =>
private string? GetValue(string defaultValue, [CallerMemberName] string callerMemberName = "") =>
GetValue(v => v, defaultValue, callerMemberName);

private void SetValue<T>(T value, [CallerMemberName] string callerMemberName = default) =>
_driverData.SetElementValue(callerMemberName!, value);
private void SetValue<T>(T value, [CallerMemberName] string callerMemberName = "") =>
_driverData.SetElementValue(callerMemberName, value);
}
}
3 changes: 3 additions & 0 deletions Src/CsvLINQPadDriver/CsvLINQPadDriver.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
<UseWpf>true</UseWpf>
<Deterministic>false</Deterministic>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand All @@ -28,6 +30,7 @@
<FileVersion>6.5.0.0</FileVersion>
<Version>6.5.0</Version>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<ApplicationIcon>Connection.ico</ApplicationIcon>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand Down
22 changes: 8 additions & 14 deletions Src/CsvLINQPadDriver/DataDisplay/CsvRowMemberProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace CsvLINQPadDriver.DataDisplay
{
internal class CsvRowMemberProvider : ICustomMemberProvider
{
private static readonly Dictionary<Type, ProviderData> ProvidersDataCache = new Dictionary<Type, ProviderData>();
private static readonly Dictionary<Type, ProviderData> ProvidersDataCache = new();

private readonly object _objectToDisplay;
private readonly ProviderData _providerData;
Expand All @@ -37,38 +37,32 @@ public IEnumerable<Type> GetTypes() =>
public IEnumerable<object> GetValues() =>
_providerData.ValuesGetter(_objectToDisplay);

protected class ProviderData
{
public IList<PropertyInfo> Properties;
public IList<FieldInfo> Fields;
public Func<object, object[]> ValuesGetter;
}
protected record ProviderData(IList<PropertyInfo> Properties, IList<FieldInfo> Fields, Func<object, object[]> ValuesGetter);

protected static ProviderData GetProviderData(Type objectType)
{
var param = Parameter(typeof(object));
var properties = objectType.GetProperties().Where(IsMemberVisible).ToList();
var fields = objectType.GetFields().Where(IsMemberVisible).ToList();

return new ProviderData
{
Properties = properties,
Fields = fields,
ValuesGetter = Lambda<Func<object, object[]>>(
return new ProviderData(
properties,
fields,
Lambda<Func<object, object[]>>(
NewArrayInit(typeof(object),
properties
.Select(propertyInfo => Property(TypeAs(param, objectType), propertyInfo))
.Concat(fields.Select(fieldInfo => Field(TypeAs(param, objectType), fieldInfo)))),
param)
.Compile()
};
);

static bool IsMemberVisible(MemberInfo member) =>
(member.MemberType & (MemberTypes.Field | MemberTypes.Property)) != 0 &&
member.GetCustomAttributes(typeof(HideFromDumpAttribute), true).Length == 0;
}

public static ICustomMemberProvider GetCsvRowMemberProvider(object objectToDisplay)
public static ICustomMemberProvider? GetCsvRowMemberProvider(object objectToDisplay)
{
var objectType = objectToDisplay.GetType();
if (!IsSupportedType(objectType))
Expand Down
13 changes: 7 additions & 6 deletions Src/CsvLINQPadDriver/DataModel/CsvColumn.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
namespace CsvLINQPadDriver.DataModel
{
public class CsvColumn : ICsvNames
public record CsvColumn
(
string CsvColumnName,
int CsvColumnIndex
) : ICsvNames
{
public string CodeName { get; set; }
public string DisplayName { get; set; }

public string CsvColumnName { get; set; }
public int CsvColumnIndex { get; set; }
public string? CodeName { get; set; }
public string? DisplayName { get; set; }
}
}
Loading

0 comments on commit 6b00dd6

Please sign in to comment.