Skip to content

Commit a1d4ed6

Browse files
nakamura-toclaude
andauthored
Optimize annotation processor I/O operations and improve environment compatibility (#1368)
* refactor: Optimize validateUnusedSqlFiles to reduce unnecessary I/O operations Replace nested loops with stream operations and add early returns to avoid redundant file system access when there are no query files to validate. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> * refactor: Improve resource handling for environments without directory path support - Add canAcceptDirectoryPath check to prevent directory operations when not supported - Make JavaFileManager location configurable with fallback to CLASS_OUTPUT - Skip unused SQL file validation when directory paths cannot be accepted 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent 52c679d commit a1d4ed6

File tree

3 files changed

+76
-29
lines changed

3 files changed

+76
-29
lines changed

doma-processor/src/main/java/org/seasar/doma/internal/apt/ProcessingContext.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import javax.annotation.processing.RoundEnvironment;
2121
import javax.lang.model.util.Elements;
2222
import javax.lang.model.util.Types;
23+
import javax.tools.JavaFileManager;
24+
import javax.tools.StandardLocation;
2325

2426
public class ProcessingContext {
2527

@@ -38,25 +40,32 @@ private void init() {
3840
if (initialized) {
3941
throw new AptIllegalStateException("already initialized");
4042
}
43+
var envClassName = env.getClass().getName();
44+
var isRunningOnEcj = envClassName.startsWith("org.eclipse.");
45+
var resourceDir = env.getOptions().get(Options.RESOURCES_DIR);
46+
var canAcceptDirectoryPath = isRunningOnEcj || resourceDir != null;
47+
var location = determineLocation(isRunningOnEcj);
48+
4149
reporter = new Reporter(env.getMessager());
4250
resources =
4351
new Resources(
44-
env.getFiler(),
45-
reporter,
46-
env.getOptions().get(Options.RESOURCES_DIR),
47-
isRunningOnEclipse(env),
48-
isDebug(env));
52+
env.getFiler(), reporter, resourceDir, canAcceptDirectoryPath, location, isDebug(env));
4953
options = new Options(env.getOptions(), resources);
5054
initialized = true;
5155
}
5256

53-
private boolean isRunningOnEclipse(ProcessingEnvironment env) {
54-
var envClassName = env.getClass().getName();
57+
private JavaFileManager.Location determineLocation(boolean isRunningOnEcj) {
5558
var unitTest = env.getOptions().get(Options.TEST_UNIT);
5659
var integrationTest = env.getOptions().get(Options.TEST_INTEGRATION);
57-
return envClassName.startsWith("org.eclipse.")
60+
if (isRunningOnEcj
5861
&& !Boolean.parseBoolean(unitTest)
59-
&& !Boolean.parseBoolean(integrationTest);
62+
&& !Boolean.parseBoolean(integrationTest)) {
63+
// Eclipse doesn’t support SOURCE_PATH, use CLASS_OUTPUT.
64+
return StandardLocation.CLASS_OUTPUT;
65+
}
66+
// To leverage Gradle’s incremental annotation processing, we recommend using the --source-path
67+
// option of javac.
68+
return StandardLocation.SOURCE_PATH;
6069
}
6170

6271
private boolean isDebug(ProcessingEnvironment env) {

doma-processor/src/main/java/org/seasar/doma/internal/apt/Resources.java

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import javax.annotation.processing.Filer;
2626
import javax.lang.model.element.Element;
2727
import javax.tools.FileObject;
28+
import javax.tools.JavaFileManager;
2829
import javax.tools.JavaFileObject;
2930
import javax.tools.StandardLocation;
3031

@@ -36,21 +37,27 @@ public class Resources {
3637

3738
private final String resourcesDir;
3839

39-
private final boolean isRunningOnEclipse;
40+
private final boolean canAcceptDirectoryPath;
41+
42+
private final JavaFileManager.Location location;
43+
44+
private final JavaFileManager.Location fallbackLocation = StandardLocation.CLASS_OUTPUT;
4045

4146
private final boolean isDebug;
4247

4348
Resources(
4449
Filer filer,
4550
Reporter reporter,
4651
String resourcesDir,
47-
boolean isRunningOnEclipse,
52+
boolean canAcceptDirectoryPath,
53+
JavaFileManager.Location location,
4854
boolean isDebug) {
4955
assertNotNull(filer, reporter);
5056
this.filer = filer;
5157
this.reporter = reporter;
5258
this.resourcesDir = resourcesDir;
53-
this.isRunningOnEclipse = isRunningOnEclipse;
59+
this.canAcceptDirectoryPath = canAcceptDirectoryPath;
60+
this.location = location;
5461
this.isDebug = isDebug;
5562
}
5663

@@ -59,6 +66,23 @@ public JavaFileObject createSourceFile(CharSequence name, Element... originating
5966
return filer.createSourceFile(name, originatingElements);
6067
}
6168

69+
/**
70+
* Indicates whether directory paths can be accepted in the {@code #getResource} method.
71+
*
72+
* @return {@code true} if directory paths can be accepted; {@code false} otherwise
73+
*/
74+
public boolean canAcceptDirectoryPath() {
75+
return canAcceptDirectoryPath;
76+
}
77+
78+
/**
79+
* Attempts to retrieve a resource file based on the specified relative path.
80+
*
81+
* @param relativePath the relative path to the desired resource; must not be null
82+
* @return a {@code FileObject} representing the resource located at the given relative path
83+
* @throws IOException if an I/O error occurs during resource retrieval
84+
* @throws AssertionError if the {@code relativePath} parameter is null
85+
*/
6286
public FileObject getResource(String relativePath) throws IOException {
6387
assertNotNull(relativePath);
6488

@@ -68,22 +92,21 @@ public FileObject getResource(String relativePath) throws IOException {
6892
return new FileObjectImpl(path);
6993
}
7094

71-
// Since Eclipse doesn’t support SOURCE_PATH, use CLASS_OUTPUT.
72-
if (isRunningOnEclipse) {
73-
return filer.getResource(StandardLocation.CLASS_OUTPUT, "", relativePath);
74-
}
75-
76-
// To leverage Gradle’s incremental annotation processing, we recommend using the --source-path
77-
// option of javac.
7895
try {
79-
return filer.getResource(StandardLocation.SOURCE_PATH, "", relativePath);
96+
return filer.getResource(location, "", relativePath);
8097
} catch (Exception e) {
81-
if (isDebug) {
82-
reporter.debug(
83-
"Fall back from SOURCE_PATH to CLASS_OUTPUT: " + relativePath + ", exception: " + e);
98+
if (location != fallbackLocation) {
99+
if (isDebug) {
100+
var message =
101+
String.format(
102+
"Fall back from %s to %s: %s, exception: %s",
103+
location, fallbackLocation, relativePath, e);
104+
reporter.debug(message);
105+
}
106+
// If a file cannot be found in the default location, use the fallbackLocation.
107+
return filer.getResource(fallbackLocation, "", relativePath);
84108
}
85-
// If a file cannot be found in SOURCE_PATH, fall back to CLASS_OUTPUT.
86-
return filer.getResource(StandardLocation.CLASS_OUTPUT, "", relativePath);
109+
throw e;
87110
}
88111
}
89112

doma-processor/src/main/java/org/seasar/doma/internal/apt/meta/dao/DaoMetaFactory.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Map;
2929
import java.util.Optional;
3030
import java.util.Set;
31+
import java.util.stream.Collectors;
3132
import javax.lang.model.element.AnnotationMirror;
3233
import javax.lang.model.element.AnnotationValue;
3334
import javax.lang.model.element.ExecutableElement;
@@ -336,16 +337,30 @@ private void validateFiles(TypeElement interfaceElement, DaoMeta daoMeta) {
336337
if (daoMeta.isError()) {
337338
return;
338339
}
340+
339341
if (!ctx.getOptions().getSqlValidation()) {
340342
return;
341343
}
344+
345+
if (!ctx.getResources().canAcceptDirectoryPath()) {
346+
return;
347+
}
348+
349+
var queryFileNames =
350+
daoMeta.getQueryMetas().stream()
351+
.flatMap(it -> it.getFileNames().stream())
352+
.collect(Collectors.toSet());
353+
if (queryFileNames.isEmpty()) {
354+
return;
355+
}
356+
342357
String dirPath = SqlFileUtil.buildPath(interfaceElement.getQualifiedName().toString());
343358
Set<String> fileNames = getFileNames(dirPath);
344-
for (QueryMeta queryMeta : daoMeta.getQueryMetas()) {
345-
for (String fileName : queryMeta.getFileNames()) {
346-
fileNames.remove(fileName);
347-
}
359+
fileNames.removeAll(queryFileNames);
360+
if (fileNames.isEmpty()) {
361+
return;
348362
}
363+
349364
Suppress suppress = interfaceElement.getAnnotation(Suppress.class);
350365
Message message = Message.DOMA4220;
351366
if (!isSuppressed(suppress, message)) {

0 commit comments

Comments
 (0)