use of com.oracle.truffle.dsl.processor.model.Parameter in project graal by oracle.
the class MethodSpecParser method parseImpl.
public TemplateMethod parseImpl(MethodSpec methodSpecification, int naturalOrder, String id, ExecutableElement method, AnnotationMirror annotation, TypeMirror returnType, List<? extends VariableElement> parameterTypes) {
ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
Parameter returnTypeMirror = matchParameter(returnTypeSpec, new CodeVariableElement(returnType, "returnType"), -1, -1);
if (returnTypeMirror == null) {
if (isEmitErrors() && method != null) {
TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<Parameter>emptyList());
String expectedReturnType = returnTypeSpec.toSignatureString(true);
String actualReturnType = ElementUtils.getSimpleName(returnType);
String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, methodSpecification.toSignatureString(method.getSimpleName().toString()));
invalidMethod.addError(message);
return invalidMethod;
} else {
return null;
}
}
List<Parameter> parameters = parseParameters(methodSpecification, parameterTypes, isUseVarArgs() && method != null ? method.isVarArgs() : false);
if (parameters == null) {
if (isEmitErrors() && method != null) {
TemplateMethod invalidMethod = new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<Parameter>emptyList());
String message = String.format("Method signature %s does not match to the expected signature: \n%s", createActualSignature(method), methodSpecification.toSignatureString(method.getSimpleName().toString()));
invalidMethod.addError(message);
return invalidMethod;
} else {
return null;
}
}
return new TemplateMethod(id, naturalOrder, template, methodSpecification, method, annotation, returnTypeMirror, parameters);
}
use of com.oracle.truffle.dsl.processor.model.Parameter in project graal by oracle.
the class NodeParser method initializeCaches.
private void initializeCaches(SpecializationData specialization, DSLExpressionResolver resolver) {
TypeMirror cacheMirror = context.getType(Cached.class);
List<CacheExpression> expressions = new ArrayList<>();
for (Parameter parameter : specialization.getParameters()) {
AnnotationMirror annotationMirror = ElementUtils.findAnnotationMirror(parameter.getVariableElement().getAnnotationMirrors(), cacheMirror);
if (annotationMirror != null) {
String initializer = ElementUtils.getAnnotationValue(String.class, annotationMirror, "value");
TypeMirror parameterType = parameter.getType();
DSLExpressionResolver localResolver = resolver;
if (parameterType.getKind() == TypeKind.DECLARED) {
localResolver = localResolver.copy(importPublicStaticMembers(ElementUtils.fromTypeMirror(parameterType), true));
}
CacheExpression cacheExpression;
DSLExpression expression = null;
try {
expression = DSLExpression.parse(initializer);
expression.accept(localResolver);
cacheExpression = new CacheExpression(parameter, annotationMirror, expression);
if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) {
cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(parameter.getType()));
}
} catch (InvalidExpressionException e) {
cacheExpression = new CacheExpression(parameter, annotationMirror, null);
cacheExpression.addError("Error parsing expression '%s': %s", initializer, e.getMessage());
}
if (!cacheExpression.hasErrors()) {
Cached cached = cacheExpression.getParameter().getVariableElement().getAnnotation(Cached.class);
cacheExpression.setDimensions(cached.dimensions());
if (parameterType.getKind() == TypeKind.ARRAY && !ElementUtils.isSubtype(((ArrayType) parameterType).getComponentType(), context.getType(NodeInterface.class))) {
if (cacheExpression.getDimensions() == -1) {
cacheExpression.addWarning("The cached dimensions attribute must be specified for array types.");
}
} else {
if (cacheExpression.getDimensions() != -1) {
cacheExpression.addError("The dimensions attribute has no affect for the type %s.", ElementUtils.getSimpleName(parameterType));
}
}
}
expressions.add(cacheExpression);
}
}
specialization.setCaches(expressions);
if (specialization.hasErrors()) {
return;
}
// verify that cache expressions are bound in the correct order.
for (int i = 0; i < expressions.size(); i++) {
CacheExpression currentExpression = expressions.get(i);
Set<VariableElement> boundVariables = currentExpression.getExpression().findBoundVariableElements();
for (int j = i + 1; j < expressions.size(); j++) {
CacheExpression boundExpression = expressions.get(j);
if (boundVariables.contains(boundExpression.getParameter().getVariableElement())) {
currentExpression.addError("The initializer expression of parameter '%s' binds unitialized parameter '%s. Reorder the parameters to resolve the problem.", currentExpression.getParameter().getLocalName(), boundExpression.getParameter().getLocalName());
break;
}
}
}
}
use of com.oracle.truffle.dsl.processor.model.Parameter in project graal by oracle.
the class NodeParser method initializePolymorphism.
private void initializePolymorphism(NodeData node) {
if (!node.needsRewrites(context)) {
return;
}
SpecializationData generic = node.getGenericSpecialization();
List<VariableElement> types = new ArrayList<>();
Collection<TypeMirror> frameTypes = new HashSet<>();
for (SpecializationData specialization : node.getSpecializations()) {
if (specialization.getFrame() != null) {
frameTypes.add(specialization.getFrame().getType());
}
}
if (node.supportsFrame()) {
frameTypes.add(node.getFrameType());
}
if (!frameTypes.isEmpty()) {
frameTypes = ElementUtils.uniqueSortedTypes(frameTypes, false);
TypeMirror frameType;
if (frameTypes.size() == 1) {
frameType = frameTypes.iterator().next();
} else {
frameType = context.getType(Frame.class);
}
types.add(new CodeVariableElement(frameType, TemplateMethod.FRAME_NAME));
}
TypeMirror returnType = null;
int index = 0;
for (Parameter genericParameter : generic.getReturnTypeAndParameters()) {
TypeMirror polymorphicType;
if (genericParameter.getLocalName().equals(TemplateMethod.FRAME_NAME)) {
continue;
}
boolean isReturnParameter = genericParameter == generic.getReturnType();
if (!genericParameter.getSpecification().isSignature()) {
polymorphicType = genericParameter.getType();
} else {
NodeExecutionData execution = genericParameter.getSpecification().getExecution();
Collection<TypeMirror> usedTypes = new HashSet<>();
for (SpecializationData specialization : node.getSpecializations()) {
if (specialization.isUninitialized()) {
continue;
}
Parameter parameter = specialization.findParameter(genericParameter.getLocalName());
if (parameter == specialization.getReturnType() && specialization.isFallback() && specialization.getMethod() == null) {
continue;
}
if (parameter == null) {
throw new AssertionError("Parameter existed in generic specialization but not in specialized. param = " + genericParameter.getLocalName());
}
if (isReturnParameter && specialization.hasUnexpectedResultRewrite()) {
if (!ElementUtils.isSubtypeBoxed(context, context.getType(Object.class), node.getGenericType(execution))) {
specialization.addError("Implicit 'Object' return type from UnexpectedResultException not compatible with generic type '%s'.", node.getGenericType(execution));
} else {
// if any specialization throws UnexpectedResultException, Object could
// be returned
usedTypes.add(context.getType(Object.class));
}
}
usedTypes.add(parameter.getType());
}
usedTypes = ElementUtils.uniqueSortedTypes(usedTypes, false);
if (usedTypes.size() == 1) {
polymorphicType = usedTypes.iterator().next();
} else {
polymorphicType = ElementUtils.getCommonSuperType(context, usedTypes);
}
if (execution != null && !ElementUtils.isSubtypeBoxed(context, polymorphicType, node.getGenericType(execution))) {
throw new AssertionError(String.format("Polymorphic types %s not compatible to generic type %s.", polymorphicType, node.getGenericType(execution)));
}
}
if (isReturnParameter) {
returnType = polymorphicType;
} else {
types.add(new CodeVariableElement(polymorphicType, "param" + index));
}
index++;
}
SpecializationMethodParser parser = new SpecializationMethodParser(context, node);
SpecializationData polymorphic = parser.create("Polymorphic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, types);
if (polymorphic == null) {
throw new AssertionError("Failed to parse polymorphic signature. " + parser.createDefaultMethodSpec(null, null, false, null) + " Types: " + returnType + " - " + types);
}
polymorphic.setKind(SpecializationKind.POLYMORPHIC);
node.getSpecializations().add(polymorphic);
}
use of com.oracle.truffle.dsl.processor.model.Parameter 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.Parameter in project graal by oracle.
the class ImplicitCastParser method create.
@Override
public ImplicitCastData create(TemplateMethod method, boolean invalid) {
if (invalid) {
return new ImplicitCastData(method, null, null);
}
Parameter target = method.findParameter("targetValue");
Parameter source = method.findParameter("sourceValue");
TypeMirror targetType = target.getType();
TypeMirror sourceType = source.getType();
if (ElementUtils.typeEquals(targetType, sourceType)) {
method.addError("Target type and source type of an @%s must not be the same type.", ImplicitCast.class.getSimpleName());
}
if (!method.getMethod().getModifiers().contains(Modifier.STATIC)) {
method.addError("@%s annotated method %s must be static.", ImplicitCast.class.getSimpleName(), method.getMethodName());
}
return new ImplicitCastData(method, sourceType, targetType);
}
Aggregations