// Concat rules (deduced) // - ItemRef can concat only with a string ';' or PropertyRef ending in ';' // - MetadataRef can concat with anything other than ItemRef // - PropertyRef cannot be right after a ItemRef // PropertyRef concats if it doesn't end in ';' // - string cannot concat with ItemRef unless it is ';'. // string concats if it ends in ';' ITaskItem[] ConvertToITaskItemArray(Project project, ExpressionOptions options) { List <ITaskItem> finalItems = new List <ITaskItem> (); object prev = null; bool prev_can_concat = false; foreach (object o in objects) { bool can_concat = prev_can_concat; string str = o as string; if (str != null) { string trimmed_str = str.Trim(); if (!IsSemicolon(str) && trimmed_str.Length > 0 && prev != null && prev is ItemReference) { // non-empty, non-semicolon string after item ref ThrowCantConcatError(prev, str); } if (trimmed_str.Length == 0 && prev is string && IsSemicolon((string)prev)) { // empty string after a ';', ignore it continue; } // empty string _after_ a itemref, not an error prev_can_concat = !(str.Length > 0 && str [str.Length - 1] == ';') && trimmed_str.Length > 0; AddItemsToArray(finalItems, ConvertToITaskItemArrayFromString(str), can_concat); prev = o; continue; } IReference br = o as IReference; if (br == null) { throw new Exception("BUG: Invalid type in objects collection."); } if (o is ItemReference) { if (prev != null && !(prev is string && (string)prev == ";")) { ThrowCantConcatError(prev, br); } prev_can_concat = true; } else if (o is MetadataReference) { if (prev != null && prev is ItemReference) { ThrowCantConcatError(prev, br); } prev_can_concat = true; } else if (o is PropertyReference) { if (prev != null && prev is ItemReference) { ThrowCantConcatError(prev, br); } string value = ((PropertyReference)o).GetValue(project); prev_can_concat = !(value.Length > 0 && value [value.Length - 1] == ';'); } AddItemsToArray(finalItems, br.ConvertToITaskItemArray(project, options), can_concat); prev = o; } // Trim and Remove empty items List <ITaskItem> toRemove = new List <ITaskItem> (); for (int i = 0; i < finalItems.Count; i++) { string s = ((ITaskItem2)finalItems [i]).EvaluatedIncludeEscaped.Trim(); if (s.Length == 0) { toRemove.Add(finalItems [i]); } else { ((ITaskItem2)finalItems [i]).EvaluatedIncludeEscaped = s; } } foreach (ITaskItem ti in toRemove) { finalItems.Remove(ti); } return(finalItems.ToArray()); }