use of javax.lang.model.element.AnnotationValue in project graal by oracle.
the class StructsProcessor method process.
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (done) {
return false;
}
// Initialize annotations
generateStructs = findAnnotation(GENERATE_STRUCTS);
knownStruct = findAnnotation(KNOWN_STRUCT);
genStructValue = findAttribute("value", generateStructs);
structName = findAttribute("structName", knownStruct);
memberNames = findAttribute("memberNames", knownStruct);
types = findAttribute("types", knownStruct);
List<String> structs = new ArrayList<>();
// Look at the @GenerateStructs annotation
for (Element e : roundEnv.getElementsAnnotatedWith(generateStructs)) {
assert e.getKind() == ElementKind.CLASS;
AnnotationMirror generateStructAnnotation = EspressoProcessor.getAnnotation(e, generateStructs);
// Obtain the value() of @GenerateStructs (The only interesting thing)
AnnotationValue v = getAttribute(generateStructAnnotation, genStructValue);
assert v.getValue() instanceof List<?>;
List<?> list = (List<?>) v.getValue();
for (Object known : list) {
// Each entry in the annotation value is a struct to generate.
assert known instanceof AnnotationValue;
assert ((AnnotationValue) known).getValue() instanceof AnnotationMirror;
AnnotationMirror knownStr = ((AnnotationMirror) ((AnnotationValue) known).getValue());
// C struct name.
String strName = (String) getAttribute(knownStr, structName).getValue();
// C struct members.
List<?> memberNamesList = (List<?>) getAttribute(knownStr, memberNames).getValue();
// native to java types.
List<?> typesList = (List<?>) getAttribute(knownStr, types).getValue();
String className = processStruct(strName, memberNamesList, typesList);
structs.add(className);
}
}
String source = generateStructCollector(structs);
commit(null, STRUCTS_CLASS, source);
done = true;
return false;
}
use of javax.lang.model.element.AnnotationValue in project graal by oracle.
the class NodeParser method parseChildren.
private List<NodeChildData> parseChildren(NodeData node, final List<TypeElement> typeHierarchy, List<? extends Element> elements) {
Map<String, TypeMirror> castNodeTypes = new HashMap<>();
for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
AnnotationMirror mirror = findAnnotationMirror(method, types.CreateCast);
if (mirror != null) {
List<String> children = (getAnnotationValueList(String.class, mirror, "value"));
if (children != null) {
for (String child : children) {
castNodeTypes.put(child, method.getReturnType());
}
}
}
}
List<NodeChildData> executedFieldChildren = new ArrayList<>();
for (VariableElement field : ElementFilter.fieldsIn(elements)) {
if (field.getModifiers().contains(Modifier.STATIC)) {
continue;
}
AnnotationMirror executed = findAnnotationMirror(field.getAnnotationMirrors(), types.Executed);
if (executed != null) {
TypeMirror type = field.asType();
String name = field.getSimpleName().toString();
Cardinality cardinality = Cardinality.ONE;
if (type.getKind() == TypeKind.ARRAY) {
cardinality = Cardinality.MANY;
}
AnnotationValue executedWith = getAnnotationValue(executed, "with");
NodeChildData child = new NodeChildData(field, executed, name, type, type, field, cardinality, executedWith, null, null);
executedFieldChildren.add(child);
if (field.getModifiers().contains(Modifier.PRIVATE)) {
child.addError("Field annotated with @%s must be visible for the generated subclass to execute.", types.Executed.asElement().getSimpleName().toString());
}
if (cardinality == Cardinality.ONE) {
if (ElementUtils.findAnnotationMirror(field, types.Node_Child) == null) {
child.addError("Field annotated with @%s must also be annotated with @%s.", types.Executed.asElement().getSimpleName().toString(), types.Node_Child.asElement().getSimpleName().toString());
}
} else {
assert cardinality == Cardinality.MANY;
if (ElementUtils.findAnnotationMirror(field, types.Node_Children) == null) {
child.addError("Field annotated with @%s must also be annotated with @%s.", types.Executed.asElement().getSimpleName().toString(), types.Node_Children.asElement().getSimpleName().toString());
}
}
}
}
NodeChildData many = null;
Set<String> names = new HashSet<>();
for (NodeChildData child : executedFieldChildren) {
if (child.needsGeneratedField()) {
throw new AssertionError("Should not need generated field.");
}
if (names.contains(child.getName())) {
child.addError("Field annotated with @%s has duplicate name '%s'. " + "Executed children must have unique names.", types.Executed.asElement().getSimpleName().toString(), child.getName());
} else if (many != null) {
child.addError("Field annotated with @%s is hidden by executed field '%s'. " + "Executed child fields with multiple children hide all following executed child declarations. " + "Reorder or remove this executed child declaration.", types.Executed.asElement().getSimpleName().toString(), many.getName());
} else if (child.getCardinality().isMany()) {
many = child;
}
names.add(child.getName());
}
List<NodeChildData> nodeChildren = new ArrayList<>();
List<TypeElement> typeHierarchyReversed = new ArrayList<>(typeHierarchy);
Collections.reverse(typeHierarchyReversed);
for (TypeElement type : typeHierarchyReversed) {
AnnotationMirror nodeChildrenMirror = findAnnotationMirror(type, types.NodeChildren);
TypeMirror nodeClassType = type.getSuperclass();
if (nodeClassType.getKind() == TypeKind.NONE || !isAssignable(nodeClassType, types.Node)) {
nodeClassType = null;
}
List<AnnotationMirror> children = collectAnnotations(nodeChildrenMirror, "value", type, types.NodeChild);
int index = 0;
for (AnnotationMirror childMirror : children) {
String name = getAnnotationValue(String.class, childMirror, "value");
if (name.equals("")) {
name = "child" + index;
}
Cardinality cardinality = Cardinality.ONE;
TypeMirror childNodeType = inheritType(childMirror, "type", nodeClassType);
if (childNodeType.getKind() == TypeKind.ARRAY) {
cardinality = Cardinality.MANY;
}
TypeMirror originalChildType = childNodeType;
TypeMirror castNodeType = castNodeTypes.get(name);
if (castNodeType != null) {
childNodeType = castNodeType;
}
Element getter = findGetter(elements, name, childNodeType);
AnnotationValue executeWith = getAnnotationValue(childMirror, "executeWith");
String create = null;
boolean implicit = (boolean) unboxAnnotationValue(getAnnotationValue(childMirror, "implicit"));
boolean implicitCreateSpecified = getAnnotationValue(childMirror, "implicitCreate", false) != null;
if (implicit || implicitCreateSpecified) {
create = (String) unboxAnnotationValue(getAnnotationValue(childMirror, "implicitCreate"));
}
String uncached = null;
boolean allowUncached = (boolean) unboxAnnotationValue(getAnnotationValue(childMirror, "allowUncached"));
boolean uncachedSpecified = getAnnotationValue(childMirror, "uncached", false) != null;
if (allowUncached || uncachedSpecified) {
uncached = (String) unboxAnnotationValue(getAnnotationValue(childMirror, "uncached"));
}
NodeChildData nodeChild = new NodeChildData(type, childMirror, name, childNodeType, originalChildType, getter, cardinality, executeWith, create, uncached);
if (implicitCreateSpecified && implicit) {
nodeChild.addError("The attributes 'implicit' and 'implicitCreate' are mutually exclusive. Remove one of the attributes to resolve this.");
}
if (uncachedSpecified && allowUncached) {
nodeChild.addError("The attributes 'allowUncached' and 'uncached' are mutually exclusive. Remove one of the attributes to resolve this.");
}
nodeChildren.add(nodeChild);
if (nodeChild.getNodeType() == null) {
nodeChild.addError("No valid node type could be resolved.");
}
if (nodeChild.hasErrors()) {
continue;
}
index++;
}
}
if (!nodeChildren.isEmpty() && !executedFieldChildren.isEmpty()) {
node.addError("The use of @%s and @%s at the same time is not supported.", types.NodeChild.asElement().getSimpleName().toString(), types.Executed.asElement().getSimpleName().toString());
return executedFieldChildren;
} else if (!executedFieldChildren.isEmpty()) {
return executedFieldChildren;
} else {
List<NodeChildData> filteredChildren = new ArrayList<>();
Set<String> encounteredNames = new HashSet<>();
for (int i = nodeChildren.size() - 1; i >= 0; i--) {
NodeChildData child = nodeChildren.get(i);
if (!encounteredNames.contains(child.getName())) {
filteredChildren.add(0, child);
encounteredNames.add(child.getName());
}
}
return filteredChildren;
}
}
use of javax.lang.model.element.AnnotationValue in project graal by oracle.
the class NodeParser method initializeReplaces.
private static void initializeReplaces(NodeData node) {
for (SpecializationData specialization : node.getSpecializations()) {
Set<SpecializationData> resolvedSpecializations = specialization.getReplaces();
Set<String> includeNames = specialization.getReplacesNames();
for (String includeName : includeNames) {
// TODO reduce complexity of this lookup.
List<SpecializationData> foundSpecializations = lookupSpecialization(node, includeName);
AnnotationValue value = getAnnotationValue(specialization.getMarkerAnnotation(), "replaces");
if (foundSpecializations.isEmpty()) {
specialization.addError(value, "The referenced specialization '%s' could not be found.", includeName);
} else {
resolvedSpecializations.addAll(foundSpecializations);
for (SpecializationData foundSpecialization : foundSpecializations) {
if (foundSpecialization.compareTo(specialization) > 0) {
specialization.addError(value, "The replaced specialization '%s' must be declared before the replacing specialization.", includeName);
}
}
}
}
}
}
use of javax.lang.model.element.AnnotationValue in project graal by oracle.
the class NodeParser method parseCached.
private void parseCached(CacheExpression cache, SpecializationData specialization, DSLExpressionResolver originalResolver, Parameter parameter) {
DSLExpressionResolver resolver = originalResolver;
AnnotationMirror cachedAnnotation = cache.getMessageAnnotation();
AnnotationValue adopt = null;
if (!cache.hasErrors()) {
adopt = getAnnotationValue(cachedAnnotation, "adopt", false);
AnnotationMirror cached = findAnnotationMirror(cache.getParameter().getVariableElement(), types.Cached);
cache.setDimensions(getAnnotationValue(Integer.class, cached, "dimensions"));
boolean disabledAdopt = adopt != null && Boolean.FALSE.equals(adopt.getValue());
if (parameter.getType().getKind() == TypeKind.ARRAY && (disabledAdopt || !isSubtype(((ArrayType) parameter.getType()).getComponentType(), types.NodeInterface))) {
if (cache.getDimensions() == -1) {
cache.addWarning("The cached dimensions attribute must be specified for array types.");
}
} else {
if (!disabledAdopt && cache.getDimensions() != -1) {
cache.addError("The dimensions attribute has no affect for the type %s.", getSimpleName(parameter.getType()));
}
}
}
List<String> expressionParameters = getAnnotationValueList(String.class, cachedAnnotation, "parameters");
String initializer = getAnnotationValue(String.class, cachedAnnotation, "value");
String uncached = getAnnotationValue(String.class, cachedAnnotation, "uncached");
String parameters = String.join(", ", expressionParameters);
initializer = initializer.replace("$parameters", parameters);
uncached = uncached.replace("$parameters", parameters);
if (ElementUtils.isAssignable(parameter.getType(), types.Library) && !ElementUtils.typeEquals(parameter.getType(), types.Library)) {
cache.addError("The use of @%s is not supported for libraries. Use @%s instead.", types.Cached.asElement().getSimpleName().toString(), types.CachedLibrary.asElement().getSimpleName().toString());
} else if (NodeCodeGenerator.isSpecializedNode(parameter.getType())) {
// if it is a node try to parse with the node parser to find out whether we
// should may use the generated create and getUncached methods.
List<CodeExecutableElement> executables = parseNodeFactoryMethods(parameter.getType());
if (executables != null) {
resolver = resolver.copy(executables);
}
}
if (!cache.hasErrors()) {
cache.setDefaultExpression(parseCachedExpression(resolver, cache, parameter.getType(), initializer));
}
boolean requireUncached = specialization.getNode().isGenerateUncached() || mode == ParseMode.EXPORTED_MESSAGE;
if (cache.hasErrors()) {
// error sync point
return;
}
boolean uncachedSpecified = getAnnotationValue(cachedAnnotation, "uncached", false) != null;
if (requireUncached) {
boolean allowUncached = getAnnotationValue(Boolean.class, cachedAnnotation, "allowUncached");
if (uncachedSpecified && allowUncached) {
cache.addError("The attributes 'allowUncached' and 'uncached' are mutually exclusive. Remove one of the attributes to resolve this.");
} else if (allowUncached) {
cache.setUncachedExpression(cache.getDefaultExpression());
} else {
if (!uncachedSpecified && cache.getDefaultExpression() != null && !cache.getDefaultExpression().mayAllocate()) {
cache.setUncachedExpression(cache.getDefaultExpression());
} else {
cache.setUncachedExpression(parseCachedExpression(resolver, cache, parameter.getType(), uncached));
if (!uncachedSpecified && cache.hasErrors()) {
cache.setUncachedExpressionError(cache.getMessages().iterator().next());
cache.getMessages().clear();
}
}
}
}
if (requireUncached && cache.getUncachedExpression() == null && cache.getDefaultExpression() != null) {
if (specialization.isTrivialExpression(cache.getDefaultExpression())) {
cache.setUncachedExpression(cache.getDefaultExpression());
}
}
if (adopt != null) {
TypeMirror type = parameter.getType();
if (type == null || !ElementUtils.isAssignable(type, types.NodeInterface) && !(type.getKind() == TypeKind.ARRAY && isAssignable(((ArrayType) type).getComponentType(), types.NodeInterface))) {
cache.addError("Type '%s' is neither a NodeInterface type, nor an array of NodeInterface types and therefore it can not be adopted. Remove the adopt attribute to resolve this.", Objects.toString(type));
}
}
cache.setAdopt(getAnnotationValue(Boolean.class, cachedAnnotation, "adopt", true));
}
use of javax.lang.model.element.AnnotationValue in project graal by oracle.
the class NodeParser method initializeOrder.
private static void initializeOrder(NodeData node) {
List<SpecializationData> specializations = node.getSpecializations();
Collections.sort(specializations);
for (SpecializationData specialization : specializations) {
String searchName = specialization.getInsertBeforeName();
if (searchName == null || specialization.getMethod() == null) {
continue;
}
List<SpecializationData> found = lookupSpecialization(node, searchName);
if (found.isEmpty() || found.get(0).getMethod() == null) {
AnnotationValue value = getAnnotationValue(specialization.getMarkerAnnotation(), "insertBefore");
specialization.addError(value, "The referenced specialization '%s' could not be found.", searchName);
continue;
}
SpecializationData first = found.iterator().next();
ExecutableElement currentMethod = specialization.getMethod();
ExecutableElement insertBeforeMethod = first.getMethod();
TypeMirror currentEnclosedType = currentMethod.getEnclosingElement().asType();
TypeMirror insertBeforeEnclosedType = insertBeforeMethod.getEnclosingElement().asType();
if (typeEquals(currentEnclosedType, insertBeforeEnclosedType) || !isSubtype(currentEnclosedType, insertBeforeEnclosedType)) {
AnnotationValue value = getAnnotationValue(specialization.getMarkerAnnotation(), "insertBefore");
specialization.addError(value, "Specializations can only be inserted before specializations in superclasses.", searchName);
continue;
}
specialization.setInsertBefore(first);
}
for (int i = 0; i < specializations.size(); i++) {
SpecializationData specialization = specializations.get(i);
SpecializationData insertBefore = specialization.getInsertBefore();
if (insertBefore != null) {
int insertIndex = specializations.indexOf(insertBefore);
if (insertIndex < i) {
specializations.remove(i);
specializations.add(insertIndex, specialization);
}
}
}
for (int i = 0; i < specializations.size(); i++) {
specializations.get(i).setIndex(i);
}
}
Aggregations