private void ProcessMetadataElements(ProjectItemElement itemElement, OperationBuilderWithMetadata operationBuilder) { if (itemElement.HasMetadata) { operationBuilder.Metadata.AddRange(itemElement.Metadata); var values = new List <string>(itemElement.Metadata.Count * 2); // Expand properties here, because a property may have a value which is an item reference (ie "@(Bar)"), and // if so we need to add the right item reference. foreach (var metadatumElement in itemElement.Metadata) { // Since we're just attempting to expand properties in order to find referenced items and not expanding metadata, // unexpected errors may occur when evaluating property functions on unexpanded metadata. Just ignore them if that happens. // See: https://github.com/Microsoft/msbuild/issues/3460 const ExpanderOptions expanderOptions = ExpanderOptions.ExpandProperties | ExpanderOptions.LeavePropertiesUnexpandedOnError; var valueWithPropertiesExpanded = _expander.ExpandIntoStringLeaveEscaped( metadatumElement.Value, expanderOptions, metadatumElement.Location); var conditionWithPropertiesExpanded = _expander.ExpandIntoStringLeaveEscaped( metadatumElement.Condition, expanderOptions, metadatumElement.ConditionLocation); values.Add(valueWithPropertiesExpanded); values.Add(conditionWithPropertiesExpanded); } var itemsAndMetadataFound = ExpressionShredder.GetReferencedItemNamesAndMetadata(values); if (itemsAndMetadataFound.Items != null) { foreach (var itemType in itemsAndMetadataFound.Items) { AddReferencedItemList(itemType, operationBuilder.ReferencedItemLists); } } } }
protected bool NeedToExpandMetadataForEachItem(ImmutableList <ProjectMetadataElement> metadata, out ItemsAndMetadataPair itemsAndMetadataFound) { List <string> values = new List <string>(metadata.Count * 2); foreach (var metadataElement in metadata) { values.Add(metadataElement.Value); values.Add(metadataElement.Condition); } itemsAndMetadataFound = ExpressionShredder.GetReferencedItemNamesAndMetadata(values); bool needToExpandMetadataForEachItem = false; if (itemsAndMetadataFound.Metadata != null && itemsAndMetadataFound.Metadata.Values.Count > 0) { // If there is bare metadata of any kind, and the Include involved an item list, we should // run items individually, as even non-built-in metadata might differ between items if (_referencedItemLists.Count >= 0) { needToExpandMetadataForEachItem = true; } else { // If there is bare built-in metadata, we must always run items individually, as that almost // always differs between items. // UNDONE: When batching is implemented for real, we need to make sure that // item definition metadata is included in all metadata operations during evaluation if (itemsAndMetadataFound.Metadata.Values.Count > 0) { needToExpandMetadataForEachItem = true; } } } return(needToExpandMetadataForEachItem); }