@@ -22,7 +22,7 @@ import { Identifier } from '../../../dataflow/environments/identifier';
2222import { Dataflow } from '../../../dataflow/graph/df-helper' ;
2323import { ArrayQueue } from '../../../util/collections/queue' ;
2424import { baseRExportOwner } from '../../../util/r-base-packages' ;
25- import { isNotUndefined } from '../../../util/assert' ;
25+ import { guard , isNotUndefined , isUndefined } from '../../../util/assert' ;
2626import type { NodeId } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id' ;
2727import { recoverContent , recoverName } from '../../../r-bridge/lang-4.x/ast/model/processing/node-id' ;
2828import type { DataflowGraph } from '../../../dataflow/graph/graph' ;
@@ -38,12 +38,12 @@ import { SliceDirection } from '../../../util/slice-direction';
3838import { RFunctionCall } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call' ;
3939import { MatchArgs } from '../../../dataflow/graph/match-args' ;
4040import { RFunctionDefinition } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-definition' ;
41- import type { RSymbol } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-symbol' ;
42- import type { RArgument } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-argument' ;
4341import { Resolve } from '../../../dataflow/environments/resolve-helper' ;
4442import { VariableResolve } from '../../../config' ;
4543import type { KnownParser } from '../../../r-bridge/parser' ;
4644import { unwrapRValueToString , unliftRValue } from '../../../util/r-value' ;
45+ import { RBinaryOp } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-binary-op' ;
46+ import { RUnaryOp } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-unary-op' ;
4747
4848function makeReport ( collector : TwoLayerCollector < string , string , CallContextQuerySubKindResult > ) : CallContextQueryKindResult {
4949 const result : CallContextQueryKindResult = { } ;
@@ -185,7 +185,7 @@ function retrieveAllCallAliases(nodeId: NodeId, graph: DataflowGraph): Map<strin
185185 }
186186 const [ info , outgoing ] = vertex ;
187187
188- if ( FunctionCallVertex . is ( info ) ) {
188+ if ( ! FunctionCallVertex . is ( info ) ) {
189189 const wantedTypes = EdgeType . Reads | EdgeType . DefinedBy | EdgeType . DefinedByOnCall ;
190190 const x = outgoing . entries ( )
191191 . filter ( ( [ , e ] ) => DfEdge . includesType ( e , wantedTypes ) )
@@ -278,18 +278,18 @@ function isParameterDefaultValue(nodeId: NodeId, ast: NormalizedAst): boolean {
278278 return false ;
279279}
280280
281- function resolveValueOfArgument ( args : { name : string | undefined , id : NodeId } [ ] , fCall : DataflowGraphVertexFunctionCall , value : string , graph : DataflowGraph < DataflowGraphVertexInfo , DfEdge > , analyzer : ReadonlyFlowrAnalysisProvider < KnownParser > ) : { dep : true , id : NodeId } | { dep : false } {
281+ function resolveValueOfArgument ( args : { name : string | undefined , id : NodeId } [ ] , fCall : DataflowGraphVertexFunctionCall , value : string , graph : DataflowGraph < DataflowGraphVertexInfo , DfEdge > , analyzer : ReadonlyFlowrAnalysisProvider < KnownParser > ) : { dep : true , call : undefined } | { dep : false } {
282282 for ( const { id } of args ) {
283283 const resolved = Resolve . toValue ( id , { environment : fCall . environment , graph, full : true , ctx : analyzer . inspectContext ( ) , resolve : VariableResolve . Alias } ) ;
284284 const result = unwrapRValueToString ( unliftRValue ( resolved ) ) ;
285285 if ( result === value ) {
286- return { dep : true , id : id } ;
286+ return { dep : true , call : undefined } ;
287287 }
288288 }
289289 return { dep : false } ;
290290}
291291
292- async function sliceAfterDep ( args : { name : string | undefined , id : NodeId } [ ] , dep : PromotedCallTest , graph : DataflowGraph < DataflowGraphVertexInfo , DfEdge > , analyzer : ReadonlyFlowrAnalysisProvider < KnownParser > , slicedParam : Set < NodeId > ) : Promise < { dep : true , id : NodeId } | { dep : false } > {
292+ async function sliceAfterDep ( args : { name : string | undefined , id : NodeId } [ ] , dep : PromotedCallTest , graph : DataflowGraph < DataflowGraphVertexInfo , DfEdge > , analyzer : ReadonlyFlowrAnalysisProvider < KnownParser > , slicedParam : Set < NodeId > ) : Promise < { dep : true , call : Required < DataflowGraphVertexFunctionCall > } | { dep : false } > {
293293 for ( const { name, id } of args ) {
294294 if ( isNotUndefined ( name ) ) {
295295 if ( slicedParam . has ( name ) ) {
@@ -306,32 +306,35 @@ async function sliceAfterDep(args: { name: string | undefined, id: NodeId }[], d
306306 for ( const results of Object . values ( argSlice [ 'static-slice' ] . results ) ) {
307307 for ( const resultId of results . slice . result ) {
308308 const name = recoverName ( resultId , graph . idMap ) ;
309- if ( name && dep ( name ) && FunctionCallVertex . is ( graph . getVertex ( resultId ) ) ) {
310- return { dep : true , id : id } ;
309+ const vertex = graph . getVertex ( resultId ) ;
310+ if ( name && dep ( name ) && FunctionCallVertex . is ( vertex ) ) {
311+ return { dep : true , call : vertex } ;
311312 }
312313 }
313314 }
314315 }
315316 return { dep : false } ;
316317}
317318
318- async function isDependentOn ( parameter : string , dep : PromotedCallTest | undefined , value : string | undefined , fCall : Required < DataflowGraphVertexFunctionCall > , graph : DataflowGraph , analyzer : ReadonlyFlowrAnalysisProvider ) : Promise < { dep : true , id : NodeId } | { dep : false } > {
319+ async function isDependentOn ( parameter : string , dep : PromotedCallTest | undefined , value : string | undefined , fCall : Required < DataflowGraphVertexFunctionCall > , graph : DataflowGraph , analyzer : ReadonlyFlowrAnalysisProvider ) : Promise < { dep : true , call : Required < DataflowGraphVertexFunctionCall > | undefined } | { dep : false } > {
319320 const astCall = graph . idMap ?. get ( fCall ?. id ) as RFunctionCall < ParentInformation > | undefined ;
320- if ( ! RFunctionCall . is ( astCall ) ) {
321+ if ( ! RFunctionCall . is ( astCall ) && ! RBinaryOp . is ( astCall ) && ! RUnaryOp . is ( astCall ) ) {
321322 return { dep : false } ;
322323 }
323324 const defs = MatchArgs . toDefinition ( astCall , graph , analyzer . inspectContext ( ) ) ;
324325 // TODO: match against signaue (so that we can for example slice for the x of a print)
325- const slicedParam = new Set < NodeId > ( ) ;
326+ const slicedParam = new Set < string > ( ) ;
326327 const isParam = parameter === '*' ? ( ) => true : ( p : string | undefined ) => p === parameter ;
328+ //todo: den fall nachher raus?
327329 if ( defs === undefined ) {
328330 if ( isNotUndefined ( dep ) ) {
329331 //e.g. f(getOption(x)), searching for dep 'getOption'
330332 for ( const arg of fCall . args ) {
331333 if ( ! FunctionArgument . isEmpty ( arg ) ) {
332- const rArg = graph . idMap ?. get ( arg . nodeId ) as RArgument ;
333- if ( rArg . value ?. type === 'RFunctionCall' && isNotUndefined ( ( rArg . value ?. functionName as RSymbol ) . content ) && dep ( Identifier . getName ( ( rArg . value ?. functionName as RSymbol ) . content ) ) ) {
334- return { dep : true , id : arg . nodeId } ;
334+ const name = recoverName ( arg . nodeId , graph . idMap ) ;
335+ const vertex = graph . getVertex ( arg . nodeId ) ;
336+ if ( name && dep ( name ) && FunctionCallVertex . is ( vertex ) ) {
337+ return { dep : true , call : vertex } ;
335338 }
336339 }
337340 }
@@ -362,8 +365,12 @@ async function isDependentOn(parameter: string, dep: PromotedCallTest | undefine
362365 if ( isNotUndefined ( dep ) ) {
363366 //e.g. f(getOption(x)), searching for dep 'getOption'
364367 for ( const [ _ , arg ] of possibleArgs ) {
365- if ( arg . value ?. type === 'RFunctionCall' && isNotUndefined ( ( arg . value ?. functionName as RSymbol ) . content ) && dep ( Identifier . getName ( ( arg . value ?. functionName as RSymbol ) . content ) ) ) {
366- return { dep : true , id : arg . info . id } ;
368+ if ( isNotUndefined ( arg . value ?. info . id ) ) {
369+ const name = recoverName ( arg . value ?. info . id , graph . idMap ) ;
370+ const vertex = graph . getVertex ( arg . value . info . id ) ;
371+ if ( name && dep ( name ) && FunctionCallVertex . is ( vertex ) ) {
372+ return { dep : true , call : vertex } ;
373+ }
367374 }
368375 }
369376 }
@@ -391,14 +398,14 @@ async function isDependentOn(parameter: string, dep: PromotedCallTest | undefine
391398 if ( isNotUndefined ( defId ) ) {
392399 const def = graph . idMap ?. get ( defId ) ;
393400 if ( RFunctionDefinition . is ( def ) ) {
394- const params = def . parameters . filter ( param => {
395- if ( isParam ( param . name . lexeme ) && ! slicedParam . has ( param . name . lexeme ) && isNotUndefined ( param . defaultValue ?. info . id ) ) {
401+ const params = def . parameters . map ( param => {
402+ return { name : recoverName ( param . info . id , graph . idMap ) , id : param . defaultValue ?. info . id } ;
403+ } ) . filter ( ( { name, id } ) => {
404+ if ( isParam ( name ) && isNotUndefined ( name ) && ! slicedParam . has ( name ) && isNotUndefined ( id ) ) {
396405 return true ;
397406 }
398407 return false ;
399- } ) . map ( param => {
400- return { name : param . name . lexeme , id : param . defaultValue ?. info . id as NodeId } ;
401- } ) ;
408+ } ) as { name : string | undefined ; id : NodeId } [ ] ;
402409 if ( isNotUndefined ( dep ) ) {
403410 const sliced = await sliceAfterDep ( params , dep , graph , analyzer , slicedParam ) ;
404411 if ( sliced . dep ) {
@@ -526,7 +533,8 @@ export async function executeCallContextQueries({ analyzer }: BasicQueryData, qu
526533 if ( query . reliesOnCriteria ) {
527534 let isDependent = true ;
528535 let fCall = info ;
529- for ( const entry of query . reliesOnCriteria ) {
536+ for ( let i = 0 ; i < query . reliesOnCriteria . length ; i ++ ) {
537+ const entry = query . reliesOnCriteria [ i ] ;
530538 const name = entry . name ;
531539 const calls = Object . hasOwn ( entry , 'calls' ) ? ( entry as ParameterConstraintWithCall ) . calls : undefined ;
532540 const value = Object . hasOwn ( entry , 'value' ) ? ( entry as ParameterConstraintWithValue ) . value : undefined ;
@@ -535,9 +543,15 @@ export async function executeCallContextQueries({ analyzer }: BasicQueryData, qu
535543 isDependent = false ;
536544 break ;
537545 } else {
538- const vertex = dataflowGraph . getVertex ( res . id ) ;
539- if ( FunctionCallVertex . is ( vertex ) ) {
540- fCall = vertex ;
546+ //case: we try to further resolve a value
547+ if ( isUndefined ( res . call ) ) {
548+ if ( i !== query . reliesOnCriteria . length - 1 ) {
549+ guard ( true , 'A value cannot be resolved further, wrong criteria' ) ;
550+ isDependent = false ;
551+ }
552+ break ;
553+ } else {
554+ fCall = res . call ;
541555 }
542556 }
543557 }
0 commit comments