Can I build a compiler plugin with a post processor to generate code from previous collected derived structs? - macros

As far as I know current usage for compiler plugin is to define the attribute for compiler to recognize and then the compiler will invoke the code defined and registered in the plugin.
I am thinking if it is possible to build a compiler plugin that have a post processor. I can some how first register the structs encountered by proc_macro_derive in a data structure within the plugin, then the post processor can generate code according to the plugin data structure populated before.
My intention is to generate a symbol table form derived structs, so I can do some experiment for dynamic typing in rust. I am not sure if it is possible to achieved in compile time without manually register them one by one in runtime.

Related

How to create a custom annotation processor for Eclipse

I'm trying to create a custom annotation processor that generates code at compilation time (as hibernate-jpamodelgen does). I've looked in the web, and I find custom annotation processors that works with maven, but do nothing when added to the Annotation Processing > Factory Path option. How could I create a processor compatible in this way? I have not found a tutorial that works.
My idea is to, for example, annotate an entity to generate automatically a base DTO, a base mapper, etc that can be extended to use in the final code.
Thank you all
OK, Already found out the problem. The tutorial I hda found out dint't specified that, in order to the compiler to be able to apply the annotation processor, there must be a META-INF/services/javax.annotation.processing.Processor file that contains the qualified class name of the processor (or processors).
I created the file pointing to my processor class, generated the jar and added it to Annotation Processing > Factory Path and all worked correctly.
Just be careful to keep the order of the processors correctly (for example, hibernate model generator claims the classes, so no more generation will be made after it), and change the jar file name each time you want to replace the library (it seems eclipse keeps a cache). These two things have given me a good headache.
Thanks all

How can I write a code generator in Ceylon

I want to write a code generator that generates a class based on the meta model of another ceylon class. I want the code generator to run at compile time. What is the best way for me to do this. I could probably accomplish this by writing a plugin for gradle or the ceylon build system but I'm hoping for a simpler solution. Unfortunately, I don't see any support for code generators in ceylon. Also, are there any plans for code generators in ceylon?
I want to write this code generator because I'm thinking about writing a simple web framework for ceylon that look at a class like the following using the meta-model:
controller
shared class Controller() {
shared void doSomething() => print("did it!");
}
I plan for it to be like Spring MVC. This framework would make a restful API from the Controller class that allows someone to write an AJAX call like this:
$http.get("/Controller/doSomething");
I want to make things more convenient, high level, and simple by doing something like GWT. I want to create a code generator that automatically generates a class like this:
shared class RemoteController() {
shared void doSomething() {
$http.get("/Controller/doSomething");
}
}
The RemoteController would be run in a user's browser as javaScript and allow client side ceylon code to do an Ajax call like this:
RemoteController().doSomething();
That would end up calling the Controller().doSomething() on the server so "did it!" would be printed.
AST Transformers have been proposed, but are still in the early design phase. For now, to do compile-time code generation, you’ll have to rig up something of your own.
To actually generate the code, I would recommend use of ceylon.ast and ceylon.formatter. The workflow would roughly be:
analyze source code –
either parse it with ceylon.ast (ceylon.ast.redhat::compileAnyCompilationUnit) and analyze it without typechecking,
or parse it using the compiler, run the typechecker, then convert it to ceylon.ast (ceylon.ast.redhat::anyCompilationUnitToCeylon), keeping the typechecker information using the new update hooks in the very soon upcoming 1.2.0 release
edit the source code AST to add your new code (using a custom ceylon.ast.core::Editor that injects new class definitions into the CompilationUnits), or perhaps create entirely new compilation units if the RemoteController lives in a different module
convert the ceylon.ast AST to a compiler AST and feed it into ceylon.formatter to turn the AST into code again (see here for an example of that)
Alternatively, if you integrate this into your build step, you could skip the ceylon.formatter part of step 3 and instead feed the converted compiler AST into the typechecker and rest of the compiler directly.

How to create a scala class based on user input?

I have a use case where I need to create a class based on user input.
For example, the user input could be : "(Int,fieldname1) : (String,fieldname2) : .. etc"
Then a class has to be created as follows at runtime
Class Some
{
Int fieldname1
String fieldname2
..so..on..
}
Is this something that Scala supports? Any help is really appreciated.
Your scenario doesn't seem to make sense. It's not so much an issue of runtime instantiation (the JVM can certainly do this with reflection). Really, what you're asking is to dynamically generate a class, which is only useful if your code makes use of it later on. But how can your code make use of it later on if you don't know what it looks like? For example, how would your later code know which fields it could reference?
No, not really.
The idea of a class is to define a type that can be checked at compile time. You see, creating it at runtime would somewhat contradict that.
You might want to store the user input in a different way, e.g. a map.
What are you trying to achieve by creating a class at runtime?
I think this makes sense, as long as you are using your "data model" in a generic manner.
Will this approach work here? Depends.
If your data coming from a file that is read at runtime but available at compile time, then you're in luck and type-safety will be maintained. In fact, you will have two options.
Split your project into two:
In the first run, read the file and write the new source
programmatically (as Strings, or better, with Treehugger).
In the second run, compile your generated class with the rest of your project and use it normally.
If #1 is too "manual", then use Macro Annotations. The idea here is that the main sub-project's compile time follows the macro sub-project's runtime. Therefore, if we provide the main sub-project with an "empty" class, members can be added to it dynamically at compile time using data that the macro sees at runtime. - To get started, Modify the macro to read from a file in this example
Else, if you're data are truly only knowable at runtime, then #Rob Starling's suggestion may work for you as it did me. I'll share my attempt if you want to be a guinea pig. For debugging, I've got an App.scala in there that shows how to pass strings to a runtime class generator and access it at runtime with Java reflection, even define a Scala type alias with it. So the question is, will your new dynamic class serve as a type-parameter in Slick, or fail to, as it sometimes does with other libraries?

Error with Groovy AST transformations when cleaning project in Eclipse

I'm trying to work through groovy's Implementing Local AST Transformations tutorial, but whenever I clean my project I get this error in each file that has the #WithLogging annotation in it:
Groovy:Could not find class for Transformation Processor AC.LoggingASTTransformation declared by AC.WithLogging
So you have a package named "AC" that contains both "WithLogging.groovy" and "LoggingASTTransformation.groovy" classes? Does it also contain any classes that implement the "WithLogging" interface?
If so, I'd suggest you move the class(es) that use your annotation to a location outside of the annotation defining package (the default will suffice, for diagnostic purposes) - Order of compilation matters with transformations. See this post on the groovy users mailing list for more on that.
Also try changing the annotation from #WithLogging to #AC.WithLogging.
As far as cleaning with Eclipse is concerned, I had a similar issue and found that I had to make a trivial modification after a clean to any file that contained my annotation. IE, add a space somewhere. Then save the file. This should rebuild everything properly.

I get new javascript every GWT compile without changing java source

GWT compiles the Java source into Javascript, and names the files according to a hash of their contents. I'm getting a new set of files every compile, because the javascript contents are changing, even when I don't change the source at all.
The files are different for OBF and PRETTY output, but if I set it to DETAILED, they're no longer different every compile. In PRETTY, I can see that all/most of the differences between compiles are in the value parameters for typeId. For example, a funciton called initValues() is called with different values for it's typeId parameter.
In PRETTY mode, the differences you see are allocation of Java Classes to TypeIds. It's how GWT manages run time type checking. You'll notice a table at the bottom of each script essentially mapping each typeId to all compatible superclasses. This is how GWT can still throw ClassCastException in JavaScript (though you should run into this very rarely!).
In OBF mode, the differences are due to the allocation of minified function names.
In both cases, it's due to the order the compiler is processing the code. Some internal symbol tables might be using a non-ordered collection store symbols for processing. It can happen for lots of reasons.
As far as I know, GWT will compile a new version every time you compile it, this is a feature ;)
You can use ant to control it though, so that it only builds the GWT section of your application if it's actually changed:
http://wiki.shiftyjelly.com/index.php/GWT#Use_The_Power_of_Ant_to_Build_Changes_Only