public void ParseBasicRemoveOperation()
        {
            XmlElement xml = CreateBasicRemoveElement();
            BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemRemove);

            Assertion.AssertEquals("i1", child.Remove);
        }
        public void ExpectAnyGetModify()
        {
            XmlElement xml = XmlTestUtilities.CreateBasicElement("i");
            BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.Any);

            Assertion.AssertEquals(ChildType.BuildItemModify, child.ChildType);
        }
示例#3
0
        /// <summary>
        /// Add items to the world. This is the in-target equivalent of an item include expression outside of a target.
        /// </summary>
        private void ExecuteAdd(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            // By making the items "not persisted", we ensure they are cleaned away when the project is reset
            BuildItem item = new BuildItem(child.Element, false /* not imported */, false /* not persisted */, itemDefinitionLibrary);

            // If the condition on the item is false, Evaluate returns an empty group
            BuildItemGroup itemsToAdd = item.Evaluate(bucket.Expander, executionDirectory, true /* expand metadata */, ParserOptions.AllowAll, loggingServices, buildEventContext);

            bucket.Lookup.AddNewItems(itemsToAdd);
        }
示例#4
0
        /// <summary>
        /// Modifies items in the world - specifically, changes their metadata. Changes to items that are part of the project manifest are backed up, so
        /// they can be reverted when the project is reset after the end of the build.
        /// </summary>
        /// <param name="child"></param>
        /// <param name="bucket"></param>
        private void ExecuteModify(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            if (!Utilities.EvaluateCondition(child.Condition, child.ConditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext))
            {
                return;
            }

            BuildItemGroup group = (BuildItemGroup)bucket.Lookup.GetItems(child.Name);

            if (group == null)
            {
                // No items of this type to modify
                return;
            }

            // Figure out what metadata names and values we need to set
            Dictionary <string, string> metadataToSet = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            List <XmlElement> metadataElements = child.GetChildren();

            foreach (XmlElement metadataElement in metadataElements)
            {
                bool         metadataCondition  = true;
                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(metadataElement, true /*no other attributes allowed*/);

                if (conditionAttribute != null)
                {
                    metadataCondition = Utilities.EvaluateCondition(conditionAttribute.Value, conditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext);
                }

                if (metadataCondition)
                {
                    string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(metadataElement);
                    string evaluatedMetadataValue   = bucket.Expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, metadataElement);
                    // The last metadata with a particular name, wins, so we just set through the indexer here.
                    metadataToSet[metadataElement.Name] = evaluatedMetadataValue;
                }
            }

            bucket.Lookup.ModifyItems(child.Name, group, metadataToSet);
        }
示例#5
0
        /// <summary>
        /// Remove items from the world. Removes to items that are part of the project manifest are backed up, so
        /// they can be reverted when the project is reset after the end of the build.
        /// </summary>
        private void ExecuteRemove(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            if (!Utilities.EvaluateCondition(child.Condition, child.ConditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext))
            {
                return;
            }

            BuildItemGroup group = bucket.Lookup.GetItems(child.Name);

            if (group == null)
            {
                // No items of this type to remove
                return;
            }

            List <BuildItem> itemsToRemove = BuildItemGroup.FindItemsMatchingSpecification(group, child.Remove, child.RemoveAttribute, bucket.Expander, executionDirectory);

            if (itemsToRemove != null)
            {
                bucket.Lookup.RemoveItems(itemsToRemove);
            }
        }
示例#6
0
        /// <summary>
        /// Creates an IntrinsicTask object around a "task" node
        /// </summary>
        internal IntrinsicTask(XmlElement taskNodeXmlElement, EngineLoggingServices loggingServices, BuildEventContext eventContext, string executionDirectory, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            this.taskNodeXmlElement    = taskNodeXmlElement;
            this.conditionAttribute    = taskNodeXmlElement.Attributes[XMakeAttributes.condition];
            this.loggingServices       = loggingServices;
            this.buildEventContext     = eventContext;
            this.executionDirectory    = executionDirectory;
            this.itemDefinitionLibrary = itemDefinitionLibrary;

            ErrorUtilities.VerifyThrow(IsIntrinsicTaskName(taskNodeXmlElement.Name), "Only PropertyGroup and ItemGroup are known intrinsic tasks");

            switch (taskNodeXmlElement.Name)
            {
            case XMakeElements.propertyGroup:
                backingType = BackingType.PropertyGroup;
                // If the backing type is a property group, we can just use a property group object; its semantics aren't
                // tangled up with the project object. Put another way, we only really need the code that understands the XML
                // format of a property group, and we can get that without the rest of BuildPropertyGroup getting in the way.
                // Specify that these properties are output properties, so they get reverted when the project is reset.
                backingPropertyGroup = new BuildPropertyGroup(null /* no parent project */, taskNodeXmlElement, PropertyType.OutputProperty);
                break;

            case XMakeElements.itemGroup:
                backingType = BackingType.ItemGroup;
                // If the backing type is an item group, we just re-use the code that understands the XML format of an item group;
                // the semantics of BuildItemGroup are too coupled to its current use in the Project object for us to re-use it.
                backingItemGroupXml = new BuildItemGroupXml(taskNodeXmlElement);
                List <XmlElement> children = backingItemGroupXml.GetChildren();
                backingBuildItemGroupChildren = new List <BuildItemGroupChildXml>(children.Count);

                foreach (XmlElement child in children)
                {
                    BuildItemGroupChildXml childXml = new BuildItemGroupChildXml(child, ChildType.Any);
                    backingBuildItemGroupChildren.Add(childXml);
                }
                break;
            }
        }
示例#7
0
        /// <summary>
        /// Creates an IntrinsicTask object around a "task" node
        /// </summary>
        internal IntrinsicTask(XmlElement taskNodeXmlElement, EngineLoggingServices loggingServices, BuildEventContext eventContext, string executionDirectory, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            this.taskNodeXmlElement = taskNodeXmlElement;
            this.conditionAttribute = taskNodeXmlElement.Attributes[XMakeAttributes.condition];
            this.loggingServices = loggingServices;
            this.buildEventContext = eventContext;
            this.executionDirectory = executionDirectory;
            this.itemDefinitionLibrary = itemDefinitionLibrary;
            
            ErrorUtilities.VerifyThrow(IsIntrinsicTaskName(taskNodeXmlElement.Name), "Only PropertyGroup and ItemGroup are known intrinsic tasks");

            switch (taskNodeXmlElement.Name)
            {
                case XMakeElements.propertyGroup:
                    backingType = BackingType.PropertyGroup;
                    // If the backing type is a property group, we can just use a property group object; its semantics aren't
                    // tangled up with the project object. Put another way, we only really need the code that understands the XML
                    // format of a property group, and we can get that without the rest of BuildPropertyGroup getting in the way.
                    // Specify that these properties are output properties, so they get reverted when the project is reset.
                    backingPropertyGroup = new BuildPropertyGroup(null /* no parent project */, taskNodeXmlElement, PropertyType.OutputProperty);
                    break;
                case XMakeElements.itemGroup:
                    backingType = BackingType.ItemGroup;
                    // If the backing type is an item group, we just re-use the code that understands the XML format of an item group;
                    // the semantics of BuildItemGroup are too coupled to its current use in the Project object for us to re-use it.
                    backingItemGroupXml = new BuildItemGroupXml(taskNodeXmlElement);
                    List<XmlElement> children = backingItemGroupXml.GetChildren();
                    backingBuildItemGroupChildren = new List<BuildItemGroupChildXml>(children.Count);

                    foreach (XmlElement child in children)
                    {
                        BuildItemGroupChildXml childXml = new BuildItemGroupChildXml(child, ChildType.Any);
                        backingBuildItemGroupChildren.Add(childXml);
                    }
                    break;
            }
        }
        public void ParseModify()
        {
            XmlDocument doc = new XmlDocument();
            XmlElement element = doc.CreateElement("i", XMakeAttributes.defaultXmlNamespace);
            BuildItemGroupChildXml child = new BuildItemGroupChildXml(element, ChildType.BuildItemModify);

            Assertion.AssertEquals(ChildType.BuildItemModify, child.ChildType);
        }
 public void RemoveAttributeMissing()
 {
     XmlDocument doc = new XmlDocument();
     XmlElement element = doc.CreateElement("i", XMakeAttributes.defaultXmlNamespace);
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(element, ChildType.BuildItemRemove);
 }
 public void InvalidlyNamedMetadata()
 {
     XmlElement xml = XmlTestUtilities.CreateBasicElementWithOneAttribute("i", "Include", "i1");
     XmlElement child1 = xml.OwnerDocument.CreateElement("m", XMakeAttributes.defaultXmlNamespace);
     XmlElement child2 = xml.OwnerDocument.CreateElement("Filename", XMakeAttributes.defaultXmlNamespace);
     xml.AppendChild(child1);
     xml.AppendChild(child2);
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemAdd);
 }
示例#11
0
        /// <summary>
        /// Remove items from the world. Removes to items that are part of the project manifest are backed up, so 
        /// they can be reverted when the project is reset after the end of the build.
        /// </summary>
        private void ExecuteRemove(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            if (!Utilities.EvaluateCondition(child.Condition, child.ConditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext))
            {
                return;
            }

            BuildItemGroup group = bucket.Lookup.GetItems(child.Name);
            if (group == null)
            {
                // No items of this type to remove
                return;
            }

            List<BuildItem> itemsToRemove = BuildItemGroup.FindItemsMatchingSpecification(group, child.Remove, child.RemoveAttribute, bucket.Expander, executionDirectory);

            if (itemsToRemove != null)
            {
                bucket.Lookup.RemoveItems(itemsToRemove);
            }
        }
 public void InvalidExcludeWithoutInclude()
 {
     XmlElement xml = XmlTestUtilities.CreateBasicElementWithOneAttribute("i", "Exclude", "i1");
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemAdd);
 }
 public void ExpectModifyGetRemove()
 {
     XmlElement xml = XmlTestUtilities.CreateBasicElementWithOneAttribute("i", "Remove", "i1"); ;
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemModify);
 }
 public void ExpectAddGetRemove()
 {
     XmlElement xml = CreateBasicRemoveElement();
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemAdd);
 }
示例#15
0
        /// <summary>
        /// Adds batchable parameters from an item element into the list. If the item element was a task, these
        /// would be its raw parameter values.
        /// </summary>
        private void GetBatchableValuesFromBuildItemGroupChild(List<string> parameterValues, BuildItemGroupChildXml child)
        {
            AddIfNotEmptyString(parameterValues, child.Include);
            AddIfNotEmptyString(parameterValues, child.Exclude);
            AddIfNotEmptyString(parameterValues, child.Remove);
            AddIfNotEmptyString(parameterValues, child.Condition);

            List<XmlElement> metadataElements = child.GetChildren();
            foreach (XmlElement metadataElement in metadataElements)
            {
                AddIfNotEmptyString(parameterValues, Utilities.GetXmlNodeInnerContents(metadataElement));
                XmlAttribute conditionAttribute = metadataElement.Attributes[XMakeAttributes.condition];
                if (conditionAttribute != null)
                {
                    AddIfNotEmptyString(parameterValues, conditionAttribute.Value);
                }
            }
        }
示例#16
0
        /// <summary>
        /// Modifies items in the world - specifically, changes their metadata. Changes to items that are part of the project manifest are backed up, so 
        /// they can be reverted when the project is reset after the end of the build.
        /// </summary>
        /// <param name="child"></param>
        /// <param name="bucket"></param>
        private void ExecuteModify(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            if (!Utilities.EvaluateCondition(child.Condition, child.ConditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext))
            {
                return;
            }

            BuildItemGroup group = (BuildItemGroup)bucket.Lookup.GetItems(child.Name);
            if (group == null)
            {
                // No items of this type to modify
                return;
            }

            // Figure out what metadata names and values we need to set
            Dictionary<string, string> metadataToSet = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

            List<XmlElement> metadataElements = child.GetChildren();
            foreach (XmlElement metadataElement in metadataElements)
            {
                bool metadataCondition = true;
                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(metadataElement, true /*no other attributes allowed*/);

                if (conditionAttribute != null)
                {
                    metadataCondition = Utilities.EvaluateCondition(conditionAttribute.Value, conditionAttribute, bucket.Expander, ParserOptions.AllowAll, loggingServices, buildEventContext);
                }

                if (metadataCondition)
                {
                    string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(metadataElement);
                    string evaluatedMetadataValue = bucket.Expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, metadataElement);
                    // The last metadata with a particular name, wins, so we just set through the indexer here.
                    metadataToSet[metadataElement.Name] = evaluatedMetadataValue;
                }
            }

            bucket.Lookup.ModifyItems(child.Name, group, metadataToSet);
        }
示例#17
0
        /// <summary>
        /// Adds batchable parameters from an item element into the list. If the item element was a task, these
        /// would be its raw parameter values.
        /// </summary>
        private void GetBatchableValuesFromBuildItemGroupChild(List <string> parameterValues, BuildItemGroupChildXml child)
        {
            AddIfNotEmptyString(parameterValues, child.Include);
            AddIfNotEmptyString(parameterValues, child.Exclude);
            AddIfNotEmptyString(parameterValues, child.Remove);
            AddIfNotEmptyString(parameterValues, child.Condition);

            List <XmlElement> metadataElements = child.GetChildren();

            foreach (XmlElement metadataElement in metadataElements)
            {
                AddIfNotEmptyString(parameterValues, Utilities.GetXmlNodeInnerContents(metadataElement));
                XmlAttribute conditionAttribute = metadataElement.Attributes[XMakeAttributes.condition];
                if (conditionAttribute != null)
                {
                    AddIfNotEmptyString(parameterValues, conditionAttribute.Value);
                }
            }
        }
示例#18
0
 /// <summary>
 /// Updates the build item xml backing store with the passed in xml backing store. 
 /// </summary>
 internal void UpdateBackingXml(BuildItemGroupChildXml backingXml)
 {
     xml =  backingXml;
     this.name = xml.Name;
 }
 public void ExpectRemoveGetAdd()
 {
     XmlElement xml = XmlTestUtilities.CreateBasicElementWithOneAttribute("i", "Include", "i1");;
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemRemove);
 }
示例#20
0
        /// <summary>
        /// Common code for constructors. If an ownerDocument is passed in, it's a persisted element.
        /// </summary>
        /// <param name="itemName">can be null</param>
        /// <param name="itemDefinitionLibrary">can only be null if ownerDocument is null</param>
        private void BuildItemHelper(XmlDocument ownerDocument, string itemName, string itemInclude, bool createCustomMetadataCache, ItemDefinitionLibrary itemDefinitionLibraryToUse)
        {
            // Only check for null. It's legal to make BuildItems with empty
            // item specs -- this is to be consistent with how we shipped TaskItem.
            // See #567058.
            ErrorUtilities.VerifyThrowArgumentNull(itemInclude, "itemInclude");

            // Validate that the item name doesn't contain any illegal characters.
            if (itemName != null)
            {
                XmlUtilities.VerifyThrowValidElementName(itemName);
                ErrorUtilities.VerifyThrowInvalidOperation(XMakeElements.IllegalItemPropertyNames[itemName] == null, "CannotModifyReservedItem", itemName);
            }

            // If no owner document was passed in, then it's not going to have an
            // XML element backing it.
            if (ownerDocument == null)
            {
                this.include = itemInclude;
                this.isPartOfProjectManifest = false;
            }
            else
            {
                ErrorUtilities.VerifyThrowArgumentLength(itemName, "itemType");
                MustHaveItemDefinitionLibrary(itemDefinitionLibraryToUse);

                // The caller has given us an owner document, so we're going to create a
                // new item element associated with that document.  The new item element
                // doesn't actually get added to the XML document automatically.
                this.xml = new BuildItemGroupChildXml(ownerDocument, itemName, itemInclude);
                this.isPartOfProjectManifest = true;
            }

            if (createCustomMetadataCache)
            {
                // PERF NOTE: only create cache if told to do so, because creating
                // this cache for a large number of items is expensive
                InitializeCustomMetadataCache();
            }

            this.name = itemName;

            // The evaluated and final item specs start off initialized to the "Include" attribute.
            this.evaluatedItemSpecEscaped = itemInclude;
            this.finalItemSpecEscaped = itemInclude;

            this.importedFromAnotherProject = false;
            this.itemDefinitionLibrary = itemDefinitionLibraryToUse;
        }
 public void InvalidIncludeAndRemoveTogether()
 {
     XmlElement xml = CreateBasicRemoveElement();
     xml.SetAttribute("Include", "i2");
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemRemove);
 }
示例#22
0
        /// <summary>
        /// Initializes a persisted item from an existing item element which exists either in the main project file or in one of
        /// the imported files.
        /// </summary>
        /// <param name="itemElementToParse"></param>
        private void InitializeFromItemElement(XmlElement element)
        {
            this.xml = new BuildItemGroupChildXml(element, ChildType.BuildItemAdd);

            this.name = xml.Name;
            this.itemSpecModifiers = null;
            this.recursivePortionOfFinalItemSpecDirectory = null;

            this.evaluatedItemSpecEscaped = xml.Include;
            this.finalItemSpecEscaped = xml.Include;

            InitializeCustomMetadataCache();
        }
 public void InvalidRemoveWithSomeMetadataChildren()
 {
     XmlElement xml = CreateBasicRemoveElement();
     XmlElement child1 = xml.OwnerDocument.CreateElement("m", XMakeAttributes.defaultXmlNamespace);
     child1.InnerText = "m1";
     xml.AppendChild(child1);
     BuildItemGroupChildXml child = new BuildItemGroupChildXml(xml, ChildType.BuildItemRemove);
 }
示例#24
0
        /// <summary>
        /// Add items to the world. This is the in-target equivalent of an item include expression outside of a target.
        /// </summary>
        private void ExecuteAdd(BuildItemGroupChildXml child, ItemBucket bucket)
        {
            // By making the items "not persisted", we ensure they are cleaned away when the project is reset
            BuildItem item = new BuildItem(child.Element, false /* not imported */, false /* not persisted */, itemDefinitionLibrary);

            // If the condition on the item is false, Evaluate returns an empty group
            BuildItemGroup itemsToAdd = item.Evaluate(bucket.Expander, executionDirectory, true /* expand metadata */, ParserOptions.AllowAll, loggingServices, buildEventContext);

            bucket.Lookup.AddNewItems(itemsToAdd);
        }