use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method parseRootType.
private NodeData parseRootType(TypeElement rootType) {
List<NodeData> enclosedNodes = new ArrayList<>();
for (TypeElement enclosedType : ElementFilter.typesIn(rootType.getEnclosedElements())) {
NodeData enclosedChild = parseRootType(enclosedType);
if (enclosedChild != null) {
enclosedNodes.add(enclosedChild);
}
}
NodeData node;
try {
node = parseNode(rootType);
} catch (CompileErrorException e) {
throw e;
} catch (Throwable e) {
RuntimeException e2 = new RuntimeException(String.format("Parsing of Node %s failed.", ElementUtils.getQualifiedName(rootType)));
e2.addSuppressed(e);
throw e2;
}
if (node == null && !enclosedNodes.isEmpty()) {
node = new NodeData(context, rootType);
}
if (node != null) {
for (NodeData enclosedNode : enclosedNodes) {
node.addEnclosedNode(enclosedNode);
}
}
return node;
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method initializeChildren.
@SuppressWarnings("unchecked")
private void initializeChildren(NodeData node) {
for (NodeChildData child : node.getChildren()) {
AnnotationValue executeWithValue1 = child.getExecuteWithValue();
List<AnnotationValue> executeWithValues = ElementUtils.resolveAnnotationValue(List.class, executeWithValue1);
List<NodeExecutionData> executeWith = new ArrayList<>();
for (AnnotationValue executeWithValue : executeWithValues) {
String executeWithString = ElementUtils.resolveAnnotationValue(String.class, executeWithValue);
if (child.getName().equals(executeWithString)) {
child.addError(executeWithValue1, "The child node '%s' cannot be executed with itself.", executeWithString);
continue;
}
NodeExecutionData found = null;
boolean before = true;
for (NodeExecutionData resolveChild : node.getChildExecutions()) {
if (resolveChild.getChild() == child) {
before = false;
continue;
}
if (resolveChild.getIndexedName().equals(executeWithString)) {
found = resolveChild;
break;
}
}
if (found == null) {
child.addError(executeWithValue1, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
continue;
} else if (!before) {
child.addError(executeWithValue1, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString, executeWithString);
continue;
}
executeWith.add(found);
}
child.setExecuteWith(executeWith);
}
for (NodeChildData child : node.getChildren()) {
TypeMirror nodeType = child.getNodeType();
NodeData fieldNodeData = parseChildNodeData(node, child, ElementUtils.fromTypeMirror(nodeType));
child.setNode(fieldNodeData);
if (fieldNodeData == null || fieldNodeData.hasErrors()) {
child.addError("Node type '%s' is invalid or not a subclass of Node.", ElementUtils.getQualifiedName(nodeType));
} else {
List<ExecutableTypeData> types = child.findGenericExecutableTypes(context);
if (types.isEmpty()) {
AnnotationValue executeWithValue = child.getExecuteWithValue();
child.addError(executeWithValue, "No generic execute method found with %s evaluated arguments for node type %s and frame types %s.", child.getExecuteWith().size(), ElementUtils.getSimpleName(nodeType), ElementUtils.getUniqueIdentifiers(createAllowedChildFrameTypes(node)));
}
}
}
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method parseChildNodeData.
private NodeData parseChildNodeData(NodeData parentNode, NodeChildData child, TypeElement originalTemplateType) {
TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) {
// generated nodes should not get called again.
return null;
}
if (!ElementUtils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) {
return null;
}
List<TypeElement> lookupTypes = collectSuperClasses(new ArrayList<TypeElement>(), templateType);
// Declaration order is not required for child nodes.
List<? extends Element> members = processingEnv.getElementUtils().getAllMembers(templateType);
NodeData node = parseNodeData(templateType, lookupTypes);
if (node.hasErrors()) {
return node;
}
List<TypeMirror> frameTypes = Collections.emptyList();
if (parentNode.getFrameType() != null) {
frameTypes = Arrays.asList(parentNode.getFrameType());
}
node.getExecutableTypes().addAll(parseExecutableTypeData(node, members, child.getExecuteWith().size(), frameTypes, true));
node.setFrameType(parentNode.getFrameType());
return node;
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeParser method parseNode.
private NodeData parseNode(TypeElement originalTemplateType) {
// reloading the type elements is needed for ecj
TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) {
// generated nodes should not get called again.
return null;
}
if (!ElementUtils.isAssignable(templateType.asType(), context.getTruffleTypes().getNode())) {
return null;
}
List<TypeElement> lookupTypes = collectSuperClasses(new ArrayList<TypeElement>(), templateType);
List<Element> members = loadMembers(templateType);
// ensure the processed element has at least one @Specialization annotation.
if (!containsSpecializations(members)) {
return null;
}
NodeData node = parseNodeData(templateType, lookupTypes);
if (node.hasErrors()) {
return node;
}
AnnotationMirror reflectable = findFirstAnnotation(lookupTypes, Introspectable.class);
if (reflectable != null) {
node.setReflectable(true);
}
AnnotationMirror reportPolymorphism = findFirstAnnotation(lookupTypes, ReportPolymorphism.class);
AnnotationMirror excludePolymorphism = findFirstAnnotation(lookupTypes, ReportPolymorphism.Exclude.class);
if (reportPolymorphism != null && excludePolymorphism == null) {
node.setReportPolymorphism(true);
}
node.getFields().addAll(parseFields(lookupTypes, members));
node.getChildren().addAll(parseChildren(node, lookupTypes, members));
node.getChildExecutions().addAll(parseExecutions(node.getFields(), node.getChildren(), members));
node.getExecutableTypes().addAll(parseExecutableTypeData(node, members, node.getSignatureSize(), context.getFrameTypes(), false));
initializeExecutableTypes(node);
initializeImportGuards(node, lookupTypes, members);
initializeChildren(node);
if (node.hasErrors()) {
// error sync point
return node;
}
node.getSpecializations().addAll(new SpecializationMethodParser(context, node).parse(members));
node.getSpecializations().addAll(new FallbackParser(context, node).parse(members));
node.getCasts().addAll(new CreateCastParser(context, node).parse(members));
if (node.hasErrors()) {
// error sync point
return node;
}
initializeSpecializations(members, node);
initializeExecutableTypeHierarchy(node);
verifySpecializationSameLength(node);
verifyVisibilities(node);
verifyMissingAbstractMethods(node, members);
verifyConstructors(node);
verifySpecializationThrows(node);
return node;
}
use of com.oracle.truffle.dsl.processor.model.NodeData in project graal by oracle.
the class NodeCodeGenerator method create.
@Override
public CodeTypeElement create(ProcessorContext context, NodeData node) {
List<CodeTypeElement> enclosedTypes = new ArrayList<>();
for (NodeData childNode : node.getEnclosingNodes()) {
CodeTypeElement type = create(context, childNode);
if (type != null) {
enclosedTypes.add(type);
}
}
List<CodeTypeElement> generatedNodes = generateNodes(context, node);
if (!generatedNodes.isEmpty() || !enclosedTypes.isEmpty()) {
CodeTypeElement type;
if (generatedNodes.isEmpty()) {
type = createContainer(node);
} else {
type = wrapGeneratedNodes(context, node, generatedNodes);
}
for (CodeTypeElement enclosedFactory : enclosedTypes) {
type.add(makeInnerClass(enclosedFactory));
}
if (node.getDeclaringNode() == null && enclosedTypes.size() > 0) {
ExecutableElement getFactories = createGetFactories(context, node);
if (getFactories != null) {
type.add(getFactories);
}
}
return type;
} else {
return null;
}
}
Aggregations