public StackSymbol(OperationEdge <int> callSite, ResolvedInvocationStatement <Node> invocation) { CallSite = callSite; Owner = null; if (invocation == null) { return; } var owner = invocation.TargetEntity; if (invocation.IsConstructor) { var index = new ParameterIndex(-1); Owner = invocation.ReturnedValues[index] as ResolvedLocalVariable; } else if (owner is ResolvedLocalVariable localVariable) { Owner = localVariable; } else if (owner is SecondaryEntity justSecondary) { Owner = Utils.FindClosestLocalOwner(justSecondary); } }
public void AddLocalVariable(ResolvedLocalVariable variable) { myVariables.Add(variable.LocalId, variable); }
protected override bool Step( GraphStructuredProgram <TNode> targetProgram, ResolvedMethod <TNode> owningMethod, TNode source, Statement statement, TNode target, Func <TNode> nodeCreator) { SecondaryEntity CreateNewVariable() { var nextId = owningMethod.Variables.Keys.Max() + 1; var variable = new ResolvedLocalVariable(nextId); owningMethod.AddLocalVariable(variable); return(variable); } if (statement is InvocationStatement invocation) { var passedParameters = invocation.PassedParameters.GroupBy( pair => ReferenceResolver.Resolve(targetProgram, owningMethod, pair.Value), pair => pair.Key) .ToDictionary( pair => { Trace.Assert(pair.Key != null); return(pair.Key); }, pair => { var targets = pair.ToList(); return(targets.Count == 1 ? targets[0] : new ParameterIndicesSet( targets.Select(targetIndex => targetIndex.Value))); }); var returnedValues = invocation.ReturnedValues.ToDictionary( pair => { Trace.Assert(pair.Key != null); return(pair.Key); }, pair => (SecondaryEntity)ReferenceResolver.Resolve(targetProgram, owningMethod, pair.Value)); var normalizedPassedParameters = AddIntermediateEdgesIfNeeded( targetProgram, passedParameters, source, nodeCreator, CreateNewVariable, out var newSource); ResolvedInvocationStatement <TNode> resolvedInvocationStatement = null; if (invocation.InvocationTarget is ClassMethodTarget classMethodTarget) { var targetMethodId = targetProgram.GetOrCreateMethodId(classMethodTarget.TargetMethod); var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, classMethodTarget.TargetClass); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetMethodId); } if (invocation.InvocationTarget is LocalVariableTarget localVariableTarget) { var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, new LocalVariableReference(localVariableTarget.Index)); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetProgram.GetOrCreateMethodId("Invoke")); } if (invocation.InvocationTarget is ClassFieldTarget classFieldTarget) { var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, new ClassFieldReference(classFieldTarget.TargetClass, classFieldTarget.TargetField)); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetProgram.GetOrCreateMethodId("Invoke")); } if (invocation.InvocationTarget is ClassPropertyTarget classPropertyTarget) { var resolvedOwner = ReferenceResolver.Resolve( targetProgram, owningMethod, new ClassPropertyReference(classPropertyTarget.TargetClass, classPropertyTarget.TargetProperty)); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetProgram.GetOrCreateMethodId("Invoke")); } if (invocation.InvocationTarget is LocalFunctionTarget localFunctionTarget) { var resolvedOwner = owningMethod; var targetMethodId = targetProgram.GetOrCreateMethodId(localFunctionTarget.TargetFunction.Value); resolvedInvocationStatement = new ResolvedInvocationStatement <TNode>( invocation, normalizedPassedParameters, returnedValues, resolvedOwner, targetMethodId); } Trace.Assert(resolvedInvocationStatement != null); var operation = new Operation <TNode>(resolvedInvocationStatement, target); targetProgram.AddOperation(newSource, operation); return(false); } return(true); }