/// <summary> /// Read in and validate an <ItemDefinitionGroup> 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 }
/// <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; }