public bool Build(string path, string sourceName)
{
if (!_mappings.Any())
{
return false;
}
var mappings = _mappings.OrderBy(item => item.GeneratedLine).ThenBy(item => item.GeneratedColumn).ToList();
var sources = new List<string>();
var names = new List<string>();
var previousGeneratedColumn = 0;
var previousGeneratedLine = 1;
var previousOriginalColumn = 0;
var previousOriginalLine = 0;
var previousName = 0;
var previousSource = 0;
StringBuilder result = new StringBuilder();
for (int i = 0; i < mappings.Count; i++)
{
var mapping = mappings[i];
if (mapping.Source != null && !sources.Contains(mapping.Source))
{
sources.Add(mapping.Source);
}
if (mapping.Name != null && !names.Contains(mapping.Name))
{
names.Add(mapping.Name);
}
if (mapping.GeneratedLine != previousGeneratedLine)
{
previousGeneratedColumn = 0;
while (mapping.GeneratedLine != previousGeneratedLine)
{
result.Append(';');
previousGeneratedLine++;
}
}
else
{
if (i > 0)
{
if (mapping == mappings[i - 1])
{
continue;
}
result.Append(',');
}
}
result.Append(Base64Vlq.Encode(mapping.GeneratedColumn - previousGeneratedColumn));
previousGeneratedColumn = mapping.GeneratedColumn;
if (mapping.Source != null)
{
var sourceIdx = sources.IndexOf(mapping.Source);
result.Append(Base64Vlq.Encode(sourceIdx - previousSource));
previousSource = sourceIdx;
// lines are stored 0-based in SourceMap spec version 3
result.Append(Base64Vlq.Encode(mapping.OriginalLine - 1 - previousOriginalLine));
previousOriginalLine = mapping.OriginalLine - 1;
result.Append(Base64Vlq.Encode(mapping.OriginalColumn - previousOriginalColumn));
previousOriginalColumn = mapping.OriginalColumn;
if (mapping.Name != null)
{
var nameIdx = names.IndexOf(mapping.Name);
result.Append(Base64Vlq.Encode(nameIdx - previousName));
previousName = nameIdx;
}
}
//else
//{
////IK: I'm not sure if we should do it?
// previousOriginalLine = 0;
// previousOriginalColumn = 0;
//}
}
var sourceMap = new StringBuilder();
sourceMap.AppendLine("{");
sourceMap.AppendLine("\t\"version\" : 3,");
sourceMap.AppendLine(string.Format("\t\"file\" : \"{0}\",", sourceName));
sourceMap.AppendLine(string.Format("\t\"sourceRoot\" : \"{0}\",", new Uri(Path.GetFullPath(path))));
sourceMap.AppendLine(string.Format("\t\"sources\" : [{0}],", string.Join(", ", sources.Select(item => "\"" + MakeRelativePath(path, item) + "\""))));
sourceMap.AppendLine(string.Format("\t\"names\" : [{0}],", string.Join(", ", names.Select(item => "\"" + item + "\""))));
sourceMap.AppendLine(string.Format("\t\"mappings\" : \"{0}\"", result));
sourceMap.AppendLine("}");
using (var file = File.Create(GetFullMapPath(path, sourceName)))
{
using (var tw = new StreamWriter(file))
{
tw.Write(sourceMap.ToString());
tw.Flush();
}
}
return true;
}