Search code examples
rascal

New assignment to collection-type class field absent from flow program with Rascal, unlike to local variables


Consider the following Java code:

import java.util.LinkedList;
import java.util.List;

class Library {
    List<String> loans = new LinkedList<>();

    public List<String> searchUser(String name) {
        List<String> usersFound = new LinkedList<>();
        return loans;
    }
}

and the following Rascal module:

module Mwe

import lang::java::flow::JavaToObjectFlow;
import lang::java::jdt::m3::AST;
import IO;

void m() {
    ast = createAstFromEclipseFile(|project://test/src/test.java|, true);
    fp = createOFG({ast});
    print(fp);
}

The resulting flow program will be:

flowProgram({
    attribute(|java+field:///Library/loans|),
    method(|java+method:///Library/searchUser(java.lang.String)|,[|java+parameter:///Library/searchUser(java.lang.String)/scope(name)/scope(0)/name|]),
    constructor(|java+constructor:///Library/Library()|,[])
},{
    assign(|java+method:///Library/searchUser(java.lang.String)/return|,|id:///|,|java+field:///Library/loans|),
    newAssign(|java+variable:///Library/searchUser(java.lang.String)/usersFound|,|java+class:///java/util/LinkedList|,|java+constructor:///java/util/LinkedList/LinkedList()|,[])
})

So, there is a new assignment of LinkedList to usersFound, but nothing comparable for loans. Why would that happen? Is that the intended behaviour?


Solution

  • Just checked the implementation, the field initializers are not included in the getStatements function (see lang::java::flow::JavaToObjectFlow on line 169). Similarly the static initializers of a class are ignored.

    The best way forward would be to either report it as a bug, or fix it and turn it into a pull-request. (pull request is the quickest way to getting it fixed on unstable)

    As a possible, yet work intensive workaround you rewrite the AST to put the field initializers inside all existing constructors (or add a constructor if there is none).