I think the IDE setup can be improved. I didn't take at shot at this yet. 2017-12-27 13:22 GMT+01:00 Jochen Theodorou <blackd...@gmx.org>:
> On 27.12.2017 10:04, Cédric Champeau wrote: > [...] > >> The consequence, however, is that any change to a Java class in Groovy >> core is going to produce a different compiler. >> > > This is fine in the IDE, as long as I do not have to bootstrap > immediately... which I do not have to. > > But I must say the IDEA setup is still annoying as hell. I freshly > generated the modules and ended up with a project I cannot compile, because > of the examples. I then switched to build, but ignore errors, which > resulted in my main (FileSystemCompiler, GroovyMain) classes not being > found, because they have not been compiled and I did not add the Groovy > global lib. Then I added the bootstrap and while the main classes now have > been found, they have been of course from the bootstrap, not the source. I > will always have to have a really, really, really good look at things to > see if I am using bootstrap or not. I mean imagine you remove a class and > then run from the IDE to see if your test still works. And it will, because > the damn class is still in the bootstrap jar, which of course you did not > create a new one. I easily lost more than half a day just trying to setup > things again. Together with the installation and fixing of intellij > itself... that was no fun day at all and lost time for Groovy development. > > For Gradle, which is aware of inputs/outputs, it means that the compiler >> has changed, and that it needs to recompile downstream consumers >> (subprojects) and, of course, re-execute their tests. This is the _correct >> behavior_. Gradle is right to do so, because the compiler has changed, so >> the bytecode generated might be different, but also since Groovy provides a >> runtime, it also needs to re-execute the tests because the runtime has >> changed. >> >> What I explain is also true of the other tasks we use, like groovydoc, or >> docgenerator. >> > > that part is perfectly fine. > > Now, let me explain why changing the strategy to use compiler N-1 is not >> necessarily a good idea for us: as I explained, Groovy also comes with a >> runtime. Say that in Groovy 3, we decide to get rid of call site caching, >> to only use invokedynamic. Then it means that the runtime of Groovy 3 will >> no longer include call site caching. However, the Groovy classes of the >> compiler would have been compiled with call site caching, so a _consumer_ >> of the compiler would fail, because those classes would no longer be there >> at runtime! >> >> Of course one might say "then you can use the invokedynamic version" of >> Groovy to compile Groovy 3, which leads to the last bit of complexity of >> our build. >> > > What you normally do is compiler with N-1 to get a compiler for N' and > then use that compiler to get the real N. Very common strategy. Of course > that means in a build where we would depend on an older release (N-1), we > not be able to use features in the new version (N') before we have created > N', which can actually compile the new features. And only then N could be > compiled using the new features from N'. Using Java is kind of like saying > we stay with N'. So there are pros and cons to this approach, it surely > does not make things more easy from the build side. It would make the > program code more easy and would be better in terms of "eat you own dog > food". > > what me really prevents from doing something like this is that the static > compiler has to many fallbacks to dynamic code where I do not want them. > > Some would have noticed that we now have a "testAll" task for each >> project. This task executes tests with the "indy" version of the compiler. >> Which means that in practice, we produce 2 versions of the compiler, not >> just one. This was the main reason for the complexity of the previous >> build, that I recently got rid of by using a different strategy and >> leveraging the Gradle build cache. So, instead of using the same outputs >> for both compilers, they are now separate, and we can run the tests in 2 >> flavors. The consequence is that tests are executed twice (one for `test`, >> the other for `testWithIndy`), but the outcome is much cleaner. >> >> I hope this clarifies things a bit. Now for daily development, you can >> use: >> >> ./gradlew :test : will only execute the call site caching version of >> tests for the "core" project >> ./gradlew :testWithIndy : will only execute the indy version of tests for >> the "core" project >> ./gradlew :testAll : will execute both flavors of tests (indy and non >> indy) for the "core" project >> >> And of course you can do the same for any subproject: >> >> ./gradlew :groovy-xml:test >> >> You can also choose precisely which test to execute by adding `--tests >> *MyTest*` to the command line. >> > > testAll and testWithIndy I did not realize,thanks. > > bye Jcohen >