Exemple #1
0
        protected override Entity RestoreImplementation <TNode>(
            GraphStructuredProgram <TNode> program,
            ResolvedMethod <TNode> method,
            Entity entity)
        {
            var localVariable = (ResolvedLocalVariable)entity;

            var exists = method.Variables.TryGetValue(localVariable.LocalId, out var variable);

            //Trace.Assert(exists);
            if (!exists)
            {
                method.AddLocalVariable(localVariable);
                variable = localVariable;
            }

            return(variable);
        }
        protected override Entity InternalResolve <TNode>(
            GraphStructuredProgram <TNode> program,
            ResolvedMethod <TNode> method,
            Reference reference)
        {
            var real   = (LocalVariableReference)reference;
            var exists = method.Variables.TryGetValue(real.Index, out var resolved);

            Trace.Assert(exists);
            if (!exists)
            {
                method.AddLocalVariable(new ResolvedLocalVariable(real.Index));
                resolved = method.Variables[real.Index];
            }

            if (resolved.DefaultClassType < 0 && real.DefaultType != null)
            {
                var defaultType = program.GetOrCreateClass(real.DefaultType);
                resolved.DefaultClassType = defaultType.Id.GlobalId;
            }

            return(resolved);
        }
        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);
        }