///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
using System;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Tasks;
using Microsoft.Build.Utilities;
namespace JetBrains.Build
{
///
/// An MSBuild task that compiles the IL projects.
///
public class Ilasm : ManagedCompiler
{
#region Data
public static Regex myRegexError = new Regex(@"^\s*(?.+?)\((?\d+)\)\s+\:\s+error\s+\-\-\s+(?.*)$", RegexOptions.Compiled | RegexOptions.Singleline);
public static Regex myRegexWarning = new Regex(@"^\s*(?.+?)\((?\d+)\)\s+\:\s+warning\s+\-\-\s+(?.*)$", RegexOptions.Compiled | RegexOptions.Singleline);
#endregion
#region Init
public Ilasm()
{
HostCompilerSupportsAllParameters = false;
NoConfig = false;
}
#endregion
#region Implementation
///
/// Adds Ilasm-specific command-line commands not handled by the base class.
///
/// The command line to popuplate.
protected void AddMoreCommandLineCommands(CommandLineBuilderExtension commandLine)
{
AddMoreCommandLineCommands_TargetType(commandLine);
}
///
/// The target type command line commands.
///
/// The command line to popuplate.
protected void AddMoreCommandLineCommands_TargetType(CommandLineBuilderExtension commandLine)
{
CommandLineAppendWhenTrue(commandLine, "/DLL", "Dll");
CommandLineAppendWhenTrue(commandLine, "/EXE", "Exe");
}
///
/// Carries out an internal CommandLineBuilderExtension.AppendWhenTrue method.
///
protected void CommandLineAppendWhenTrue(CommandLineBuilderExtension commandLine, string switchName, string parameterName)
{
object o = Bag[parameterName];
if((o != null) && ((bool)o))
commandLine.AppendSwitch(switchName);
}
///
/// Adapts the bag property values to the Ilasm before they get into the command line.
///
protected void PreprocessBag()
{
PreprocessBag_TargetType();
}
///
/// Removes the TargetType property, adds the /dll and /exe instead.
///
protected void PreprocessBag_TargetType()
{
var sTargetType = Bag["TargetType"] as string;
if(sTargetType == null)
return;
// Suppress
Bag["TargetType"] = null;
// Inject the replacement
switch(sTargetType.ToLowerInvariant())
{
case "library":
Bag["Dll"] = true;
break;
case "winexe":
Bag["Exe"] = true;
break;
default:
Log.LogError(string.Format("Unexpected TargetType value {0}.", sTargetType));
break;
}
}
#endregion
#region Overrides
///
///Fills the specified with the switches and other information that cannot go into a response file.
///
///
///The to fill with switches and other information that cannot go into a response file.
protected override void AddCommandLineCommands(CommandLineBuilderExtension commandLine)
{
// Update values to fit the ilasm
PreprocessBag();
base.AddCommandLineCommands(commandLine);
base.AddResponseFileCommands(commandLine); // All the response file content goes to the command line for Ilasm
// Additional commands, not supported by the base class
AddMoreCommandLineCommands(commandLine);
}
///
///Fills the specified with the switches and other information that can go into a response file.
///
///
///The to fill with switches and other information.
protected override void AddResponseFileCommands(CommandLineBuilderExtension commandLine)
{
return; // Nothing goes to the response file, Ilasm won't support one
}
///
///Returns the fully qualified path to the executable file.
///
///
///
///The fully qualified path to the executable file.
///
///
protected override string GenerateFullPathToTool()
{
string path = ToolLocationHelper.GetPathToDotNetFrameworkFile(ToolName, TargetDotNetFrameworkVersion.VersionLatest);
if(path == null)
Log.LogError("Could not locate the {0} compiler.", ToolName);
return path;
}
///
///Parses a single line of text to identify any errors or warnings in canonical format.
///
///
///A value of that indicates the importance level with which to log the message.
///A single line of text for the method to parse.
protected override void LogEventsFromTextOutput(string text, MessageImportance messageImportance)
{
if(text.IndexOf("error --", StringComparison.InvariantCultureIgnoreCase) >= 0)
{
Match match = myRegexError.Match(text);
if(match.Success)
{
int nLine;
if(!int.TryParse(match.Groups["Line"].Value, out nLine))
nLine = 0;
Log.LogError("", "", "", match.Groups["Filename"].Value, nLine, 0, 0, 0, match.Groups["Text"].Value);
}
else
Log.LogError(text);
}
else if(text.IndexOf("warning --", StringComparison.InvariantCultureIgnoreCase) >= 0)
{
Match match = myRegexWarning.Match(text);
if(match.Success)
{
int nLine;
if(!int.TryParse(match.Groups["Line"].Value, out nLine))
nLine = 0;
Log.LogWarning("", "", "", match.Groups["Filename"].Value, nLine, 0, 0, 0, match.Groups["Text"].Value);
}
else
Log.LogWarning(text);
}
else
base.LogEventsFromTextOutput(text, messageImportance);
}
///
///Gets the name of the executable file to run.
///
///
///
///The name of the executable file to run.
///
///
protected override string ToolName
{
get
{
return "IlAsm.exe";
}
}
#endregion
}
}