rileywhite / cilador Goto Github PK
View Code? Open in Web Editor NEWFody weaver that provides powerful CIL manipulation tools, including C# mixin functionality
License: Apache License 2.0
Fody weaver that provides powerful CIL manipulation tools, including C# mixin functionality
License: Apache License 2.0
Currently mixin implementation fields that are initialized in their declaration silently lose their value on cloning. Add support for this
Specifically test mixin implementations and targets to ensure that they are not value types. Allow nested value types within the mixin implementation, however.
To reproduce, modify http://github.com/rileywhite/Bix.Mixers.Fody-Examples HelloMixin type like as follows, and attempt to compile.
public class HelloMixin : IHelloWorld
{
string IHelloWorld.Hello()
{
return "Hello World";
}
}
Error message follows.
Error 1 Fody: An unhandled exception occurred: Exception: Failed to resolve assembly: 'MyMixinDefinitions, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null' StackTrace: at Mono.Cecil.BaseAssemblyResolver.Resolve(AssemblyNameReference name, ReaderParameters parameters) at Mono.Cecil.DefaultAssemblyResolver.Resolve(AssemblyNameReference name) at Mono.Cecil.MetadataResolver.Resolve(TypeReference type) at Mono.Cecil.MetadataResolver.Resolve(MethodReference method) at Mono.Cecil.MethodReference.Resolve() at Bix.Mixers.Fody.ILCloning.RootContext.RootImportMethodOutsideOfSource(MethodReference method, TypeReference importedDeclaringType) in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\ILCloning\RootContext.cs:line 374 at Bix.Mixers.Fody.ILCloning.RootContext.RootImport(MethodReference method) in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\ILCloning\RootContext.cs:line 312 at Bix.Mixers.Fody.ILCloning.MethodCloner.CloneStructure() in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\ILCloning\MethodCloner.cs:line 82 at Bix.Mixers.Fody.ILCloning.ILCloningExtensions.CloneStructure(IEnumerable`1 cloners) in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\ILCloning\ILCloningExtensions.cs:line 36 at Bix.Mixers.Fody.ILCloning.TypeCloner.CloneStructure() in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\ILCloning\TypeCloner.cs:line 88 at Bix.Mixers.Fody.InterfaceMixins.InterfaceMixinCommandMixer.Execute() in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\InterfaceMixins\InterfaceMixinCommandMixer.cs:line 115 at Bix.Mixers.Fody.InterfaceMixins.InterfaceMixinCommand.Mix(IWeavingContext weavingContext, TypeDefinition target, CustomAttribute mixCommandAttribute) in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\InterfaceMixins\InterfaceMixinCommand.cs:line 122 at Bix.Mixers.Fody.Core.ModuleWeaver.FindAndInvokeMixCommands(TypeDefinition targetType, List`1 mixCommandAttributes) in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\Core\ModuleWeaver.cs:line 411 at Bix.Mixers.Fody.Core.ModuleWeaver.Execute() in c:\Users\Riley\Documents\GitHub\Bix.Mixers.Fody\src\Bix.Mixers\Fody\Core\ModuleWeaver.cs:line 336 at lambda_method(Closure , Object ) at InnerWeaver.ExecuteWeavers(List`1 weaverInstances) in c:\TeamCity\buildAgent\work\7495521761d392b9\FodyIsolated\InnerWeaver.cs:line 90 at InnerWeaver.Execute() in c:\TeamCity\buildAgent\work\7495521761d392b9\FodyIsolated\InnerWeaver.cs:line 31 Source: Mono.Cecil TargetSite: Mono.Cecil.AssemblyDefinition Resolve(Mono.Cecil.AssemblyNameReference, Mono.Cecil.ReaderParameters) MyApplicationLibrary
Currently when a mixin implementation's default constructor contains logic, it is silently lost. Check for this, and raise an error. It is still not supported, but there should be feedback given to the user.
Allow mixin implementations to have code within a parameterless constructor, and ensure that code runs within every constructor in the mixin target.
Reproduce: Create generic nested type within mixin implementation. Create property with type of a generic parameter. Set the property in the nested type's constructor.
With the 0.2.0 modification to rely on on-demand target creation rather than carefully ordered target creation, sometimes source generic property and method references, which are new objects rather than references, are created after the target is created but before the target is fully cloned, meaning that details are still missing.
Need to find a way to delay generic type and method creation until after the generic target is fully cloned.
The interface must support being closed in the configuration or within the implementation, and itmust also support being left open. It must also be possible for the implementation to specify a rule for discovering generic arguments at code-weaving time.
Fody Version 2 is out and you will need to do an update for your addin to be usable with it
Specifically:
Please ping me if u need help
Support mixin implementation type initializers. Ensure that mixin targets run mixin implmentation type initializer code.
Variables are often referenced by index rather than by variable definition. Indexes need shifted when mixing a variable initialization that creates a local variable, such as when using object initialization, and when the target has constructors that also have local variables.
When this happens, the mixed assembly will be invalid.
Ensure that try/catch/finally blocks are mixed correctly.
When at least one class is using a mixin, attributes start going missing from various methods.
The classes do not have to be making use of a mixin for them to be affected.
If an affected method is removed, a new method is affected.
So far, it seems that its an all or nothing lost, each affected method looses all of its attributes if there was more than one present.
Looking at the IL of the generated assembly, the attributes are missing from the affected methods.
I am using .Net 4.5, latest from NuGet as of 5/2/2014:
Fody 1.23.2 net45
Bix.Mixers.Fody 0.1.1.0 net45
I am able to reproduce this using simple classes on a program that lists methods and the System.ComponentModel.DescriptionAttribute on a series of classes.
Mixins:
public interface IMixinInterface
{
void MixinMethodA();
void MixinMethodB();
void MixinMethodC();
}
public class MixinImplementation : IMixinInterface
{
[Description("This is MixinMethodA, implemented via a Mixin")]
public void MixinMethodA()
{
}
[Description("This is MixinMethodB, implemented via a Mixin")]
public void MixinMethodB()
{
}
[Description("This is MixinMethodC, implemented via a Mixin")]
public void MixinMethodC()
{
}
}
Main project:
[InterfaceMixin(typeof(IMixinInterface))]
class MixinTargetClass
{
[Description("This is PrimaryMethodA, implemented directly")]
public void PrimaryMethodA()
{
}
[Description("This is PrimaryMethodB, implemented directly")]
public void PrimaryMethodB()
{
}
[Description("This is PrimaryMethodC, implemented directly")]
public void PrimaryMethodC()
{
}
}
public class NonMixinClass
{
[Description("This is Method A")]
public void MethodA()
{
}
[Description("This is Method B")]
public void MethodB()
{
}
[Description("This is Method C")]
public void MethodC()
{
}
[Description("This is Method D")]
public void MethodD()
{
}
}
public static class Program
{
private static Type[] Targets =
{
typeof(NonMixinClass),
typeof(MixinTargetClass),
};
public static void Main(string[] args)
{
foreach (var target in Targets)
{
Console.WriteLine("Methods in class {0}", target.Name);
WriteMethods(target);
}
Console.ReadKey();
}
private static void WriteMethods(Type target)
{
// Skip Equals, ToString, GetHashCode
foreach (var method in target.GetMethods().Where(x => x.DeclaringType == target))
{
Console.WriteLine(" {0}", method.Name);
Console.WriteLine(" {0}", GetMethodDescription(method));
}
}
private static string GetMethodDescription(MethodInfo method)
{
var attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(method, typeof (DescriptionAttribute));
if (attribute == null)
{
return "<No Description>";
}
return attribute.Description;
}
}
Weavers
<Weavers>
<Bix.Mixers>
<bmfc:BixMixersConfig xmlns:bmfc="urn:Bix:Mixers:Fody:Config">
<MixCommandConfig d4p1:type="bmfc:InterfaceMixinConfigType" xmlns:d4p1="http://www.w3.org/2001/XMLSchema-instance">
<InterfaceMixinMap Interface="Mixins.IMixinInterface, Mixins"
Mixin="Mixins.MixinImplementation, Mixins"/>
</MixCommandConfig>
</bmfc:BixMixersConfig>
</Bix.Mixers>
</Weavers>
When ran, the output is
Methods in class NonMixinClass
MethodA
This is Method A
MethodB
This is Method B
MethodC
This is Method C
MethodD
<No Description>
Methods in class MixinTargetClass
PrimaryMethodA
<No Description>
PrimaryMethodB
This is PrimaryMethodB, implemented directly
PrimaryMethodC
This is PrimaryMethodC, implemented directly
MixinMethodA
This is MixinMethodA, implemented via a Mixin
MixinMethodB
This is MixinMethodB, implemented via a Mixin
MixinMethodC
This is MixinMethodC, implemented via a Mixin
Notice how NonMixinClass.MethodD and MixinTargetClass.PrimaryMethodA were reported as not having the attribute.
If the Fody build step is disabled, or the InterfaceMixin attribute is removed from MixinTargetClass, the result is correct and the methods now have their attributes:
Methods in class NonMixinClass
MethodA
This is Method A
MethodB
This is Method B
MethodC
This is Method C
MethodD
This is Method D
Methods in class MixinTargetClass
PrimaryMethodA
This is PrimaryMethodA, implemented directly
PrimaryMethodB
This is PrimaryMethodB, implemented directly
PrimaryMethodC
This is PrimaryMethodC, implemented directly
Initialized statid fields are not supported. This should have been included with support for instance fields.
Still researching
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.