Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

implementor: Correct F# Event Identification #39

Closed
wants to merge 2 commits into from

Conversation

arfbtwn
Copy link
Contributor

@arfbtwn arfbtwn commented Jun 19, 2014

The MethodInfo.IsSpecialName property doesn't appear to be set true for
event add/remove methods produced with the F# compiler, even with the
[<CLIEvent>] annotation applied to the event.

This appears partly due to F#'s generalisation of the signature for
event handler delegate types, but also because we attempt to treat all
methods equally when implementing them.

This patch provides a quick hack to solve the problem with minimal
change to the TypeImplementor class.

The MethodInfo.IsSpecialName property doesn't appear to be set true for
event add/remove methods produced with the F# compiler, even with the
[<CLIEvent>] annotation applied to the event.

This appears partly due to F#'s generalisation of the signature for
event handler delegate types, but also because we attempt to treat all
methods equally when implementing them.

This patch provides a quick hack to solve the problem with minimal
change to the TypeImplementor class.
@arfbtwn
Copy link
Contributor Author

arfbtwn commented Jun 19, 2014

As I mention in the commit message above, this is essentially a quick hack to correct the behaviour in F#, a better solution can be found in #37.

This short test program demonstrates the problem on current master:

open System.Collections.Generic
open DBus

type StringVariantMap = Dictionary<string,obj>

type PropertiesChangedHandler = delegate of string * StringVariantMap * string[] -> unit

[<Interface ("org.freedesktop.DBus.Properties")>]
type IProperties =
    abstract member Get : string -> string -> obj 
    abstract member Set : string -> string -> obj -> unit
    abstract member GetAll : string -> StringVariantMap
    [<CLIEvent>]
    abstract member PropertiesChanged : IDelegateEvent<PropertiesChangedHandler>

let ofn = Bus.Session.GetObject<IProperties>("org.freedesktop.Notifications", new ObjectPath("/org/freedesktop/Notifications"))

leading to this output:

Unhandled Exception:
System.ArgumentException: Cannot create a struct with no fields
Parameter name: signature
            at DBus.Protocol.Signature.MakeStruct (Signature signature) [0x00000] in <filename unknown>:0 
            at DBus.Protocol.Signature.GetSig (System.Type type) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.SigsForMethod (System.Reflection.MethodInfo mi, DBus.Protocol.Signature& inSig, DBus.Protocol.Signature& outSig) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.GenHookupMethod (System.Reflection.Emit.ILGenerator ilg, System.Reflection.MethodInfo declMethod, System.Reflection.MethodInfo invokeMethod, System.String interface, System.String member) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.Implement (System.Reflection.Emit.TypeBuilder typeB, System.Type iface, System.String interfaceName) [0x00000] in <filename unknown>:0 
            at DBus.TypeImplementer.GetImplementation (System.Type declType) [0x00000] in <filename unknown>:0 
            at DBus.BusObject.GetObject (DBus.Connection conn, System.String bus_name, DBus.ObjectPath object_path, System.Type declType) [0x00000] in <filename unknown>:0 
            at DBus.Connection.GetObject (System.Type type, System.String bus_name, DBus.ObjectPath path) [0x00000] in <filename unknown>:0 
            at DBus.Connection.GetObject[IProperties] (System.String bus_name, DBus.ObjectPath path) [0x00000] in <filename unknown>:0 
            at <StartupCode$helloevents>.$Helloevents.main@ () [0x00000] in <filename unknown>:0 

Since the previous commit was a hack, and slightly questionable, this
one builds upon it by adding a class with two simple extension methods
for MethodBase objects; IsEvent and IsProperty.

They are used to ensure the correct branches are followed when
generating hookup methods for proxy classes since the IsSpecialName
property is unreliable on interfaces originating in F#.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant