2 // MSBuildProjectServiceExtension.cs
5 // Ankit Jain <jankit@novell.com>
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 using MonoDevelop
.Core
;
30 using MonoDevelop
.Core
.Execution
;
31 using MonoDevelop
.Projects
;
34 using System
.CodeDom
.Compiler
;
35 using System
.Collections
.Generic
;
36 using System
.Diagnostics
;
38 using System
.Text
.RegularExpressions
;
40 namespace MonoDevelop
.Prj2Make
42 public class MSBuildProjectServiceExtension
: ProjectServiceExtension
45 protected override BuildResult
Build (IProgressMonitor monitor
, IBuildTarget entry
, string configuration
)
47 //xamlg any SilverLightPages
48 DotNetProject project
= entry
as DotNetProject
;
50 return base.Build (monitor
, entry
, configuration
);
52 foreach (ProjectFile pf
in project
.Files
) {
53 if (pf
.BuildAction
!= BuildAction
.EmbeddedResource
)
56 //Check for SilverLightPage
57 if (pf
.ExtendedProperties
["MonoDevelop.MSBuildFileFormat.SilverlightPage"] == null)
60 string generated_file_name
;
61 CompilerError error
= GenerateXamlPartialClass (pf
.Name
, out generated_file_name
, monitor
);
63 CompilerResults cr
= new CompilerResults (new TempFileCollection ());
64 cr
.Errors
.Add (error
);
66 monitor
.Log
.WriteLine (GettextCatalog
.GetString("Build complete -- ") +
67 GettextCatalog
.GetPluralString("{0} error", "{0} errors", cr
.Errors
.Count
) +
68 GettextCatalog
.GetPluralString("{0} warning", "{0} warnings", 0),
70 return new BuildResult (cr
, String
.Empty
);
74 return base.Build (monitor
, entry
, configuration
);
77 CompilerError
GenerateXamlPartialClass (string fname
, out string generated_file_name
, IProgressMonitor monitor
)
79 generated_file_name
= fname
+ ".g.cs";
81 //Check whether resgen required
82 FileInfo finfo_resx
= new FileInfo (fname
);
83 FileInfo finfo_resources
= new FileInfo (generated_file_name
);
84 if (finfo_resx
.LastWriteTime
< finfo_resources
.LastWriteTime
)
87 using (StringWriter sw
= new StringWriter ()) {
88 LoggingService
.LogDebug ("Generating partial classes for\n{0}$ {1} {2}", Path
.GetDirectoryName (fname
), "xamlg", fname
);
89 monitor
.Log
.WriteLine (GettextCatalog
.GetString (
90 "Generating partial classes for {0} with {1}", fname
, "xamlg"));
91 ProcessWrapper pw
= null;
93 ProcessStartInfo info
= Runtime
.ProcessService
.CreateProcessStartInfo (
94 "xamlg", String
.Format ("\"{0}\"", fname
),
95 Path
.GetDirectoryName (fname
), false);
97 if (PlatformID
.Unix
== Environment
.OSVersion
.Platform
)
98 info
.EnvironmentVariables
["MONO_IOMAP"] = "drive";
100 pw
= Runtime
.ProcessService
.StartProcess (info
, sw
, sw
, null);
101 } catch (System
.ComponentModel
.Win32Exception ex
) {
102 LoggingService
.LogError (GettextCatalog
.GetString (
103 "Error while trying to invoke '{0}' to generate partial classes for '{1}' :\n {2}", "xamlg", fname
, ex
.ToString ()));
104 monitor
.Log
.WriteLine (GettextCatalog
.GetString (
105 "Error while trying to invoke '{0}' to generate partial classes for '{1}' :\n {2}", "xamlg", fname
, ex
.Message
));
107 return new CompilerError (fname
, 0, 0, String
.Empty
, ex
.Message
);
110 //FIXME: Handle exceptions
113 if (pw
.ExitCode
!= 0) {
114 //FIXME: Stop build on error?
115 string output
= sw
.ToString ();
116 LoggingService
.LogError (GettextCatalog
.GetString (
117 "Unable to generate partial classes ({0}) for {1}. \nReason: \n{2}\n",
118 "xamlg", fname
, output
));
119 monitor
.Log
.WriteLine (GettextCatalog
.GetString (
120 "Unable to generate partial classes ({0}) for {1}. \nReason: \n{2}\n",
121 "xamlg", fname
, output
));
123 //Try to get the line/pos
126 Match match
= RegexErrorLinePos
.Match (output
);
127 if (match
.Success
&& match
.Groups
.Count
== 3) {
129 line
= int.Parse (match
.Groups
[1].Value
);
130 } catch (FormatException
){
134 pos
= int.Parse (match
.Groups
[2].Value
);
135 } catch (FormatException
){
139 return new CompilerError (fname
, line
, pos
, "", output
);
147 // Used for parsing "Line 123, position 5" errors from tools
148 // like resgen, xamlg
149 static Regex regexErrorLinePos
;
150 static Regex RegexErrorLinePos
{
152 if (regexErrorLinePos
== null)
153 regexErrorLinePos
= new Regex (@"Line (\d*), position (\d*)");
154 return regexErrorLinePos
;