Generate Silver Type Declarations programatically

Hi guys,

My task is to generate Silver definitions for Cooper’s jar files just like what Fire does when you Goto Definition.

I digged into what Frameworks Fire is using and I seemed to find SilverCodeProvider from RemObjects.Elements.CodeDom which seems to be responsible for Silver code generation, but I couldn’t figure out how to create a CodeCompileUnit for any .jar file. I also tried loading the solution with RemObjects.EBuild.EBuildSolution but it hits object reference is not set to an instance to the object when calling constructor with solution path.

Can you please point out how can I achieve this?
I also found https://github.com/remobjects/ROCodeGen, but not sure where to start with it?

You’ll wanna use CodeGen4, not ROCodeGen; the latter is specific tom Remoting SDK (it too builds on CodeGen4).

@mh: Thanks, Any suggestion how I can load parse .class files from .jar in it? Supposedly there should be some way how make some CodeDom from it right? And then I see something like CodeDomToCG4?

Hm, no idea. you’ll probably on your own with that and will need to go by whatever format jars have, which is probably documented somewhere. I know its a zip container of .class files, but i’m not sure how those files are structured. @ck might have pointers for you on how he does it for the compiler.

@mh, @ck: Fire somehow generates nice Silver definitions. Is there any way I can use the .dlls you use in Fire to do this?

I need the consistency for having exactly the same definitions as Fire presents, so that I can then generate the apple swift’s dummy frameworks that will provide the same typings, but accessible in apple’s swift, so that Xcode code completion can be leveraged. The differences between Silver and Swift will then be highlighted with Swift Linter that won’t allow writing something Silver will not accept.

Good question. these apis aren’t easy to access (and prone to change as we don’t want to hardcode the interface to this).

you can use CodeGen4 for that. it’s why fire uses. you just need to provide the input.

@ck, @mh. Thanks for the feedback.
Do you think there is a way you can provide some example how this might be achieved with current API?

I see what CodeGen4 can do. But for the input there should be something like a CodeDom generated after jar classes gets parsed with Elements Compiler Toolchain. This is something I don’t understand how to achieve.

I struggled with API in RemObjects.EBuild.*
I found the following in RemObjects.EBuild.Elements. The EbuildTask called ElementsResolveReferencesForTarget -> I suspect this can provide the objects that denote references along with symbol it exposes that I guess I will be able to then feed to CodeGen4. However I was not able to create EBuildSolution and EBuildProject -> when calling

var appPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
appPath += "/Silver/LakestoneCore.Android/LakestoneCore.Android.elements";
var url = Url.UrlWithFilePath____isDirectory(appPath, false);
var proj = new EBuildProject(url);

it will initialize the empty project without parsing all data like targets and so on.

If you can suggest any way I can generate the same what Fire does when pressing ‘Go To Definition’ I will be very happy, so far the raw alternative is loading classes from dex at runtime and getting all its API/types with reflection but I don’t think this is a proper approach in this case.

@mh, @ck:
Ok, solved, I just parse the .class files directly with http://commons.apache.org/proper/commons-bcel/apidocs/org/apache/bcel/classfile/ClassParser.html.

2 Likes

No, this does noting like this, and it’s not code you should be using or relying on (and most importantly, aren’t really licensed to distribute ;), as it’s part of the elements core compiler chain. (it’s also still beta and not actually used by the production compiler, at this stage.

That said, it also doesn’t even do what you want to do. ElementsResolveReferences* is used for locating references (i.e. jars, dlls) by name during build; it does nothing to process the contents of them.

Got it thanks, yeah that’s true.