https://euske.github.io/
void printResult(Stream out, String result) { out.writeLine("result:"+result); } void printStat(Stream out, int stat) { out.writeLine("stat:"+stat); } void printInfo(Stream strm, String info) { strm.writeLine("info:"+info); // XXX "strm" should be "out". }
Note: "out" might not necessarily be the best name
for an output stream, but it is consistent throughout the program.
We also tried to:
view" = window (GUI application)
      view" = table (SQL engine)
    message
      msg
    = open(...); write( , ...);
out
strm = open(...); write(strm, ...);
out
  out
  strm (Hey!)
  out
Take a look at the variable line:
private BufferedReader fp;
public String get() {
    String line = fp.readLine();
    int i = line.indexOf(' ');
    return line.substring(0, i);
}
Here is its data flow visualization:
The red lines above = a use flow of line:
fp.readLine() → line → #this:indexOf() → #arg1:substring()
This path shows what is assigned to the variable line and
how it is used.
private BufferedReader fp;
public String get() {
    String line = fp.readLine();
    int i = line.indexOf(' ');
    return line.substring(0, i);
}
public void show() {
    String name = get();
    System.out.println(name+"!!");
}
Note that line in function get()
is now name in function show().
Here's the data flow graph:
The final use flow of line:
fp.readLine() → line → #this:indexOf() → #arg1:substring() → assign:name → L:+ → #arg0:println()
line in this program.
Trained a Bayesian probabilistic model that predicts a variable name from a given use flow:
The following use flow predicts ??? = line:
fp.readLine() → ??? → #this:indexOf() → #arg1:substring() → assign:name → L:+ → #arg0:println()
If the variable name is other than line,
it is inconsistent with this usage.
Algorithm:
Evaluated our method with the following projects: (#edges < #useflow)
| Project | kLoC | #vars | #nodes | #edges | 
|---|---|---|---|---|
| ant (build tool) | 112k | 23,971 | 350k | 5,211k | 
| antlr4 (parser generator) | 31k | 7,131 | 74k | 1,103k | 
| bcel (byte code analyzer) | 31k | 6,583 | 80k | 1,190k | 
| compress (data compression) | 24k | 5,896 | 69k | 929k | 
| jedit (text editor) | 115k | 21,977 | 294k | 6,106k | 
| jhotdraw (diagram renderer) | 80k | 17,367 | 235k | 2,351k | 
| junit (unit testing) | 9k | 2,384 | 21k | 280k | 
| lucene (document indexing) | 109k | 30,341 | 414k | 7,146k | 
| tomcat (web server) | 238k | 49,275 | 649k | 11,799k | 
| weka (machine learning) | 324k | 59,274 | 943k | 13,224k | 
| xerces (XML parser) | 114k | 21,852 | 314k | 7,017k | 
| xz (data compression) | 7k | 1,825 | 23k | 299k | 
Test subjects: authors (3) + grad students (6) = 9 people.
Present a pair of variables (whose names hidden) to human subjects:
     ...
  100:     */
  101:    protected void addArg(CommandlineJava aa, String argument, String value) {
  102:        if (value != null) {
  103:            aa.createArgument().setValue(argument);
  104:            aa.createArgument().setValue(value);
  105:        }
     ...
     ...
   87:     */
   88:    protected void addArg(CommandlineJava bb, String argument) {
   89:        if (argument != null && !argument.isEmpty()) {
   90:           bb.createArgument().setValue(argument);
   91:        }
     ...
Tested for 12 projects × 5 variable pairs × 9 subjects = 540 questionnaires.
Defects: Only tested with the high similarity pairs. Therefore the test was not completely blind. :(
Present a snippet to human subjects:
xxx → 
     ...
   82:     */
   83:    public BuildException(String xxx, Throwable cause, Location location) {
   84:        this(xxx, cause);
   85:        this.location = location;
     ...
     ...
   67:     */
   68:    public BuildException(String message, Throwable cause) {
   69:        super(message, cause);
   70:    }
     ...
Their choices are (in random order):
Tested for 12 projects × 10 variables × 9 subjects = 1,080 questionnaires.
Based on our results, we manually submitted 12 patches to the open source projects.
Tested for 12 projects × 5 questions × 9 subjects = 540 questionnaires.
The results did not know that our system produced good explanation for its suggestions. :(
Some of the system suggestions were good:
org/apache/bcel/Const.java:
-  public static short getNoOfOperands(final int index) {
-      return NO_OF_OPERANDS[index];
+  public static short getNoOfOperands(final int opcode) {
+      return NO_OF_OPERANDS[opcode];
gjt/sp/jedit/bsh/classpath/BshClassPath.java:
-	void errorWhileMapping( String s ) {
+	void errorWhileMapping( String msg ) {
...
org/apache/jasper/compiler/Generator.java - String pkgName = className.substring(0, lastIndex); - genPreamblePackage(pkgName); + String packageName = className.substring(0, lastIndex); + genPreamblePackage(packageName);
org/apache/xerces/impl/xpath/regex/RegexParser.java
-        ReferencePosition(int n, int pos) {
+        ReferencePosition(int n, int offset) {
src/org/tukaani/xz/lz/Hash234.java
-    void normalize(int normalizeOffset) {
-        LZEncoder.normalize(hash2Table, HASH_2_SIZE, normalizeOffset);
+    void normalize(int normalizationOffset) {
+        LZEncoder.normalize(hash2Table, HASH_2_SIZE, normalizationOffset);
...