use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.
the class NodeParser method parseExecutableTypeData.
private List<ExecutableTypeData> parseExecutableTypeData(NodeData node, List<? extends Element> elements, int signatureSize, List<TypeMirror> frameTypes, boolean includeFinals) {
List<ExecutableTypeData> typeData = new ArrayList<>();
for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
Set<Modifier> modifiers = method.getModifiers();
if (modifiers.contains(Modifier.PRIVATE) || modifiers.contains(Modifier.STATIC)) {
continue;
}
if (!includeFinals && modifiers.contains(Modifier.FINAL)) {
continue;
}
if (!method.getSimpleName().toString().startsWith("execute")) {
continue;
}
if (ElementUtils.findAnnotationMirror(context.getEnvironment(), method, Specialization.class) != null) {
continue;
}
ExecutableTypeData executableType = new ExecutableTypeData(node, method, signatureSize, context.getFrameTypes());
if (executableType.getFrameParameter() != null) {
boolean supportedType = false;
for (TypeMirror type : frameTypes) {
if (ElementUtils.isAssignable(type, executableType.getFrameParameter())) {
supportedType = true;
break;
}
}
if (!supportedType) {
continue;
}
}
typeData.add(executableType);
}
namesUnique(typeData);
return typeData;
}
use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.
the class NodeParser method buildExecutableHierarchy.
private static void buildExecutableHierarchy(NodeData node, ExecutableTypeData parent, ListIterator<ExecutableTypeData> executesIterator) {
while (executesIterator.hasNext()) {
ExecutableTypeData other = executesIterator.next();
if (other.canDelegateTo(parent)) {
parent.addDelegatedFrom(other);
executesIterator.remove();
}
}
for (int i = 1; i < parent.getDelegatedFrom().size(); i++) {
buildExecutableHierarchy(node, parent.getDelegatedFrom().get(i - 1), parent.getDelegatedFrom().listIterator(i));
}
}
use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData 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.ExecutableTypeData in project graal by oracle.
the class NodeParser method buildExecutableHierarchy.
private static List<ExecutableTypeData> buildExecutableHierarchy(NodeData node) {
List<ExecutableTypeData> executes = node.getExecutableTypes();
if (executes.isEmpty()) {
return Collections.emptyList();
}
List<ExecutableTypeData> hierarchyExecutes = new ArrayList<>(executes);
Collections.sort(hierarchyExecutes);
ExecutableTypeData parent = hierarchyExecutes.get(0);
ListIterator<ExecutableTypeData> executesIterator = hierarchyExecutes.listIterator(1);
buildExecutableHierarchy(node, parent, executesIterator);
return hierarchyExecutes;
}
use of com.oracle.truffle.dsl.processor.model.ExecutableTypeData in project graal by oracle.
the class NodeParser method initializeExecutableTypes.
private void initializeExecutableTypes(NodeData node) {
List<ExecutableTypeData> allExecutes = node.getExecutableTypes();
Set<String> inconsistentFrameTypes = new HashSet<>();
TypeMirror frameType = null;
for (ExecutableTypeData execute : allExecutes) {
TypeMirror frame = execute.getFrameParameter();
TypeMirror resolvedFrameType;
if (frame != null) {
resolvedFrameType = frame;
if (frameType == null) {
frameType = resolvedFrameType;
} else if (!ElementUtils.typeEquals(frameType, resolvedFrameType)) {
// found inconsistent frame types
inconsistentFrameTypes.add(ElementUtils.getSimpleName(frameType));
inconsistentFrameTypes.add(ElementUtils.getSimpleName(resolvedFrameType));
}
}
}
if (!inconsistentFrameTypes.isEmpty()) {
// ensure they are sorted somehow
List<String> inconsistentFrameTypesList = new ArrayList<>(inconsistentFrameTypes);
Collections.sort(inconsistentFrameTypesList);
node.addError("Invalid inconsistent frame types %s found for the declared execute methods. The frame type must be identical for all execute methods.", inconsistentFrameTypesList);
}
if (frameType == null) {
frameType = context.getType(void.class);
}
node.setFrameType(frameType);
boolean genericFound = false;
for (ExecutableTypeData type : node.getExecutableTypes()) {
if (!type.hasUnexpectedValue(context)) {
genericFound = true;
break;
}
}
// no generic executes
if (!genericFound) {
node.addError("No accessible and overridable generic execute method found. Generic execute methods usually have the " + "signature 'public abstract {Type} execute(VirtualFrame)' and must not throw any checked exceptions.");
}
int nodeChildDeclarations = 0;
int nodeChildDeclarationsRequired = 0;
List<NodeExecutionData> executions = node.getChildExecutions();
for (NodeExecutionData execution : executions) {
if (execution.getChild() == null) {
nodeChildDeclarationsRequired = execution.getIndex() + 1;
} else {
nodeChildDeclarations++;
}
}
List<String> requireNodeChildDeclarations = new ArrayList<>();
for (ExecutableTypeData type : allExecutes) {
if (type.getEvaluatedCount() < nodeChildDeclarationsRequired) {
requireNodeChildDeclarations.add(ElementUtils.createReferenceName(type.getMethod()));
}
}
if (!requireNodeChildDeclarations.isEmpty()) {
node.addError("Not enough child node declarations found. Please annotate the node class with addtional @NodeChild annotations or remove all execute methods that do not provide all evaluated values. " + "The following execute methods do not provide all evaluated values for the expected signature size %s: %s.", executions.size(), requireNodeChildDeclarations);
}
if (nodeChildDeclarations > 0 && executions.size() == node.getMinimalEvaluatedParameters()) {
for (NodeChildData child : node.getChildren()) {
child.addError("Unnecessary @NodeChild declaration. All evaluated child values are provided as parameters in execute methods.");
}
}
}
Aggregations