Ejemplo n.º 1
0
 protected override bool Step(
     GraphStructuredProgram <TNode> targetProgram,
     ResolvedMethod <TNode> targetMethod,
     TNode source, Statement statement, TNode target,
     Func <TNode> nodeCreator)
 {
     targetProgram.AddOperation(source, new Operation <TNode>(statement, target));
     return(true);
 }
Ejemplo n.º 2
0
        public void Transform(
            INodeBasedProgram <int> sourceMethod,
            GraphStructuredProgram <TNode> targetProgram,
            ResolvedMethod <TNode> targetMethod,
            Func <int, TNode> mapper)
        {
            int counter = -1;

            TNode CreateNewNode()
            {
                var newNode = mapper(counter--);

                targetMethod.AddOwnedNode(newNode);
                return(newNode);
            }

            var visited = new HashSet <int>();

            var localStarts = sourceMethod.GetStarts();

            var queued = new Stack <(TNode source, int target)>();

            foreach (var localStart in localStarts)
            {
                queued.Push((targetMethod.Start, localStart));
            }

            if (queued.Count == 0)
            {
                targetProgram.AddOperation(targetMethod.Start, new Operation <TNode>(myNop, targetMethod.Final));
            }

            while (queued.Count > 0)
            {
                var(source, rawTarget) = queued.Pop();

                var statement = sourceMethod.StatementAt(rawTarget);
                var target    = mapper(rawTarget);

                InternalStep(targetProgram, targetMethod, source, statement, target, CreateNewNode);

                if (visited.Contains(rawTarget))
                {
                    continue;
                }

                if (sourceMethod.IsFinal(rawTarget))
                {
                    targetProgram.AddOperation(target, new Operation <TNode>(myReturn, targetMethod.Final));
                }
                else
                {
                    var transitions = sourceMethod.Transitions(rawTarget).ToList();
                    foreach (var transition in transitions)
                    {
                        queued.Push((target, transition));
                    }
                }

                visited.Add(rawTarget);
            }
        }
        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);
        }