Browse Source

msbuild: test fixes. Implemented GlobalEngine and project unloading

svn path=/trunk/mcs/; revision=58682
Crestez Dan Leonard 20 years ago
parent
commit
ba5bc1a421

+ 7 - 0
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog

@@ -1,3 +1,10 @@
+2006-03-29  Crestez Leonard  <[email protected]>
+	
+	* InternalLoggerException.cs, InvalidProjectFileException.cs: Fixed
+	to pass tests. Wrote serialization constructor.
+	* Engine.cs, Project.cs: Global engine and project unloading, test and
+	formatting fixes.
+
 2006-03-28  Marek Sieradzki  <[email protected]>
 
 	* UsingTask.cs: Formatting changes.

+ 52 - 12
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs

@@ -44,7 +44,6 @@ namespace Microsoft.Build.BuildEngine {
 		bool			onlyLogCriticalEvents;
 		IDictionary		projects;
 
-		// FIXME
 		static Engine		globalEngine;
 		static Version		version;
 
@@ -173,34 +172,70 @@ namespace Microsoft.Build.BuildEngine {
 			return result;
 		}
 
+		internal void CheckBinPath ()
+		{
+			if (BinPath == null) {
+				throw new InvalidOperationException("Before a project can be instantiated, " +
+					"Engine.BinPath must be set to the location on disk where MSBuild " + 
+					"is installed. This is used to evaluate $(MSBuildBinPath).");
+			}
+		}
+
 		public Project CreateNewProject ()
 		{
+			CheckBinPath ();
 			return new Project (this);
 		}
 
 		public Project GetLoadedProject (string projectFullFileName)
 		{
+			if (projectFullFileName == null) {
+				throw new ArgumentNullException ("projectFullFileName");
+			}
 			return (Project) projects [projectFullFileName];
 		}
 
-		public void RegisterLogger (ILogger logger)
+		internal void RemoveLoadedProject (Project p)
 		{
-			if (logger == null)
-				throw new ArgumentNullException ("logger");
-			logger.Initialize (eventSource);
-			loggers.Add (logger);
+			if (p.FullFileName != "") {
+				projects.Remove (p.FullFileName);
+			}
 		}
-		
-		[MonoTODO]
-		public void UnloadAllProjects ()
+
+		internal void AddLoadedProject (Project p)
 		{
+			if (p.FullFileName != "") {
+				projects.Add (p.FullFileName, p);
+			}
 		}
-		
-		[MonoTODO]
+	
 		public void UnloadProject (Project project)
 		{
+			if (project.ParentEngine != this) {
+				throw new InvalidOperationException("This project is not loaded in this engine");
+			}
+			project.CheckUnloaded ();
+			if (project.FullFileName != "") {
+				projects.Remove (project.FullFileName);
+			}
+			project.Unload ();
 		}
 
+		public void UnloadAllProjects ()
+		{
+			foreach (DictionaryEntry e in projects) {
+				UnloadProject ((Project) e.Value);
+			}
+		}
+
+		public void RegisterLogger (ILogger logger)
+		{
+			if (logger == null)
+				throw new ArgumentNullException ("logger");
+			logger.Initialize (eventSource);
+			loggers.Add (logger);
+		}
+		
 		public void UnregisterAllLoggers ()
 		{
 			// FIXME: check if build succeeded
@@ -262,7 +297,12 @@ namespace Microsoft.Build.BuildEngine {
 		}
 
 		public static Engine GlobalEngine {
-			get { return globalEngine; }
+			get {
+				if (globalEngine == null) {
+					globalEngine = new Engine ();
+				}
+				return globalEngine;
+			}
 		}
 
 		public BuildPropertyGroup GlobalProperties {

+ 16 - 6
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/InternalLoggerException.cs

@@ -40,21 +40,31 @@ namespace Microsoft.Build.BuildEngine {
 		string		helpKeyword;
 		
 		public InternalLoggerException ()
-			: base ("Internal logger exception has occured.")
 		{
+			throw new System.InvalidOperationException(
+				"An InternalLoggerException can only be thrown by the MSBuild engine. " +
+				"The public constructors of this class cannot be used to create an " +
+				"instance of the exception.");
 		}
 
 		public InternalLoggerException (string message)
-			: base (message)
+			: this ()
 		{
 		}
 
-		public InternalLoggerException (string message,
-						Exception innerException)
-			: base (message, innerException)
+		public InternalLoggerException (string message,	Exception innerException)
+			: this ()
 		{
 		}
 
+		protected InternalLoggerException (SerializationInfo info, StreamingContext context)
+			: base (info, context)
+		{
+			buildEventArgs = (BuildEventArgs) info.GetValue("BuildEventArgs", typeof(BuildEventArgs));
+			errorCode = info.GetString("ErrorCode");
+			helpKeyword = info.GetString("HelpKeywordPrefix");
+		}
+
 		public override void GetObjectData (SerializationInfo info,
 						    StreamingContext context)
 		{
@@ -84,4 +94,4 @@ namespace Microsoft.Build.BuildEngine {
 	}
 }
 
-#endif
+#endif

+ 22 - 10
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/InvalidProjectFileException.cs

@@ -35,7 +35,6 @@ namespace Microsoft.Build.BuildEngine {
 	[Serializable]
 	public sealed class InvalidProjectFileException : Exception {
 		
-		string	baseMessage;
 		int	columnNumber;
 		int	endColumnNumber;
 		string	errorCode;
@@ -43,19 +42,16 @@ namespace Microsoft.Build.BuildEngine {
 		string	helpKeyword;
 		int	lineNumber;
 		int	endLineNumber;
-		string	message;
 		string	projectFile;
 		
 		public InvalidProjectFileException ()
 			: base ("Invalid project file exception has occured")
 		{
-			this.message = "Invalid project file exception has occured";
 		}
 
 		public InvalidProjectFileException (string message)
 			: base (message)
 		{
-			this.message = message;
 		}
 
 		public InvalidProjectFileException (string projectFile,
@@ -74,7 +70,6 @@ namespace Microsoft.Build.BuildEngine {
 			this.columnNumber = columnNumber;
 			this.endLineNumber = endLineNumber;
 			this.endColumnNumber = endColumnNumber;
-			this.message = message;
 			this.errorSubcategory = errorSubcategory;
 			this.errorCode = errorCode;
 			this.helpKeyword = helpKeyword;
@@ -86,6 +81,8 @@ namespace Microsoft.Build.BuildEngine {
 		{
 		}
 
+		// FIXME: set line/column numbers?
+		[MonoTODO]
 		public InvalidProjectFileException (XmlNode xmlNode,
 						    string message,
 						    string errorSubcategory,
@@ -93,17 +90,28 @@ namespace Microsoft.Build.BuildEngine {
 						    string helpKeyword)
 			: base (message)
 		{
-			this.message = message;
 			this.errorSubcategory = errorSubcategory;
 			this.errorCode = errorCode;
 			this.helpKeyword = helpKeyword;
 		}
 
+		protected InvalidProjectFileException (SerializationInfo info, StreamingContext context)
+			: base (info, context)
+		{
+			this.columnNumber = info.GetInt32 ("ColumnNumber");
+			this.endColumnNumber = info.GetInt32 ("EndColumnNumber");
+			this.errorCode = info.GetString ("ErrorCode");
+			this.errorSubcategory = info.GetString ("ErrorSubcategory");
+			this.helpKeyword = info.GetString ("HelpKeyword");
+			this.lineNumber = info.GetInt32 ("LineNumber");
+			this.endLineNumber = info.GetInt32 ("EndLineNumber");
+			this.projectFile = info.GetString ("ProjectFile");
+		}
+
 		public override void GetObjectData (SerializationInfo info,
 						    StreamingContext context)
 		{
 			base.GetObjectData (info, context);
-			info.AddValue ("BaseMessage", baseMessage);
 			info.AddValue ("ColumnNumber", columnNumber);
 			info.AddValue ("EndColumnNumber", endColumnNumber);
 			info.AddValue ("ErrorCode", errorCode);
@@ -116,7 +124,7 @@ namespace Microsoft.Build.BuildEngine {
 
 		public string BaseMessage {
 			get {
-				return baseMessage;
+				return base.Message;
 			}
 		}
 
@@ -164,7 +172,11 @@ namespace Microsoft.Build.BuildEngine {
 
 		public override string Message {
 			get {
-				return base.Message;
+				if (projectFile == null || projectFile == "") {
+					return BaseMessage;
+				} else {
+					return BaseMessage + "  " + ProjectFile;
+				}
 			}
 		}
 
@@ -176,4 +188,4 @@ namespace Microsoft.Build.BuildEngine {
 	}
 }
 
-#endif
+#endif

+ 29 - 8
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs

@@ -44,7 +44,6 @@ namespace Microsoft.Build.BuildEngine {
 		bool				buildEnabled;
 		IDictionary			conditionedProperties;
 		string[]			defaultTargets;
-		IList				directlyImportedProjects;
 		Encoding			encoding;
 		BuildPropertyGroup		environmentProperties;
 		BuildItemGroup			evaluatedItems;
@@ -58,21 +57,18 @@ namespace Microsoft.Build.BuildEngine {
 		GroupingCollection		groups;
 		bool				isDirty;
 		bool				isValidated;
-		bool				isReset;
 		BuildItemGroupCollection	itemGroups;
-		IDictionary			importedProjects;
 		ImportCollection		imports;
 		string				initialTargets;
 		Engine				parentEngine;
 		BuildPropertyGroupCollection	propertyGroups;
-		BuildPropertyGroup		reservedProperties;
 		string				schemaFile;
 		TaskDatabase			taskDatabase;
 		TargetCollection		targets;
 		DateTime			timeOfLastDirty;
 		UsingTaskCollection		usingTasks;
 		XmlDocument			xmlDocument;
-		//XmlElement			xmlElement;
+		bool				unloaded;
 
 		public Project ()
 			: this (Engine.GlobalEngine)
@@ -91,6 +87,7 @@ namespace Microsoft.Build.BuildEngine {
 			targets = new TargetCollection (this);
 			taskDatabase = new TaskDatabase ();
 			globalProperties = new BuildPropertyGroup ();
+			fullFileName = String.Empty;
 
 			foreach (BuildProperty bp in parentEngine.GlobalProperties) {
 				GlobalProperties.AddProperty (bp.Clone (true));
@@ -183,6 +180,7 @@ namespace Microsoft.Build.BuildEngine {
 				   BuildSettings buildFlags)
 		
 		{
+			CheckUnloaded ();
 			if (targetNames.Length == 0) {
 				if (defaultTargets.Length != 0) {
 					targetNames = defaultTargets;
@@ -235,6 +233,8 @@ namespace Microsoft.Build.BuildEngine {
 		// Does the actual loading.
 		private void DoLoad (TextReader textReader)
 		{
+			ParentEngine.RemoveLoadedProject (this);
+
 			XmlReaderSettings settings = new XmlReaderSettings ();
 
 			if (SchemaFile != null) {
@@ -245,7 +245,16 @@ namespace Microsoft.Build.BuildEngine {
 
 			XmlReader xmlReader = XmlReader.Create (textReader, settings);
 			xmlDocument.Load (xmlReader);
+
+			if (xmlDocument.DocumentElement.GetAttribute("xmlns") != "http://schemas.microsoft.com/developer/msbuild/2003") {
+				throw new InvalidProjectFileException(
+					@"The default XML namespace of the project must be the MSBuild XML namespace." + 
+					" If the project is authored in the MSBuild 2003 format, please add " +
+					"xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" to the <Project> element. " +
+					"If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format.  ");
+			}
 			ProcessXml ();
+			ParentEngine.AddLoadedProject (this);
 		}
 
 		public void Load (string projectFileName)
@@ -267,6 +276,18 @@ namespace Microsoft.Build.BuildEngine {
 			DoLoad (new StringReader (projectXml));
 		}
 
+		internal void Unload ()
+		{
+			unloaded = true;
+		}
+
+		internal void CheckUnloaded ()
+		{
+			if (unloaded) {
+				throw new InvalidOperationException("This project object is no longer valid.");
+			}
+		}
+
 		private void ProcessXml ()
 		{
 			XmlElement xmlElement = xmlDocument.DocumentElement;
@@ -280,7 +301,7 @@ namespace Microsoft.Build.BuildEngine {
 			ProcessElements (xmlElement, null);
 			
 			isDirty = false;
-			Evaluate();
+			Evaluate ();
 		}
 
 		private void InitializeProperties ()
@@ -559,7 +580,7 @@ namespace Microsoft.Build.BuildEngine {
 				throw new ArgumentNullException ("xmlElement");
 			BuildItemGroup big = new BuildItemGroup (xmlElement, this);
 			ItemGroups.Add (big);
-			big.Evaluate();
+			big.Evaluate ();
 		}
 		
 		private void AddPropertyGroup (XmlElement xmlElement)
@@ -568,7 +589,7 @@ namespace Microsoft.Build.BuildEngine {
 				throw new ArgumentNullException ("xmlElement");
 			BuildPropertyGroup bpg = new BuildPropertyGroup (xmlElement, this);
 			PropertyGroups.Add (bpg);
-			bpg.Evaluate();
+			bpg.Evaluate ();
 		}
 		
 		private void AddChoose (XmlElement xmlElement)

+ 5 - 0
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog

@@ -1,3 +1,8 @@
+2006-03-29  Crestez Leonard  <[email protected]>
+
+	* EngineTest.cs: Added test for GlobalEngine.
+	* ProjectTest.cs: Fixed tests.
+	
 2006-03-27  Crestez Leonard  <[email protected]>
 
 	* ProjectTest.cs, EngineTest.cs: Added new tests.

+ 11 - 1
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs

@@ -39,7 +39,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[SetUp]
 		public void SetUp ()
 		{
-		    binPath = "binPath";
+			binPath = "binPath";
 		}
 
 		[Test]
@@ -130,5 +130,15 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 			project = new Project (engine);
 			Assert.AreEqual (4, project.GlobalProperties.Count, "A15");
 		}
+
+		[Test]
+		public void TestGlobalEngine ()
+		{
+			engine = new Engine ();
+			Assert.IsFalse (engine == Engine.GlobalEngine, "1");
+			Assert.IsNotNull (Engine.GlobalEngine, "2");
+			engine = Engine.GlobalEngine;
+			Assert.AreSame (engine, Engine.GlobalEngine, "3");
+		}
 	}
 }

+ 7 - 6
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs

@@ -84,13 +84,14 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 			
 			engine = new Engine (binPath);
 			proj = engine.CreateNewProject ();
+			Assert.AreEqual (String.Empty, proj.FullFileName, "A1");
+
 			proj.LoadXml (documentString);
-			
-			Assert.AreEqual ("Build; Compile", proj.DefaultTargets, "A1");
+			Assert.AreEqual (String.Empty, proj.FullFileName, "A2");
 			proj.DefaultTargets = "Build";
-			Assert.AreEqual ("Build", proj.DefaultTargets, "A2");
+			Assert.AreEqual ("Build", proj.DefaultTargets, "A3");
 			cproj = CloneProject (proj);
-			Assert.AreEqual (proj.DefaultTargets, cproj.DefaultTargets, "A3");
+			Assert.AreEqual (proj.DefaultTargets, cproj.DefaultTargets, "A4");
 		}
 
 		[Test]
@@ -135,11 +136,11 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 		[Test]
 		public void TestItems ()
 		{
-			Engine engine = new Engine ();
+			Engine engine = new Engine (binPath);
 			Project proj = engine.CreateNewProject ();
 
 			string documentString = @"
-				<Project>
+				<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
 					<ItemGroup>
 						<Item0 Include=""A"" />
 						<Item1 Include=""A;B;C"" />