Skip to content

Commit

Permalink
Illuminator (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
sgaliamov committed Apr 11, 2021
1 parent ec65920 commit c54d3f9
Show file tree
Hide file tree
Showing 71 changed files with 858 additions and 523 deletions.
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
[submodule "external/illuminator"]
path = external/illuminator
url = https://github.com/sgaliamov/illuminator.git
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"*.sln"
],
"cSpell.words": [
"Brfalse",
"MSIL",
"Redstone",
"Skylake",
"Struct",
Expand Down
12 changes: 0 additions & 12 deletions ILLightenComparer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
readme.md = readme.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Illuminator", "external\illuminator\src\Illuminator\Illuminator.csproj", "{BA1BD1BA-215E-483D-BD64-63DAA30FF778}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{15FA73AD-EF43-4228-A4F6-44E186E5C06B}"
ProjectSection(SolutionItems) = preProject
scripts\benchmarks.ps1 = scripts\benchmarks.ps1
Expand All @@ -34,13 +32,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EBC9FF7F-B
docs\roadmap.md = docs\roadmap.md
EndProjectSection
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Illuminator.Shared", "external\illuminator\src\Illuminator\Illuminator.Shared.shproj", "{4497D5CE-4813-46BA-868D-58D696AE81D4}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
external\illuminator\src\Illuminator\Illuminator.Shared.projitems*{020c78a5-4642-42c5-900c-dd3658051481}*SharedItemsImports = 5
external\illuminator\src\Illuminator\Illuminator.Shared.projitems*{4497d5ce-4813-46ba-868d-58d696ae81d4}*SharedItemsImports = 13
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Expand All @@ -58,10 +50,6 @@ Global
{52C5C857-3A08-4D74-B954-1B99FEB403D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52C5C857-3A08-4D74-B954-1B99FEB403D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52C5C857-3A08-4D74-B954-1B99FEB403D5}.Release|Any CPU.Build.0 = Release|Any CPU
{BA1BD1BA-215E-483D-BD64-63DAA30FF778}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA1BD1BA-215E-483D-BD64-63DAA30FF778}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA1BD1BA-215E-483D-BD64-63DAA30FF778}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA1BD1BA-215E-483D-BD64-63DAA30FF778}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
9 changes: 9 additions & 0 deletions ILLightenComparer.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_PARAMETER/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_EXTENDS_LIST/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/ALIGN_MULTILINE_CALLS_CHAIN/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/INDENT_PREPROCESSOR_IF/@EntryValue">USUAL_INDENT</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ install:

before_build:
- pwsh: |
gitversion /l console /output buildserver /verbosity warn
gitversion /l console /output buildserver /verbosity quiet
if ($env:APPVEYOR_REPO_TAG -eq $false) {
Set-AppveyorBuildVariable -Name Configuration -Value debug
}
Expand Down
18 changes: 5 additions & 13 deletions docs/deployment.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
# Deployment process
# Development

## Preliminary statements
1. Create a new feature branch from *master*.
1. Squash and merge RP.
1. Publish [release](https://github.com/sgaliamov/il-lighten-comparer/releases/new).

1. Use GitFlow to have separate `develop` and `master` branch.
1. Version of the next package is defined by tag on `master` branch.
1. Promotion on productions must happen manually, but automatically to private `nuget` hub.

## Release

1. Create PR from `develop` branch to `master`. Make sure that all checks is passed.
1. Merge RP (do not squash `develop`).
1. Wait for all builds to ensure that it works after the merge.
1. Add [release notes](https://github.com/sgaliamov/il-lighten-comparer/tags) and publish the release.
1. [Deploy](https://ci.appveyor.com/environment/40781/deployments/new) to [nuget.org](https://nuget.org) if need be.
It will publish the package to [nuget.org](https://www.nuget.org/packages/ILLightenComparer/).
1 change: 0 additions & 1 deletion external/illuminator
Submodule illuminator deleted from b45d39
28 changes: 15 additions & 13 deletions src/ILLightenComparer.Benchmarks/Benchmark/EqualityBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using Illuminator.Extensions;
using static Illuminator.Functional;
using Illuminator;
using static Illuminator.Functions;

namespace ILLightenComparer.Benchmarks.Benchmark
{
Expand All @@ -15,9 +15,9 @@ public class EqualityBenchmark
private const int N = 10000;
private readonly int[] _one = new int[N];
private readonly int[] _other = new int[N];

[SuppressMessage("Code Quality", "IDE0052:Remove unread private members", Justification = "<Pending>")]
private bool _out;

private Func<int, int, bool> _subCompare;
private Func<int, int, bool> _subNot;

Expand All @@ -32,21 +32,23 @@ public void Setup()
}

var subCompare = new DynamicMethod("SubCompare", typeof(bool), new[] { typeof(int), typeof(int) });
using (var il = subCompare.GetILGenerator().CreateILEmitter()) {
il.Sub(LoadArgument(0), LoadArgument(1))
.IfFalse_S(out var equals)
.Return(0)
using (var il = subCompare.GetILGenerator().UseIlluminator()) {
il.Sub(Ldarg(0), Ldarg(1))
.Brfalse_S(out var equals)
.Ldc_I4_0()
.Ret()
.MarkLabel(equals)
.Return(1);
.Ldc_I4_1()
.Ret();

_subCompare = subCompare.CreateDelegate<Func<int, int, bool>>();
}

var subNot = new DynamicMethod("SubNot", typeof(bool), new[] { typeof(int), typeof(int) });
using (var il = subNot.GetILGenerator().CreateILEmitter()) {
il.Sub(LoadArgument(0), LoadArgument(1))
using (var il = subNot.GetILGenerator().UseIlluminator()) {
il.Sub(Ldarg(0), Ldarg(1))
.Not()
.Return();
.Ret();

_subNot = subNot.CreateDelegate<Func<int, int, bool>>();
}
Expand Down Expand Up @@ -77,7 +79,7 @@ public void Sub()
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Sub(int a, int b) => (a - b) == 0;
private static bool Sub(int a, int b) => a - b == 0;

[Benchmark]
public void Equals()
Expand All @@ -101,4 +103,4 @@ public void Operator()
[MethodImpl(MethodImplOptions.NoInlining)]
private static bool Operator(int a, int b) => a == b;
}
}
}
3 changes: 1 addition & 2 deletions src/ILLightenComparer.Tests/ComparerTests/GenericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using FluentAssertions.Execution;
using Force.DeepCloner;
using ILLightenComparer.Tests.Utilities;
using Illuminator.Extensions;

namespace ILLightenComparer.Tests.ComparerTests
{
Expand Down Expand Up @@ -152,7 +151,7 @@ private static void Comparisons_work_identical<T>(IComparer<T> referenceComparer
var expected = referenceComparer.Compare(x, y).Normalize();
var actual = typedComparer.Compare(x, y).Normalize();

var message = $"{type.DisplayName()} should be supported.\n"
var message = $"{type.FullName} should be supported.\n"
+ $"x: {x.ToJson()},\n"
+ $"y: {y.ToJson()}";

Expand Down
1 change: 1 addition & 0 deletions src/ILLightenComparer.Tests/EqualityExamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public void Basic_usage()

var equality = comparer.Equals(x, y);
var hashX = comparer.GetHashCode(x);

var hashY = comparer.GetHashCode(y);

using (new AssertionScope()) {
Expand Down
3 changes: 1 addition & 2 deletions src/ILLightenComparer.Tests/EqualityTests/GenericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using FluentAssertions.Execution;
using Force.DeepCloner;
using ILLightenComparer.Tests.Utilities;
using Illuminator.Extensions;

namespace ILLightenComparer.Tests.EqualityTests
{
Expand Down Expand Up @@ -166,7 +165,7 @@ private void Comparisons_work_identical<T>(IEqualityComparer<T> referenceCompare
var expectedEquals = referenceComparer.Equals(x, y);
var actualEquals = typedComparer.Equals(x, y);

var message = $"{type.DisplayName()} should be supported.";
var message = $"{type.FullName} should be supported.";
actualEquals.Should().Be(expectedEquals, message);

if (_compareHashes) {
Expand Down
8 changes: 2 additions & 6 deletions src/ILLightenComparer.Tests/EqualityTests/SampleTypesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ public void Compare_nullable_types_directly()
}

[Fact]
public void Compare_types_directly()
{
public void Compare_types_directly() =>
Parallel.ForEach(TestTypes.Types, item => {
var (type, referenceComparer) = item;
new GenericTests(false).GenericTest(type, referenceComparer, Constants.SmallCount);
});
}

[Fact]
public void Should_use_delayed_comparison()
Expand All @@ -69,14 +67,12 @@ public void Should_use_delayed_comparison()
}
}

private static void TestCollection(Type genericCollectionType = null)
{
private static void TestCollection(Type genericCollectionType = null) =>
Parallel.ForEach(TestTypes.Types, item => {
var (type, referenceComparer) = item;
TestCollection(type, referenceComparer, genericCollectionType, false);
TestCollection(type, referenceComparer, genericCollectionType, true);
});
}

private static void TestNullableCollection(Type genericCollectionType = null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Reflection;
using AutoFixture.Kernel;
using Illuminator.Extensions;

namespace ILLightenComparer.Tests.Utilities
{
Expand Down
1 change: 0 additions & 1 deletion src/ILLightenComparer.Tests/Utilities/FixtureBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using AutoFixture;
using AutoFixture.Kernel;
using Force.DeepCloner;
using Illuminator.Extensions;
using Xunit;

namespace ILLightenComparer.Tests.Utilities
Expand Down
1 change: 0 additions & 1 deletion src/ILLightenComparer.Tests/Utilities/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using FluentAssertions.Execution;
using ILLightenComparer.Tests.Comparers;
using ILLightenComparer.Tests.EqualityComparers;
using Illuminator.Extensions;
using Xunit;

namespace ILLightenComparer.Tests.Utilities
Expand Down
3 changes: 1 addition & 2 deletions src/ILLightenComparer.Tests/Utilities/ObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using Illuminator.Extensions;
using Newtonsoft.Json;

namespace ILLightenComparer.Tests.Utilities
Expand Down Expand Up @@ -34,7 +33,7 @@ public static T GetOrAddProperty<T, TTarget>(this TTarget obj, string name, Func
public static Type GetGenericInterface(this Type type, Type generic)
{
if (!generic.IsGenericType) {
throw new ArgumentException($"{generic.DisplayName()} should be generic type.", nameof(generic));
throw new ArgumentException($"{generic.FullName} should be generic type.", nameof(generic));
}

if (type.IsInterface && type.IsGenericType && type.GetGenericTypeDefinition() == generic) {
Expand Down
1 change: 0 additions & 1 deletion src/ILLightenComparer.Tests/Utilities/ObjectWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Illuminator.Extensions;

namespace ILLightenComparer.Tests.Utilities
{
Expand Down
32 changes: 31 additions & 1 deletion src/ILLightenComparer.Tests/Utilities/ReflectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,35 @@ public static Type MakeNullable(this Type type)
}

public static bool IsSealedType(this Type type) => type.IsValueType || type.IsSealed;

public static bool IsNullable(this Type type) =>
type.IsValueType
&& type.IsGenericType
&& !type.IsGenericTypeDefinition
&& ReferenceEquals(type.GetGenericTypeDefinition(), typeof(Nullable<>));

public static bool IsPrimitive(this Type type) =>
type.IsPrimitive
|| type.IsEnum
|| ReferenceEquals(type, typeof(string))
// || ReferenceEquals(type, typeof(object)) // todo: 3. move extensions to separate assembly
|| ReferenceEquals(type, typeof(decimal));

public static bool ImplementsGenericInterface(this Type type, Type generic) => type.FindGenericInterface(generic) != null;

public static Type FindGenericInterface(this Type type, Type generic)
{
if (!generic.IsGenericType) {
throw new ArgumentException($"{generic.FullName} should be generic type.", nameof(generic));
}

if (type.IsInterface && type.IsGenericType && type.GetGenericTypeDefinition() == generic) {
return type;
}

return Array.Find(
type.GetInterfaces(),
t => t.IsGenericType && generic == t.GetGenericTypeDefinition());
}
}
}
}
9 changes: 6 additions & 3 deletions src/ILLightenComparer/Abstractions/IComparisonEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ internal interface IComparisonEmitter

internal static class ComparisonEmitterExtensions
{
public static ILEmitterFunc Emit(this IComparisonEmitter emitter, Label next) => il => emitter.Emit(il, next);
public static ILEmitterFunc EmitCheckForResult(this IComparisonEmitter emitter, Label next) => il => emitter.EmitCheckForResult(il, next);
public static ILEmitterFunc Emit(this IComparisonEmitter emitter, Label next) =>
(in ILEmitter il) => emitter.Emit(il, next);

public static ILEmitterFunc EmitCheckForResult(this IComparisonEmitter emitter, Label next) =>
(in ILEmitter il) => emitter.EmitCheckForResult(il, next);
}
}
}
20 changes: 11 additions & 9 deletions src/ILLightenComparer/Abstractions/IHasherEmitter.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
using System.Reflection.Emit;
using Illuminator;
using static Illuminator.Functional;
using static ILLightenComparer.Extensions.Functions;
using static Illuminator.Functions;

namespace ILLightenComparer.Abstractions
{
internal interface IHasherEmitter
{
/// <summary>
/// Hashing logic builder.
/// Hashing logic builder.
/// </summary>
ILEmitter Emit(ILEmitter il);

/// <summary>
/// Hashing logic builder with variable to accumulate hash.
/// Hashing logic builder with variable to accumulate hash.
/// </summary>
ILEmitter Emit(ILEmitter il, LocalBuilder hash);
}

internal static class HasherEmitterExtensions
{
public static ILEmitterFunc Emit(this IHasherEmitter hasher, LocalBuilder hash) => il => hasher.Emit(il, hash);
public static ILEmitterFunc Emit(this IHasherEmitter hasher, LocalBuilder hash) =>
(in ILEmitter il) => hasher.Emit(il, hash);

public static ILEmitter EmitHashing(this IHasherEmitter hasher, ILEmitter il, LocalBuilder hash)
{
var add = Add(
ShiftLeft(LoadLocal(hash), LoadInteger(5)),
LoadLocal(hash));
Shl(Ldloc(hash), Ldc_I4(5)),
Ldloc(hash));

return il
.Xor(add, Cast<long>(hasher.Emit(hash))) // todo: 2. need to cast?
.Store(hash);
.Xor(add, Cast<long>(hasher.Emit(hash))) // todo: 2. need to cast?
.Stloc(hash);
}
}
}
}
Loading

0 comments on commit c54d3f9

Please sign in to comment.