Features
CodeProber usage is described and demonstrated in the following resources:
- YouTube: 5 minute overview
- Paper: Publication in JSS
- YouTube: Demonstration at LIVE 2023 (13 minutes)
Basic Features
Listed below are a number of basic features supported in CodeProber.
Creating Probe from Code

Right click anywhere in the CodeProber editor to create a new probe.
Creating Probe from Reference

If the output of a probe is an AST reference, you can click it to create a new probe. This allows you to iteratively follow references across the AST.
AST View

When selecting the property name while creating a new probe, you can click the triple dots, and then “Render AST downwards”. This will show the AST structure of tree of the node in question.
Pretty Print

In the same dropdown where you create the AST view, you can also
select “Pretty Print” to access a pretty-printed representation of
your AST. For this to work well you must implement the
cpr_pp*
methods described in AST API.
Search Probe

When selecting property name, you can enter a string on the form
*.propName?predicate
and then press enter to create a
“search probe”. Search probes can show all nodes in a given subtree
that fulfill a predicate, and then evaluate some property on them.
Both *.propName
and ?predicate
is
optional.
- If you just type
*.propName
, then propName is evaluated for every node in the given subtree. - If you just type
?predicate
, then the search probe will list all nodes that pass the predicate, but not evaluate any property on them.
predicate
can have multiple components, separated by
&
, and each component can have an explicit comparison
using =foo
. If no explicit comparison exists, then it is
treated as if you wrote =true
. For example, you can write
isConstant&type=IntType
.
Predicates can also perform subtype-based filtering using
<:
. A common use case for this is to write something
like this<:Expr
to select all expressions in a tree.
The right hand side of <:
should use either the fullly
qualified type of an AST node like pkg.name.here.Expr
, or
just the simple name like Expr
.
Workspace

Using the system
property -Dcpr.workspace
, you can expose a filesystem
in the CodeProber UI. Any changes you make in the UI will be saved to
disk, and any changes to disk will be loaded into in the UI.
Text Probe

CodeProber interprets text in the format [[A.b.c]]
as
a “text probe”. Text probes are evaluated by CodeProber, and the
results are rendered in a blue box the editor. If you additionally add
=d
, it will treat the probe as an assertion, and show a
green or red box depending on if the assertion passed or not. For
example, in the image it evaluated AddExpr.constant
and
compared it with 3
. The comparison succeeded, so the box
is green.
Three comparison operators are available: =
,
!=
and ~=
. They perform equals, not-equals
and contains (as in String.contains) comparison respectively. Contains
can for example be useful when checking error messages, as they are
often quite long and you may not want to check them in their
entirety.
For example, a full error message may be
[fileName:lineNumber] Expected int, got boolean in arg 0 to funcName (ERR-CODE 12345)
.
This information is nice to give the end user, but may be a bit
verbose to include everywhere in your test files. Therefore, you can
write [[CallExpr.errors~=Expected int, got boolean]]
,
which checks that the error message contains the string “Expected int,
got boolean” somewhere, and ignores the rest of the message.
Testing

By combining a workspace and text probes with assertions, you can write persistent unit tests for your AST. The tests can be evaluated inside the CodeProber UI by pressing the “Run Tests” button (only visible when a workspace is active). The tests can also be run in a command-line using something similar to the following command:
java -Dcpr.workspace=path/to/workspace -jar codeprober.jar --test yourtool.jar
The exit code ($?
) is set to 0 or 1 as expected on
success/failure. This allows you to run your assertions for example in
a CI/CD pipeline.
Diagnostics

The CodeProber text editor can display diagnostics in the form of squiggly lines and arrows. There are two ways to make diagnostics appear:
- Print a “diagnostic string” to stdout while a probe is being evaluated
- Return an object that implements the cpr_getDiagnostic API, which returns a “diagnostic string”.
A diagnostic string follows one of the following two patterns:
- SEVERITY@S;E;MSG
- LINE-TYPE@S;E;COL
The first pattern is for “squiggly lines”. SEVERITY is one of ERR, WARN, INFO or HINT.
S and E are line and column bits
packed into a single 32 bit integer in the format 0xLLLLLCCC. For
example line 5 column 7 is 20487
((5 << 12) + 7
).
MSG is any string.
The second pattern is for lines and arrows. TYPE is one of:
- PP (plain-plain) - just a line, no arrow
- PA (plain-arrow) - line in the starting point, arrow in the ending point
- AP (arrow-plain) - opposite of PA.
- AA (arrow-arrow) - an arrow on both sides.
COL is a string in the form
#RGBA
.
See also the Diagnostic class in the AST API.
Diagnostic Examples
// A warning (yellow) squiggly between line 5 column 7 and line 5 column 10
"WARN@20487;20490;Hover message here"
// A semitransparent red arrow pointing from line 3 column 2 to line 3 column 5
"LINE-PA@12291;12293;#F007"
// A double-sided green arrow pointing between line 1 column 2 and line 3 column 4
"LINE-AA@4098;8195;#0F0F"
Advanced Features
There are a number of features in CodeProber which are undocumented. They may simply be new, or considered too advanced/unstable for general use. If you are relying on something not listed in the table above, please reach out (for example by opening an issue), and we can work on documenting/stabilizing it.