private static SourceSectionFilter combine(SourceSectionFilter filter, Mode mode) { List<Class<?>> tags = new ArrayList<>(); tags.add(StandardTags.RootTag.class); if (mode == Mode.STATEMENTS) { tags.add(StandardTags.StatementTag.class); } return SourceSectionFilter.newBuilder().tagIs(tags.toArray(new Class<?>[0])).and(filter).build(); }
/** * Creates a new {@link SourceSectionFilter} expression using a {@link Builder builder} pattern. * Individual builder statements are interpreted as conjunctions (AND) while multiple parameters * for individual filter expressions are treated as disjunctions (OR). To create the final * filter finalize the expression using {@link Builder#build()}. * * @see Builder#sourceIs(Source...) * @see Builder#mimeTypeIs(String...) * @see Builder#tagIs(Class...) * @see Builder#tagIsNot(Class...) * @see Builder#sourceSectionEquals(SourceSection...) * @see Builder#indexIn(int, int) * @see Builder#lineIn(int, int) * @see Builder#lineIs(int) * @see Builder#rootNameIs(Predicate) * @see Builder#build() * * @return a new builder to create new {@link SourceSectionFilter} instances * @since 0.12 */ public static Builder newBuilder() { return new SourceSectionFilter(null).new Builder(); }
Set<Class<?>> getLimitedTags() { Set<Class<?>> tags = filterSourceSection.getLimitedTags(); if (inputFilter != null) { Set<Class<?>> inputTags = inputFilter.getLimitedTags(); if (tags == null) { return inputTags; } if (inputTags == null) { return tags; } if (inputTags.equals(tags)) { return tags; } else { Set<Class<?>> compoundTags = new HashSet<>(); compoundTags.addAll(tags); compoundTags.addAll(inputTags); return compoundTags; } } else { return tags; } }
private void verifyLineIndices(IndexRange... ranges) { verifyNotNull(ranges); for (IndexRange indexRange : ranges) { if (indexRange.startIndex < 1) { throw new IllegalArgumentException(String.format("Start line/column must be >= 1 but was %s.", indexRange.startIndex)); } } }
boolean isInstrumentedLeaf(Set<Class<?>> providedTags, Node instrumentedNode, SourceSection section) { return getFilter().isInstrumentedNode(providedTags, instrumentedNode, section); }
@Override void verifyFilter(SourceSectionFilter filter) { Set<Class<?>> providedTags = getProvidedTags(language); // filters must not reference tags not declared in @RequiredTags Set<Class<?>> referencedTags = filter.getReferencedTags(); if (!providedTags.containsAll(referencedTags)) { Set<Class<?>> missingTags = new HashSet<>(referencedTags); missingTags.removeAll(providedTags); Set<Class<?>> allTags = new LinkedHashSet<>(providedTags); allTags.addAll(missingTags); StringBuilder builder = new StringBuilder("{"); String sep = ""; for (Class<?> tag : allTags) { builder.append(sep); builder.append(tag.getSimpleName()); sep = ", "; } builder.append("}"); throw new IllegalArgumentException(String.format("The attached filter %s references the following tags %s which are not declared as provided by the language. " + "To fix this annotate the language class %s with @%s(%s).", filter, missingTags, language.getClass().getName(), ProvidedTags.class.getSimpleName(), builder)); } }
private void verifySourceOnly(SourceSectionFilter filter) { if (!filter.isSourceOnly()) { throw new IllegalArgumentException(String.format("The attached filter %s uses filters that require source sections to verifiy. " + "Source listeners can only use filter critera based on Source objects like mimeTypeIs or sourceIs.", filter)); } }
boolean isInstrumentedRoot(Set<Class<?>> providedTags, RootNode rootNode, SourceSection rootSourceSection, int rootNodeBits) { return getInstrumenter().isInstrumentableRoot(rootNode) && getFilter().isInstrumentedRoot(providedTags, rootSourceSection, rootNode, rootNodeBits); }
private static void reconstructStack(ArrayList<StackTraceEntry> sourceLocations, Node node, SourceSectionFilter sourceSectionFilter, Instrumenter instrumenter) { if (node == null || sourceSectionFilter == null) { return; } // We exclude the node itself as it will be pushed on the stack by the StackPushPopNode Node current = node.getParent(); while (current != null) { if (sourceSectionFilter.includes(current) && current.getSourceSection() != null) { sourceLocations.add(new StackTraceEntry(instrumenter, current, StackTraceEntry.STATE_INTERPRETED)); } current = current.getParent(); } }
boolean isInstrumentedSource(com.oracle.truffle.api.source.Source source) { return getInstrumenter().isInstrumentableSource(source) && getFilter().isInstrumentedSource(source); }
private void verifyLineIndices(IndexRange... ranges) { verifyNotNull(ranges); for (IndexRange indexRange : ranges) { if (indexRange.startIndex < 1) { throw new IllegalArgumentException(String.format("Start line/column must be >= 1 but was %s.", indexRange.startIndex)); } } }
boolean isInstrumentedLeaf(Set<Class<?>> providedTags, Node instrumentedNode, SourceSection section) { return getFilter().isInstrumentedNode(providedTags, instrumentedNode, section); }
@Override void verifyFilter(SourceSectionFilter filter) { Set<Class<?>> providedTags = getProvidedTags(languageInfo); // filters must not reference tags not declared in @RequiredTags Set<Class<?>> referencedTags = filter.getReferencedTags(); if (!providedTags.containsAll(referencedTags)) { Set<Class<?>> missingTags = new HashSet<>(referencedTags); missingTags.removeAll(providedTags); Set<Class<?>> allTags = new LinkedHashSet<>(providedTags); allTags.addAll(missingTags); StringBuilder builder = new StringBuilder("{"); String sep = ""; for (Class<?> tag : allTags) { builder.append(sep); builder.append(tag.getSimpleName()); sep = ", "; } builder.append("}"); Nodes langAccess = AccessorInstrumentHandler.nodesAccess(); TruffleLanguage<?> lang = langAccess.getLanguageSpi(languageInfo); throw new IllegalArgumentException(String.format("The attached filter %s references the following tags %s which are not declared as provided by the language. " + "To fix this annotate the language class %s with @%s(%s).", filter, missingTags, lang.getClass().getName(), ProvidedTags.class.getSimpleName(), builder)); } }
private void verifySourceOnly(SourceSectionFilter filter) { if (!filter.isSourceOnly()) { throw new IllegalArgumentException(String.format("The attached filter %s uses filters that require source sections to verifiy. " + "Source listeners can only use filter critera based on Source objects like mimeTypeIs or sourceIs.", filter)); } }
boolean isInstrumentedRoot(Set<Class<?>> providedTags, RootNode rootNode, SourceSection rootSourceSection, int rootNodeBits) { return getInstrumenter().isInstrumentableRoot(rootNode) && getFilter().isInstrumentedRoot(providedTags, rootSourceSection, rootNode, rootNodeBits); }
@Override public Caller visitFrame(FrameInstance frameInstance) { // we stop at eval root stack frames if (!SuspendedEvent.isEvalRootStackFrame(DebuggerSession.this, frameInstance) && (depth++ == 0)) { return null; } Node callNode = frameInstance.getCallNode(); while (callNode != null && !SourceSectionFilter.ANY.includes(callNode)) { callNode = callNode.getParent(); } if (callNode == null) { return null; } RootNode root = callNode.getRootNode(); if (root == null || !includeInternal && root.isInternal()) { return null; } return new Caller(frameInstance, callNode); } });
boolean isInstrumentedSource(com.oracle.truffle.api.source.Source source) { return getInstrumenter().isInstrumentableSource(source) && getFilter().isInstrumentedSource(source); }
@Override public <T extends ExecuteSourceListener> EventBinding<T> attachExecuteSourceListener(SourceFilter filter, T listener, boolean notifyLoaded) { SourceSectionFilter sectionsFilter = SourceSectionFilter.newBuilder().sourceFilter(filter).build(); return InstrumentationHandler.this.attachExecuteSourceListener(this, sectionsFilter, listener, notifyLoaded); }
/** * Add a filter for all source sections that are tagged with one of the given tags. * * @param tags matches one of the given tags * @return the builder to chain calls * @since 0.12 */ public Builder tagIs(Class<?>... tags) { verifyNotNull(tags); expressions.add(new EventFilterExpression.TagIs(tags)); return this; }
/** * Parent must match {@link #filterSourceSection} and child must match {@link #inputFilter}. */ boolean isChildInstrumentedLeaf(Set<Class<?>> providedTags, RootNode rootNode, Node parent, SourceSection parentSourceSection, Node current, SourceSection currentSourceSection) { if (inputFilter == null) { return false; } else if (rootNode == null) { return false; } else if (!InstrumentationHandler.isInstrumentableNode(parent, parentSourceSection)) { return false; } if (isInstrumentedLeaf(providedTags, parent, parentSourceSection) && inputFilter.isInstrumentedNode(providedTags, current, currentSourceSection)) { return true; } return false; }