use of com.oracle.truffle.dsl.processor.model.NodeFieldData in project graal by oracle.
the class NodeParser method verifyMissingAbstractMethods.
private static void verifyMissingAbstractMethods(NodeData nodeData, List<? extends Element> originalElements) {
if (!nodeData.needsFactory()) {
// if we need go generate factory for it.
return;
}
List<Element> elements = newElementList(originalElements);
Set<Element> unusedElements = new HashSet<>(elements);
for (ExecutableElement method : nodeData.getAllTemplateMethods()) {
unusedElements.remove(method);
}
for (NodeFieldData field : nodeData.getFields()) {
if (field.getGetter() != null) {
unusedElements.remove(field.getGetter());
}
}
for (NodeChildData child : nodeData.getChildren()) {
if (child.getAccessElement() != null) {
unusedElements.remove(child.getAccessElement());
}
}
Map<String, List<ExecutableElement>> methodsByName = null;
outer: for (ExecutableElement unusedMethod : ElementFilter.methodsIn(unusedElements)) {
if (unusedMethod.getModifiers().contains(Modifier.ABSTRACT)) {
// group by method name to avoid N^2 worst case complexity.
if (methodsByName == null) {
methodsByName = new HashMap<>();
for (ExecutableElement m : ElementFilter.methodsIn(unusedElements)) {
String name = m.getSimpleName().toString();
List<ExecutableElement> groupedElements = methodsByName.get(name);
if (groupedElements == null) {
groupedElements = new ArrayList<>();
methodsByName.put(name, groupedElements);
}
groupedElements.add(m);
}
}
for (ExecutableElement otherMethod : methodsByName.get(unusedMethod.getSimpleName().toString())) {
if (unusedMethod == otherMethod) {
continue;
}
if (ProcessorContext.getInstance().getEnvironment().getElementUtils().overrides(otherMethod, unusedMethod, nodeData.getTemplateType())) {
// -> the method does not need an implementation.
continue outer;
}
}
nodeData.addError("The type %s must implement the inherited abstract method %s.", ElementUtils.getSimpleName(nodeData.getTemplateType()), ElementUtils.getReadableSignature(unusedMethod));
}
}
}
use of com.oracle.truffle.dsl.processor.model.NodeFieldData in project graal by oracle.
the class NodeParser method parseExecutions.
private List<NodeExecutionData> parseExecutions(List<NodeFieldData> fields, List<NodeChildData> children, List<? extends Element> elements) {
List<ExecutableElement> methods = ElementFilter.methodsIn(elements);
boolean hasVarArgs = false;
int maxSignatureSize = 0;
if (!children.isEmpty()) {
int lastIndex = children.size() - 1;
hasVarArgs = children.get(lastIndex).getCardinality() == Cardinality.MANY;
if (hasVarArgs) {
maxSignatureSize = lastIndex;
} else {
maxSignatureSize = children.size();
}
}
List<NodeFieldData> nonGetterFields = new ArrayList<>();
for (NodeFieldData field : fields) {
if (field.getGetter() == null && field.isGenerated()) {
nonGetterFields.add(field);
}
}
TypeMirror cacheAnnotation = context.getType(Cached.class);
List<TypeMirror> frameTypes = context.getFrameTypes();
// pre-parse specializations to find signature size
for (ExecutableElement method : methods) {
AnnotationMirror mirror = ElementUtils.findAnnotationMirror(processingEnv, method, Specialization.class);
if (mirror == null) {
continue;
}
int currentArgumentIndex = 0;
parameter: for (VariableElement var : method.getParameters()) {
TypeMirror type = var.asType();
if (currentArgumentIndex == 0) {
// skip optionals
for (TypeMirror frameType : frameTypes) {
if (ElementUtils.typeEquals(type, frameType)) {
continue parameter;
}
}
}
if (currentArgumentIndex < nonGetterFields.size()) {
for (NodeFieldData field : nonGetterFields) {
if (ElementUtils.typeEquals(var.asType(), field.getType())) {
continue parameter;
}
}
}
if (ElementUtils.findAnnotationMirror(var.getAnnotationMirrors(), cacheAnnotation) != null) {
continue parameter;
}
currentArgumentIndex++;
}
maxSignatureSize = Math.max(maxSignatureSize, currentArgumentIndex);
}
List<NodeExecutionData> executions = new ArrayList<>();
for (int i = 0; i < maxSignatureSize; i++) {
boolean varArgParameter = false;
int childIndex = i;
if (i >= children.size() - 1) {
if (hasVarArgs) {
varArgParameter = hasVarArgs;
childIndex = Math.min(i, children.size() - 1);
} else if (i >= children.size()) {
childIndex = -1;
}
}
int varArgsIndex = -1;
NodeChildData child = null;
if (childIndex != -1) {
varArgsIndex = varArgParameter ? Math.abs(childIndex - i) : -1;
child = children.get(childIndex);
}
executions.add(new NodeExecutionData(child, i, varArgsIndex));
}
return executions;
}
use of com.oracle.truffle.dsl.processor.model.NodeFieldData in project graal by oracle.
the class NodeParser method parseFields.
private List<NodeFieldData> parseFields(List<TypeElement> typeHierarchy, List<? extends Element> elements) {
Set<String> names = new HashSet<>();
List<NodeFieldData> fields = new ArrayList<>();
for (VariableElement field : ElementFilter.fieldsIn(elements)) {
if (field.getModifiers().contains(Modifier.STATIC)) {
continue;
} else if (field.getAnnotation(Executed.class) != null) {
continue;
}
if (field.getModifiers().contains(Modifier.PUBLIC) || field.getModifiers().contains(Modifier.PROTECTED)) {
String name = field.getSimpleName().toString();
fields.add(new NodeFieldData(field, null, field, false));
names.add(name);
}
}
List<TypeElement> reversedTypeHierarchy = new ArrayList<>(typeHierarchy);
Collections.reverse(reversedTypeHierarchy);
for (TypeElement typeElement : reversedTypeHierarchy) {
AnnotationMirror nodeChildrenMirror = ElementUtils.findAnnotationMirror(processingEnv, typeElement, NodeFields.class);
List<AnnotationMirror> children = ElementUtils.collectAnnotations(context, nodeChildrenMirror, "value", typeElement, NodeField.class);
for (AnnotationMirror mirror : children) {
String name = ElementUtils.firstLetterLowerCase(ElementUtils.getAnnotationValue(String.class, mirror, "name"));
TypeMirror type = ElementUtils.getAnnotationValue(TypeMirror.class, mirror, "type");
if (type != null) {
NodeFieldData field = new NodeFieldData(typeElement, mirror, new CodeVariableElement(type, name), true);
if (name.isEmpty()) {
field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Field name cannot be empty.");
} else if (names.contains(name)) {
field.addError(ElementUtils.getAnnotationValue(mirror, "name"), "Duplicate field name '%s'.", name);
}
names.add(name);
fields.add(field);
} else {
// Type is null here. This indicates that the type could not be resolved.
// The Java compiler will subsequently raise the appropriate error.
}
}
}
for (NodeFieldData nodeFieldData : fields) {
nodeFieldData.setGetter(findGetter(elements, nodeFieldData.getName(), nodeFieldData.getType()));
}
return fields;
}
use of com.oracle.truffle.dsl.processor.model.NodeFieldData in project graal by oracle.
the class NodeParser method initializeExpressions.
private void initializeExpressions(List<? extends Element> elements, NodeData node) {
List<Element> members = filterNotAccessibleElements(node.getTemplateType(), elements);
List<VariableElement> fields = new ArrayList<>();
for (NodeFieldData field : node.getFields()) {
fields.add(field.getVariable());
}
for (SpecializationData specialization : node.getSpecializations()) {
if (specialization.getMethod() == null) {
continue;
}
List<Element> specializationMembers = new ArrayList<>(members.size() + specialization.getParameters().size() + fields.size());
for (Parameter p : specialization.getParameters()) {
specializationMembers.add(p.getVariableElement());
}
specializationMembers.addAll(fields);
specializationMembers.addAll(members);
DSLExpressionResolver resolver = new DSLExpressionResolver(context, specializationMembers);
initializeCaches(specialization, resolver);
initializeGuards(specialization, resolver);
if (specialization.hasErrors()) {
continue;
}
initializeLimit(specialization, resolver);
initializeAssumptions(specialization, resolver);
}
}
use of com.oracle.truffle.dsl.processor.model.NodeFieldData in project graal by oracle.
the class NodeMethodParser method addDefaultFieldMethodSpec.
protected void addDefaultFieldMethodSpec(MethodSpec methodSpec) {
for (NodeFieldData field : getNode().getFields()) {
if (field.getGetter() == null) {
ParameterSpec spec = new ParameterSpec(field.getName(), field.getType());
spec.setLocal(true);
methodSpec.addOptional(spec);
}
}
}
Aggregations