public virtual async Task <IEntity> CreateMethodEntityAsync(MethodDescriptor methodDescriptor)
        {
            var methodParserInfo = await this.FindMethodInProjectAsync(methodDescriptor);

            MethodEntity methodEntity = null;

            if (methodParserInfo != null)
            {
                var methodEntityGenerator = new MethodParser(methodParserInfo);
                methodEntity = methodEntityGenerator.ParseMethod();
            }
            else
            {
                var methodEntityGenerator = new LibraryMethodParser(methodDescriptor);
                methodEntity = methodEntityGenerator.ParseMethod();
            }

            // this is for RTA analysis
            if (methodEntity.InstantiatedTypes.Count > 0)
            {
                await this.rtaManager.AddInstantiatedTypesAsync(methodEntity.InstantiatedTypes);
            }

            return(methodEntity);
        }
        public override Task OnDeactivateAsync()
        {
            StatsHelper.RegisterDeactivation("MethodEntityGrain", this.GrainFactory);

            Logger.LogWarning(this.GetLogger(), "MethodEntityGrain", "OnDeactivate", "Deactivation for {0} ", this.GetPrimaryKeyString());

            this.methodEntity = null;
            return(Task.CompletedTask);
        }
        private async Task CreateMethodEntityAsync(MethodDescriptor methodDescriptor)
        {
            // This is a private method. We must not register this as a grain callee
            // await StatsHelper.RegisterMsg("MethodEntityGrain::CreateMethodEntity", this.GrainFactory);

            this.solutionGrain = OrleansSolutionManager.GetSolutionGrain(this.GrainFactory);

            this.State.MethodDescriptor = methodDescriptor;
            var methodDescriptorToSearch = methodDescriptor.BaseDescriptor;

            var codeProviderGrain = await solutionGrain.GetProjectCodeProviderAsync(methodDescriptorToSearch);

            // This wrapper caches some of the queries to codeProvider
            //this.codeProvider = new ProjectCodeProviderWithCache(codeProviderGrain);
            this.codeProvider = codeProviderGrain;

            //Logger.LogWarning(this.GetLogger(), "MethodEntityGrain", "CreateMethodEntity", "{0} calls to proivder {1}", methodDescriptor, this.codeProvider);
            var sw = new Stopwatch();

            sw.Start();

            this.methodEntity = (MethodEntity)await codeProvider.CreateMethodEntityAsync(methodDescriptorToSearch);

            sw.Stop();

            Logger.LogInfo(this.GetLogger(), "MethodEntityGrain", "CreateMethodEntity", "{0};call to provider;{1};ms;{2};ticks", methodDescriptor, sw.ElapsedMilliseconds, sw.ElapsedTicks);

            if (methodDescriptor.IsAnonymousDescriptor)
            {
                this.methodEntity = this.methodEntity.GetAnonymousMethodEntity((AnonymousMethodDescriptor)methodDescriptor);
            }

            //// this is for RTA analysis
            //await solutionGrain.AddInstantiatedTypesAsync(this.methodEntity.InstantiatedTypes);

            // This take cares of doing the progation of types
            this.methodEntityPropagator = new MethodEntityWithPropagator(methodEntity, codeProvider);

            await this.WriteStateAsync();

            //Logger.LogWarning(this.GetLogger(), "MethodEntityGrain", "CreateMethodEntity", "Exit {0}", methodDescriptor);
        }
        /// <summary>
        /// Copy the information regarding parameters and callers from one entity and other
        /// The PropGraph of the old entity is used but copied
        /// This is used when one method is updated to recompute the PropGraph using the original input values
        /// </summary>
        /// <param name="oldEntity"></param>
        internal void CopyInterfaceDataAndCallers(MethodEntity entity)
        {
            Contract.Requires(this.ParameterNodes != null);
            foreach (var parameter in this.ParameterNodes)
            {
                if (parameter != null)
                {
                    this.PropGraph.Add(parameter, entity.PropGraph.GetTypes(parameter));
                    this.PropGraph.AddToWorkList(parameter);
                }
            }
            if (this.ThisRef != null)
            {
                this.PropGraph.Add(this.ThisRef, entity.PropGraph.GetTypes(entity.ThisRef));
                this.PropGraph.AddToWorkList(this.ThisRef);
            }

            foreach (var callersContext in entity.Callers)
            {
                this.AddToCallers(callersContext);
            }
        }
        /// <summary>
        /// Compute all the calless of this method entities
        /// </summary>
        /// <returns></returns>
        //internal static async Task<ISet<MethodDescriptor>> GetCalleesAsync(MethodEntity methodEntity, IProjectCodeProvider codeProvider)
        //{
        //	var result = new HashSet<MethodDescriptor>();

        //	foreach (var callNode in methodEntity.PropGraph.CallNodes)
        //	{
        //		result.UnionWith(await GetCalleesAsync(methodEntity, callNode, codeProvider));
        //	}

        //	return result;
        //}

        /// <summary>
        /// Computes all the potential callees for a particular method invocation
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        internal static async Task <ISet <MethodDescriptor> > GetCalleesAsync(MethodEntity methodEntity, AnalysisCallNode node, IProjectCodeProvider codeProvider)
        {
            var stopWatch = Stopwatch.StartNew();

            ISet <MethodDescriptor> result;
            var calleesForNode = new HashSet <MethodDescriptor>();
            var invExp         = methodEntity.PropGraph.GetInvocationInfo((AnalysisCallNode)node);

            Meausure("ME.PG.GetInvocationInfo", stopWatch);

            Contract.Assert(invExp != null);
            Contract.Assert(codeProvider != null);

            var calleeResult = await methodEntity.PropGraph.ComputeCalleesForNodeAsync(invExp, codeProvider);

            Meausure("ME.PG.ComputeCalleesForNode", stopWatch);

            calleesForNode.UnionWith(calleeResult);

            //calleesForNode.UnionWith(invExp.ComputeCalleesForNode(this.MethodEntity.PropGraph,this.codeProvider));

            result = calleesForNode;
            return(result);
        }
Пример #6
0
        //private Queue<PropagationEffects> propagationEffectsToSend;
        //private Orleans.Runtime.Logger logger = GrainClient.Logger;

        ///// <summary>
        ///// This build a MethodEntityPropagator with a solution
        ///// The solution provides its CodeProvicer
        ///// </summary>
        ///// <param name="methodDescriptor"></param>
        ///// <param name="solutionManager"></param>
        //public MethodEntityWithPropagator(MethodDescriptor methodDescriptor, IProjectCodeProvider codeProvider)
        //{
        //	var methodDescriptorToSearch = methodDescriptor.BaseDescriptor;
        //
        //	this.codeProvider = codeProvider;
        //	this.propagationEffectsToSend = new Queue<PropagationEffects>();
        //	this.methodEntity = (MethodEntity)this.codeProvider.CreateMethodEntityAsync(methodDescriptorToSearch).Result;
        //
        //	//var providerEntity = ProjectCodeProvider.FindCodeProviderAndEntity(methodDescriptorToSearch, solutionManager.Solution).Result;
        //	//this.methodEntity = providerEntity.Item2;
        //	//this.codeProvider = providerEntity.Item1;
        //
        //	if (methodDescriptor.IsAnonymousDescriptor)
        //	{
        //		this.methodEntity = this.methodEntity.GetAnonymousMethodEntity((AnonymousMethodDescriptor)methodDescriptor);
        //	}
        //}

        /// <summary>
        /// Creates the Propagator using directly an entity and a provider
        /// This can be used by the MethodEntityGrain
        /// </summary>
        /// <param name="methodEntity"></param>
        /// <param name="provider"></param>
        public MethodEntityWithPropagator(MethodEntity methodEntity, IProjectCodeProvider provider)
        {
            this.codeProvider = provider;
            this.methodEntity = methodEntity;
            //this.propagationEffectsToSend = new Queue<PropagationEffects>();
        }
        /// <summary>
        /// Generates a dictionary invocationNode -> potential callees
        /// This is used for example by the demo to get the caller / callee info
        /// </summary>
        /// <returns></returns>
        internal static async Task <IDictionary <AnalysisCallNode, ISet <MethodDescriptor> > > GetCalleesInfo(MethodEntity methodEntity, IProjectCodeProvider codeProvider)
        {
            var calleesPerEntity = new Dictionary <AnalysisCallNode, ISet <MethodDescriptor> >();

            foreach (var calleeNode in methodEntity.PropGraph.CallNodes)
            {
                calleesPerEntity[calleeNode] = await GetCalleesAsync(methodEntity, calleeNode, codeProvider);
            }

            return(calleesPerEntity);
        }
 internal void RegisterAnonymousMethod(AnonymousMethodDescriptor methodDescriptor, MethodEntity methodEntity)
 {
     this.anonymousMethods[methodDescriptor] = methodEntity;
 }