FGyama, or Flow Graph yama is a static source code analyzer
that extracts an interprocedural dataflow graph from
Java source code. It's designed to be scalable so that
it can be applied to a large code base.
public class Hello {
public static void main(String[] args) {
String name = args[0];
System.out.println("Hello, "+name);
}
}

<?xml version="1.0" encoding="UTF-8"?><fgyama>
<class extends="Ljava/lang/Object;" name="LHello;" path="/home/euske/work/r/fgyama/tests/Hello.java">
<method id="LHello;.<clinit>()V" name="<clinit>" style="initializer">
<ast end="141" start="0" type="55"/>
<scope name="LHello;.<clinit>"/>
</method>
<method id="LHello;.main([Ljava/lang/String;)V" name="main" style="static">
<ast end="139" start="25" type="31"/>
<scope name="LHello;.:main:25:139">
<node id="M2_main_N1" kind="input" ref="#arg0" type="[Ljava/lang/String;">
<ast end="62" start="49" type="44"/>
</node>
<node id="M2_main_N2" kind="assign_var" ref="$LHello;.:main:25:139/$args" type="[Ljava/lang/String;">
<ast end="62" start="49" type="44"/>
<accept src="M2_main_N1"/>
</node>
<node id="M2_main_N3" kind="input" ref="#this" type="LHello;"/>
<node id="M2_main_N4" kind="input" ref="%Ljava/lang/String;" type="Ljava/lang/String;"/>
<node id="M2_main_N5" kind="input" ref="@Ljava/lang/System;/.out" type="Ljava/io/PrintStream;"/>
<scope name="LHello;.:main:25:139.:B:64:139">
<node id="M2_main_N6" kind="ref_var" ref="$LHello;.:main:25:139/$args" type="[Ljava/lang/String;">
<ast end="85" start="81" type="42"/>
<accept src="M2_main_N2"/>
</node>
<node data="0" id="M2_main_N7" kind="value" type="I">
<ast end="87" start="86" type="34"/>
</node>
<node id="M2_main_N8" kind="ref_array" ref="%Ljava/lang/String;" type="Ljava/lang/String;">
<ast end="88" start="81" type="2"/>
<accept label="array" src="M2_main_N6"/>
<accept label="index" src="M2_main_N7"/>
<accept src="M2_main_N4"/>
</node>
<node id="M2_main_N9" kind="assign_var" ref="$LHello;.:main:25:139.:B:64:139/$name" type="Ljava/lang/String;">
<ast end="88" start="74" type="59"/>
<accept src="M2_main_N8"/>
</node>
<node id="M2_main_N10" kind="ref_field" ref="@Ljava/lang/System;/.out" type="Ljava/io/PrintStream;">
<ast end="108" start="98" type="40"/>
<accept src="M2_main_N5"/>
</node>
<node data="Hello, " id="M2_main_N11" kind="value" type="Ljava/lang/String;">
<ast end="126" start="117" type="45"/>
</node>
<node id="M2_main_N12" kind="ref_var" ref="$LHello;.:main:25:139.:B:64:139/$name" type="Ljava/lang/String;">
<ast end="131" start="127" type="42"/>
<accept src="M2_main_N9"/>
</node>
<node data="+" id="M2_main_N13" kind="op_infix" type="Ljava/lang/String;">
<ast end="131" start="117" type="27"/>
<accept label="L" src="M2_main_N11"/>
<accept label="R" src="M2_main_N12"/>
</node>
<node data="Ljava/io/PrintStream;.println(Ljava/lang/String;)V" id="M2_main_N14" kind="call" type="V">
<ast end="132" start="98" type="32"/>
<accept label="#this" src="M2_main_N10"/>
<accept label="#arg0" src="M2_main_N13"/>
</node>
<node id="M2_main_N15" kind="receive" type="V">
<ast end="132" start="98" type="32"/>
<accept src="M2_main_N14"/>
</node>
</scope>
</scope>
</method>
</class>
</fgyama>
| Kind |
Data |
Input(s) |
| value |
Actual value |
|
| valueset |
Value count |
value0, value1, ... |
| op_assign |
Assignment operator |
L, R |
| op_prefix |
Prefix operator |
(default) |
| op_infix |
Infix operator |
L, R |
| op_postfix |
Postfix operator |
(default) |
| op_typecast |
Casting type |
(default) |
| op_typecheck |
Checking type |
(default) |
| op_iter |
|
(default) |
| ref_var |
|
(default) |
| ref_array |
|
(default), array, index |
| ref_field |
|
(default), obj |
| assign_var |
|
(default) |
| assign_array |
|
(default), array, index |
| assign_field |
|
(default), obj |
| Kind |
Data |
Input(s) |
| call |
Method IDs |
@type, #arg0, ..., #bypass, .field, %type |
| new |
Method ID |
@type, #arg0, ..., #bypass, .field, %type |
| input |
|
|
| output |
|
(default) |
| return |
|
(default) |
| receive |
|
(default), Fields |
| throw |
|
!type |
| catch |
|
exc0, ... |
| catchjoin |
|
!type |
| Kind |
Data |
Input(s) |
| join |
|
cond, true, false |
| begin |
Loop ID |
init, cont |
| end |
Loop ID |
(default), cond, _repeat |
| repeat |
Loop ID |
(default), _end |
| case |
Label count |
(default), match0, ... |
$ mvn exec:java -Dexec.args="./tests/Hello.java" > Hello.graph
or
$ ./tools/java2df.sh ./tests/Hello.java > Hello.graph
then
$ python tools/graph2gv.py Hello.graph | dot -Tsvg > Hello.svg
XmlExporter exporter = new XmlExporter(System.out);
Java2DF converter = new Java2DF();
converter.loadDefaults(); // Load the standard classes.
converter.loadJarFile("path/to/my.jar"); // Add a jar.
converter.addSourceFile("path/to/Hello.java"); // Add a source code.
// Perform analysis for every user-defined class.
for (DFSourceKlass klass : converter.getSourceKlasses()) {
converter.analyzeKlass(exporter, klass);
}
exporter.close();
-v: increases verbosity.
-i filelist: takes a filename list.
-o output: specifies the output file.
-C classpath: add a jar file / directory to the classpath.
-S: strict mode. (stops at a first error)
-F: pretty printing XML.
(c-add-style "me"
'("Java"
(c-offsets-alist . (
(arglist-cont . c-lineup-argcont)
(arglist-intro . +)
))
))