On Wed, Jul 29, 2020 at 6:41 PM Jonathan Gibbons < jonathan.gibb...@oracle.com> wrote:
> > On 7/29/20 5:49 AM, Christian Stein wrote: > > I wonder whether the logic at [1] is a) the sole place that > > controls this feature and b) whether it can be enhanced > > to also prune stale classes from previous javac runs. > > That should be the only place. > > The minor complication about pruning stale classes is that > it is not a 1-1 mapping from .java to .class files, and that for > a perfect job, you have to read the .class file to determine the > likely origin of the .java file. Are you referring to the optional "SourceFile Attribute" as described in JVMS 4.7.10? If yes, I hoped to learn about a mandatory information within the class file format that hints to its origin/compilation unit. The current implementation uses "inferBinaryName". That method returns a single value - which doesn't account for multiple types being declared in a single compilation unit: for example, a Foo.java file may (but should not) produce Bar.class and Baz.class, correct? Local experiments support this observation, as the timestamp check is not performed when the source file name and the inferred class file name(s) don't match. Meaning, Foo.java is always added to the list of "to be compiled files" as there's no Foo.class in the destination directory. So, an outline of more correct implementation could like this: a) scan each .java files for type declarations to determine all .class files being produced b) collect those .class files c) check whether .java files need to be compiled, if yes, add them to fileObjects list d) prune all .class files from the destination directory that are not collected by step b) I bet, the parsing work as described in a) will need some more CPU cycles compared to the "inferBinaryName" -- but the gain would be a more correct behaviour of javac when used with `--module` option.