This is mostly for Stephane and Tom, but anyone else who has any ideas is welcome to comment of course.
native shared class NativeHeader(variable Integer b, Integer c) {
native shared String meth() => "Native header method ``nbm()``";
native shared String attr => "Native header attribute ``nba``";
native String nbm();
native String nba;
}
native("jvm") shared class NativeHeader(variable Integer b, Integer c) {
native("jvm") String nbm() => "``b++``:``c``";
native("jvm") String nba => "``b++``:``c``";
}
native("js") shared class NativeHeader(variable Integer b, Integer c) {
native("js") String nbm() => "``b++``,``c``";
native("js") String nba => "``b++``,``c``";
}
which is giving me problems on the JVM side because of the way I decided to implement this feature.
So first I'll explain how this is handled now. In the beginning I just ignored native headers (and I still do when they are methods or attributes) using them only as a template against which the implementations were checked (all signatures have to be exactly the same).
But as you can see a native header can have a default implementations for its native members (see "meth()" and "attr") which meant that they need to exist somewhere.
So what I decided to do was to create a hidden super class with a "$header" suffix which would look something like this:
abstract public class NativeHeader$header {
private long b;
private final long c;
public NativeHeader$header(long b$param, long c) {
this.b = b$param;
this.c = c;
}
public String meth() { return "Native header method " + nbm$priv(); }
public String getAttr() { return "Native header attribute " + getNba$priv(); }
abstract private String nbm$priv();
abstract private String getNba$priv();
}
and an implementation that would subclass it like this:
public class NativeHeader extends NativeHeader$header {
public NativeHeader$header(long b$param, long c) {
super(b$param, c);
}
private String nbm$priv() { return "" + b++ + ":" + c; }
private String getNba$priv() { return "" + b++ + ":" + c; }
This works for simple cases but as you can see in the above code it won't work for anything slightly more complex because anything non-"shared" is always made "private" in the generated Java code.
So to make this work I'd need to remove all the "private" modifiers in the header and make sure I skip anything in the subclass that was already defined in the header.
The problem I see with this is that the generated class would be quite a bit different from what we normally generate and I just can't really foresee the problems this might cause in more complex cases.
So I thought of a different way to go about this problem and that is to not generate this special hidden header class but to generate just a single class using basically a merge of the header and its implementation.
We can do that because right now the header and its implementations must be in the same source file because I couldn't figure out the class-loading requirements for incremental compilation.
The problem I see with that particular solution is that the requirement for header and implementation to be in the same source file would be fixed forever, there would be no way to ever do incremental compilation (because the header would not really exist except in code).
So I hope this makes somewhat sense to you guys and you have some opinion on this you'd like to share.
-Tako