From 5c5fa8ed3be49401240030ca3aaa46d1fbc8307e Mon Sep 17 00:00:00 2001 From: Elad Zelingher Date: Tue, 12 May 2020 01:25:28 -0400 Subject: [PATCH 1/6] Trying to revive this project and make it work on dotnet core Such a mistake. --- .../GraphClimber/DesignTimeBuild/.dtbcache.v2 | Bin 0 -> 197280 bytes .../Examples/Binary/BinaryFormatter.cs | 46 + .../Examples/Binary/BinaryReaderProcessor.cs | 4 +- .../Binary/BinaryStateMemberProvider.cs | 43 +- .../Examples/Binary/BinaryWriterProcessor.cs | 4 +- .../Examples/Binary/IWriter.cs | 0 .../Examples/Binary/IsArrayAttribute.cs | 0 .../Examples/Binary/PositionRestore.cs | 0 .../Examples/Binary/SuperBinaryReader.cs} | 50 +- .../Examples/Binary/SuperBinaryWriter.cs | 43 + .../Examples/Extractor/Extractor.cs | 7 +- .../Examples/Extractor/ExtractorProcessor.cs | 0 .../Examples/MyCustomStateMember.cs | 21 +- .../Examples/OldGames.cs | 0 .../Examples/Store/IStore.cs | 0 .../Examples/Store/StoreReaderProcessor.cs | 20 +- .../Examples/Store/StoreSerializer.cs | 33 + .../Examples/Store/StoreWriterProcessor.cs | 4 +- .../Examples/Store/TrivialStore.cs | 0 .../Examples/Xml/Box.cs | 11 + .../Examples/Xml/XmlReaderProcessor.cs | 43 +- .../Examples/Xml/XmlSerializer.cs | 38 + .../Examples/Xml/XmlWriterProcessor.cs | 12 +- .../GraphClimber.ConsoleApp.csproj | 12 + src/GraphClimber.ConsoleApp/Program.cs | 250 ++++++ .../CSharpExpressionDescriber.cs | 27 - .../GraphClimber.Debug.csproj | 66 -- .../Properties/AssemblyInfo.cs | 36 - src/GraphClimber.Debug/packages.config | 4 - .../GraphClimber.Tests.csproj | 77 +- .../Properties/AssemblyInfo.cs | 35 - src/GraphClimber.Tests/packages.config | 4 - src/GraphClimber.sln | 37 +- src/GraphClimber.sln.DotSettings | 3 +- .../GraphClimber/DesignTimeBuild/.dtbcache.v2 | Bin 0 -> 3631 bytes src/GraphClimber/App.config | 6 - .../CachingStateMemberProvider.cs | 47 ++ .../DescriptorExtensionMethods.cs | 446 +++++----- .../AccessPrivateFieldVisitor.cs | 179 ---- .../DebugExpressionCompiler.cs | 77 -- .../DebugExpressionVistor.cs | 107 --- .../DebugViewExpressionDescriber.cs | 37 - .../ExpressionCompiler/IExpressionCompiler.cs | 9 - .../IExpressionDescriber.cs | 16 - .../NonTrivialConstantVisitor.cs | 58 -- .../ExpressionCompiler/StringExtensions.cs | 87 -- .../TrivialExpressionCompiler.cs | 44 - .../Extensions => }/ExpressionExtensions.cs | 12 +- .../AccessorFactory.cs | 16 +- .../ArrayStateMember.cs | 81 ++ .../ClimbDelegateFactory.cs | 11 +- .../ExpressionImplementation/ClimbStore.cs | 9 +- .../DefaultGraphClimber.cs | 13 +- .../DelegateCache/ClimbDelegateCache.cs | 4 +- .../DescriptorVariable.cs | 2 - .../ExpressionImplementation/EnumConvert.cs | 34 + .../EnumUnderlyingStateMember.cs | 44 +- .../Mutators/NullProcessorMutator.cs | 1 - .../Mutators/PolymorphismMutator.cs | 3 - .../Mutators/RevisitedMutator.cs | 1 - .../PropertyStateMember.cs | 3 +- .../PropertyStateMemberProvider.cs | 2 +- .../RouteDelegateFactory.cs | 8 +- .../ValueDescriptor.cs | 4 +- src/GraphClimber/GraphClimber.csproj | 188 +---- src/GraphClimber/Program.cs | 385 --------- src/GraphClimber/Properties/AssemblyInfo.cs | 38 - src/GraphClimber/SlowGraphClimber.cs | 797 ------------------ .../ValueDescriptor/DelegateStateMember.cs | 177 +--- 69 files changed, 954 insertions(+), 2922 deletions(-) create mode 100644 src/.vs/GraphClimber/DesignTimeBuild/.dtbcache.v2 create mode 100644 src/GraphClimber.ConsoleApp/Examples/Binary/BinaryFormatter.cs rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Binary/BinaryReaderProcessor.cs (98%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Binary/BinaryStateMemberProvider.cs (74%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Binary/BinaryWriterProcessor.cs (98%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Binary/IWriter.cs (100%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Binary/IsArrayAttribute.cs (100%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Binary/PositionRestore.cs (100%) rename src/{GraphClimber/Examples/Binary/SuperBinaryWriter.cs => GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryReader.cs} (74%) create mode 100644 src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryWriter.cs rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Extractor/Extractor.cs (55%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Extractor/ExtractorProcessor.cs (100%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/MyCustomStateMember.cs (77%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/OldGames.cs (100%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Store/IStore.cs (100%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Store/StoreReaderProcessor.cs (83%) create mode 100644 src/GraphClimber.ConsoleApp/Examples/Store/StoreSerializer.cs rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Store/StoreWriterProcessor.cs (98%) rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Store/TrivialStore.cs (100%) create mode 100644 src/GraphClimber.ConsoleApp/Examples/Xml/Box.cs rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Xml/XmlReaderProcessor.cs (67%) create mode 100644 src/GraphClimber.ConsoleApp/Examples/Xml/XmlSerializer.cs rename src/{GraphClimber => GraphClimber.ConsoleApp}/Examples/Xml/XmlWriterProcessor.cs (84%) create mode 100644 src/GraphClimber.ConsoleApp/GraphClimber.ConsoleApp.csproj create mode 100644 src/GraphClimber.ConsoleApp/Program.cs delete mode 100644 src/GraphClimber.Debug/ExpressionCompiler/CSharpExpressionDescriber.cs delete mode 100644 src/GraphClimber.Debug/GraphClimber.Debug.csproj delete mode 100644 src/GraphClimber.Debug/Properties/AssemblyInfo.cs delete mode 100644 src/GraphClimber.Debug/packages.config delete mode 100644 src/GraphClimber.Tests/Properties/AssemblyInfo.cs delete mode 100644 src/GraphClimber.Tests/packages.config create mode 100644 src/GraphClimber/.vs/GraphClimber/DesignTimeBuild/.dtbcache.v2 delete mode 100644 src/GraphClimber/App.config create mode 100644 src/GraphClimber/CachingStateMemberProvider.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/AccessPrivateFieldVisitor.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/DebugExpressionCompiler.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/DebugExpressionVistor.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/DebugViewExpressionDescriber.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/IExpressionCompiler.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/IExpressionDescriber.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/NonTrivialConstantVisitor.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/StringExtensions.cs delete mode 100644 src/GraphClimber/ExpressionCompiler/TrivialExpressionCompiler.cs rename src/GraphClimber/{ExpressionCompiler/Extensions => }/ExpressionExtensions.cs (92%) create mode 100644 src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs create mode 100644 src/GraphClimber/ExpressionImplementation/EnumConvert.cs delete mode 100644 src/GraphClimber/Program.cs delete mode 100644 src/GraphClimber/Properties/AssemblyInfo.cs delete mode 100644 src/GraphClimber/SlowGraphClimber.cs diff --git a/src/.vs/GraphClimber/DesignTimeBuild/.dtbcache.v2 b/src/.vs/GraphClimber/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000000000000000000000000000000000000..e2ce513a0772d11e295551737f333c228e7ef17d GIT binary patch literal 197280 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 _binaryReader; + private readonly IGraphClimber _binaryWriter; + + public BinaryFormatter() + { + IStateMemberProvider provider = new BinaryStateMemberProvider(new PropertyStateMemberProvider()); + _binaryReader = DefaultGraphClimber.Create(provider); + _binaryWriter = DefaultGraphClimber.Create(provider); + } + + public object Deserialize(IReader reader) + { + return Deserialize(reader); + } + + public T Deserialize(IReader reader) + { + BinaryReaderProcessor processor = new BinaryReaderProcessor(reader); + StrongBox box = new StrongBox(); + _binaryReader.Climb(box, processor); + return box.Value; + } + + public void Serialize(IWriter writer, object graph) + { + Serialize(writer, graph); + } + + public void Serialize(IWriter writer, T graph) + { + BinaryWriterProcessor processor = new BinaryWriterProcessor(writer); + StrongBox box = new StrongBox(){Value = graph}; + _binaryWriter.Climb(box, processor); + } + } +} \ No newline at end of file diff --git a/src/GraphClimber/Examples/Binary/BinaryReaderProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs similarity index 98% rename from src/GraphClimber/Examples/Binary/BinaryReaderProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs index be93dfb..6729b02 100644 --- a/src/GraphClimber/Examples/Binary/BinaryReaderProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs @@ -46,7 +46,7 @@ public void ProcessReferenceType(IWriteOnlyExactValueDescriptor descriptor { descriptor.Route( new BinaryStateMember - (new MyCustomStateMember((IReflectionStateMember) descriptor.StateMember, + (new MyCustomStateMember(descriptor.StateMember, type), true, true), @@ -210,7 +210,7 @@ public void ProcessForWriteOnly(IWriteOnlyExactValueDescriptor descripto if (TryReadReferenceType(descriptor, out type)) { string value = _reader.ReadString(); - _objects.Add(value); + //_objects.Add(value); descriptor.Set(value); } } diff --git a/src/GraphClimber/Examples/Binary/BinaryStateMemberProvider.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryStateMemberProvider.cs similarity index 74% rename from src/GraphClimber/Examples/Binary/BinaryStateMemberProvider.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/BinaryStateMemberProvider.cs index e06db47..118a0c2 100644 --- a/src/GraphClimber/Examples/Binary/BinaryStateMemberProvider.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryStateMemberProvider.cs @@ -18,17 +18,16 @@ public BinaryStateMemberProvider(IStateMemberProvider underlying) public IEnumerable Provide(Type type) { return _underlying.Provide(type) - .Select(x => new BinaryStateMember((IReflectionStateMember)x)); + .Select(x => new BinaryStateMember(x)); } public IStateMember ProvideArrayMember(Type arrayType, int[] indices) { - return new BinaryStateMember((IReflectionStateMember) - _underlying.ProvideArrayMember(arrayType, indices)); + return new BinaryStateMember(_underlying.ProvideArrayMember(arrayType, indices)); } } - public class BinaryStateMember : IReflectionStateMember + public class BinaryStateMember : IStateMember { private readonly IStateMember _stateMember; private readonly bool _knownType; @@ -132,42 +131,6 @@ public bool HeaderHandled get { return _headerHandled; } } - public MemberInfo UnderlyingMemberInfo - { - get - { - var reflectionStateMember = _stateMember as IReflectionStateMember; - if (reflectionStateMember != null) - { - return reflectionStateMember.UnderlyingMemberInfo; - } - - throw new NotImplementedException(); - } - } - - public object GetValue(object owner) - { - var reflectionStateMember = _stateMember as IReflectionStateMember; - if (reflectionStateMember != null) - { - return reflectionStateMember.GetValue(owner); - } - - throw new NotImplementedException(); - } - - public void SetValue(object owner, object value) - { - var reflectionStateMember = _stateMember as IReflectionStateMember; - if (reflectionStateMember != null) - { - reflectionStateMember.SetValue(owner, value); - } - - throw new NotImplementedException(); - } - protected bool Equals(BinaryStateMember other) { return Equals(_stateMember, other._stateMember) && _knownType.Equals(other._knownType); diff --git a/src/GraphClimber/Examples/Binary/BinaryWriterProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs similarity index 98% rename from src/GraphClimber/Examples/Binary/BinaryWriterProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs index 3f5b1da..c96d85d 100644 --- a/src/GraphClimber/Examples/Binary/BinaryWriterProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs @@ -16,12 +16,12 @@ public static class ReadWriteHeader class ReferenceEqualityComparer : IEqualityComparer { - public bool Equals(object x, object y) + bool IEqualityComparer.Equals(object x, object y) { return ReferenceEquals(x, y); } - public int GetHashCode(object obj) + int IEqualityComparer.GetHashCode(object obj) { if (obj == null) { diff --git a/src/GraphClimber/Examples/Binary/IWriter.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/IWriter.cs similarity index 100% rename from src/GraphClimber/Examples/Binary/IWriter.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/IWriter.cs diff --git a/src/GraphClimber/Examples/Binary/IsArrayAttribute.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/IsArrayAttribute.cs similarity index 100% rename from src/GraphClimber/Examples/Binary/IsArrayAttribute.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/IsArrayAttribute.cs diff --git a/src/GraphClimber/Examples/Binary/PositionRestore.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/PositionRestore.cs similarity index 100% rename from src/GraphClimber/Examples/Binary/PositionRestore.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/PositionRestore.cs diff --git a/src/GraphClimber/Examples/Binary/SuperBinaryWriter.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryReader.cs similarity index 74% rename from src/GraphClimber/Examples/Binary/SuperBinaryWriter.cs rename to src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryReader.cs index 07c731e..a788f9f 100644 --- a/src/GraphClimber/Examples/Binary/SuperBinaryWriter.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryReader.cs @@ -1,52 +1,10 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace GraphClimber.Examples { - - class SuperBinaryWriter : BinaryWriter - { - private readonly IDictionary _writtenStrings = new Dictionary(); - - protected SuperBinaryWriter() - { - } - - public SuperBinaryWriter(Stream output) : base(output) - { - } - - public SuperBinaryWriter(Stream output, Encoding encoding) : base(output, encoding) - { - } - - public SuperBinaryWriter(Stream output, Encoding encoding, bool leaveOpen) : base(output, encoding, leaveOpen) - { - } - - public override void Write(string value) - { - int id; - if (_writtenStrings.TryGetValue(value, out id)) - { - base.Write((byte)1); - base.Write(id); - } - else - { - _writtenStrings[value] = _writtenStrings.Count; - base.Write((byte)0); - base.Write(value); - } - } - } - - - class SuperBinaryReader : BinaryReader + internal class SuperBinaryReader : BinaryReader { private readonly IList _readStrings = new List(); @@ -64,7 +22,7 @@ public SuperBinaryReader(Stream input, Encoding encoding, bool leaveOpen) : base public override string ReadString() { - var isRead = base.ReadByte(); + byte isRead = base.ReadByte(); if (isRead == 1) { @@ -202,4 +160,4 @@ public override int GetHashCode() return base.GetHashCode(); } } -} +} \ No newline at end of file diff --git a/src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryWriter.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryWriter.cs new file mode 100644 index 0000000..2dd4dd8 --- /dev/null +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/SuperBinaryWriter.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace GraphClimber.Examples +{ + internal class SuperBinaryWriter : BinaryWriter + { + private readonly IDictionary _writtenStrings = new Dictionary(); + + protected SuperBinaryWriter() + { + } + + public SuperBinaryWriter(Stream output) : base(output) + { + } + + public SuperBinaryWriter(Stream output, Encoding encoding) : base(output, encoding) + { + } + + public SuperBinaryWriter(Stream output, Encoding encoding, bool leaveOpen) : base(output, encoding, leaveOpen) + { + } + + public override void Write(string value) + { + int id; + if (_writtenStrings.TryGetValue(value, out id)) + { + base.Write((byte)1); + base.Write(id); + } + else + { + _writtenStrings[value] = _writtenStrings.Count; + base.Write((byte)0); + base.Write(value); + } + } + } +} diff --git a/src/GraphClimber/Examples/Extractor/Extractor.cs b/src/GraphClimber.ConsoleApp/Examples/Extractor/Extractor.cs similarity index 55% rename from src/GraphClimber/Examples/Extractor/Extractor.cs rename to src/GraphClimber.ConsoleApp/Examples/Extractor/Extractor.cs index a911824..350aca4 100644 --- a/src/GraphClimber/Examples/Extractor/Extractor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Extractor/Extractor.cs @@ -4,19 +4,20 @@ namespace GraphClimber.Examples { public class Extractor { - private readonly SlowGraphClimber> _climber; + private readonly IGraphClimber> _climber; public Extractor() { _climber = - new SlowGraphClimber>(new ReflectionPropertyStateMemberProvider()); + DefaultGraphClimber> + .Create(new PropertyStateMemberProvider()); } public void Extract(object value, Action callback) { ExtractorProcessor processor = new ExtractorProcessor(callback); - _climber.Route(value, processor, false); + _climber.Climb(new Box() {Value = value}, processor); } } } \ No newline at end of file diff --git a/src/GraphClimber/Examples/Extractor/ExtractorProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Extractor/ExtractorProcessor.cs similarity index 100% rename from src/GraphClimber/Examples/Extractor/ExtractorProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Extractor/ExtractorProcessor.cs diff --git a/src/GraphClimber/Examples/MyCustomStateMember.cs b/src/GraphClimber.ConsoleApp/Examples/MyCustomStateMember.cs similarity index 77% rename from src/GraphClimber/Examples/MyCustomStateMember.cs rename to src/GraphClimber.ConsoleApp/Examples/MyCustomStateMember.cs index ff0ef66..7ec607c 100644 --- a/src/GraphClimber/Examples/MyCustomStateMember.cs +++ b/src/GraphClimber.ConsoleApp/Examples/MyCustomStateMember.cs @@ -4,12 +4,12 @@ namespace GraphClimber.Examples { - public class MyCustomStateMember : IReflectionStateMember + public class MyCustomStateMember : IStateMember { - private readonly IReflectionStateMember _underlying; + private readonly IStateMember _underlying; private readonly Type _memberType; - public MyCustomStateMember(IReflectionStateMember underlying, Type memberType) + public MyCustomStateMember(IStateMember underlying, Type memberType) { _underlying = underlying; _memberType = memberType; @@ -63,21 +63,6 @@ public Expression GetSetExpression(Expression obj, Expression value) return _underlying.GetSetExpression(obj, value); } - public MemberInfo UnderlyingMemberInfo - { - get { return _underlying.UnderlyingMemberInfo; } - } - - public object GetValue(object owner) - { - return _underlying.GetValue(owner); - } - - public void SetValue(object owner, object value) - { - _underlying.SetValue(owner, value); - } - protected bool Equals(MyCustomStateMember other) { return Equals(_underlying, other._underlying) && Equals(_memberType, other._memberType); diff --git a/src/GraphClimber/Examples/OldGames.cs b/src/GraphClimber.ConsoleApp/Examples/OldGames.cs similarity index 100% rename from src/GraphClimber/Examples/OldGames.cs rename to src/GraphClimber.ConsoleApp/Examples/OldGames.cs diff --git a/src/GraphClimber/Examples/Store/IStore.cs b/src/GraphClimber.ConsoleApp/Examples/Store/IStore.cs similarity index 100% rename from src/GraphClimber/Examples/Store/IStore.cs rename to src/GraphClimber.ConsoleApp/Examples/Store/IStore.cs diff --git a/src/GraphClimber/Examples/Store/StoreReaderProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Store/StoreReaderProcessor.cs similarity index 83% rename from src/GraphClimber/Examples/Store/StoreReaderProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Store/StoreReaderProcessor.cs index 25e6714..62072ec 100644 --- a/src/GraphClimber/Examples/Store/StoreReaderProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Store/StoreReaderProcessor.cs @@ -19,20 +19,21 @@ public StoreReaderProcessor(IStore store) public void Process(IWriteOnlyValueDescriptor descriptor) { string type; + + IStore temp = _store; + + _store = _store.GetInner(descriptor.StateMember.Name); + if (_store.TryGet("Type", out type)) { - var value = (T)Activator.CreateInstance(Type.GetType(type)); descriptor.Set(value); - var temp = _store; - _store = _store.GetInner(descriptor.StateMember.Name); - descriptor.Climb(); - - _store = temp; } + + _store = temp; } [ProcessorMethod(Precedence = 99)] @@ -43,17 +44,16 @@ public void ProcessPrimitives<[Primitive]T>(IWriteOnlyExactValueDescriptor de { descriptor.Set(value); } - } [ProcessorMethod] public void Process(IWriteOnlyValueDescriptor descriptor) { - string type; + IStore innerStore = _store.GetInner(descriptor.StateMember.Name); - if (_store.TryGet("Type", out type)) + if (innerStore.TryGet("Type", out string type)) { - descriptor.Route(new MyCustomStateMember((IReflectionStateMember)descriptor.StateMember, Type.GetType(type)), descriptor.Owner, true); + descriptor.Route(new MyCustomStateMember(descriptor.StateMember, Type.GetType(type)), descriptor.Owner, true); } } diff --git a/src/GraphClimber.ConsoleApp/Examples/Store/StoreSerializer.cs b/src/GraphClimber.ConsoleApp/Examples/Store/StoreSerializer.cs new file mode 100644 index 0000000..aa2fe8c --- /dev/null +++ b/src/GraphClimber.ConsoleApp/Examples/Store/StoreSerializer.cs @@ -0,0 +1,33 @@ +namespace GraphClimber.Examples +{ + public class StoreSerializer + { + private readonly IGraphClimber _storeWriterClimber; + private readonly IGraphClimber _storeReaderClimber; + + public StoreSerializer() + { + IStateMemberProvider stateMemberProvider = new PropertyStateMemberProvider(); + _storeWriterClimber = DefaultGraphClimber.Create(stateMemberProvider); + _storeReaderClimber = DefaultGraphClimber.Create(stateMemberProvider); + } + + public void Write(object value, IStore store) + { + Box box = new Box() {Value = value}; + _storeWriterClimber.Climb(box, new StoreWriterProcessor(store)); + } + + public object Read(IStore store) + { + return Read(store); + } + + public T Read(IStore store) + { + Box box = new Box(); + _storeReaderClimber.Climb(box, new StoreReaderProcessor(store)); + return box.Value; + } + } +} \ No newline at end of file diff --git a/src/GraphClimber/Examples/Store/StoreWriterProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Store/StoreWriterProcessor.cs similarity index 98% rename from src/GraphClimber/Examples/Store/StoreWriterProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Store/StoreWriterProcessor.cs index 9479727..f54e809 100644 --- a/src/GraphClimber/Examples/Store/StoreWriterProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Store/StoreWriterProcessor.cs @@ -1,4 +1,3 @@ -using System.Collections.Concurrent; using System.Collections.Generic; using GraphClimber.ValueDescriptor; @@ -19,11 +18,10 @@ public StoreWriterProcessor(IStore store) public void Process(IReadOnlyValueDescriptor descriptor) { var value = descriptor.Get(); - _store.Set("Type", value.GetType().AssemblyQualifiedName); - var temp = _store; _store = _store.GetInner(descriptor.StateMember.Name); + _store.Set("Type", value.GetType().AssemblyQualifiedName); descriptor.Climb(); diff --git a/src/GraphClimber/Examples/Store/TrivialStore.cs b/src/GraphClimber.ConsoleApp/Examples/Store/TrivialStore.cs similarity index 100% rename from src/GraphClimber/Examples/Store/TrivialStore.cs rename to src/GraphClimber.ConsoleApp/Examples/Store/TrivialStore.cs diff --git a/src/GraphClimber.ConsoleApp/Examples/Xml/Box.cs b/src/GraphClimber.ConsoleApp/Examples/Xml/Box.cs new file mode 100644 index 0000000..3a8b98a --- /dev/null +++ b/src/GraphClimber.ConsoleApp/Examples/Xml/Box.cs @@ -0,0 +1,11 @@ +namespace GraphClimber.Examples +{ + internal class Box : Box + { + public T Value { get; set; } + } + + internal class Box + { + } +} \ No newline at end of file diff --git a/src/GraphClimber/Examples/Xml/XmlReaderProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Xml/XmlReaderProcessor.cs similarity index 67% rename from src/GraphClimber/Examples/Xml/XmlReaderProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Xml/XmlReaderProcessor.cs index a39191c..8cdb163 100644 --- a/src/GraphClimber/Examples/Xml/XmlReaderProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Xml/XmlReaderProcessor.cs @@ -30,9 +30,16 @@ public void ProcessString(IWriteOnlyExactValueDescriptor descriptor) XElement element = _reader.Element(descriptor.StateMember.Name); - string result = element.Value; + if (element != null) + { + string result = element.Value; - descriptor.Set(result); + descriptor.Set(result); + } + else + { + descriptor.Set(null); + } } [ProcessorMethod(Precedence = 102)] @@ -40,16 +47,23 @@ public void ProcessGeneric(IWriteOnlyValueDescriptor descriptor) { XElement temp = _reader; - _reader = _reader.Element(descriptor.StateMember.Name); - - CreateObject(descriptor); + if (!(descriptor.Owner is Box)) + { + _reader = _reader.Element(descriptor.StateMember.Name); + } - descriptor.Climb(); + if (_reader != null) + { + if (CreateObject(descriptor)) + { + descriptor.Climb(); + } + } _reader = temp; } - private void CreateObject(IWriteOnlyValueDescriptor descriptor) + private bool CreateObject(IWriteOnlyValueDescriptor descriptor) { XAttribute attribute = _reader.Attribute("Type"); @@ -63,13 +77,22 @@ private void CreateObject(IWriteOnlyValueDescriptor descriptor) (T) Activator.CreateInstance(instanceType); descriptor.Set(field); + + return true; } + + return false; } [ProcessorMethod] public void ProcessObject(IWriteOnlyExactValueDescriptor descriptor) { - XElement element = _reader.Element(descriptor.StateMember.Name); + XElement element = _reader; + + if (!(descriptor.Owner is Box)) + { + element = _reader.Element(descriptor.StateMember.Name); + } XAttribute attribute = element.Attribute("Type"); @@ -81,11 +104,9 @@ public void ProcessObject(IWriteOnlyExactValueDescriptor descriptor) // TODO: this will be the route method.. descriptor.Route - (new MyCustomStateMember((IReflectionStateMember) descriptor.StateMember, + (new MyCustomStateMember(descriptor.StateMember, instanceType), descriptor.Owner, true); } } - - } } \ No newline at end of file diff --git a/src/GraphClimber.ConsoleApp/Examples/Xml/XmlSerializer.cs b/src/GraphClimber.ConsoleApp/Examples/Xml/XmlSerializer.cs new file mode 100644 index 0000000..373b9ea --- /dev/null +++ b/src/GraphClimber.ConsoleApp/Examples/Xml/XmlSerializer.cs @@ -0,0 +1,38 @@ +using System.Xml; +using System.Xml.Linq; + +namespace GraphClimber.Examples +{ + public class XmlSerializer + { + private readonly IGraphClimber _writerClimber; + private readonly IGraphClimber _readerClimber; + + public XmlSerializer() + { + IStateMemberProvider memberProvider = new CachingStateMemberProvider(new PropertyStateMemberProvider()); + + _readerClimber = DefaultGraphClimber.Create(memberProvider); + _writerClimber = DefaultGraphClimber.Create(memberProvider); + } + + public void Serialize(T value, XmlWriter writer) + { + XmlWriterProcessor processor = new XmlWriterProcessor(writer); + _writerClimber.Climb(new Box {Value = value}, processor); + } + + public object Deserialize(XElement element) + { + return Deserialize(element); + } + + public T Deserialize(XElement element) + { + XmlReaderProcessor processor = new XmlReaderProcessor(element); + Box box = new Box(); + _readerClimber.Climb(box, processor); + return box.Value; + } + } +} \ No newline at end of file diff --git a/src/GraphClimber/Examples/Xml/XmlWriterProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Xml/XmlWriterProcessor.cs similarity index 84% rename from src/GraphClimber/Examples/Xml/XmlWriterProcessor.cs rename to src/GraphClimber.ConsoleApp/Examples/Xml/XmlWriterProcessor.cs index 561397e..c9b9ba9 100644 --- a/src/GraphClimber/Examples/Xml/XmlWriterProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Xml/XmlWriterProcessor.cs @@ -7,12 +7,10 @@ namespace GraphClimber.Examples public class XmlWriterProcessor : INullProcessor { private readonly XmlWriter _writer; - private StringWriter _stringWriter; - public XmlWriterProcessor() + public XmlWriterProcessor(XmlWriter writer) { - _stringWriter = new StringWriter(); - _writer = new XmlTextWriter(_stringWriter); + _writer = writer; } [ProcessorMethod] @@ -63,9 +61,9 @@ private void EndWritePropertyName() public void ProcessNull(IWriteOnlyValueDescriptor descriptor) { - WritePropertyName(descriptor); - _writer.WriteValue("null"); - EndWritePropertyName(); + //WritePropertyName(descriptor); + //_writer.WriteValue("null"); + //EndWritePropertyName(); } } } \ No newline at end of file diff --git a/src/GraphClimber.ConsoleApp/GraphClimber.ConsoleApp.csproj b/src/GraphClimber.ConsoleApp/GraphClimber.ConsoleApp.csproj new file mode 100644 index 0000000..3135c38 --- /dev/null +++ b/src/GraphClimber.ConsoleApp/GraphClimber.ConsoleApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + + diff --git a/src/GraphClimber.ConsoleApp/Program.cs b/src/GraphClimber.ConsoleApp/Program.cs new file mode 100644 index 0000000..add8bbc --- /dev/null +++ b/src/GraphClimber.ConsoleApp/Program.cs @@ -0,0 +1,250 @@ +using System; +using System.IO; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Xml; +using System.Xml.Linq; +using GraphClimber.ConsoleApp.Examples.Binary; +using GraphClimber.Examples; +using GraphClimber.Examples.Binary; + +namespace GraphClimber +{ + enum Days + { + Sunday, + Monday, + Tuesday, + Wendensday, + Thursday, + Friday, + Saturday + } + + class SimpleType + { + + + public ValueType SomeValueType { get; set; } + + public string String { get; set; } + + public IConvertible Convertible { get; set; } + + + } + + public class Program + { + private static readonly IStateMemberProvider _stateMemberProvider = new CachingStateMemberProvider(new PropertyStateMemberProvider()); + + public static void DoSomething(StrongBox hello) + { + Console.WriteLine(hello); + } + + + static void Main(string[] args) + { + //ExpressionDebugGames.Play(); + IStore store = new TrivialStore(); + + store.Set("A", 5); + store.GetInner("A").Set("A", 10); + + SerializeDeserializeXML(); + + SerializeDeserializeStore(); + + SerializeDeserializeBinary(); + } + + public static object GetSimpleTypeInstance() + { + return new SimpleType() + { + Convertible = "sadasd", + SomeValueType = Days.Monday, + String = "Hello W0rld" + }; + } + + public class PersonHolder + { + public IPerson A { get; set; } + public IPerson B { get; set; } + + public IPerson C { get; set; } + } + + private static void SerializeDeserializeBinary() + { + BinaryFormatter formatter = new BinaryFormatter(); + + var person = new Box{Value = new []{"abc", "abc", "abc"}}; + + //object person = GetPerson(); + + //IPerson structure = new Person2() { Age = 25, Surprise = Days.Monday }; + //person = new PersonHolder() { A = structure, B = structure, C = structure }; + + //structure.IncreaseAge(); + + var stream = new MemoryStream(); + IWriter loggingWriter = new LoggingWriter(new CompressingWriter(new BinaryWriterAdapter(new BinaryWriter(stream))), Console.Out); + + formatter.Serialize(loggingWriter, person); + + stream.Position = 0; + IReader loggingReader = new LoggingReader(new DecompressingReader(new BinaryReaderAdapter(new BinaryReader(stream))), Console.Out); + + object deserialized = formatter.Deserialize(loggingReader); + } + + private static void SerializeDeserializeXML() + { + XmlSerializer serializer = new XmlSerializer(); + + var text = + @" + Shani Elharrar + 24 + + 23 + 4 + +"; + + // Writer code: + Person person = new Person() + { + Age = 24, + Name = "Shani Elharrar", + Surprise = new Person() + { + Age = 23, + Name = null, + Surprise = 4 + } + }; + + StringWriter stringWriter = new StringWriter(); + + serializer.Serialize(person, new XmlTextWriter(stringWriter)); + + string xml = stringWriter.ToString(); + + object result = serializer.Deserialize(XElement.Parse(xml)); + } + + public struct MyClass + { + public string Name { get; set; } + } + + class Person + { + public Person() + { + //Children = new List(); + } + + public string Name { get; set; } + + public int Age { get; set; } + + public object Surprise { get; set; } + + public Person Father { get; set; } + + //public IList Children { get; set; } + } + + internal struct Person2 : IPerson + { + public string Name { get; set; } + + public int Age { get; set; } + + public object Surprise { get; set; } + + public object Father { get; set; } + + public Days Day { get; set; } + public void IncreaseAge() + { + Age++; + } + } + + + public static void SerializeDeserializeStore() + { + IStore store = new TrivialStore(); + StoreSerializer serializer = new StoreSerializer(); + + Person person = GetPerson(); + serializer.Write(person, store); + + object copy = serializer.Read(store); + } + + private static Person GetPerson() + { + var ilan = new Person { Age = 26 + 25, Name = "Ilan Zelingher", Surprise = 1 }; + ilan.Surprise = ilan; + return new Person() + { + Age = 26, + Name = "Elad Zelinger", + Father = ilan, + //Children = { new Person() { Name = "Jason"}, new Person() { Name = "Tomerh" }}, + Surprise = new Person() + { + Age = 21, + Name = "Yosi Attias", + Surprise = new MyClass() + { + Name = "YO!" + } + } + }; + } + + private static Person2 GetPerson2() + { + Person2 ilan = new Person2 { Age = 26 + 25, Name = "Ilan Zelingher" }; + + ilan.Surprise = ilan; + return new Person2() + { + Age = 26, + Name = "Elad Zelinger", + Father = ilan, + Day = Days.Tuesday, + Surprise = new Person2() + { + Age = 21, + Name = "Yosi Attias", + Surprise =ilan + //new object[] + //{ + // ilan, ilan, 342, "Hello", + // new int[,]{{1,1},{2,3},{5,8}}, + // new int[]{1,1,2,3,5,8}, + // Days.Saturday + //} + } + }; + + } + } + + public interface IPerson + { + + void IncreaseAge(); + + } +} \ No newline at end of file diff --git a/src/GraphClimber.Debug/ExpressionCompiler/CSharpExpressionDescriber.cs b/src/GraphClimber.Debug/ExpressionCompiler/CSharpExpressionDescriber.cs deleted file mode 100644 index eb83805..0000000 --- a/src/GraphClimber.Debug/ExpressionCompiler/CSharpExpressionDescriber.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.IO; -using System.Linq.Expressions; -using GraphClimber.ExpressionCompiler; -using Mono.Linq.Expressions; - -namespace GraphClimber.Debug.ExpressionCompiler -{ - public class CSharpExpressionDescriber : IExpressionDescriber - { - public static readonly IExpressionDescriber Empty = new CSharpExpressionDescriber(); - - private CSharpExpressionDescriber() - { - - } - - public string Describe(Expression expression) - { - var stringWriter = new StringWriter(); - var csharpWriter = new CSharpWriter(new TextFormatter(stringWriter)); - - csharpWriter.Write(expression); - - return stringWriter.ToString(); - } - } -} \ No newline at end of file diff --git a/src/GraphClimber.Debug/GraphClimber.Debug.csproj b/src/GraphClimber.Debug/GraphClimber.Debug.csproj deleted file mode 100644 index 6ab3bfe..0000000 --- a/src/GraphClimber.Debug/GraphClimber.Debug.csproj +++ /dev/null @@ -1,66 +0,0 @@ - - - - - Debug - AnyCPU - {B003B6BA-6A13-403E-8C1E-D26AE60C58A0} - Library - Properties - GraphClimber.Debug - GraphClimber.Debug - v4.5 - 512 - - - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - true - - - - ..\packages\Mono.Linq.Expressions.1.2.0.0\lib\Mono.Linq.Expressions.dll - - - - - - - - - - - - - - - - {f7fa4635-c6c6-4d82-b344-b737438e1651} - GraphClimber - - - - - - - - \ No newline at end of file diff --git a/src/GraphClimber.Debug/Properties/AssemblyInfo.cs b/src/GraphClimber.Debug/Properties/AssemblyInfo.cs deleted file mode 100644 index 4538988..0000000 --- a/src/GraphClimber.Debug/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GraphClimber.Debug")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GraphClimber.Debug")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("8e268eed-bd81-4354-be31-618dd525e6fa")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/GraphClimber.Debug/packages.config b/src/GraphClimber.Debug/packages.config deleted file mode 100644 index 7c2d45b..0000000 --- a/src/GraphClimber.Debug/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/GraphClimber.Tests/GraphClimber.Tests.csproj b/src/GraphClimber.Tests/GraphClimber.Tests.csproj index 34530ae..423f3aa 100644 --- a/src/GraphClimber.Tests/GraphClimber.Tests.csproj +++ b/src/GraphClimber.Tests/GraphClimber.Tests.csproj @@ -1,70 +1,19 @@ - - - + + - Debug - AnyCPU - {99B3FD79-4D4B-4536-9F6B-2F53E86F8603} - Library - Properties - GraphClimber.Tests - GraphClimber.Tests - v4.5 - 512 - 00cceabe + netcoreapp3.1 + + false - - true - full - false - ..\..\bin\Debug\Tests\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - ..\..\bin\Release\Tests\ - TRACE - prompt - 4 - - - - False - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll - - - - - - - - - - - - - - - - + - - {f7fa4635-c6c6-4d82-b344-b737438e1651} - GraphClimber - + + + + - + - - - \ No newline at end of file + + diff --git a/src/GraphClimber.Tests/Properties/AssemblyInfo.cs b/src/GraphClimber.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index c5a809b..0000000 --- a/src/GraphClimber.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GraphClimber.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GraphClimber.Tests")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("99b3fd79-4d4b-4536-9f6b-2f53e86f8603")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/GraphClimber.Tests/packages.config b/src/GraphClimber.Tests/packages.config deleted file mode 100644 index c714ef3..0000000 --- a/src/GraphClimber.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/GraphClimber.sln b/src/GraphClimber.sln index ad77fe3..59ac61a 100644 --- a/src/GraphClimber.sln +++ b/src/GraphClimber.sln @@ -1,13 +1,13 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.31101.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30011.22 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphClimber", "GraphClimber\GraphClimber.csproj", "{F7FA4635-C6C6-4D82-B344-B737438E1651}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GraphClimber", "GraphClimber\GraphClimber.csproj", "{BD78BB49-71BF-4CFA-8DAE-E178623C225D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphClimber.Tests", "GraphClimber.Tests\GraphClimber.Tests.csproj", "{99B3FD79-4D4B-4536-9F6B-2F53E86F8603}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphClimber.Tests", "GraphClimber.Tests\GraphClimber.Tests.csproj", "{1CE9D582-AD82-4D61-B6D1-85AFF6288841}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphClimber.Debug", "GraphClimber.Debug\GraphClimber.Debug.csproj", "{B003B6BA-6A13-403E-8C1E-D26AE60C58A0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphClimber.ConsoleApp", "GraphClimber.ConsoleApp\GraphClimber.ConsoleApp.csproj", "{5686D351-394B-4D2B-A06D-5A3FF1C5108B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,20 +15,23 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F7FA4635-C6C6-4D82-B344-B737438E1651}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7FA4635-C6C6-4D82-B344-B737438E1651}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7FA4635-C6C6-4D82-B344-B737438E1651}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7FA4635-C6C6-4D82-B344-B737438E1651}.Release|Any CPU.Build.0 = Release|Any CPU - {99B3FD79-4D4B-4536-9F6B-2F53E86F8603}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {99B3FD79-4D4B-4536-9F6B-2F53E86F8603}.Debug|Any CPU.Build.0 = Debug|Any CPU - {99B3FD79-4D4B-4536-9F6B-2F53E86F8603}.Release|Any CPU.ActiveCfg = Release|Any CPU - {99B3FD79-4D4B-4536-9F6B-2F53E86F8603}.Release|Any CPU.Build.0 = Release|Any CPU - {B003B6BA-6A13-403E-8C1E-D26AE60C58A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B003B6BA-6A13-403E-8C1E-D26AE60C58A0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B003B6BA-6A13-403E-8C1E-D26AE60C58A0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B003B6BA-6A13-403E-8C1E-D26AE60C58A0}.Release|Any CPU.Build.0 = Release|Any CPU + {BD78BB49-71BF-4CFA-8DAE-E178623C225D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD78BB49-71BF-4CFA-8DAE-E178623C225D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD78BB49-71BF-4CFA-8DAE-E178623C225D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD78BB49-71BF-4CFA-8DAE-E178623C225D}.Release|Any CPU.Build.0 = Release|Any CPU + {1CE9D582-AD82-4D61-B6D1-85AFF6288841}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1CE9D582-AD82-4D61-B6D1-85AFF6288841}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1CE9D582-AD82-4D61-B6D1-85AFF6288841}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1CE9D582-AD82-4D61-B6D1-85AFF6288841}.Release|Any CPU.Build.0 = Release|Any CPU + {5686D351-394B-4D2B-A06D-5A3FF1C5108B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5686D351-394B-4D2B-A06D-5A3FF1C5108B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5686D351-394B-4D2B-A06D-5A3FF1C5108B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5686D351-394B-4D2B-A06D-5A3FF1C5108B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8D0DC358-E9C0-426C-BD72-7EFD69F49DB5} + EndGlobalSection EndGlobal diff --git a/src/GraphClimber.sln.DotSettings b/src/GraphClimber.sln.DotSettings index 0a046fc..993cd6d 100644 --- a/src/GraphClimber.sln.DotSettings +++ b/src/GraphClimber.sln.DotSettings @@ -1,3 +1,2 @@  - <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> - <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> \ No newline at end of file + <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> \ No newline at end of file diff --git a/src/GraphClimber/.vs/GraphClimber/DesignTimeBuild/.dtbcache.v2 b/src/GraphClimber/.vs/GraphClimber/DesignTimeBuild/.dtbcache.v2 new file mode 100644 index 0000000000000000000000000000000000000000..6d1d6c82227fbd27be7df397c9f1d7cc69f09887 GIT binary patch literal 3631 zcmcgv|8o<^6<-GfGR9zI8X#$i3N#Hd);E6_O?$E=J1SrtOC~A3HeKDVF{U4Nspv0i3$y|?7~tE(H-Ti#$BCHz*_m&wgN zrbKWE#e+T8W0Hj)Qw^qgKkV=UBZayM0%%RyeDFm)pqh*DME;v8f4lMEMEd+rv(wfz z^r`d<4|!KoIV5K*g;HUOOm<|<$emQxF7=+%K5MXug+9#U$L#tb)w3n(fV~j%`5SHI zdP++rWGH89K|m(8RdZ{sX5`g3OqtE!PI+odu|YQ&p2#$|_XJBaqUJ`9!*-5bJ5>yY zC&C`@lUy+l745M_GF3zrc+Z)?Nb;b+pfaqM*GlDkSSof&?<%FzI=N8n#X%5JeV}k3 z3Z?ykcNfTfkx40}WRZ}%8cCd)Cg+QZuw_yx`mD!8R_*N7>dpI&=H~wPeS0jO+D@ak z*T~*izA2Hpku;n_AiU({$@|4f+Gvr?N9fY9UuEIqew$n_9`ODF3$+x{@Q^M*sc&O_ z0hHvXYAvGOfRRhZ9uF7|5NOqvas~E_Nb>>z7EUM>MXal$`^-%;#SNKOY0Mx}+-*st zgL=RRT_y`YPV~o#qKpHkn6BQcS6w7ZA7PQ-f&!KQ^yT{MUH1|9q)?)#^G~>nX^?O0 z*yqBnl*$_}&SnsYTo2t2!*?Aa0_7q~HTUwhkOo7=Rr=Q5gQ9#J20>)V2Qkvd!{;_e zeM?h?)RbG;v!=2Sqi`rmoX;djKvi-&i)6YO>)txH8pS$skY;iKp$d8z$ZXL%_K-=1 zT&u1jKc?ydRjOR@6nTnm?n91pn*sInPg#JfaKNNniy~Vz+=n=-0NWWvZXuI$_nwU8 zeST6Yp_mB>`245 z6mdlU@l&2|2rtI5BM`Q^{vz%k3rkl?@A!*s(7LDdunp~ZqQ1++Q)bp|*6bwL&cGk! zV)iweObCNt)KTQwiQ)fF4uuS{wg022JZdKm-mS+dn4xwz;r^p~ga$hph_H|n)BG%q zDu*I_Kfh}7@&8axa!2Y$19Ekng-oKh?qU!?m_|&3I@1chAoiKHKr1q{ zEBPUK#*fXHS?cU#$@?6g?#PtsmU_U3qe4h7W9Fp6=)o!>7dlB}OYU=9m_d@e^VT_V zFv;1@8(RNQHD6-4wu6!BJ!a>|LuNUqGUtE>8l%aL2)U!}T}vE*ww4y6E*W9kJZJw0z;y{|0$ac~@CDEU{scS#9s-Ym z9pEvr3w#Oe0Xd)zbO6h5dG~=Qz*m6fy$rl9|7*NEt&Umn{uy`*`~|Szy1-w7zX9I> ze+MYg1w6n97|;Xyzq6N~dn literal 0 HcmV?d00001 diff --git a/src/GraphClimber/App.config b/src/GraphClimber/App.config deleted file mode 100644 index fe04a3a..0000000 --- a/src/GraphClimber/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/GraphClimber/CachingStateMemberProvider.cs b/src/GraphClimber/CachingStateMemberProvider.cs new file mode 100644 index 0000000..7a70bdf --- /dev/null +++ b/src/GraphClimber/CachingStateMemberProvider.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using GraphClimber.ValueDescriptor; + +namespace GraphClimber +{ + public class CachingStateMemberProvider : IStateMemberProvider + { + private readonly IStateMemberProvider _underlying; + + private readonly IDictionary> _cache = new Dictionary>(); + private readonly object _syncRoot = new object(); + + public CachingStateMemberProvider(IStateMemberProvider underlying) + { + _underlying = underlying; + } + + public IEnumerable Provide(Type type) + { + IEnumerable retVal; + if (_cache.TryGetValue(type, out retVal)) + { + return retVal; + } + + lock (_syncRoot) + { + if (!_cache.TryGetValue(type, out retVal)) + { + // ToList() is here to cache yield return methods. + _cache[type] = retVal = _underlying.Provide(type).ToList(); + } + } + + return retVal; + } + + public IStateMember ProvideArrayMember(Type arrayType, int[] indices) + { + return _underlying.ProvideArrayMember(arrayType, indices); + } + } +} \ No newline at end of file diff --git a/src/GraphClimber/DescriptorExtensionMethods.cs b/src/GraphClimber/DescriptorExtensionMethods.cs index d442fe0..f9f10e7 100644 --- a/src/GraphClimber/DescriptorExtensionMethods.cs +++ b/src/GraphClimber/DescriptorExtensionMethods.cs @@ -4,227 +4,227 @@ namespace GraphClimber { - public static class DescriptorExtensionMethods - { - - public static void RouteRuntimeType(this IValueDescriptor descriptor, bool skipSpecialMethod = false) - { - RouteRuntimeType(descriptor, typeof (TRuntime), skipSpecialMethod); - } - - public static void RouteRuntimeType(this IValueDescriptor descriptor, Type runtimeType, - bool skipSpecialMethod = false) - { - descriptor.Route(descriptor.StateMember, runtimeType, descriptor.Owner, skipSpecialMethod); - } - - public static void RouteMemberType(this IValueDescriptor descriptor, bool skipSpecialMethod = false) - { - var memberType = typeof(TMember); - RouteMemberType(descriptor, memberType, skipSpecialMethod); - } - - public static void RouteMemberType(IValueDescriptor descriptor, Type memberType, bool skipSpecialMethod = false) - { - descriptor.Route(descriptor.StateMember.WithMemberType(memberType), memberType, descriptor.Owner, skipSpecialMethod); - } - - public static void RouteMemberType(this IValueDescriptor descriptor, string name, bool skipSpecialMethod = false) - { - var memberType = typeof(TMember); - RouteMemberType(descriptor, name, memberType, skipSpecialMethod); - } - - public static void RouteMemberType(IValueDescriptor descriptor, string name, Type memberType, - bool skipSpecialMethod = false) - { - descriptor.Route(descriptor.StateMember.WithMemberType(memberType).WithName(name), memberType, descriptor.Owner, - skipSpecialMethod); - } - } - - public static class StateMemberExtensions - { - - public static IStateMember WithName(this IStateMember stateMember, string name) - { - return new NamedStateMember(stateMember, name); - } - - public static IStateMember WithMemberType(this IStateMember stateMember, Type memberType) - { - return new MemberTypeStateMember(stateMember, memberType); - } - - private class NamedStateMember : IStateMember - { - private readonly IStateMember _underlying; - private readonly string _name; - - public NamedStateMember(IStateMember underlying, string name) - { - _underlying = underlying; - _name = name; - } - - public string Name - { - get { return _name; } - } - - public Type OwnerType - { - get { return _underlying.OwnerType; } - } - - public Type MemberType - { - get { return _underlying.MemberType; } - } - - public bool CanRead - { - get { return _underlying.CanRead; } - } - - public bool CanWrite - { - get { return _underlying.CanWrite; } - } - - public Expression GetGetExpression(Expression obj) - { - return _underlying.GetGetExpression(obj); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - return _underlying.GetSetExpression(obj, value); - } - - public bool IsArrayElement - { - get { return _underlying.IsArrayElement; } - } - - public int[] ElementIndex - { - get { return _underlying.ElementIndex; } - } - - protected bool Equals(NamedStateMember other) - { - return Equals(_underlying, other._underlying) && string.Equals(_name, other._name); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((NamedStateMember) obj); - } - - public override int GetHashCode() - { - unchecked - { - return ((_underlying != null ? _underlying.GetHashCode() : 0)*397) ^ (_name != null ? _name.GetHashCode() : 0); - } - } - } - - private class MemberTypeStateMember : IStateMember, IReflectionStateMember - { - private readonly IStateMember _underlying; - private readonly Type _memberType; - - public MemberTypeStateMember(IStateMember underlying, Type memberType) - { - _underlying = underlying; - _memberType = memberType; - } - - public string Name - { - get { return _underlying.Name; } - } - - public Type OwnerType - { - get { return _underlying.OwnerType; } - } - - public Type MemberType - { - get { return _memberType; } - } - - public bool CanRead - { - get { return _underlying.CanRead; } - } - - public bool CanWrite - { - get { return _underlying.CanWrite; } - } - - public Expression GetGetExpression(Expression obj) - { - return _underlying.GetGetExpression(obj); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - return _underlying.GetSetExpression(obj, value); - } - - public bool IsArrayElement - { - get { return _underlying.IsArrayElement; } - } - - public int[] ElementIndex - { - get { return _underlying.ElementIndex; } - } - - protected bool Equals(MemberTypeStateMember other) - { - return Equals(_underlying, other._underlying) && Equals(_memberType, other._memberType); - } - - public override bool Equals(object obj) - { - if (ReferenceEquals(null, obj)) return false; - if (ReferenceEquals(this, obj)) return true; - if (obj.GetType() != this.GetType()) return false; - return Equals((MemberTypeStateMember) obj); - } - - public override int GetHashCode() - { - unchecked - { - return ((_underlying != null ? _underlying.GetHashCode() : 0)*397) ^ (_memberType != null ? _memberType.GetHashCode() : 0); - } - } - - public MemberInfo UnderlyingMemberInfo - { - get { return ((IReflectionStateMember)_underlying).UnderlyingMemberInfo; } - } - - public object GetValue(object owner) - { - throw new NotImplementedException(); - } - - public void SetValue(object owner, object value) - { - throw new NotImplementedException(); - } - } - } + //public static class DescriptorExtensionMethods + //{ + + // public static void RouteRuntimeType(this IValueDescriptor descriptor, bool skipSpecialMethod = false) + // { + // RouteRuntimeType(descriptor, typeof (TRuntime), skipSpecialMethod); + // } + + // public static void RouteRuntimeType(this IValueDescriptor descriptor, Type runtimeType, + // bool skipSpecialMethod = false) + // { + // descriptor.Route(descriptor.StateMember, runtimeType, descriptor.Owner, skipSpecialMethod); + // } + + // public static void RouteMemberType(this IValueDescriptor descriptor, bool skipSpecialMethod = false) + // { + // var memberType = typeof(TMember); + // RouteMemberType(descriptor, memberType, skipSpecialMethod); + // } + + // public static void RouteMemberType(IValueDescriptor descriptor, Type memberType, bool skipSpecialMethod = false) + // { + // descriptor.Route(descriptor.StateMember.WithMemberType(memberType), memberType, descriptor.Owner, skipSpecialMethod); + // } + + // public static void RouteMemberType(this IValueDescriptor descriptor, string name, bool skipSpecialMethod = false) + // { + // var memberType = typeof(TMember); + // RouteMemberType(descriptor, name, memberType, skipSpecialMethod); + // } + + // public static void RouteMemberType(IValueDescriptor descriptor, string name, Type memberType, + // bool skipSpecialMethod = false) + // { + // descriptor.Route(descriptor.StateMember.WithMemberType(memberType).WithName(name), memberType, descriptor.Owner, + // skipSpecialMethod); + // } + //} + + //public static class StateMemberExtensions + //{ + + // public static IStateMember WithName(this IStateMember stateMember, string name) + // { + // return new NamedStateMember(stateMember, name); + // } + + // public static IStateMember WithMemberType(this IStateMember stateMember, Type memberType) + // { + // return new MemberTypeStateMember(stateMember, memberType); + // } + + // private class NamedStateMember : IStateMember + // { + // private readonly IStateMember _underlying; + // private readonly string _name; + + // public NamedStateMember(IStateMember underlying, string name) + // { + // _underlying = underlying; + // _name = name; + // } + + // public string Name + // { + // get { return _name; } + // } + + // public Type OwnerType + // { + // get { return _underlying.OwnerType; } + // } + + // public Type MemberType + // { + // get { return _underlying.MemberType; } + // } + + // public bool CanRead + // { + // get { return _underlying.CanRead; } + // } + + // public bool CanWrite + // { + // get { return _underlying.CanWrite; } + // } + + // public Expression GetGetExpression(Expression obj) + // { + // return _underlying.GetGetExpression(obj); + // } + + // public Expression GetSetExpression(Expression obj, Expression value) + // { + // return _underlying.GetSetExpression(obj, value); + // } + + // public bool IsArrayElement + // { + // get { return _underlying.IsArrayElement; } + // } + + // public int[] ElementIndex + // { + // get { return _underlying.ElementIndex; } + // } + + // protected bool Equals(NamedStateMember other) + // { + // return Equals(_underlying, other._underlying) && string.Equals(_name, other._name); + // } + + // public override bool Equals(object obj) + // { + // if (ReferenceEquals(null, obj)) return false; + // if (ReferenceEquals(this, obj)) return true; + // if (obj.GetType() != this.GetType()) return false; + // return Equals((NamedStateMember) obj); + // } + + // public override int GetHashCode() + // { + // unchecked + // { + // return ((_underlying != null ? _underlying.GetHashCode() : 0)*397) ^ (_name != null ? _name.GetHashCode() : 0); + // } + // } + // } + + // private class MemberTypeStateMember : IStateMember, IReflectionStateMember + // { + // private readonly IStateMember _underlying; + // private readonly Type _memberType; + + // public MemberTypeStateMember(IStateMember underlying, Type memberType) + // { + // _underlying = underlying; + // _memberType = memberType; + // } + + // public string Name + // { + // get { return _underlying.Name; } + // } + + // public Type OwnerType + // { + // get { return _underlying.OwnerType; } + // } + + // public Type MemberType + // { + // get { return _memberType; } + // } + + // public bool CanRead + // { + // get { return _underlying.CanRead; } + // } + + // public bool CanWrite + // { + // get { return _underlying.CanWrite; } + // } + + // public Expression GetGetExpression(Expression obj) + // { + // return _underlying.GetGetExpression(obj); + // } + + // public Expression GetSetExpression(Expression obj, Expression value) + // { + // return _underlying.GetSetExpression(obj, value); + // } + + // public bool IsArrayElement + // { + // get { return _underlying.IsArrayElement; } + // } + + // public int[] ElementIndex + // { + // get { return _underlying.ElementIndex; } + // } + + // protected bool Equals(MemberTypeStateMember other) + // { + // return Equals(_underlying, other._underlying) && Equals(_memberType, other._memberType); + // } + + // public override bool Equals(object obj) + // { + // if (ReferenceEquals(null, obj)) return false; + // if (ReferenceEquals(this, obj)) return true; + // if (obj.GetType() != this.GetType()) return false; + // return Equals((MemberTypeStateMember) obj); + // } + + // public override int GetHashCode() + // { + // unchecked + // { + // return ((_underlying != null ? _underlying.GetHashCode() : 0)*397) ^ (_memberType != null ? _memberType.GetHashCode() : 0); + // } + // } + + // public MemberInfo UnderlyingMemberInfo + // { + // get { return ((IReflectionStateMember)_underlying).UnderlyingMemberInfo; } + // } + + // public object GetValue(object owner) + // { + // throw new NotImplementedException(); + // } + + // public void SetValue(object owner, object value) + // { + // throw new NotImplementedException(); + // } + // } + //} } diff --git a/src/GraphClimber/ExpressionCompiler/AccessPrivateFieldVisitor.cs b/src/GraphClimber/ExpressionCompiler/AccessPrivateFieldVisitor.cs deleted file mode 100644 index 5667553..0000000 --- a/src/GraphClimber/ExpressionCompiler/AccessPrivateFieldVisitor.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using GraphClimber.ExpressionCompiler.Extensions; - -namespace GraphClimber.ExpressionCompiler -{ - /// - /// An - /// that mutates expressions that calls non public members (Fields, Properties or Methods) - /// to use "reflection" accessors. - /// - /// This is usually used on expressions that compiled to dynamic assemblies, Because - /// in this type of compilation, They cannot access non public members. - /// - public class AccessPrivateFieldVisitor : ExpressionVisitor - { - private const BindingFlags BindingFlags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public; - - public static readonly ExpressionVisitor Empty = new AccessPrivateFieldVisitor(); - - /// - /// Gets the field value from the given instance - /// - /// - /// - /// The instance to get the field value from, Or null for static fields - /// - [DebuggerNonUserCode] - public static object GetFieldValue(string assemblyQualifiedName, string fieldName, object instance) - { - return GetType(assemblyQualifiedName).GetField(fieldName, BindingFlags).GetValue(instance); - } - - /// - /// Gets the property value from the given instance - /// - /// - /// - /// The instance to get the property value from, Or null for static properties - /// - [DebuggerNonUserCode] - public static object GetPropertyValue(string assemblyQualifiedName, string propertyName, object instance) - { - return GetType(assemblyQualifiedName).GetProperty(propertyName, BindingFlags).GetValue(instance); - } - - /// - /// Calls the method on the given instance and returns the value from the method - /// - /// - /// - /// - /// The instance to call the method on, Or null for static methods - /// - /// - [DebuggerNonUserCode] - public static object CallMethod(string assemblyQualifiedName, string methodName, string[] genericArgumentTypes, - object instance, - params object[] parameters) - { - var methodInfo = GetType(assemblyQualifiedName).GetMethod(methodName, BindingFlags); - - if (methodInfo.ContainsGenericParameters) - { - methodInfo = methodInfo.MakeGenericMethod(genericArgumentTypes.Select(GetType).ToArray()); - } - - return methodInfo.Invoke(instance, parameters); - } - - /// - /// Gets the given type or throws exception in case - /// it's not found. - /// - /// - /// - private static Type GetType(string assemblyQualifiedName) - { - var returnValue = Type.GetType(assemblyQualifiedName); - - if (returnValue == null) - { - throw new NullReferenceException( - string.Format("Could not load type with assembly qualified name : '{0}', Exception thrown by '{1}'.", - assemblyQualifiedName, typeof (AccessPrivateFieldVisitor))); - } - - return returnValue; - } - - protected override Expression VisitMethodCall(MethodCallExpression node) - { - if (!node.Method.IsPublic) - { - // In case of static methods, instance should be null. - var reflectionInstance = node.Object ?? ExpressionExtensions.Null; - - // In case of generic method, - // we create an array of the assembly qualified names of the generic arguments. - var genericArgumentTypes = node.Method.IsGenericMethod - ? (Expression)Expression.NewArrayInit(typeof(string), node.Method.GetGenericArguments().Select(t => t.AssemblyQualifiedName.Constant())) - : ExpressionExtensions.Null; - - return - Expression.Call(null, typeof(AccessPrivateFieldVisitor).GetMethod("CallMethod"), - node.Method.DeclaringType.AssemblyQualifiedName.Constant(), - node.Method.Name.Constant(), - genericArgumentTypes, - reflectionInstance, - Expression.NewArrayInit(typeof(object), node.Arguments)).Convert(node.Type); - } - - return base.VisitMethodCall(node); - } - - protected override Expression VisitMember(MemberExpression node) - { - var fieldInfo = node.Member as FieldInfo; - if (fieldInfo != null) - { - return VisitFieldMemberExpression(node, fieldInfo); - } - - var propertyInfo = node.Member as PropertyInfo; - if (propertyInfo != null) - { - return VisitPropertyMemberExpression(node, propertyInfo); - } - - - return base.VisitMember(node); - } - - private static Expression VisitFieldMemberExpression(MemberExpression node, FieldInfo fieldInfo) - { - FieldAttributes fieldAttributes = fieldInfo.Attributes; - - bool isPrivateField = fieldAttributes.HasFlag(FieldAttributes.Private) || - fieldAttributes.HasFlag(FieldAttributes.PrivateScope); - - if (isPrivateField) - { - var argument = node.Expression ?? ExpressionExtensions.Null; - - return Expression.Call(null, - typeof (AccessPrivateFieldVisitor).GetMethod("GetFieldValue"), - fieldInfo.DeclaringType.AssemblyQualifiedName.Constant(), - fieldInfo.Name.Constant(), - argument).Convert(node.Type); - } - - return node; - } - - private static Expression VisitPropertyMemberExpression(MemberExpression node, PropertyInfo propertyInfo) - { - bool isPrivate = - new[] {propertyInfo.GetGetMethod(true), propertyInfo.GetSetMethod(true)}.Where(m => m != null) - .Select(m => m.Attributes) - .Any(m => m.HasFlag(MethodAttributes.Private)); - - if (isPrivate) - { - var argument = node.Expression.Convert() ?? ExpressionExtensions.Null; - - return Expression.Call(null, - typeof (AccessPrivateFieldVisitor).GetMethod("GetPropertyValue"), - propertyInfo.DeclaringType.AssemblyQualifiedName.Constant(), - propertyInfo.Name.Constant(), - argument).Convert(node.Type); - } - - return node; - } - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/DebugExpressionCompiler.cs b/src/GraphClimber/ExpressionCompiler/DebugExpressionCompiler.cs deleted file mode 100644 index 0a911a8..0000000 --- a/src/GraphClimber/ExpressionCompiler/DebugExpressionCompiler.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Reflection.Emit; -using System.Runtime.CompilerServices; - -namespace GraphClimber.ExpressionCompiler -{ - /// - /// An - /// That compiles methods into dynamic assemblies. - /// - /// Also it, Writes the expression description to temporary file and allows - /// debugging with normal IDE (e.g Visual Studio). - /// - public class DebugExpressionCompiler : IExpressionCompiler - { - private readonly IExpressionDescriber _expressionDescriber; - - public DebugExpressionCompiler(IExpressionDescriber expressionDescriber) - { - _expressionDescriber = expressionDescriber; - } - - public TDelegate Compile(Expression expression) - { - var dynamicType = GetDynamicTypeBuilder(); - var dynamicMethod = dynamicType.DefineMethod(expression.Name, MethodAttributes.Public | MethodAttributes.Static); - - var tempFileName = Path.GetTempFileName(); - - File.AppendAllText(tempFileName, _expressionDescriber.Describe(expression)); - - var symbolDocument = Expression.SymbolDocument(tempFileName); - - var finalExpression = MutateLambdaExpression(expression, symbolDocument); - - CompileToMethod(finalExpression, dynamicMethod); - - var newType = dynamicType.CreateType(); - - return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), newType.GetMethod(dynamicMethod.Name)); - } - - private static void CompileToMethod(Expression expression, - MethodBuilder dynamicMethod) - { - var gen = DebugInfoGenerator.CreatePdbGenerator(); - expression.CompileToMethod(dynamicMethod, gen); - } - - private Expression MutateLambdaExpression(Expression expression, - SymbolDocumentInfo symbolDocument) - { - Expression returnValue = GetVisitors(expression, symbolDocument) - .Aggregate(expression, (current, visitor) => visitor.Visit(current)); - - return (Expression)returnValue; - } - - private static TypeBuilder GetDynamicTypeBuilder() - { - var dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("GraphClimber.RuntimeGenerated"), - AssemblyBuilderAccess.RunAndSave); - var dynamicModule = dynamicAssembly.DefineDynamicModule("DynamicModule", true); - var dynamicType = dynamicModule.DefineType("GeneratedType", TypeAttributes.Public); - return dynamicType; - } - - private ExpressionVisitor[] GetVisitors(Expression expression, SymbolDocumentInfo symbolDocument) - { - return new[] { new DebugExpressionVistor(symbolDocument, expression, _expressionDescriber), NonTrivialConstantVisitor.Empty, AccessPrivateFieldVisitor.Empty }; - } - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/DebugExpressionVistor.cs b/src/GraphClimber/ExpressionCompiler/DebugExpressionVistor.cs deleted file mode 100644 index b1ec51e..0000000 --- a/src/GraphClimber/ExpressionCompiler/DebugExpressionVistor.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; - -namespace GraphClimber.ExpressionCompiler -{ - public class DebugExpressionVistor : ExpressionVisitor - { - private static readonly ICollection _untouchedExpressionTypes = new[] { typeof(ParameterExpression), typeof(ConstantExpression) }; - private static readonly ICollection _unsymboledExpressionTypes = new[] { typeof(BlockExpression), typeof(LambdaExpression), typeof(LoopExpression) }; - - private static readonly string[] _newLineSeperator = { Environment.NewLine }; - - private readonly SymbolDocumentInfo _symbolDocumentInfo; - private readonly IExpressionDescriber _expressionDescriber; - private readonly string _initialDebugView; - private int _currentIndex; - - public DebugExpressionVistor(SymbolDocumentInfo symbolDocumentInfo, Expression initialExpression, IExpressionDescriber expressionDescriber) - { - _symbolDocumentInfo = symbolDocumentInfo; - _expressionDescriber = expressionDescriber; - - _initialDebugView = _expressionDescriber.Describe(initialExpression); - } - - private bool ContainsType(IEnumerable types, object instance) - { - var type = instance.GetType(); - - return types.Any(currentType => currentType.IsAssignableFrom(type)); - } - - public override Expression Visit(Expression node) - { - if (node == null) - { - return null; - } - - // Untouched remains as they are - if (ContainsType(_untouchedExpressionTypes, node)) - { - return node; - } - - // Unsymboled is not symboled, the node children are. - if (ContainsType(_unsymboledExpressionTypes, node)) - { - return base.Visit(node); - } - - Range range = GetCurrentExpressionRange(node); - - // Still not sure why I have so many plus one. - Expression debugInfoExpression = Expression.DebugInfo(_symbolDocumentInfo, - range.Start.Line + 1, - range.Start.Column + 1, - range.End.Line + 1, - range.End.Column + 1); - - Expression innerExpression = base.Visit(node); - - return Expression.Block(debugInfoExpression, innerExpression); - } - - private Range GetCurrentExpressionRange(Expression node) - { - string debugView = _expressionDescriber.Describe(node); - string[] debugViewLines = debugView.Split(_newLineSeperator, StringSplitOptions.RemoveEmptyEntries); - string firstDebugViewLine = debugViewLines.First(); - - var newIndex = _initialDebugView.IndexOf(firstDebugViewLine, _currentIndex, StringComparison.Ordinal); - _currentIndex = newIndex; - - Position start = _initialDebugView.GetPosition(_currentIndex); - int spacing = _initialDebugView.Split(_newLineSeperator, StringSplitOptions.None)[start.Line].IndexOfNot(' '); - - Position end = _initialDebugView.GetPosition(_currentIndex + debugView.Length + (debugViewLines.Length - 1) * spacing); - - return new Range(start, end); - } - - private struct Range - { - private readonly T _start; - private readonly T _end; - - public Range(T start, T end) - { - _start = start; - _end = end; - } - - public T Start - { - get { return _start; } - } - - public T End - { - get { return _end; } - } - } - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/DebugViewExpressionDescriber.cs b/src/GraphClimber/ExpressionCompiler/DebugViewExpressionDescriber.cs deleted file mode 100644 index a0889c8..0000000 --- a/src/GraphClimber/ExpressionCompiler/DebugViewExpressionDescriber.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Linq.Expressions; -using System.Reflection; - -namespace GraphClimber.ExpressionCompiler -{ - /// - /// Implementation of - /// using the property "DebugView" of the expressions. - /// - /// This may not work if microsoft/mono changes the implementation - /// of "DebugView". - /// - public class DebugViewExpressionDescriber : IExpressionDescriber - { - public static readonly IExpressionDescriber Empty = new DebugViewExpressionDescriber(); - - private static readonly PropertyInfo _debugView = typeof(Expression).GetProperty("DebugView", BindingFlags.NonPublic | BindingFlags.Instance); - - /// - /// Private C'tor, Please use property to get the instance of . - /// - private DebugViewExpressionDescriber() - { - - } - - private static string GetDebugView(Expression expression) - { - return (string) _debugView.GetValue(expression); - } - - public string Describe(Expression expression) - { - return GetDebugView(expression); - } - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/IExpressionCompiler.cs b/src/GraphClimber/ExpressionCompiler/IExpressionCompiler.cs deleted file mode 100644 index e8fcdc6..0000000 --- a/src/GraphClimber/ExpressionCompiler/IExpressionCompiler.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Linq.Expressions; - -namespace GraphClimber.ExpressionCompiler -{ - public interface IExpressionCompiler - { - TDelegate Compile(Expression expression); - } -} diff --git a/src/GraphClimber/ExpressionCompiler/IExpressionDescriber.cs b/src/GraphClimber/ExpressionCompiler/IExpressionDescriber.cs deleted file mode 100644 index a4fae01..0000000 --- a/src/GraphClimber/ExpressionCompiler/IExpressionDescriber.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Linq.Expressions; - -namespace GraphClimber.ExpressionCompiler -{ - /// - /// Represents an object that can transform expressions to their describing strings. - /// - /// E.g, Transform expression to C# code. - /// - public interface IExpressionDescriber - { - - string Describe(Expression expression); - - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/NonTrivialConstantVisitor.cs b/src/GraphClimber/ExpressionCompiler/NonTrivialConstantVisitor.cs deleted file mode 100644 index d70d6fd..0000000 --- a/src/GraphClimber/ExpressionCompiler/NonTrivialConstantVisitor.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Reflection; -using GraphClimber.ExpressionCompiler.Extensions; - -namespace GraphClimber.ExpressionCompiler -{ - public class NonTrivialConstantVisitor : ExpressionVisitor - { - private static readonly MethodInfo _getMethodInfo = typeof (NonTrivialConstantVisitor).GetMethod("Get", BindingFlags.Static | BindingFlags.Public); - - private static readonly IList _objects = new List(); - private static readonly object _syncRoot = new object(); - - public static readonly ExpressionVisitor Empty = new NonTrivialConstantVisitor(); - - private NonTrivialConstantVisitor() - { - - } - - public static object Get(int number) - { - return _objects[number]; - } - - public static int Add(object value) - { - lock (_syncRoot) - { - int objectNumber = _objects.Count; - - _objects.Add(value); - - return objectNumber; - } - } - - protected override Expression VisitConstant(ConstantExpression node) - { - if (node.Type.IsPrimitive || node.Type == typeof(string)) - { - return base.VisitConstant(node); - } - - // RuntimeType is internal, using Type instead. - if (node.Type.FullName == "System.RuntimeType") - { - return Expression.Constant(node.Value, typeof (Type)); - } - - int objectNumber = Add(node.Value); - - return Expression.Call(_getMethodInfo, objectNumber.Constant()).Convert(node.Type); - } - } -} diff --git a/src/GraphClimber/ExpressionCompiler/StringExtensions.cs b/src/GraphClimber/ExpressionCompiler/StringExtensions.cs deleted file mode 100644 index 7e95a4d..0000000 --- a/src/GraphClimber/ExpressionCompiler/StringExtensions.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; - -namespace GraphClimber.ExpressionCompiler -{ - public static class StringExtensions - { - - /// - /// Gets the cursor position (Column, Line) of the given index in the given string. - /// - /// - /// - /// - public static Position GetPosition(this string str, int index) - { - var column = index; - var newLineIndex = str.IndexOf(Environment.NewLine, StringComparison.Ordinal); - var newLines = 0; - - while (newLineIndex != -1 && newLineIndex < index) - { - newLines++; - column = index - newLineIndex - Environment.NewLine.Length; - newLineIndex = str.IndexOf(Environment.NewLine, newLineIndex + 1, StringComparison.Ordinal); - } - - return new Position(newLines, column); - } - - public static int IndexOfNot(this string str, char chr) - { - for (int i = 0; i < str.Length; i++) - { - if (str[i] != chr) - { - return i; - } - } - - return -1; - } - - public static string FirstLowerCase(this string str) - { - return str.Substring(0, 1).ToLowerInvariant() + str.Substring(1); - } - - } - - /// - /// Represents a position inside a string - /// - public struct Position - { - private readonly int _line; - private readonly int _column; - - public Position(int line, int column) - { - _line = line; - _column = column; - } - - /// - /// Gets the line of the position - /// - public int Line - { - get - { - return _line; - } - } - - /// - /// Gets the column of the position - /// - public int Column - { - get - { - return _column; - } - } - - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/TrivialExpressionCompiler.cs b/src/GraphClimber/ExpressionCompiler/TrivialExpressionCompiler.cs deleted file mode 100644 index f17733b..0000000 --- a/src/GraphClimber/ExpressionCompiler/TrivialExpressionCompiler.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; - -namespace GraphClimber.ExpressionCompiler -{ - public class TrivialExpressionCompiler : IExpressionCompiler - { - public TDelegate Compile(Expression expression) - { - return expression.Compile(); - } - } - - public class FallbackExpressionCompiler : IExpressionCompiler - { - private readonly IExpressionCompiler[] _compilers; - - public FallbackExpressionCompiler(params IExpressionCompiler[] compilers) - { - _compilers = compilers; - } - - public TDelegate Compile(Expression expression) - { - IList exceptions = null; - - foreach (var compiler in _compilers) - { - try - { - return compiler.Compile(expression); - } - catch (Exception e) - { - exceptions = exceptions ?? new List(); - exceptions.Add(e); - } - } - - throw new AggregateException("Could not compile expression with any of the compilers given. Exceptions are collected.", exceptions); - } - } -} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionCompiler/Extensions/ExpressionExtensions.cs b/src/GraphClimber/ExpressionExtensions.cs similarity index 92% rename from src/GraphClimber/ExpressionCompiler/Extensions/ExpressionExtensions.cs rename to src/GraphClimber/ExpressionExtensions.cs index e400a15..fafcf3b 100644 --- a/src/GraphClimber/ExpressionCompiler/Extensions/ExpressionExtensions.cs +++ b/src/GraphClimber/ExpressionExtensions.cs @@ -1,12 +1,8 @@ using System; using System.Linq.Expressions; -namespace GraphClimber.ExpressionCompiler.Extensions +namespace GraphClimber { - /// - /// Provides extension methods to create - /// expressions easier. - /// internal static class ExpressionExtensions { @@ -71,5 +67,9 @@ public static Expression Convert(this Expression expression, Type newType) return Expression.Convert(expression, newType); } + public static string FirstLowerCase(this string str) + { + return str.Substring(0, 1).ToLowerInvariant() + str.Substring(1); + } } -} +} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionImplementation/AccessorFactory.cs b/src/GraphClimber/ExpressionImplementation/AccessorFactory.cs index 2632027..e9d33a6 100644 --- a/src/GraphClimber/ExpressionImplementation/AccessorFactory.cs +++ b/src/GraphClimber/ExpressionImplementation/AccessorFactory.cs @@ -1,21 +1,9 @@ using System; using System.Linq.Expressions; -using System.Reflection; -using System.Reflection.Emit; -using GraphClimber.ExpressionCompiler; -using GraphClimber.ExpressionCompiler.Extensions; - namespace GraphClimber { internal class AccessorFactory : IAccessorFactory { - private readonly IExpressionCompiler _compiler; - - public AccessorFactory(IExpressionCompiler compiler) - { - _compiler = compiler; - } - public Action GetSetter(IStateMember member) { ParameterExpression instance = Expression.Parameter(typeof(object)); @@ -27,7 +15,7 @@ public Action GetSetter(IStateMember member) "Setter_" + member.Name, new[] {instance, value}); - return _compiler.Compile(lambda); + return lambda.Compile(); } public Func GetGetter(IStateMember member) @@ -40,7 +28,7 @@ public Func GetGetter(IStateMember member) "Getter_" + member.Name, new[] {instance}); - return _compiler.Compile(lambda); + return lambda.Compile(); } private static Expression GetGetterExpression(IStateMember member, Expression instance) diff --git a/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs b/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs new file mode 100644 index 0000000..430e1e6 --- /dev/null +++ b/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs @@ -0,0 +1,81 @@ +using System; +using System.Linq.Expressions; +using System.Reflection; + +namespace GraphClimber +{ + internal class ArrayStateMember : IStateMember + { + private readonly Type _arrayType; + private readonly Type _arrayElementType; + private readonly int[] _indices; + + public ArrayStateMember(Type arrayType, Type arrayElementType, int[] indices) + { + _arrayType = arrayType; + _arrayElementType = arrayElementType; + _indices = indices; + } + + public string Name + { + get + { + return string.Format("[{0}]", + string.Join(", ", _indices)); + } + } + + public Type OwnerType + { + get + { + return _arrayType; + } + } + + public Type MemberType + { + get + { + return _arrayElementType; + } + } + + public bool CanRead + { + get { return true; } + } + + public bool CanWrite + { + get { return true; } + } + + public Expression GetGetExpression(Expression obj) + { + throw new NotImplementedException(); + } + + public Expression GetSetExpression(Expression obj, Expression value) + { + throw new NotImplementedException(); + } + + public bool IsArrayElement + { + get + { + return true; + } + } + + public int[] ElementIndex + { + get + { + return _indices; + } + } + } +} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs b/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs index ee3bbe7..8e3b040 100644 --- a/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs +++ b/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs @@ -2,9 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; -using System.Reflection; -using GraphClimber.ExpressionCompiler; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { @@ -14,16 +11,14 @@ internal class ClimbDelegateFactory private readonly IStateMemberProvider _stateMemberProvider; private readonly IMethodMapper _methodMapper; private readonly ClimbStore _climbStore; - private readonly IExpressionCompiler _compiler; private readonly CallProcessMutator _mutator; - public ClimbDelegateFactory(Type processorType, IStateMemberProvider stateMemberProvider, IMethodMapper methodMapper, ClimbStore climbStore, IExpressionCompiler compiler) + public ClimbDelegateFactory(Type processorType, IStateMemberProvider stateMemberProvider, IMethodMapper methodMapper, ClimbStore climbStore) { _processorType = processorType; _stateMemberProvider = stateMemberProvider; _methodMapper = methodMapper; _climbStore = climbStore; - _compiler = compiler; _mutator = new CallProcessMutator(_processorType, _methodMapper); } @@ -77,7 +72,7 @@ private ClimbDelegate CreateReferenceDelegate(Type runtimeType) "Climb_" + runtimeType.Name, new[] {processor, value}); - ClimbDelegate result = _compiler.Compile(lambda); + ClimbDelegate result = lambda.Compile(); return result; } @@ -138,7 +133,7 @@ private ClimbDelegate CreateArrayDelegate(Type runtimeType) "Climb_" + runtimeType.Name, new[] { processor, value }); - ClimbDelegate result = _compiler.Compile(lambda); + ClimbDelegate result = lambda.Compile(); return result; diff --git a/src/GraphClimber/ExpressionImplementation/ClimbStore.cs b/src/GraphClimber/ExpressionImplementation/ClimbStore.cs index 73cd7dd..15de967 100644 --- a/src/GraphClimber/ExpressionImplementation/ClimbStore.cs +++ b/src/GraphClimber/ExpressionImplementation/ClimbStore.cs @@ -1,5 +1,4 @@ using System; -using GraphClimber.ExpressionCompiler; namespace GraphClimber { @@ -16,11 +15,11 @@ internal class ClimbStore : IClimbStore private readonly RouteDelegateFactory _routeFactory; private readonly ClimbDelegateFactory _climbFactory; - public ClimbStore(Type processorType, IStateMemberProvider stateMemberProvider, IMethodMapper methodMapper, IExpressionCompiler compiler) + public ClimbStore(Type processorType, IStateMemberProvider stateMemberProvider, IMethodMapper methodMapper) { - _accessorFactory = new AccessorFactory(compiler); - _routeFactory = new RouteDelegateFactory(processorType, methodMapper, this, compiler); - _climbFactory = new ClimbDelegateFactory(processorType, stateMemberProvider, methodMapper, this, compiler); + _accessorFactory = new AccessorFactory(); + _routeFactory = new RouteDelegateFactory(processorType, methodMapper, this); + _climbFactory = new ClimbDelegateFactory(processorType, stateMemberProvider, methodMapper, this); } public Action GetSetter(IStateMember member) diff --git a/src/GraphClimber/ExpressionImplementation/DefaultGraphClimber.cs b/src/GraphClimber/ExpressionImplementation/DefaultGraphClimber.cs index 210c0b5..eaeaf1e 100644 --- a/src/GraphClimber/ExpressionImplementation/DefaultGraphClimber.cs +++ b/src/GraphClimber/ExpressionImplementation/DefaultGraphClimber.cs @@ -1,14 +1,12 @@ -using GraphClimber.ExpressionCompiler; - -namespace GraphClimber +namespace GraphClimber { - class DefaultGraphClimber : IGraphClimber + public class DefaultGraphClimber : IGraphClimber { private readonly ClimbStore _climbStore; - public DefaultGraphClimber(IStateMemberProvider stateMemberProvider, IMethodMapper methodMapper, IExpressionCompiler expressionCompiler ) + private DefaultGraphClimber(IStateMemberProvider stateMemberProvider, IMethodMapper methodMapper) { - _climbStore = new ClimbStore(typeof (TProcessor), stateMemberProvider, methodMapper, expressionCompiler); + _climbStore = new ClimbStore(typeof (TProcessor), stateMemberProvider, methodMapper); } public void Climb(object parent, TProcessor processor) @@ -25,8 +23,7 @@ public static IGraphClimber Create(IStateMemberProvider stateMemberP { return new DefaultGraphClimber( stateMemberProvider, - new MethodMapper(), - new TrivialExpressionCompiler()); + new MethodMapper()); } } } diff --git a/src/GraphClimber/ExpressionImplementation/DelegateCache/ClimbDelegateCache.cs b/src/GraphClimber/ExpressionImplementation/DelegateCache/ClimbDelegateCache.cs index 3b100fb..3d20e9e 100644 --- a/src/GraphClimber/ExpressionImplementation/DelegateCache/ClimbDelegateCache.cs +++ b/src/GraphClimber/ExpressionImplementation/DelegateCache/ClimbDelegateCache.cs @@ -4,12 +4,12 @@ namespace GraphClimber { internal class ClimbDelegateCache : DelegateCache> { - public new TDelegate Get(Type fieldType, Type runtimeType) + public TDelegate Get(Type fieldType, Type runtimeType) { return base.Get(Tuple.Create(fieldType, runtimeType)); } - public new TDelegate GetOrAdd(Type fieldType, Type runtimeType, Func factory) + public TDelegate GetOrAdd(Type fieldType, Type runtimeType, Func factory) { Func, TDelegate> tupleFactory = tuple => factory(tuple.Item1, tuple.Item2); diff --git a/src/GraphClimber/ExpressionImplementation/DescriptorVariable.cs b/src/GraphClimber/ExpressionImplementation/DescriptorVariable.cs index 2ed46fa..9b159bc 100644 --- a/src/GraphClimber/ExpressionImplementation/DescriptorVariable.cs +++ b/src/GraphClimber/ExpressionImplementation/DescriptorVariable.cs @@ -2,8 +2,6 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { diff --git a/src/GraphClimber/ExpressionImplementation/EnumConvert.cs b/src/GraphClimber/ExpressionImplementation/EnumConvert.cs new file mode 100644 index 0000000..48df970 --- /dev/null +++ b/src/GraphClimber/ExpressionImplementation/EnumConvert.cs @@ -0,0 +1,34 @@ +using System; +using System.Linq.Expressions; + +namespace GraphClimber +{ + internal class EnumConvert + { + public static readonly Func ToUnderlying = GetToUnderlying(); + public static readonly Func ToEnum = GetToEnum(); + + private static Func GetToUnderlying() + { + return GetConvert(); + } + + private static Func GetToEnum() + { + return GetConvert(); + } + + + private static Func GetConvert() + { + var parameter = Expression.Parameter(typeof(TSource), "value"); + + Expression> lambda = + Expression.Lambda> + (Expression.Convert(parameter, typeof(TTarget)), + parameter); + + return lambda.Compile(); + } + } +} \ No newline at end of file diff --git a/src/GraphClimber/ExpressionImplementation/EnumUnderlyingStateMember.cs b/src/GraphClimber/ExpressionImplementation/EnumUnderlyingStateMember.cs index 92bf935..3318c70 100644 --- a/src/GraphClimber/ExpressionImplementation/EnumUnderlyingStateMember.cs +++ b/src/GraphClimber/ExpressionImplementation/EnumUnderlyingStateMember.cs @@ -1,11 +1,10 @@ using System; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { - internal class EnumUnderlyingStateMember : IStateMember, IReflectionStateMember + internal class EnumUnderlyingStateMember : IStateMember { private readonly IStateMember _underlying; @@ -76,46 +75,5 @@ public override int GetHashCode() { return (_underlying != null ? _underlying.GetHashCode() : 0); } - - public MemberInfo UnderlyingMemberInfo - { - get - { - var underlying = _underlying as IReflectionStateMember; - - if (underlying != null) - { - return underlying.UnderlyingMemberInfo; - } - - throw new NotImplementedException(); - } - } - - public object GetValue(object owner) - { - var underlying = _underlying as IReflectionStateMember; - - if (underlying != null) - { - return underlying.GetValue(owner); - } - - throw new NotImplementedException(); - } - - public void SetValue(object owner, object value) - { - var underlying = _underlying as IReflectionStateMember; - - if (underlying != null) - { - underlying.SetValue(owner, value); - } - else - { - throw new NotImplementedException(); - } - } } } \ No newline at end of file diff --git a/src/GraphClimber/ExpressionImplementation/Mutators/NullProcessorMutator.cs b/src/GraphClimber/ExpressionImplementation/Mutators/NullProcessorMutator.cs index bb48da9..90dd9a7 100644 --- a/src/GraphClimber/ExpressionImplementation/Mutators/NullProcessorMutator.cs +++ b/src/GraphClimber/ExpressionImplementation/Mutators/NullProcessorMutator.cs @@ -1,7 +1,6 @@ using System; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { diff --git a/src/GraphClimber/ExpressionImplementation/Mutators/PolymorphismMutator.cs b/src/GraphClimber/ExpressionImplementation/Mutators/PolymorphismMutator.cs index 55b44a6..8fa6ae8 100644 --- a/src/GraphClimber/ExpressionImplementation/Mutators/PolymorphismMutator.cs +++ b/src/GraphClimber/ExpressionImplementation/Mutators/PolymorphismMutator.cs @@ -1,9 +1,6 @@ using System; -using System.Linq; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { diff --git a/src/GraphClimber/ExpressionImplementation/Mutators/RevisitedMutator.cs b/src/GraphClimber/ExpressionImplementation/Mutators/RevisitedMutator.cs index 01fb68f..92afa29 100644 --- a/src/GraphClimber/ExpressionImplementation/Mutators/RevisitedMutator.cs +++ b/src/GraphClimber/ExpressionImplementation/Mutators/RevisitedMutator.cs @@ -1,7 +1,6 @@ using System; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { diff --git a/src/GraphClimber/ExpressionImplementation/PropertyStateMember.cs b/src/GraphClimber/ExpressionImplementation/PropertyStateMember.cs index 3d7ae61..e7d242c 100644 --- a/src/GraphClimber/ExpressionImplementation/PropertyStateMember.cs +++ b/src/GraphClimber/ExpressionImplementation/PropertyStateMember.cs @@ -1,11 +1,10 @@ using System; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { - internal class PropertyStateMember : IReflectionStateMember + internal class PropertyStateMember : IStateMember { private readonly PropertyInfo _property; private static readonly int[] EmptyIndex = new int[0]; diff --git a/src/GraphClimber/ExpressionImplementation/PropertyStateMemberProvider.cs b/src/GraphClimber/ExpressionImplementation/PropertyStateMemberProvider.cs index 370da85..7051932 100644 --- a/src/GraphClimber/ExpressionImplementation/PropertyStateMemberProvider.cs +++ b/src/GraphClimber/ExpressionImplementation/PropertyStateMemberProvider.cs @@ -5,7 +5,7 @@ namespace GraphClimber { - internal class PropertyStateMemberProvider : IStateMemberProvider + public class PropertyStateMemberProvider : IStateMemberProvider { public IEnumerable Provide(Type type) { diff --git a/src/GraphClimber/ExpressionImplementation/RouteDelegateFactory.cs b/src/GraphClimber/ExpressionImplementation/RouteDelegateFactory.cs index 4965c57..4ca9bc2 100644 --- a/src/GraphClimber/ExpressionImplementation/RouteDelegateFactory.cs +++ b/src/GraphClimber/ExpressionImplementation/RouteDelegateFactory.cs @@ -1,26 +1,22 @@ using System; using System.Linq.Expressions; using System.Reflection; -using GraphClimber.ExpressionCompiler; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber { internal class RouteDelegateFactory { private readonly IClimbStore _climbStore; - private readonly IExpressionCompiler _compiler; private readonly Type _processorType; private readonly SpecialMethodMutator _specialMutator; private readonly IMethodMapper _methodMapper; - public RouteDelegateFactory(Type processorType, IMethodMapper methodMapper, IClimbStore climbStore, IExpressionCompiler compiler) + public RouteDelegateFactory(Type processorType, IMethodMapper methodMapper, IClimbStore climbStore) { _processorType = processorType; _climbStore = climbStore; _specialMutator = new SpecialMethodMutator(processorType); _methodMapper = methodMapper; - _compiler = compiler; } public RouteDelegate GetRouteDelegate(IStateMember member, Type runtimeMemberType) @@ -58,7 +54,7 @@ public RouteDelegate GetRouteDelegate(IStateMember member, Type runtimeMemberTyp "Route_" + runtimeMemberType.Name, new[] {processor, owner, skipSpecialMethods}); - return _compiler.Compile(lambda); + return lambda.Compile(); } } } \ No newline at end of file diff --git a/src/GraphClimber/ExpressionImplementation/ValueDescriptor.cs b/src/GraphClimber/ExpressionImplementation/ValueDescriptor.cs index 13c9f80..e3f22d5 100644 --- a/src/GraphClimber/ExpressionImplementation/ValueDescriptor.cs +++ b/src/GraphClimber/ExpressionImplementation/ValueDescriptor.cs @@ -77,11 +77,11 @@ protected void Climb(TField value) } else { - ClimReference(value, type); + ClimbReference(value, type); } } - private void ClimReference(TField value, Type type) + private void ClimbReference(TField value, Type type) { if (type == typeof(TRuntime)) { diff --git a/src/GraphClimber/GraphClimber.csproj b/src/GraphClimber/GraphClimber.csproj index 7b7c688..dbdcea4 100644 --- a/src/GraphClimber/GraphClimber.csproj +++ b/src/GraphClimber/GraphClimber.csproj @@ -1,185 +1,7 @@ - - - + + - Debug - AnyCPU - {F7FA4635-C6C6-4D82-B344-B737438E1651} - Exe - Properties - GraphClimber - GraphClimber - v4.5 - 512 - 12.0.0 - 2.0 - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true + netstandard2.0 - - AnyCPU - true - full - false - ..\..\bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - ..\..\bin\Release\ - TRACE - prompt - 4 - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4.5 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - - - \ No newline at end of file + + diff --git a/src/GraphClimber/Program.cs b/src/GraphClimber/Program.cs deleted file mode 100644 index 5c2e3d4..0000000 --- a/src/GraphClimber/Program.cs +++ /dev/null @@ -1,385 +0,0 @@ -using System; -using System.IO; -using System.Linq.Expressions; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Xml.Linq; -using GraphClimber.Examples; -using GraphClimber.Examples.Binary; -using GraphClimber.ExpressionCompiler; -using GraphClimber.ExpressionCompiler.Extensions; - -namespace GraphClimber -{ - internal class EnumConvert - { - public static readonly Func ToUnderlying = GetToUnderlying(); - public static readonly Func ToEnum = GetToEnum(); - - private static Func GetToUnderlying() - { - return GetConvert(); - } - - private static Func GetToEnum() - { - return GetConvert(); - } - - - private static Func GetConvert() - { - var parameter = Expression.Parameter(typeof(TSource), "value"); - - Expression> lambda = - Expression.Lambda> - (Expression.Convert(parameter, typeof (TTarget)), - parameter); - - return lambda.Compile(); - } - - } - - enum Days - { - Sunday, - Monday, - Tuesday, - Wendensday, - Thursday, - Friday, - Saturday - } - - public class ExpressionDebugGames - { - private static int PrivateField = 2; - - private static int PrivateProperty - { - get { return 5; } - } - - private static int PrivateMethod() - { - return 3; - } - - private static int GenericMethod(TEnum value) where TEnum : IConvertible - { - return 2; - } - - public static void Play() - { - - Expression> hi = () => typeof(int); - - MemberExpression propertyOrField = Expression.Field(null, typeof(ExpressionDebugGames).GetField("PrivateField", BindingFlags.Static | BindingFlags.NonPublic)); - MemberExpression property = Expression.Property(null, typeof(ExpressionDebugGames), "PrivateProperty"); - MethodCallExpression method = Expression.Call(null, - typeof(ExpressionDebugGames).GetMethod("PrivateMethod", BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(typeof(object))); - - var parameter = Expression.Parameter(typeof(int), "someNumberArgument"); - - var variable = Expression.Variable(typeof(int), "myInt"); - var @break = Expression.Label(); - Expression exp = Expression.Assign(variable, Expression.Divide(propertyOrField, Expression.Subtract(property, method))); - exp = Expression.Block(new[] { variable }, exp, Expression.Add(2.Constant(), 5.Constant()), Expression.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expression.Constant("Hello Worlda"))); - - - var iVariable = Expression.Variable(typeof(int), "i"); - // exp = CustomExpression.For(iVariable, 0.Constant(), Expression.LessThan(iVariable, 5.Constant()), Expression.PostIncrementAssign(iVariable), exp); - - exp = Expression.Block(exp, - Expression.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), - Expression.Constant("Goodbye"))); - - var lambda = Expression.Lambda>(exp, "Hello_World", - new[] { parameter }); - - var expression = new DebugExpressionCompiler(DebugViewExpressionDescriber.Empty).Compile(lambda); - - expression(56); - } - - } - - class SimpleType - { - - - public ValueType SomeValueType { get; set; } - - public string String { get; set; } - - public IConvertible Convertible { get; set; } - - - } - - public class Program - { - private static readonly IStateMemberProvider _stateMemberProvider = new CachingStateMemberProvider(new ReflectionPropertyStateMemberProvider()); - - public static void DoSomething(StrongBox hello) - { - Console.WriteLine(hello); - } - - - static void Main(string[] args) - { - //ExpressionDebugGames.Play(); - //IStore store = new TrivialStore(); - - //store.Set("A", 5); - //store.GetInner("A").Set("A", 10); - - //SerializeDeserializeXML(); - - //SerializeDeserializeStore(); - - SerializeDeserializeBinary(); - } - - public static object GetSimpleTypeInstance() - { - return new SimpleType() - { - Convertible = "sadasd", - SomeValueType = Days.Monday, - String = "Hello W0rld" - }; - } - - public class PersonHolder - { - public IPerson A { get; set; } - public IPerson B { get; set; } - - public IPerson C { get; set; } - } - - private static void SerializeDeserializeBinary() - { - object person = GetSimpleTypeInstance(); - - IPerson structure = new Person2() { Age = 25, Surprise = Days.Monday }; - person = new PersonHolder() { A = structure, B = structure, C = structure }; - - structure.IncreaseAge(); - - //var stateMemberProvider = new BinaryStateMemberProvider(_stateMemberProvider); - var stateMemberProvider = new BinaryStateMemberProvider(new PropertyStateMemberProvider()); - - //var writeClimber = new SlowGraphClimber(stateMemberProvider); - //var readClimber = new SlowGraphClimber(stateMemberProvider); - - var stream = new MemoryStream(); - var binaryWriterProcessor = new BinaryWriterProcessor(new LoggingWriter(new CompressingWriter(new BinaryWriterAdapter(new BinaryWriter(stream))), Console.Out)); - - var writerGraphClimber = DefaultGraphClimber.Create(stateMemberProvider); - - //ClimbDelegate> climb2 = - // store2.GetClimb>(typeof(StrongBox)); - - //climb2(binaryWriterProcessor, - // new StrongBox(person)); - - writerGraphClimber.Climb(new StrongBox(person), binaryWriterProcessor); - - //writeClimber.Route(person, binaryWriterProcessor, false); - - stream.Position = 0; - var binaryReaderProcessor = new BinaryReaderProcessor(new LoggingReader(new DecompressingReader(new BinaryReaderAdapter(new BinaryReader(stream))), Console.Out)); - - var readerGraphClimber = DefaultGraphClimber.Create(stateMemberProvider); - var strongBox = new StrongBox(); - - readerGraphClimber.Climb(strongBox, binaryReaderProcessor); - - - //ClimbStore store = new ClimbStore(binaryReaderProcessor.GetType(), - // new BinaryStateMemberProvider(new PropertyStateMemberProvider()), - // new MethodMapper(), - // new TrivialExpressionCompiler()); - - //ClimbDelegate> climb = store.GetClimb>(typeof (StrongBox)); - - //climb(binaryReaderProcessor, strongBox); - } - - private static void SerializeDeserializeXML() - { - var text = - @" - Shani Elharrar - 24 - - null - 23 - 4 - -"; - - - // Reader code: - SlowGraphClimber climber2 = - new SlowGraphClimber - (_stateMemberProvider); - - XElement reader = XElement.Parse(text); - - XmlReaderProcessor processor2 = - new XmlReaderProcessor(reader); - - Person person2 = new Person(); - - climber2.Climb(person2, - processor2); - - - // Writer code: - SlowGraphClimber climber = - new SlowGraphClimber - (_stateMemberProvider); - - Person person = new Person() - { - Age = 24, - Name = "Shani Elharrar", - Surprise = new Person() - { - Age = 23, - Name = null, - Surprise = 4 - } - }; - - XmlWriterProcessor processor = new XmlWriterProcessor(); - - climber.Climb(person, - processor); - } - - public struct MyClass - { - public string Name { get; set; } - } - - class Person - { - public Person() - { - //Children = new List(); - } - - public string Name { get; set; } - - public int Age { get; set; } - - public object Surprise { get; set; } - - public Person Father { get; set; } - - //public IList Children { get; set; } - } - - internal struct Person2 : IPerson - { - public string Name { get; set; } - - public int Age { get; set; } - - public object Surprise { get; set; } - - public object Father { get; set; } - - public Days Day { get; set; } - public void IncreaseAge() - { - Age++; - } - } - - - public static void SerializeDeserializeStore() - { - var store = new TrivialStore(); - - SlowGraphClimber climber = new SlowGraphClimber(_stateMemberProvider); - - var processor = new StoreWriterProcessor(store); - var box = new StrongBox(GetPerson()); - - climber.Climb(box, processor); - - - SlowGraphClimber readerClimber = new SlowGraphClimber(_stateMemberProvider); - - var readerProcessor = new StoreReaderProcessor(store); - var readBox = new StrongBox(null); - readerClimber.Climb(readBox, readerProcessor); - - } - - private static Person GetPerson() - { - var ilan = new Person { Age = 26 + 25, Name = "Ilan Zelingher", Surprise = 1 }; - ilan.Surprise = ilan; - return new Person() - { - Age = 26, - Name = "Elad Zelinger", - Father = ilan, - //Children = { new Person() { Name = "Jason"}, new Person() { Name = "Tomerh" }}, - Surprise = new Person() - { - Age = 21, - Name = "Yosi Attias", - Surprise = new MyClass() - { - Name = "YO!" - } - } - }; - } - - private static Person2 GetPerson2() - { - Person2 ilan = new Person2 { Age = 26 + 25, Name = "Ilan Zelingher" }; - - ilan.Surprise = ilan; - return new Person2() - { - Age = 26, - Name = "Elad Zelinger", - Father = ilan, - Day = Days.Tuesday, - Surprise = new Person2() - { - Age = 21, - Name = "Yosi Attias", - Surprise =ilan - //new object[] - //{ - // ilan, ilan, 342, "Hello", - // new int[,]{{1,1},{2,3},{5,8}}, - // new int[]{1,1,2,3,5,8}, - // Days.Saturday - //} - } - }; - - } - } - - public interface IPerson - { - - void IncreaseAge(); - - } -} \ No newline at end of file diff --git a/src/GraphClimber/Properties/AssemblyInfo.cs b/src/GraphClimber/Properties/AssemblyInfo.cs deleted file mode 100644 index 56a3be0..0000000 --- a/src/GraphClimber/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("GraphClimber")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("CodeSharp")] -[assembly: AssemblyProduct("GraphClimber")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: InternalsVisibleTo("GraphClimber.Debug")] -[assembly: InternalsVisibleTo("GraphClimber.RuntimeGenerated")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("f7fa4635-c6c6-4d82-b344-b737438e1651")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/GraphClimber/SlowGraphClimber.cs b/src/GraphClimber/SlowGraphClimber.cs deleted file mode 100644 index ddfff39..0000000 --- a/src/GraphClimber/SlowGraphClimber.cs +++ /dev/null @@ -1,797 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using GraphClimber.ValueDescriptor; - -namespace GraphClimber -{ - public class CachingStateMemberProvider : IStateMemberProvider - { - private readonly IStateMemberProvider _underlying; - - private readonly IDictionary> _cache = new Dictionary>(); - private readonly object _syncRoot = new object(); - - public CachingStateMemberProvider(IStateMemberProvider underlying) - { - _underlying = underlying; - } - - public IEnumerable Provide(Type type) - { - IEnumerable retVal; - if (_cache.TryGetValue(type, out retVal)) - { - return retVal; - } - - lock (_syncRoot) - { - if (!_cache.TryGetValue(type, out retVal)) - { - // ToList() is here to cache yield return methods. - _cache[type] = retVal = _underlying.Provide(type).ToList(); - } - } - - return retVal; - } - - public IStateMember ProvideArrayMember(Type arrayType, int[] indices) - { - // TODO : May not be smart performance wise. - return new ArrayStateMember(arrayType, arrayType.GetElementType(), indices); - } - } - - internal class ReflectionPropertyStateMemberProvider : IStateMemberProvider - { - public IEnumerable Provide(Type type) - { - return type.GetRuntimeProperties() - .Where(x => x.GetIndexParameters().Length == 0) - .Select(x => new ReflectionPropertyStateMember(x)); - } - - public IStateMember ProvideArrayMember(Type arrayType, int[] indices) - { - return new ArrayStateMember(arrayType, arrayType.GetElementType(), indices); - } - } - - - - internal class ReflectionPropertyStateMember : IReflectionStateMember - { - private readonly PropertyInfo _property; - - public ReflectionPropertyStateMember(PropertyInfo property) - { - _property = property; - } - - public string Name - { - get { return _property.Name; } - } - - public Type OwnerType - { - get { return _property.ReflectedType; } - } - - public virtual Type MemberType - { - get { return _property.PropertyType; } - } - - public bool CanRead - { - get { return _property.CanRead; } - } - - public bool CanWrite - { - get { return _property.CanWrite; } - } - - public Expression GetGetExpression(Expression obj) - { - throw new NotImplementedException(); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - throw new NotImplementedException(); - } - - public bool IsArrayElement - { - get { return false; } - } - - public int[] ElementIndex - { - get - { - // The empty index - return new int[0]; - } - } - - public MemberInfo UnderlyingMemberInfo - { - get - { - return _property; - } - } - - public object GetValue(object owner) - { - return _property.GetValue(owner); - } - - public void SetValue(object owner, object value) - { - _property.SetValue(owner, value); - } - } - - public interface IReflectionStateMember : IStateMember - { - MemberInfo UnderlyingMemberInfo { get; } - - object GetValue(object owner); - - void SetValue(object owner, object value); - } - - internal class ReflectionValueDescriptor : - IReadOnlyValueDescriptor, - IReadOnlyExactValueDescriptor, - IWriteOnlyExactValueDescriptor, - IWriteOnlyValueDescriptor, - IReadWriteValueDescriptor, - IReflectionValueDescriptor where - TRuntime : TField - { - private readonly IStateMemberProvider _stateMemberProvider; - private readonly IReflectionStateMember _stateMember; - private readonly object _owner; - private readonly object _processor; - - public ReflectionValueDescriptor(object processor, IStateMemberProvider stateMemberProvider, - IReflectionStateMember stateMember, object owner) - { - _stateMemberProvider = stateMemberProvider; - _stateMember = stateMember; - _owner = owner; - _processor = processor; - } - - public TField Get() - { - return (TField) _stateMember.GetValue(_owner); - } - - object IReflectionValueDescriptor.Get() - { - return Get(); - } - - TRuntime IReadOnlyValueDescriptor.Get() - { - return (TRuntime) Get(); - } - - TRuntime IReadOnlyExactValueDescriptor.Get() - { - IReadOnlyValueDescriptor casted = this; - return casted.Get(); - } - - public void Set(TField value) - { - _stateMember.SetValue(_owner, value); - } - - public IStateMember StateMember - { - get { return _stateMember; } - } - - public object Owner - { - get { return _owner; } - } - - public void Climb() - { - TField value = Get(); - - Type runtimeType; - - if (value != null) - { - runtimeType = value.GetType(); - } - else - { - throw new NullReferenceException("Can't climb on null, you silly developer!"); - } - - if (runtimeType.IsArray) - { - ClimbArray((Array) (object) value); - } - else - { - IEnumerable members = - _stateMemberProvider.Provide(runtimeType); - - object boxed = value; - - foreach (IReflectionStateMember member in - members.Cast()) - { - Type runtimeMemberType = GetRuntimeMemberType(member, value); - VisitMember(member, boxed, runtimeMemberType, false, false); - } - - if (runtimeType.IsValueType) - { - Set((TField) boxed); - } - } - } - - private void ClimbArray(Array array) - { - int dimension = array.Rank; - - IEnumerable> indexesSets = - Enumerable.Range(0, dimension) - .Select(index => Enumerable.Range(array.GetLowerBound(index), - array.GetLength(index))); - - IEnumerable> allIndexes = - Combinatorics.CartesianProduct(indexesSets.Reverse()); - - foreach (IEnumerable indexSet in allIndexes) - { - int[] indices = indexSet.Reverse().ToArray(); - - IReflectionStateMember decorated = (IReflectionStateMember) - _stateMemberProvider.ProvideArrayMember(array.GetType(), indices); - - Type runtimeMemberType = GetRuntimeMemberType(decorated, array); - - VisitMember(decorated, array, runtimeMemberType, false, false); - } - } - - private Type GetRuntimeMemberType(IReflectionStateMember member, object value) - { - Type memberType = member.MemberType; - - object memberValue = member.GetValue(value); - - var result = - memberValue != null ? memberValue.GetType() : memberType; - - return result; - } - - private void VisitMember(IReflectionStateMember member, - object owner, - Type runtimeMemberType, - bool skipSpecialMethod, - bool routed) - { - IReflectionValueDescriptor descriptor = - CreateDescriptor(member, owner, runtimeMemberType); - - CallProcess(descriptor, skipSpecialMethod, routed); - } - - private IReflectionValueDescriptor CreateDescriptor(IReflectionStateMember member, object value, - Type runtimeMemberType) - { - Type descriptorType; - - Type memberType = member.MemberType; - if (memberType.IsEnum) - { - descriptorType = typeof (ReflectionEnumValueDescriptor<,,>) - .MakeGenericType(memberType, runtimeMemberType, - memberType.GetEnumUnderlyingType()); - } - else - { - descriptorType = typeof(ReflectionValueDescriptor<,>) - .MakeGenericType(memberType, runtimeMemberType); - } - - IReflectionValueDescriptor descriptor = - (IReflectionValueDescriptor) Activator.CreateInstance - (descriptorType, - _processor, _stateMemberProvider, member, value); - - return descriptor; - } - - public void Route(IStateMember stateMember, object owner, bool skipSpecialMethod = true) - { - VisitMember((IReflectionStateMember) stateMember, - owner, - stateMember.MemberType, - skipSpecialMethod, true); - } - - public void Route(IStateMember stateMember, Type runtimeMemberType, object owner, bool skipSpecialMethod = true) - { - VisitMember((IReflectionStateMember) stateMember, - owner, - runtimeMemberType, - skipSpecialMethod, true); - } - - private void CallProcess(IReflectionValueDescriptor descriptor, bool skipSpecialMethod, bool routed) - { - Type fieldType = descriptor.StateMember.MemberType; - - bool methodCalled = false; - - if (!fieldType.IsValueType && !skipSpecialMethod) - { - methodCalled = TryCallSpecialMethod(descriptor, fieldType); - } - - if (!methodCalled) - { - CallMatchedProcess(descriptor, routed); - } - } - - private bool TryCallSpecialMethod(IReflectionValueDescriptor descriptor, Type fieldType) - { - object value = descriptor.Get(); - - INullProcessor processor = _processor as INullProcessor; - IRevisitedProcessor revisitedProcessor = _processor as IRevisitedProcessor; - - if (processor != null && value == null) - { - CallGenericMethod(descriptor, typeof (INullProcessor), fieldType, "ProcessNull"); - return true; - } - else if ((value != null) && - (revisitedProcessor != null) && - revisitedProcessor.Visited(value)) - { - CallGenericMethod(descriptor, typeof (IRevisitedProcessor), fieldType, "ProcessRevisited"); - return true; - } - - return false; - } - - private void CallGenericMethod(IReflectionValueDescriptor descriptor, Type processorType, Type genericType, string methodName) - { - MethodInfo methodToCall = - processorType.GetMethod(methodName) - .MakeGenericMethod(genericType); - - methodToCall.Invoke(_processor, new object[] {descriptor}); - } - - private void CallMatchedProcess(IReflectionValueDescriptor descriptor, bool routed) - { - GenericArgumentBinder binder = new GenericArgumentBinder(new FallbackToFirstCandidateMethodSelector(new BinderMethodSelector(Type.DefaultBinder))); - - IEnumerable methods = - _processor.GetType().GetMethods() - .Where(x => x.IsDefined(typeof (ProcessorMethodAttribute))) - .Where(x => !x.GetCustomAttribute().OnlyOnRoute || routed); - - Type descriptorType = descriptor.GetType(); - - IEnumerable> candidates = - methods.Select(method => Bind(binder, method, descriptorType)) - .Where(x => x != null) - .GroupBy(x => x.GetCustomAttribute().Precedence) - .OrderBy(x => x.Key); - - IGrouping maximum = candidates.FirstOrDefault(); - - if (maximum.Skip(1).Any()) - { - throw new Exception("Too many candidates for the processor thingy. Use precedence."); - } - else - { - MethodInfo method = maximum.FirstOrDefault(); - - if (method != null) - { - method.Invoke(_processor, new object[] {descriptor}); - } - else - { - throw new Exception( - "No method found :(, this might be a bug in your code, or in the GraphClimber. Good luck."); - } - } - } - - private MethodInfo Bind(GenericArgumentBinder binder, MethodInfo method, Type descriptorType) - { - MethodInfo bindedMethod; - - if (binder.TryBind(method, new[] {descriptorType}, out bindedMethod)) - { - return bindedMethod; - } - - return null; - } - } - - internal class ReflectionEnumValueDescriptor : - ReflectionValueDescriptor, - IReadOnlyEnumExactValueDescriptor, - IWriteOnlyEnumExactValueDescriptor - where TRuntime : TField - where TField : IConvertible - where TUnderlying : IConvertible - { - private readonly IStateMember _underlyingValueStateMember; - - public ReflectionEnumValueDescriptor(object processor, IStateMemberProvider stateMemberProvider, IReflectionStateMember stateMember, object owner) : - base(processor, stateMemberProvider, stateMember, owner) - { - _underlyingValueStateMember = new EnumUnderlyingValueStateMember(stateMember); - } - - public TUnderlying GetUnderlying() - { - TField result = Get(); - - TUnderlying value = - (TUnderlying) Convert.ChangeType(result, typeof (TUnderlying)); - - return value; - } - - public void SetUnderlying(TUnderlying value) - { - long asLong = - (long) Convert.ChangeType(value, typeof (long)); - - TField result = - (TField) Enum.ToObject(typeof (TField), asLong); - - Set(result); - } - - public IStateMember UnderlyingValueStateMember - { - get - { - return _underlyingValueStateMember; - } - } - } - - internal class EnumUnderlyingValueStateMember : IReflectionStateMember - { - private readonly IReflectionStateMember _stateMember; - private readonly Type _enumType; - private readonly Type _underlyingType; - - public EnumUnderlyingValueStateMember(IReflectionStateMember stateMember) - { - _stateMember = stateMember; - _enumType = _stateMember.MemberType; - _underlyingType = _enumType.GetEnumUnderlyingType(); - } - - public string Name - { - get { return _stateMember.Name; } - } - - public Type OwnerType - { - get { return _stateMember.OwnerType; } - } - - public Type MemberType - { - get { return _underlyingType; } - } - - public bool CanRead - { - get { return _stateMember.CanRead; } - } - - public bool CanWrite - { - get { return _stateMember.CanWrite; } - } - - public Expression GetGetExpression(Expression obj) - { - return _stateMember.GetGetExpression(obj); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - return _stateMember.GetSetExpression(obj, value); - } - - public bool IsArrayElement - { - get { return _stateMember.IsArrayElement; } - } - - public int[] ElementIndex - { - get { return _stateMember.ElementIndex; } - } - - public MemberInfo UnderlyingMemberInfo - { - get { return _stateMember.UnderlyingMemberInfo; } - } - - public object GetValue(object owner) - { - return Convert.ChangeType(_stateMember.GetValue(owner), _underlyingType); - } - - public void SetValue(object owner, object value) - { - // Thats how they do it :( - object casted = - Enum.ToObject(_enumType, Convert.ToInt64(value)); - - _stateMember.SetValue(owner, casted); - } - } - - internal class ArrayStateMember : IReflectionStateMember - { - private readonly Type _arrayType; - private readonly Type _arrayElementType; - private readonly int[] _indices; - - public ArrayStateMember(Type arrayType, Type arrayElementType, int[] indices) - { - _arrayType = arrayType; - _arrayElementType = arrayElementType; - _indices = indices; - } - - public string Name - { - get - { - return string.Format("[{0}]", - string.Join(", ", _indices)); - } - } - - public Type OwnerType - { - get - { - return _arrayType; - } - } - - public Type MemberType - { - get - { - return _arrayElementType; - } - } - - public bool CanRead - { - get { return true; } - } - - public bool CanWrite - { - get { return true; } - } - - public Expression GetGetExpression(Expression obj) - { - throw new NotImplementedException(); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - throw new NotImplementedException(); - } - - public bool IsArrayElement - { - get - { - return true; - } - } - - public int[] ElementIndex - { - get - { - return _indices; - } - } - - public MemberInfo UnderlyingMemberInfo - { - get { throw new NotImplementedException(); } - } - - public object GetValue(object owner) - { - Array array = owner as Array; - return array.GetValue(_indices); - } - - public void SetValue(object owner, object value) - { - Array array = owner as Array; - array.SetValue(value, _indices); - } - } - - internal interface IReflectionValueDescriptor : IValueDescriptor - { - object Get(); - } - - - public class SlowGraphClimber : IGraphClimber - { - private readonly IStateMemberProvider _stateMemberProvider; - - public SlowGraphClimber(IStateMemberProvider stateMemberProvider) - { - _stateMemberProvider = stateMemberProvider; - } - - public void Climb(object parent, TProcessor processor) - { - var descriptor = GetDescriptor(parent, processor); - - descriptor.Climb(); - } - - public void Route(IStateMember stateMember, object current, TProcessor processor, bool skipSpecialMethod) - { - throw new NotImplementedException(); - } - - public void Route(object current, TProcessor processor, bool skipSpecialMethod) - { - var descriptor = GetDescriptor(current, processor); - - descriptor.Route(descriptor.StateMember, current.GetType(), new Box { Parent = current }, skipSpecialMethod); - } - - - private ReflectionValueDescriptor GetDescriptor(object current, TProcessor processor) - { - var descriptor = - new ReflectionValueDescriptor(processor, - _stateMemberProvider, - new StaticStateMember(current), - null); - return descriptor; - } - - - private class Box - { - public object Parent { get; set; } - } - } - - /* - public class StaticValueDescriptor : IReadOnlyValueDescriptor, - IReadOnlyExactValueDescriptor, - IReadWriteValueDescriptor - { - private readonly object _current; - private readonly object _processor; - - public StaticValueDescriptor(object current, object processor) - { - _current = current; - _processor = processor; - throw new NotImplementedException(); - } - - public void Set(object value) - { - throw new NotImplementedException(); - } - - public object Get() - { - return _current; - } - - public IStateMember StateMember - { - get { return StaticStateMember.Empty; } - } - - public class StaticStateMember : IStateMember - { - public static readonly IStateMember Empty = new StaticStateMember(); - - private StaticStateMember() - { - - } - - - public string Name - { - get { return "InitialValue"; } - } - - public Type OwnerType - { - get { return typeof (object); } - } - - public Type MemberType - { - get { return typeof(object); } - } - - public Expression GetGetExpression(Expression obj) - { - throw new NotImplementedException(); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - throw new NotImplementedException(); - } - } - - public object Owner - { - get { throw new NotImplementedException(); } - } - - public void Climb() - { - throw new NotImplementedException(); - } - - public void Route(IStateMember stateMember, Type runtimeMemberType, object owner) - { - throw new NotImplementedException(); - } - - public void Route(IStateMember stateMember, object owner) - { - throw new NotImplementedException(); - } - }*/ -} \ No newline at end of file diff --git a/src/GraphClimber/ValueDescriptor/DelegateStateMember.cs b/src/GraphClimber/ValueDescriptor/DelegateStateMember.cs index 74f882d..1e1cde4 100644 --- a/src/GraphClimber/ValueDescriptor/DelegateStateMember.cs +++ b/src/GraphClimber/ValueDescriptor/DelegateStateMember.cs @@ -2,11 +2,10 @@ using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; -using GraphClimber.ExpressionCompiler.Extensions; namespace GraphClimber.ValueDescriptor { - public class StaticStateMember : IReflectionStateMember + public class StaticStateMember : IStateMember { private readonly object _value; private readonly string _name; @@ -61,24 +60,9 @@ public int[] ElementIndex { get { throw new NotImplementedException(); } } - - public MemberInfo UnderlyingMemberInfo - { - get { throw new NotImplementedException(); } - } - - public object GetValue(object owner) - { - return _value; - } - - public void SetValue(object owner, object value) - { - // Does nothing! - } } - public class StrongBoxStateMember : IReflectionStateMember + public class StrongBoxStateMember : IStateMember { private readonly StrongBox _strongBox; private readonly string _name; @@ -149,161 +133,4 @@ public void SetValue(object owner, object value) _strongBox.Value = (T) value; } } - - public class DelegateStateMember : IReflectionStateMember - { - private readonly Type _memberType; - private readonly Func _getValue; - private readonly Action _setValue; - - public DelegateStateMember(Type memberType, Func getValue, Action setValue) - { - _memberType = memberType; - _getValue = getValue; - _setValue = setValue; - } - - - public string Name - { - get { return "Value"; } - } - - public Type OwnerType - { - get { throw new NotSupportedException(); } - } - - public Type MemberType - { - get { return _memberType; } - } - - public bool CanRead - { - get { return true; } - } - - public bool CanWrite - { - get { return true; } - } - - public Expression GetGetExpression(Expression obj) - { - return Expression.Invoke(_getValue.Constant()); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - return Expression.Invoke(_setValue.Constant(), value); - } - - public bool IsArrayElement - { - get { return false; } - } - - public int[] ElementIndex - { - get { throw new NotSupportedException(); } - } - - public MemberInfo UnderlyingMemberInfo - { - get { throw new NotImplementedException(); } - } - - public object GetValue(object owner) - { - return _getValue(); - } - - public void SetValue(object owner, object value) - { - _setValue(value); - } - - public static IReflectionStateMember Create(Type memberType, Func getValue, Action setValue) - { - return new DelegateStateMember(memberType, getValue, setValue); - } - - public static IReflectionStateMember Create(Func getValue, Action setValue) - { - return new SafeDelegateStateMember(getValue, setValue); - } - } - - public class SafeDelegateStateMember : IReflectionStateMember - { - private readonly Func _getValue; - private readonly Action _setValue; - - public SafeDelegateStateMember(Func getValue, Action setValue) - { - _getValue = getValue; - _setValue = setValue; - } - - public string Name - { - get { return "Value"; } - } - - public Type OwnerType - { - get { throw new NotSupportedException(); } - } - - public Type MemberType - { - get { return typeof (T); } - } - - public bool CanRead - { - get { return true; } - } - - public bool CanWrite - { - get { return true; } - } - - public Expression GetGetExpression(Expression obj) - { - return Expression.Invoke(_getValue.Constant()); - } - - public Expression GetSetExpression(Expression obj, Expression value) - { - return Expression.Invoke(_setValue.Constant(), value); - } - - public bool IsArrayElement - { - get { return false; } - } - - public int[] ElementIndex - { - get { throw new NotSupportedException(); } - } - - public MemberInfo UnderlyingMemberInfo - { - get { throw new NotImplementedException(); } - } - - public object GetValue(object owner) - { - return _getValue(); - } - - public void SetValue(object owner, object value) - { - _setValue((T) value); - } - } } From 827912fce3c3502cc10750b5db9c4fb99b3244a8 Mon Sep 17 00:00:00 2001 From: Elad Zelingher Date: Tue, 12 May 2020 07:55:54 -0400 Subject: [PATCH 2/6] Implementation of CreateArrayDelegate --- .../ArrayStateMember.cs | 19 ++- .../ClimbDelegateFactory.cs | 127 ++++++++++++------ 2 files changed, 104 insertions(+), 42 deletions(-) diff --git a/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs b/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs index 430e1e6..f730739 100644 --- a/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs +++ b/src/GraphClimber/ExpressionImplementation/ArrayStateMember.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -54,12 +56,25 @@ public bool CanWrite public Expression GetGetExpression(Expression obj) { - throw new NotImplementedException(); + Expression getExpression = ArrayAccess(obj); + return getExpression; + } + + private Expression ArrayAccess(Expression obj) + { + ConstantExpression array = Expression.Constant(_indices, typeof(int[])); + + IEnumerable indices = + Enumerable.Range(0, _indices.Length) + .Select(x => Expression.ArrayIndex(array, + Expression.Constant(x))); + return Expression.ArrayAccess(obj.Convert(this._arrayType), indices); } public Expression GetSetExpression(Expression obj, Expression value) { - throw new NotImplementedException(); + Expression arrayAccess = ArrayAccess(obj); + return Expression.Assign(arrayAccess, value); } public bool IsArrayElement diff --git a/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs b/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs index 8e3b040..a78989c 100644 --- a/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs +++ b/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs @@ -51,16 +51,7 @@ private ClimbDelegate CreateReferenceDelegate(Type runtimeType) foreach (IStateMember member in members) { - DescriptorWriter writer = new DescriptorWriter(_climbStore); - - DescriptorVariable descriptor = - writer.GetDescriptor(castedProcessor, owner, member, member.MemberType); - - Expression callProcessor = - _mutator.GetExpression(castedProcessor, owner, member, descriptor.Reference); - - descriptorVariables.Add(descriptor.Reference); - expressions.Add(descriptor.Declaration); + Expression callProcessor = CallProcessor(castedProcessor, owner, member, descriptorVariables, expressions); expressions.Add(callProcessor); } @@ -77,6 +68,27 @@ private ClimbDelegate CreateReferenceDelegate(Type runtimeType) return result; } + private Expression CallProcessor + (Expression castedProcessor, + Expression owner, + IStateMember member, + List methodVariables, + List methodAssignments) + { + DescriptorWriter writer = new DescriptorWriter(_climbStore); + + DescriptorVariable descriptor = + writer.GetDescriptor(castedProcessor, owner, member, member.MemberType); + + Expression callProcessor = + _mutator.GetExpression(castedProcessor, owner, member, descriptor.Reference); + + methodVariables.Add(descriptor.Reference); + methodAssignments.Add(descriptor.Declaration); + + return callProcessor; + } + private ClimbDelegate CreateArrayDelegate(Type runtimeType) { @@ -88,17 +100,45 @@ private ClimbDelegate CreateArrayDelegate(Type runtimeType) var ranks = runtimeType.GetArrayRank(); + int[] indices = new int[ranks]; + var member = _stateMemberProvider.ProvideArrayMember(runtimeType, indices); + + List variables = new List(); + List assignments = new List(); + + Expression callExpression = + CallProcessor(castedProcessor, owner, member, variables, assignments); + + var loop = LoopArrayBounds(ranks, owner, Expression.Constant(indices), callExpression, variables, assignments); + + BlockExpression climbBody = + Expression.Block(variables, + assignments.Concat(new[] {loop})); + + Expression> lambda = + Expression.Lambda>(climbBody, + "Climb_" + runtimeType.Name, + new[] { processor, value }); + + ClimbDelegate result = lambda.Compile(); + + return result; + } + + private static Expression LoopArrayBounds + (int ranks, + Expression owner, + Expression stateMemberArray, + Expression callExpression, + List parameterExpressions, + List assignments) + { var rankParameters = - Enumerable.Range(0, ranks).Select(r => Expression.Variable(typeof (int), "rank_" + r)).ToList(); + Enumerable.Range(0, ranks).Select(r => Expression.Variable(typeof(int), "rank_" + r)).ToList(); var upperBoundParameters = - Enumerable.Range(0, ranks).Select(r => Expression.Variable(typeof (int), "upper_" + r)).ToList(); - - var assignRankParameters = new Expression[ranks]; - var assignUpperParameters = new Expression[ranks]; - + Enumerable.Range(0, ranks).Select(r => Expression.Variable(typeof(int), "upper_" + r)).ToList(); - Expression callExpression = Expression.Empty(); // TODO : Complete. for (int rank = ranks - 1; rank >= 0; rank--) { @@ -106,38 +146,45 @@ private ClimbDelegate CreateArrayDelegate(Type runtimeType) var breakTarget = Expression.Label("break"); var continueTarget = Expression.Label("continue"); - assignRankParameters[rank] = Expression.Assign(rankParameters[rank], - Expression.Call(owner, "GetLowerBound", null, Expression.Constant(rank))); + // i_k = array.GetLowerBound(k) + var currentLoopVariableAssignment = + Expression.Assign(rankParameters[rank], + Expression.Call(owner, "GetLowerBound", null, + Expression.Constant(rank))); + + // length_k = array.GetUpperBound(k) + var currentUpperBoundAssignment = Expression.Assign(upperBoundParameters[rank], + Expression.Call(owner, "GetUpperBound", null, + Expression.Constant(rank))); + + assignments.Add(currentLoopVariableAssignment); + assignments.Add(currentUpperBoundAssignment); + + Expression binaryExpression = Expression.ArrayAccess(stateMemberArray, + Expression.Constant(rank)); + Expression setIndexer = + Expression.Assign(binaryExpression, + rankParameters[rank]); - assignUpperParameters[rank] = Expression.Assign(upperBoundParameters[rank], - Expression.Call(owner, "GetUpperBound", null, Expression.Constant(rank))); + Expression setIndexerAndCallMethod = + Expression.Block(setIndexer, callExpression); var loopBody = Expression.Block( - Expression.IfThen( - Expression.Equal(upperBoundParameters[rank], rankParameters[rank]), - Expression.Goto(breakTarget)), - callExpression, - Expression.PostIncrementAssign(rankParameters[rank]), - Expression.Goto(continueTarget)); + Expression.IfThen( + Expression.GreaterThan(rankParameters[rank], upperBoundParameters[rank]), + Expression.Goto(breakTarget)), + setIndexerAndCallMethod, + Expression.PostIncrementAssign(rankParameters[rank]), + Expression.Goto(continueTarget)); callExpression = Expression.Loop(loopBody, breakTarget, continueTarget); } - BlockExpression climbBody = - Expression.Block(rankParameters.Concat(upperBoundParameters), - assignRankParameters.Concat(assignUpperParameters).Concat(new[] {callExpression})); - - Expression> lambda = - Expression.Lambda>(climbBody, - "Climb_" + runtimeType.Name, - new[] { processor, value }); - - ClimbDelegate result = lambda.Compile(); - - return result; + parameterExpressions.AddRange(rankParameters); + parameterExpressions.AddRange(upperBoundParameters); - throw new NotImplementedException("CreateArrayDelegate is not implemented"); + return callExpression; } } } \ No newline at end of file From c90baa8b0007561fec2fd3d8bca56637d2b4caa4 Mon Sep 17 00:00:00 2001 From: Elad Zelingher Date: Tue, 12 May 2020 08:06:45 -0400 Subject: [PATCH 3/6] Resetting the variable at the beginning of the inner loop --- src/GraphClimber.ConsoleApp/Program.cs | 2 +- .../ExpressionImplementation/ClimbDelegateFactory.cs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/GraphClimber.ConsoleApp/Program.cs b/src/GraphClimber.ConsoleApp/Program.cs index add8bbc..639cdc8 100644 --- a/src/GraphClimber.ConsoleApp/Program.cs +++ b/src/GraphClimber.ConsoleApp/Program.cs @@ -82,7 +82,7 @@ private static void SerializeDeserializeBinary() { BinaryFormatter formatter = new BinaryFormatter(); - var person = new Box{Value = new []{"abc", "abc", "abc"}}; + var person = new Box{Value = new [,]{{"abc", "abc", "abc"},{"2","3","4"}}}; //object person = GetPerson(); diff --git a/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs b/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs index a78989c..37bed6b 100644 --- a/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs +++ b/src/GraphClimber/ExpressionImplementation/ClimbDelegateFactory.cs @@ -143,8 +143,8 @@ private static Expression LoopArrayBounds for (int rank = ranks - 1; rank >= 0; rank--) { // Create a for loop from lowerBound to upperBound? - var breakTarget = Expression.Label("break"); - var continueTarget = Expression.Label("continue"); + var breakTarget = Expression.Label("break" + rank); + var continueTarget = Expression.Label("continue" + rank); // i_k = array.GetLowerBound(k) var currentLoopVariableAssignment = @@ -157,7 +157,6 @@ private static Expression LoopArrayBounds Expression.Call(owner, "GetUpperBound", null, Expression.Constant(rank))); - assignments.Add(currentLoopVariableAssignment); assignments.Add(currentUpperBoundAssignment); Expression binaryExpression = Expression.ArrayAccess(stateMemberArray, @@ -178,7 +177,9 @@ private static Expression LoopArrayBounds Expression.PostIncrementAssign(rankParameters[rank]), Expression.Goto(continueTarget)); - callExpression = Expression.Loop(loopBody, breakTarget, continueTarget); + callExpression = + Expression.Block(currentLoopVariableAssignment, + Expression.Loop(loopBody, breakTarget, continueTarget)); } parameterExpressions.AddRange(rankParameters); From 56cb5ada37d0070d5ae13c128a78e529fff66385 Mon Sep 17 00:00:00 2001 From: Elad Zelingher Date: Tue, 12 May 2020 08:26:17 -0400 Subject: [PATCH 4/6] TEnum : Enum --- .../Examples/Binary/BinaryReaderProcessor.cs | 2 +- .../Examples/Binary/BinaryWriterProcessor.cs | 2 +- .../ExpressionImplementation/EnumReadWriteDescriptor.cs | 8 ++++---- src/GraphClimber/ValueDescriptor/IEnumValueDescriptor.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs index 6729b02..0c5a947 100644 --- a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs @@ -283,7 +283,7 @@ private int[] ReadIntArray() public void ProcessEnumForWriteOnly<[IsEnum] TEnum, TUnderlying> (IEnumReadWriteExactValueDescriptor descriptor) where TUnderlying : IConvertible - where TEnum : IConvertible + where TEnum : Enum, IConvertible { IStateMember underlying = descriptor.UnderlyingValueStateMember; diff --git a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs index c96d85d..de343d0 100644 --- a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryWriterProcessor.cs @@ -142,7 +142,7 @@ public void ProcessArray<[IsArray]TArray>(IReadOnlyExactValueDescriptor public void ProcessEnumForReadOnly<[IsEnum]TEnum, TUnderlying> (IReadOnlyEnumExactValueDescriptor descriptor) where TUnderlying : IConvertible - where TEnum : IConvertible + where TEnum : Enum { WriteAssemblyQualifiedNameIfNeeded((BinaryStateMember)descriptor.StateMember, typeof (TEnum)); diff --git a/src/GraphClimber/ExpressionImplementation/EnumReadWriteDescriptor.cs b/src/GraphClimber/ExpressionImplementation/EnumReadWriteDescriptor.cs index 5735b56..6259ce9 100644 --- a/src/GraphClimber/ExpressionImplementation/EnumReadWriteDescriptor.cs +++ b/src/GraphClimber/ExpressionImplementation/EnumReadWriteDescriptor.cs @@ -5,7 +5,7 @@ namespace GraphClimber internal class EnumReadOnlyDescriptor : ReadOnlyDescriptor, IReadOnlyEnumExactValueDescriptor - where TRuntime : TField, IConvertible + where TRuntime : Enum, TField where TUnderlying : IConvertible { // TRuntime is Enum! @@ -29,7 +29,7 @@ internal class EnumWriteOnlyDescriptor : WriteOnlyDescriptor, IWriteOnlyEnumExactValueDescriptor where TUnderlying : IConvertible - where TField : IConvertible + where TField : Enum { // TField is Enum! public EnumWriteOnlyDescriptor(object processor, @@ -48,7 +48,7 @@ public void SetUnderlying(TUnderlying value) } public interface IEnumReadWriteExactValueDescriptor : IReadOnlyEnumExactValueDescriptor, IWriteOnlyEnumExactValueDescriptor - where TEnum : IConvertible + where TEnum : Enum, IConvertible where TUnderlying : IConvertible { } @@ -56,7 +56,7 @@ public interface IEnumReadWriteExactValueDescriptor : IReadO internal class EnumReadWriteDescriptor : ReadWriteDescriptor, IEnumReadWriteExactValueDescriptor - where TRuntime : TField, IConvertible + where TRuntime : Enum, TField where TUnderlying : IConvertible { // TRuntime is Enum! diff --git a/src/GraphClimber/ValueDescriptor/IEnumValueDescriptor.cs b/src/GraphClimber/ValueDescriptor/IEnumValueDescriptor.cs index 7f2f6e1..b04b033 100644 --- a/src/GraphClimber/ValueDescriptor/IEnumValueDescriptor.cs +++ b/src/GraphClimber/ValueDescriptor/IEnumValueDescriptor.cs @@ -14,7 +14,7 @@ public interface IEnumValueDescriptor public interface IReadOnlyEnumExactValueDescriptor : IEnumValueDescriptor, IReadOnlyExactValueDescriptor - where TEnum : IConvertible + where TEnum : Enum where TUnderlying : IConvertible { /// @@ -31,7 +31,7 @@ public interface IReadOnlyEnumExactValueDescriptor : public interface IWriteOnlyEnumExactValueDescriptor : IEnumValueDescriptor, IWriteOnlyExactValueDescriptor - where TEnum : IConvertible + where TEnum : Enum where TUnderlying : IConvertible { /// From d593566bce2597116ca9e333e6e82bee10533eee Mon Sep 17 00:00:00 2001 From: Elad Zelingher Date: Tue, 12 May 2020 08:34:27 -0400 Subject: [PATCH 5/6] When an enum is an object we force to convert it to an enum --- .../Examples/Binary/BinaryReaderProcessor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs index 0c5a947..dc6f09b 100644 --- a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs @@ -298,6 +298,9 @@ public void ProcessEnumForWriteOnly<[IsEnum] TEnum, TUnderlying> descriptor.Route(new BinaryStateMember(underlying, true, handled), descriptor.Owner, true); + + // TODO: weird + descriptor.Set(descriptor.Get()); } } } \ No newline at end of file From 2113e2f0aad6f7a44a7a22c45a8bdedc75c22db7 Mon Sep 17 00:00:00 2001 From: Elad Zelingher Date: Tue, 12 May 2020 12:43:11 -0400 Subject: [PATCH 6/6] Removing cast only if it is not a custom operator --- .../Examples/Binary/BinaryReaderProcessor.cs | 3 --- src/GraphClimber/ExpressionExtensions.cs | 12 +++++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs index dc6f09b..0c5a947 100644 --- a/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs +++ b/src/GraphClimber.ConsoleApp/Examples/Binary/BinaryReaderProcessor.cs @@ -298,9 +298,6 @@ public void ProcessEnumForWriteOnly<[IsEnum] TEnum, TUnderlying> descriptor.Route(new BinaryStateMember(underlying, true, handled), descriptor.Owner, true); - - // TODO: weird - descriptor.Set(descriptor.Get()); } } } \ No newline at end of file diff --git a/src/GraphClimber/ExpressionExtensions.cs b/src/GraphClimber/ExpressionExtensions.cs index fafcf3b..d2a1ecb 100644 --- a/src/GraphClimber/ExpressionExtensions.cs +++ b/src/GraphClimber/ExpressionExtensions.cs @@ -58,7 +58,8 @@ public static Expression Convert(this Expression expression, Type newType) var unaryExpression = expression as UnaryExpression; if (unaryExpression != null) { - if (unaryExpression.NodeType == ExpressionType.Convert) + if (unaryExpression.NodeType == ExpressionType.Convert && + !unaryExpression.IsCustomConversion()) { return Convert(unaryExpression.Operand, newType); } @@ -67,6 +68,15 @@ public static Expression Convert(this Expression expression, Type newType) return Expression.Convert(expression, newType); } + private static bool IsCustomConversion(this UnaryExpression unaryExpression) + { + Type conversionType = unaryExpression.Type; + Type originalType = unaryExpression.Operand.Type; + + return !(conversionType.IsAssignableFrom(originalType) || + originalType.IsAssignableFrom(conversionType)); + } + public static string FirstLowerCase(this string str) { return str.Substring(0, 1).ToLowerInvariant() + str.Substring(1);