use of com.oracle.truffle.api.instrumentation.InstrumentableNode 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.api.instrumentation.InstrumentableNode in project graal by oracle.
the class SuspendableLocationFinder method findNearestBound.
private static SourceSection findNearestBound(Source source, Set<Class<? extends Tag>> elementTags, int line, int column, SuspendAnchor anchor, TruffleInstrument.Env env) {
int offset = source.getLineStartOffset(line);
if (column > 0) {
offset += column - 1;
}
NearestSections sectionsCollector = new NearestSections(elementTags, (column <= 0) ? line : 0, offset, anchor);
// All SourceSections of the Source are loaded already when the source was executed
env.getInstrumenter().attachLoadSourceSectionListener(SourceSectionFilter.newBuilder().sourceIs(source).build(), sectionsCollector, true).dispose();
SourceSection section = sectionsCollector.getExactSection();
if (section != null) {
return section;
}
InstrumentableNode contextNode = sectionsCollector.getContainsNode();
if (contextNode == null) {
contextNode = sectionsCollector.getNextNode();
}
if (contextNode == null) {
contextNode = sectionsCollector.getPreviousNode();
}
if (contextNode == null) {
return null;
}
Node node = contextNode.findNearestNodeAt(offset, elementTags);
if (node == null) {
return null;
}
return node.getSourceSection();
}
Aggregations