I have created https://issues.apache.org/jira/browse/GROOVY-11291 for
this topic
@OZ: Please feel free to add your angle to the ticket G-)
Cheers,
mg
On 18/01/2024 23:18, MG wrote:
Hi Jochen,
1. For our case we would not need to have obsolete class files to be
deleted, just that no (typically closure) class files be generated
with a different name, even though they are identical to existing
ones.
1. IntelliJ also does not (at least reliably) remove unused
classes even when doing a rebuild all, we always wipe the out
dir completely for that reason from time to time...
2. ...rsyncing the result to the server then removes unused
classes there too.
3. But since this does not influence turnaround times, it does
not bother us.
2. From what Jochen says, avoinding regenerating classes needlessly
with a different name seems at least in theory possible through
some sort of hashing mechanism.
3. From the top of my head: An alternative might maybe be to not
number the closure classes, but to use the the hash value as part
of their name, so that unchanged classes automatically keep the
same name.
1. This would make the names less readable, but more
deterministic, but would require collision avoidance if two
hashes collide...
2. ...but might also allow for closure class sharing (maybe
useful for small collect/forEach closures ?).
Cheers,
mg
On 16/01/2024 12:42, Jochen Theodorou wrote:
Am 15.01.24 um 20:24 schrieb o...@ocs.cz:
Jochen,
On 15. 1. 2024, at 10:35, Jochen Theodorou <blackd...@gmx.org> wrote:
If the goal is to give Groovyc a source file and let it compile that,
but write only certain files... well that is something that could be
worked out.
Well I don't know.
Theoretically, it would be nice if the compiler wrote only those
.classes, which did change from the previous compilation.
I might be overlooking something of importance, but I fear that
would be pretty difficult, at the verge of impossible. I guess the
solution might be found somewhere nearby creating some hash of the
last generated code, stored in .class, checking when building and
not re-writing the .class if unchanged... am not sure whether
feasible at all.
Assume the following Java-like
import static Foo.bar
class BarExec {
public Runable getExec() {
return new Runable() {
public void run(){ bar() }
}}}}
So basically this wraps a call around Foo.bar, in way you would not do
it anymore these days, but this is just for illustration. So assume my
change now is replacing the import and import Foo.bar2 instead of
Foo.bar. Because the method is called in the anonymous class in getExec
the minimum we need to do is recompile BarExec$1. BarExec does not need
recompilation, even though the code we changed is not even directly in
the inner class. That kind of problem makes it really difficult to do
any kind of partial compilation
But the idea with a hash (where we compile the whole file) sounds
possible to me.
This is not really incremental compilation like we may know
it from eclipse-java though.
I've tried to use the Eclipse thing and it was terrible enough (not
just due to unreliable incremental build; a plethora of other
problems, GUI ugly as hell, contra-intuitive and completely
non-ergonomic, slow and crashing pretty often) that I spent a
non-trivial time writing my own scripts and even an external EOF
model editor to be able to use Xcode to build my WebObjects/Groovy
applications :)
yeah, Eclipse has its weaknesses
Anyway I would be contented with a build system which
- never tries to re-compile sources which did not change after the
previous build (this works with my scripts all right)
- reliably re-builds all the classes generated by a source changed
after the previous build (this works with my scripts all right)
- reliably deletes classes which were created by the previous build,
but do not exist anymore with the current one (and this, alas, my
scripts do not support properly yet).
to know what files we would create we would have to do a complete
compilation process except the actual writing of files. Under the
assumption of a class Foo will produce a number of class files
Foo($.+)*.class we could then in theory identify which files for Foo are
then surplus. But if you for example deleted Bar.groovy, then we do not
have a Bar.groovy to find out that we do not need Bar.class and
Bar$1.class anymore. For this we would have to compile all source files,
though we would not have to create the class files of course.
Now what do you understand under re-compile? process the source like in
a normal compilation and write out the result, or does it not matter if
the result is written out? If the later does not matter, then
determining the list of unused top-level classes conflicts with the idea
of re-compiling only files that did not change. This is also because in
Groovy a source file can contain any number of top level classes, it
does not even have to contain a class that is similar to the name of the
file.
But of course if you say you want the fixed relationship of one file
containing one class and its inner classes, then this is actually
solvable. For example if there is a bar.class but not bar.groovy we can
delete bar.class. Or if there is bar.class bar$1.class and bar$2.class
and if bar was changed, then any bar class file with a time from before
the last compilation can be deleted.
I understand Eclipse and other Java-related IDEs do this completely
wrong, for they naïvely assume an XXX.source always generates just
XXX.class. I might be wrong of course — for years I happily use
Xcode plus my scripts and haven't touched those other IDEs by a
ten-foot pole; perhaps they improved meantime :)
IDEs usually know that there can be more. At least inner classes for the
Java case. Well... they all got even more memory hungry mostly.
Sometimes it is interesting to work with something like vscode for
example. It makes a more lean impression... but in the end it is similar
bad in terms of memory consumption once you start adding plugins. If you
are happy with xcode, stay with xcode ;)
bye Jochen
bye Jochen