Search in sources :

Example 1 with Option

use of com.oracle.truffle.api.Option in project graal by oracle.

the class OptionProcessor method processElement.

private boolean processElement(Element element, AnnotationMirror elementAnnotation, OptionsInfo info) {
    ProcessorContext context = ProcessorContext.getInstance();
    if (!element.getModifiers().contains(Modifier.STATIC)) {
        error(element, elementAnnotation, "Option field must be static");
        return false;
    }
    if (element.getModifiers().contains(Modifier.PRIVATE)) {
        error(element, elementAnnotation, "Option field cannot be private");
        return false;
    }
    String[] groupPrefixStrings = null;
    Option.Group prefix = info.type.getAnnotation(Option.Group.class);
    if (prefix != null) {
        groupPrefixStrings = prefix.value();
    } else {
        TypeMirror erasedTruffleType = context.getEnvironment().getTypeUtils().erasure(context.getType(TruffleLanguage.class));
        if (context.getEnvironment().getTypeUtils().isAssignable(info.type.asType(), erasedTruffleType)) {
            TruffleLanguage.Registration registration = info.type.getAnnotation(TruffleLanguage.Registration.class);
            if (registration != null) {
                groupPrefixStrings = new String[] { registration.id() };
                if (groupPrefixStrings[0].isEmpty()) {
                    error(element, elementAnnotation, "%s must specify an id such that Truffle options can infer their prefix.", TruffleLanguage.Registration.class.getSimpleName());
                    return false;
                }
            }
        } else if (context.getEnvironment().getTypeUtils().isAssignable(info.type.asType(), context.getType(TruffleInstrument.class))) {
            TruffleInstrument.Registration registration = info.type.getAnnotation(TruffleInstrument.Registration.class);
            if (registration != null) {
                groupPrefixStrings = new String[] { registration.id() };
                if (groupPrefixStrings[0].isEmpty()) {
                    error(element, elementAnnotation, "%s must specify an id such that Truffle options can infer their prefix.", TruffleInstrument.Registration.class.getSimpleName());
                    return false;
                }
            }
        }
    }
    if (groupPrefixStrings == null || groupPrefixStrings.length == 0) {
        groupPrefixStrings = new String[] { "" };
    }
    Option annotation = element.getAnnotation(Option.class);
    assert annotation != null;
    assert element instanceof VariableElement;
    assert element.getKind() == ElementKind.FIELD;
    VariableElement field = (VariableElement) element;
    String fieldName = field.getSimpleName().toString();
    Elements elements = processingEnv.getElementUtils();
    Types types = processingEnv.getTypeUtils();
    TypeMirror fieldType = field.asType();
    if (fieldType.getKind() != TypeKind.DECLARED) {
        error(element, elementAnnotation, "Option field must be of type " + OptionKey.class.getName());
        return false;
    }
    TypeMirror optionKeyType = elements.getTypeElement(OptionKey.class.getName()).asType();
    if (!types.isSubtype(fieldType, types.erasure(optionKeyType))) {
        error(element, elementAnnotation, "Option field type %s is not a subclass of %s", fieldType, optionKeyType);
        return false;
    }
    if (!field.getModifiers().contains(Modifier.STATIC)) {
        error(element, elementAnnotation, "Option field must be static");
        return false;
    }
    if (field.getModifiers().contains(Modifier.PRIVATE)) {
        error(element, elementAnnotation, "Option field cannot be private");
        return false;
    }
    String help = annotation.help();
    if (help.length() != 0) {
        char firstChar = help.charAt(0);
        if (!Character.isUpperCase(firstChar)) {
            error(element, elementAnnotation, "Option help text must start with upper case letter");
            return false;
        }
    }
    AnnotationValue value = ElementUtils.getAnnotationValue(elementAnnotation, "name", false);
    String optionName;
    if (value == null) {
        optionName = fieldName;
    } else {
        optionName = annotation.name();
    }
    if (!optionName.isEmpty() && !Character.isUpperCase(optionName.charAt(0))) {
        error(element, elementAnnotation, "Option names must start with capital letter");
        return false;
    }
    boolean deprecated = annotation.deprecated();
    OptionCategory category = annotation.category();
    if (category == null) {
        category = OptionCategory.DEBUG;
    }
    for (String group : groupPrefixStrings) {
        String name;
        if (group.isEmpty() && optionName.isEmpty()) {
            error(element, elementAnnotation, "Both group and option name cannot be empty");
            continue;
        } else if (optionName.isEmpty()) {
            name = group;
        } else {
            if (group.isEmpty()) {
                name = optionName;
            } else {
                name = group + "." + optionName;
            }
        }
        info.options.add(new OptionInfo(name, help, field, elementAnnotation, deprecated, category));
    }
    return true;
}
Also used : TruffleInstrument(com.oracle.truffle.api.instrumentation.TruffleInstrument) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Types(javax.lang.model.util.Types) VariableElement(javax.lang.model.element.VariableElement) Elements(javax.lang.model.util.Elements) TypeMirror(javax.lang.model.type.TypeMirror) AnnotationValue(javax.lang.model.element.AnnotationValue) Option(com.oracle.truffle.api.Option) TruffleLanguage(com.oracle.truffle.api.TruffleLanguage) OptionCategory(org.graalvm.options.OptionCategory)

Aggregations

Option (com.oracle.truffle.api.Option)1 TruffleLanguage (com.oracle.truffle.api.TruffleLanguage)1 TruffleInstrument (com.oracle.truffle.api.instrumentation.TruffleInstrument)1 SupportedAnnotationTypes (javax.annotation.processing.SupportedAnnotationTypes)1 AnnotationValue (javax.lang.model.element.AnnotationValue)1 VariableElement (javax.lang.model.element.VariableElement)1 TypeMirror (javax.lang.model.type.TypeMirror)1 Elements (javax.lang.model.util.Elements)1 Types (javax.lang.model.util.Types)1 OptionCategory (org.graalvm.options.OptionCategory)1