コード例 #1
0
            public CorePointsToAnalysisData MergeCoreAnalysisDataForBackEdge(
                PointsToAnalysisData forwardEdgeAnalysisData,
                PointsToAnalysisData backEdgeAnalysisData,
                Func <PointsToAbstractValue, ImmutableHashSet <AnalysisEntity> > getChildAnalysisEntities,
                Action <AnalysisEntity, PointsToAnalysisData> resetAbstractValue)
            {
                // Stop tracking points to values present in both branches if their is an assignment to a may-be null value from the back edge.
                // Clone the input forwardEdgeAnalysisData to ensure we don't overwrite the input dictionary.
                forwardEdgeAnalysisData = (PointsToAnalysisData)forwardEdgeAnalysisData.Clone();
                List <AnalysisEntity> keysInMap1 = forwardEdgeAnalysisData.CoreAnalysisData.Keys.ToList();

                foreach (var key in keysInMap1)
                {
                    var forwardEdgeValue = forwardEdgeAnalysisData[key];
                    if (backEdgeAnalysisData.TryGetValue(key, out var backEdgeValue) &&
                        backEdgeValue != forwardEdgeValue)
                    {
                        switch (backEdgeValue.NullState)
                        {
                        case NullAbstractValue.MaybeNull:
                            stopTrackingAnalysisDataForKeyAndChildren();
                            break;

                        case NullAbstractValue.NotNull:
                            if (backEdgeValue.MakeMayBeNull() != forwardEdgeValue)
                            {
                                if (forwardEdgeValue.NullState == NullAbstractValue.NotNull)
                                {
                                    stopTrackingAnalysisDataForChildren();
                                }
                                else
                                {
                                    stopTrackingAnalysisDataForKeyAndChildren();
                                }
                            }
                            break;
                        }

                        void stopTrackingAnalysisDataForKeyAndChildren()
                        {
                            stopTrackingAnalysisDataForChildren();
                            stopTrackingAnalysisDataForEntity(key);
                        }

                        void stopTrackingAnalysisDataForChildren()
                        {
                            var childEntities = getChildAnalysisEntities(forwardEdgeValue)
                                                .AddRange(getChildAnalysisEntities(backEdgeValue));

                            foreach (var childEntity in childEntities)
                            {
                                stopTrackingAnalysisDataForEntity(childEntity);
                            }
                        }

                        void stopTrackingAnalysisDataForEntity(AnalysisEntity entity)
                        {
                            if (entity.IsChildOrInstanceMember)
                            {
                                resetAbstractValue(entity, forwardEdgeAnalysisData);
                            }
                        }
                    }
                }

                var resultMap = Merge(forwardEdgeAnalysisData.CoreAnalysisData, backEdgeAnalysisData.CoreAnalysisData);

                Debug.Assert(Compare(forwardEdgeAnalysisData.CoreAnalysisData, resultMap) <= 0);
                Debug.Assert(Compare(backEdgeAnalysisData.CoreAnalysisData, resultMap) <= 0);
                return(resultMap);
            }