use of com.oracle.truffle.dsl.processor.java.model.GeneratedElement in project graal by oracle.
the class GeneratorUtils method createClass.
public static CodeTypeElement createClass(Template sourceModel, TemplateMethod sourceMethod, Set<Modifier> modifiers, String simpleName, TypeMirror superType) {
TypeElement templateType = sourceModel.getTemplateType();
ProcessorContext context = ProcessorContext.getInstance();
PackageElement pack = ElementUtils.findPackageElement(templateType);
CodeTypeElement clazz = new CodeTypeElement(modifiers, ElementKind.CLASS, pack, simpleName);
TypeMirror resolvedSuperType = superType;
if (resolvedSuperType == null) {
resolvedSuperType = context.getType(Object.class);
}
clazz.setSuperClass(resolvedSuperType);
CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror(context.getTypes().GeneratedBy);
Element generatedByElement = templateType;
while (generatedByElement instanceof GeneratedElement) {
generatedByElement = generatedByElement.getEnclosingElement();
}
if (generatedByElement instanceof TypeElement) {
generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(generatedByElement.asType()));
if (sourceMethod != null) {
generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(ElementUtils.createReferenceName(sourceMethod.getMethod())));
}
clazz.addAnnotationMirror(generatedByAnnotation);
}
return clazz;
}
use of com.oracle.truffle.dsl.processor.java.model.GeneratedElement in project graal by oracle.
the class Log method message.
public void message(Kind kind, Element element, AnnotationMirror mirror, AnnotationValue value, String format, Object... args) {
AnnotationMirror usedMirror = mirror;
Element usedElement = element;
AnnotationValue usedValue = value;
String message = String.format(format, args);
if (element instanceof GeneratedElement) {
usedMirror = ((GeneratedElement) element).getGeneratorAnnotationMirror();
usedElement = ((GeneratedElement) element).getGeneratorElement();
usedValue = null;
if (usedElement != null) {
message = String.format("Element %s: %s", element, message);
}
}
if (kind != Kind.WARNING || emitWarnings) {
processingEnv.getMessager().printMessage(kind, message, usedElement, usedMirror, usedValue);
}
}
use of com.oracle.truffle.dsl.processor.java.model.GeneratedElement in project graal by oracle.
the class ElementUtils method getBinaryName.
public static String getBinaryName(TypeElement provider) {
if (provider instanceof GeneratedElement) {
String packageName = getPackageName(provider);
Element enclosing = provider.getEnclosingElement();
StringBuilder b = new StringBuilder();
b.append(provider.getSimpleName().toString());
while (enclosing != null) {
ElementKind kind = enclosing.getKind();
if ((kind.isClass() || kind.isInterface()) && enclosing instanceof TypeElement) {
b.insert(0, enclosing.getSimpleName().toString() + "$");
} else {
break;
}
enclosing = enclosing.getEnclosingElement();
}
b.insert(0, packageName + ".");
return b.toString();
} else {
return ProcessorContext.getInstance().getEnvironment().getElementUtils().getBinaryName(provider).toString();
}
}
use of com.oracle.truffle.dsl.processor.java.model.GeneratedElement in project graal by oracle.
the class MessageContainer method emitDefault.
private void emitDefault(ProcessorContext context, Log log, Message message) {
Kind kind = message.getKind();
Element messageElement = getMessageElement();
AnnotationMirror messageAnnotation = getMessageAnnotation();
AnnotationValue messageValue = getMessageAnnotationValue();
if (message.getAnnotationValue() != null) {
messageValue = message.getAnnotationValue();
}
if (message.getAnnotationMirror() != null) {
messageAnnotation = message.getAnnotationMirror();
}
Element enclosedElement = message.getEnclosedElement();
if (messageElement instanceof GeneratedElement) {
throw new AssertionError("Tried to emit message to generated element: " + messageElement + ". Make sure messages are redirected correctly. Message: " + message.getText());
}
String text = message.getText();
List<String> expectedErrors = ExpectError.getExpectedErrors(context.getEnvironment(), messageElement);
if (!expectedErrors.isEmpty()) {
if (ExpectError.isExpectedError(context.getEnvironment(), messageElement, text)) {
return;
}
log.message(kind, messageElement, null, null, "Message expected one of '%s' but was '%s'.", expectedErrors, text);
} else {
if (enclosedElement == null) {
log.message(kind, messageElement, messageAnnotation, messageValue, text);
} else {
log.message(kind, enclosedElement, null, null, text);
}
}
}
use of com.oracle.truffle.dsl.processor.java.model.GeneratedElement in project graal by oracle.
the class NodeParser method computeSharing.
public static Map<CacheExpression, String> computeSharing(Element templateType, Collection<NodeData> nodes, boolean emitSharingWarnings) {
TruffleTypes types = ProcessorContext.getInstance().getTypes();
Map<SharableCache, Collection<CacheExpression>> groups = computeSharableCaches(nodes);
// compute unnecessary sharing.
Map<String, List<SharableCache>> declaredGroups = new HashMap<>();
for (NodeData node : nodes) {
for (SpecializationData specialization : node.getSpecializations()) {
for (CacheExpression cache : specialization.getCaches()) {
if (cache.isAlwaysInitialized()) {
continue;
}
String group = cache.getSharedGroup();
if (group != null) {
declaredGroups.computeIfAbsent(group, (v) -> new ArrayList<>()).add(new SharableCache(specialization, cache));
}
}
}
}
Map<CacheExpression, String> sharedExpressions = new LinkedHashMap<>();
for (NodeData node : nodes) {
for (SpecializationData specialization : node.getSpecializations()) {
for (CacheExpression cache : specialization.getCaches()) {
if (cache.isAlwaysInitialized()) {
continue;
}
Element declaringElement;
if (node.getTemplateType() instanceof GeneratedElement) {
// generated node
declaringElement = node.getTemplateType().getEnclosingElement();
if (!declaringElement.getKind().isClass() && !declaringElement.getKind().isInterface()) {
throw new AssertionError("Unexpected declared element for generated element: " + declaringElement.toString());
}
} else {
declaringElement = node.getTemplateType();
}
String group = cache.getSharedGroup();
SharableCache sharable = new SharableCache(specialization, cache);
Collection<CacheExpression> expressions = groups.get(sharable);
List<SharableCache> declaredSharing = declaredGroups.get(group);
if (group != null) {
if (declaredSharing.size() <= 1) {
if (!ElementUtils.elementEquals(templateType, declaringElement)) {
// modifiable.
continue;
}
}
if (declaredSharing.size() <= 1 && (expressions == null || expressions.size() <= 1)) {
cache.addError(cache.getSharedGroupMirror(), cache.getSharedGroupValue(), "Could not find any other cached parameter that this parameter could be shared. " + "Cached parameters are only sharable if they declare the same type and initializer expressions and if the specialization only has a single instance. " + "Remove the @%s annotation or make the parameter sharable to resolve this.", types.Cached_Shared.asElement().getSimpleName().toString());
} else {
if (declaredSharing.size() <= 1) {
String error = String.format("No other cached parameters are specified as shared with the group '%s'.", group);
Set<String> similarGroups = new LinkedHashSet<>(declaredGroups.keySet());
similarGroups.remove(group);
List<String> fuzzyMatches = ExportsParser.fuzzyMatch(similarGroups, group, 0.7f);
if (!fuzzyMatches.isEmpty()) {
StringBuilder appendix = new StringBuilder(" Did you mean ");
String sep = "";
for (String string : fuzzyMatches) {
appendix.append(sep);
appendix.append('\'').append(string).append('\'');
sep = ", ";
}
error += appendix.toString() + "?";
}
cache.addError(cache.getSharedGroupMirror(), cache.getSharedGroupValue(), error);
} else {
StringBuilder b = new StringBuilder();
for (SharableCache otherCache : declaredSharing) {
if (cache == otherCache.expression) {
continue;
}
String reason = sharable.equalsWithReason(otherCache);
if (reason == null) {
continue;
}
String signature = formatCacheExpression(otherCache.expression);
b.append(String.format(" - %s : %s%n", signature, reason));
}
if (b.length() != 0) {
cache.addError(cache.getSharedGroupMirror(), cache.getSharedGroupValue(), "Could not share some of the cached parameters in group '%s': %n%sRemove the @%s annotation or resolve the described issues to allow sharing.", group, b.toString(), types.Cached_Shared.asElement().getSimpleName().toString());
} else {
sharedExpressions.put(sharable.expression, group);
}
}
}
} else if (expressions != null && expressions.size() > 1) {
if (emitSharingWarnings) {
/*
* We only emit sharing warnings for the same declaring type, because
* otherwise sharing warnings might not be resolvable if the base type
* is not modifiable.
*/
List<CacheExpression> declaredInExpression = new ArrayList<>();
for (CacheExpression expression : expressions) {
if (ElementUtils.isDeclaredIn(expression.getParameter().getVariableElement(), declaringElement)) {
declaredInExpression.add(expression);
}
}
if (declaredInExpression.size() > 1 && findAnnotationMirror(cache.getParameter().getVariableElement(), types.Cached_Exclusive) == null) {
StringBuilder sharedCaches = new StringBuilder();
Set<String> recommendedGroups = new LinkedHashSet<>();
for (CacheExpression cacheExpression : declaredInExpression) {
if (cacheExpression != cache) {
String signature = formatCacheExpression(cacheExpression);
sharedCaches.append(String.format(" - %s%n", signature));
String otherGroup = cacheExpression.getSharedGroup();
if (otherGroup != null) {
recommendedGroups.add(otherGroup);
}
}
}
String recommendedGroup = recommendedGroups.size() == 1 ? recommendedGroups.iterator().next() : "group";
cache.addWarning("The cached parameter may be shared with: %n%s Annotate the parameter with @%s(\"%s\") or @%s to allow or deny sharing of the parameter.", sharedCaches, types.Cached_Shared.asElement().getSimpleName().toString(), recommendedGroup, types.Cached_Exclusive.asElement().getSimpleName().toString());
}
}
}
}
}
}
return sharedExpressions;
}
Aggregations