mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
working on generalized compiler interfacing
This commit is contained in:
parent
fdb004d7c3
commit
0fa7409d96
11 changed files with 302 additions and 73 deletions
|
@ -20,12 +20,11 @@ With this interface supports the following placeholders in command-line paramete
|
|||
|
||||
%FO indicates the output path and filename.
|
||||
|
||||
%PI indicates the path of the input file (without filename).
|
||||
|
||||
%PO indicates the path of the output file (without filename).
|
||||
|
||||
%PT indicates the temporary directory path where the compiler is located.
|
||||
|
||||
%PW indicates the path of the open wad file when compiled as internal script lump.
|
||||
If compiled as file, or the wad file is not saved, %PW is the same as %PT
|
||||
|
||||
These placeholders are case-sensitive!
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
|
|
|
@ -26,15 +26,19 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using System.Windows.Forms;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Compilers
|
||||
{
|
||||
public sealed class AccCompiler : Compiler
|
||||
internal sealed class AccCompiler : Compiler
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const string ACS_ERROR_FILE = "acs.err";
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
@ -65,15 +69,113 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This runs the compiler with a file as input.
|
||||
public override bool CompileFile(string filename)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// This runs the compiler with lump data as input.
|
||||
public override bool CompileLump(Stream lumpdata)
|
||||
// This runs the compiler
|
||||
public override bool Run()
|
||||
{
|
||||
ProcessStartInfo processinfo;
|
||||
Process process;
|
||||
TimeSpan deltatime;
|
||||
string waddir = null;
|
||||
int line = 0;
|
||||
|
||||
// Find wad directory
|
||||
if(General.Map.FilePathName.Length > 0)
|
||||
waddir = Path.GetDirectoryName(General.Map.FilePathName);
|
||||
|
||||
// When no luck, use temp path
|
||||
if(waddir == null) waddir = this.tempdir.FullName;
|
||||
|
||||
// Create parameters
|
||||
string args = this.parameters;
|
||||
args = args.Replace("%FI", inputfile);
|
||||
args = args.Replace("%FO", outputfile);
|
||||
args = args.Replace("%PT", this.tempdir.FullName);
|
||||
args = args.Replace("%PW", waddir);
|
||||
|
||||
// Setup process info
|
||||
processinfo = new ProcessStartInfo();
|
||||
processinfo.Arguments = args;
|
||||
processinfo.FileName = Path.Combine(this.tempdir.FullName, info.ProgramFile);
|
||||
processinfo.CreateNoWindow = false;
|
||||
processinfo.ErrorDialog = false;
|
||||
processinfo.UseShellExecute = true;
|
||||
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
processinfo.WorkingDirectory = this.workingdir;
|
||||
|
||||
// Output info
|
||||
General.WriteLogLine("Running compiler...");
|
||||
General.WriteLogLine("Program: " + processinfo.FileName);
|
||||
General.WriteLogLine("Arguments: " + processinfo.Arguments);
|
||||
|
||||
try
|
||||
{
|
||||
// Start the compiler
|
||||
process = Process.Start(processinfo);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Unable to start the compiler
|
||||
General.ShowErrorMessage("Unable to start the compiler (" + info.Name + "). " + e.GetType().Name + ": " + e.Message, MessageBoxButtons.OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for compiler to complete
|
||||
process.WaitForExit();
|
||||
deltatime = TimeSpan.FromTicks(process.ExitTime.Ticks - process.StartTime.Ticks);
|
||||
General.WriteLogLine("Compiler process has finished.");
|
||||
General.WriteLogLine("Compile time: " + deltatime.TotalSeconds.ToString("########0.00") + " seconds");
|
||||
|
||||
// Now find the error file
|
||||
string errfile = Path.Combine(this.tempdir.FullName, ACS_ERROR_FILE);
|
||||
if(File.Exists(errfile))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Regex to find error lines
|
||||
Regex errlinematcher = new Regex("\\:[0-9]+\\:\\b", RegexOptions.Compiled | RegexOptions.CultureInvariant);
|
||||
|
||||
// Read all lines
|
||||
string[] errlines = File.ReadAllLines(errfile);
|
||||
while(line < errlines.Length)
|
||||
{
|
||||
// Check line
|
||||
string linestr = errlines[line];
|
||||
Match match = errlinematcher.Match(linestr);
|
||||
if(match.Success && (match.Index > 0))
|
||||
{
|
||||
CompilerError err = new CompilerError();
|
||||
|
||||
// The match without spaces and semicolon is the line number
|
||||
string linenr = match.Value.Replace(":", "").Trim();
|
||||
if(!int.TryParse(linenr, out err.linenumber))
|
||||
err.linenumber = CompilerError.NO_LINE_NUMBER;
|
||||
|
||||
// Everything before the match is the filename
|
||||
err.filename = linestr.Substring(0, match.Index);
|
||||
if(!Path.IsPathRooted(err.filename))
|
||||
{
|
||||
// Add working directory to filename
|
||||
err.filename = Path.Combine(processinfo.WorkingDirectory, err.filename);
|
||||
}
|
||||
|
||||
// Everything after the match is the description
|
||||
err.description = linestr.Substring(match.Index + match.Length).Trim();
|
||||
|
||||
// Report the error
|
||||
ReportError(err);
|
||||
}
|
||||
|
||||
// Next line
|
||||
line++;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Error reading errors (ironic, isn't it)
|
||||
ReportError(new CompilerError("Failed to retrieve compiler error report. " + e.GetType().Name + ": " + e.Message));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
protected CompilerInfo info;
|
||||
protected string parameters;
|
||||
protected string workingdir;
|
||||
protected string outputfile;
|
||||
protected string inputfile;
|
||||
|
||||
// Files
|
||||
protected DirectoryInfo tempdir;
|
||||
|
@ -53,9 +55,11 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
|
||||
public string Parameters { get { return parameters; } set { parameters = value; } }
|
||||
public string WorkingDirectory { get { return workingdir; } set { workingdir = value; } }
|
||||
public string InputFile { get { return inputfile; } set { inputfile = value; } }
|
||||
public string OutputFile { get { return outputfile; } set { outputfile = value; } }
|
||||
public string Location { get { return tempdir.FullName; } }
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public CompilerError[] Errors { get { return errors.ToArray(); } }
|
||||
|
@ -114,16 +118,10 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// This runs the compiler with a file as input.
|
||||
/// This runs the compiler.
|
||||
/// </summary>
|
||||
/// <returns>Returns false when failed to start.</returns>
|
||||
public virtual bool CompileFile(string filename) { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// This runs the compiler with lump data as input.
|
||||
/// </summary>
|
||||
/// <returns>Returns false when failed to start.</returns>
|
||||
public virtual bool CompileLump(Stream lumpdata) { return false; }
|
||||
public virtual bool Run() { return false; }
|
||||
|
||||
/// <summary>
|
||||
/// Use this to report an error.
|
||||
|
@ -151,8 +149,14 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
// Go for all assemblies
|
||||
foreach(Assembly a in asms)
|
||||
{
|
||||
Type[] types;
|
||||
|
||||
// Find the class
|
||||
Type[] types = a.GetExportedTypes();
|
||||
if(a == General.ThisAssembly)
|
||||
types = a.GetTypes();
|
||||
else
|
||||
types = a.GetExportedTypes();
|
||||
|
||||
foreach(Type t in types)
|
||||
{
|
||||
if(t.IsSubclassOf(typeof(Compiler)) && (t.Name == info.ProgramInterface))
|
||||
|
|
|
@ -30,11 +30,30 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
{
|
||||
public struct CompilerError
|
||||
{
|
||||
// Constants
|
||||
public const int NO_LINE_NUMBER = -1;
|
||||
|
||||
// Members
|
||||
public string description;
|
||||
public string filename;
|
||||
public int linenumber;
|
||||
|
||||
// Constructor
|
||||
public CompilerError(string description)
|
||||
{
|
||||
this.description = description;
|
||||
this.filename = "";
|
||||
this.linenumber = NO_LINE_NUMBER;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public CompilerError(string description, string filename)
|
||||
{
|
||||
this.description = description;
|
||||
this.filename = filename;
|
||||
this.linenumber = NO_LINE_NUMBER;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public CompilerError(string description, string filename, int linenumber)
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ using System.Windows.Forms;
|
|||
|
||||
namespace CodeImp.DoomBuilder.Compilers
|
||||
{
|
||||
public sealed class NodesCompiler : Compiler
|
||||
internal sealed class NodesCompiler : Compiler
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
@ -39,15 +39,10 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
|
||||
#region ================== Variables
|
||||
|
||||
// Output file
|
||||
private string outputfile;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public string OutputFile { get { return outputfile; } set { outputfile = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
@ -79,7 +74,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
#region ================== Methods
|
||||
|
||||
// This runs the compiler with a file as input.
|
||||
public override bool CompileFile(string filename)
|
||||
public override bool Run()
|
||||
{
|
||||
ProcessStartInfo processinfo;
|
||||
Process process;
|
||||
|
@ -87,7 +82,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
|
||||
// Create parameters
|
||||
string args = this.parameters;
|
||||
args = args.Replace("%FI", filename);
|
||||
args = args.Replace("%FI", inputfile);
|
||||
args = args.Replace("%FO", outputfile);
|
||||
|
||||
// Setup process info
|
||||
|
@ -98,7 +93,7 @@ namespace CodeImp.DoomBuilder.Compilers
|
|||
processinfo.ErrorDialog = false;
|
||||
processinfo.UseShellExecute = true;
|
||||
processinfo.WindowStyle = ProcessWindowStyle.Hidden;
|
||||
processinfo.WorkingDirectory = this.tempdir.FullName;
|
||||
processinfo.WorkingDirectory = this.workingdir;
|
||||
|
||||
// Output info
|
||||
General.WriteLogLine("Running compiler...");
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace CodeImp.DoomBuilder.Config
|
|||
string compilername;
|
||||
|
||||
General.WriteLogLine("Registered nodebuilder configuration '" + name + "' from '" + filename + "'");
|
||||
|
||||
|
||||
// Initialize
|
||||
this.name = name;
|
||||
this.compiler = null;
|
||||
|
@ -111,20 +111,9 @@ namespace CodeImp.DoomBuilder.Config
|
|||
}
|
||||
|
||||
// This runs the nodebuilder
|
||||
public NodesCompiler CreateCompiler()
|
||||
public Compiler CreateCompiler()
|
||||
{
|
||||
Compiler c = compiler.Create();
|
||||
if(c is NodesCompiler)
|
||||
{
|
||||
NodesCompiler ns = (c as NodesCompiler);
|
||||
ns.Parameters = parameters;
|
||||
return ns;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nodebuilders must use a NodesCompiler!
|
||||
throw new ArgumentException("Cannot create compiler interface '" + compiler.ProgramInterface + "' for nodebuilder '" + name + "'. Nodebuilders must use a NodesCompiler compiler interface!");
|
||||
}
|
||||
return compiler.Create();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -93,7 +93,12 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
|
||||
// This compiles the script
|
||||
public virtual void Compile()
|
||||
{
|
||||
}
|
||||
|
||||
// This saves the document (used for both explicit and implicit)
|
||||
// Return true when successfully saved
|
||||
public virtual bool Save()
|
||||
|
|
|
@ -394,7 +394,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A tab is selected
|
||||
private void tabs_Selecting(object sender, TabControlCancelEventArgs e)
|
||||
{
|
||||
|
@ -408,16 +408,19 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
CloseScript(t, false);
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
|
||||
// Compile Script clicked
|
||||
private void buttoncompile_Click(object sender, EventArgs e)
|
||||
{
|
||||
// First save all implicit scripts to the temporary wad file
|
||||
ImplicitSave();
|
||||
|
||||
// TODO: Now compile this lump
|
||||
// Compile script
|
||||
ScriptDocumentTab t = (tabs.SelectedTab as ScriptDocumentTab);
|
||||
t.Compile();
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
|
||||
// Undo clicked
|
||||
private void buttonundo_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
@ -425,7 +428,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
t.Undo();
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
|
||||
// Redo clicked
|
||||
private void buttonredo_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
@ -433,7 +436,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
t.Redo();
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
|
||||
// Cut clicked
|
||||
private void buttoncut_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
@ -441,7 +444,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
t.Cut();
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
|
||||
// Copy clicked
|
||||
private void buttoncopy_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,7 @@ using CodeImp.DoomBuilder.Config;
|
|||
using CodeImp.DoomBuilder.Types;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Compilers;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -80,6 +81,49 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This compiles the script file
|
||||
public override void Compile()
|
||||
{
|
||||
DirectoryInfo tempdir;
|
||||
Compiler compiler;
|
||||
string inputfile, outputfile;
|
||||
|
||||
// List of errors
|
||||
List<CompilerError> errors = new List<CompilerError>();
|
||||
|
||||
try
|
||||
{
|
||||
// Initialize compiler
|
||||
compiler = config.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
return;
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = config.Parameters;
|
||||
compiler.InputFile = Path.GetFileName(filepathname);
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(filepathname);
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
errors.AddRange(compiler.Errors);
|
||||
}
|
||||
|
||||
// Dispose compiler
|
||||
compiler.Dispose();
|
||||
|
||||
// TODO: Feed errors to panel
|
||||
|
||||
}
|
||||
|
||||
// This saves the document (used for both explicit and implicit)
|
||||
// Return true when successfully saved
|
||||
public override bool Save()
|
||||
|
|
|
@ -40,9 +40,9 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
|
||||
private string lumpname;
|
||||
|
||||
#endregion
|
||||
|
@ -90,6 +90,13 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// Compile script
|
||||
public override void Compile()
|
||||
{
|
||||
// Do it!
|
||||
General.Map.CompileLump(lumpname);
|
||||
}
|
||||
|
||||
// Implicit save
|
||||
public override bool Save()
|
||||
{
|
||||
|
|
|
@ -89,6 +89,7 @@ namespace CodeImp.DoomBuilder
|
|||
private Launcher launcher;
|
||||
private ThingsFilter thingsfilter;
|
||||
private ScriptEditorForm scriptwindow;
|
||||
private List<CompilerError> errors;
|
||||
|
||||
// Disposing
|
||||
private bool isdisposed = false;
|
||||
|
@ -121,6 +122,7 @@ namespace CodeImp.DoomBuilder
|
|||
public IMapSetIO FormatInterface { get { return io; } }
|
||||
internal Launcher Launcher { get { return launcher; } }
|
||||
public ThingsFilter ThingsFilter { get { return thingsfilter; } }
|
||||
internal List<CompilerError> Errors { get { return errors; } }
|
||||
public bool IsScriptsWindowOpen { get { return (scriptwindow != null) && !scriptwindow.IsDisposed; } }
|
||||
|
||||
#endregion
|
||||
|
@ -557,7 +559,7 @@ namespace CodeImp.DoomBuilder
|
|||
{
|
||||
// Create the compiler interface that will run the nodebuilder
|
||||
// This automatically creates a temporary directory for us
|
||||
NodesCompiler compiler = nodebuilder.CreateCompiler();
|
||||
Compiler compiler = nodebuilder.CreateCompiler();
|
||||
|
||||
// Make temporary filename
|
||||
tempfile1 = General.MakeTempFilename(compiler.Location);
|
||||
|
@ -587,8 +589,11 @@ namespace CodeImp.DoomBuilder
|
|||
buildwad.Dispose();
|
||||
|
||||
// Run the nodebuilder
|
||||
compiler.Parameters = nodebuilder.Parameters;
|
||||
compiler.InputFile = Path.GetFileName(tempfile1);
|
||||
compiler.OutputFile = Path.GetFileName(tempfile2);
|
||||
if(compiler.CompileFile(Path.GetFileName(tempfile1)))
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(tempfile1);
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Open the output file
|
||||
buildwad = new WAD(tempfile2);
|
||||
|
@ -1116,27 +1121,84 @@ namespace CodeImp.DoomBuilder
|
|||
}
|
||||
|
||||
// This compiles a script lump and returns any errors that may have occurred
|
||||
internal CompilerError[] CompileLump(Lump scriptlump, bool showwarning)
|
||||
// Returns true when our code worked properly (even when the compiler returned errors)
|
||||
internal bool CompileLump(string lumpname)
|
||||
{
|
||||
DirectoryInfo tempdir;
|
||||
CompilerError[] errors;
|
||||
Compiler compiler;
|
||||
string inputfile, outputfile;
|
||||
|
||||
// Find the lump
|
||||
Lump lump = tempwad.FindLump(lumpname);
|
||||
if(lump == null) throw new Exception("No such lump in temporary wad file '" + lumpname + "'.");
|
||||
|
||||
// New list of errors
|
||||
errors = new List<CompilerError>();
|
||||
|
||||
// Determine the script configuration to use
|
||||
ScriptConfiguration scriptconfig = config.MapLumps[scriptlump.Name].script;
|
||||
|
||||
// Initialize compiler
|
||||
Compiler compiler = scriptconfig.Compiler.Create();
|
||||
|
||||
ScriptConfiguration scriptconfig = config.MapLumps[lump.Name].script;
|
||||
|
||||
try
|
||||
{
|
||||
// Initialize compiler
|
||||
compiler = scriptconfig.Compiler.Create();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
errors.Add(new CompilerError("Unable to initialize compiler. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Write lump data to temp script file in compiler's temp directory
|
||||
inputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
lump.Stream.Seek(0, SeekOrigin.Begin);
|
||||
BinaryReader reader = new BinaryReader(lump.Stream);
|
||||
File.WriteAllBytes(inputfile, reader.ReadBytes((int)lump.Stream.Length));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors.Add(new CompilerError("Unable to write script to working file. " + e.GetType().Name + ": " + e.Message));
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make random output filename
|
||||
outputfile = General.MakeTempFilename(compiler.Location, "tmp");
|
||||
|
||||
// Run compiler
|
||||
compiler.Parameters = scriptconfig.Parameters;
|
||||
|
||||
errors = compiler.Errors;
|
||||
|
||||
// Clean up
|
||||
compiler.Dispose();
|
||||
|
||||
// Done
|
||||
return errors;
|
||||
compiler.InputFile = Path.GetFileName(inputfile);
|
||||
compiler.OutputFile = Path.GetFileName(outputfile);
|
||||
compiler.WorkingDirectory = Path.GetDirectoryName(inputfile);
|
||||
if(compiler.Run())
|
||||
{
|
||||
// Fetch errors
|
||||
errors.AddRange(compiler.Errors);
|
||||
|
||||
// Clean up
|
||||
compiler.Dispose();
|
||||
if(errors.Count == 0) errors = null;
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fail
|
||||
compiler.Dispose();
|
||||
errors = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This clears all compiler errors
|
||||
internal void ClearCompilerErrors()
|
||||
{
|
||||
errors = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
Loading…
Reference in a new issue