internal void Load (TaskDatabase db) { AssemblyLoadInfo loadInfo = null; if (AssemblyName != null) { loadInfo = new AssemblyLoadInfo (AssemblyName, TaskName); } else if (AssemblyFile != null) { Expression exp = new Expression (); // FIXME: test it exp.Parse (AssemblyFile, ParseOptions.Split); string filename = (string) exp.ConvertTo (project, typeof (string)); if (Path.IsPathRooted (filename) == false) { string ffn; if (importedProject != null) { ffn = Path.GetDirectoryName (importedProject.FullFileName); } else if (project.FullFileName != String.Empty) { ffn = Path.GetDirectoryName (project.FullFileName); } else { ffn = Environment.CurrentDirectory; } filename = Path.Combine (ffn, filename); } loadInfo = new AssemblyLoadInfo (LoadInfoType.AssemblyFilename, filename, null, null, null, null, TaskName); } db.RegisterTask (TaskName, loadInfo); }
public ItemReference (string original_string, string itemName, string transform, string separator, int start, int length) { this.itemName = itemName; this.start = start; this.length = length; this.original_string = original_string; // Transform and separator are never expanded for item refs if (transform != null) { this.transform = new Expression (); this.transform.Parse (transform, ParseOptions.AllowMetadata | ParseOptions.Split); } if (separator != null) { this.separator = new Expression (); this.separator.Parse (separator, ParseOptions.Split); } }
// In eval phase, any ref'ed item would've already been expanded // or it doesnt exist, so dont expand again // In non-eval, items have _already_ been expanded, so dont expand again // So, ignore @options internal ITaskItem[] ConvertToITaskItemArray (Expression transform, Expression separator, ExpressionOptions options) { if (separator != null) // separator present, so return as a single "join'ed" string return new ITaskItem [] { new TaskItem (ConvertToString (transform, separator, options)) }; ITaskItem[] array = new ITaskItem [buildItems.Count]; int i = 0; foreach (BuildItem item in buildItems) array [i++] = item.ConvertToITaskItem (transform, ExpressionOptions.DoNotExpandItemRefs); return array; }
// In eval phase, any ref'ed item would've already been expanded // or it doesnt exist, so dont expand again // In non-eval, items have _already_ been expanded, so dont expand again // So, ignore @options internal string ConvertToString (Expression transform, Expression separator, ExpressionOptions options) { string separatorString; // Item refs are not expanded for separator or transform if (separator == null) separatorString = ";"; else separatorString = (string) separator.ConvertTo (parentProject, typeof (string), ExpressionOptions.DoNotExpandItemRefs); string[] items = new string [buildItems.Count]; int i = 0; foreach (BuildItem bi in buildItems) items [i++] = bi.ConvertToString (transform, ExpressionOptions.DoNotExpandItemRefs); return String.Join (separatorString, items); }
void AddMetadata (string name, string value) { if (parent_item_group != null) { Expression e = new Expression (); e.Parse (value, ParseOptions.AllowItemsNoMetadataAndSplit); evaluatedMetadata [name] = (string) e.ConvertTo (parent_item_group.ParentProject, typeof (string), ExpressionOptions.ExpandItemRefs); } else evaluatedMetadata [name] = Utilities.Unescape (value); unevaluatedMetadata [name] = value; }
// during property's eval phase, this is never reached, as PropertyReference // handles the eval case // // during item's eval phase, we have expand: true, that's what we // do here.. // // during non-eval, expand: true // So, its always true here internal string ConvertToString (Project project, ExpressionOptions options) { if (converting) { // found ref to @this while trying to ConvertToString // for @this! return FinalValue; } converting = true; try { Expression exp = new Expression (); // in non-evaluation phase, properties are always expanded exp.Parse (FinalValue, options == ExpressionOptions.ExpandItemRefs ? ParseOptions.AllowItems : ParseOptions.None); return (string) exp.ConvertTo (project, typeof (string), options); } finally { converting = false; } }
string GetItemSpecFromTransform (Expression transform, ExpressionOptions options) { StringBuilder sb; if (transform == null) { if (options == ExpressionOptions.ExpandItemRefs) { // With usual code paths, this will never execute, // but letting this be here, incase BI.ConvertTo* // is called directly Expression expr = new Expression (); expr.Parse (finalItemSpec, ParseOptions.AllowItemsNoMetadataAndSplit); return (string) expr.ConvertTo (parent_item_group.ParentProject, typeof (string), ExpressionOptions.ExpandItemRefs); } else { return finalItemSpec; } } else { // Transform, _DONT_ expand itemrefs sb = new StringBuilder (); foreach (object o in transform.Collection) { if (o is string) { sb.Append ((string)o); } else if (o is PropertyReference) { sb.Append (((PropertyReference)o).ConvertToString ( parent_item_group.ParentProject, ExpressionOptions.DoNotExpandItemRefs)); } else if (o is ItemReference) { sb.Append (((ItemReference)o).ConvertToString ( parent_item_group.ParentProject, ExpressionOptions.DoNotExpandItemRefs)); } else if (o is MetadataReference) { sb.Append (GetMetadata (((MetadataReference)o).MetadataName)); } } return sb.ToString (); } }
// during item's eval phase, any item refs in this item, have either // already been expanded or are non-existant, so expand can be _false_ // // during prop's eval phase, this isn't reached, as it parses expressions // with allowItems=false, so no ItemReferences are created at all // // at other times, item refs have already been expanded, so expand: false internal string ConvertToString (Expression transform, ExpressionOptions options) { return GetItemSpecFromTransform (transform, options); }
void AddAndRemoveMetadata (Project project, BuildItem item) { if (!string.IsNullOrEmpty (removeMetadata)) { var removeExpr = new Expression (); removeExpr.Parse (removeMetadata, ParseOptions.AllowItemsNoMetadataAndSplit); var removeSpec = (string[]) removeExpr.ConvertTo ( project, typeof (string[]), ExpressionOptions.ExpandItemRefs); foreach (var remove in removeSpec) { item.DeleteMetadata (remove); } } if (!string.IsNullOrEmpty (keepMetadata)) { var keepExpr = new Expression (); keepExpr.Parse (keepMetadata, ParseOptions.AllowItemsNoMetadataAndSplit); var keepSpec = (string[]) keepExpr.ConvertTo ( project, typeof (string[]), ExpressionOptions.ExpandItemRefs); var metadataNames = new string [item.evaluatedMetadata.Count]; item.evaluatedMetadata.Keys.CopyTo (metadataNames, 0); foreach (string name in metadataNames) { if (!keepSpec.Contains (name)) item.DeleteMetadata (name); } } }
protected void ParseAttribute (string value) { Expression expr = new Expression (); expr.Parse (value, ParseOptions.AllowItemsMetadataAndSplit); foreach (object o in expr.Collection) { MetadataReference mr = o as MetadataReference; if (mr != null) { consumedMetadataReferences.Add (mr); if (mr.IsQualified) consumedQMetadataReferences.Add (mr); else consumedUQMetadataReferences.Add (mr); continue; } ItemReference ir = o as ItemReference; if (ir != null) { BuildItemGroup group; if (!project.TryGetEvaluatedItemByNameBatched (ir.ItemName, out group)) if (!project.EvaluatedItemsByName.TryGetValue (ir.ItemName, out group)) group = new BuildItemGroup (); consumedItemsByName [ir.ItemName] = group; } } }
List <Target> GetDependencies () { List <Target> list = new List <Target> (); Target t; string [] targetNames; Expression deps; if (DependsOnTargets != String.Empty) { deps = new Expression (); deps.Parse (DependsOnTargets, ParseOptions.AllowItemsNoMetadataAndSplit); targetNames = (string []) deps.ConvertTo (Project, typeof (string [])); foreach (string dep_name in targetNames) { t = project.Targets [dep_name.Trim ()]; if (t == null) throw new InvalidProjectFileException (String.Format ( "Target '{0}', a dependency of target '{1}', not found.", dep_name.Trim (), Name)); list.Add (t); } } return list; }
bool IBuildTask.ResolveOutputItems () { var taskEngine = new TaskEngine (parentTarget.Project, null, Type); taskEngine.PublishOutput (taskElement, l => { var pv = GetParameterValue (l.Name); Expression exp = new Expression (); exp.Parse (pv, ParseOptions.AllowItemsNoMetadataAndSplit); return exp.ConvertTo (parentTarget.Project, l.PropertyType); }); return true; }
bool BuildTargetNeeded () { ITaskItem [] inputFiles; ITaskItem [] outputFiles; DateTime oldestInput, youngestOutput; if (String.IsNullOrEmpty (inputs.Trim ())) return true; if (String.IsNullOrEmpty (outputs.Trim ())) return true; Expression e = new Expression (); e.Parse (inputs, ParseOptions.AllowItemsMetadataAndSplit); inputFiles = (ITaskItem[]) e.ConvertTo (project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); e = new Expression (); e.Parse (outputs, ParseOptions.AllowItemsMetadataAndSplit); outputFiles = (ITaskItem[]) e.ConvertTo (project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); if (inputFiles == null || inputFiles.Length == 0) return false; //FIXME: if input specified, then output must also // be there, add tests and confirm if (outputFiles == null || outputFiles.Length == 0) return false; if (File.Exists (inputFiles [0].ItemSpec)) oldestInput = File.GetLastWriteTime (inputFiles [0].ItemSpec); else return true; if (File.Exists (outputFiles [0].ItemSpec)) youngestOutput = File.GetLastWriteTime (outputFiles [0].ItemSpec); else return true; foreach (ITaskItem item in inputFiles) { string file = item.ItemSpec; if (file.Trim () == String.Empty) continue; if (File.Exists (file.Trim ())) { if (File.GetLastWriteTime (file.Trim ()) > oldestInput) oldestInput = File.GetLastWriteTime (file.Trim ()); } else { return true; } } foreach (ITaskItem item in outputFiles) { string file = item.ItemSpec; if (file.Trim () == String.Empty) continue; if (File.Exists (file.Trim ())) { if (File.GetLastWriteTime (file.Trim ()) < youngestOutput) youngestOutput = File.GetLastWriteTime (file.Trim ()); } else return true; } if (oldestInput > youngestOutput) return true; else return false; }
void AddMetadata (string name, string value) { var options = IsDynamic ? ParseOptions.AllowItemsMetadataAndSplit : ParseOptions.AllowItemsNoMetadataAndSplit; if (parent_item_group != null) { Expression e = new Expression (); e.Parse (value, options); evaluatedMetadata [name] = (string) e.ConvertTo (parent_item_group.ParentProject, typeof (string), ExpressionOptions.ExpandItemRefs); } else evaluatedMetadata [name] = MSBuildUtils.Unescape (value); unevaluatedMetadata [name] = value; }
// FIXME: in some situations items might not be allowed static Token EvaluateToken (Token token, Project context) { Expression oe = new Expression (); oe.Parse (token.Value, ParseOptions.AllowItemsMetadataAndSplit); return new Token ((string) oe.ConvertTo (context, typeof (string)), token.Type); }
internal void Evaluate (Project project, bool evaluatedTo) { // FIXME: maybe make Expression.ConvertTo (null, ...) work as MSBuildUtils.Unescape ()? if (project == null) { this.finalItemSpec = MSBuildUtils.Unescape (Include); return; } foreach (XmlNode xn in itemElement.ChildNodes) { XmlElement xe = xn as XmlElement; if (xe != null && ConditionParser.ParseAndEvaluate (xe.GetAttribute ("Condition"), project)) AddMetadata (xe.Name, xe.InnerText); } if (IsDynamic) { if (!evaluatedTo) return; if (!string.IsNullOrEmpty (Remove)) { RemoveItems (project); return; } if (string.IsNullOrEmpty (Include)) { UpdateMetadata (project); return; } } DirectoryScanner directoryScanner; Expression includeExpr, excludeExpr; ITaskItem[] includes, excludes; var options = IsDynamic ? ParseOptions.AllowItemsMetadataAndSplit : ParseOptions.AllowItemsNoMetadataAndSplit; includeExpr = new Expression (); includeExpr.Parse (Include, options); excludeExpr = new Expression (); excludeExpr.Parse (Exclude, options); includes = (ITaskItem[]) includeExpr.ConvertTo (project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); excludes = (ITaskItem[]) excludeExpr.ConvertTo (project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); this.finalItemSpec = (string) includeExpr.ConvertTo (project, typeof (string), ExpressionOptions.ExpandItemRefs); directoryScanner = new DirectoryScanner (); directoryScanner.Includes = includes; directoryScanner.Excludes = excludes; if (project.FullFileName != String.Empty) directoryScanner.BaseDirectory = new DirectoryInfo (Path.GetDirectoryName (project.FullFileName)); else directoryScanner.BaseDirectory = new DirectoryInfo (Directory.GetCurrentDirectory ()); directoryScanner.Scan (); foreach (ITaskItem matchedItem in directoryScanner.MatchedItems) AddEvaluatedItem (project, evaluatedTo, matchedItem); }
bool BuildTargetNeeded (out string reason, out bool skipCompletely) { reason = String.Empty; ITaskItem [] inputFiles; ITaskItem [] outputFiles; DateTime youngestInput, oldestOutput; skipCompletely = false; if (String.IsNullOrEmpty (inputs.Trim ())) { return true; } if (String.IsNullOrEmpty (outputs.Trim ())) { project.ParentEngine.LogError ("Target {0} has inputs but no outputs specified.", name); return true; } Expression e = new Expression (); e.Parse (inputs, ParseOptions.AllowItemsMetadataAndSplit); inputFiles = (ITaskItem[]) e.ConvertTo (project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); e = new Expression (); e.Parse (outputs, ParseOptions.AllowItemsMetadataAndSplit); outputFiles = (ITaskItem[]) e.ConvertTo (project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); if (outputFiles == null || outputFiles.Length == 0) { reason = String.Format ("No output files were specified for target {0}, skipping.", name); return false; } if (inputFiles == null || inputFiles.Length == 0) { skipCompletely = true; reason = String.Format ("No input files were specified for target {0}, skipping.", name); return false; } youngestInput = DateTime.MinValue; oldestOutput = DateTime.MaxValue; string youngestInputFile, oldestOutputFile; youngestInputFile = oldestOutputFile = String.Empty; foreach (ITaskItem item in inputFiles) { string file = item.ItemSpec.Trim (); if (file.Length == 0) continue; if (!File.Exists (file)) { reason = String.Format ("Target {0} needs to be built as input file '{1}' does not exist.", name, file); return true; } DateTime lastWriteTime = File.GetLastWriteTime (file); if (lastWriteTime > youngestInput) { youngestInput = lastWriteTime; youngestInputFile = file; } } foreach (ITaskItem item in outputFiles) { string file = item.ItemSpec.Trim (); if (file.Length == 0) continue; if (!File.Exists (file)) { reason = String.Format ("Target {0} needs to be built as output file '{1}' does not exist.", name, file); return true; } DateTime lastWriteTime = File.GetLastWriteTime (file); if (lastWriteTime < oldestOutput) { oldestOutput = lastWriteTime; oldestOutputFile = file; } } if (youngestInput > oldestOutput) { reason = String.Format ("Target {0} needs to be built as input file '{1}' is newer than output file '{2}'", name, youngestInputFile, oldestOutputFile); return true; } return false; }
void RemoveItems (Project project) { BuildItemGroup group; if (!project.TryGetEvaluatedItemByNameBatched (Name, out group)) return; var removeExpr = new Expression (); removeExpr.Parse (Remove, ParseOptions.AllowItemsNoMetadataAndSplit); var removes = (ITaskItem[]) removeExpr.ConvertTo ( project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs); var directoryScanner = new DirectoryScanner (); directoryScanner.Includes = removes; if (project.FullFileName != String.Empty) directoryScanner.BaseDirectory = new DirectoryInfo (Path.GetDirectoryName (project.FullFileName)); else directoryScanner.BaseDirectory = new DirectoryInfo (Directory.GetCurrentDirectory ()); directoryScanner.Scan (); foreach (ITaskItem matchedItem in directoryScanner.MatchedItems) { group.RemoveItem (matchedItem); } }
// returns true, if the @result should be included in the values list bool TryGetObjectFromString (string raw, Type type, out object result) { Expression e; result = null; e = new Expression (); e.Parse (raw, ParseOptions.AllowItemsMetadataAndSplit); // See rules in comment for 'Prepare' string str = (string) e.ConvertTo (parentProject, typeof (string)); if (!type.IsArray && str == String.Empty) return false; if (str.Trim ().Length == 0 && type.IsArray && (type.GetElementType () == typeof (string) || type.GetElementType () == typeof (ITaskItem))) return true; result = e.ConvertTo (parentProject, type, ExpressionOptions.ExpandItemRefs); return true; }
internal ITaskItem ConvertToITaskItem (Expression transform, ExpressionOptions options) { TaskItem taskItem; taskItem = new TaskItem (GetItemSpecFromTransform (transform, options), evaluatedMetadata); return taskItem; }
string EvaluatePath (string path) { var exp = new Expression (); exp.Parse (path, ParseOptions.Split); return (string) exp.ConvertTo (project, typeof (string)); }
internal void Evaluate () { BuildProperty evaluated = new BuildProperty (Name, Value); // In evaluate phase, properties are not expanded Expression exp = new Expression (); exp.Parse (Value, ParseOptions.None); evaluated.finalValue = (string) exp.ConvertTo (parentProject, typeof (string), ExpressionOptions.DoNotExpandItemRefs); parentProject.EvaluatedProperties.AddProperty (evaluated); }
bool BuildDependencies (out bool executeOnErrors) { executeOnErrors = false; if (String.IsNullOrEmpty (DependsOnTargets)) return true; var expr = new Expression (); expr.Parse (DependsOnTargets, ParseOptions.AllowItemsNoMetadataAndSplit); string [] targetNames = (string []) expr.ConvertTo (Project, typeof (string [])); bool result = BuildOtherTargets (targetNames, tname => engine.LogError ("Target '{0}', a dependency of target '{1}', not found.", tname, Name), out executeOnErrors); if (!result && executeOnErrors) ExecuteOnErrors (); return result; }
internal ITaskItem[] ConvertToITaskItemArray (Project project, ExpressionOptions options) { if (converting) { // found ref to @this while trying to ConvertToITaskItemArray // for @this! ITaskItem []items = new ITaskItem [1]; items [0] = new TaskItem (FinalValue); return items; } converting = true; try { Expression exp = new Expression (); // in non-evaluation phase, properties are always expanded exp.Parse (FinalValue, ParseOptions.Split | (options == ExpressionOptions.ExpandItemRefs ? ParseOptions.AllowItems : ParseOptions.None)); return (ITaskItem[]) exp.ConvertTo (project, typeof (ITaskItem[]), options); } finally { converting = false; } }
string EvaluateProjectPath (string file) { Expression exp; exp = new Expression (); exp.Parse (file, ParseOptions.Split); return (string) exp.ConvertTo (project, typeof (string)); }