jimmmeh / runsharp

Automatically exported from code.google.com/p/runsharp
MIT License
0 stars 0 forks source link

Implicit interface implementations not working for methods with parameters #6

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
This only happens to the setter, getter was fine. To reproduce the error:

    public interface IProperty
    {
        int Bar { get; set; }
    }

    class InterfacePropertyBug
    {
        public static void GenFoo(AssemblyGen tg)
        {
            TypeGen g = tg.Public.Class("InterfacePropertyBug.Foo",
typeof(object), typeof(IProperty));
            {
                FieldGen bar = g.Private.Field(typeof (int), "_bar");
                g.Public.SimpleProperty(bar, "Bar");
            }
        }
    }

And below is the stack trace. BTW it was working fine in 0.1.1 alpha.

System.NotImplementedException was unhandled
  Message="Method 'Void set_Bar(Int32)' of interface
'ConsoleApplication1.IProperty' is not implemented"
  Source="TriAxis.RunSharp"
  StackTrace:
       at TriAxis.RunSharp.TypeGen.Complete() in
R:\runsharp\RunSharp\TypeGen.cs:line 666
       at TriAxis.RunSharp.AssemblyGen.Complete() in
R:\runsharp\RunSharp\AssemblyGen.cs:line 257
       at TriAxis.RunSharp.AssemblyGen.Save() in
R:\runsharp\RunSharp\AssemblyGen.cs:line 242
       at ConsoleApplication1.Program.Main(String[] args) in
R:\runsharp\ConsoleApplication1\Program.cs:line 35
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()

Original issue reported on code.google.com by kenne...@gmail.com on 29 Oct 2009 at 3:05

GoogleCodeExporter commented 8 years ago
Issue 6 and 7 are related. This is because ProcessAttributes is called in the
constructor of MethodGen. At that time, due the the new way of specifying the
parameter, no parameter exists yet.

In the ProcessAttributes, it try to match the current method with interface, it 
won't
match for any method actually takes parameter(s).

I can see two solutions to this:
 1. The Method() call should return an intermediate type instead of MethodGen, say
MethodDef, MethodDef parameter definitions, not MethodGen. And MethodDef should 
have
implicit conversion to MethodGen and CodeGen. That way, when the MethodGen
constructor is invoked, method signature is final.
 2. Drop off the new parameter syntax. Introduce something like below example, I
actually like this approach better and I'll explain why.

g.Public.Method<ReturnType>("MethodName", Parameter.In<int>("p1"),
Parameter.Out<string>("p2"));

The overloads are:
MethodGen Method(Type returnType, string methodName, params Parameter[] 
parameters);
MethodGen Method<T>(string methodName, params Parameter[] parameters);

And in Parameter

public class Parameter {
  public Parameter(Type type, string name) : Parameter(type, name, Direction.In) {}
  public Parameter(Type type, string name, Direction d) { ... }
  // ParameterInfo has type name and direction. 
  // This is very useful when you are implementing an interface by reflecting it.
  public Parameter(ParameterInfo pi) { ... }

  public static In(Type type, string name) { ... }
  public static In<T>(string name) { ... }
  public static Out(Type type, string name) { ... }
  public static Out<T>(string name) { ... }
  public static Ref(Type type, string name) { ... }
  public static Ref<T>(string name) { ... }
  public static From(ParameterInfo pi) { ... }
}

Original comment by kenne...@gmail.com on 29 Oct 2009 at 4:55

GoogleCodeExporter commented 8 years ago
OK, so let me explain why I prefer 2nd option. I'm writing code to dynamically 
create
a decorator based on any interface. I use reflection to get all the members of 
an
interface and implements each member by delegating the call down to the target
instance. And sure I do something more before and/or after the call. With the 
new
.Parameter() approach, it is very cumbersome to do this.

The new proposed approach works for both manually specified parameters or
programmatically generated ones.

Original comment by kenne...@gmail.com on 29 Oct 2009 at 5:27

GoogleCodeExporter commented 8 years ago
Hi,

can you please provide an example on how cumbersome it can get with the new 
syntax? I may have 
missed something, but I don't see that much difference between the two, other 
than that with 
the 'provide all parameters at once' approach you have to create some 
intermediate array of 
parameters.

The bug itself can be fixed rather easily by simply moving the 
PreprocessAttributes call to 
CreateMember(), where it should have been from the beginning.

Thanks & Regards,
Stefan

Original comment by StefanSi...@gmail.com on 22 Dec 2009 at 11:08

GoogleCodeExporter commented 8 years ago

Original comment by StefanSi...@gmail.com on 22 Dec 2009 at 11:09

GoogleCodeExporter commented 8 years ago
Issue 7 has been merged into this issue.

Original comment by StefanSi...@gmail.com on 22 Dec 2009 at 11:10

GoogleCodeExporter commented 8 years ago

Original comment by StefanSi...@gmail.com on 22 Dec 2009 at 11:34