Example #1
0
        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);
            }
        }
Example #2
0
        private void ProcessInvocation(
            State state,
            ResolvedInvocationStatement <Node> invocation,
            OperationEdge <Node> currentTransition)
        {
            var targets          = CollectPossibleTargets(invocation.TargetEntity, invocation.TargetMethodId);
            var passedParameters = invocation.PassedParameters.ToDictionary(
                pair => Utils.FindClosestLocalOwner(pair.Key), pair => pair.Value);

            if (state is ResolvedLocalVariable localState)
            {
                if (!passedParameters.ContainsKey(localState))
                {
                    return;
                }

                var parameterIndex = passedParameters[localState].Value;

                foreach (var target in targets)
                {
                    var isSink   = false;
                    var isFilter = false;
                    if (target is ResolvedMethod <Node> method)
                    {
                        isSink   = method.HasAttribute(mySinkAttributeId);
                        isFilter = method.HasAttribute(myFilterAttributeId);
                    }

                    if (isSink)
                    {
                        Accept(new FinalState());
                    }
                    else
                    {
                        if (!isFilter)
                        {
                            var nextState = target.Variables[parameterIndex];
                            var frame     = new StackSymbol(currentTransition, invocation);
                            Push(nextState, frame, target.EntryPoint);
                        }
                    }
                }
            }
            else
            {
                foreach (var target in targets)
                {
                    var frame = new StackSymbol(currentTransition, invocation);
                    Push(state, frame, target.EntryPoint);
                }
            }
        }
        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);
        }