/// <summary> /// Evaluates a When clause. Checks if the condition is true, and if it is, /// applies all of the contained property group, item lists, and import statements. /// Returns true if the When clause is process (because the condition is true), false /// otherwise. /// </summary> /// <remarks> /// </remarks> /// <owner>DavidLe</owner> /// <param name="parentPropertyBag"></param> /// <param name="ignoreCondition"></param> /// <param name="honorCondition"></param> /// <param name="conditionedPropertiesTable"></param> /// <param name="pass"></param> /// <returns>bool</returns> internal void Evaluate ( BuildPropertyGroup parentPropertyBag, bool ignoreCondition, bool honorCondition, Hashtable conditionedPropertiesTable, ProcessingPass pass ) { foreach (IItemPropertyGrouping propOrItem in this.propertyAndItemLists) { // This is where we selectively evaluate PropertyGroups or Itemgroups during their respective passes. // Once we go to a one-pass model, we'll simple spin through all the children and evaluate. if (propOrItem is BuildPropertyGroup && pass == ProcessingPass.Pass1) { ((BuildPropertyGroup)propOrItem).Evaluate(parentPropertyBag, conditionedPropertiesTable, pass); } else if (propOrItem is BuildItemGroup && pass == ProcessingPass.Pass2) { ((BuildItemGroup)propOrItem).Evaluate(parentPropertyBag, parentProject.EvaluatedItemsByName, ignoreCondition, honorCondition, pass); } else if (propOrItem is Choose) { ((Choose)propOrItem).Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); } } }
/// <summary> /// Evaluates the Choose clause by stepping through each when and evaluating. /// </summary> /// <remarks> /// </remarks> /// <owner>DavidLe</owner> /// <param name="parentPropertyBag"></param> /// <param name="ignoreCondition"></param> /// <param name="honorCondition"></param> /// <param name="conditionedPropertiesTable"></param> /// <param name="pass"></param> internal void Evaluate ( BuildPropertyGroup parentPropertyBag, bool ignoreCondition, bool honorCondition, Hashtable conditionedPropertiesTable, ProcessingPass pass ) { if (pass == ProcessingPass.Pass1) { whenLastTaken = null; bool whenTaken = false; foreach (When currentWhen in this.whenClauseList) { if (currentWhen.EvaluateCondition(parentPropertyBag, conditionedPropertiesTable)) { whenTaken = true; currentWhen.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); whenLastTaken = currentWhen; break; } } if (!whenTaken && otherwiseClause != null) { // Process otherwise whenLastTaken = otherwiseClause; otherwiseClause.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); } } else { ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass2, "ProcessingPass must be Pass1 or Pass2."); whenLastTaken?.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); } }
/// <summary> /// Evaluates the Choose clause by stepping through each when and evaluating. /// </summary> /// <remarks> /// </remarks> /// <owner>DavidLe</owner> /// <param name="parentPropertyBag"></param> /// <param name="ignoreCondition"></param> /// <param name="honorCondition"></param> /// <param name="conditionedPropertiesTable"></param> /// <param name="pass"></param> internal void Evaluate ( BuildPropertyGroup parentPropertyBag, bool ignoreCondition, bool honorCondition, Hashtable conditionedPropertiesTable, ProcessingPass pass ) { if (pass == ProcessingPass.Pass1) { whenLastTaken = null; bool whenTaken = false; foreach (When currentWhen in this.whenClauseList) { if (currentWhen.EvaluateCondition(parentPropertyBag, conditionedPropertiesTable)) { whenTaken = true; currentWhen.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); whenLastTaken = currentWhen; break; } } if (!whenTaken && otherwiseClause != null) { // Process otherwise whenLastTaken = otherwiseClause; otherwiseClause.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); } } else { ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass2, "ProcessingPass must be Pass1 or Pass2."); if (whenLastTaken != null) { whenLastTaken.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); } } }
/// <summary> /// Evaluates an item group that's *outside* of a Target. /// Metadata is not allowed on conditions, and we against the parent project. /// </summary> internal void Evaluate ( BuildPropertyGroup existingProperties, Hashtable existingItemsByName, bool collectItemsIgnoringCondition, bool collectItemsRespectingCondition, ProcessingPass pass ) { ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass2, "Pass should be Pass2 for ItemGroups."); ErrorUtilities.VerifyThrow(collectItemsIgnoringCondition || collectItemsRespectingCondition, "collectItemsIgnoringCondition and collectItemsRespectingCondition can't both be false."); Expander expander = new Expander(existingProperties, existingItemsByName, ExpanderOptions.ExpandAll); bool itemGroupCondition = Utilities.EvaluateCondition(Condition, (IsPersisted ? xml.ConditionAttribute : null), expander, ParserOptions.AllowPropertiesAndItemLists, parentProject); if (!itemGroupCondition && !collectItemsIgnoringCondition) { // Neither list needs updating return; } foreach (BuildItem currentItem in this) { bool itemCondition = Utilities.EvaluateCondition(currentItem.Condition, currentItem.ConditionAttribute, expander, ParserOptions.AllowPropertiesAndItemLists, parentProject); if (!itemCondition && !collectItemsIgnoringCondition) { // Neither list needs updating continue; } if (collectItemsIgnoringCondition) { // Since we're re-evaluating the project, clear out the previous list of child items // for each persisted item tag. currentItem.ChildItems.Clear(); } currentItem.EvaluateAllItemMetadata(expander, ParserOptions.AllowPropertiesAndItemLists, parentProject.ParentEngine.LoggingServices, parentProject.ProjectBuildEventContext); BuildItemGroup items = BuildItemGroup.ExpandItemIntoItems(parentProject.ProjectDirectory, currentItem, expander, false /* do not expand metadata */); foreach (BuildItem item in items) { BuildItem newItem = BuildItem.CreateClonedParentedItem(item, currentItem); if (itemGroupCondition && itemCondition && collectItemsRespectingCondition) { parentProject.AddToItemListByName(newItem); } if (collectItemsIgnoringCondition) { parentProject.AddToItemListByNameIgnoringCondition(newItem); // Set up the other half of the parent/child relationship. newItem.ParentPersistedItem.ChildItems.AddItem(newItem); } } } }
/// <summary> /// Evaluates condition on property group, and if true, evaluates /// on each contained property. If that's true as well, adds property /// to evaluatedPropertyBag. /// </summary> /// <owner>DavidLe</owner> /// <param name="evaluatedPropertyBag"></param> /// <param name="conditionedPropertiesTable"></param> /// <param name="pass"></param> internal void Evaluate ( BuildPropertyGroup evaluatedPropertyBag, Hashtable conditionedPropertiesTable, ProcessingPass pass ) { ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass1, "Pass should be Pass1 for PropertyGroups."); Expander expander = new Expander(evaluatedPropertyBag); if (!Utilities.EvaluateCondition(this.Condition, this.ConditionAttribute, expander, conditionedPropertiesTable, ParserOptions.AllowProperties, ParentProject.ParentEngine.LoggingServices, ParentProject.ProjectBuildEventContext)) { return; } // Add all the properties to our project-level property bag. foreach (BuildProperty currentProperty in this.propertyList) { if (!Utilities.EvaluateCondition(currentProperty.Condition, currentProperty.ConditionAttribute, expander, conditionedPropertiesTable, ParserOptions.AllowProperties, ParentProject.ParentEngine.LoggingServices, parentProject.ProjectBuildEventContext)) { continue; } BuildProperty newProperty = currentProperty.Clone(false); newProperty.Evaluate(expander); evaluatedPropertyBag.SetProperty(newProperty); } }
/// <summary> /// Evaluates a When clause. Checks if the condition is true, and if it is, /// applies all of the contained property group, item lists, and import statements. /// Returns true if the When clause is process (because the condition is true), false /// otherwise. /// </summary> /// <remarks> /// </remarks> /// <owner>DavidLe</owner> /// <param name="parentPropertyBag"></param> /// <param name="ignoreCondition"></param> /// <param name="honorCondition"></param> /// <param name="conditionedPropertiesTable"></param> /// <param name="pass"></param> /// <returns>bool</returns> internal void Evaluate ( BuildPropertyGroup parentPropertyBag, bool ignoreCondition, bool honorCondition, Hashtable conditionedPropertiesTable, ProcessingPass pass ) { foreach (IItemPropertyGrouping propOrItem in this.propertyAndItemLists) { // This is where we selectively evaluate PropertyGroups or Itemgroups during their respective passes. // Once we go to a one-pass model, we'll simple spin through all the children and evaluate. if (propOrItem is BuildPropertyGroup && pass == ProcessingPass.Pass1) { ((BuildPropertyGroup) propOrItem).Evaluate(parentPropertyBag, conditionedPropertiesTable, pass); } else if (propOrItem is BuildItemGroup && pass == ProcessingPass.Pass2) { ((BuildItemGroup) propOrItem).Evaluate(parentPropertyBag, parentProject.EvaluatedItemsByName, ignoreCondition, honorCondition, pass); } else if (propOrItem is Choose) { ((Choose) propOrItem).Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass); } } }