17
22
// You should have received a copy of the GNU General Public License
18
23
// along with this program; if not, write to the Free Software
19
24
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
using System.Text.RegularExpressions;
24
using System.Collections;
26
using System.Diagnostics;
28
using System.Text.RegularExpressions;
29
using System.Collections;
31
using System.Diagnostics;
27
32
using System.CodeDom.Compiler;
28
33
using System.Threading;
30
using MonoDevelop.Core;
35
using MonoDevelop.Core;
31
36
using MonoDevelop.Core.Execution;
32
37
using MonoDevelop.Core.Gui;
33
using MonoDevelop.Core.Gui.Components;
38
using MonoDevelop.Core.Gui.Components;
39
using MonoDevelop.Core.Serialization;
34
40
using MonoDevelop.Projects;
39
/// This class controls the compilation of VB.net files and VB.net projects
41
public class VBBindingCompilerServices
41
using MonoDevelop.Projects.Text;
43
using MonoDevelop.VBNetBinding.Extensions;
45
namespace MonoDevelop.VBNetBinding {
48
/// This class controls the compilation of VB.net files and VB.net projects
50
public class VBBindingCompilerServices
43
52
//matches "/home/path/Default.aspx.vb (40,31) : Error VBNC30205: Expected end of statement."
44
53
//and "Error : VBNC99999: vbnc crashed nearby this location in the source code."
45
54
//and "Error : VBNC99999: Unexpected error: Object reference not set to an instance of an object"
46
static Regex regexError = new Regex (@"^\s*((?<file>.*)\((?<line>\d*),(?<column>\d*)\) : )?(?<level>\w+) :? ?(?<number>[^:]*): (?<message>.*)$",
55
static Regex regexError = new Regex (@"^\s*((?<file>.*) \((?<line>\d*),(?<column>\d*)\) : )?(?<level>\w+) :? ?(?<number>[^:]*): (?<message>.*)$",
47
56
RegexOptions.Compiled | RegexOptions.ExplicitCapture);
49
public bool CanCompile(string fileName)
51
return Path.GetExtension(fileName) == ".vb";
54
string GetCompilerName(string compilerVersion)
56
//string runtimeDirectory = Path.Combine(fileUtilityService.NETFrameworkInstallRoot, compilerVersion);
57
//if (compilerVersion.Length == 0 || compilerVersion == "Standard" || !Directory.Exists(runtimeDirectory)) {
58
// runtimeDirectory = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory();
60
//return String.Concat('"', Path.Combine(runtimeDirectory, "vbc.exe"), '"');
64
string GenerateOptions (DotNetProjectConfiguration configuration, VBCompilerParameters compilerparameters, string outputFileName)
66
StringBuilder sb = new StringBuilder();
67
bool hasWin32Resource = false;
69
sb.Append("-out:");sb.Append("\"" + outputFileName + "\"");/*sb.Append('"');*/sb.Append(Environment.NewLine);
71
sb.Append("-nologo");sb.Append(Environment.NewLine);
72
sb.Append("-utf8output");sb.Append(Environment.NewLine);
74
// if (compilerparameters.DebugMode) {
75
// sb.Append("--debug+");sb.Append(Environment.NewLine);
76
// sb.Append("--debug:full");sb.Append(Environment.NewLine);
79
//if (compilerparameters.Optimize) {
80
// sb.Append("-optimize");sb.Append(Environment.NewLine);
83
//if (compilerparameters.OptionStrict) {
84
// sb.Append("-optionstrict");sb.Append(Environment.NewLine);
87
//if (compilerparameters.OptionExplicit) {
88
// sb.Append("-optionexplicit");sb.Append(Environment.NewLine);
90
// sb.Append("--optionexplicit-");sb.Append(Environment.NewLine);
93
if (compilerparameters.Win32Resource != null && compilerparameters.Win32Resource.Length > 0 && File.Exists(compilerparameters.Win32Resource)) {
94
sb.Append("-win32resource:");sb.Append('"');sb.Append(compilerparameters.Win32Resource);sb.Append('"');sb.Append(Environment.NewLine);
95
hasWin32Resource = true;
97
if (compilerparameters.Win32Icon != null && compilerparameters.Win32Icon.Length > 0 && File.Exists(compilerparameters.Win32Icon)) {
99
Console.WriteLine ("Warning: Both Win32 icon and Win32 resource cannot be specified. Ignoring the icon.");
101
sb.Append("-win32icon:");sb.Append('"');sb.Append(compilerparameters.Win32Icon);sb.Append('"');sb.Append(Environment.NewLine);
104
if (compilerparameters.RootNamespace!= null && compilerparameters.RootNamespace.Length > 0) {
105
sb.Append("-rootnamespace:");sb.Append('"');sb.Append(compilerparameters.RootNamespace);sb.Append('"');sb.Append(Environment.NewLine);
108
if (compilerparameters.DefineSymbols.Length > 0) {
109
sb.Append("-define:");sb.Append('"');sb.Append(compilerparameters.DefineSymbols);sb.Append('"');sb.Append(Environment.NewLine);
58
string GenerateOptions (DotNetProjectConfiguration configuration, VBCompilerParameters compilerparameters, string outputFileName)
60
DotNetProject project = (DotNetProject) configuration.ParentItem;
61
StringBuilder sb = new StringBuilder ();
63
sb.AppendFormat ("\"-out:{0}\"", outputFileName);
66
sb.AppendLine ("-nologo");
67
sb.AppendLine ("-utf8output");
69
sb.AppendFormat ("-debug:{0}", compilerparameters.DebugType);
72
if (compilerparameters.Optimize)
73
sb.AppendLine ("-optimize+");
76
switch (project.GetOptionStrict ()) {
78
sb.AppendLine ("-optionstrict+");
81
sb.AppendLine ("-optionstrict-");
85
switch (project.GetOptionExplicit ()) {
87
sb.AppendLine ("-optionexplicit+");
90
sb.AppendLine ("-optionexplicit-");
94
switch (project.GetOptionCompare ()) {
96
sb.AppendLine ("-optioncompare:binary");
99
sb.AppendLine ("-optioncompare:text");
103
switch (project.GetOptionInfer ()) {
105
sb.AppendLine ("-optioninfer+");
108
sb.AppendLine ("-optioninfer-");
112
string mytype = project.GetMyType ();
113
if (!string.IsNullOrEmpty (mytype)) {
114
sb.AppendFormat ("-define:_MYTYPE=\\\"{0}\\\"", mytype);
118
string win32IconPath = project.GetApplicationIconPath ();
119
if (!string.IsNullOrEmpty (win32IconPath) && File.Exists (win32IconPath)) {
120
sb.AppendFormat ("\"-win32icon:{0}\"", win32IconPath);
124
if (!string.IsNullOrEmpty (project.GetCodePage ())) {
125
TextEncoding enc = TextEncoding.GetEncoding (project.GetCodePage ());
126
sb.AppendFormat ("-codepage:{0}", enc.CodePage);
130
if (!string.IsNullOrEmpty (project.GetRootNamespace ())) {
131
sb.AppendFormat ("-rootnamespace:{0}", project.GetRootNamespace ());
135
if (!string.IsNullOrEmpty (compilerparameters.DefineConstants)) {
136
sb.AppendFormat ("\"-define:{0}\"", compilerparameters.DefineConstants);
140
if (compilerparameters.DefineDebug)
141
sb.AppendLine ("-define:DEBUG=-1");
143
if (compilerparameters.DefineTrace)
144
sb.AppendLine ("-define:TRACE=-1");
146
if (compilerparameters.WarningsDisabled) {
147
sb.AppendLine ("-nowarn");
148
} else if (!string.IsNullOrEmpty (compilerparameters.NoWarn)) {
149
sb.AppendFormat ("-nowarn:{0}", compilerparameters.NoWarn);
153
if (!string.IsNullOrEmpty (compilerparameters.WarningsAsErrors)) {
154
sb.AppendFormat ("-warnaserror+:{0}", compilerparameters.WarningsAsErrors);
111
158
if (configuration.SignAssembly) {
112
159
if (File.Exists (configuration.AssemblyKeyFile)) {
113
sb.Append("-keyfile:");sb.Append('"');sb.Append(configuration.AssemblyKeyFile);sb.Append('"');sb.Append(Environment.NewLine);
117
if (compilerparameters.MainClass != null && compilerparameters.MainClass.Length > 0) {
118
sb.Append("-main:");sb.Append(compilerparameters.MainClass);sb.Append(Environment.NewLine);
121
if(compilerparameters.Imports.Length > 0) {
122
sb.Append("-imports:");sb.Append(compilerparameters.Imports);sb.Append(Environment.NewLine);
125
switch (configuration.CompileTarget) {
126
case CompileTarget.Exe:
127
sb.Append("-target:exe");
129
case CompileTarget.WinExe:
130
sb.Append("-target:winexe");
132
case CompileTarget.Library:
133
sb.Append("-target:library");
135
case CompileTarget.Module:
136
sb.Append("-target:module");
139
throw new NotSupportedException("unknown compile target:" + configuration.CompileTarget);
141
sb.Append(Environment.NewLine);
142
return sb.ToString();
145
public ICompilerResult Compile (ProjectFileCollection projectFiles, ProjectReferenceCollection references, DotNetProjectConfiguration configuration, IProgressMonitor monitor)
160
sb.AppendFormat ("\"-keyfile:{0}\"", configuration.AssemblyKeyFile);
165
if (!string.IsNullOrEmpty (compilerparameters.DocumentationFile)) {
166
sb.AppendFormat ("-doc:{0}", compilerparameters.DocumentationFile);
170
string mainClass = project.GetMainClass ();
171
if (!string.IsNullOrEmpty (mainClass) && mainClass != "Sub Main") {
172
sb.Append ("-main:");
173
sb.Append (project.GetMainClass ());
177
if (compilerparameters.RemoveIntegerChecks)
178
sb.AppendLine ("-removeintchecks+");
180
if (!string.IsNullOrEmpty (compilerparameters.AdditionalParameters)) {
181
sb.Append (compilerparameters.AdditionalParameters);
185
switch (configuration.CompileTarget) {
186
case CompileTarget.Exe:
187
sb.AppendLine ("-target:exe");
189
case CompileTarget.WinExe:
190
sb.AppendLine ("-target:winexe");
192
case CompileTarget.Library:
193
sb.AppendLine ("-target:library");
195
case CompileTarget.Module:
196
sb.AppendLine ("-target:module");
199
throw new NotSupportedException("unknown compile target:" + configuration.CompileTarget);
202
return sb.ToString();
205
public BuildResult Compile (ProjectFileCollection projectFiles, ProjectReferenceCollection references, DotNetProjectConfiguration configuration, IProgressMonitor monitor)
147
207
VBCompilerParameters compilerparameters = (VBCompilerParameters) configuration.CompilationParameters;
148
if (compilerparameters == null) compilerparameters = new VBCompilerParameters ();
208
if (compilerparameters == null)
209
compilerparameters = new VBCompilerParameters ();
150
211
string exe = configuration.CompiledOutputName;
151
string responseFileName = Path.GetTempFileName();
152
StreamWriter writer = new StreamWriter(responseFileName);
154
writer.WriteLine(GenerateOptions (configuration, compilerparameters, exe));
156
foreach (ProjectReference lib in references) {
157
foreach (string fileName in lib.GetReferencedFileNames())
158
writer.WriteLine(String.Concat("-r:", fileName));
161
// write source files and embedded resources
162
foreach (ProjectFile finfo in projectFiles) {
163
if (finfo.Subtype != Subtype.Directory) {
164
switch (finfo.BuildAction) {
165
case BuildAction.Compile:
166
writer.WriteLine("\"" + finfo.Name + "\"");
169
case BuildAction.EmbedAsResource:
212
string responseFileName = Path.GetTempFileName();
213
StreamWriter writer = new StreamWriter (responseFileName);
215
writer.WriteLine (GenerateOptions (configuration, compilerparameters, exe));
218
foreach (ProjectReference lib in references) {
219
foreach (string fileName in lib.GetReferencedFileNames(configuration.Id)) {
220
writer.Write ("\"-r:");
221
writer.Write (fileName);
222
writer.WriteLine ("\"");
226
// Write source files and embedded resources
227
foreach (ProjectFile finfo in projectFiles) {
228
if (finfo.Subtype != Subtype.Directory) {
229
switch (finfo.BuildAction) {
231
writer.WriteLine("\"" + finfo.Name + "\"");
234
case "EmbeddedResource":
170
235
string fname = finfo.Name;
171
236
if (String.Compare (Path.GetExtension (fname), ".resx", true) == 0)
172
237
fname = Path.ChangeExtension (fname, ".resources");
174
writer.WriteLine(@"""-resource:{0},{1}""", fname, finfo.ResourceId);
239
writer.WriteLine("\"-resource:{0},{1}\"", fname, finfo.ResourceId);
243
writer.WriteLine ("-imports:{0}", Path.GetFileName (finfo.Name));
182
TempFileCollection tf = new TempFileCollection ();
186
string compilerName = GetCompilerName(compilerparameters.VBCompilerVersion);
187
string outstr = String.Concat(compilerName, " @", responseFileName);
252
TempFileCollection tf = new TempFileCollection ();
256
string compilerName = "vbnc";
257
string outstr = String.Concat (compilerName, " @", responseFileName);
190
260
string workingDir = ".";
191
261
if (projectFiles != null && projectFiles.Count > 0)
192
262
workingDir = projectFiles [0].Project.BaseDirectory;
195
265
monitor.Log.WriteLine (compilerName + " " + string.Join (" ", File.ReadAllLines (responseFileName)));
196
266
exitCode = DoCompilation (outstr, tf, workingDir, ref output);
198
CompilerResults results = new CompilerResults (tf);
199
DefaultCompilerResult result = new DefaultCompilerResult (results, output);
201
268
monitor.Log.WriteLine (output);
203
ParseOutput(tf, output, results);
205
if (results.Errors.Count == 0 && exitCode != 0) {
269
BuildResult result = ParseOutput (tf, output);
270
if (result.Errors.Count == 0 && exitCode != 0) {
206
271
// Compilation failed, but no errors?
207
272
// Show everything the compiler said.
208
273
result.AddError (output);
211
FileService.DeleteFile (responseFileName);
212
if (configuration.CompileTarget != CompileTarget.Library) {
213
WriteManifestFile(exe);
218
// code duplication: see C# backend : CSharpBindingCompilerManager
219
void WriteManifestFile(string fileName)
221
string manifestFile = String.Concat(fileName, ".manifest");
222
if (File.Exists(manifestFile)) {
225
StreamWriter sw = new StreamWriter(manifestFile);
226
sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
228
sw.WriteLine("<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">");
229
sw.WriteLine(" <dependency>");
230
sw.WriteLine(" <dependentAssembly>");
231
sw.WriteLine(" <assemblyIdentity");
232
sw.WriteLine(" type=\"win32\"");
233
sw.WriteLine(" name=\"Microsoft.Windows.Common-Controls\"");
234
sw.WriteLine(" version=\"6.0.0.0\"");
235
sw.WriteLine(" processorArchitecture=\"X86\"");
236
sw.WriteLine(" publicKeyToken=\"6595b64144ccf1df\"");
237
sw.WriteLine(" language=\"*\"");
239
sw.WriteLine(" </dependentAssembly>");
240
sw.WriteLine(" </dependency>");
241
sw.WriteLine("</assembly>");
245
void ParseOutput(TempFileCollection tf, string output, CompilerResults cr)
276
FileService.DeleteFile (responseFileName);
277
if (configuration.CompileTarget != CompileTarget.Library) {
278
WriteManifestFile (exe);
283
// code duplication: see C# backend : CSharpBindingCompilerManager
284
void WriteManifestFile(string fileName)
286
string manifestFile = String.Concat(fileName, ".manifest");
287
if (File.Exists(manifestFile)) {
290
StreamWriter sw = new StreamWriter(manifestFile);
291
sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
293
sw.WriteLine("<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">");
294
sw.WriteLine(" <dependency>");
295
sw.WriteLine(" <dependentAssembly>");
296
sw.WriteLine(" <assemblyIdentity");
297
sw.WriteLine(" type=\"win32\"");
298
sw.WriteLine(" name=\"Microsoft.Windows.Common-Controls\"");
299
sw.WriteLine(" version=\"6.0.0.0\"");
300
sw.WriteLine(" processorArchitecture=\"X86\"");
301
sw.WriteLine(" publicKeyToken=\"6595b64144ccf1df\"");
302
sw.WriteLine(" language=\"*\"");
304
sw.WriteLine(" </dependentAssembly>");
305
sw.WriteLine(" </dependency>");
306
sw.WriteLine("</assembly>");
310
BuildResult ParseOutput(TempFileCollection tf, string output)
312
CompilerResults results = new CompilerResults (tf);
247
314
using (StringReader sr = new StringReader (output)) {
249
316
string curLine = sr.ReadLine();