Search in sources :

Example 1 with Resolve

use of com.oracle.truffle.api.interop.Resolve in project graal by oracle.

the class InteropDSLProcessor method processElement.

private void processElement(Element e) throws IOException {
    if (e.getKind() != ElementKind.CLASS) {
        return;
    }
    MessageResolution messageImplementations = e.getAnnotation(MessageResolution.class);
    if (messageImplementations == null) {
        return;
    }
    // Check the receiver
    final String receiverTypeFullClassName = Utils.getReceiverTypeFullClassName(messageImplementations);
    if (isReceiverNonStaticInner(messageImplementations)) {
        emitError(receiverTypeFullClassName + " cannot be used as a receiver as it is not a static inner class.", e);
        return;
    }
    if (e.getModifiers().contains(Modifier.PRIVATE) || e.getModifiers().contains(Modifier.PROTECTED)) {
        emitError("Class must be public or package protected", e);
        return;
    }
    // check if there is a @LanguageCheck class
    Element curr = e;
    List<TypeElement> receiverChecks = new ArrayList<>();
    for (Element innerClass : curr.getEnclosedElements()) {
        if (innerClass.getKind() != ElementKind.CLASS) {
            continue;
        }
        if (innerClass.getAnnotation(CanResolve.class) != null) {
            receiverChecks.add((TypeElement) innerClass);
        }
    }
    if (receiverChecks.size() == 0 && isInstanceMissing(receiverTypeFullClassName)) {
        emitError("Missing isInstance method in class " + receiverTypeFullClassName, e);
        return;
    }
    if (receiverChecks.size() == 0 && isInstanceHasWrongSignature(receiverTypeFullClassName)) {
        emitError("Method isInstance in class " + receiverTypeFullClassName + " has an invalid signature: expected signature (object: TruffleObject).", e);
        return;
    }
    if (receiverChecks.size() > 1) {
        emitError("Only one @LanguageCheck element allowed", e);
        return;
    }
    // Collect all inner classes with an @Resolve annotation
    curr = e;
    List<TypeElement> elements = new ArrayList<>();
    for (Element innerClass : curr.getEnclosedElements()) {
        if (innerClass.getKind() != ElementKind.CLASS) {
            continue;
        }
        if (innerClass.getAnnotation(Resolve.class) != null) {
            elements.add((TypeElement) innerClass);
        }
    }
    ForeignAccessFactoryGenerator factoryGenerator = new ForeignAccessFactoryGenerator(processingEnv, messageImplementations, (TypeElement) e);
    // Process inner classes with an @Resolve annotation
    boolean generationSuccessfull = true;
    for (TypeElement elem : elements) {
        generationSuccessfull &= processResolveClass(elem.getAnnotation(Resolve.class), messageImplementations, elem, factoryGenerator);
    }
    if (!generationSuccessfull) {
        return;
    }
    if (!receiverChecks.isEmpty()) {
        generationSuccessfull &= processLanguageCheck(messageImplementations, receiverChecks.get(0), factoryGenerator);
    }
    if (!generationSuccessfull) {
        return;
    }
    try {
        factoryGenerator.generate();
    } catch (FilerException ex) {
        emitError("Foreign factory class with same name already exists", e);
        return;
    }
}
Also used : MessageResolution(com.oracle.truffle.api.interop.MessageResolution) CanResolve(com.oracle.truffle.api.interop.CanResolve) TypeElement(javax.lang.model.element.TypeElement) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ArrayList(java.util.ArrayList) FilerException(javax.annotation.processing.FilerException) CanResolve(com.oracle.truffle.api.interop.CanResolve) Resolve(com.oracle.truffle.api.interop.Resolve)

Aggregations

CanResolve (com.oracle.truffle.api.interop.CanResolve)1 MessageResolution (com.oracle.truffle.api.interop.MessageResolution)1 Resolve (com.oracle.truffle.api.interop.Resolve)1 ArrayList (java.util.ArrayList)1 FilerException (javax.annotation.processing.FilerException)1 Element (javax.lang.model.element.Element)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 TypeElement (javax.lang.model.element.TypeElement)1 VariableElement (javax.lang.model.element.VariableElement)1