private Task CreateAndSendCallMessageAsync(CallInfo callInfo, ResolvedCallee callee, PropagationKind propKind) { var callMessageInfo = new CallMessageInfo(callInfo.Caller, callee.Method, callee.ReceiverType, callInfo.ArgumentsPossibleTypes, callInfo.CallNode, callInfo.LHS, propKind); var source = new MethodEntityDescriptor(callInfo.Caller); var callerMessage = new CallerMessage(source, callMessageInfo); return(this.AnalyzeCalleeAsync(callMessageInfo.Callee, callerMessage, propKind)); }
private async Task <ISet <ResolvedCallee> > GetPossibleCalleesForDelegateCallAsync(DelegateVariableNode @delegate, IProjectCodeProvider codeProvider) { var possibleCallees = new HashSet <ResolvedCallee>(); var possibleDelegateMethods = this.GetPossibleMethodsForDelegate(@delegate); foreach (var method in possibleDelegateMethods) { if (method.IsStatic) { // Static method call var resolvedCallee = new ResolvedCallee(method); possibleCallees.Add(resolvedCallee); } else { // Instance method call var receiverPossibleTypes = this.GetTypes(@delegate); if (receiverPossibleTypes.Count > 0) { foreach (var receiverType in receiverPossibleTypes) { //var aMethod = delegateInstance.FindMethodImplementation(t); // Diego: Should I use : codeProvider.FindImplementation(delegateInstance, t); var callee = await codeProvider.FindMethodImplementationAsync(method, receiverType); var resolvedCallee = new ResolvedCallee(receiverType, callee); possibleCallees.Add(resolvedCallee); } } else { // We don't have any possibleType for the receiver, // so we just use the receiver's declared type to // identify the calle method implementation // if Count is 0, it is a delegate that do not came form an instance variable var receiverType = @delegate.Type; var resolvedCallee = new ResolvedCallee(receiverType, method); possibleCallees.Add(resolvedCallee); } } } return(possibleCallees); }
private Task CreateAndSendCallMessageAsync(CallInfo callInfo, ResolvedCallee callee, PropagationKind propKind) { var callMessageInfo = new CallMessageInfo(callInfo.Caller, callee.Method, callee.ReceiverType, callInfo.ArgumentsPossibleTypes, callInfo.CallNode, callInfo.LHS, propKind); var source = new MethodEntityDescriptor(callInfo.Caller); var callerMessage = new CallerMessage(source, callMessageInfo); //Logger.LogWarning(GrainClient.Logger, "Orchestrator", "CreateAndSendCallMsg", "Enqueuing: {0}", callee); //await WaitQueue(QUEUE_THRESHOLD); this.messageWorkList.Enqueue(callerMessage); //this.messageWorkList.Add(callerMessage); return(Task.CompletedTask); //return AnalyzeCalleeAsync(callMessageInfo.Callee, callerMessage, propKind); }
private async Task <ISet <ResolvedCallee> > GetPossibleCalleesForMethodCallAsync(PropGraphNodeDescriptor receiver, MethodDescriptor method, IProjectCodeProvider codeProvider) { var possibleCallees = new HashSet <ResolvedCallee>(); // TODO: This is not good: one reason is that loads like b = this.f are not working // in a method m after call r.m() because only the value of r is passed and not all its structure (fields) //if (methodCallInfo.IsConstructor || methodCallInfo.Method.IsStatic) //if (methodCallInfo.Method.IsStatic) //if (methodCallInfo.Method.IsStatic || !methodCallInfo.Method.IsVirtual) if (method.IsStatic) { // Static method call var resolvedCallee = new ResolvedCallee(method); possibleCallees.Add(resolvedCallee); } else if (!method.IsVirtual) { // Non-virtual method call var receiverPossibleTypes = this.GetTypes(receiver); if (receiverPossibleTypes.Count > 0) { foreach (var receiverType in receiverPossibleTypes) { var resolvedCallee = new ResolvedCallee(receiverType, method); possibleCallees.Add(resolvedCallee); } } } else { // Instance method call //// I need to compute all the callees //// In case of a deletion we can discard the deleted callee //// If callInfo.ReceiverPossibleTypes == {} it means that some info in missing => we should be conservative and use the instantiated types (RTA) //// TODO: I make this False for testing what happens if we remove this //if (conservativeWithTypes && methodCallInfo.ReceiverPossibleTypes.Count == 0) //{ // // TO-DO: Should I fix the node in the receiver to show that is not loaded. Ideally I should use the declared type. // // Here I will use the already instantiated types // foreach (var candidateTypeDescriptor in methodCallInfo.InstantiatedTypes) // { // var isSubtype = await codeProvider.IsSubtypeAsync(candidateTypeDescriptor, methodCallInfo.Receiver.Type); // if (isSubtype) // { // methodCallInfo.ReceiverPossibleTypes.Add(candidateTypeDescriptor); // } // } //} var receiverPossibleTypes = this.GetTypes(receiver); if (receiverPossibleTypes.Count > 0) { foreach (var receiverType in receiverPossibleTypes) { // Given a method m and T find the most accurate implementation wrt to T // it can be T.m or the first super class implementing m var methodDescriptor = await codeProvider.FindMethodImplementationAsync(method, receiverType); var resolvedCallee = new ResolvedCallee(receiverType, methodDescriptor); possibleCallees.Add(resolvedCallee); } } //else //{ // // We don't have any possibleType for the receiver, // // so we just use the receiver's declared type to // // identify the calle method implementation // possibleCallees.Add(methodCallInfo.Method); //} } return(possibleCallees); }