Search in sources :

Example 1 with Registration

use of com.oracle.truffle.api.TruffleLanguage.Registration in project graal by oracle.

the class LanguageRegistrationProcessor method generateFile.

private void generateFile(List<TypeElement> languages) {
    String filename = "META-INF/truffle/language";
    // sorted properties
    Properties p = new SortedProperties();
    int cnt = 0;
    for (TypeElement l : languages) {
        Registration annotation = l.getAnnotation(Registration.class);
        if (annotation == null) {
            continue;
        }
        String prefix = "language" + ++cnt + ".";
        String className = processingEnv.getElementUtils().getBinaryName(l).toString();
        String id = annotation.id();
        if (id != null && !id.isEmpty()) {
            p.setProperty(prefix + "id", id);
        }
        p.setProperty(prefix + "name", annotation.name());
        p.setProperty(prefix + "implementationName", annotation.implementationName());
        p.setProperty(prefix + "version", annotation.version());
        p.setProperty(prefix + "className", className);
        String[] mimes = annotation.mimeType();
        for (int i = 0; i < mimes.length; i++) {
            p.setProperty(prefix + "mimeType." + i, mimes[i]);
        }
        String[] dependencies = annotation.dependentLanguages();
        Arrays.sort(dependencies);
        for (int i = 0; i < dependencies.length; i++) {
            p.setProperty(prefix + "dependentLanguage." + i, dependencies[i]);
        }
        p.setProperty(prefix + "interactive", Boolean.toString(annotation.interactive()));
        p.setProperty(prefix + "internal", Boolean.toString(annotation.internal()));
    }
    if (cnt > 0) {
        try {
            FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, languages.toArray(new Element[0]));
            try (OutputStream os = file.openOutputStream()) {
                p.store(os, "Generated by " + LanguageRegistrationProcessor.class.getName());
            }
        } catch (IOException e) {
            if (e instanceof FilerException) {
                if (e.getMessage().startsWith("Source file already created")) {
                    // ignore source file already created errors
                    return;
                }
            }
            processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), languages.get(0));
        }
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) Registration(com.oracle.truffle.api.TruffleLanguage.Registration) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) OutputStream(java.io.OutputStream) FileObject(javax.tools.FileObject) IOException(java.io.IOException) Properties(java.util.Properties) FilerException(javax.annotation.processing.FilerException)

Example 2 with Registration

use of com.oracle.truffle.api.TruffleLanguage.Registration in project graal by oracle.

the class LanguageRegistrationProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    if (roundEnv.processingOver()) {
        generateFile(registrations);
        registrations.clear();
        return true;
    }
    for (Element e : roundEnv.getElementsAnnotatedWith(Registration.class)) {
        Registration annotation = e.getAnnotation(Registration.class);
        if (annotation != null && e.getKind() == ElementKind.CLASS) {
            if (!e.getModifiers().contains(Modifier.PUBLIC)) {
                emitError("Registered language class must be public", e);
                continue;
            }
            if (e.getEnclosingElement().getKind() != ElementKind.PACKAGE && !e.getModifiers().contains(Modifier.STATIC)) {
                emitError("Registered language inner-class must be static", e);
                continue;
            }
            TypeMirror truffleLang = processingEnv.getTypeUtils().erasure(processingEnv.getElementUtils().getTypeElement(TruffleLanguage.class.getName()).asType());
            if (!processingEnv.getTypeUtils().isAssignable(e.asType(), truffleLang)) {
                emitError("Registered language class must subclass TruffleLanguage", e);
                continue;
            }
            boolean foundConstructor = false;
            for (ExecutableElement constructor : ElementFilter.constructorsIn(e.getEnclosedElements())) {
                if (!constructor.getModifiers().contains(Modifier.PUBLIC)) {
                    continue;
                }
                if (!constructor.getParameters().isEmpty()) {
                    continue;
                }
                foundConstructor = true;
                break;
            }
            Element singletonElement = null;
            for (Element mem : e.getEnclosedElements()) {
                if (!mem.getModifiers().contains(Modifier.PUBLIC)) {
                    continue;
                }
                if (mem.getKind() != ElementKind.FIELD) {
                    continue;
                }
                if (!mem.getModifiers().contains(Modifier.FINAL)) {
                    continue;
                }
                if (!"INSTANCE".equals(mem.getSimpleName().toString())) {
                    continue;
                }
                if (processingEnv.getTypeUtils().isAssignable(mem.asType(), truffleLang)) {
                    singletonElement = mem;
                    break;
                }
            }
            if (singletonElement != null) {
                emitWarning("Using a singleton field is deprecated. Please provide a public no-argument constructor instead.", singletonElement);
            } else {
                if (!foundConstructor) {
                    emitError("A TruffleLanguage subclass must have a public no argument constructor.", e);
                } else {
                    assertNoErrorExpected(e);
                }
            }
            registrations.add((TypeElement) e);
        }
    }
    return true;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) Registration(com.oracle.truffle.api.TruffleLanguage.Registration) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) TruffleLanguage(com.oracle.truffle.api.TruffleLanguage)

Aggregations

Registration (com.oracle.truffle.api.TruffleLanguage.Registration)2 Element (javax.lang.model.element.Element)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 TypeElement (javax.lang.model.element.TypeElement)2 TruffleLanguage (com.oracle.truffle.api.TruffleLanguage)1 IOException (java.io.IOException)1 OutputStream (java.io.OutputStream)1 Properties (java.util.Properties)1 FilerException (javax.annotation.processing.FilerException)1 TypeMirror (javax.lang.model.type.TypeMirror)1 FileObject (javax.tools.FileObject)1