use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement in project graal by oracle.
the class TypeSystemCodeGenerator method createExpectMethod.
static CodeExecutableElement createExpectMethod(Modifier visibility, TypeSystemData typeSystem, TypeMirror sourceTypeOriginal, TypeMirror expectedTypeOriginal) {
TypeMirror expectedType = ElementUtils.fillInGenericWildcards(expectedTypeOriginal);
TypeMirror sourceType = ElementUtils.fillInGenericWildcards(sourceTypeOriginal);
if (ElementUtils.isObject(expectedType) || ElementUtils.isVoid(expectedType)) {
return null;
}
CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), expectedType, TypeSystemCodeGenerator.expectTypeMethodName(typeSystem, expectedType));
method.setVisibility(visibility);
method.addParameter(new CodeVariableElement(sourceType, LOCAL_VALUE));
method.addThrownType(typeSystem.getContext().getTruffleTypes().getUnexpectedValueException());
CodeTreeBuilder body = method.createBuilder();
body.startIf().tree(check(typeSystem, expectedType, LOCAL_VALUE)).end().startBlock();
body.startReturn().tree(cast(typeSystem, expectedType, LOCAL_VALUE)).end();
body.end();
body.startThrow().startNew(typeSystem.getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end();
return method;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement in project graal by oracle.
the class AbstractCodeWriter method visitVariable.
@Override
public Void visitVariable(VariableElement f, Void p) {
Element parent = f.getEnclosingElement();
for (AnnotationMirror annotation : f.getAnnotationMirrors()) {
visitAnnotation(f, annotation);
write(" ");
}
CodeTree init = null;
if (f instanceof CodeVariableElement) {
init = ((CodeVariableElement) f).getInit();
}
if (parent != null && parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) {
write(f.getSimpleName());
if (init != null) {
write("(");
visitTree(init, p, f);
write(")");
}
} else {
writeModifiers(f.getModifiers(), true);
boolean varArgs = false;
if (parent != null && parent.getKind() == ElementKind.METHOD) {
ExecutableElement method = (ExecutableElement) parent;
if (method.isVarArgs() && method.getParameters().indexOf(f) == method.getParameters().size() - 1) {
varArgs = true;
}
}
TypeMirror varType = f.asType();
if (varArgs) {
if (varType.getKind() == TypeKind.ARRAY) {
varType = ((ArrayType) varType).getComponentType();
}
write(useImport(f, varType));
write("...");
} else {
write(useImport(f, varType));
}
write(" ");
write(f.getSimpleName());
if (init != null) {
write(" = ");
visitTree(init, p, f);
}
}
return null;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement in project graal by oracle.
the class NodeParser method createGenericSpecialization.
private SpecializationData createGenericSpecialization(final NodeData node) {
FallbackParser parser = new FallbackParser(context, node);
MethodSpec specification = parser.createDefaultMethodSpec(node.getSpecializations().iterator().next().getMethod(), null, true, null);
List<VariableElement> parameterTypes = new ArrayList<>();
int signatureIndex = 1;
for (ParameterSpec spec : specification.getRequired()) {
parameterTypes.add(new CodeVariableElement(createGenericType(node, spec), "arg" + signatureIndex));
if (spec.isSignature()) {
signatureIndex++;
}
}
TypeMirror returnType = createGenericType(node, specification.getReturnType());
SpecializationData generic = parser.create("Generic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, parameterTypes);
if (generic == null) {
throw new RuntimeException("Unable to create generic signature for node " + node.getNodeId() + " with " + parameterTypes + ". Specification " + specification + ".");
}
return generic;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeVariableElement 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.java.model.CodeVariableElement 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);
}
Aggregations