adamped / xamarin.flutter

Running Flutter on Xamarin
MIT License
250 stars 39 forks source link

CSharpWriter: Mixin creation #3

Closed adamped closed 5 years ago

adamped commented 6 years ago

Create all mixin's as appropriate, including the method body implementations. Since Mixin's aren't available in C#, you will need to devise a method on how to implement them.

krdmllr commented 6 years ago

I would try to implement the following solution: If we take this simplified dart example

class A{}
class B{
    void Sample(){
        //Logic
    }
} 
class C extends A with B {}

The generated code woud look like this:

public class A{}

public interface IB{
    void Sample();
}
public class B : IB {
    public void Sample(){
        //Logic
    }
}  
public class C : A, IB{

    private B _bManager = new B();
    public void Sample(){
        _bManager.Sample();
    }
}
adamped commented 6 years ago

I think that approach will work. My concern is regarding the code in the dart methods, particularly when they go if (object is B), we would need to change that to if (object is IB). But in other areas they might be doing new B(); which means we would have to make sure we use B and just change everything to IB.

But in saying all that, I don't see when they would ever create a new instance of a Mixin by itself, but I suppose its certainly possible.

I say continue on with your approach for now, it seems like the best way forward.

JeroMiya commented 5 years ago

Looks like C# 8 will support interfaces with default implementations - maybe you could use those?

Otherwise, maybe take a look at the Scala compiler's implementation of multiple inheritance on the JVM, which uses abstract base classes and static methods in the generation. See this SO thread for a good explanation of the mechanics: https://stackoverflow.com/questions/7637752/using-scala-traits-with-implemented-methods-in-java

JeroMiya commented 5 years ago

@adamped @krdmllr My understanding of Dart is that every class definition is implicitly an interface. Could the problem be solved by generating an IClassName interface for all classes, with their publicly accessible members, and then replace all checks for if(object is B) with if(object is IB) even if not involved in a mixin? You may also need to replace all references to B in parameter lists, fields, etc... with IB as well. But since you do it globally rather than conditionally based on usage in a mixin, it might be easier to transform.

krdmllr commented 5 years ago

@JeroMiya we currently generate an interface for all mixins and abstract classes. Best would be to replace the class/interface solution with the default implementations of c# 8, but that feature is not available yet.

adamped commented 5 years ago

If only that C#8 interface implementation feature was complete. It would be saving me a large headache right now :)