/// <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; } }
private void InitializeForRunningTargetBatches() { // Make sure the <target> node has been given to us. ErrorUtilities.VerifyThrow(targetElement != null, "Need an XML node representing the <target> element."); // Make sure this really is the <target> node. ProjectXmlUtilities.VerifyThrowElementName(targetElement, XMakeElements.target); overallSuccess = true; projectContent = new Lookup(parentProject.evaluatedItemsByName, parentProject.evaluatedItems, parentProject.evaluatedProperties, parentProject.ItemDefinitionLibrary); // If we need to use the task thread - ie, we encounter a non-intrinsic task - we will need to make sure // the task thread only sees clones of the project items and properties. We insert a scope to allow us to // do that later. See comment in InitializeForRunningFirstNonIntrinsicTask() placeholderForClonedProjectContent = projectContent.EnterScope(); buckets = BatchingEngine.PrepareBatchingBuckets(targetElement, targetParameters, projectContent); currentBucket = 0; // Initialize the first bucket InitializeForRunningSingleTargetBatch(); }
/// <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; }