From 0af9caeee7947e97d79c832f015b1a5d3c16ae61 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:22:30 +0000 Subject: [PATCH 01/12] processing: extract generic AnnotationProcessingContext base class (#348) --- .../AnnotationProcessingContext.java | 350 ++++++++++++++++++ .../processing/ProcessingContext.java | 312 +--------------- 2 files changed, 361 insertions(+), 301 deletions(-) create mode 100644 processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java new file mode 100644 index 00000000..37e12adf --- /dev/null +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -0,0 +1,350 @@ +/* + * MIT License + * + * Copyright (c) 2025-2026 Andreas Igel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.javahelpers.simple.builders.processor.processing; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import org.javahelpers.simple.builders.processor.model.type.TypeName; +import org.javahelpers.simple.builders.processor.processing.logging.PerformanceTracker; +import org.javahelpers.simple.builders.processor.processing.logging.ProcessingLogger; + +/** + * Generic annotation-processing context: wraps {@link ProcessingEnvironment}, {@link Elements}, + * {@link Types}, logging and performance tracking, providing domain-agnostic helpers for type and + * element operations. + * + *

Builder-specific state lives in {@link ProcessingContext}, which extends this base. + */ +public class AnnotationProcessingContext { + + /** Element utility of the annotation processing framework. */ + protected final Elements elementUtils; + + /** Type utility of the annotation processing framework. */ + protected final Types typeUtils; + + /** Logger for info, debug, warning and error output. */ + protected final ProcessingLogger logger; + + /** The processing environment of the current round. */ + protected final ProcessingEnvironment processingEnv; + + /** Performance tracker for pipeline phase timing. */ + protected final PerformanceTracker performanceTracker; + + /** + * Creates the context. + * + * @param logger logger for output + * @param processingEnv the annotation processing environment + * @param performanceTracker tracker for pipeline phase timing + */ + public AnnotationProcessingContext( + ProcessingLogger logger, + ProcessingEnvironment processingEnv, + PerformanceTracker performanceTracker) { + this.elementUtils = processingEnv.getElementUtils(); + this.typeUtils = processingEnv.getTypeUtils(); + this.logger = logger; + this.processingEnv = processingEnv; + this.performanceTracker = performanceTracker; + } + + /** + * Returns the annotation values of an annotation mirror, including default values. + * + * @param annotationMirror the annotation mirror to read + * @return the annotation's element values keyed by their method element + */ + public Map getElementValuesWithDefaults( + AnnotationMirror annotationMirror) { + Map elementValues = new HashMap<>(); + elementUtils.getElementValuesWithDefaults(annotationMirror).forEach(elementValues::put); + return elementValues; + } + + /** + * Gets the performance tracker for this processing context. + * + *

When performance tracking is disabled, returns a {@link NoOpPerformanceTracker} that has + * zero overhead. When enabled via {@code -Asimplebuilder.performanceTracking=true}, returns an + * {@link ActivePerformanceTracker} that measures execution times. + * + * @return the performance tracker instance + */ + public PerformanceTracker getPerformanceTracker() { + return performanceTracker; + } + + /** + * Starts a new performance tracking phase. The phase name is passed to {@link + * #endPerformancePhase(String)} for recording. + */ + public void startPerformancePhase() { + performanceTracker.startPhase(); + } + + /** + * Ends the current performance tracking phase and records its duration under the given name. + * + * @param phase the phase name to record + */ + public void endPerformancePhase(String phase) { + performanceTracker.endPhase(phase); + } + + /** + * Get the TypeElement for a given qualified class name. + * + * @param qualifiedName the canonical class name (e.g., "java.lang.String") + * @return the type element, or null if not found + */ + public TypeElement getTypeElement(String qualifiedName) { + return elementUtils.getTypeElement(qualifiedName); + } + + /** + * Get the TypeElement for a given TypeName. + * + * @param typeName the TypeName containing package and class name + * @return the type element, or null if not found + */ + public TypeElement getTypeElement(TypeName typeName) { + if (typeName == null) { + return null; + } + return getTypeElement(typeName.getFullQualifiedName()); + } + + /** + * Get the package containing an element. + * + * @param element the element + * @return the package element + */ + public PackageElement getPackageOf(Element element) { + return elementUtils.getPackageOf(element); + } + + /** + * Get the package element for a qualified package name. + * + * @param name the qualified package name + * @return the package element, or null if no such package is visible to the compilation + */ + public PackageElement getPackageElement(String name) { + return elementUtils.getPackageElement(name); + } + + /** + * Get the package name of an element. + * + * @param element the element + * @return the qualified package name + */ + public String getPackageName(Element element) { + return elementUtils.getPackageOf(element).getQualifiedName().toString(); + } + + /** + * Get all members of a type, including inherited members. + * + * @param typeElement the type to inspect + * @return list of all members (wildcard enforced by the javax.lang.model API) + */ + @SuppressWarnings("java:S1452") + public List getAllMembers(TypeElement typeElement) { + return elementUtils.getAllMembers(typeElement); + } + + /** + * Get the Javadoc comment for an element. + * + * @param element the element + * @return the doc comment, or null if none + */ + public String getDocComment(Element element) { + return elementUtils.getDocComment(element); + } + + /** + * Convert a type mirror to its corresponding element. + * + * @param typeMirror the type mirror + * @return the element, or null if not representable as an element + */ + public Element asElement(TypeMirror typeMirror) { + return typeUtils.asElement(typeMirror); + } + + /** + * Check if two types are the same type. + * + * @param type1 first type + * @param type2 second type + * @return true if the types are the same + */ + public boolean isSameType(TypeMirror type1, TypeMirror type2) { + return typeUtils.isSameType(type1, type2); + } + + /** + * Get the erasure of a type (removes generic type information). + * + * @param typeMirror the type to erase + * @return the erasure of the type + */ + public TypeMirror erasure(TypeMirror typeMirror) { + return typeUtils.erasure(typeMirror); + } + + /** + * Check if one type is assignable to another. + * + * @param type1 the type to check + * @param type2 the target type + * @return true if type1 is assignable to type2 + */ + public boolean isAssignable(TypeMirror type1, TypeMirror type2) { + return typeUtils.isAssignable(type1, type2); + } + + /** + * Returns the direct supertypes of a type. + * + * @param typeMirror the type + * @return list of direct supertypes + */ + @SuppressWarnings("java:S1452") + public java.util.List directSupertypes(TypeMirror typeMirror) { + return typeUtils.directSupertypes(typeMirror); + } + + /** + * Logs an info-level message that appears in normal Maven output. + * + * @param message the info message to log + */ + public void info(String message) { + logger.info(message); + } + + /** + * Logs an info-level message with a formatted string. + * + * @param format the format string + * @param args arguments referenced by the format specifiers in the format string + */ + public void info(String format, Object... args) { + logger.info(format, args); + } + + /** + * Logs a debug message visible when Maven is run with -X flag. + * + * @param message the debug message to log + */ + public void debug(String message) { + logger.debug(message); + } + + /** + * Logs a debug message with a formatted string. Only visible when enabled via -Averbose=true or + * -Asimplebuilder.verbose=true. + * + * @param format the format string + * @param args arguments referenced by the format specifiers in the format string + */ + public void debug(String format, Object... args) { + logger.debug(format, args); + } + + /** + * Starts a new hierarchical operation context for logging with formatted message. + * + * @param format the format string for the operation message + * @param args arguments referenced by the format specifiers + */ + public void debugStartOperation(String format, Object... args) { + logger.debugStartOperation(format, args); + } + + /** Ends the current hierarchical operation context for logging. */ + public void debugEndOperation() { + logger.debugEndOperation(); + } + + /** Ends the current hierarchical operation context with a closing message for logging. */ + public void debugEndOperation(String format, Object... args) { + logger.debugEndOperation(format, args); + } + + /** Resets the indentation level to prevent cascading errors between processing runs. */ + public void resetIndentation() { + logger.resetIndentation(); + } + + /** + * Logs a warning message without requiring a specific element context. + * + * @param format the format string + * @param args arguments referenced by the format specifiers in the format string + */ + public void warning(String format, Object... args) { + logger.warning(null, format, args); + } + + /** + * Reports a warning at the location of the given element with a formatted message. + * + * @param element the element where the warning occurred, used for location information + * @param format the format string + * @param args arguments referenced by the format specifiers in the format string + */ + public void warning(Element element, String format, Object... args) { + logger.warning(element, format, args); + } + + /** + * Reports an error with a formatted message. + * + * @param format the format string + * @param args arguments referenced by the format specifiers in the format string + */ + public void error(String format, Object... args) { + logger.error(format, args); + } +} diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java index e0bdf6c2..159aeae5 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java @@ -24,27 +24,16 @@ package org.javahelpers.simple.builders.processor.processing; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.Optional; import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; import org.javahelpers.simple.builders.processor.analysis.BuilderScopeResolver; import org.javahelpers.simple.builders.processor.analysis.TypeMappingContext; import org.javahelpers.simple.builders.processor.generators.registry.GeneratorRegistry; import org.javahelpers.simple.builders.processor.model.core.BuilderConfiguration; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; -import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.processing.logging.ActivePerformanceTracker; import org.javahelpers.simple.builders.processor.processing.logging.NoOpPerformanceTracker; import org.javahelpers.simple.builders.processor.processing.logging.PerformanceTracker; @@ -56,13 +45,9 @@ * *

This eliminates repetitive parameter passing and provides a cleaner API. */ -public final class ProcessingContext implements TypeMappingContext { - private final Elements elementUtils; - private final Types typeUtils; - private final ProcessingLogger logger; +public final class ProcessingContext extends AnnotationProcessingContext + implements TypeMappingContext { private final BuilderConfigurationReader configurationReader; - private final ProcessingEnvironment processingEnv; - private final PerformanceTracker performanceTracker; private final BuilderScopeResolver builderScopeResolver; private GeneratorRegistry generatorRegistry; @@ -79,23 +64,22 @@ public ProcessingContext( ProcessingLogger logger, BuilderConfiguration globalConfiguration, ProcessingEnvironment processingEnv) { - this.elementUtils = processingEnv.getElementUtils(); - this.typeUtils = processingEnv.getTypeUtils(); - this.logger = logger; - this.processingEnv = processingEnv; + super(logger, processingEnv, createPerformanceTracker(processingEnv)); this.configurationReader = new BuilderConfigurationReader(globalConfiguration, logger, elementUtils); + this.builderScopeResolver = new BuilderScopeResolver(this); + // GeneratorRegistry will be lazily initialized on first access + } + + private static PerformanceTracker createPerformanceTracker(ProcessingEnvironment processingEnv) { // Initialize performance tracker based on compiler argument CompilerArgumentsReader argReader = new CompilerArgumentsReader(processingEnv); boolean perfTrackingEnabled = argReader.readBooleanValue(CompilerArgumentsEnum.PERFORMANCE_TRACKING); String perfOutputFile = argReader.readValue(CompilerArgumentsEnum.PERFORMANCE_OUTPUT_FILE); - this.performanceTracker = - perfTrackingEnabled - ? new ActivePerformanceTracker(perfOutputFile, PipelinePhases.PIPELINE_HIERARCHY) - : new NoOpPerformanceTracker(); - this.builderScopeResolver = new BuilderScopeResolver(this); - // GeneratorRegistry will be lazily initialized on first access + return perfTrackingEnabled + ? new ActivePerformanceTracker(perfOutputFile, PipelinePhases.PIPELINE_HIERARCHY) + : new NoOpPerformanceTracker(); } /** @@ -159,19 +143,6 @@ public boolean isMemberAccessibleFromBuilderPackage(Element member) { return getPackageName(member).equals(getBuilderPackageName()); } - /** - * Returns the annotation values of an annotation mirror, including default values. - * - * @param annotationMirror the annotation mirror to read - * @return the annotation's element values keyed by their method element - */ - public Map getElementValuesWithDefaults( - AnnotationMirror annotationMirror) { - Map elementValues = new HashMap<>(); - elementUtils.getElementValuesWithDefaults(annotationMirror).forEach(elementValues::put); - return elementValues; - } - /** * Gets the configuration reader for reading builder configurations. * @@ -196,36 +167,6 @@ public GeneratorRegistry getGeneratorRegistry() { return generatorRegistry; } - /** - * Gets the performance tracker for this processing context. - * - *

When performance tracking is disabled, returns a {@link NoOpPerformanceTracker} that has - * zero overhead. When enabled via {@code -Asimplebuilder.performanceTracking=true}, returns an - * {@link ActivePerformanceTracker} that measures execution times. - * - * @return the performance tracker instance - */ - public PerformanceTracker getPerformanceTracker() { - return performanceTracker; - } - - /** - * Starts a new performance tracking phase. The phase name is passed to {@link - * #endPerformancePhase(String)} for recording. - */ - public void startPerformancePhase() { - performanceTracker.startPhase(); - } - - /** - * Ends the current performance tracking phase and records its duration under the given name. - * - * @param phase the phase name to record - */ - public void endPerformancePhase(String phase) { - performanceTracker.endPhase(phase); - } - /** * Get the builder scope resolver for deciding whether a builder may be referenced. * @@ -258,237 +199,6 @@ public Optional resolveGeneratedType(TypeElement typeElement) { return builderScopeResolver.resolveUsableBuilderType(typeElement); } - /** - * Get the TypeElement for a given qualified class name. - * - * @param qualifiedName the canonical class name (e.g., "java.lang.String") - * @return the type element, or null if not found - */ - @Override - public TypeElement getTypeElement(String qualifiedName) { - return elementUtils.getTypeElement(qualifiedName); - } - - /** - * Get the TypeElement for a given TypeName. - * - * @param typeName the TypeName containing package and class name - * @return the type element, or null if not found - */ - public TypeElement getTypeElement(TypeName typeName) { - if (typeName == null) { - return null; - } - return getTypeElement(typeName.getFullQualifiedName()); - } - - /** - * Get the package containing an element. - * - * @param element the element - * @return the package element - */ - public PackageElement getPackageOf(Element element) { - return elementUtils.getPackageOf(element); - } - - /** - * Get the package element for a qualified package name. - * - * @param name the qualified package name - * @return the package element, or null if no such package is visible to the compilation - */ - public PackageElement getPackageElement(String name) { - return elementUtils.getPackageElement(name); - } - - /** - * Get the package name of an element. - * - * @param element the element - * @return the qualified package name - */ - @Override - public String getPackageName(Element element) { - return elementUtils.getPackageOf(element).getQualifiedName().toString(); - } - - /** - * Get all members of a type, including inherited members. - * - * @param typeElement the type to inspect - * @return list of all members (wildcard enforced by the javax.lang.model API) - */ - @SuppressWarnings("java:S1452") - @Override - public List getAllMembers(TypeElement typeElement) { - return elementUtils.getAllMembers(typeElement); - } - - /** - * Get the Javadoc comment for an element. - * - * @param element the element - * @return the doc comment, or null if none - */ - public String getDocComment(Element element) { - return elementUtils.getDocComment(element); - } - - /** - * Convert a type mirror to its corresponding element. - * - * @param typeMirror the type mirror - * @return the element, or null if not representable as an element - */ - @Override - public Element asElement(TypeMirror typeMirror) { - return typeUtils.asElement(typeMirror); - } - - /** - * Check if two types are the same type. - * - * @param type1 first type - * @param type2 second type - * @return true if the types are the same - */ - @Override - public boolean isSameType(TypeMirror type1, TypeMirror type2) { - return typeUtils.isSameType(type1, type2); - } - - /** - * Get the erasure of a type (removes generic type information). - * - * @param typeMirror the type to erase - * @return the erasure of the type - */ - @Override - public TypeMirror erasure(TypeMirror typeMirror) { - return typeUtils.erasure(typeMirror); - } - - /** - * Check if one type is assignable to another. - * - * @param type1 the type to check - * @param type2 the target type - * @return true if type1 is assignable to type2 - */ - @Override - public boolean isAssignable(TypeMirror type1, TypeMirror type2) { - return typeUtils.isAssignable(type1, type2); - } - - /** - * Returns the direct supertypes of a type. - * - * @param typeMirror the type - * @return list of direct supertypes - */ - @SuppressWarnings("java:S1452") - @Override - public java.util.List directSupertypes(TypeMirror typeMirror) { - return typeUtils.directSupertypes(typeMirror); - } - - /** - * Logs an info-level message that appears in normal Maven output. - * - * @param message the info message to log - */ - public void info(String message) { - logger.info(message); - } - - /** - * Logs an info-level message with a formatted string. - * - * @param format the format string - * @param args arguments referenced by the format specifiers in the format string - */ - public void info(String format, Object... args) { - logger.info(format, args); - } - - /** - * Logs a debug message visible when Maven is run with -X flag. - * - * @param message the debug message to log - */ - public void debug(String message) { - logger.debug(message); - } - - /** - * Logs a debug message with a formatted string. Only visible when enabled via -Averbose=true or - * -Asimplebuilder.verbose=true. - * - * @param format the format string - * @param args arguments referenced by the format specifiers in the format string - */ - @Override - public void debug(String format, Object... args) { - logger.debug(format, args); - } - - /** - * Starts a new hierarchical operation context for logging with formatted message. - * - * @param format the format string for the operation message - * @param args arguments referenced by the format specifiers - */ - public void debugStartOperation(String format, Object... args) { - logger.debugStartOperation(format, args); - } - - /** Ends the current hierarchical operation context for logging. */ - public void debugEndOperation() { - logger.debugEndOperation(); - } - - /** Ends the current hierarchical operation context with a closing message for logging. */ - public void debugEndOperation(String format, Object... args) { - logger.debugEndOperation(format, args); - } - - /** Resets the indentation level to prevent cascading errors between processing runs. */ - public void resetIndentation() { - logger.resetIndentation(); - } - - /** - * Logs a warning message without requiring a specific element context. - * - * @param format the format string - * @param args arguments referenced by the format specifiers in the format string - */ - public void warning(String format, Object... args) { - logger.warning(null, format, args); - } - - /** - * Reports a warning at the location of the given element with a formatted message. - * - * @param element the element where the warning occurred, used for location information - * @param format the format string - * @param args arguments referenced by the format specifiers in the format string - */ - public void warning(Element element, String format, Object... args) { - logger.warning(element, format, args); - } - - /** - * Reports an error with a formatted message. - * - * @param format the format string - * @param args arguments referenced by the format specifiers in the format string - */ - public void error(String format, Object... args) { - logger.error(format, args); - } - /** * Returns whether strict/fail-fast generation mode is enabled via the global compiler * configuration. From b69933cca1f57210335c315b47695c1f39fc4a1f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:24:19 +0000 Subject: [PATCH 02/12] analysis: migrate JavaLangAnalyser signatures to AnnotationProcessingContext (#348) --- .../processor/analysis/JavaLangAnalyser.java | 51 ++++++++++--------- .../AnnotationProcessingContext.java | 32 +++++++++++- .../processing/ProcessingContext.java | 25 ++------- 3 files changed, 62 insertions(+), 46 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/JavaLangAnalyser.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/JavaLangAnalyser.java index 15e812cf..e7ca58bd 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/JavaLangAnalyser.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/JavaLangAnalyser.java @@ -50,7 +50,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Strings; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.AnnotationProcessingContext; /** Helperclass for extrating specific information from existing classes. */ public final class JavaLangAnalyser { @@ -68,7 +68,8 @@ private JavaLangAnalyser() {} * @param context the processing context, used to resolve {@link java.lang.Object}'s methods * @return {@code true}, if it is no method with the signature of a java.lang.Object method */ - public static boolean isNoMethodOfObjectClass(ExecutableElement mth, ProcessingContext context) { + public static boolean isNoMethodOfObjectClass( + ExecutableElement mth, AnnotationProcessingContext context) { TypeElement objectElement = context.getTypeElement(Object.class.getCanonicalName()); if (objectElement == null) { return true; @@ -89,7 +90,7 @@ public static boolean isNoMethodOfObjectClass(ExecutableElement mth, ProcessingC * @return filtered list excluding Object class methods */ public static List findAllPossibleSettersOfClass( - TypeElement typeElement, ProcessingContext context) { + TypeElement typeElement, AnnotationProcessingContext context) { return ElementFilter.methodsIn(context.getAllMembers(typeElement)).stream() .filter(mth -> isNoMethodOfObjectClass(mth, context)) .filter(JavaLangAnalyser::isSetterForField) @@ -250,7 +251,7 @@ public static List findAnnotationInstances( Element element, Class annotationClass, Class containerClass, - ProcessingContext context) { + AnnotationProcessingContext context) { if (element == null) { return List.of(); } @@ -275,7 +276,7 @@ public static List findAnnotationInstances( * @return the annotation mirrors wrapped by the container */ private static List unwrapContainerInstances( - AnnotationMirror containerMirror, ProcessingContext context) { + AnnotationMirror containerMirror, AnnotationProcessingContext context) { Optional containerValue = findAnnotationAttribute(containerMirror, "value", context); if (containerValue.isEmpty() || !(containerValue.get().getValue() instanceof List entries)) { @@ -299,7 +300,9 @@ private static List unwrapContainerInstances( * @return the attribute's value, or empty if the annotation has no such attribute */ public static Optional findAnnotationAttribute( - AnnotationMirror annotationMirror, String attributeName, ProcessingContext context) { + AnnotationMirror annotationMirror, + String attributeName, + AnnotationProcessingContext context) { for (Map.Entry entry : context.getElementValuesWithDefaults(annotationMirror).entrySet()) { if (entry.getKey().getSimpleName().contentEquals(attributeName)) { @@ -311,13 +314,13 @@ public static Optional findAnnotationAttribute( /** * Single-parameter variant of {@link #findMethodsStatic(TypeElement, List, TypeName, - * ProcessingContext)}. + * AnnotationProcessingContext)}. */ public static List findMethodsStatic( TypeElement type, TypeName expectedParameterType, TypeName expectedReturnType, - ProcessingContext context) { + AnnotationProcessingContext context) { return findMethodsStatic(type, List.of(expectedParameterType), expectedReturnType, context); } @@ -335,7 +338,7 @@ public static List findMethodsStatic( TypeElement type, List expectedParameterTypes, TypeName expectedReturnType, - ProcessingContext context) { + AnnotationProcessingContext context) { return findMethods(type, expectedParameterTypes, expectedReturnType, context).stream() .filter(Predicate.not(JavaLangAnalyser::isNotStatic)) .toList(); @@ -351,7 +354,9 @@ public static List findMethodsStatic( * @return the matching methods, in declaration order */ public static List findMethodsStatic( - TypeElement type, List expectedParameterTypes, ProcessingContext context) { + TypeElement type, + List expectedParameterTypes, + AnnotationProcessingContext context) { return findMethods(type, expectedParameterTypes, mirror -> true, context).stream() .filter(Predicate.not(JavaLangAnalyser::isNotStatic)) .toList(); @@ -371,7 +376,7 @@ public static List findMethods( TypeElement type, List expectedParameterTypes, TypeName expectedReturnType, - ProcessingContext context) { + AnnotationProcessingContext context) { Predicate returnTypeMatcher = expectedReturnType == null ? mirror -> mirror.getKind() == VOID @@ -383,7 +388,7 @@ private static List findMethods( TypeElement type, List expectedParameterTypes, Predicate returnTypeMatcher, - ProcessingContext context) { + AnnotationProcessingContext context) { if (type == null) { return List.of(); } @@ -463,7 +468,7 @@ public record ReadableProperty(String name, String accessor, TypeMirror typeMirr * @return the readable properties in declaration order */ public static List findReadableProperties( - TypeElement typeElement, ProcessingContext context) { + TypeElement typeElement, AnnotationProcessingContext context) { if (typeElement == null) { return List.of(); } @@ -478,7 +483,7 @@ public static List findReadableProperties( && hasNoParameters(method) && method.getReturnType().getKind() != VOID && isNoMethodOfObjectClass(method, context) - && context.isMemberAccessibleFromBuilderPackage(method)) { + && context.isAccessibleFromGeneratedPackage(method)) { String name = propertyNameOf(method); properties.putIfAbsent( name, @@ -487,7 +492,7 @@ && isNoMethodOfObjectClass(method, context) } for (VariableElement field : ElementFilter.fieldsIn(context.getAllMembers(typeElement))) { if (!field.getModifiers().contains(STATIC) - && context.isMemberAccessibleFromBuilderPackage(field)) { + && context.isAccessibleFromGeneratedPackage(field)) { String name = field.getSimpleName().toString(); properties.putIfAbsent(name, new ReadableProperty(name, name, field.asType())); } @@ -505,7 +510,7 @@ && isNoMethodOfObjectClass(method, context) * @return the field functions in declaration order */ public static List findFieldFunctions( - TypeElement type, ProcessingContext context) { + TypeElement type, AnnotationProcessingContext context) { return ElementFilter.methodsIn(context.getAllMembers(type)).stream() .filter(JavaLangAnalyser::isNotStatic) .filter(method -> isNoMethodOfObjectClass(method, context)) @@ -542,7 +547,7 @@ private static String propertyNameOf(ExecutableElement method) { * @return {@code true} if the type declares or inherits a matching constructor */ public static boolean hasConstructorAccepting( - TypeElement builderType, TypeName expectedType, ProcessingContext context) { + TypeElement builderType, TypeName expectedType, AnnotationProcessingContext context) { if (builderType == null) { return false; } @@ -759,7 +764,7 @@ public static Optional findGetterForField( TypeElement dtoType, String fieldName, TypeMirror fieldTypeMirror, - ProcessingContext context) { + AnnotationProcessingContext context) { if (dtoType == null || fieldName == null || fieldTypeMirror == null) { return Optional.empty(); } @@ -772,7 +777,7 @@ public static Optional findGetterForField( if (Strings.CI.equalsAny(name, fieldName, "is" + fieldName, "get" + fieldName) && candidate.getParameters().isEmpty() && context.isSameType(candidate.getReturnType(), fieldTypeMirror) - && context.isMemberAccessibleFromBuilderPackage(candidate)) { + && context.isAccessibleFromGeneratedPackage(candidate)) { return Optional.of(candidate); } } @@ -827,7 +832,7 @@ public static Optional findReco * @return Optional containing the setter ExecutableElement if found */ public static Optional findSetterForField( - TypeElement dtoType, String fieldName, ProcessingContext context) { + TypeElement dtoType, String fieldName, AnnotationProcessingContext context) { if (dtoType == null || fieldName == null) { return Optional.empty(); } @@ -837,7 +842,7 @@ public static Optional findSetterForField( if (candidate.getSimpleName().contentEquals(setterName) && candidate.getParameters().size() == 1 && candidate.getReturnType().getKind() == VOID - && context.isMemberAccessibleFromBuilderPackage(candidate)) { + && context.isAccessibleFromGeneratedPackage(candidate)) { return Optional.of(candidate); } } @@ -859,7 +864,7 @@ public static Optional findSetterForField( public static Optional findConstructorForBuilder( TypeElement annotatedType, Class constructorAnnotation, - ProcessingContext context) { + AnnotationProcessingContext context) { List ctors = ElementFilter.constructorsIn(context.getAllMembers(annotatedType)).stream() .filter(context::isAccessibleFromGeneratedPackage) @@ -895,7 +900,7 @@ public static Optional findConstructorForBuilder( * @return {@code true} if an accessible constructor exists */ public static boolean hasAccessibleConstructor( - TypeElement typeElement, ProcessingContext context) { + TypeElement typeElement, AnnotationProcessingContext context) { return ElementFilter.constructorsIn(context.getAllMembers(typeElement)).stream() .anyMatch(context::isAccessibleFromGeneratedPackage); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index 37e12adf..b88c1ab4 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -32,6 +32,7 @@ import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; @@ -48,7 +49,7 @@ * *

Builder-specific state lives in {@link ProcessingContext}, which extends this base. */ -public class AnnotationProcessingContext { +public abstract class AnnotationProcessingContext { /** Element utility of the annotation processing framework. */ protected final Elements elementUtils; @@ -179,6 +180,35 @@ public String getPackageName(Element element) { return elementUtils.getPackageOf(element).getQualifiedName().toString(); } + /** + * Returns the name of the package generated code is written to. + * + * @return the qualified name of the package generated classes are placed in + */ + protected abstract String getGeneratedPackageName(); + + /** + * Checks whether a member (constructor, method) is accessible from the package generated code is + * written to. + * + *

Public members are always accessible. Private members are never accessible - generated code + * lives in a separate top-level class. Package-private and protected members are only accessible + * when the member's declaring package equals the generated package (protected access through + * inheritance does not apply, as generated code does not extend the target type). + * + * @param member the member to check + * @return {@code true} if generated code may call the member + */ + public boolean isAccessibleFromGeneratedPackage(Element member) { + if (member.getModifiers().contains(Modifier.PUBLIC)) { + return true; + } + if (member.getModifiers().contains(Modifier.PRIVATE)) { + return false; + } + return getPackageName(member).equals(getGeneratedPackageName()); + } + /** * Get all members of a type, including inherited members. * diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java index 159aeae5..f3a2cdf2 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java @@ -27,7 +27,6 @@ import java.util.Optional; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import org.javahelpers.simple.builders.processor.analysis.BuilderScopeResolver; import org.javahelpers.simple.builders.processor.analysis.TypeMappingContext; @@ -110,21 +109,9 @@ public String getBuilderPackageName() { return this.processingTarget.builderPackage(); } - /** - * Checks whether a member (constructor, method) is accessible from the package the generated - * builder is written to. - * - *

Public members are always accessible. Private members are never accessible - the generated - * builder is a separate top-level class. Package-private and protected members are only - * accessible when the member's declaring package equals the builder package (protected access - * through inheritance does not apply, as the builder does not extend the target type). - * - * @param member the member to check - * @return {@code true} if generated code in the builder package may call the member - */ @Override - public boolean isAccessibleFromGeneratedPackage(Element member) { - return isMemberAccessibleFromBuilderPackage(member); + protected String getGeneratedPackageName() { + return getBuilderPackageName(); } /** @@ -134,13 +121,7 @@ public boolean isAccessibleFromGeneratedPackage(Element member) { * @return {@code true} if the member is accessible from the builder package */ public boolean isMemberAccessibleFromBuilderPackage(Element member) { - if (member.getModifiers().contains(Modifier.PUBLIC)) { - return true; - } - if (member.getModifiers().contains(Modifier.PRIVATE)) { - return false; - } - return getPackageName(member).equals(getBuilderPackageName()); + return isAccessibleFromGeneratedPackage(member); } /** From c6dd8ccc1d4c2958924c0b89902b69d8c66429c7 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:38:24 +0000 Subject: [PATCH 03/12] processing: rename ProcessingContext to BuilderProcessingContext (builder-only state left) --- .../custom/StringValidationGenerator.java | 6 +- .../builders/processor/BuilderProcessor.java | 6 +- .../analysis/BuilderScopeResolver.java | 14 ++-- .../processor/generators/BuilderEnhancer.java | 7 +- .../processor/generators/MethodGenerator.java | 6 +- ...ilderImplementationAnnotationEnhancer.java | 6 +- .../builder/ClassJavaDocEnhancer.java | 6 +- .../builder/ConditionalEnhancer.java | 6 +- .../builder/ConstructorEnhancer.java | 6 +- .../builder/CoreMethodsEnhancer.java | 6 +- .../builder/FieldPrefillEnhancer.java | 6 +- .../builder/GeneratedAnnotationEnhancer.java | 6 +- .../generators/builder/InterfaceEnhancer.java | 6 +- .../builder/JacksonAnnotationEnhancer.java | 8 +-- .../builder/WithInterfaceEnhancer.java | 6 +- .../field/AddToCollectionGenerator.java | 8 +-- .../field/ArrayBuilderConsumerGenerator.java | 8 +-- .../field/ArrayConversionGenerator.java | 8 +-- .../field/BasicSetterGenerator.java | 6 +- .../field/FieldInstanceConsumerGenerator.java | 8 +-- .../field/ListConsumerGenerator.java | 6 +- .../field/MapConsumerGenerator.java | 6 +- .../field/NestedBuilderConsumerGenerator.java | 6 +- .../field/OptionalHelperGenerator.java | 6 +- .../field/SetConsumerGenerator.java | 6 +- .../field/StringBuilderConsumerGenerator.java | 8 +-- .../field/StringFormatHelperGenerator.java | 8 +-- .../field/SupplierMethodGenerator.java | 8 +-- .../field/UpdateHelperGenerator.java | 10 +-- .../field/VarArgsHelperGenerator.java | 11 ++-- .../registry/GeneratorRegistry.java | 6 +- .../generators/util/MethodGeneratorUtil.java | 19 +++--- .../AnnotationProcessingContext.java | 2 +- .../BuilderConfigurationReader.java | 4 +- .../processing/BuilderDefinitionCreator.java | 36 +++++----- ...ext.java => BuilderProcessingContext.java} | 4 +- .../processing/ProcessingTarget.java | 4 +- .../processor/BuilderScopeResolverTest.java | 6 +- .../CustomizingDocumentationTest.java | 66 +++++++++---------- .../RoasterCodeGeneratorResilienceTest.java | 9 +-- 40 files changed, 190 insertions(+), 180 deletions(-) rename processor/src/main/java/org/javahelpers/simple/builders/processor/processing/{ProcessingContext.java => BuilderProcessingContext.java} (98%) diff --git a/example-custom-generator/src/main/java/org/javahelpers/simple/builders/example/custom/StringValidationGenerator.java b/example-custom-generator/src/main/java/org/javahelpers/simple/builders/example/custom/StringValidationGenerator.java index fd218928..ddd370db 100644 --- a/example-custom-generator/src/main/java/org/javahelpers/simple/builders/example/custom/StringValidationGenerator.java +++ b/example-custom-generator/src/main/java/org/javahelpers/simple/builders/example/custom/StringValidationGenerator.java @@ -31,7 +31,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.javadoc.JavadocDto; import org.javahelpers.simple.builders.processor.generators.MethodGenerator; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Custom generator that adds validation methods for String fields. @@ -60,13 +60,13 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { // Only apply to String fields return "java.lang.String".equals(field.getFieldType().getFullQualifiedName()); } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { String fieldInDto = field.getOriginalFieldName(); String fieldInBuilder = field.getFieldNameInBuilder(); String methodName = "validate" + StringUtils.capitalize(fieldInDto); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/BuilderProcessor.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/BuilderProcessor.java index 0c560e70..f666dad4 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/BuilderProcessor.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/BuilderProcessor.java @@ -78,9 +78,9 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameMap; import org.javahelpers.simple.builders.processor.model.type.TypeNameSet; import org.javahelpers.simple.builders.processor.processing.BuilderConfigurationReader; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import org.javahelpers.simple.builders.processor.processing.CompilerArgumentsEnum; import org.javahelpers.simple.builders.processor.processing.CompilerArgumentsReader; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; import org.javahelpers.simple.builders.processor.processing.ProcessingTarget; import org.javahelpers.simple.builders.processor.processing.SourceFormatterResolver; import org.javahelpers.simple.builders.processor.processing.logging.PerformanceTracker; @@ -97,7 +97,7 @@ public class BuilderProcessor extends AbstractProcessor { private static final String MSG_FAILED_TO_GENERATE = "simple-builders: Failed to generate builder - %s"; - private ProcessingContext context; + private BuilderProcessingContext context; private ProcessingLogger logger; private ClassCodeGenerator codeGenerator; private SourceFormatterResolver formatterResolver; @@ -121,7 +121,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) { SimpleBuildersSpiIntegration.initCompilation(processingEnv.getElementUtils()); - this.context = new ProcessingContext(logger, globalConfig, processingEnv); + this.context = new BuilderProcessingContext(logger, globalConfig, processingEnv); this.codeGenerator = new RoasterCodeGenerator( new GenerationEnvironment( diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/BuilderScopeResolver.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/BuilderScopeResolver.java index dcb8802d..5965a7a1 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/BuilderScopeResolver.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/analysis/BuilderScopeResolver.java @@ -44,7 +44,7 @@ import org.javahelpers.simple.builders.processor.model.type.BuilderInstantiation; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Central resolver that decides whether a builder may be referenced for a given type. @@ -75,7 +75,7 @@ private record ResolutionInputs(BuilderConfiguration configuration, String build List.of(GENERATED_FACTORY_METHOD_NAME, "of"); private static final char[] UPPERCASE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); - private final ProcessingContext context; + private final BuilderProcessingContext context; private ResolutionInputs cachedResolutionInputs; private PackageScopes usagePackages = PackageScopes.unscoped(); private final Map> resolvedBuilderTypes = new HashMap<>(); @@ -86,7 +86,7 @@ private record ResolutionInputs(BuilderConfiguration configuration, String build * * @param context the processing context providing configuration and type utilities */ - public BuilderScopeResolver(ProcessingContext context) { + public BuilderScopeResolver(BuilderProcessingContext context) { this.context = context; } @@ -94,9 +94,9 @@ public BuilderScopeResolver(ProcessingContext context) { * Resolves the builder type to use for the given referenced type, if any. * *

This method reads the configuration from the processing context via {@link - * org.javahelpers.simple.builders.processor.processing.ProcessingContext#getConfiguration()}. The - * caller must ensure that {@link - * org.javahelpers.simple.builders.processor.processing.ProcessingContext#initProcessingTarget} + * org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext#getConfiguration()}. + * The caller must ensure that {@link + * org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext#initProcessingTarget} * has been invoked with the owner element's resolved configuration beforehand, so that * per-element {@code builderUsagePackages} overrides are respected. * @@ -170,7 +170,7 @@ public Optional resolveGeneratedBuilder(TypeElement referencedT *

Unlike {@link #resolveUsableBuilderType(TypeElement)}, this method takes the configuration * as an explicit parameter rather than reading it from the processing context. This is because it * is called during generation-plan resolution, before {@link - * org.javahelpers.simple.builders.processor.processing.ProcessingContext#initProcessingTarget} + * org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext#initProcessingTarget} * has been invoked for the element, so the context does not yet hold the per-element * configuration. * diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/BuilderEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/BuilderEnhancer.java index 124a091c..a2b87607 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/BuilderEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/BuilderEnhancer.java @@ -25,7 +25,7 @@ import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Interface for enhancing or modifying generated builders beyond the basic field-based methods. @@ -72,7 +72,8 @@ public non-sealed interface BuilderEnhancer extends Generator { * @param context the processing context for configuration and utilities * @return true if this enhancer should be applied to this builder */ - boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context); + boolean appliesTo( + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context); /** * Enhances the builder by adding or modifying its structure. @@ -91,5 +92,5 @@ public non-sealed interface BuilderEnhancer extends Generator { * @param builderDto the builder to enhance (modifiable) * @param context the processing context for configuration and utilities */ - void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context); + void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/MethodGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/MethodGenerator.java index 8c4f6fe0..07960df2 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/MethodGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/MethodGenerator.java @@ -28,7 +28,7 @@ import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Service Provider Interface (SPI) for generating builder methods for fields. @@ -67,7 +67,7 @@ public non-sealed interface MethodGenerator extends Generator { * @param context the processing context containing configuration and utilities * @return true if this generator should generate methods for this field, false otherwise */ - boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context); + boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context); /** * Generates methods for the given field. @@ -85,5 +85,5 @@ public non-sealed interface MethodGenerator extends Generator { * @return list of generated methods (may be empty but should not be null) */ List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context); + FieldDto field, TypeName builderType, BuilderProcessingContext context); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/BuilderImplementationAnnotationEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/BuilderImplementationAnnotationEnhancer.java index 84c5447e..44cddfc3 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/BuilderImplementationAnnotationEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/BuilderImplementationAnnotationEnhancer.java @@ -29,7 +29,7 @@ import org.javahelpers.simple.builders.processor.model.annotation.AnnotationDto; import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds the @BuilderImplementation annotation to generated builder classes. @@ -74,12 +74,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldUseBuilderImplementationAnnotation(); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { AnnotationDto builderImplementationAnnotation = createBuilderImplementationAnnotation(builderDto); builderDto.addClassAnnotation(builderImplementationAnnotation); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ClassJavaDocEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ClassJavaDocEnhancer.java index 55a15759..96dbdf25 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ClassJavaDocEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ClassJavaDocEnhancer.java @@ -31,7 +31,7 @@ import org.javahelpers.simple.builders.processor.model.javadoc.JavadocDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds class-level JavaDoc to generated builder classes. @@ -83,12 +83,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return true; // Class JavaDoc is always needed for builders } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { TypeName targetType = builderDto.getBuildingTargetTypeName(); JavadocDto javadoc = createClassJavadoc(targetType); String indentionString = " "; diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConditionalEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConditionalEnhancer.java index dee0a9b6..58a88b59 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConditionalEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConditionalEnhancer.java @@ -33,7 +33,7 @@ import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds conditional methods to generated builders. @@ -96,12 +96,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldGenerateConditionalLogic(); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { // Add conditional(BooleanSupplier, Consumer, Consumer) method BuilderMethodDto conditionalMethod = createConditionalMethod(builderDto); builderDto.addMethod(conditionalMethod); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConstructorEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConstructorEnhancer.java index 113569ad..4c7b4ce5 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConstructorEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/ConstructorEnhancer.java @@ -33,7 +33,7 @@ import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNamePrimitive; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds builder constructors. @@ -59,12 +59,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return true; // Constructors are always needed } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { builderDto.addConstructor(createEmptyConstructor(builderDto)); builderDto.addConstructor(createFromInstanceConstructor(builderDto)); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/CoreMethodsEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/CoreMethodsEnhancer.java index 8bbc1687..56ba9285 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/CoreMethodsEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/CoreMethodsEnhancer.java @@ -37,7 +37,7 @@ import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.GenericParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds core builder methods (build, create, toString). @@ -94,12 +94,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return true; // Core methods are always needed } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { // Add build() method BuilderMethodDto buildMethod = createBuildMethod(builderDto); builderDto.addMethod(buildMethod); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/FieldPrefillEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/FieldPrefillEnhancer.java index 54fa97d2..d37c322e 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/FieldPrefillEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/FieldPrefillEnhancer.java @@ -31,7 +31,7 @@ import org.javahelpers.simple.builders.processor.model.type.BuilderInstantiation; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds the private prefilling methods backing {@link @@ -50,13 +50,13 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return builderDto.getAllFieldsForBuilder().stream() .anyMatch(field -> fieldPrefill(field).isPresent()); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { builderDto.getAllFieldsForBuilder().stream() .map(FieldPrefillEnhancer::fieldPrefill) .flatMap(Optional::stream) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/GeneratedAnnotationEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/GeneratedAnnotationEnhancer.java index 57f5594e..858fbbdf 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/GeneratedAnnotationEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/GeneratedAnnotationEnhancer.java @@ -29,7 +29,7 @@ import org.javahelpers.simple.builders.processor.model.annotation.AnnotationDto; import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds the @Generated annotation to generated builder classes. @@ -74,12 +74,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldUseGeneratedAnnotation(); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { AnnotationDto generatedAnnotation = createGeneratedAnnotation(); builderDto.addClassAnnotation(generatedAnnotation); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/InterfaceEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/InterfaceEnhancer.java index 3befd280..58a93edf 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/InterfaceEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/InterfaceEnhancer.java @@ -28,7 +28,7 @@ import org.javahelpers.simple.builders.processor.model.annotation.InterfaceName; import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds the IBuilderBase interface to generated builder classes. @@ -85,12 +85,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldImplementBuilderBase(); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { // Add the IBuilderBase interface to the builder InterfaceName builderBaseInterface = createBuilderBaseInterface(builderDto); builderDto.addInterface(builderBaseInterface); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/JacksonAnnotationEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/JacksonAnnotationEnhancer.java index bcefd482..64de2308 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/JacksonAnnotationEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/JacksonAnnotationEnhancer.java @@ -27,7 +27,7 @@ import org.javahelpers.simple.builders.processor.model.annotation.AnnotationDto; import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds the @JsonPOJOBuilder annotation to generated builder classes. @@ -84,13 +84,13 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldUseJacksonDeserializerAnnotation() && isJacksonAvailable(context); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { AnnotationDto jacksonAnnotation = createJsonPOJOBuilderAnnotation(builderDto); builderDto.addClassAnnotation(jacksonAnnotation); } @@ -101,7 +101,7 @@ public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext co * @param context the processing context * @return true if Jackson is available, false otherwise */ - private boolean isJacksonAvailable(ProcessingContext context) { + private boolean isJacksonAvailable(BuilderProcessingContext context) { return context.getTypeElement("com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder") != null; } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/WithInterfaceEnhancer.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/WithInterfaceEnhancer.java index 45bf1317..e5fb06f2 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/WithInterfaceEnhancer.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/builder/WithInterfaceEnhancer.java @@ -35,7 +35,7 @@ import org.javahelpers.simple.builders.processor.model.type.NestedTypeDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Enhancer that adds the "With" interface to generated builders. @@ -95,12 +95,12 @@ public int getPriority() { @Override public boolean appliesTo( - BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldGenerateWithInterface(); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { BuilderNestedTypeDto withInterface = createWithInterface(builderDto); builderDto.addNestedType(withInterface); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/AddToCollectionGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/AddToCollectionGenerator.java index f057dcd4..45d47d4b 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/AddToCollectionGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/AddToCollectionGenerator.java @@ -40,7 +40,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameList; import org.javahelpers.simple.builders.processor.model.type.TypeNameSet; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates add2FieldName helper methods for List and Set fields. @@ -90,7 +90,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateAddToCollectionHelpers()) { return false; } @@ -103,7 +103,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { List methods = new ArrayList<>(); TypeName fieldType = field.getFieldType(); @@ -139,7 +139,7 @@ private BuilderMethodDto createAddToCollectionMethod( TypeName fieldType, TypeName elementType, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { String methodName = "add2" + StringUtils.capitalize(originalFieldName); BuilderMethodDto methodDto = new BuilderMethodDto(methodName, builderType); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayBuilderConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayBuilderConsumerGenerator.java index ad720281..b56771e5 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayBuilderConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayBuilderConsumerGenerator.java @@ -39,7 +39,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameArray; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; import org.javahelpers.simple.builders.processor.model.type.TypeNamePrimitive; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates ArrayListBuilder consumer methods for array fields. @@ -87,7 +87,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateBuilderConsumer()) { return false; } @@ -97,7 +97,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { TypeName fieldType = field.getFieldType(); @@ -120,7 +120,7 @@ private BuilderMethodDto createFieldConsumerWithArrayBuilder( TypeName collectionBuilderType, TypeName elementType, TypeName returnBuilderType, - ProcessingContext context) { + BuilderProcessingContext context) { String fieldName = field.getOriginalFieldName(); String fieldNameInBuilder = field.getFieldNameInBuilder(); TypeNameGeneric builderTypeGeneric = new TypeNameGeneric(collectionBuilderType, elementType); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayConversionGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayConversionGenerator.java index 328eefd3..6e808a2b 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayConversionGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ArrayConversionGenerator.java @@ -38,7 +38,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameArray; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; import org.javahelpers.simple.builders.processor.model.type.TypeNamePrimitive; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates array-from-List conversion methods for array fields. @@ -83,13 +83,13 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return field.getFieldType() instanceof TypeNameArray; } @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { TypeName fieldType = field.getFieldType(); @@ -111,7 +111,7 @@ private BuilderMethodDto createFieldSetterForArrayFromList( TypeName listType, TypeName elementType, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { String fieldName = field.getOriginalFieldName(); String fieldNameInBuilder = field.getFieldNameInBuilder(); MethodParameterDto parameter = new MethodParameterDto(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/BasicSetterGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/BasicSetterGenerator.java index 6e5c295b..fcf0ba78 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/BasicSetterGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/BasicSetterGenerator.java @@ -31,7 +31,7 @@ import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates basic setter methods for all fields of the builder. @@ -78,13 +78,13 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return true; } @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { BuilderMethodDto setterMethod = MethodGeneratorUtil.createBuilderMethodForFieldWithTransform( diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/FieldInstanceConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/FieldInstanceConsumerGenerator.java index b35fdb00..87d3efa3 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/FieldInstanceConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/FieldInstanceConsumerGenerator.java @@ -35,7 +35,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameList; import org.javahelpers.simple.builders.processor.model.type.TypeNameMap; import org.javahelpers.simple.builders.processor.model.type.TypeNameSet; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Consumer-based methods for fields with concrete classes that have empty constructors. @@ -90,7 +90,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateFieldConsumer()) { return false; } @@ -115,7 +115,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con * @param context the processing context * @return true if a specific consumer (List, Set, or Map) should be generated instead */ - private boolean hasSpecificCollectionConsumer(FieldDto field, ProcessingContext context) { + private boolean hasSpecificCollectionConsumer(FieldDto field, BuilderProcessingContext context) { TypeName fieldType = field.getFieldType(); return (fieldType instanceof TypeNameList @@ -128,7 +128,7 @@ private boolean hasSpecificCollectionConsumer(FieldDto field, ProcessingContext @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { if (!field.getFieldType().hasEmptyConstructor()) { return Collections.emptyList(); } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ListConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ListConsumerGenerator.java index 4af8daaf..0b8d67ac 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ListConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/ListConsumerGenerator.java @@ -43,7 +43,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; import org.javahelpers.simple.builders.processor.model.type.TypeNameList; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Consumer-based methods for List fields with collection builder support. @@ -98,7 +98,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateBuilderConsumer()) { return false; } @@ -118,7 +118,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { if (!(field.getFieldType() instanceof TypeNameList fieldTypeGeneric && fieldTypeGeneric.isParameterized())) { return Collections.emptyList(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/MapConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/MapConsumerGenerator.java index ad7d4904..a446de18 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/MapConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/MapConsumerGenerator.java @@ -39,7 +39,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; import org.javahelpers.simple.builders.processor.model.type.TypeNameMap; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Consumer-based methods for Map fields with map builder support. @@ -105,7 +105,7 @@ public int getPriority() { */ @Override public boolean appliesTo( - final FieldDto field, final TypeName dtoType, final ProcessingContext context) { + final FieldDto field, final TypeName dtoType, final BuilderProcessingContext context) { BuilderConfiguration configuration = context.getConfiguration(); TypeName fieldType = field.getFieldType(); return @@ -133,7 +133,7 @@ public boolean appliesTo( */ @Override public List generateMethods( - final FieldDto field, final TypeName builderType, final ProcessingContext context) { + final FieldDto field, final TypeName builderType, final BuilderProcessingContext context) { if (!(field.getFieldType() instanceof TypeNameMap fieldTypeGeneric && fieldTypeGeneric.isParameterized())) { return Collections.emptyList(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/NestedBuilderConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/NestedBuilderConsumerGenerator.java index c6972145..11d07fcd 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/NestedBuilderConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/NestedBuilderConsumerGenerator.java @@ -36,7 +36,7 @@ import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Consumer-based methods for fields whose type has a @SimpleBuilder annotation. @@ -89,7 +89,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateBuilderConsumer()) { return false; } @@ -98,7 +98,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { Optional fieldBuilderOpt = field.getFieldType().getResolvedBuilder(); if (fieldBuilderOpt.isEmpty() || fieldBuilderOpt.get().funcForPrefilledBuilder().isEmpty()) { return Collections.emptyList(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/OptionalHelperGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/OptionalHelperGenerator.java index 3b8f54a7..4cec8f61 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/OptionalHelperGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/OptionalHelperGenerator.java @@ -36,7 +36,7 @@ import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates unboxed Optional helper methods for {@code Optional} fields. @@ -83,7 +83,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateUnboxedOptional()) { return false; } @@ -92,7 +92,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { TypeNameGeneric genericType = (TypeNameGeneric) field.getFieldType(); List innerTypes = genericType.getInnerTypeArguments(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SetConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SetConsumerGenerator.java index fcbf56b8..65cc9e3d 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SetConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SetConsumerGenerator.java @@ -41,7 +41,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; import org.javahelpers.simple.builders.processor.model.type.TypeNameSet; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Consumer-based methods for Set fields with collection builder support. @@ -95,7 +95,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateBuilderConsumer()) { return false; } @@ -114,7 +114,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { if (!(field.getFieldType() instanceof TypeNameSet fieldTypeGeneric && fieldTypeGeneric.isParameterized())) { return Collections.emptyList(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringBuilderConsumerGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringBuilderConsumerGenerator.java index bf8c1823..a3d9ecfe 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringBuilderConsumerGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringBuilderConsumerGenerator.java @@ -39,7 +39,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameArray; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Consumer-based methods for String and {@code Optional} fields using @@ -88,7 +88,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateBuilderConsumer()) { return false; } @@ -106,7 +106,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { String transform = isOptionalString(field.getFieldType()) ? "Optional.of(builder.toString())" @@ -134,7 +134,7 @@ private BuilderMethodDto createStringBuilderConsumer( String fieldJavadoc, String transform, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { TypeName stringBuilderType = map2TypeName(StringBuilder.class); TypeNameGeneric consumerType = createConsumerType(stringBuilderType); MethodParameterDto parameter = new MethodParameterDto(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringFormatHelperGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringFormatHelperGenerator.java index 7c6d4779..bded858b 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringFormatHelperGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/StringFormatHelperGenerator.java @@ -43,7 +43,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameArray; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates String.format helper methods for String and {@code Optional} fields. @@ -90,7 +90,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateStringFormatHelpers()) { return false; } @@ -113,7 +113,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { List methods = new ArrayList<>(); TypeName fieldType = field.getFieldType(); @@ -168,7 +168,7 @@ private BuilderMethodDto createStringFormatMethodWithTransform( String transform, List annotations, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { TypeName stringType = map2TypeName(String.class); MethodParameterDto formatParam = new MethodParameterDto(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SupplierMethodGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SupplierMethodGenerator.java index 0823bb2e..dccebc93 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SupplierMethodGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/SupplierMethodGenerator.java @@ -41,7 +41,7 @@ import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates Supplier-based methods for builder fields. @@ -88,13 +88,13 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldGenerateFieldSupplier(); } @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { BuilderMethodDto supplierMethod = createFieldSupplier( @@ -126,7 +126,7 @@ private BuilderMethodDto createFieldSupplier( String fieldJavaDoc, TypeName fieldType, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { TypeNameGeneric supplierType = new TypeNameGeneric(map2TypeName(Supplier.class), fieldType); String parameterName = fieldName + SUFFIX_SUPPLIER; diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/UpdateHelperGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/UpdateHelperGenerator.java index 6d738c1f..e354fe49 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/UpdateHelperGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/UpdateHelperGenerator.java @@ -56,7 +56,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameGeneric; import org.javahelpers.simple.builders.processor.model.type.TypeNamePrimitive; import org.javahelpers.simple.builders.processor.model.type.TypeNamePrimitive.PrimitiveTypeEnum; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates update helper methods for builder fields. @@ -143,13 +143,13 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return context.getConfiguration().shouldGenerateUpdateHelpers(); } @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { String originalFieldName = field.getOriginalFieldName(); String parameterName = originalFieldName + "Updater"; TypeNameGeneric updaterType = @@ -206,7 +206,7 @@ The value must have been set before (directly or via an existing instance). * Returns Javadoc guidance pointing to the builder-consumer overload when such a helper will be * generated for this field (nested DTO or collection of nested DTOs). */ - private static String builderConsumerGuidance(FieldDto field, ProcessingContext context) { + private static String builderConsumerGuidance(FieldDto field, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateBuilderConsumer()) { return ""; } @@ -228,7 +228,7 @@ private static String builderConsumerGuidance(FieldDto field, ProcessingContext * method-level example additionally requires an example value for setting the field first. */ private static void addUpdateExample( - BuilderMethodDto methodDto, FieldDto field, ProcessingContext context) { + BuilderMethodDto methodDto, FieldDto field, BuilderProcessingContext context) { Optional updateExpression = getUpdateExample(field.getFieldType()); if (updateExpression.isEmpty()) { return; diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/VarArgsHelperGenerator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/VarArgsHelperGenerator.java index 37b8c13b..48c37fed 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/VarArgsHelperGenerator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/field/VarArgsHelperGenerator.java @@ -38,7 +38,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameList; import org.javahelpers.simple.builders.processor.model.type.TypeNameMap; import org.javahelpers.simple.builders.processor.model.type.TypeNameSet; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Generates varargs helper methods for List, Set, and Map fields. @@ -88,7 +88,7 @@ public int getPriority() { } @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { if (!context.getConfiguration().shouldGenerateVarArgsHelpers()) { return false; } @@ -99,7 +99,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con @Override public List generateMethods( - FieldDto field, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName builderType, BuilderProcessingContext context) { TypeName fieldType = field.getFieldType(); TypeName parameterType = null; @@ -136,7 +136,10 @@ public List generateMethods( * @return the method DTO for the setter */ private BuilderMethodDto createFieldSetterByVarArgs( - FieldDto field, TypeName parameterType, TypeName builderType, ProcessingContext context) { + FieldDto field, + TypeName parameterType, + TypeName builderType, + BuilderProcessingContext context) { String baseExpression; TypeName fieldType = field.getFieldType(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/registry/GeneratorRegistry.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/registry/GeneratorRegistry.java index ecdd4ab9..2240bc72 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/registry/GeneratorRegistry.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/registry/GeneratorRegistry.java @@ -37,7 +37,7 @@ import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import org.javahelpers.simple.builders.processor.processing.logging.PerformanceTracker; /** @@ -59,7 +59,7 @@ public class GeneratorRegistry { private final List methodGenerators; private final List builderEnhancers; - private final ProcessingContext context; + private final BuilderProcessingContext context; private final ComponentFilter componentFilter; private final PerformanceTracker performanceTracker; @@ -69,7 +69,7 @@ public class GeneratorRegistry { * @param context the processing context for configuration and utilities * @param processingEnv the processing environment for reading compiler arguments */ - public GeneratorRegistry(ProcessingContext context, ProcessingEnvironment processingEnv) { + public GeneratorRegistry(BuilderProcessingContext context, ProcessingEnvironment processingEnv) { this.context = context; this.methodGenerators = new ArrayList<>(); this.builderEnhancers = new ArrayList<>(); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/util/MethodGeneratorUtil.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/util/MethodGeneratorUtil.java index d1521e97..f6192efd 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/util/MethodGeneratorUtil.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/generators/util/MethodGeneratorUtil.java @@ -44,7 +44,7 @@ import org.javahelpers.simple.builders.processor.model.type.TypeNameMap; import org.javahelpers.simple.builders.processor.model.type.TypeNameSet; import org.javahelpers.simple.builders.processor.model.type.TypeNameVariable; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; /** * Utility class providing common functionality for method generators. @@ -84,14 +84,15 @@ private MethodGeneratorUtil() { * @param context the processing context containing the configuration with the method name prefix * @return the method name with prefix applied */ - public static String generateBuilderMethodName(String fieldName, ProcessingContext context) { + public static String generateBuilderMethodName( + String fieldName, BuilderProcessingContext context) { return generateBuilderMethodName(fieldName, context.getConfiguration().getSetterPrefix()); } /** * Generates a builder method name by prepending the given setter prefix to the capitalized field * name — the same name derivation the context-based overload resolves from {@code setterPrefix}, - * for callers without a {@link ProcessingContext} (e.g. SPI adapters). + * for callers without a {@link BuilderProcessingContext} (e.g. SPI adapters). * * @param fieldName the field name * @param setterPrefix the configured setter prefix, or {@code null}/empty for none @@ -110,7 +111,7 @@ public static String generateBuilderMethodName(String fieldName, String setterPr * @param context the processing context * @return the AccessModifier for method access, or null for package-private */ - public static AccessModifier getMethodAccessModifier(ProcessingContext context) { + public static AccessModifier getMethodAccessModifier(BuilderProcessingContext context) { return context.getConfiguration().getMethodAccess(); } @@ -124,7 +125,7 @@ public static AccessModifier getMethodAccessModifier(ProcessingContext context) * @return a new {@link BuilderMethodDto} with name and modifier set */ public static BuilderMethodDto createBuilderMethod( - String fieldName, TypeName returnType, ProcessingContext context) { + String fieldName, TypeName returnType, BuilderProcessingContext context) { BuilderMethodDto method = new BuilderMethodDto(generateBuilderMethodName(fieldName, context), returnType); method.setModifier(getMethodAccessModifier(context)); @@ -173,7 +174,7 @@ public static BuilderMethodDto createBuilderMethodForFieldWithTransform( String transform, TypeName parameterType, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { MethodParameterDto parameter = new MethodParameterDto(); parameter.setParameterName(field.getOriginalFieldName()); @@ -235,7 +236,7 @@ public static BuilderMethodDto createFieldConsumerWithBuilder( String emptyConstructorArgs, Map additionalTemplateArguments, TypeName parentBuilderType, - ProcessingContext context) { + BuilderProcessingContext context) { TypeName fieldBuilderType = fieldBuilder.typeName(); TypeNameGeneric consumerType = createConsumerType(fieldBuilderType); MethodParameterDto parameter = new MethodParameterDto(); @@ -381,7 +382,7 @@ public static BuilderMethodDto createFieldConsumerWithElementBuilders( TypeName collectionBuilderType, ResolvedBuilder elementBuilder, TypeName returnBuilderType, - ProcessingContext context) { + BuilderProcessingContext context) { // The collection builder receives a supplier for element builders: the resolved // instantiation path as a method reference String elementSupplier = @@ -409,7 +410,7 @@ public static BuilderMethodDto createFieldConsumerWithElementBuilders( * @return the method DTO for the simple field consumer */ public static BuilderMethodDto createSimpleFieldConsumer( - FieldDto field, TypeName fieldType, TypeName builderType, ProcessingContext context) { + FieldDto field, TypeName fieldType, TypeName builderType, BuilderProcessingContext context) { TypeNameGeneric consumerType = createConsumerType(fieldType); MethodParameterDto parameter = new MethodParameterDto(); parameter.setParameterName(field.getOriginalFieldName() + SUFFIX_CONSUMER); diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index b88c1ab4..a1841da4 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -47,7 +47,7 @@ * {@link Types}, logging and performance tracking, providing domain-agnostic helpers for type and * element operations. * - *

Builder-specific state lives in {@link ProcessingContext}, which extends this base. + *

Builder-specific state lives in {@link BuilderProcessingContext}, which extends this base. */ public abstract class AnnotationProcessingContext { diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderConfigurationReader.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderConfigurationReader.java index e2cfedb4..2868ffa8 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderConfigurationReader.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderConfigurationReader.java @@ -133,8 +133,8 @@ public BuilderConfiguration getGlobalConfiguration() { *

  • {@code BuilderConfiguration} — add the field, builder method, merge logic, and a typed * accessor (e.g. {@code formattingModeEnum}) if enum conversion is needed. Set the default * in {@code BuilderConfiguration.DEFAULT}. - *
  • {@code ProcessingContext} — should NOT need a dedicated field or getter. The resolved - * per-target config ({@code context.getConfiguration()}) and global config ({@code + *
  • {@code BuilderProcessingContext} — should NOT need a dedicated field or getter. The + * resolved per-target config ({@code context.getConfiguration()}) and global config ({@code * context.getConfigurationReader().getGlobalConfiguration()}) carry all option values. * Special-casing outside {@code BuilderConfiguration} breaks the merge chain and bypasses * annotation overrides. diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderDefinitionCreator.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderDefinitionCreator.java index 4c75d9a7..fcc58502 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderDefinitionCreator.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderDefinitionCreator.java @@ -89,7 +89,7 @@ private BuilderDefinitionCreator() { * @throws BuilderException if validation or generation failed */ public static BuilderDefinitionDto extractFromElement( - Element annotatedElement, ProcessingContext context) throws BuilderException { + Element annotatedElement, BuilderProcessingContext context) throws BuilderException { validateAnnotatedElement(annotatedElement); TypeElement annotatedType = (TypeElement) annotatedElement; @@ -172,7 +172,7 @@ public static BuilderDefinitionDto extractFromElement( * @param context the processing context */ private static void finalizeDefinition( - BuilderDefinitionDto builderDto, ProcessingContext context) { + BuilderDefinitionDto builderDto, BuilderProcessingContext context) { context.debugStartOperation("Finalizing builder definition"); // 1. Convert FieldDto → ClassFieldDto @@ -325,7 +325,7 @@ private static String buildSetterSourceDescription(FieldDto field, String source * @param context the processing context for logging */ private static void resolveMethodConflicts( - BuilderDefinitionDto builderDto, ProcessingContext context) { + BuilderDefinitionDto builderDto, BuilderProcessingContext context) { context.debugStartOperation("Resolving method conflicts"); // Collect all BuilderMethodDto instances grouped by signature key @@ -456,7 +456,7 @@ private static ClassFieldDto convertToClassField(FieldDto field) { /** Initializes the builder definition with package, class name, and generics. */ private static BuilderDefinitionDto initializeBuilderDefinition( - TypeElement annotatedType, ProcessingContext context) { + TypeElement annotatedType, BuilderProcessingContext context) { BuilderDefinitionDto result = new BuilderDefinitionDto(); String packageName = context.getPackageName(annotatedType); String builderPackageName = context.getBuilderPackageName(); @@ -487,7 +487,7 @@ private static BuilderDefinitionDto initializeBuilderDefinition( private static List extractConstructorFields( TypeElement annotatedType, BuilderDefinitionDto builderDef, - ProcessingContext context, + BuilderProcessingContext context, Map fieldNameRegistry) { List constructorFields = new LinkedList<>(); Optional constructorOpt = @@ -527,7 +527,7 @@ private static List extractConstructorFields( private static List extractSetterFields( TypeElement annotatedType, BuilderDefinitionDto result, - ProcessingContext context, + BuilderProcessingContext context, Map fieldNameRegistry) { context.debugStartOperation("Analysing setters for finding fields"); List setterFields = new LinkedList<>(); @@ -592,7 +592,7 @@ private static List extractSetterFields( } /** Logs the addition of a field with its type information. */ - private static void logFieldAddition(FieldDto field, ProcessingContext context) { + private static void logFieldAddition(FieldDto field, BuilderProcessingContext context) { String fieldTypeName = field.getFieldType().getClassName(); if (field.getFieldType().getPackageName() != null && !field.getFieldType().getPackageName().isEmpty()) { @@ -603,7 +603,7 @@ private static void logFieldAddition(FieldDto field, ProcessingContext context) } private static boolean isMethodRelevantForBuilder( - ExecutableElement mth, ProcessingContext context) { + ExecutableElement mth, BuilderProcessingContext context) { if (!hasNoThrowablesDeclared(mth)) { context.debug("Skipping: declares throwables"); return false; @@ -634,7 +634,7 @@ private static boolean isMethodRelevantForBuilder( private static Optional createFieldFromSetter( ExecutableElement mth, TypeName builderType, - ProcessingContext context, + BuilderProcessingContext context, Map fieldNameRegistry) { String methodName = mth.getSimpleName().toString(); String fieldName = StringUtils.uncapitalize(Strings.CI.removeStart(methodName, "set")); @@ -706,7 +706,7 @@ private static Optional createFieldFromConstructor( TypeElement annotatedType, VariableElement param, TypeName builderType, - ProcessingContext context, + BuilderProcessingContext context, Map fieldNameRegistry) { String fieldName = param.getSimpleName().toString(); // Extract javadoc from constructor parameter (if present) @@ -746,7 +746,7 @@ private static String resolveFieldNameConflict( String fieldName, VariableElement param, Map fieldNameRegistry, - ProcessingContext context) { + BuilderProcessingContext context) { FieldDto existing = fieldNameRegistry.get(fieldName); if (existing == null) { @@ -806,7 +806,7 @@ private static Optional createFieldDto( VariableElement param, TypeName dtoType, TypeName builderType, - ProcessingContext context) { + BuilderProcessingContext context) { MethodParameterDto paramDto = map2MethodParameter(param, context); if (paramDto == null || dtoType == null) { return Optional.empty(); @@ -922,7 +922,7 @@ private static void detectAndApplyFieldDeprecation( VariableElement param, TypeMirror fieldTypeMirror, TypeElement dtoTypeElement, - ProcessingContext context) { + BuilderProcessingContext context) { if (dtoTypeElement == null) { return; } @@ -1042,7 +1042,9 @@ private static void applyDeprecationToMethod( * @param context processing context */ private static void applyDtoDeprecation( - BuilderDefinitionDto builderDto, TypeElement annotatedType, ProcessingContext context) { + BuilderDefinitionDto builderDto, + TypeElement annotatedType, + BuilderProcessingContext context) { Optional deprecatedAnnot = FieldAnnotationExtractor.extractDeprecatedAnnotation(annotatedType, context); if (deprecatedAnnot.isEmpty()) { @@ -1116,7 +1118,9 @@ private static void addDeprecatedJavadoc(JavadocDto javadoc, String deprecatedJa * @param context processing context */ private static void applyDeprecationSuppressions( - BuilderDefinitionDto builderDto, TypeElement annotatedType, ProcessingContext context) { + BuilderDefinitionDto builderDto, + TypeElement annotatedType, + BuilderProcessingContext context) { boolean dtoDeprecated = annotatedType.getAnnotation(Deprecated.class) != null; boolean constructorDeprecated = isConstructorDeprecated(annotatedType, context); // Check getter method deprecation from the flag stored during field creation — a deprecated @@ -1182,7 +1186,7 @@ private static void applyDeprecationSuppressions( * @return {@code true} if the selected constructor is deprecated */ private static boolean isConstructorDeprecated( - TypeElement annotatedType, ProcessingContext context) { + TypeElement annotatedType, BuilderProcessingContext context) { return JavaLangAnalyser.findConstructorForBuilder( annotatedType, SimpleBuilderConstructor.class, context) .filter(ctor -> ctor.getAnnotation(Deprecated.class) != null) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java similarity index 98% rename from processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java rename to processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java index f3a2cdf2..b05d7e3c 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java @@ -44,7 +44,7 @@ * *

    This eliminates repetitive parameter passing and provides a cleaner API. */ -public final class ProcessingContext extends AnnotationProcessingContext +public final class BuilderProcessingContext extends AnnotationProcessingContext implements TypeMappingContext { private final BuilderConfigurationReader configurationReader; private final BuilderScopeResolver builderScopeResolver; @@ -59,7 +59,7 @@ public final class ProcessingContext extends AnnotationProcessingContext * @param globalConfiguration the global builder configuration read from compiler arguments * @param processingEnv the processing environment providing access to utilities and facilities */ - public ProcessingContext( + public BuilderProcessingContext( ProcessingLogger logger, BuilderConfiguration globalConfiguration, ProcessingEnvironment processingEnv) { diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingTarget.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingTarget.java index d523006c..f33d0478 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingTarget.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/ProcessingTarget.java @@ -30,8 +30,8 @@ * Per-target processing state for the type whose builder is currently being generated. * *

    {@link org.javahelpers.simple.builders.processor.BuilderProcessor} sets one instance per - * processed type on the {@link ProcessingContext} before extraction starts, so downstream analysis - * can reach it without threading both values through every call. + * processed type on the {@link BuilderProcessingContext} before extraction starts, so downstream + * analysis can reach it without threading both values through every call. * * @param configuration the resolved builder configuration for the current target * @param builderPackage the package the generated builder is written to. This is the configured diff --git a/processor/src/test/java/org/javahelpers/simple/builders/processor/BuilderScopeResolverTest.java b/processor/src/test/java/org/javahelpers/simple/builders/processor/BuilderScopeResolverTest.java index 32678366..4d880371 100644 --- a/processor/src/test/java/org/javahelpers/simple/builders/processor/BuilderScopeResolverTest.java +++ b/processor/src/test/java/org/javahelpers/simple/builders/processor/BuilderScopeResolverTest.java @@ -47,7 +47,7 @@ import org.javahelpers.simple.builders.processor.model.type.BuilderInstantiation; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import org.javahelpers.simple.builders.processor.processing.ProcessingTarget; import org.javahelpers.simple.builders.processor.processing.logging.ProcessingLogger; import org.javahelpers.simple.builders.processor.testing.ProcessorTestUtils; @@ -1314,8 +1314,8 @@ public boolean process(Set annotations, RoundEnvironment return false; } TypeElement helper = processingEnv.getElementUtils().getTypeElement("lib.LibHelper"); - ProcessingContext context = - new ProcessingContext( + BuilderProcessingContext context = + new BuilderProcessingContext( ProcessingLogger.create(processingEnv), BuilderConfiguration.DEFAULT, processingEnv); context.initProcessingTarget(new ProcessingTarget(configuration("lib", "Builder"), "")); BuilderScopeResolver resolver = context.getBuilderScopeResolver(); diff --git a/processor/src/test/java/org/javahelpers/simple/builders/processor/CustomizingDocumentationTest.java b/processor/src/test/java/org/javahelpers/simple/builders/processor/CustomizingDocumentationTest.java index a040bc39..c7c34e3c 100644 --- a/processor/src/test/java/org/javahelpers/simple/builders/processor/CustomizingDocumentationTest.java +++ b/processor/src/test/java/org/javahelpers/simple/builders/processor/CustomizingDocumentationTest.java @@ -122,18 +122,18 @@ void testGeneratorInterfaceStructure() { import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class TestMethodGenerator implements MethodGenerator { @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { // Check if field type is String by comparing class name return "java.lang.String".equals(field.getFieldType().getFullQualifiedName()); } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { return List.of(); } @@ -165,16 +165,16 @@ void testBuilderEnhancerStructure() { import org.javahelpers.simple.builders.processor.generators.BuilderEnhancer; import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; public class TestBuilderEnhancer implements BuilderEnhancer { @Override - public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return true; } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { // Enhancement logic } @@ -208,17 +208,17 @@ void testCustomGeneratorMethodCreation() { import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class CustomHelperGenerator implements MethodGenerator { @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return "java.lang.String".equals(field.getFieldType().getFullQualifiedName()); } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { String fieldName = field.getFieldNameInBuilder(); String methodName = "custom" + capitalize(fieldName); @@ -268,17 +268,17 @@ void testGeneratorPriorityPattern() { import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class HighPriorityGenerator implements MethodGenerator { @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return true; } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { return List.of(); } @@ -299,7 +299,7 @@ public int getPriority() { /** * Test error handling pattern from CUSTOMIZING.md. * - *

    Validates the recommended error handling approach using ProcessingContext. + *

    Validates the recommended error handling approach using BuilderProcessingContext. */ @Test void testErrorHandlingPattern() { @@ -311,17 +311,17 @@ void testErrorHandlingPattern() { import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class SafeGenerator implements MethodGenerator { @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return true; } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { try { // Generation logic return List.of(); @@ -360,12 +360,12 @@ void testConditionalApplicationPattern() { import org.javahelpers.simple.builders.processor.model.core.FieldDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class ConditionalGenerator implements MethodGenerator { @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { // Check if component should apply if (!shouldApply(field, context)) { return false; @@ -376,7 +376,7 @@ public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext con } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { return List.of(); } @@ -385,7 +385,7 @@ public int getPriority() { return 100; } - private boolean shouldApply(FieldDto field, ProcessingContext context) { + private boolean shouldApply(FieldDto field, BuilderProcessingContext context) { return "java.lang.String".equals(field.getFieldType().getFullQualifiedName()); } } @@ -415,7 +415,7 @@ void testCompleteCustomValidationGenerator() { import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class CustomValidationGenerator implements MethodGenerator { @@ -424,14 +424,14 @@ public class CustomValidationGenerator implements MethodGenerator { new TypeName("org.javahelpers.simple.builders.core.util", "TrackedValue"); @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { // Only apply to String fields with @Email annotation return "java.lang.String".equals(field.getFieldType().getFullQualifiedName()) && field.hasAnnotation("javax.validation.constraints.Email"); } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { String fieldName = field.getFieldNameInBuilder(); String methodName = "validated" + capitalize(fieldName); @@ -490,12 +490,12 @@ void testCompleteCustomValidationEnhancer() { import org.javahelpers.simple.builders.processor.model.core.BuilderDefinitionDto; import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; public class CustomValidationEnhancer implements BuilderEnhancer { @Override - public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { // Only apply to DTOs with validation annotations return builderDto.getAllFieldsForBuilder().stream() .flatMap(field -> field.getParameterAnnotations().stream()) @@ -507,7 +507,7 @@ public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, Proc } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { // Add validation method to builder BuilderMethodDto validateMethod = createValidateMethod(); builderDto.addMethod(validateMethod); @@ -535,7 +535,7 @@ private BuilderMethodDto createValidateMethod() { return method; } - private boolean isValidationAvailable(ProcessingContext context) { + private boolean isValidationAvailable(BuilderProcessingContext context) { return context.getTypeElement("javax.validation.Valid") != null; } } @@ -600,19 +600,19 @@ void testDateParserGeneratorExample() { import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import java.util.List; public class DateParserGenerator implements MethodGenerator { @Override - public boolean appliesTo(FieldDto field, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(FieldDto field, TypeName dtoType, BuilderProcessingContext context) { return "java.time.LocalDate".equals(field.getFieldType().getFullQualifiedName()) && field.hasAnnotation("org.javahelpers.simple.builders.processor.testannotations.ParseFromString"); } @Override - public List generateMethods(FieldDto field, TypeName builderType, ProcessingContext context) { + public List generateMethods(FieldDto field, TypeName builderType, BuilderProcessingContext context) { String fieldName = field.getFieldNameInBuilder(); String methodName = fieldName + "FromString"; @@ -664,17 +664,17 @@ void testBuilderFactoryEnhancerExample() { import org.javahelpers.simple.builders.processor.model.method.BuilderMethodDto; import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; - import org.javahelpers.simple.builders.processor.processing.ProcessingContext; + import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; public class BuilderFactoryEnhancer implements BuilderEnhancer { @Override - public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, ProcessingContext context) { + public boolean appliesTo(BuilderDefinitionDto builderDto, TypeName dtoType, BuilderProcessingContext context) { return dtoType.hasAnnotation("org.javahelpers.simple.builders.processor.testannotations.BuilderFactory"); } @Override - public void enhanceBuilder(BuilderDefinitionDto builderDto, ProcessingContext context) { + public void enhanceBuilder(BuilderDefinitionDto builderDto, BuilderProcessingContext context) { TypeName builderType = builderDto.getBuilderTypeName(); // Add static factory method (conceptual - actual API may differ) diff --git a/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java b/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java index fb0940e0..428a3125 100644 --- a/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java +++ b/processor/src/test/java/org/javahelpers/simple/builders/processor/RoasterCodeGeneratorResilienceTest.java @@ -43,7 +43,7 @@ import org.javahelpers.simple.builders.processor.model.method.MethodDto; import org.javahelpers.simple.builders.processor.model.method.MethodParameterDto; import org.javahelpers.simple.builders.processor.model.type.TypeName; -import org.javahelpers.simple.builders.processor.processing.ProcessingContext; +import org.javahelpers.simple.builders.processor.processing.BuilderProcessingContext; import org.javahelpers.simple.builders.processor.processing.SourceFormatterResolver; import org.javahelpers.simple.builders.processor.processing.logging.ProcessingLogger; import org.javahelpers.simple.builders.processor.testing.CapturingProcessingLogger; @@ -85,7 +85,8 @@ void shouldWrapRenderingRuntimeExceptionInCodeGenerationException() { ProcessingEnvironment env = ProcessingEnvironmentStub.createEmpty(); ProcessingLogger logger = ProcessingLogger.create(env); - ProcessingContext context = new ProcessingContext(logger, BuilderConfiguration.DEFAULT, env); + BuilderProcessingContext context = + new BuilderProcessingContext(logger, BuilderConfiguration.DEFAULT, env); RoasterCodeGenerator generator = new RoasterCodeGenerator( new GenerationEnvironment( @@ -117,8 +118,8 @@ void shouldKeepFirstMethodAndWarnOnDuplicateSignature() { CapturingProcessingLogger capturing = CapturingProcessingLogger.create(); ProcessingEnvironment env = ProcessingEnvironmentStub.createEmpty(); - ProcessingContext context = - new ProcessingContext(capturing.logger(), BuilderConfiguration.DEFAULT, env); + BuilderProcessingContext context = + new BuilderProcessingContext(capturing.logger(), BuilderConfiguration.DEFAULT, env); RoasterCodeGenerator generator = new RoasterCodeGenerator( new GenerationEnvironment( From f6735090e6b5908684d9a41286243c49826a63f8 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:42:59 +0000 Subject: [PATCH 04/12] processing: inject strict mode via AnnotationProcessingOptions record (#348) --- .../AnnotationProcessingContext.java | 48 ++++++++++++++++++- .../AnnotationProcessingOptions.java | 35 ++++++++++++++ .../processing/BuilderProcessingContext.java | 46 ++---------------- 3 files changed, 87 insertions(+), 42 deletions(-) create mode 100644 processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index a1841da4..e4ccaab2 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -66,22 +66,28 @@ public abstract class AnnotationProcessingContext { /** Performance tracker for pipeline phase timing. */ protected final PerformanceTracker performanceTracker; + /** Static options supplied by the concrete context. */ + protected final AnnotationProcessingOptions options; + /** * Creates the context. * * @param logger logger for output * @param processingEnv the annotation processing environment * @param performanceTracker tracker for pipeline phase timing + * @param options static options of the concrete context */ public AnnotationProcessingContext( ProcessingLogger logger, ProcessingEnvironment processingEnv, - PerformanceTracker performanceTracker) { + PerformanceTracker performanceTracker, + AnnotationProcessingOptions options) { this.elementUtils = processingEnv.getElementUtils(); this.typeUtils = processingEnv.getTypeUtils(); this.logger = logger; this.processingEnv = processingEnv; this.performanceTracker = performanceTracker; + this.options = options; } /** @@ -180,6 +186,46 @@ public String getPackageName(Element element) { return elementUtils.getPackageOf(element).getQualifiedName().toString(); } + /** + * Returns whether strict/fail-fast mode is enabled via the supplied {@link + * AnnotationProcessingOptions}. + * + * @return {@code true} if strict mode is enabled, {@code false} otherwise + */ + public boolean isStrictModeEnabled() { + return options.strictModeEnabled(); + } + + /** + * Reports an error or warning based on strict mode. In strict mode a build failure is emitted; + * otherwise a warning is logged so processing can continue. + * + * @param element the element associated with the problem, for compiler location information + * @param format the format string + * @param args arguments referenced by the format specifiers + */ + public void reportBasedOnStrictMode(Element element, String format, Object... args) { + if (isStrictModeEnabled()) { + logger.error(element, format, args); + } else { + logger.warning(element, format, args); + } + } + + /** + * Reports an error or warning based on strict mode, without an element location. + * + * @param format the format string + * @param args arguments referenced by the format specifiers + */ + public void reportBasedOnStrictMode(String format, Object... args) { + if (isStrictModeEnabled()) { + logger.error(format, args); + } else { + logger.warning(format, args); + } + } + /** * Returns the name of the package generated code is written to. * diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java new file mode 100644 index 00000000..7b7815ed --- /dev/null +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java @@ -0,0 +1,35 @@ +/* + * MIT License + * + * Copyright (c) 2025-2026 Andreas Igel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.javahelpers.simple.builders.processor.processing; + +/** + * Static options a concrete annotation-processing context supplies to {@link + * AnnotationProcessingContext} at construction. How each option is derived (compiler arguments, + * annotation configuration, ...) is the concrete context's responsibility. + * + * @param strictModeEnabled whether strict/fail-fast mode is enabled: strict mode reports problems + * as errors, otherwise as warnings + */ +public record AnnotationProcessingOptions(boolean strictModeEnabled) {} diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java index b05d7e3c..50dfab46 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java @@ -63,7 +63,11 @@ public BuilderProcessingContext( ProcessingLogger logger, BuilderConfiguration globalConfiguration, ProcessingEnvironment processingEnv) { - super(logger, processingEnv, createPerformanceTracker(processingEnv)); + super( + logger, + processingEnv, + createPerformanceTracker(processingEnv), + new AnnotationProcessingOptions(globalConfiguration.isStrictModeEnabled())); this.configurationReader = new BuilderConfigurationReader(globalConfiguration, logger, elementUtils); this.builderScopeResolver = new BuilderScopeResolver(this); @@ -179,44 +183,4 @@ public boolean shouldCopyTypeAnnotations() { public Optional resolveGeneratedType(TypeElement typeElement) { return builderScopeResolver.resolveUsableBuilderType(typeElement); } - - /** - * Returns whether strict/fail-fast generation mode is enabled via the global compiler - * configuration. - * - * @return true if {@code -Asimplebuilder.strict=true} was supplied, false otherwise - */ - public boolean isStrictModeEnabled() { - return configurationReader.getGlobalConfiguration().isStrictModeEnabled(); - } - - /** - * Reports an error or warning based on strict mode. In strict mode a build failure is emitted; - * otherwise a warning is logged so generation of remaining builders can continue. - * - * @param element the element associated with the problem, for compiler location information - * @param format the format string - * @param args arguments referenced by the format specifiers - */ - public void reportBasedOnStrictMode(Element element, String format, Object... args) { - if (isStrictModeEnabled()) { - logger.error(element, format, args); - } else { - logger.warning(element, format, args); - } - } - - /** - * Reports an error or warning based on strict mode, without an element location. - * - * @param format the format string - * @param args arguments referenced by the format specifiers - */ - public void reportBasedOnStrictMode(String format, Object... args) { - if (isStrictModeEnabled()) { - logger.error(format, args); - } else { - logger.warning(format, args); - } - } } From 6319139a4bf9b22c267762544fdb7036bc7220a5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 21:57:39 +0000 Subject: [PATCH 05/12] processing: move performance-tracker init into base via options builder (#348) --- .../AnnotationProcessingContext.java | 20 ++++- .../AnnotationProcessingOptions.java | 89 ++++++++++++++++++- .../processing/BuilderProcessingContext.java | 27 +++--- 3 files changed, 116 insertions(+), 20 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index e4ccaab2..f518804d 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -39,6 +39,8 @@ import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import org.javahelpers.simple.builders.processor.model.type.TypeName; +import org.javahelpers.simple.builders.processor.processing.logging.ActivePerformanceTracker; +import org.javahelpers.simple.builders.processor.processing.logging.NoOpPerformanceTracker; import org.javahelpers.simple.builders.processor.processing.logging.PerformanceTracker; import org.javahelpers.simple.builders.processor.processing.logging.ProcessingLogger; @@ -69,24 +71,36 @@ public abstract class AnnotationProcessingContext { /** Static options supplied by the concrete context. */ protected final AnnotationProcessingOptions options; + /** + * Creates the context with default options (strict mode and performance tracking disabled). + * + * @param logger logger for output + * @param processingEnv the annotation processing environment + */ + public AnnotationProcessingContext(ProcessingLogger logger, ProcessingEnvironment processingEnv) { + this(logger, processingEnv, AnnotationProcessingOptions.builder().build()); + } + /** * Creates the context. * * @param logger logger for output * @param processingEnv the annotation processing environment - * @param performanceTracker tracker for pipeline phase timing * @param options static options of the concrete context */ public AnnotationProcessingContext( ProcessingLogger logger, ProcessingEnvironment processingEnv, - PerformanceTracker performanceTracker, AnnotationProcessingOptions options) { this.elementUtils = processingEnv.getElementUtils(); this.typeUtils = processingEnv.getTypeUtils(); this.logger = logger; this.processingEnv = processingEnv; - this.performanceTracker = performanceTracker; + this.performanceTracker = + options.performanceTrackingEnabled() + ? new ActivePerformanceTracker( + options.performanceOutputFile(), options.phaseHierarchy()) + : new NoOpPerformanceTracker(); this.options = options; } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java index 7b7815ed..c5ca509c 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java @@ -24,6 +24,10 @@ package org.javahelpers.simple.builders.processor.processing; +import java.util.List; +import java.util.Map; +import org.javahelpers.simple.builders.processor.processing.logging.PhaseHierarchy; + /** * Static options a concrete annotation-processing context supplies to {@link * AnnotationProcessingContext} at construction. How each option is derived (compiler arguments, @@ -31,5 +35,88 @@ * * @param strictModeEnabled whether strict/fail-fast mode is enabled: strict mode reports problems * as errors, otherwise as warnings + * @param performanceTrackingEnabled whether pipeline phase timing is collected + * @param performanceOutputFile file the performance report is written to + * @param phaseHierarchy the phase tree the performance report renders with */ -public record AnnotationProcessingOptions(boolean strictModeEnabled) {} +public record AnnotationProcessingOptions( + boolean strictModeEnabled, + boolean performanceTrackingEnabled, + String performanceOutputFile, + PhaseHierarchy phaseHierarchy) { + + /** + * Creates a builder for {@link AnnotationProcessingOptions}. Defaults: strict mode and + * performance tracking disabled, no output file, empty phase hierarchy. + * + * @return a new builder + */ + public static Builder builder() { + return new Builder(); + } + + /** Builder for {@link AnnotationProcessingOptions}. */ + public static final class Builder { + + private boolean strictModeEnabled; + private boolean performanceTrackingEnabled; + private String performanceOutputFile; + private PhaseHierarchy phaseHierarchy = new PhaseHierarchy(List.of(), Map.of()); + + private Builder() {} + + /** + * Sets whether strict/fail-fast mode is enabled. + * + * @param strictModeEnabled {@code true} to report problems as errors instead of warnings + * @return this builder + */ + public Builder strictModeEnabled(boolean strictModeEnabled) { + this.strictModeEnabled = strictModeEnabled; + return this; + } + + /** + * Sets whether pipeline phase timing is collected. + * + * @param performanceTrackingEnabled {@code true} to enable performance tracking + * @return this builder + */ + public Builder performanceTrackingEnabled(boolean performanceTrackingEnabled) { + this.performanceTrackingEnabled = performanceTrackingEnabled; + return this; + } + + /** + * Sets the file the performance report is written to. + * + * @param performanceOutputFile path of the report output file + * @return this builder + */ + public Builder performanceOutputFile(String performanceOutputFile) { + this.performanceOutputFile = performanceOutputFile; + return this; + } + + /** + * Sets the phase tree the performance report renders with. + * + * @param phaseHierarchy top-level phases in display order and their sub-phases + * @return this builder + */ + public Builder phaseHierarchy(PhaseHierarchy phaseHierarchy) { + this.phaseHierarchy = phaseHierarchy; + return this; + } + + /** + * Builds the options. + * + * @return the configured {@link AnnotationProcessingOptions} + */ + public AnnotationProcessingOptions build() { + return new AnnotationProcessingOptions( + strictModeEnabled, performanceTrackingEnabled, performanceOutputFile, phaseHierarchy); + } + } +} diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java index 50dfab46..f1146df6 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java @@ -33,9 +33,6 @@ import org.javahelpers.simple.builders.processor.generators.registry.GeneratorRegistry; import org.javahelpers.simple.builders.processor.model.core.BuilderConfiguration; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; -import org.javahelpers.simple.builders.processor.processing.logging.ActivePerformanceTracker; -import org.javahelpers.simple.builders.processor.processing.logging.NoOpPerformanceTracker; -import org.javahelpers.simple.builders.processor.processing.logging.PerformanceTracker; import org.javahelpers.simple.builders.processor.processing.logging.ProcessingLogger; /** @@ -63,26 +60,24 @@ public BuilderProcessingContext( ProcessingLogger logger, BuilderConfiguration globalConfiguration, ProcessingEnvironment processingEnv) { - super( - logger, - processingEnv, - createPerformanceTracker(processingEnv), - new AnnotationProcessingOptions(globalConfiguration.isStrictModeEnabled())); + super(logger, processingEnv, createOptions(processingEnv, globalConfiguration)); this.configurationReader = new BuilderConfigurationReader(globalConfiguration, logger, elementUtils); this.builderScopeResolver = new BuilderScopeResolver(this); // GeneratorRegistry will be lazily initialized on first access } - private static PerformanceTracker createPerformanceTracker(ProcessingEnvironment processingEnv) { - // Initialize performance tracker based on compiler argument + private static AnnotationProcessingOptions createOptions( + ProcessingEnvironment processingEnv, BuilderConfiguration globalConfiguration) { + // Derive generic context options from the builder's compiler arguments CompilerArgumentsReader argReader = new CompilerArgumentsReader(processingEnv); - boolean perfTrackingEnabled = - argReader.readBooleanValue(CompilerArgumentsEnum.PERFORMANCE_TRACKING); - String perfOutputFile = argReader.readValue(CompilerArgumentsEnum.PERFORMANCE_OUTPUT_FILE); - return perfTrackingEnabled - ? new ActivePerformanceTracker(perfOutputFile, PipelinePhases.PIPELINE_HIERARCHY) - : new NoOpPerformanceTracker(); + return AnnotationProcessingOptions.builder() + .strictModeEnabled(globalConfiguration.isStrictModeEnabled()) + .performanceTrackingEnabled( + argReader.readBooleanValue(CompilerArgumentsEnum.PERFORMANCE_TRACKING)) + .performanceOutputFile(argReader.readValue(CompilerArgumentsEnum.PERFORMANCE_OUTPUT_FILE)) + .phaseHierarchy(PipelinePhases.PIPELINE_HIERARCHY) + .build(); } /** From b03afca2b74c4e65421a0c5cdc774b436354676f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:00:36 +0000 Subject: [PATCH 06/12] processing: default strict mode to enabled in options builder (#348) --- .../processor/processing/AnnotationProcessingContext.java | 2 +- .../processor/processing/AnnotationProcessingOptions.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index f518804d..331cb170 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -72,7 +72,7 @@ public abstract class AnnotationProcessingContext { protected final AnnotationProcessingOptions options; /** - * Creates the context with default options (strict mode and performance tracking disabled). + * Creates the context with default options (strict mode enabled, performance tracking disabled). * * @param logger logger for output * @param processingEnv the annotation processing environment diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java index c5ca509c..872b80e2 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingOptions.java @@ -46,7 +46,7 @@ public record AnnotationProcessingOptions( PhaseHierarchy phaseHierarchy) { /** - * Creates a builder for {@link AnnotationProcessingOptions}. Defaults: strict mode and + * Creates a builder for {@link AnnotationProcessingOptions}. Defaults: strict mode enabled, * performance tracking disabled, no output file, empty phase hierarchy. * * @return a new builder @@ -58,7 +58,7 @@ public static Builder builder() { /** Builder for {@link AnnotationProcessingOptions}. */ public static final class Builder { - private boolean strictModeEnabled; + private boolean strictModeEnabled = true; private boolean performanceTrackingEnabled; private String performanceOutputFile; private PhaseHierarchy phaseHierarchy = new PhaseHierarchy(List.of(), Map.of()); From ef6993168463950738a6caf9cca6e16777f04dbf Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:10:34 +0000 Subject: [PATCH 07/12] processing: make AnnotationProcessingContext instantiable via default package hook (#348) --- .../processing/AnnotationProcessingContext.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index 331cb170..d478966b 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -51,7 +51,7 @@ * *

    Builder-specific state lives in {@link BuilderProcessingContext}, which extends this base. */ -public abstract class AnnotationProcessingContext { +public class AnnotationProcessingContext { /** Element utility of the annotation processing framework. */ protected final Elements elementUtils; @@ -121,7 +121,7 @@ public Map getElementValuesWithDefaults( * Gets the performance tracker for this processing context. * *

    When performance tracking is disabled, returns a {@link NoOpPerformanceTracker} that has - * zero overhead. When enabled via {@code -Asimplebuilder.performanceTracking=true}, returns an + * zero overhead. When enabled via the supplied {@link AnnotationProcessingOptions}, returns an * {@link ActivePerformanceTracker} that measures execution times. * * @return the performance tracker instance @@ -243,9 +243,12 @@ public void reportBasedOnStrictMode(String format, Object... args) { /** * Returns the name of the package generated code is written to. * - * @return the qualified name of the package generated classes are placed in + * @return the qualified name of the package generated classes are placed in, or {@code null} when + * the context generates no code into a specific package */ - protected abstract String getGeneratedPackageName(); + protected String getGeneratedPackageName() { + return null; + } /** * Checks whether a member (constructor, method) is accessible from the package generated code is @@ -266,7 +269,8 @@ public boolean isAccessibleFromGeneratedPackage(Element member) { if (member.getModifiers().contains(Modifier.PRIVATE)) { return false; } - return getPackageName(member).equals(getGeneratedPackageName()); + String generatedPackage = getGeneratedPackageName(); + return generatedPackage != null && getPackageName(member).equals(generatedPackage); } /** From 1ab8c720ce9445e865a4dedaf9b8f097e0a7812d Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:12:02 +0000 Subject: [PATCH 08/12] processing: keep moved methods in upstream order in base class (#348) --- .../AnnotationProcessingContext.java | 146 +++++++++--------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index d478966b..9b3d1a31 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -104,6 +104,39 @@ public AnnotationProcessingContext( this.options = options; } + /** + * Returns the name of the package generated code is written to. + * + * @return the qualified name of the package generated classes are placed in, or {@code null} when + * the context generates no code into a specific package + */ + protected String getGeneratedPackageName() { + return null; + } + + /** + * Checks whether a member (constructor, method) is accessible from the package generated code is + * written to. + * + *

    Public members are always accessible. Private members are never accessible - generated code + * lives in a separate top-level class. Package-private and protected members are only accessible + * when the member's declaring package equals the generated package (protected access through + * inheritance does not apply, as generated code does not extend the target type). + * + * @param member the member to check + * @return {@code true} if generated code may call the member + */ + public boolean isAccessibleFromGeneratedPackage(Element member) { + if (member.getModifiers().contains(Modifier.PUBLIC)) { + return true; + } + if (member.getModifiers().contains(Modifier.PRIVATE)) { + return false; + } + String generatedPackage = getGeneratedPackageName(); + return generatedPackage != null && getPackageName(member).equals(generatedPackage); + } + /** * Returns the annotation values of an annotation mirror, including default values. * @@ -200,79 +233,6 @@ public String getPackageName(Element element) { return elementUtils.getPackageOf(element).getQualifiedName().toString(); } - /** - * Returns whether strict/fail-fast mode is enabled via the supplied {@link - * AnnotationProcessingOptions}. - * - * @return {@code true} if strict mode is enabled, {@code false} otherwise - */ - public boolean isStrictModeEnabled() { - return options.strictModeEnabled(); - } - - /** - * Reports an error or warning based on strict mode. In strict mode a build failure is emitted; - * otherwise a warning is logged so processing can continue. - * - * @param element the element associated with the problem, for compiler location information - * @param format the format string - * @param args arguments referenced by the format specifiers - */ - public void reportBasedOnStrictMode(Element element, String format, Object... args) { - if (isStrictModeEnabled()) { - logger.error(element, format, args); - } else { - logger.warning(element, format, args); - } - } - - /** - * Reports an error or warning based on strict mode, without an element location. - * - * @param format the format string - * @param args arguments referenced by the format specifiers - */ - public void reportBasedOnStrictMode(String format, Object... args) { - if (isStrictModeEnabled()) { - logger.error(format, args); - } else { - logger.warning(format, args); - } - } - - /** - * Returns the name of the package generated code is written to. - * - * @return the qualified name of the package generated classes are placed in, or {@code null} when - * the context generates no code into a specific package - */ - protected String getGeneratedPackageName() { - return null; - } - - /** - * Checks whether a member (constructor, method) is accessible from the package generated code is - * written to. - * - *

    Public members are always accessible. Private members are never accessible - generated code - * lives in a separate top-level class. Package-private and protected members are only accessible - * when the member's declaring package equals the generated package (protected access through - * inheritance does not apply, as generated code does not extend the target type). - * - * @param member the member to check - * @return {@code true} if generated code may call the member - */ - public boolean isAccessibleFromGeneratedPackage(Element member) { - if (member.getModifiers().contains(Modifier.PUBLIC)) { - return true; - } - if (member.getModifiers().contains(Modifier.PRIVATE)) { - return false; - } - String generatedPackage = getGeneratedPackageName(); - return generatedPackage != null && getPackageName(member).equals(generatedPackage); - } - /** * Get all members of a type, including inherited members. * @@ -441,4 +401,44 @@ public void warning(Element element, String format, Object... args) { public void error(String format, Object... args) { logger.error(format, args); } + + /** + * Returns whether strict/fail-fast mode is enabled via the supplied {@link + * AnnotationProcessingOptions}. + * + * @return {@code true} if strict mode is enabled, {@code false} otherwise + */ + public boolean isStrictModeEnabled() { + return options.strictModeEnabled(); + } + + /** + * Reports an error or warning based on strict mode. In strict mode a build failure is emitted; + * otherwise a warning is logged so processing can continue. + * + * @param element the element associated with the problem, for compiler location information + * @param format the format string + * @param args arguments referenced by the format specifiers + */ + public void reportBasedOnStrictMode(Element element, String format, Object... args) { + if (isStrictModeEnabled()) { + logger.error(element, format, args); + } else { + logger.warning(element, format, args); + } + } + + /** + * Reports an error or warning based on strict mode, without an element location. + * + * @param format the format string + * @param args arguments referenced by the format specifiers + */ + public void reportBasedOnStrictMode(String format, Object... args) { + if (isStrictModeEnabled()) { + logger.error(format, args); + } else { + logger.warning(format, args); + } + } } From ab429da7b77d520f182f4fb51d0b2d2a50fff1af Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:16:51 +0000 Subject: [PATCH 09/12] processing: carry generated package as state, drop the hook method (#348) --- .../processing/AnnotationProcessingContext.java | 16 +++++++++------- .../processing/BuilderProcessingContext.java | 6 +----- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index 9b3d1a31..8fb3cbd4 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -71,6 +71,9 @@ public class AnnotationProcessingContext { /** Static options supplied by the concrete context. */ protected final AnnotationProcessingOptions options; + /** Package generated code is written to, or {@code null} when not generating into a package. */ + private String generatedPackageName; + /** * Creates the context with default options (strict mode enabled, performance tracking disabled). * @@ -105,13 +108,13 @@ public AnnotationProcessingContext( } /** - * Returns the name of the package generated code is written to. + * Sets the name of the package generated code is written to. Called when the current generation + * target is known. * - * @return the qualified name of the package generated classes are placed in, or {@code null} when - * the context generates no code into a specific package + * @param generatedPackageName the qualified name of the package generated classes are placed in */ - protected String getGeneratedPackageName() { - return null; + protected void setGeneratedPackageName(String generatedPackageName) { + this.generatedPackageName = generatedPackageName; } /** @@ -133,8 +136,7 @@ public boolean isAccessibleFromGeneratedPackage(Element member) { if (member.getModifiers().contains(Modifier.PRIVATE)) { return false; } - String generatedPackage = getGeneratedPackageName(); - return generatedPackage != null && getPackageName(member).equals(generatedPackage); + return generatedPackageName != null && getPackageName(member).equals(generatedPackageName); } /** diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java index f1146df6..3c7d4076 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java @@ -88,6 +88,7 @@ private static AnnotationProcessingOptions createOptions( */ public void initProcessingTarget(ProcessingTarget processingTarget) { this.processingTarget = processingTarget; + setGeneratedPackageName(processingTarget.builderPackage()); } /** @@ -108,11 +109,6 @@ public String getBuilderPackageName() { return this.processingTarget.builderPackage(); } - @Override - protected String getGeneratedPackageName() { - return getBuilderPackageName(); - } - /** * Tests whether a member is accessible from the package the generated builder is written to. * From 3ae5189e2b58015da39bee96ba8c3c8bc5be94c0 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:25:59 +0000 Subject: [PATCH 10/12] processing: implement TypeMappingContext on base with neutral defaults (#348) --- .../AnnotationProcessingContext.java | 27 ++++++++++++++++++- .../processing/BuilderProcessingContext.java | 4 +-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index 8fb3cbd4..41e214b7 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; @@ -38,6 +39,8 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; +import org.javahelpers.simple.builders.processor.analysis.TypeMappingContext; +import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; import org.javahelpers.simple.builders.processor.model.type.TypeName; import org.javahelpers.simple.builders.processor.processing.logging.ActivePerformanceTracker; import org.javahelpers.simple.builders.processor.processing.logging.NoOpPerformanceTracker; @@ -51,7 +54,7 @@ * *

    Builder-specific state lives in {@link BuilderProcessingContext}, which extends this base. */ -public class AnnotationProcessingContext { +public class AnnotationProcessingContext implements TypeMappingContext { /** Element utility of the annotation processing framework. */ protected final Elements elementUtils; @@ -443,4 +446,26 @@ public void reportBasedOnStrictMode(String format, Object... args) { logger.warning(format, args); } } + + /** + * {@inheritDoc} + * + *

    Default: a generic context copies no type annotations; override to derive from + * configuration. + */ + @Override + public boolean shouldCopyTypeAnnotations() { + return false; + } + + /** + * {@inheritDoc} + * + *

    Default: a generic context knows no generated types; override to resolve generated + * replacement types. + */ + @Override + public Optional resolveGeneratedType(TypeElement typeElement) { + return Optional.empty(); + } } diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java index 3c7d4076..5598d2db 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/BuilderProcessingContext.java @@ -29,7 +29,6 @@ import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import org.javahelpers.simple.builders.processor.analysis.BuilderScopeResolver; -import org.javahelpers.simple.builders.processor.analysis.TypeMappingContext; import org.javahelpers.simple.builders.processor.generators.registry.GeneratorRegistry; import org.javahelpers.simple.builders.processor.model.core.BuilderConfiguration; import org.javahelpers.simple.builders.processor.model.type.ResolvedBuilder; @@ -41,8 +40,7 @@ * *

    This eliminates repetitive parameter passing and provides a cleaner API. */ -public final class BuilderProcessingContext extends AnnotationProcessingContext - implements TypeMappingContext { +public final class BuilderProcessingContext extends AnnotationProcessingContext { private final BuilderConfigurationReader configurationReader; private final BuilderScopeResolver builderScopeResolver; From 24e71e43b4077c570d395636fc043c94ec72859f Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:27:56 +0000 Subject: [PATCH 11/12] processing: place TypeMappingContext methods at their upstream position (#348) --- .../AnnotationProcessingContext.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index 41e214b7..17fb9dc2 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -185,6 +185,28 @@ public void endPerformancePhase(String phase) { performanceTracker.endPhase(phase); } + /** + * {@inheritDoc} + * + *

    Default: a generic context copies no type annotations; override to derive from + * configuration. + */ + @Override + public boolean shouldCopyTypeAnnotations() { + return false; + } + + /** + * {@inheritDoc} + * + *

    Default: a generic context knows no generated types; override to resolve generated + * replacement types. + */ + @Override + public Optional resolveGeneratedType(TypeElement typeElement) { + return Optional.empty(); + } + /** * Get the TypeElement for a given qualified class name. * @@ -446,26 +468,4 @@ public void reportBasedOnStrictMode(String format, Object... args) { logger.warning(format, args); } } - - /** - * {@inheritDoc} - * - *

    Default: a generic context copies no type annotations; override to derive from - * configuration. - */ - @Override - public boolean shouldCopyTypeAnnotations() { - return false; - } - - /** - * {@inheritDoc} - * - *

    Default: a generic context knows no generated types; override to resolve generated - * replacement types. - */ - @Override - public Optional resolveGeneratedType(TypeElement typeElement) { - return Optional.empty(); - } } From 6a9e652cf69077ab8d54c7c5f8e4afc7253b6fb4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:33:09 +0000 Subject: [PATCH 12/12] processing: restore @Override on TypeMappingContext methods in base (#348) --- .../processing/AnnotationProcessingContext.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java index 17fb9dc2..d63e779c 100644 --- a/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java +++ b/processor/src/main/java/org/javahelpers/simple/builders/processor/processing/AnnotationProcessingContext.java @@ -132,6 +132,7 @@ protected void setGeneratedPackageName(String generatedPackageName) { * @param member the member to check * @return {@code true} if generated code may call the member */ + @Override public boolean isAccessibleFromGeneratedPackage(Element member) { if (member.getModifiers().contains(Modifier.PUBLIC)) { return true; @@ -213,6 +214,7 @@ public Optional resolveGeneratedType(TypeElement typeElement) { * @param qualifiedName the canonical class name (e.g., "java.lang.String") * @return the type element, or null if not found */ + @Override public TypeElement getTypeElement(String qualifiedName) { return elementUtils.getTypeElement(qualifiedName); } @@ -256,6 +258,7 @@ public PackageElement getPackageElement(String name) { * @param element the element * @return the qualified package name */ + @Override public String getPackageName(Element element) { return elementUtils.getPackageOf(element).getQualifiedName().toString(); } @@ -267,6 +270,7 @@ public String getPackageName(Element element) { * @return list of all members (wildcard enforced by the javax.lang.model API) */ @SuppressWarnings("java:S1452") + @Override public List getAllMembers(TypeElement typeElement) { return elementUtils.getAllMembers(typeElement); } @@ -287,6 +291,7 @@ public String getDocComment(Element element) { * @param typeMirror the type mirror * @return the element, or null if not representable as an element */ + @Override public Element asElement(TypeMirror typeMirror) { return typeUtils.asElement(typeMirror); } @@ -298,6 +303,7 @@ public Element asElement(TypeMirror typeMirror) { * @param type2 second type * @return true if the types are the same */ + @Override public boolean isSameType(TypeMirror type1, TypeMirror type2) { return typeUtils.isSameType(type1, type2); } @@ -308,6 +314,7 @@ public boolean isSameType(TypeMirror type1, TypeMirror type2) { * @param typeMirror the type to erase * @return the erasure of the type */ + @Override public TypeMirror erasure(TypeMirror typeMirror) { return typeUtils.erasure(typeMirror); } @@ -319,6 +326,7 @@ public TypeMirror erasure(TypeMirror typeMirror) { * @param type2 the target type * @return true if type1 is assignable to type2 */ + @Override public boolean isAssignable(TypeMirror type1, TypeMirror type2) { return typeUtils.isAssignable(type1, type2); } @@ -330,6 +338,7 @@ public boolean isAssignable(TypeMirror type1, TypeMirror type2) { * @return list of direct supertypes */ @SuppressWarnings("java:S1452") + @Override public java.util.List directSupertypes(TypeMirror typeMirror) { return typeUtils.directSupertypes(typeMirror); } @@ -369,6 +378,7 @@ public void debug(String message) { * @param format the format string * @param args arguments referenced by the format specifiers in the format string */ + @Override public void debug(String format, Object... args) { logger.debug(format, args); }