using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using VBASync.Localization;
namespace VBASync.Model
{
public static class ModuleProcessing
{
private static bool _inBlock;
public static string ExtensionFromType(ModuleType type)
{
switch (type)
{
case ModuleType.Class:
return ".cls";
case ModuleType.Form:
return ".frm";
case ModuleType.Standard:
return ".bas";
case ModuleType.StaticClass:
return ".cls";
case ModuleType.Ini:
return ".ini";
case ModuleType.Licenses:
return ".bin";
default:
throw new ApplicationException(VBASyncResources.ErrorUnrecognizedModuleType);
}
}
public static string FixCase(string oldString, string newString)
{
var sb = new StringBuilder();
var dr = VbaDiffer.CreateVbaDiffs(oldString, newString);
var aPos = 0;
var bPos = 0;
foreach (var db in dr.DiffBlocks)
{
while (bPos < db.InsertStartB)
{
if (sb.Length > 0)
{
sb.Append("\r\n");
}
sb.Append(dr.PiecesOld[aPos++]);
bPos++;
}
var i = 0;
aPos += db.DeleteCountA;
while (i < (db.DeleteCountA < db.InsertCountB ? db.DeleteCountA : db.InsertCountB))
{
var isVbBaseLine = (dr.PiecesNew[i + db.InsertStartB].StartsWith("Attribute VB_Base =", StringComparison.InvariantCultureIgnoreCase)
|| dr.PiecesNew[i + db.InsertStartB].StartsWith("Attribute VB_Base=", StringComparison.InvariantCultureIgnoreCase))
&& !dr.PiecesNew[i + db.InsertStartB].EndsWith("_")
&& (dr.PiecesOld[i + db.DeleteStartA].StartsWith("Attribute VB_Base =", StringComparison.InvariantCultureIgnoreCase)
|| dr.PiecesOld[i + db.DeleteStartA].StartsWith("Attribute VB_Base=", StringComparison.InvariantCultureIgnoreCase))
&& !dr.PiecesOld[i + db.DeleteStartA].EndsWith("_");
if (sb.Length > 0)
{
sb.Append("\r\n");
}
sb.Append(isVbBaseLine ? dr.PiecesOld[i++ + db.DeleteStartA] : dr.PiecesNew[i++ + db.InsertStartB]);
bPos++;
}
if (db.InsertCountB > db.DeleteCountA)
{
while (i < db.InsertCountB)
{
if (sb.Length > 0)
{
sb.Append("\r\n");
}
sb.Append(dr.PiecesNew[i++ + db.InsertStartB]);
bPos++;
}
}
}
while (aPos < dr.PiecesOld.Length)
{
if (sb.Length > 0)
{
sb.Append("\r\n");
}
sb.Append(dr.PiecesOld[aPos++]);
}
return sb.ToString();
}
internal static bool HasCode(string moduleText)
{
_inBlock = false;
return moduleText?.Split(new[] { "\r\n" }, StringSplitOptions.None).Any(LineIsCode) ?? false;
}
internal static string StubOut(string moduleText)
{
_inBlock = false;
var lines = moduleText?.Split(new[] { "\r\n" }, StringSplitOptions.None) ?? new string[0];
var sb = new StringBuilder();
for (var i = 0; i < lines.Length; ++i)
{
if (LineIsCode(lines[i]))
{
return sb.ToString();
}
sb.Append(lines[i]).Append("\r\n");
}
return sb.ToString();
}
internal static ModuleType TypeFromText(string moduleText)
{
if (Regex.IsMatch(moduleText, @"^\s*(\s_\r\n\s*)*Version\s*(\s_\r\n\s*)*5.00\s*(\s_\r\n\s*)*$",
RegexOptions.Multiline | RegexOptions.IgnoreCase))
{
return ModuleType.Form;
}
if (!Regex.IsMatch(moduleText, @"^\s*(\s_\r\n\s*)*Version\s*(\s_\r\n\s*)*1.0\s*(\s_\r\n\s*)*Class\s*(\s_\r\n\s*)*$",
RegexOptions.Multiline | RegexOptions.IgnoreCase))
{
return ModuleType.Standard;
}
if (Regex.IsMatch(moduleText, @"^\s*(\s_\r\n\s*)*Attribute\s*(\s_\r\n\s*)*VB_PredeclaredID\s*(\s_\r\n\s*)*=\s*(\s_\r\n\s*)*True\s*(\s_\r\n\s*)*$",
RegexOptions.Multiline | RegexOptions.IgnoreCase))
{
return ModuleType.StaticClass;
}
return ModuleType.Class;
}
private static bool LineIsCode(string line)
{
var trimLine = line?.TrimStart();
if (string.IsNullOrWhiteSpace(trimLine) || trimLine.StartsWith("Version", StringComparison.InvariantCultureIgnoreCase)
|| trimLine.StartsWith("Attribute", StringComparison.InvariantCultureIgnoreCase))
{
return false;
}
if (trimLine.StartsWith("Begin", StringComparison.InvariantCultureIgnoreCase))
{
_inBlock = true;
return false;
}
if (_inBlock && trimLine.StartsWith("End", StringComparison.InvariantCultureIgnoreCase))
{
_inBlock = false;
return false;
}
return !_inBlock;
}
}
}