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); }