using System;
using System.IO;
using System.Text.RegularExpressions;
using NAnt.Core.Attributes;
using NAnt.Core.Types;
using NAnt.DotNet.Tasks;
namespace Nemerle.Tools.NAntTasks
{
///
/// Compiles Nemerle programs.
///
[TaskName ("ncc")]
public class NccTask : CompilerBase
{
private static _classNameRegex : Regex = Regex (@"^((?/\*.*?(\*/|$))|[\s\.\{]+|class\s+(?\w+)|(?\w+))*");
private static _namespaceRegex : Regex = Regex (@"^((?/\*.*?(\*/|$))|[\s\.\{]+|namespace\s+(?(\w+(\.\w+)*)+)|(?\w+))*");
///
/// Initialize new instance of the .
///
public this ()
{
SupportsKeyFile = true;
}
private static FindExecutable (toolName : string) : string
{
def my_file = Uri (typeof (NccTask).Assembly.EscapedCodeBase).LocalPath;
def ncc_file = Path.Combine (Path.GetDirectoryName (my_file), toolName);
if (File.Exists (ncc_file)) {
// The tool found in the same folder.
//
ncc_file;
}
else {
// Query the shell association.
//
def regPath = $@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\$toolName.exe";
def regKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (regPath);
if (regKey != null) {
// The tool is registered with the Shell API.
//
regKey.GetValue (null) :> string;
}
else {
// Return the tool name itself.
// The environment will search common paths for the tool.
//
toolName;
}
}
}
///
/// The name of the executable that should be used to launch the
/// external program.
///
///
/// The name of the executable that should be used to launch the external
/// program, or if no name is specified.
///
///
/// If available, the configured value in the NAnt configuration
/// file will be used if no name is specified.
///
public override ExeName : string
{
get
{
when (base.ExeName == Name)
base.ExeName = FindExecutable (Name);
base.ExeName;
}
set { base.ExeName = value; }
}
///
/// Gets the class name regular expression for the language of the
/// current compiler.
///
///
/// Class name regular expression for the language of the current
/// compiler.
///
protected override ClassNameRegex : Regex
{
get { _classNameRegex; }
}
///
/// Gets the namespace regular expression for the language of the
/// current compiler.
///
///
/// Namespace regular expression for the language of the current
/// compiler.
///
protected override NamespaceRegex : Regex
{
get { _namespaceRegex; }
}
///
/// Gets the command-line arguments for the external program.
///
///
/// The command-line arguments for the external program.
///
public override ProgramArguments : string
{
// quoting is done in CompilerBase
//
get { "-from-file:" + base.ProgramArguments.Substring (1); }
}
///
/// Writes an option using the default output format.
///
/// The to which the compiler options should be written.
/// The name of the option which should be passed to the compiler.
protected override WriteOption (writer : TextWriter, name : string) : void
{
writer.WriteLine ("-{0}", name);
}
///
/// Writes an option and its value using the default output format.
///
/// The to which the compiler options should be written.
/// The name of the option which should be passed to the compiler.
/// The value of the option which should be passed to the compiler.
///
/// The combination of and
/// (separated by a colon) is quoted
/// unless is already surrounded by quotes.
///
protected override WriteOption (writer : TextWriter, name : string, arg : string) : void
{
writer.WriteLine ((if (arg.StartsWith ("\"") && arg.EndsWith ("\"")) "-{0}:{1}" else "\"-{0}:{1}\""), name, arg);
}
///
/// Writes the compiler options to the specified .
///
///
/// to which the compiler options should be written.
protected override WriteOptions (writer : TextWriter) : void
{
when (DocFile != null) {
WriteOption (writer, "xml", DocFile.FullName);
}
when (Debug) {
WriteOption (writer, "debug");
WriteOption (writer, "def", "DEBUG");
WriteOption (writer, "def", "TRACE");
}
when (NoStdLib) {
WriteOption (writer, "nostdlib");
WriteOption (writer, "nostdmacros");
}
when (Optimize) {
WriteOption (writer, "Ot");
}
WriteOption (writer, "greedy-");
WriteOption (writer, "no-color");
WriteOption (writer, "bar-");
}
///
/// Determines whether compilation is needed.
///
protected override NeedsCompiling () : bool
{
(DocFile != null &&
FileSet.FindMoreRecentLastWriteTime (
DocFile.FullName, OutputFile.LastWriteTime) != null) || base.NeedsCompiling ();
}
///
/// Gets the file extension required by the current compiler.
///
///
/// For the Nemerle compiler, the file extension is always n.
///
public override Extension : string
{
get { "n"; }
}
///
/// The name of the XML documentation file to generate.
///
///
///
/// Corresponds with the -doc: flag.
///
///
[TaskAttribute ("doc")]
public DocFile : FileInfo { get; set; }
///
/// Instructs the compiler not to import mscorlib.dll. The default is
/// .
///
///
///
/// Corresponds with the -nostdlib flag.
///
///
[TaskAttribute ("nostdlib")]
[BooleanValidator]
public NoStdLib : bool { get; set; }
///
/// Specifies whether the compiler should perform tail call optimizations
/// to make output files smaller, faster, and more effecient. The default
/// is .
///
///
/// if the compiler should perform optimizations;
/// otherwise, .
///
///
///
/// Corresponds with the -general-tail-call-opt flag.
///
///
[TaskAttribute ("optimize")]
[BooleanValidator]
public Optimize : bool { get; set; }
}
}