Skip to content

Commit 0480798

Browse files
authored
Merge pull request #76 from avaje/feature/GeneratedJavadoc
Add javadoc comments into generated code
2 parents 9efd648 + 0cf4f48 commit 0480798

File tree

8 files changed

+121
-32
lines changed

8 files changed

+121
-32
lines changed

inject-generator/src/main/java/io/avaje/inject/generator/Constants.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ class Constants {
44

55
static final String KOTLIN_METADATA = "kotlin.Metadata";
66
static final String GENERATED_9 = "javax.annotation.processing.Generated";
7+
static final String GENERATED_LOCAL = "io.avaje.inject.spi.Generated";
78

89
static final String PROVIDER = "javax.inject.Provider";
10+
static final String SINGLETON = "javax.inject.Singleton";
11+
static final String INJECT = "javax.inject.Inject";
912

1013
static final String PATH = "io.avaje.http.api.Path";
1114
static final String CONTROLLER = "io.avaje.http.api.Controller";
@@ -14,19 +17,16 @@ class Constants {
1417
static final String AT_GENERATED = "@Generated(\"io.avaje.inject.generator\")";
1518
static final String META_INF_FACTORY = "META-INF/services/io.avaje.inject.spi.BeanContextFactory";
1619

20+
static final String BEANCONTEXT = "io.avaje.inject.BeanContext;";
21+
static final String CONTEXTMODULE = "io.avaje.inject.ContextModule;";
22+
1723
static final String BEAN_FACTORY = "io.avaje.inject.spi.BeanFactory";
1824
static final String BEAN_FACTORY2 = "io.avaje.inject.spi.BeanFactory2";
1925
static final String BEAN_LIFECYCLE = "io.avaje.inject.spi.BeanLifecycle";
2026
static final String BUILDER = "io.avaje.inject.spi.Builder";
21-
static final String SINGLETON = "javax.inject.Singleton";
22-
static final String INJECT = "javax.inject.Inject";
23-
24-
static final String IMPORT_CONTEXTMODULE = "import io.avaje.inject.ContextModule;";
25-
static final String IMPORT_DEPENDENCYMETA = "import io.avaje.inject.spi.DependencyMeta;";
26-
static final String IMPORT_BEANCONTEXT = "import io.avaje.inject.BeanContext;";
27-
static final String IMPORT_BEANCONTEXTFACTORY = "import io.avaje.inject.spi.BeanContextFactory;";
28-
static final String IMPORT_BUILDERFACTORY = "import io.avaje.inject.spi.BuilderFactory;";
29-
static final String IMPORT_BUILDER = "import io.avaje.inject.spi.Builder;";
27+
static final String DEPENDENCYMETA = "io.avaje.inject.spi.DependencyMeta;";
28+
static final String BEANCONTEXTFACTORY = "io.avaje.inject.spi.BeanContextFactory;";
29+
static final String BUILDERFACTORY = "io.avaje.inject.spi.BuilderFactory;";
3030

3131
static boolean isBeanLifecycle(String type) {
3232
return BEAN_LIFECYCLE.equals(type);

inject-generator/src/main/java/io/avaje/inject/generator/MetaData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ private boolean hasMethod() {
194194
}
195195

196196
private void appendProvides(StringBuilder sb, String attribute, List<String> types) {
197-
sb.append(",").append(attribute).append("={");
197+
sb.append(", ").append(attribute).append("={");
198198
for (int i = 0; i < types.size(); i++) {
199199
if (i > 0) {
200200
sb.append(",");

inject-generator/src/main/java/io/avaje/inject/generator/MethodReader.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515

1616
class MethodReader {
1717

18+
private static final String CODE_COMMENT_LIFECYCLE =" /**\n * Lifecycle wrapper for %s.\n */";
19+
private static final String CODE_COMMENT_BUILD_FACTORYBEAN = " /**\n * Create and register %s via factory bean method %s#%s().\n */";
20+
1821
private final ProcessingContext context;
1922
private final ExecutableElement element;
2023
private final String factoryType;
24+
private final String methodName;
2125
private final TypeMirror returnType;
2226
private final String returnTypeRaw;
2327
private final String shortName;
@@ -40,6 +44,7 @@ class MethodReader {
4044
this.isFactory = bean != null;
4145
this.context = context;
4246
this.element = element;
47+
this.methodName = element.getSimpleName().toString();
4348
this.returnType = element.getReturnType();
4449
this.returnTypeRaw = returnType.toString();
4550
this.shortName = Util.shortName(returnTypeRaw);
@@ -52,6 +57,10 @@ class MethodReader {
5257
initInterfaces();
5358
}
5459

60+
String getName() {
61+
return methodName;
62+
}
63+
5564
private void initInterfaces() {
5665
Element element = context.asElement(returnType);
5766
if (element instanceof TypeElement) {
@@ -84,9 +93,6 @@ List<MethodParam> getParams() {
8493
return params;
8594
}
8695

87-
String getName() {
88-
return element.getSimpleName().toString();
89-
}
9096

9197
MetaData createMeta() {
9298

@@ -112,15 +118,12 @@ String builderGetFactory() {
112118
}
113119

114120
String builderBuildBean() {
115-
116-
String methodName = element.getSimpleName().toString();
117121
StringBuilder sb = new StringBuilder();
118122
if (isVoid) {
119123
sb.append(String.format(" factory.%s(", methodName));
120124
} else {
121125
sb.append(String.format(" %s bean = factory.%s(", Util.shortName(returnTypeRaw), methodName));
122126
}
123-
124127
for (int i = 0; i < params.size(); i++) {
125128
if (i > 0) {
126129
sb.append(",");
@@ -135,7 +138,7 @@ void builderBuildAddBean(Append writer) {
135138
if (!isVoid) {
136139
writer.append(" ");
137140
if (beanLifeCycle || hasLifecycleMethods()) {
138-
writer.append(" %s $bean = ", shortName);
141+
writer.append("%s $bean = ", shortName);
139142
}
140143
writer.append("builder.register(bean, ");
141144
if (name == null) {
@@ -197,7 +200,7 @@ void buildLifecycleClass(Append writer) {
197200
if (!hasLifecycleMethods()) {
198201
return;
199202
}
200-
203+
writer.append(CODE_COMMENT_LIFECYCLE, shortName).eol();
201204
writer.append(" static class %s$lifecycle implements BeanLifecycle {", shortName).eol().eol();
202205
writer.append(" final %s bean;", shortName).eol().eol();
203206
writer.append(" %s$lifecycle(%s bean) {", shortName, shortName).eol();
@@ -251,6 +254,10 @@ void writeRequestConstructor(Append writer) {
251254
}
252255
}
253256

257+
public void commentBuildMethod(Append writer) {
258+
writer.append(CODE_COMMENT_BUILD_FACTORYBEAN, shortName, factoryShortName, methodName).eol();
259+
}
260+
254261
static class MethodParam {
255262

256263
private final String named;

inject-generator/src/main/java/io/avaje/inject/generator/ProcessingContext.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class ProcessingContext {
5353
}
5454

5555
private String generatedAnnotation(boolean jdk8) {
56-
return jdk8 ? null : isTypeAvailable(Constants.GENERATED_9) ? Constants.GENERATED_9 : null;
56+
return jdk8 ? Constants.GENERATED_LOCAL : isTypeAvailable(Constants.GENERATED_9) ? Constants.GENERATED_9 : Constants.GENERATED_LOCAL;
5757
}
5858

5959
private boolean isTypeAvailable(String canonicalName) {
@@ -151,6 +151,10 @@ void deriveContextName(String factoryPackage) {
151151
}
152152
}
153153

154+
String contextName() {
155+
return contextName;
156+
}
157+
154158
String getContextPackage() {
155159
return contextPackage;
156160
}

inject-generator/src/main/java/io/avaje/inject/generator/SimpleBeanWriter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
*/
1313
class SimpleBeanWriter {
1414

15+
private static final String CODE_COMMENT = "/**\n * Generated source - dependency injection builder for %s.\n */";
16+
private static final String CODE_COMMENT_FACTORY = "/**\n * Generated source - dependency injection factory for request scoped %s.\n */";
17+
private static final String CODE_COMMENT_LIFECYCLE =" /**\n * Lifecycle wrapper for %s.\n */";
18+
private static final String CODE_COMMENT_BUILD = " /**\n * Create and register %s.\n */";
19+
1520
private final BeanReader beanReader;
1621
private final ProcessingContext context;
1722
private final String originName;
@@ -73,6 +78,7 @@ private void writeStaticFactoryBeanLifecycle() {
7378
}
7479

7580
private void writeFactoryBeanMethod(MethodReader method) {
81+
method.commentBuildMethod(writer);
7682
writer.append(" public static void build_%s(Builder builder) {", method.getName()).eol();
7783
method.buildAddFor(writer);
7884
writer.append(method.builderGetFactory()).eol();
@@ -91,6 +97,7 @@ private void writeStaticFactoryMethod() {
9197
}
9298

9399
int providerIndex = 0;
100+
writer.append(CODE_COMMENT_BUILD, shortName).eol();
94101
writer.append(" public static void build(Builder builder");
95102
for (MethodReader.MethodParam param : constructor.getParams()) {
96103
if (param.isGenericType()) {
@@ -125,6 +132,7 @@ private void writeStaticFactoryMethod() {
125132
}
126133
if (beanReader.isFieldInjectionRequired() || beanReader.isMethodInjectionRequired()) {
127134
writer.append(" builder.addInjector(b -> {").eol();
135+
writer.append(" // field and method injection").eol();
128136
for (FieldReader fieldReader : beanReader.getInjectFields()) {
129137
String fieldName = fieldReader.getFieldName();
130138
String getDependency = fieldReader.builderGetDependency();
@@ -166,6 +174,7 @@ private void lifecycleMethod(String method, Element methodElement) {
166174
private void writeLifecycleWrapper() {
167175
if (beanReader.isLifecycleWrapperRequired()) {
168176
writer.append(" private final %s bean;", shortName).eol().eol();
177+
writer.append(CODE_COMMENT_LIFECYCLE, shortName).eol();
169178
writer.append(" public %s%s(%s bean) {", shortName, suffix, shortName).eol();
170179
writer.append(" this.bean = bean;").eol();
171180
writer.append(" }").eol().eol();
@@ -180,6 +189,11 @@ private void writeClassEnd() {
180189
}
181190

182191
private void writeClassStart() {
192+
if (beanReader.isRequestScoped()) {
193+
writer.append(CODE_COMMENT_FACTORY, shortName).eol();
194+
} else {
195+
writer.append(CODE_COMMENT, shortName).eol();
196+
}
183197
if (context.isGeneratedAvailable()) {
184198
writer.append(Constants.AT_GENERATED).eol();
185199
}

inject-generator/src/main/java/io/avaje/inject/generator/SimpleFactoryWriter.java

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,47 @@
44
import javax.tools.JavaFileObject;
55
import java.io.IOException;
66
import java.io.Writer;
7+
import java.util.Set;
8+
import java.util.TreeSet;
79

810
/**
911
* Write the source code for the factory.
1012
*/
1113
class SimpleFactoryWriter {
1214

15+
private static final String CODE_COMMENT_FACTORY =
16+
"/**\n" +
17+
" * Generated source - Creates the BeanContext for the %s module.\n" +
18+
" * \n" +
19+
" * With JPMS Java module system this generated class should be explicitly\n" +
20+
" * registered in module-info via a <code>provides</code> clause like:\n" +
21+
" * \n" +
22+
" * <pre>{@code\n" +
23+
" * \n" +
24+
" * module example {\n" +
25+
" * requires io.avaje.inject;\n" +
26+
" * \n" +
27+
" * provides io.avaje.inject.spi.BeanContextFactory with %s._di$BeanContextFactory;\n" +
28+
" * \n" +
29+
" * }\n" +
30+
" * \n" +
31+
" * }</pre>\n" +
32+
" */";
33+
34+
private static final String CODE_COMMENT_CREATE_CONTEXT =
35+
" /**\n" +
36+
" * Create and return the BeanContext.\n" +
37+
" * <p>\n" +
38+
" * Creates all the beans in order based on constuctor dependencies.\n" +
39+
" * The beans are registered into the builder along with callbacks for\n" +
40+
" * field injection, method injection and lifecycle support.\n" +
41+
" * <p>\n" +
42+
" * Ultimately the builder returns the BeanContext containing the beans.\n" +
43+
" *\n" +
44+
" * @param parent The parent context for multi-module wiring\n" +
45+
" * @return The BeanContext containing the beans\n" +
46+
" */";
47+
1348
private final MetaDataOrdering ordering;
1449
private final ProcessingContext context;
1550

@@ -69,9 +104,12 @@ private void writeBuildMethods() {
69104

70105
private void writeCreateMethod() {
71106

107+
writer.append(CODE_COMMENT_CREATE_CONTEXT).eol();
72108
writer.append(" @Override").eol();
73109
writer.append(" public BeanContext createContext(Builder parent) {").eol();
74110
writer.append(" builder.setParent(parent);").eol();
111+
writer.append(" // create beans in order based on constructor dependencies").eol();
112+
writer.append(" // i.e. \"provides\" followed by \"dependsOn\"").eol();
75113
for (MetaData metaData : ordering.getOrdered()) {
76114
writer.append(" build_%s();", metaData.getBuildName()).eol();
77115
}
@@ -81,20 +119,10 @@ private void writeCreateMethod() {
81119
}
82120

83121
private void writePackage() {
84-
85122
writer.append("package %s;", factoryPackage).eol().eol();
86-
87-
final String generated = context.getGeneratedAnnotation();
88-
if (generated != null) {
89-
writer.append("import %s;", generated).eol();
123+
for (String type : factoryImportTypes()) {
124+
writer.append("import %s;", type).eol();
90125
}
91-
writer.append(Constants.IMPORT_BEANCONTEXT).eol();
92-
writer.append(Constants.IMPORT_CONTEXTMODULE).eol();
93-
writer.append(Constants.IMPORT_DEPENDENCYMETA).eol().eol();
94-
writer.append(Constants.IMPORT_BEANCONTEXTFACTORY).eol();
95-
writer.append(Constants.IMPORT_BUILDER).eol();
96-
writer.append(Constants.IMPORT_BUILDERFACTORY).eol();
97-
98126
for (String type : ordering.getImportTypes()) {
99127
if (Util.validImportType(type)) {
100128
writer.append("import %s;", type).eol();
@@ -103,8 +131,24 @@ private void writePackage() {
103131
writer.eol();
104132
}
105133

134+
private Set<String> factoryImportTypes() {
135+
Set<String> importTypes = new TreeSet<>();
136+
final String generated = context.getGeneratedAnnotation();
137+
if (generated != null) {
138+
importTypes.add(generated);
139+
}
140+
importTypes.add(Constants.BEANCONTEXT);
141+
importTypes.add(Constants.CONTEXTMODULE);
142+
importTypes.add(Constants.DEPENDENCYMETA);
143+
importTypes.add(Constants.BEANCONTEXTFACTORY);
144+
importTypes.add(Constants.BUILDER);
145+
importTypes.add(Constants.BUILDERFACTORY);
146+
return importTypes;
147+
}
148+
106149
private void writeStartClass() {
107150

151+
writer.append(CODE_COMMENT_FACTORY, context.contextName(), factoryPackage).eol();
108152
context.buildAtContextModule(writer);
109153

110154
writer.append("public class %s implements BeanContextFactory {", factoryShortName).eol().eol();
@@ -138,4 +182,5 @@ private Writer createFileWriter() throws IOException {
138182
JavaFileObject jfo = context.createWriter(factoryFullName);
139183
return jfo.openWriter();
140184
}
185+
141186
}

inject/src/main/java/io/avaje/inject/spi/Builder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public interface Builder {
8282
void addLifecycle(BeanLifecycle bean);
8383

8484
/**
85-
* Add a field injector.
85+
* Add field and method injection.
8686
*/
8787
void addInjector(Consumer<Builder> injector);
8888

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.avaje.inject.spi;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* Marks source code that has been generated.
10+
*/
11+
@Target(ElementType.TYPE)
12+
@Retention(RetentionPolicy.SOURCE)
13+
public @interface Generated {
14+
15+
/**
16+
* The name of the generator used to generate this source.
17+
*/
18+
String value();
19+
}

0 commit comments

Comments
 (0)