예제 #1
0
        /// <summary>
        /// Constructor for the When block.  Parses the contents of the When block (property
        /// groups, item groups, and nested chooses) and stores them.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <owner>DavidLe</owner>
        /// <param name="parentProject"></param>
        /// <param name="parentGroupingCollection"></param>
        /// <param name="whenElement"></param>
        /// <param name="importedFromAnotherProject"></param>
        /// <param name="options"></param>
        /// <param name="nestingDepth">stack overflow guard</param>
        internal When(
            Project parentProject,
            GroupingCollection parentGroupingCollection,
            XmlElement whenElement,
            bool importedFromAnotherProject,
            Options options,
            int nestingDepth
            )
        {
            // Make sure the <When> node has been given to us.
            error.VerifyThrow(whenElement != null, "Need valid (non-null) <When> element.");

            // Make sure this really is the <When> node.
            error.VerifyThrow(whenElement.Name == XMakeElements.when || whenElement.Name == XMakeElements.otherwise,
                              "Expected <{0}> or <{1}> element; received <{2}> element.",
                              XMakeElements.when, XMakeElements.otherwise, whenElement.Name);

            this.propertyAndItemLists = new GroupingCollection(parentGroupingCollection);
            this.parentProject        = parentProject;

            string elementName = ((options == Options.ProcessWhen) ? XMakeElements.when : XMakeElements.otherwise);

            if (options == Options.ProcessWhen)
            {
                conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(whenElement, /*verify sole attribute*/ true);
                ProjectErrorUtilities.VerifyThrowInvalidProject(conditionAttribute != null, whenElement, "MissingCondition", XMakeElements.when);
            }
            else
            {
                ProjectXmlUtilities.VerifyThrowProjectNoAttributes(whenElement);
            }

            ProcessWhenChildren(whenElement, parentProject, importedFromAnotherProject, nestingDepth);
        }
예제 #2
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates
            /// this specific item definition element and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definition is incorrectly defined</exception>
            private void EvaluateItemDefinitionElement(XmlElement itemDefinitionElement, BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(itemDefinitionElement);

                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(itemDefinitionElement, /* sole attribute */ true);
                string       condition          = ProjectXmlUtilities.GetAttributeValue(conditionAttribute);

                MetadataDictionary metadataDictionary = null;
                string             itemType           = itemDefinitionElement.Name;

                itemDefinitionsDictionary.TryGetValue(itemType, out metadataDictionary);

                Expander expander = new Expander(properties, itemType, metadataDictionary);

                if (!Utilities.EvaluateCondition(condition, conditionAttribute, expander, ParserOptions.AllowPropertiesAndItemMetadata, parentProject))
                {
                    return;
                }

                List <XmlElement> childElements = ProjectXmlUtilities.GetValidChildElements(itemDefinitionElement);

                foreach (XmlElement child in childElements)
                {
                    EvaluateItemDefinitionChildElement(child, properties, itemDefinitionsDictionary);
                }
            }
예제 #3
0
        /// <summary>
        /// BuildItemGroup element is provided
        /// </summary>
        internal BuildItemGroupXml(XmlElement element)
        {
            ErrorUtilities.VerifyThrowNoAssert(element != null, "Need a valid XML node.");
            ProjectXmlUtilities.VerifyThrowElementName(element, XMakeElements.itemGroup);

            this.element            = element;
            this.conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(element, true /*no other attributes allowed*/);
        }
예제 #4
0
            /// <summary>
            /// Read in and validate an &lt;ItemDefinitionGroup&gt; element and all its children.
            /// This is currently only called from ItemDefinitionLibrary. Projects don't know about it.
            /// </summary>
            internal BuildItemDefinitionGroupXml(XmlElement element, Project parentProject)
            {
                ProjectXmlUtilities.VerifyThrowElementName(element, XMakeElements.itemDefinitionGroup);
                ProjectXmlUtilities.VerifyThrowProjectValidNamespace(element);

                this.element            = element;
                this.parentProject      = parentProject;
                this.conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(element, /* sole attribute */ true);
                this.condition          = ProjectXmlUtilities.GetAttributeValue(conditionAttribute);

                // Currently, don't bother validating the children until evaluation time
            }
예제 #5
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates
            /// this specific item definition child element and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definition is incorrectly defined</exception>
            private void EvaluateItemDefinitionChildElement(XmlElement itemDefinitionChildElement, BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(itemDefinitionChildElement);
                ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.IsItemSpecModifier(itemDefinitionChildElement.Name), itemDefinitionChildElement, "ItemSpecModifierCannotBeCustomMetadata", itemDefinitionChildElement.Name);
                ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[itemDefinitionChildElement.Name] == null, itemDefinitionChildElement, "CannotModifyReservedItemMetadata", itemDefinitionChildElement.Name);

                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(itemDefinitionChildElement, /* sole attribute */ true);
                string       condition          = ProjectXmlUtilities.GetAttributeValue(conditionAttribute);

                MetadataDictionary metadataDictionary = null;
                string             itemType           = itemDefinitionChildElement.ParentNode.Name;

                itemDefinitionsDictionary.TryGetValue(itemType, out metadataDictionary);

                Expander expander = new Expander(properties, itemType, metadataDictionary);

                if (!Utilities.EvaluateCondition(condition, conditionAttribute, expander, ParserOptions.AllowPropertiesAndItemMetadata, parentProject))
                {
                    return;
                }

                string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(itemDefinitionChildElement);

                bool containsItemVector = ItemExpander.ExpressionContainsItemVector(unevaluatedMetadataValue);

                // We don't allow expressions like @(foo) in the value, as no items exist at this point.
                ProjectErrorUtilities.VerifyThrowInvalidProject(!containsItemVector, itemDefinitionChildElement, "MetadataDefinitionCannotContainItemVectorExpression", unevaluatedMetadataValue, itemDefinitionChildElement.Name);

                string evaluatedMetadataValue = expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, itemDefinitionChildElement);

                if (metadataDictionary == null)
                {
                    metadataDictionary = new MetadataDictionary(StringComparer.OrdinalIgnoreCase);
                    itemDefinitionsDictionary.Add(itemType, metadataDictionary);
                }

                // We only store the evaluated value; build items store the unevaluated value as well, but apparently only to
                // gather recursive portions (its re-evaluation always goes back to the XML).
                // Overwrite any existing default value for this particular metadata
                metadataDictionary[itemDefinitionChildElement.Name] = evaluatedMetadataValue;
            }
예제 #6
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);
        }