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;
		}
Пример #2
0
		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;
		}
Пример #3
0
        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);
                }
            }
        }
Пример #4
0
        // 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;
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
        // 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));
            }
        }