Skip to content

Commit

Permalink
feat: autodoc parse @configuration objects (#289)
Browse files Browse the repository at this point in the history
  • Loading branch information
paullatzelsperger authored Nov 11, 2024
1 parent 7a132db commit 51e98dd
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public synchronized void init(ProcessingEnvironment processingEnv) {
//todo: replace this Noop converter with an actual JavadocConverter
overviewIntrospector = new OverviewIntrospector(javadoc -> javadoc, processingEnv.getElementUtils());

extensionIntrospector = new ExtensionIntrospector(processingEnv.getElementUtils());
extensionIntrospector = new ExtensionIntrospector(processingEnv.getElementUtils(), processingEnv.getTypeUtils());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.eclipse.edc.plugins.autodoc.core.processor.introspection;

import org.eclipse.edc.plugins.autodoc.core.processor.compiler.AnnotationFunctions;
import org.eclipse.edc.runtime.metamodel.annotation.Configuration;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
Expand All @@ -36,6 +37,7 @@
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
Expand All @@ -51,9 +53,11 @@
public class ExtensionIntrospector {
public static final String CONTEXT_ATTRIBUTE = "context";
private final Elements elementUtils;
private final Types typeUtils;

public ExtensionIntrospector(Elements elementUtils) {
public ExtensionIntrospector(Elements elementUtils, Types typeUtils) {
this.elementUtils = elementUtils;
this.typeUtils = typeUtils;
}

/**
Expand Down Expand Up @@ -102,7 +106,10 @@ public List<Service> resolveProvidedServices(Element element) {
* Resolves configuration points declared with {@link Setting}.
*/
public List<ConfigurationSetting> resolveConfigurationSettings(Element element) {
return getEnclosedElementsAnnotatedWith(element, Setting.class)
var settingsInConfigObjects = getEnclosedElementsAnnotatedWith(element, Configuration.class)
.flatMap(e -> getEnclosedElementsAnnotatedWith(typeUtils.asElement(e.asType()), Setting.class));

return Stream.concat(settingsInConfigObjects, getEnclosedElementsAnnotatedWith(element, Setting.class))
.filter(VariableElement.class::isInstance)
.map(VariableElement.class::cast)
.map(this::createConfigurationSetting)
Expand Down Expand Up @@ -139,9 +146,13 @@ private ConfigurationSetting createConfigurationSetting(VariableElement settingE
prefix = resolveConfigurationPrefix(settingElement);
}

var keyValue = prefix + settingElement.getConstantValue().toString();
// either take the config key value directly from the annotated variable or from the "key" attribute
var keyValue = prefix + ofNullable(settingElement.getConstantValue())
.orElseGet(() -> attributeValue(String.class, "key", settingMirror, elementUtils))
.toString();

return ConfigurationSetting.Builder.newInstance().key(keyValue)
return ConfigurationSetting.Builder.newInstance()
.key(keyValue)
.description(attributeValue(String.class, "value", settingMirror, elementUtils))
.type(attributeValue(String.class, "type", settingMirror, elementUtils))
.required(attributeValue(Boolean.class, "required", settingMirror, elementUtils))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@

package org.eclipse.edc.plugins.autodoc.core.processor.introspection;

import org.eclipse.edc.runtime.metamodel.annotation.Configuration;
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.ExtensionPoint;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
import org.eclipse.edc.runtime.metamodel.annotation.Provides;
import org.eclipse.edc.runtime.metamodel.annotation.Requires;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.runtime.metamodel.annotation.Settings;
import org.eclipse.edc.runtime.metamodel.annotation.Spi;
import org.eclipse.edc.runtime.metamodel.domain.Service;

Expand Down Expand Up @@ -93,13 +95,30 @@ public String getModuleName(RoundEnvironment environment) {
* @return a set containing the distinct extension symbols. Elements in that set are most likely of type Symbol.ClassSymbol
*/
public Set<Element> getExtensionElements(RoundEnvironment environment) {


var settingsSymbols = environment.getElementsAnnotatedWith(Setting.class).stream()
.peek(setting -> {
var serviceExtensionType = typeUtils.erasure(elementUtils.getTypeElement(SYSTEM_EXTENSION_NAME).asType());
var enclosingElement = setting.getEnclosingElement().asType();

// @Setting annotations may only occur in extension classes or in types annotated with @Settings
if (!typeUtils.isAssignable(enclosingElement, serviceExtensionType) && setting.getEnclosingElement().getAnnotation(Settings.class) == null) {
var message = "@Setting annotation must be used inside a ServiceExtension implementation or a type annotated with @Settings, the " +
"ones defined in %s will be excluded from the autodoc manifest".formatted(enclosingElement);
processingEnv.getMessager().printMessage(ERROR, message, setting);
}
});

// check that fields annotated with @Configuration occur only inside extension classes
environment.getElementsAnnotatedWith(Configuration.class)
.forEach(setting -> {
var serviceExtensionType = typeUtils.erasure(elementUtils.getTypeElement(SYSTEM_EXTENSION_NAME).asType());
var enclosingElement = setting.getEnclosingElement().asType();

if (!typeUtils.isAssignable(enclosingElement, serviceExtensionType)) {
var message = "@Setting annotation must be used inside a ServiceExtension implementation, the " +
"ones defined in %s will be excluded from the autodoc manifest".formatted(enclosingElement);
var message = "@Configuration annotations must be used inside a ServiceExtension implementation, the " +
"ones defined in %s will be excluded from the autodoc manifest".formatted(enclosingElement);
processingEnv.getMessager().printMessage(ERROR, message, setting);
}
});
Expand Down

0 comments on commit 51e98dd

Please sign in to comment.