protected override ISet <VariableAlias> TransferInterprocedural(FlowNode node, ISet <VariableAlias> data) { // Important to remember: the node passed here is always a predecessor (First) of the node that receives the transferred information (Second). ISet <VariableAlias> transferred = null; if (node is FlowTransfer transfer) { // TODO extract this into separate instructions by the monotone framework? if (transfer.TransfersTo) { // TODO extremal nodes & values per method transferred = data.Where(alias => InvocationExpression.IsParameterIdentifierOf(transfer.TargetMethod, alias.Source)).ToImmutableHashSet(); } else { transferred = data.Where(alias => InvocationExpression.IsResultIdentifierOf(transfer.SourceMethod, alias.Source)).ToImmutableHashSet(); } } if (transferred == null) { transferred = _TransferRegular(node, data, true); } return(transferred); }
protected override ISet <VariableDescriptor> TransferInterprocedural(FlowNode node, ISet <VariableDescriptor> data) { ISet <VariableDescriptor> transferred = null; if (node is FlowTransfer transfer) { // TODO extract this into separate instructions by the monotone framework? if (transfer.TransfersTo) { transferred = data.Where(descriptor => InvocationExpression.IsParameterIdentifierOf(transfer.TargetMethod, descriptor.Name)).ToImmutableHashSet(); } else { transferred = data.Where(descriptor => InvocationExpression.IsResultIdentifierOf(transfer.SourceMethod, descriptor.Name)).ToImmutableHashSet(); } } if (transferred == null) { transferred = _TransferRegular(node, data, true); } return(transferred); }