public static ConditionExpression ParseCondition (string condition) { ConditionParser parser = new ConditionParser (condition); ConditionExpression e = parser.ParseExpression (); if (!parser.tokenizer.IsEOF ()) throw new ExpressionParseException (String.Format ("Unexpected token at end of condition: \"{0}\"", parser.tokenizer.Token.Value)); return e; }
public static ConditionExpression ParseCondition (string condition) { ConditionParser parser = new ConditionParser (condition); ConditionExpression e = parser.ParseExpression (); if (!parser.tokenizer.IsEOF ()) throw new ExpressionParseException (String.Format ("Unexpected token found, {0}, in condition \"{1}\"", parser.tokenizer.Token, condition)); return e; }
public void PublishOutput() { XmlElement xmlElement; PropertyInfo propertyInfo; string propertyName; string taskParameter; string itemName; object o; foreach (XmlNode xmlNode in taskElement.ChildNodes) { if (!(xmlNode is XmlElement)) { continue; } xmlElement = (XmlElement)xmlNode; if (xmlElement.Name != "Output") { throw new InvalidProjectFileException("Only Output elements can be Task's child nodes."); } if (xmlElement.GetAttribute("ItemName") != String.Empty && xmlElement.GetAttribute("PropertyName") != String.Empty) { throw new InvalidProjectFileException("Only one of ItemName and PropertyName attributes can be specified."); } if (xmlElement.GetAttribute("TaskParameter") == String.Empty) { throw new InvalidProjectFileException("TaskParameter attribute must be specified."); } if (!ConditionParser.ParseAndEvaluate(xmlElement.GetAttribute("Condition"), parentProject)) { continue; } taskParameter = xmlElement.GetAttribute("TaskParameter"); itemName = xmlElement.GetAttribute("ItemName"); propertyName = xmlElement.GetAttribute("PropertyName"); propertyInfo = taskType.GetProperty(taskParameter, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (propertyInfo == null) { throw new InvalidProjectFileException(String.Format( "The parameter '{0}' was not found for the '{1}' task.", taskParameter, taskElement.Name)); } if (!propertyInfo.IsDefined(outputAttribute, false)) { throw new InvalidProjectFileException("This is not output property."); } o = propertyInfo.GetValue(task, null); if (itemName != String.Empty) { PublishItemGroup(propertyInfo, o, itemName); } else { PublishProperty(propertyInfo, o, propertyName); } } }
// For every extension path, in order, finds suitable // import filename(s) matching the Import, and calls // @func with them // // func: bool func(importPath, from_source_msg) // // If for an extension path, atleast one file gets imported, // then it stops at that. // So, in case imports like "$(MSBuildExtensionsPath)\foo\*", // for every extension path, it will try to import the "foo\*", // and if atleast one file gets successfully imported, then it // stops at that internal static void ForEachExtensionPathTillFound(XmlElement xmlElement, Project project, ImportedProject importingProject, Func <string, string, bool> func) { string project_attribute = xmlElement.GetAttribute("Project"); string condition_attribute = xmlElement.GetAttribute("Condition"); bool has_extn_ref = project_attribute.IndexOf("$(MSBuildExtensionsPath)") >= 0 || project_attribute.IndexOf("$(MSBuildExtensionsPath32)") >= 0 || project_attribute.IndexOf("$(MSBuildExtensionsPath64)") >= 0; string importingFile = importingProject != null ? importingProject.FullFileName : project.FullFileName; DirectoryInfo base_dir_info = null; if (!String.IsNullOrEmpty(importingFile)) { base_dir_info = new DirectoryInfo(Path.GetDirectoryName(importingFile)); } else { base_dir_info = new DirectoryInfo(Directory.GetCurrentDirectory()); } IEnumerable <string> extn_paths = has_extn_ref ? GetExtensionPaths(project) : new string [] { null }; try { foreach (string path in extn_paths) { string extn_msg = null; if (has_extn_ref) { project.SetExtensionsPathProperties(path); extn_msg = "from extension path " + path; } // do this after setting new Extension properties, as condition might // reference it if (!ConditionParser.ParseAndEvaluate(condition_attribute, project)) { continue; } // We stop if atleast one file got imported. // Remaining extension paths are *not* tried bool atleast_one = false; foreach (string importPath in GetImportPathsFromString(project_attribute, project, base_dir_info)) { try { if (func(importPath, extn_msg)) { atleast_one = true; } } catch (Exception e) { throw new InvalidProjectFileException(String.Format( "{0}: Project file could not be imported, it was being imported by " + "{1}: {2}", importPath, importingFile, e.Message), e); } } if (atleast_one) { return; } } } finally { if (has_extn_ref) { project.SetExtensionsPathProperties(Project.DefaultExtensionsPath); } } }
internal void Evaluate(EvaluationType type) { BuildItemGroup big; BuildPropertyGroup bpg; LinkedListNode <object> evaluate_iterator; if (type == EvaluationType.Property) { evaluate_iterator = list.First; add_iterator = list.First; while (evaluate_iterator != null) { if (evaluate_iterator.Value is BuildPropertyGroup) { bpg = (BuildPropertyGroup)evaluate_iterator.Value; if (ConditionParser.ParseAndEvaluate(bpg.Condition, project)) { bpg.Evaluate(); } } // if it wasn't moved by adding anything because of evaluating a Import shift it if (add_iterator == evaluate_iterator) { add_iterator = add_iterator.Next; } evaluate_iterator = evaluate_iterator.Next; } } else if (type == EvaluationType.Item) { evaluate_iterator = list.First; add_iterator = list.First; while (evaluate_iterator != null) { if (evaluate_iterator.Value is BuildItemGroup) { big = (BuildItemGroup)evaluate_iterator.Value; if (ConditionParser.ParseAndEvaluate(big.Condition, project)) { big.Evaluate(); } } evaluate_iterator = evaluate_iterator.Next; } } else if (type == EvaluationType.Choose) { evaluate_iterator = list.First; add_iterator = list.First; while (evaluate_iterator != null) { if (evaluate_iterator.Value is BuildChoose) { BuildChoose bc = (BuildChoose)evaluate_iterator.Value; bool whenUsed = false; foreach (BuildWhen bw in bc.Whens) { if (ConditionParser.ParseAndEvaluate(bw.Condition, project)) { bw.Evaluate(); whenUsed = true; break; } } if (!whenUsed && bc.Otherwise != null && ConditionParser.ParseAndEvaluate(bc.Otherwise.Condition, project)) { bc.Otherwise.Evaluate(); } } evaluate_iterator = evaluate_iterator.Next; } } add_iterator = null; }
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); } }
// For every extension path, in order, finds suitable // import filename(s) matching the Import, and calls // @func with them // // func: bool func(importPath, from_source_msg) // // If for an extension path, atleast one file gets imported, // then it stops at that. // So, in case imports like "$(MSBuildExtensionsPath)\foo\*", // for every extension path, it will try to import the "foo\*", // and if atleast one file gets successfully imported, then it // stops at that internal static void ForEachExtensionPathTillFound(XmlElement xmlElement, Project project, ImportedProject importingProject, Func <string, string, bool> func) { string project_attribute = xmlElement.GetAttribute("Project"); string condition_attribute = xmlElement.GetAttribute("Condition"); bool has_extn_ref = project_attribute.IndexOf("$(MSBuildExtensionsPath)") >= 0 || project_attribute.IndexOf("$(MSBuildExtensionsPath32)") >= 0 || project_attribute.IndexOf("$(MSBuildExtensionsPath64)") >= 0; bool condn_has_extn_ref = condition_attribute.IndexOf("$(MSBuildExtensionsPath)") >= 0 || condition_attribute.IndexOf("$(MSBuildExtensionsPath32)") >= 0 || condition_attribute.IndexOf("$(MSBuildExtensionsPath64)") >= 0; // we can skip the following logic in case the condition doesn't reference any extension paths // and it evaluates to false since nothing would change anyway if (!condn_has_extn_ref && !ConditionParser.ParseAndEvaluate(condition_attribute, project)) { return; } string importingFile = importingProject != null ? importingProject.FullFileName : project.FullFileName; DirectoryInfo base_dir_info = null; if (!String.IsNullOrEmpty(importingFile)) { base_dir_info = new DirectoryInfo(Path.GetDirectoryName(importingFile)); } else { base_dir_info = new DirectoryInfo(Directory.GetCurrentDirectory()); } var importPaths = GetImportPathsFromString(project_attribute, project, base_dir_info); var extensionPaths = GetExtensionPaths(project); if (!has_extn_ref) { foreach (var importPath in importPaths) { foreach (var extensionPath in extensionPaths) { has_extn_ref = has_extn_ref || importPath.IndexOf(extensionPath) >= 0; } } } IEnumerable <string> extn_paths = has_extn_ref ? extensionPaths : new string [] { null }; bool import_needed = false; var currentLoadSettings = project.ProjectLoadSettings; try { foreach (var settings in new ProjectLoadSettings [] { ProjectLoadSettings.None, currentLoadSettings }) { foreach (string path in extn_paths) { string extn_msg = null; if (has_extn_ref) { project.SetExtensionsPathProperties(path); extn_msg = "from extension path " + path; } // do this after setting new Extension properties, as condition might // reference it if (!ConditionParser.ParseAndEvaluate(condition_attribute, project)) { continue; } import_needed = true; project.ProjectLoadSettings = settings; // We stop if atleast one file got imported. // Remaining extension paths are *not* tried bool atleast_one = false; foreach (string importPath in importPaths) { try { if (func(importPath, extn_msg)) { atleast_one = true; } } catch (Exception e) { throw new InvalidProjectFileException(String.Format( "{0}: Project file could not be imported, it was being imported by " + "{1}: {2}", importPath, importingFile, e.Message), e); } } if (atleast_one) { return; } } } } finally { project.ProjectLoadSettings = currentLoadSettings; if (has_extn_ref) { project.SetExtensionsPathProperties(Project.DefaultExtensionsPath); } } if (import_needed) { throw new InvalidProjectFileException(String.Format("{0} could not import \"{1}\"", importingFile, project_attribute)); } }