/// <summary> /// This is used by the incremental analysis when a caller is removed of modified /// </summary> /// <param name="context"></param> public void RemoveFromCallers(CallContext context) { //callers = callers.Remove(context); callers.Remove(context); }
/// <summary> /// Return an EntityProccesor. It is the class that performs the analysis using the data in the entity /// </summary> /// <param name="dispatcher"></param> /// <returns></returns> //public IEntityProcessor GetEntityProcessor(IDispatcher dispatcher) //{ // //if (this.EntityProcessor == null) // //{ // // EntityProcessor = new MethodEntityProcessor(this, dispatcher, true); // //} // //return EntityProcessor; // return new MethodEntityProcessor(this, dispatcher, true); //} public void AddToCallers(CallContext context) { //callers = callers.Add(context); callers.Add(context); }
/// <summary> /// Async versions of DispachReturnMessage /// </summary> /// <param name="context"></param> /// <param name="returnVariable"></param> /// <param name="propKind"></param> /// <returns></returns> internal async Task DispachReturnMessageAsync(CallContext context, VariableNode returnVariable, PropagationKind propKind) { var caller = context.Caller; var lhs = context.CallLHS; var types = returnVariable != null ? GetTypes(returnVariable, propKind) : new HashSet<TypeDescriptor>(); // Diego TO-DO, different treatment for adding and removal if (propKind == PropagationKind.ADD_TYPES && types.Count() == 0 && returnVariable != null) { var instTypes = new HashSet<TypeDescriptor>(); foreach (var iType in this.MethodEntity.InstantiatedTypes) { var isSubtype = await codeProvider.IsSubtypeAsync(iType,returnVariable.Type); if (isSubtype) { instTypes.Add(iType); } } //instTypes.UnionWith( // this.MethodEntity.InstantiatedTypes // .Where(iType => codeProvider.IsSubtypeAsync(iType,returnVariable.Type).Result)); //// .Where(iType => iType.IsSubtype(returnVariable.Type))); foreach (var t in instTypes) { types.Add(t); } } // Jump to caller var destination = EntityFactory.Create(caller,this.dispatcher); var retMessageInfo = new ReturnMessageInfo( lhs, types, propKind, this.MethodEntity.InstantiatedTypes, context.Invocation); var returnMessage = new ReturnMessage(this.MethodEntity.EntityDescriptor, retMessageInfo); //if (lhs != null) { await this.SendMessageAsync(destination, returnMessage); } //else //{ // return new Task(() => { }); //} }
private async Task HandleCallEventAsync(CallMessageInfo callMessage) { if (MethodEntity.CanBeAnalized) { Contract.Assert(callMessage.ArgumentValues.Count() == this.MethodEntity.ParameterNodes.Count()); if (this.Verbose) { Logger.Instance.Log("MethodEntityProcessor", "HandleCallEventAsync", "Reached {0} via call {1}", this.MethodEntity.MethodDescriptor, callMessage); } // This is the node in the caller where info of ret-value should go var lhs = callMessage.LHS; // Save caller info var callContext = new CallContext(callMessage.Caller, callMessage.LHS, callMessage.CallNode); /// Loop detected due to recursion //if (MethodEntity.NodesProcessing.Contains(callMessage.CallNode)) //if (MethodEntity.NodesProcessing.Contains(callContext)) //{ // if (this.Verbose) // { // Logger.Instance.Log(string.Format("Recursion loop {0} ", this.Method.ToString())); // } // //lock (this.MethodEntity) // //{ // // MethodEntity.NodesProcessing.Remove(callContext); // // //MethodEntity.NodesProcessing.Remove(callMessage.CallNode); // //} // //EndOfPropagationEventAsync(callMessage.PropagationKind); // return new Task(() => { }); //} // Just a test to try to block the Entity to a single simultaneous caller //while (this.MethodEntity.CurrentContext != null) //{ // Logger.Instance.Log(string.Format("Waiting: {0} to finish", this.Method)); // Thread.Sleep(10); //} //lock (this.MethodEntity) { //this.MethodEntity.CurrentContext = callContext; // Here is when I register the caller this.MethodEntity.AddToCallers(callContext); if (this.MethodEntity.ThisRef != null) { await this.MethodEntity.PropGraph.DiffPropAsync(Demarshaler.Demarshal(callMessage.Receivers), this.MethodEntity.ThisRef, callMessage.PropagationKind); } var pairIterator = new PairIterator<PropGraphNodeDescriptor, ISet<TypeDescriptor>> (this.MethodEntity.ParameterNodes, callMessage.ArgumentValues); foreach (var pair in pairIterator) { var parameterNode = pair.Item1; //PropGraph.Add(pn, argumentValues[i]); if (parameterNode != null) { await this.MethodEntity.PropGraph.DiffPropAsync( Demarshaler.Demarshal(pair.Item2), parameterNode, callMessage.PropagationKind); } } } switch (callMessage.PropagationKind) { case PropagationKind.ADD_TYPES: await PropagateAsync(); break; case PropagationKind.REMOVE_TYPES: await PropagateDeleteAsync(); break; } } else { await EndOfPropagationEventAsync(callMessage.PropagationKind,false); } }
private void HandleCallEvent(CallMessageInfo callMessage) { if (MethodEntity.CanBeAnalized) { Contract.Assert(callMessage.ArgumentValues.Count() == this.MethodEntity.ParameterNodes.Count()); if (this.Verbose) { Logger.Instance.Log("MethodEntityProcessor", "HandleCallEvent", "Reached {0} via call", this.MethodEntity.MethodDescriptor); } // This tries to check that the invocation is repeated (didn't work: need to check) //if (MethodEntity.Callers.Where(cs => cs.Invocation.Equals(callMessage.CallNode)).Count()>0) // This check if the method is already in caller list if (MethodEntity.Callers.Where(cs => cs.Caller.Equals(callMessage.Caller)).Count() > 0) { if (this.Verbose) { Logger.Instance.Log("MethodEntityProcessor", "HandleCallEvent", "Recursion loop {0} ", this.MethodEntity.MethodDescriptor); } EndOfPropagationEvent(callMessage.PropagationKind, false); return; } // Save caller info var context = new CallContext(callMessage.Caller, callMessage.LHS, callMessage.CallNode); this.MethodEntity.AddToCallers(context); // Propagate type info in method //PropGraph.Add(thisRef, receivers); if (this.MethodEntity.ThisRef != null) { this.MethodEntity.PropGraph.DiffProp(Demarshaler.Demarshal(callMessage.Receivers), this.MethodEntity.ThisRef, callMessage.PropagationKind); } var pairEnumerable = new PairIterator<PropGraphNodeDescriptor, ISet<TypeDescriptor>>( this.MethodEntity.ParameterNodes, callMessage.ArgumentValues); foreach (var pair in pairEnumerable) { var parameterNode = pair.Item1; //PropGraph.Add(pn, argumentValues[i]); if (parameterNode != null) { this.MethodEntity.PropGraph.DiffProp( Demarshaler.Demarshal(pair.Item2), parameterNode, callMessage.PropagationKind); } } if (callMessage.PropagationKind == PropagationKind.ADD_TYPES) { Propagate(); } if (callMessage.PropagationKind == PropagationKind.REMOVE_TYPES) { PropagateDelete(); } } else { EndOfPropagationEvent(callMessage.PropagationKind, false); } }