11package es .upv .mist .slicing .graphs .sdg ;
22
3- import com .github .javaparser .ast .Node ;
43import com .github .javaparser .ast .body .CallableDeclaration ;
54import com .github .javaparser .ast .expr .Expression ;
65import com .github .javaparser .ast .expr .ObjectCreationExpr ;
76import com .github .javaparser .ast .expr .ThisExpr ;
7+ import com .github .javaparser .resolution .Resolvable ;
8+ import com .github .javaparser .resolution .declarations .ResolvedMethodLikeDeclaration ;
89import es .upv .mist .slicing .graphs .CallGraph ;
910import es .upv .mist .slicing .graphs .ExpressionObjectTreeFinder ;
1011import es .upv .mist .slicing .graphs .cfg .CFG ;
1112import es .upv .mist .slicing .nodes .GraphNode ;
12- import es .upv .mist .slicing .nodes .ObjectTree ;
1313import es .upv .mist .slicing .nodes .VariableAction ;
14- import es .upv .mist .slicing .nodes .VariableAction .Definition ;
1514import es .upv .mist .slicing .nodes .VariableAction .Movable ;
1615import es .upv .mist .slicing .nodes .VariableAction .Usage ;
1716import es .upv .mist .slicing .nodes .io .ActualIONode ;
2019
2120import java .util .Map ;
2221import java .util .Objects ;
22+ import java .util .Set ;
2323import java .util .function .Predicate ;
24+ import java .util .stream .Collectors ;
2425import java .util .stream .Stream ;
2526
2627/** An interprocedural usage finder, which adds the associated actions to formal and actual nodes in the CFGs. */
@@ -29,6 +30,32 @@ public InterproceduralUsageFinder(CallGraph callGraph, Map<CallableDeclaration<?
2930 super (callGraph , cfgMap );
3031 }
3132
33+ @ Override
34+ public void save () {
35+ super .save ();
36+ markTransferenceToRoot ();
37+ }
38+
39+ /** For every variable action -scope-in- or -arg-in- in the graph,
40+ * runs {@link ExpressionObjectTreeFinder#locateAndMarkTransferenceToRoot(Expression, VariableAction)}. */
41+ protected void markTransferenceToRoot () {
42+ for (CallGraph .Edge <?> edge : graph .edgeSet ()) {
43+ for (ActualIONode actualIn : locateActualInNode (edge )) {
44+ for (VariableAction va : edge .getGraphNode ().getVariableActions ()) {
45+ if (va instanceof Movable && ((Movable ) va ).getRealNode ().equals (actualIn )) {
46+ ExpressionObjectTreeFinder finder = new ExpressionObjectTreeFinder (edge .getGraphNode ());
47+ if (va .getName ().equals ("-scope-in-" )) {
48+ Expression scope = Objects .requireNonNullElseGet (actualIn .getArgument (), ThisExpr ::new );
49+ finder .locateAndMarkTransferenceToRoot (scope , va );
50+ } else if (va .getName ().equals ("-arg-in-" )) {
51+ finder .locateAndMarkTransferenceToRoot (actualIn .getArgument (), va );
52+ }
53+ }
54+ }
55+ }
56+ }
57+ }
58+
3259 @ Override
3360 protected void handleFormalAction (CallGraph .Vertex vertex , Usage use ) {
3461 CFG cfg = cfgMap .get (vertex .getDeclaration ());
@@ -43,42 +70,62 @@ protected void handleActualAction(CallGraph.Edge<?> edge, Usage use) {
4370 if (use .isParameter ()) {
4471 if (!use .isPrimitive ()) {
4572 assert use .hasObjectTree ();
46- ActualIONode actualIn = locateActualInNode (edge , use .getName ());
47- Definition def = new Definition (VariableAction .DeclarationType .SYNTHETIC , "-arg-in-" , graphNode , (ObjectTree ) use .getObjectTree ().clone ());
48- Movable movDef = new Movable (def , actualIn );
49- graphNode .addVariableActionAfterLastMatchingRealNode (movDef , actualIn );
50- ExpressionObjectTreeFinder finder = new ExpressionObjectTreeFinder (graphNode );
51- finder .locateAndMarkTransferenceToRoot (actualIn .getArgument (), def );
73+ int index = ASTUtils .getMatchingParameterIndex (graph .getEdgeTarget (edge ).getDeclaration (), use .getName ());
74+ VariableAction argIn = locateArgIn (graphNode , edge .getCall (), index );
75+ argIn .getObjectTree ().addAll (use .getObjectTree ());
5276 }
5377 } else if (use .isField ()) {
5478 if (use .isStatic ()) {
5579 // Known limitation: static fields
5680 } else {
5781 // An object creation expression input an existing object via actual-in because it creates it.
5882 assert !(edge .getCall () instanceof ObjectCreationExpr );
59- ActualIONode actualIn = locateActualInNode (edge , use .getName ());
60- Definition def = new Definition (VariableAction .DeclarationType .SYNTHETIC , "-scope-in-" , graphNode , (ObjectTree ) use .getObjectTree ().clone ());
61- Movable movDef = new Movable (def , actualIn );
62- Expression scope = Objects .requireNonNullElseGet (actualIn .getArgument (), ThisExpr ::new );
63- graphNode .addVariableActionAfterLastMatchingRealNode (movDef , actualIn );
64- ExpressionObjectTreeFinder finder = new ExpressionObjectTreeFinder (graphNode );
65- finder .locateAndMarkTransferenceToRoot (scope , def );
83+ VariableAction scopeIn = locateScopeIn (graphNode , edge .getCall ());
84+ scopeIn .getObjectTree ().addAll (use .getObjectTree ());
6685 }
6786 } else {
6887 throw new IllegalStateException ("Definition must be either from a parameter or a field!" );
6988 }
7089 }
7190
72- /** Locates the actual- in node associated with the given variable name and call edge . */
73- protected ActualIONode locateActualInNode (CallGraph .Edge <?> edge , String name ) {
91+ /** Find all actual in nodes in the given call. */
92+ protected Set < ActualIONode > locateActualInNode (CallGraph .Edge <?> edge ) {
7493 return edge .getGraphNode ().getSyntheticNodesInMovables ().stream ()
7594 .filter (ActualIONode .class ::isInstance )
7695 .map (ActualIONode .class ::cast )
7796 .filter (ActualIONode ::isInput )
78- .filter (actual -> actual .getVariableName ().equals (name ))
79- .filter (actual -> ASTUtils .equalsWithRange (actual .getAstNode (), (Node ) edge .getCall ()))
80- .findFirst ()
81- .orElseThrow (() -> new IllegalStateException ("can't locate actual-in node" ));
97+ .filter (actual -> ASTUtils .equalsWithRange (actual .getAstNode (), edge .getCall ()))
98+ .collect (Collectors .toSet ());
99+ }
100+
101+ /** Find the -arg-in- variable action that corresponds to the given node, call and index. */
102+ protected VariableAction locateArgIn (GraphNode <?> graphNode , Resolvable <? extends ResolvedMethodLikeDeclaration > call , int index ) {
103+ return locateActionIn (graphNode , call , index , "-arg-in-" );
104+ }
105+
106+ /** Find the -scope-in- variable action that corresponds to the given node and call. */
107+ protected VariableAction locateScopeIn (GraphNode <?> graphNode , Resolvable <? extends ResolvedMethodLikeDeclaration > call ) {
108+ return locateActionIn (graphNode , call , 0 , "-scope-in-" );
109+ }
110+
111+ /** Find the nth variable action from the given node and call that matches the given name. 0 represents the first occurrence. */
112+ protected VariableAction locateActionIn (GraphNode <?> graphNode , Resolvable <? extends ResolvedMethodLikeDeclaration > call , int index , String actionName ) {
113+ boolean inCall = false ;
114+ for (VariableAction va : graphNode .getVariableActions ()) {
115+ if (va instanceof VariableAction .CallMarker && ASTUtils .equalsWithRange (((VariableAction .CallMarker ) va ).getCall (), call )) {
116+ if (((VariableAction .CallMarker ) va ).isEnter ())
117+ inCall = true ;
118+ else
119+ break ; // The call has ended, can't find the action now
120+ }
121+ if (inCall && va .isDefinition () && va .getName ().equals (actionName )) {
122+ if (index == 0 )
123+ return va ;
124+ else
125+ index --;
126+ }
127+ }
128+ throw new IllegalStateException ("Could not locate " + actionName + " for call " + call + " in node " + graphNode );
82129 }
83130
84131 @ Override
0 commit comments