Skip to content

Commit 46a48d0

Browse files
authored
feat: autodoc error on misplaced @setting annotations (#228)
* feat: print warning on misplaced @setting annotations * fail when @setting is defined in a non-extension class
1 parent 5138526 commit 46a48d0

File tree

7 files changed

+303
-357
lines changed

7 files changed

+303
-357
lines changed

plugins/autodoc/autodoc-processor/src/main/java/org/eclipse/edc/plugins/autodoc/core/processor/EdcModuleProcessor.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import javax.annotation.processing.SupportedOptions;
3939
import javax.annotation.processing.SupportedSourceVersion;
4040
import javax.lang.model.SourceVersion;
41+
import javax.lang.model.element.Element;
4142
import javax.lang.model.element.TypeElement;
4243
import javax.tools.StandardLocation;
4344

@@ -52,8 +53,8 @@
5253
* {@link #EDC_OUTPUTDIR_OVERRIDE} as a processor parameter.
5354
*/
5455
@SupportedAnnotationTypes({
55-
"org.eclipse.edc.runtime.metamodel.annotation.EdcSetting",
56-
"org.eclipse.edc.runtime.metamodel.annotation.EdcSettingContext",
56+
"org.eclipse.edc.runtime.metamodel.annotation.Setting",
57+
"org.eclipse.edc.runtime.metamodel.annotation.SettingContext",
5758
"org.eclipse.edc.runtime.metamodel.annotation.Extension",
5859
"org.eclipse.edc.runtime.metamodel.annotation.Spi",
5960
"org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint",
@@ -72,19 +73,19 @@ public class EdcModuleProcessor extends AbstractProcessor {
7273
private final ObjectMapper mapper = new ObjectMapper();
7374

7475
private ModuleIntrospector moduleIntrospector;
75-
7676
private OverviewIntrospector overviewIntrospector;
7777

7878
private EdcModule.Builder moduleBuilder;
7979
private EdcServiceExtension.Builder extensionBuilder;
8080
private ExtensionIntrospector extensionIntrospector;
8181

8282
private ModuleType moduleType;
83+
private Set<Element> extensionElements;
8384

8485
@Override
8586
public synchronized void init(ProcessingEnvironment processingEnv) {
8687
super.init(processingEnv);
87-
moduleIntrospector = new ModuleIntrospector(processingEnv.getElementUtils(), processingEnv.getTypeUtils());
88+
moduleIntrospector = new ModuleIntrospector(processingEnv);
8889
//todo: replace this Noop converter with an actual JavadocConverter
8990
overviewIntrospector = new OverviewIntrospector(javadoc -> javadoc, processingEnv.getElementUtils());
9091

@@ -93,8 +94,11 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
9394

9495
@Override
9596
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment environment) {
96-
if (!initializeModuleBuilder(environment)) {
97-
return false; // error, do not continue processing
97+
if (moduleBuilder == null) {
98+
var result = initializeModuleBuilder(environment);
99+
if (!result) {
100+
return false; // error, do not continue processing
101+
}
98102
}
99103

100104
if (environment.processingOver()) {
@@ -105,8 +109,6 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
105109
}
106110

107111
if (moduleType == ModuleType.EXTENSION) {
108-
var extensionElements = moduleIntrospector.getExtensionElements(environment);
109-
110112
extensionElements.forEach(element -> {
111113
extensionBuilder = EdcServiceExtension.Builder.newInstance().type(moduleType)
112114
.name(extensionIntrospector.getExtensionName(element))
@@ -116,6 +118,7 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
116118
.configuration(extensionIntrospector.resolveConfigurationSettings(element))
117119
.overview(overviewIntrospector.generateModuleOverview(moduleType, environment))
118120
.categories(extensionIntrospector.getExtensionCategories(element));
121+
119122
moduleBuilder.extension(extensionBuilder.build());
120123
});
121124
} else {
@@ -129,11 +132,6 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
129132
}
130133

131134
private boolean initializeModuleBuilder(RoundEnvironment environment) {
132-
if (moduleBuilder != null) {
133-
// already initialized in a previous round
134-
return true;
135-
}
136-
137135
var id = processingEnv.getOptions().get(ID);
138136
if (id == null) {
139137
processingEnv.getMessager().printMessage(ERROR, "Value for '" + ID + "' not set on processor configuration. Skipping manifest generation.");
@@ -146,7 +144,8 @@ private boolean initializeModuleBuilder(RoundEnvironment environment) {
146144
return false;
147145
}
148146

149-
moduleType = determineAndValidateModuleType(environment);
147+
extensionElements = moduleIntrospector.getExtensionElements(environment);
148+
moduleType = determineAndValidateModuleType(environment, extensionElements);
150149
if (moduleType == ModuleType.INVALID) {
151150
// error or not a module, return
152151
return false;
@@ -158,8 +157,7 @@ private boolean initializeModuleBuilder(RoundEnvironment environment) {
158157
}
159158

160159
@Nullable
161-
private ModuleType determineAndValidateModuleType(RoundEnvironment environment) {
162-
var extensionElements = moduleIntrospector.getExtensionElements(environment);
160+
private ModuleType determineAndValidateModuleType(RoundEnvironment environment, Set<Element> extensionElements) {
163161
if (extensionElements.isEmpty()) {
164162
// check if it is an SPI
165163
var spiElements = environment.getElementsAnnotatedWith(Spi.class);

plugins/autodoc/autodoc-processor/src/main/java/org/eclipse/edc/plugins/autodoc/core/processor/introspection/ModuleIntrospector.java

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@
2828
import java.util.Set;
2929
import java.util.stream.Collectors;
3030
import java.util.stream.Stream;
31+
import javax.annotation.processing.ProcessingEnvironment;
3132
import javax.annotation.processing.RoundEnvironment;
3233
import javax.lang.model.element.Element;
3334
import javax.lang.model.element.TypeElement;
3435
import javax.lang.model.util.Elements;
3536
import javax.lang.model.util.Types;
3637

3738
import static java.util.stream.Collectors.toList;
39+
import static javax.tools.Diagnostic.Kind.ERROR;
3840
import static org.eclipse.edc.plugins.autodoc.core.processor.compiler.AnnotationFunctions.attributeStringValues;
3941
import static org.eclipse.edc.plugins.autodoc.core.processor.compiler.AnnotationFunctions.attributeValue;
4042
import static org.eclipse.edc.plugins.autodoc.core.processor.compiler.AnnotationFunctions.mirrorFor;
@@ -46,10 +48,12 @@ public class ModuleIntrospector {
4648
private static final String SERVICE_EXTENSION_NAME = "org.eclipse.edc.spi.system.ServiceExtension";
4749
private final Elements elementUtils;
4850
private final Types typeUtils;
51+
private final ProcessingEnvironment processingEnv;
4952

50-
public ModuleIntrospector(Elements elementUtils, Types typeUtils) {
51-
this.elementUtils = elementUtils;
52-
this.typeUtils = typeUtils;
53+
public ModuleIntrospector(ProcessingEnvironment processingEnv) {
54+
this.processingEnv = processingEnv;
55+
this.elementUtils = processingEnv.getElementUtils();
56+
this.typeUtils = processingEnv.getTypeUtils();
5357
}
5458

5559

@@ -89,23 +93,30 @@ public String getModuleName(RoundEnvironment environment) {
8993
* @return a set containing the distinct extension symbols. Elements in that set are most likely of type Symbol.ClassSymbol
9094
*/
9195
public Set<Element> getExtensionElements(RoundEnvironment environment) {
92-
var extensionClasses = environment.getElementsAnnotatedWith(Extension.class);
93-
var settingsSymbols = environment.getElementsAnnotatedWith(Setting.class);
96+
var settingsSymbols = environment.getElementsAnnotatedWith(Setting.class).stream()
97+
.peek(setting -> {
98+
var enclosingElement = setting.getEnclosingElement().asType();
99+
var serviceExtensionType = typeUtils.erasure(elementUtils.getTypeElement(SERVICE_EXTENSION_NAME).asType());
100+
if (!typeUtils.isAssignable(enclosingElement, serviceExtensionType)) {
101+
var message = "@Setting annotation must be used inside a ServiceExtension implementation, the " +
102+
"ones defined in %s will be excluded from the autodoc manifest".formatted(enclosingElement);
103+
processingEnv.getMessager().printMessage(ERROR, message, setting);
104+
}
105+
});
106+
94107
var injectSymbols = environment.getElementsAnnotatedWith(Inject.class);
95108
var providerSymbols = environment.getElementsAnnotatedWith(Provider.class);
96-
var providesClasses = environment.getElementsAnnotatedWith(Provides.class);
97-
var requiresClasses = environment.getElementsAnnotatedWith(Requires.class);
98-
99-
var symbols = settingsSymbols.stream();
100-
symbols = Stream.concat(symbols, injectSymbols.stream());
101-
symbols = Stream.concat(symbols, providerSymbols.stream());
102109

103-
var classes = symbols.map(Element::getEnclosingElement)
110+
var classes = Stream.of(settingsSymbols, injectSymbols.stream(), providerSymbols.stream())
111+
.reduce(Stream::concat)
112+
.orElse(Stream.empty())
113+
.map(Element::getEnclosingElement)
104114
.filter(this::isExtension)
105115
.collect(Collectors.toSet());
106-
classes.addAll(requiresClasses);
107-
classes.addAll(providesClasses);
108-
classes.addAll(extensionClasses);
116+
117+
classes.addAll(environment.getElementsAnnotatedWith(Requires.class));
118+
classes.addAll(environment.getElementsAnnotatedWith(Provides.class));
119+
classes.addAll(environment.getElementsAnnotatedWith(Extension.class));
109120

110121
return classes;
111122
}

plugins/autodoc/autodoc-processor/src/test/java/org/eclipse/edc/plugins/autodoc/core/processor/EdcModuleProcessorExtensionTest.java

Lines changed: 0 additions & 138 deletions
This file was deleted.

plugins/autodoc/autodoc-processor/src/test/java/org/eclipse/edc/plugins/autodoc/core/processor/EdcModuleProcessorSpiTest.java

Lines changed: 0 additions & 60 deletions
This file was deleted.

0 commit comments

Comments
 (0)