use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.
the class InstrumentableProcessor method process.
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
return false;
}
try {
ProcessorContext context = new ProcessorContext(processingEnv, null);
ProcessorContext.setThreadLocalInstance(context);
DeclaredType instrumentableNode = context.getDeclaredType(InstrumentableNode.class);
ExecutableElement createWrapper = ElementUtils.findExecutableElement(instrumentableNode, CREATE_WRAPPER_NAME);
for (Element element : roundEnv.getElementsAnnotatedWith(GenerateWrapper.class)) {
if (!element.getKind().isClass() && !element.getKind().isInterface()) {
continue;
}
try {
if (element.getKind() != ElementKind.CLASS) {
emitError(element, String.format("Only classes can be annotated with %s.", GenerateWrapper.class.getSimpleName()));
continue;
}
if (createWrapper == null) {
emitError(element, String.format("Fatal %s.%s not found.", InstrumentableNode.class.getSimpleName(), CREATE_WRAPPER_NAME));
continue;
}
if (!ElementUtils.isAssignable(element.asType(), instrumentableNode)) {
emitError(element, String.format("Classes annotated with @%s must implement %s.", GenerateWrapper.class.getSimpleName(), InstrumentableNode.class.getSimpleName()));
continue;
} else {
boolean createWrapperFound = false;
for (ExecutableElement declaredMethod : ElementFilter.methodsIn(element.getEnclosedElements())) {
if (ElementUtils.signatureEquals(declaredMethod, createWrapper)) {
createWrapperFound = true;
break;
}
}
if (!createWrapperFound) {
emitError(element, String.format("Classes annotated with @%s must declare/override %s.%s and return a new instance of the generated wrapper class called %s." + " You may copy the following generated implementation: %n" + " @Override public %s createWrapper(%s probeNode) {%n" + " return new %s(this, probeNode);%n" + " }", GenerateWrapper.class.getSimpleName(), InstrumentableNode.class.getSimpleName(), CREATE_WRAPPER_NAME, createWrapperClassName((TypeElement) element), com.oracle.truffle.api.instrumentation.InstrumentableNode.WrapperNode.class.getSimpleName(), ProbeNode.class.getSimpleName(), createWrapperClassName((TypeElement) element)));
continue;
}
if (!ElementUtils.isAssignable(element.asType(), context.getType(Node.class))) {
emitError(element, String.format("Classes annotated with @%s must extend %s.", GenerateWrapper.class.getSimpleName(), Node.class.getSimpleName()));
continue;
}
}
AnnotationMirror generateWrapperMirror = ElementUtils.findAnnotationMirror(element.getAnnotationMirrors(), context.getType(GenerateWrapper.class));
if (generateWrapperMirror == null) {
continue;
}
CodeTypeElement unit = generateWrapperOnly(context, element);
if (unit == null) {
continue;
}
DeclaredType overrideType = (DeclaredType) context.getType(Override.class);
DeclaredType unusedType = (DeclaredType) context.getType(SuppressWarnings.class);
unit.accept(new GenerateOverrideVisitor(overrideType), null);
unit.accept(new FixWarningsVisitor(context.getEnvironment(), unusedType, overrideType), null);
unit.accept(new CodeWriter(context.getEnvironment(), element), null);
} catch (Throwable e) {
// never throw annotation processor exceptions to the compiler
// it might screw up its state.
handleThrowable(e, element);
}
}
// remove with deprecations
processLegacyInstrumentable(roundEnv, context);
return true;
} finally {
ProcessorContext.setThreadLocalInstance(null);
}
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.
the class FlatNodeGenFactory method create.
public CodeTypeElement create(CodeTypeElement clazz) {
for (NodeChildData child : node.getChildren()) {
clazz.addOptional(createAccessChildMethod(child));
}
for (NodeFieldData field : node.getFields()) {
if (!field.isGenerated()) {
continue;
}
clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), field.getType(), field.getName()));
if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) {
CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter());
method.getModifiers().remove(Modifier.ABSTRACT);
method.createBuilder().startReturn().string("this.").string(field.getName()).end();
clazz.add(method);
}
}
for (ExecutableElement superConstructor : GeneratorUtils.findUserConstructors(node.getTemplateType().asType())) {
clazz.add(createNodeConstructor(clazz, superConstructor));
}
for (NodeExecutionData execution : node.getChildExecutions()) {
if (execution.getChild() != null && execution.getChild().needsGeneratedField()) {
clazz.add(createNodeField(PRIVATE, execution.getNodeType(), nodeFieldName(execution), Child.class));
}
}
createFields(clazz);
TypeMirror genericReturnType = node.getPolymorphicSpecialization().getReturnType().getType();
List<ExecutableTypeData> executableTypes = filterExecutableTypes(node.getExecutableTypes(), reachableSpecializations);
List<ExecutableTypeData> genericExecutableTypes = new ArrayList<>();
List<ExecutableTypeData> specializedExecutableTypes = new ArrayList<>();
List<ExecutableTypeData> voidExecutableTypes = new ArrayList<>();
for (ExecutableTypeData type : executableTypes) {
if (ElementUtils.isVoid(type.getReturnType())) {
voidExecutableTypes.add(type);
} else if (type.hasUnexpectedValue(context) && !ElementUtils.typeEquals(genericReturnType, type.getReturnType())) {
specializedExecutableTypes.add(type);
} else {
genericExecutableTypes.add(type);
}
}
if (genericExecutableTypes.size() > 1) {
boolean hasGenericTypeMatch = false;
for (ExecutableTypeData genericExecutable : genericExecutableTypes) {
if (ElementUtils.typeEquals(genericExecutable.getReturnType(), genericReturnType)) {
hasGenericTypeMatch = true;
break;
}
}
if (hasGenericTypeMatch) {
for (ListIterator<ExecutableTypeData> iterator = genericExecutableTypes.listIterator(); iterator.hasNext(); ) {
ExecutableTypeData executableTypeData = iterator.next();
if (!ElementUtils.typeEquals(genericReturnType, executableTypeData.getReturnType())) {
iterator.remove();
specializedExecutableTypes.add(executableTypeData);
}
}
}
}
SpecializationData fallback = node.getGenericSpecialization();
if (fallback.getMethod() != null && fallback.isReachable()) {
clazz.add(createFallbackGuard());
}
for (ExecutableTypeData type : genericExecutableTypes) {
createExecute(clazz, type, Collections.<ExecutableTypeData>emptyList());
}
for (ExecutableTypeData type : specializedExecutableTypes) {
createExecute(clazz, type, genericExecutableTypes);
}
for (ExecutableTypeData type : voidExecutableTypes) {
List<ExecutableTypeData> genericAndSpecialized = new ArrayList<>();
genericAndSpecialized.addAll(genericExecutableTypes);
genericAndSpecialized.addAll(specializedExecutableTypes);
createExecute(clazz, type, genericAndSpecialized);
}
clazz.addOptional(createExecuteAndSpecialize());
if (shouldReportPolymorphism(node, reachableSpecializations)) {
clazz.addOptional(createCheckForPolymorphicSpecialize());
if (requiresCacheCheck()) {
clazz.addOptional(createCountCaches());
}
}
NodeInfo nodeInfo = node.getTemplateType().getAnnotation(NodeInfo.class);
if (nodeInfo == null || nodeInfo.cost() == NodeCost.MONOMORPHIC) /* the default */
{
clazz.add(createGetCostMethod());
}
for (TypeMirror type : ElementUtils.uniqueSortedTypes(expectedTypes, false)) {
if (!typeSystem.hasType(type)) {
clazz.addOptional(TypeSystemCodeGenerator.createExpectMethod(PRIVATE, typeSystem, context.getType(Object.class), type));
}
}
for (TypeMirror assumptionType : isValidSignatures.values()) {
clazz.add(createIsValid(assumptionType));
}
clazz.getEnclosedElements().addAll(removeThisMethods.values());
for (SpecializationData specialization : specializationClasses.keySet()) {
CodeTypeElement type = specializationClasses.get(specialization);
if (getInsertAccessorSet(true).contains(specialization)) {
type.add(createInsertAccessor(true));
} else if (getInsertAccessorSet(false).contains(specialization)) {
type.add(createInsertAccessor(false));
}
}
if (node.isReflectable()) {
generateReflectionInfo(clazz);
}
return clazz;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.
the class GeneratorUtils method isCopyConstructor.
static boolean isCopyConstructor(ExecutableElement element) {
if (element.getParameters().size() != 1) {
return false;
}
VariableElement var = element.getParameters().get(0);
TypeElement enclosingType = ElementUtils.findNearestEnclosingType(var);
if (ElementUtils.typeEquals(var.asType(), enclosingType.asType())) {
return true;
}
List<TypeElement> types = ElementUtils.getDirectSuperTypes(enclosingType);
for (TypeElement type : types) {
if (!(type instanceof CodeTypeElement)) {
// no copy constructors which are not generated types
return false;
}
if (ElementUtils.typeEquals(var.asType(), type.asType())) {
return true;
}
}
return false;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.
the class NodeCodeGenerator method create.
@Override
public CodeTypeElement create(ProcessorContext context, NodeData node) {
List<CodeTypeElement> enclosedTypes = new ArrayList<>();
for (NodeData childNode : node.getEnclosingNodes()) {
CodeTypeElement type = create(context, childNode);
if (type != null) {
enclosedTypes.add(type);
}
}
List<CodeTypeElement> generatedNodes = generateNodes(context, node);
if (!generatedNodes.isEmpty() || !enclosedTypes.isEmpty()) {
CodeTypeElement type;
if (generatedNodes.isEmpty()) {
type = createContainer(node);
} else {
type = wrapGeneratedNodes(context, node, generatedNodes);
}
for (CodeTypeElement enclosedFactory : enclosedTypes) {
type.add(makeInnerClass(enclosedFactory));
}
if (node.getDeclaringNode() == null && enclosedTypes.size() > 0) {
ExecutableElement getFactories = createGetFactories(context, node);
if (getFactories != null) {
type.add(getFactories);
}
}
return type;
} else {
return null;
}
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTypeElement in project graal by oracle.
the class NodeFactoryFactory method create.
public CodeTypeElement create() {
Modifier visibility = ElementUtils.getVisibility(node.getTemplateType().getModifiers());
TypeMirror nodeFactory = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getType(NodeFactory.class)), node.getNodeType());
CodeTypeElement clazz = GeneratorUtils.createClass(node, null, modifiers(), factoryClassName(node), null);
if (visibility != null) {
clazz.getModifiers().add(visibility);
}
clazz.getModifiers().add(Modifier.FINAL);
if (createdFactoryElement != null) {
clazz.getImplements().add(nodeFactory);
CodeAnnotationMirror supressWarnings = new CodeAnnotationMirror(context.getDeclaredType(SuppressWarnings.class));
supressWarnings.setElementValue(supressWarnings.findExecutableElement("value"), new CodeAnnotationValue(Arrays.asList(new CodeAnnotationValue("unchecked"), new CodeAnnotationValue("rawtypes"))));
clazz.getAnnotationMirrors().add(supressWarnings);
clazz.add(createNodeFactoryConstructor());
clazz.add(createCreateGetNodeClass());
clazz.add(createCreateGetExecutionSignature());
clazz.add(createCreateGetNodeSignatures());
clazz.add(createCreateNodeMethod());
clazz.add(createGetInstanceMethod(visibility));
clazz.add(createInstanceConstant(clazz.asType()));
createFactoryMethods(clazz);
}
return clazz;
}
Aggregations