/// <summary> /// Push the tables down and add a fresh new primary entry at the top. /// Returns the new scope. In general, callers should not use this returned scope. /// </summary> internal LookupEntry EnterScope() { // We don't create the tables unless we need them LookupEntry entry = new LookupEntry(null, null); lookupEntries.AddFirst(entry); return(entry); }
internal Lookup(Hashtable itemsByName, BuildItemGroup projectItems, BuildPropertyGroup properties, ItemDefinitionLibrary itemDefinitionLibrary) { ErrorUtilities.VerifyThrow(itemDefinitionLibrary != null, "Expect library"); this.projectItems = projectItems; this.itemDefinitionLibrary = itemDefinitionLibrary; LookupEntry entry = new LookupEntry(itemsByName, properties); lookupEntries.AddFirst(entry); }
/// <summary> /// Modifies items in this scope with the same set of metadata modifications. /// Assumes all the items in the group have the same, provided, type. /// </summary> internal void ModifyItems(string name, BuildItemGroup group, Dictionary <string, string> metadataChanges) { MustBeOwningThread(); // Modifying in outer scope could be easily implemented, but our code does not do it at present MustNotBeOuterScope(); #if DEBUG // This item should not already be in any remove table; there is no way a project can // modify items that were already removed // Obviously, do this only in debug, as it's a slow check for bugs. LinkedListNode <LookupEntry> node = lookupEntries.First; while (node != null) { LookupEntry entry = node.Value; foreach (BuildItem item in group) { BuildItem actualItem = RetrieveOriginalFromCloneTable(item); MustNotBeInTable(entry.Removes, actualItem); } node = node.Next; } #endif if (metadataChanges.Count == 0) { return; } // Put in the modify table // We don't need to check whether the item is in the add table vs. the main table; either // way the modification will be applied. PrimaryModifyTable = CreateTableIfNecessary(PrimaryModifyTable); Dictionary <BuildItem, Dictionary <string, string> > modifiesOfType; if (!PrimaryModifyTable.TryGetValue(name, out modifiesOfType)) { modifiesOfType = new Dictionary <BuildItem, Dictionary <string, string> >(); PrimaryModifyTable[name] = modifiesOfType; } foreach (BuildItem item in group) { // If we're asked to modify a clone we handed out, record it as a modify of the original // instead BuildItem actualItem = RetrieveOriginalFromCloneTable(item); KeyValuePair <BuildItem, Dictionary <string, string> > modify = new KeyValuePair <BuildItem, Dictionary <string, string> >(actualItem, metadataChanges); MergeModificationsIntoModificationTable(modifiesOfType, modify, ModifyMergeType.SecondWins); } }
/// <summary> /// Verify item is not in any table in any scope /// </summary> private void MustNotBeInAnyTables(BuildItem item) { // This item should not already be in any table; there is no way a project can // create items that already existed // Obviously, do this only in debug, as it's a slow check for bugs. LinkedListNode <LookupEntry> node = lookupEntries.First; while (node != null) { LookupEntry entry = node.Value; MustNotBeInTable(entry.Adds, item); MustNotBeInTable(entry.Removes, item); MustNotBeInTable(entry.Modifies, item); node = node.Next; } }