private async Task CreateAndSendCallMessageAsync(AnalysisInvocationExpession callInfo, MethodDescriptor realCallee, TypeDescriptor receiverType, PropagationKind propKind) { var callMessage = await CreateCallMessageAsync(callInfo, realCallee, receiverType, propKind); var callerMessage = new CallerMessage(this.EntityDescriptor, callMessage); var destination = EntityFactory.Create(realCallee, this.dispatcher); await this.SendMessageAsync(destination, callerMessage); }
//public void RegisterVirtualDelegateCall(MethodDescriptor callee, VariableNode receiver, // IList<AnalysisNode> arguments, // VariableNode lhs, DelegateVariableNode delegateVariableNode) //{ // Contract.Requires(receiver != null); // Contract.Requires(arguments != null); // Contract.Requires(lhs != null); // Contract.Requires(callee != null); // Contract.Requires(delegateVariableNode != null); // var callExp = new DelegateCallInfo(this.Method, delegateVariableNode, receiver, arguments, lhs); // this.PropagationGraph.AddEdge(receiver, delegateVariableNode); // RegisterInvocation(arguments, delegateVariableNode, callExp); //} private void RegisterInvocation(IList<PropGraphNodeDescriptor> arguments, AnalysisCallNode invocationNode, AnalysisInvocationExpession callExp) { Contract.Requires(callExp != null); Contract.Requires(arguments != null); Contract.Requires(invocationNode != null); this.PropagationGraph.AddCall(callExp, invocationNode); this.PropagationGraph.AddToWorkList(invocationNode); foreach (var a in arguments) { if (a != null) { PropagationGraph.AddEdge(a, invocationNode); } } }
private async Task<CallMessageInfo> CreateCallMessageAsync(AnalysisInvocationExpession callInfo, MethodDescriptor actuallCallee, TypeDescriptor computedReceiverType, PropagationKind propKind) { // var calleType = (TypeDescriptor)actuallCallee.ContainerType; var calleType = computedReceiverType; ISet<TypeDescriptor> potentialReceivers = new HashSet<TypeDescriptor>(); if (callInfo.Receiver != null) { // BUG!!!! I should use simply computedReceiverType // Instead of copying all types with use the type we use to compute the callee foreach (var type in GetTypes(callInfo.Receiver, propKind)) { var isSubType = await codeProvider.IsSubtypeAsync(type, calleType); if(isSubType) { potentialReceivers.Add(type); } } //potentialReceivers.UnionWith( // GetTypes(callInfo.Receiver, propKind) // .Where(t => codeProvider.IsSubtype(t, calleType))); //.Where(t => t.IsSubtype(calleType))); // potentialReceivers.Add((AnalysisType)calleType); } var argumentValues = callInfo.Arguments .Select(a => a != null ? GetTypes(a, propKind) : new HashSet<TypeDescriptor>()); Contract.Assert(argumentValues.Count() == callInfo.Arguments.Count()); return new CallMessageInfo(callInfo.Caller, actuallCallee, callInfo.CallNode, potentialReceivers, new List<ISet<TypeDescriptor>>(argumentValues), callInfo.LHS, callInfo.InstatiatedTypes, propKind); }
private void CreateAndSendCallMessage(AnalysisInvocationExpession callInfo, MethodDescriptor realCallee, TypeDescriptor receiverType, PropagationKind propKind) { /// Here I have all the necessary info to update the callgraph /// var callMessage = CreateCallMessage(callInfo, realCallee, receiverType, propKind); var callerMessage = new CallerMessage(this.EntityDescriptor, callMessage); var destination = EntityFactory.Create(realCallee, this.dispatcher); this.SendMessage(destination, callerMessage); }