use of com.oracle.truffle.api.interop.MessageResolution 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;
}
}
Aggregations