eclipse-jdt / eclipse-jdt/eclipse.jdt.core

Batch compiler and generation of sources during annotation processing

Open
#1,482 2 comments 1 reaction 0 assignees View on GitHub
Dominant language
Java
Stars
237
Forks
195
Avg merge
1d 10h
Merged PRs (30d)
49

Description

The batch compiler, which is bundled in `ecj.jar`, works under the assumption that no generated source files will exist prior to annotation processing (so called *clean state*). This prevents it from being used in any other setting than a *clean build*.
This violates the `javax.annotation.processing.Filer` interface, which says:
> During each run of an annotation processing tool, a file with a given pathname may be created only once. If that file already exists before the first attempt to create it, the old contents will be deleted ...

From `org.eclipse.jdt.internal.compiler.apt.dispatch.BatchFilerImpl`:
```java
public JavaFileObject createSourceFile(CharSequence name, Element... originatingElements) throws IOException {
// ... omitted code that extracts type element name
TypeElement typeElement = this._env._elementUtils.getTypeElement(name);
if (typeElement != null) { // *** why?
throw new FilerException("Source file already exists : " + moduleAndPkgString); //$NON-NLS-1$
}
Location location = mod == null ? StandardLocation.SOURCE_OUTPUT : this._fileManager.getLocationForModule(StandardLocation.SOURCE_OUTPUT, mod);
JavaFileObject jfo = this._fileManager.getJavaFileForOutput(location, name.toString(), JavaFileObject.Kind.SOURCE, null);
URI uri = jfo.toUri();
if (this._createdFiles.contains(uri)) {
throw new FilerException("Source file already created : " + name); //$NON-NLS-1$
}

this._createdFiles.add(uri);
// hook the file object's writers to create compilation unit and add to addedUnits()
return new HookedJavaFileObject(jfo, jfo.getName(), name.toString(), this);
}
```
It can be seen that, under this implementation, if the file already exists before the first attempt to create it, an exception will be thrown instead of the old contents being deleted.

P.S. I attempted a workaround in my own annotation processor that deleted the source file before creating it, but to no avail, since the said source file was still accessible in the processing environment.

Contributor guide

Open the contributing guide

Research direction

Start in org.eclipse.jdt.internal.compiler.apt.dispatch.BatchFilerImpl, especially createSourceFile, and compare its existing-file check with the javax.annotation.processing.Filer contract quoted in the issue. Reproduce batch annotation processing with a pre-existing generated source, then verify that the behavior matches the contract without breaking the existing created-files check.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system, compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.