* Makefile.am:
[monodevelop.git] / main / src / addins / prj2make-sharp-lib / MSBuildProjectServiceExtension.cs
blobe529f6a0d9a3fe153035ba5af2b9ebd7064ccebe
1 //
2 // MSBuildProjectServiceExtension.cs
3 //
4 // Author:
5 // Ankit Jain <jankit@novell.com>
6 //
7 // Copyright (C) 2007 Novell, Inc (http://www.novell.com)
8 //
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;
33 using System;
34 using System.CodeDom.Compiler;
35 using System.Collections.Generic;
36 using System.Diagnostics;
37 using System.IO;
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;
49 if (project == null)
50 return base.Build (monitor, entry, configuration);
52 foreach (ProjectFile pf in project.Files) {
53 if (pf.BuildAction != BuildAction.EmbeddedResource)
54 continue;
56 //Check for SilverLightPage
57 if (pf.ExtendedProperties ["MonoDevelop.MSBuildFileFormat.SilverlightPage"] == null)
58 continue;
60 string generated_file_name;
61 CompilerError error = GenerateXamlPartialClass (pf.Name, out generated_file_name, monitor);
62 if (error != null) {
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),
69 cr.Errors.Count, 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)
85 return null;
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;
92 try {
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
111 pw.WaitForOutput ();
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
124 int line = 0;
125 int pos = 0;
126 Match match = RegexErrorLinePos.Match (output);
127 if (match.Success && match.Groups.Count == 3) {
128 try {
129 line = int.Parse (match.Groups [1].Value);
130 } catch (FormatException){
133 try {
134 pos = int.Parse (match.Groups [2].Value);
135 } catch (FormatException){
139 return new CompilerError (fname, line, pos, "", output);
143 //No errors
144 return null;
147 // Used for parsing "Line 123, position 5" errors from tools
148 // like resgen, xamlg
149 static Regex regexErrorLinePos;
150 static Regex RegexErrorLinePos {
151 get {
152 if (regexErrorLinePos == null)
153 regexErrorLinePos = new Regex (@"Line (\d*), position (\d*)");
154 return regexErrorLinePos;