/// <summary> /// Constructor, which captures the hashtable of items to use when expanding the item reference. /// </summary> private ItemExpander ( XmlNode parentNode, ReadOnlyLookup readOnlyLookup ) { this.parentNode = parentNode; this.readOnlyLookup = readOnlyLookup; }
/// <summary> /// Attempts to extract the items in the given item vector. Item vectors embedded in strings, and item vectors with /// separator specifications are considered invalid, because it is not clear if those item vectors are meant to be lists /// or strings -- if the latter, the ExpandEmbeddedItemVectors() method should be used instead. /// </summary> /// <owner>SumedhK;RGoel</owner> /// <param name="itemVectorExpression"></param> /// <param name="parentNode"></param> /// <param name="itemsByType"></param> /// <returns>a virtual BuildItemGroup containing the items resulting from the expression, or null if the expression was invalid.</returns> internal static BuildItemGroup ItemizeItemVector ( string itemVectorExpression, XmlNode parentNode, ReadOnlyLookup readOnlyLookup ) { Match throwAwayMatch; return(ItemExpander.ItemizeItemVector(itemVectorExpression, parentNode, readOnlyLookup, out throwAwayMatch)); }
/// <summary> /// Attempts to extract the items in the given item vector expression. Item vectors embedded in strings, /// and item vectors with separator specifications are considered invalid, because it is not clear /// if those item vectors are meant to be lists or strings -- if the latter, the ExpandEmbeddedItemVectors() /// method should be used instead. /// </summary> /// <param name="itemVectorExpression"></param> /// <param name="parentNode"></param> /// <param name="readOnlyLookup"></param> /// <param name="itemVectorMatch"></param> /// <returns>a virtual BuildItemGroup containing the items resulting from the expression, or null if the expression was invalid.</returns> /// <owner>SumedhK;RGoel</owner> internal static BuildItemGroup ItemizeItemVector ( string itemVectorExpression, XmlNode parentNode, ReadOnlyLookup readOnlyLookup, out Match itemVectorMatch ) { itemVectorMatch = null; BuildItemGroup items = null; itemVectorMatch = GetItemVectorMatches(itemVectorExpression); if (itemVectorMatch?.Success == true) { // The method above reports a match if there are any // valid @(itemlist) references in the given expression. // If the passed-in expression contains exactly one item list reference, // with nothing else concatenated to the beginning or end, then proceed // with itemizing it, otherwise error. ProjectErrorUtilities.VerifyThrowInvalidProject(itemVectorMatch.Value == itemVectorExpression, parentNode, "EmbeddedItemVectorCannotBeItemized", itemVectorExpression); ItemExpander itemExpander = new ItemExpander(parentNode, readOnlyLookup); // If the reference contains a separator, we need to flatten the list into a scalar and then create // an item group with a single item. This is necessary for VSWhidbey 525917 - basically we need this // to be able to convert item lists with user specified separators into properties. if (itemVectorMatch.Groups["SEPARATOR_SPECIFICATION"].Length > 0) { string expandedItemVector = itemExpander.ExpandItemVector(itemVectorMatch); string itemType = itemVectorMatch.Groups["TYPE"].Value; items = new BuildItemGroup(); if (expandedItemVector.Length > 0) { items.AddNewItem(itemType, expandedItemVector); } } else { items = itemExpander.ItemizeItemVector(itemVectorMatch); } ErrorUtilities.VerifyThrow(items != null, "ItemizeItemVector shouldn't give us null."); } return(items); }
/// <summary> /// Expands all item vectors embedded in the given string. /// </summary> /// <owner>SumedhK</owner> /// <param name="s"></param> /// <param name="parentNode"></param> /// <param name="itemsByType"></param> /// <returns>Given string, with embedded item vectors expanded.</returns> internal static string ExpandEmbeddedItemVectors(string s, XmlNode parentNode, ReadOnlyLookup readOnlyLookup) { // Before we do the expensive RegEx stuff, at least make sure there's // an @ sign in the expression somewhere. If not, skip all the hard work. if (s.IndexOf('@') != -1) { ItemExpander itemExpander = new ItemExpander(parentNode, readOnlyLookup); return(itemVectorPattern.Replace(s, new MatchEvaluator(itemExpander.ExpandItemVector))); } else { return(s); } }
// Used by ItemBucket internal Expander(ReadOnlyLookup lookup, Dictionary<string, string> itemMetadata) : this(lookup, itemMetadata, ExpanderOptions.ExpandAll) { }
// Used by unit tests internal Expander(ReadOnlyLookup lookup, Dictionary<string, string> itemMetadata, ExpanderOptions options) { ErrorUtilities.VerifyThrow(options != ExpanderOptions.Invalid, "Must specify options"); this.lookup = lookup; this.itemMetadata = itemMetadata; this.options = options; }
// Used by IntrinsicTask internal Expander(ReadOnlyLookup lookup) : this(lookup, null, ExpanderOptions.ExpandPropertiesAndItems) { }
/// <summary> /// Creates a set of complicated item metadata and properties, and items to exercise /// the Expander class. The data here contains escaped characters, metadata that /// references properties, properties that reference items, and other complex scenarios. /// </summary> /// <param name="pg"></param> /// <param name="primaryItemsByName"></param> /// <param name="secondaryItemsByName"></param> /// <param name="itemMetadata"></param> /// <owner>RGoel</owner> private void CreateComplexPropertiesItemsMetadata ( out ReadOnlyLookup readOnlyLookup, out Dictionary<string, string> itemMetadata ) { itemMetadata = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); itemMetadata["Culture"] = "abc%253bdef;$(Gee_Aych_Ayee)"; itemMetadata["Language"] = "english"; BuildPropertyGroup pg = new BuildPropertyGroup(); pg.SetProperty("Gee_Aych_Ayee", "ghi"); pg.SetProperty("OutputPath", @"\jk ; l\mno%253bpqr\stu"); pg.SetProperty("TargetPath", "@(IntermediateAssembly->'%(RelativeDir)')"); BuildItemGroup intermediateAssemblyItemGroup = new BuildItemGroup(); BuildItem i1 = intermediateAssemblyItemGroup.AddNewItem("IntermediateAssembly", @"subdir1\engine.dll"); i1.SetMetadata("aaa", "111"); BuildItem i2 = intermediateAssemblyItemGroup.AddNewItem("IntermediateAssembly", @"subdir2\tasks.dll"); i2.SetMetadata("bbb", "222"); BuildItemGroup contentItemGroup = new BuildItemGroup(); BuildItem i3 = contentItemGroup.AddNewItem("Content", "splash.bmp"); i3.SetMetadata("ccc", "333"); BuildItemGroup resourceItemGroup = new BuildItemGroup(); BuildItem i4 = resourceItemGroup.AddNewItem("Resource", "string$(p).resx"); i4.SetMetadata("ddd", "444"); BuildItem i5 = resourceItemGroup.AddNewItem("Resource", "dialogs%253b.resx"); i5.SetMetadata("eee", "555"); BuildItemGroup contentItemGroup2 = new BuildItemGroup(); BuildItem i6 = contentItemGroup2.AddNewItem("Content", "about.bmp"); i6.SetMetadata("fff", "666"); Hashtable secondaryItemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase); secondaryItemsByName["Resource"] = resourceItemGroup; secondaryItemsByName["Content"] = contentItemGroup2; Lookup lookup = LookupHelpers.CreateLookup(pg, secondaryItemsByName); // Add primary items lookup.EnterScope(); lookup.PopulateWithItems("IntermediateAssembly", intermediateAssemblyItemGroup); lookup.PopulateWithItems("Content", contentItemGroup); readOnlyLookup = new ReadOnlyLookup(lookup); }
/// <summary> /// Attempts to extract the items in the given item vector expression. Item vectors embedded in strings, /// and item vectors with separator specifications are considered invalid, because it is not clear /// if those item vectors are meant to be lists or strings -- if the latter, the ExpandEmbeddedItemVectors() /// method should be used instead. /// </summary> /// <param name="itemVectorExpression"></param> /// <param name="parentNode"></param> /// <param name="readOnlyLookup"></param> /// <param name="itemVectorMatch"></param> /// <returns>a virtual BuildItemGroup containing the items resulting from the expression, or null if the expression was invalid.</returns> /// <owner>SumedhK;RGoel</owner> internal static BuildItemGroup ItemizeItemVector ( string itemVectorExpression, XmlNode parentNode, ReadOnlyLookup readOnlyLookup, out Match itemVectorMatch ) { itemVectorMatch = null; BuildItemGroup items = null; itemVectorMatch = GetItemVectorMatches(itemVectorExpression); if (itemVectorMatch != null && itemVectorMatch.Success) { // The method above reports a match if there are any // valid @(itemlist) references in the given expression. // If the passed-in expression contains exactly one item list reference, // with nothing else concatenated to the beginning or end, then proceed // with itemizing it, otherwise error. ProjectErrorUtilities.VerifyThrowInvalidProject(itemVectorMatch.Value == itemVectorExpression, parentNode, "EmbeddedItemVectorCannotBeItemized", itemVectorExpression); ItemExpander itemExpander = new ItemExpander(parentNode, readOnlyLookup); // If the reference contains a separator, we need to flatten the list into a scalar and then create // an item group with a single item. This is necessary for VSWhidbey 525917 - basically we need this // to be able to convert item lists with user specified separators into properties. if (itemVectorMatch.Groups["SEPARATOR_SPECIFICATION"].Length > 0) { string expandedItemVector = itemExpander.ExpandItemVector(itemVectorMatch); string itemType = itemVectorMatch.Groups["TYPE"].Value; items = new BuildItemGroup(); if (expandedItemVector.Length > 0) { items.AddNewItem(itemType, expandedItemVector); } } else { items = itemExpander.ItemizeItemVector(itemVectorMatch); } ErrorUtilities.VerifyThrow(items != null, "ItemizeItemVector shouldn't give us null."); } return items; }
/// <summary> /// Attempts to extract the items in the given item vector. Item vectors embedded in strings, and item vectors with /// separator specifications are considered invalid, because it is not clear if those item vectors are meant to be lists /// or strings -- if the latter, the ExpandEmbeddedItemVectors() method should be used instead. /// </summary> /// <owner>SumedhK;RGoel</owner> /// <param name="itemVectorExpression"></param> /// <param name="parentNode"></param> /// <param name="itemsByType"></param> /// <returns>a virtual BuildItemGroup containing the items resulting from the expression, or null if the expression was invalid.</returns> internal static BuildItemGroup ItemizeItemVector ( string itemVectorExpression, XmlNode parentNode, ReadOnlyLookup readOnlyLookup ) { Match throwAwayMatch; return ItemExpander.ItemizeItemVector(itemVectorExpression, parentNode, readOnlyLookup, out throwAwayMatch); }
/// <summary> /// Expands all item vectors embedded in the given string. /// </summary> /// <owner>SumedhK</owner> /// <param name="s"></param> /// <param name="parentNode"></param> /// <param name="itemsByType"></param> /// <returns>Given string, with embedded item vectors expanded.</returns> internal static string ExpandEmbeddedItemVectors(string s, XmlNode parentNode, ReadOnlyLookup readOnlyLookup) { // Before we do the expensive RegEx stuff, at least make sure there's // an @ sign in the expression somewhere. If not, skip all the hard work. if (s.IndexOf('@') != -1) { ItemExpander itemExpander = new ItemExpander(parentNode, readOnlyLookup); return itemVectorPattern.Replace(s, new MatchEvaluator(itemExpander.ExpandItemVector)); } else { return s; } }