Esempio n. 1
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};
			bool import_needed = false;
			
			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;

					import_needed = true;

					// 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);
			}

			if (import_needed)
				throw new InvalidProjectFileException (String.Format ("{0} could not import \"{1}\"", importingFile, project_attribute));
		}
Esempio n. 2
0
        void ExecuteOnErrors()
        {
            foreach (XmlElement onError in onErrorElements)
            {
                if (onError.GetAttribute("ExecuteTargets") == String.Empty)
                {
                    throw new InvalidProjectFileException("ExecuteTargets attribute is required in OnError element.");
                }

                string on_error_condition = onError.GetAttribute("Condition");
                if (!ConditionParser.ParseAndEvaluate(on_error_condition, Project))
                {
                    LogMessage(MessageImportance.Low,
                               "OnError for target {0} skipped due to false condition: {1}",
                               Name, on_error_condition);
                    continue;
                }

                string[] targetsToExecute = onError.GetAttribute("ExecuteTargets").Split(';');
                foreach (string t in targetsToExecute)
                {
                    this.project.Targets [t].Build();
                }
            }
        }
Esempio n. 3
0
        public bool Build(BuildTask buildTask, out bool executeOnErrors)
        {
            executeOnErrors = false;
            try {
                Init();

                // populate list of referenced items and metadata
                ParseTaskAttributes(buildTask);
                if (consumedMetadataReferences.Count == 0)
                {
                    // No batching required
                    if (ConditionParser.ParseAndEvaluate(buildTask.Condition, project))
                    {
                        return(buildTask.Execute());
                    }
                    else                     // skipped, it should be logged
                    {
                        return(true);
                    }
                }

                BatchAndPrepareBuckets();
                return(Run(buildTask, out executeOnErrors));
            } finally {
                consumedItemsByName          = null;
                consumedMetadataReferences   = null;
                consumedQMetadataReferences  = null;
                consumedUQMetadataReferences = null;
                batchedItemsByName           = null;
                commonItemsByName            = null;
            }
        }
Esempio n. 4
0
        // if @alternateProjectPath is available then that it used as the EvaluatedProjectPath!
        internal Import(XmlElement importElement, string alternateProjectPath, Project project, ImportedProject originalProject)
        {
            if (importElement == null)
            {
                throw new ArgumentNullException("importElement");
            }
            if (project == null)
            {
                throw new ArgumentNullException("project");
            }

            this.project         = project;
            this.importElement   = importElement;
            this.originalProject = originalProject;

            if (ProjectPath == String.Empty)
            {
                throw new InvalidProjectFileException("The required attribute \"Project\" is missing from element <Import>.");
            }

            if (ConditionParser.ParseAndEvaluate(Condition, project))
            {
                evaluatedProjectPath = String.IsNullOrEmpty(alternateProjectPath) ? EvaluateProjectPath(ProjectPath) : alternateProjectPath;

                evaluatedProjectPath = GetFullPath();
                if (EvaluatedProjectPath == String.Empty)
                {
                    throw new InvalidProjectFileException("The required attribute \"Project\" is missing from element <Import>.");
                }
            }
        }
Esempio n. 5
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);
                }
            }

            DirectoryScanner directoryScanner;
            Expression       includeExpr, excludeExpr;

            ITaskItem[] includes, excludes;

            includeExpr = new Expression();
            includeExpr.Parse(Include, ParseOptions.AllowItemsNoMetadataAndSplit);
            excludeExpr = new Expression();
            excludeExpr.Parse(Exclude, ParseOptions.AllowItemsNoMetadataAndSplit);

            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);
            }
        }
Esempio n. 6
0
        bool BuildActual(string built_targets_key, out bool executeOnErrors)
        {
            bool result = false;

            executeOnErrors = false;

            // built targets are keyed by the particular set of global
            // properties. So, a different set could allow a target
            // to run again
            built_targets_key = project.GetKeyForTarget(Name);
            if (project.ParentEngine.BuiltTargetsOutputByName.ContainsKey(built_targets_key))
            {
                LogTargetSkipped();
                return(true);
            }

            // Push a null/empty batch, effectively clearing it
            project.PushBatch(null, null);
            if (!ConditionParser.ParseAndEvaluate(Condition, Project))
            {
                LogMessage(MessageImportance.Low,
                           "Target {0} skipped due to false condition: {1}",
                           Name, Condition);
                project.PopBatch();
                return(true);
            }

            try {
                buildState = BuildState.Started;

#if NET_4_0
                result = BuildDependencies(out executeOnErrors) &&
                         BuildBeforeThisTargets(out executeOnErrors) &&
                         DoBuild(out executeOnErrors) &&                         // deps & Before targets built fine, do main build
                         BuildAfterThisTargets(out executeOnErrors);
#else
                result = BuildDependencies(out executeOnErrors) && DoBuild(out executeOnErrors);
#endif

                buildState = BuildState.Finished;
            } catch (Exception e) {
                LogError("Error building target {0}: {1}", Name, e.ToString());
                return(false);
            } finally {
                project.PopBatch();
            }

            ITaskItem[] outputs = (ITaskItem[])OutputsAsITaskItems.Clone();
            foreach (ITaskItem item in outputs)
            {
                item.SetMetadata("MSBuildProjectFile", TargetFile);
                item.SetMetadata("MSBuildTargetName", Name);
            }
            project.ParentEngine.BuiltTargetsOutputByName [built_targets_key] = outputs;

            return(result);
        }
Esempio n. 7
0
        bool Build(string built_targets_key, out bool executeOnErrors)
        {
            bool result = false;

            executeOnErrors = false;

            // built targets are keyed by the particular set of global
            // properties. So, a different set could allow a target
            // to run again
            built_targets_key = project.GetKeyForTarget(Name);
            if (project.ParentEngine.BuiltTargetsOutputByName.ContainsKey(built_targets_key))
            {
                LogTargetSkipped();
                return(true);
            }

            // Push a null/empty batch, effectively clearing it
            project.PushBatch(null, null);
            if (!ConditionParser.ParseAndEvaluate(Condition, Project))
            {
                LogMessage(MessageImportance.Low,
                           "Target {0} skipped due to false condition: {1}",
                           Name, Condition);
                project.PopBatch();
                return(true);
            }

            try {
                buildState = BuildState.Started;
                result     = BuildDependencies(GetDependencies(), out executeOnErrors);

                if (!result && executeOnErrors)
                {
                    ExecuteOnErrors();
                }

                if (result)
                {
                    // deps built fine, do main build
                    result = DoBuild(out executeOnErrors);
                }

                buildState = BuildState.Finished;
            } catch (Exception e) {
                LogError("Error building target {0}: {1}", Name, e.ToString());
                return(false);
            } finally {
                project.PopBatch();
            }

            project.ParentEngine.BuiltTargetsOutputByName [built_targets_key] = (ITaskItem[])Outputs.Clone();
            project.BuiltTargetKeys.Add(built_targets_key);

            return(result);
        }
 void EvaluateBuildItemGroup(BuildItemGroup big)
 {
     project.PushThisFileProperty(big.DefinedInFileName);
     try {
         if (ConditionParser.ParseAndEvaluate(big.Condition, project))
         {
             big.Evaluate();
         }
     } finally {
         project.PopThisFileProperty();
     }
 }
Esempio n. 9
0
        internal void Evaluate()
        {
            if (AssemblyName == null && AssemblyFile == null)
            {
                throw new InvalidProjectFileException("A <UsingTask> element must contain either the \"AssemblyName\" attribute or the \"AssemblyFile\" attribute (but not both).  ");
            }

            if (ConditionParser.ParseAndEvaluate(Condition, project))
            {
                project.TaskDatabase.RegisterUsingTask(this);
            }
        }
Esempio n. 10
0
 bool CheckCondition(Project project)
 {
     if (parent_item_group != null && !ConditionParser.ParseAndEvaluate(parent_item_group.Condition, project))
     {
         return(false);
     }
     if (parent_item != null && !parent_item.CheckCondition(project))
     {
         return(false);
     }
     return(ConditionParser.ParseAndEvaluate(Condition, project));
 }
        bool Run(BuildTask buildTask, out bool executeOnErrors)
        {
            executeOnErrors = false;

            // Run the task in batches
            bool retval = true;

            if (buckets.Count == 0)
            {
                // batched mode, but no values in the corresponding items!
                if (ConditionParser.ParseAndEvaluate(buildTask.Condition, project))
                {
                    retval = buildTask.Execute();
                    if (!retval && !buildTask.ContinueOnError)
                    {
                        executeOnErrors = true;
                    }
                }

                return(retval);
            }

            // batched
            foreach (Dictionary <string, BuildItemGroup> bucket in buckets)
            {
                project.PushBatch(bucket, commonItemsByName);
                try
                {
                    if (ConditionParser.ParseAndEvaluate(buildTask.Condition, project))
                    {
                        retval = buildTask.Execute();
                        if (!retval && !buildTask.ContinueOnError)
                        {
                            executeOnErrors = true;
                            break;
                        }
                    }
                }
                finally
                {
                    project.PopBatch();
                }
            }

            return(retval);
        }
Esempio n. 12
0
        internal void Evaluate()
        {
            if (evaluated)
            {
                return;
            }

            foreach (BuildProperty bp in properties)
            {
                if (ConditionParser.ParseAndEvaluate(bp.Condition, parentProject))
                {
                    bp.Evaluate();
                }
            }

            evaluated = true;
        }
Esempio n. 13
0
        bool Execute(IBuildTask buildTask, TaskExecutionMode taskExecutionMode)
        {
            if (ConditionParser.ParseAndEvaluate(buildTask.Condition, project))
            {
                switch (taskExecutionMode)
                {
                case TaskExecutionMode.Complete:
                    return(buildTask.Execute());

                case TaskExecutionMode.SkipAndSetOutput:
                    return(buildTask.ResolveOutputItems());

                default:
                    throw new NotImplementedException();
                }
            }

            return(true);
        }
 void EvaluateBuildChoose(BuildChoose bc)
 {
     project.PushThisFileProperty(bc.DefinedInFileName);
     try {
         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();
         }
     } finally {
         project.PopThisFileProperty();
     }
 }
Esempio n. 15
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");

            // Visual Studio project files use a property called VCTargetsPath, that is defined in the
            // registry under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0.
            // Override it as xbuild doesn't know about it.
            bool has_vc_ref = project_attribute.IndexOf("$(VCTargetsPath)") >= 0;

            if (has_vc_ref)
            {
                project_attribute = project_attribute.Replace("$(VCTargetsPath)", "$(MSBuildExtensionsPath)");
            }

            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);
                }
            }
        }
Esempio n. 16
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 Exception(String.Format(
                                            "The parameter '{0}' was not found for the '{1}' task.", taskParameter, taskElement.Name));
                }
                if (!propertyInfo.IsDefined(outputAttribute, false))
                {
                    throw new Exception("This is not output property.");
                }

                o = propertyInfo.GetValue(task, null);
                // FIXME: maybe we should throw an exception here?
                if (o == null)
                {
                    continue;
                }

                if (itemName != String.Empty)
                {
                    PublishItemGroup(propertyInfo, o, itemName);
                }
                else
                {
                    PublishProperty(propertyInfo, o, propertyName);
                }
            }
        }
Esempio n. 17
0
        internal void Evaluate(EvaluationType type)
        {
            BuildItemGroup          big;
            BuildPropertyGroup      bpg;
            Import                  import;
            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;
        }
Esempio n. 18
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));
            }
        }