Esempio n. 1
0
        public void ProcessItemElement(string rootDirectory, ProjectItemElement itemElement, bool conditionResult)
        {
            LazyItemOperation operation = null;

            if (itemElement.IncludeLocation != null)
            {
                operation = BuildIncludeOperation(rootDirectory, itemElement, conditionResult);
            }
            else if (itemElement.RemoveLocation != null)
            {
                operation = BuildRemoveOperation(rootDirectory, itemElement);
            }
            else if (itemElement.UpdateLocation != null)
            {
                operation = BuildUpdateOperation(rootDirectory, itemElement);
            }
            else
            {
                throw new NotImplementedException();
            }

            LazyItemList previousItemList = GetItemList(itemElement.ItemType);
            LazyItemList newList          = new LazyItemList(previousItemList, operation);

            _itemLists[itemElement.ItemType] = newList;
        }
Esempio n. 2
0
        public void ProcessItemElement(string rootDirectory, ProjectItemElement itemElement, bool conditionResult)
        {
            LazyItemOperation operation = null;

            if (itemElement.IncludeLocation != null)
            {
                operation = BuildIncludeOperation(rootDirectory, itemElement, conditionResult);
            }
            else if (itemElement.RemoveLocation != null)
            {
                operation = BuildRemoveOperation(rootDirectory, itemElement, conditionResult);
            }
            else if (itemElement.UpdateLocation != null)
            {
                operation = BuildUpdateOperation(rootDirectory, itemElement, conditionResult);
            }
            else
            {
                ErrorUtilities.ThrowInternalErrorUnreachable();
            }

            LazyItemList previousItemList = GetItemList(itemElement.ItemType);
            LazyItemList newList          = new LazyItemList(previousItemList, operation);

            _itemLists[itemElement.ItemType] = newList;
        }
Esempio n. 3
0
            static ImmutableList <ItemData> .Builder GetItemsImplementation(LazyItemList lazyItemList, ImmutableHashSet <string> globsToIgnore)
            {
                Stack <LazyItemList> itemListStack = new Stack <LazyItemList>();

                //  Keep a separate stack of lists of globs to ignore that only gets modified for Remove operations
                Stack <ImmutableHashSet <string> > globsToIgnoreStack = null;

                for (var currentList = lazyItemList; currentList != null; currentList = currentList._previous)
                {
                    //  If this is a remove operation, then add any globs that will be removed
                    //  to a list of globs to ignore in previous operations
                    var removeOperation = currentList._operation as RemoveOperation;
                    if (removeOperation != null)
                    {
                        if (globsToIgnoreStack == null)
                        {
                            globsToIgnoreStack = new Stack <ImmutableHashSet <string> >();
                        }

                        var globsToIgnoreFromFutureOperations = globsToIgnoreStack.Count > 0 ? globsToIgnoreStack.Peek() : globsToIgnore;

                        var globsToIgnoreForPreviousOperations = removeOperation.GetRemovedGlobs();
                        foreach (var globToRemove in globsToIgnoreFromFutureOperations)
                        {
                            globsToIgnoreForPreviousOperations.Add(globToRemove);
                        }

                        globsToIgnoreStack.Push(globsToIgnoreForPreviousOperations.ToImmutable());
                    }

                    itemListStack.Push(currentList);
                }

                ImmutableList <ItemData> .Builder items = ImmutableList.CreateBuilder <ItemData>();
                ImmutableHashSet <string>         currentGlobsToIgnore = globsToIgnoreStack == null ? globsToIgnore : globsToIgnoreStack.Peek();

                //  Walk back down the stack of item lists applying operations
                while (itemListStack.Count > 0)
                {
                    var currentList = itemListStack.Pop();

                    //  If this is a remove operation, then it could modify the globs to ignore, so pop the potentially
                    //  modified entry off the stack of globs to ignore
                    var removeOperation = currentList._operation as RemoveOperation;
                    if (removeOperation != null)
                    {
                        globsToIgnoreStack.Pop();
                        currentGlobsToIgnore = globsToIgnoreStack.Count == 0 ? globsToIgnore : globsToIgnoreStack.Peek();
                    }

                    currentList._operation.Apply(items, currentGlobsToIgnore);
                    //  TODO: Cache result of operation (possibly only if it involved executing globs)
                }

                return(items);
            }
Esempio n. 4
0
        ICollection <ItemData> GetItems(string itemType)
        {
            LazyItemList itemList = GetItemList(itemType);

            if (itemList == null)
            {
                return(ImmutableList <ItemData> .Empty);
            }
            return(itemList.GetItems(ImmutableHashSet <string> .Empty).Where(itemData => itemData.ConditionResult).ToList());
        }
Esempio n. 5
0
        private ImmutableList <I> GetItems(string itemType)
        {
            LazyItemList itemList = GetItemList(itemType);

            if (itemList == null)
            {
                return(ImmutableList <I> .Empty);
            }

            return(itemList.GetMatchedItems(ImmutableHashSet <string> .Empty));
        }
Esempio n. 6
0
                internal static Item Create(LazyItemList list, int index, int height)
                {
                    var id = list.ItemIdOffset + index;

                    if (id % ItemTypeModulous == 0)
                    {
                        return(new Alternate(id, list.Id, height));
                    }

                    return(new Normal(id, list.Id, height));
                }
Esempio n. 7
0
            private static ImmutableList <ItemData> .Builder ComputeItems(LazyItemList lazyItemList, ImmutableHashSet <string> globsToIgnore)
            {
                // Stack of operations up to the first one that's cached (exclusive)
                Stack <LazyItemList> itemListStack = new Stack <LazyItemList>();

                ImmutableList <ItemData> .Builder items = null;

                // Keep a separate stack of lists of globs to ignore that only gets modified for Remove operations
                Stack <ImmutableHashSet <string> > globsToIgnoreStack = null;

                for (var currentList = lazyItemList; currentList != null; currentList = currentList._previous)
                {
                    var globsToIgnoreFromFutureOperations = globsToIgnoreStack?.Peek() ?? globsToIgnore;

                    ImmutableList <ItemData> itemsFromCache;
                    if (currentList._memoizedOperation.TryGetFromCache(globsToIgnoreFromFutureOperations, out itemsFromCache))
                    {
                        // the base items on top of which to apply the uncached operations are the items of the first operation that is cached
                        items = itemsFromCache.ToBuilder();
                        break;
                    }

                    //  If this is a remove operation, then add any globs that will be removed
                    //  to a list of globs to ignore in previous operations
                    var removeOperation = currentList._memoizedOperation.Operation as RemoveOperation;
                    if (removeOperation != null)
                    {
                        if (globsToIgnoreStack == null)
                        {
                            globsToIgnoreStack = new Stack <ImmutableHashSet <string> >();
                        }

                        var globsToIgnoreForPreviousOperations = removeOperation.GetRemovedGlobs();
                        foreach (var globToRemove in globsToIgnoreFromFutureOperations)
                        {
                            globsToIgnoreForPreviousOperations.Add(globToRemove);
                        }

                        globsToIgnoreStack.Push(globsToIgnoreForPreviousOperations.ToImmutable());
                    }

                    itemListStack.Push(currentList);
                }

                if (items == null)
                {
                    items = ImmutableList.CreateBuilder <ItemData>();
                }

                ImmutableHashSet <string> currentGlobsToIgnore = globsToIgnoreStack == null ? globsToIgnore : globsToIgnoreStack.Peek();

                //  Walk back down the stack of item lists applying operations
                while (itemListStack.Count > 0)
                {
                    var currentList = itemListStack.Pop();

                    //  If this is a remove operation, then it could modify the globs to ignore, so pop the potentially
                    //  modified entry off the stack of globs to ignore
                    var removeOperation = currentList._memoizedOperation.Operation as RemoveOperation;
                    if (removeOperation != null)
                    {
                        globsToIgnoreStack.Pop();
                        currentGlobsToIgnore = globsToIgnoreStack.Count == 0 ? globsToIgnore : globsToIgnoreStack.Peek();
                    }

                    currentList._memoizedOperation.Apply(items, currentGlobsToIgnore);
                }

                return(items);
            }
Esempio n. 8
0
 public LazyItemList(LazyItemList previous, LazyItemOperation operation)
 {
     _previous          = previous;
     _memoizedOperation = new MemoizedOperation(operation);
 }
Esempio n. 9
0
 public LazyItemList(LazyItemList previous, LazyItemOperation operation)
 {
     _previous  = previous;
     _operation = operation;
 }
Esempio n. 10
0
            private static OrderedItemDataCollection.Builder ComputeItems(LazyItemList lazyItemList, ImmutableHashSet <string> globsToIgnore)
            {
                // Stack of operations up to the first one that's cached (exclusive)
                Stack <LazyItemList> itemListStack = new Stack <LazyItemList>();

                OrderedItemDataCollection.Builder items = null;

                // Keep a separate stack of lists of globs to ignore that only gets modified for Remove operations
                Stack <ImmutableHashSet <string> > globsToIgnoreStack = null;

                for (var currentList = lazyItemList; currentList != null; currentList = currentList._previous)
                {
                    var globsToIgnoreFromFutureOperations = globsToIgnoreStack?.Peek() ?? globsToIgnore;

                    OrderedItemDataCollection itemsFromCache;
                    if (currentList._memoizedOperation.TryGetFromCache(globsToIgnoreFromFutureOperations, out itemsFromCache))
                    {
                        // the base items on top of which to apply the uncached operations are the items of the first operation that is cached
                        items = itemsFromCache.ToBuilder();
                        break;
                    }

                    // If this is a remove operation, then add any globs that will be removed
                    //  to a list of globs to ignore in previous operations
                    if (currentList._memoizedOperation.Operation is RemoveOperation removeOperation)
                    {
                        globsToIgnoreStack ??= new Stack <ImmutableHashSet <string> >();

                        var globsToIgnoreForPreviousOperations = removeOperation.GetRemovedGlobs();
                        foreach (var globToRemove in globsToIgnoreFromFutureOperations)
                        {
                            globsToIgnoreForPreviousOperations.Add(globToRemove);
                        }

                        globsToIgnoreStack.Push(globsToIgnoreForPreviousOperations.ToImmutable());
                    }

                    itemListStack.Push(currentList);
                }

                if (items == null)
                {
                    items = OrderedItemDataCollection.CreateBuilder();
                }

                ImmutableHashSet <string> currentGlobsToIgnore = globsToIgnoreStack == null ? globsToIgnore : globsToIgnoreStack.Peek();

                Dictionary <string, UpdateOperation> itemsWithNoWildcards = new Dictionary <string, UpdateOperation>(StringComparer.OrdinalIgnoreCase);
                bool addedToBatch = false;

                // Walk back down the stack of item lists applying operations
                while (itemListStack.Count > 0)
                {
                    var currentList = itemListStack.Pop();

                    if (currentList._memoizedOperation.Operation is UpdateOperation op)
                    {
                        bool addToBatch = true;
                        int  i;
                        // The TextFragments are things like abc.def or x*y.*z.
                        for (i = 0; i < op.Spec.Fragments.Count; i++)
                        {
                            ItemSpecFragment frag = op.Spec.Fragments[i];
                            if (MSBuildConstants.CharactersForExpansion.Any(frag.TextFragment.Contains))
                            {
                                // Fragment contains wild cards, items, or properties. Cannot batch over it using a dictionary.
                                addToBatch = false;
                                break;
                            }

                            string fullPath = FileUtilities.GetFullPath(frag.TextFragment, frag.ProjectDirectory);
                            if (itemsWithNoWildcards.ContainsKey(fullPath))
                            {
                                // Another update will already happen on this path. Make that happen before evaluating this one.
                                addToBatch = false;
                                break;
                            }
                            else
                            {
                                itemsWithNoWildcards.Add(fullPath, op);
                            }
                        }
                        if (!addToBatch)
                        {
                            // We found a wildcard. Remove any fragments associated with the current operation and process them later.
                            for (int j = 0; j < i; j++)
                            {
                                itemsWithNoWildcards.Remove(currentList._memoizedOperation.Operation.Spec.Fragments[j].TextFragment);
                            }
                        }
                        else
                        {
                            addedToBatch = true;
                            continue;
                        }
                    }

                    if (addedToBatch)
                    {
                        addedToBatch = false;
                        ProcessNonWildCardItemUpdates(itemsWithNoWildcards, items);
                    }

                    // If this is a remove operation, then it could modify the globs to ignore, so pop the potentially
                    //  modified entry off the stack of globs to ignore
                    if (currentList._memoizedOperation.Operation is RemoveOperation)
                    {
                        globsToIgnoreStack.Pop();
                        currentGlobsToIgnore = globsToIgnoreStack.Count == 0 ? globsToIgnore : globsToIgnoreStack.Peek();
                    }

                    currentList._memoizedOperation.Apply(items, currentGlobsToIgnore);
                }

                // We finished looping through the operations. Now process the final batch if necessary.
                ProcessNonWildCardItemUpdates(itemsWithNoWildcards, items);

                return(items);
            }