Indeed, some methods are there, but others are not:
rascal>p = createOFG(|project://eLib|);
...
rascal>cv = |java+method:///java/util/Map/containsValue(java.lang.Object)|;
loc: |java+method:///java/util/Map/containsValue(java.lang.Object)|
rascal>/c:call(_,_,_,cv,_) := p ? c : "bla"
Stm: call(
|id:///|,
|id:///|,
|java+field:///Library/users|,
|java+method:///java/util/Map/containsValue(java.lang.Object)|,
[|java+parameter:///Library/addUser(User)/scope(user)/scope(0)/user|])
rascal>cv = |java+method:///java/util/Map/put(java.lang.Object,java.lang.Object)|;
loc: |java+method:///java/util/Map/put(java.lang.Object,java.lang.Object)|
rascal>/c:call(_,_,_,cv,_) := p ? c : "bla"
value: "bla"
So, these queries shows that the flow program indeed contains a call to containsValue but not to put
.
While reading the code of lang::ofg::ast::Java2OFG
it seems something special is going on with some of the methods in container classes. Instead of calls to put ending up as a call
in the flow language, these method calls are transformed into assignments! This means that Java2OFG models flow into a collection using a special abstract symbolic variable, i.e. map's put
method is modeled as an variable assignment and get
as a variable lookup.
That's a correct model, and useful otherwise data would flow into the container API, for which we have no model of the internals, and would never come out again.
The algorithm missed edges from the key of a map to the receiver though, and also skipped flow from primitive types. A new version is published here: https://gist.github.com/jurgenvinju/60645058b6d0b0ccce0fc6f856da6ea6