Moved to ADO2024 PI#
Ran SortCodeMethods
This commit is contained in:
299
ADO2024/PI1/Helper-2024-01-08.cs
Normal file
299
ADO2024/PI1/Helper-2024-01-08.cs
Normal file
@ -0,0 +1,299 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace File_Folder_Helper.ADO2024.PI1;
|
||||
|
||||
internal static partial class Helper20240108
|
||||
{
|
||||
|
||||
private record Method(string Name,
|
||||
int ParameterCount,
|
||||
int StartLine,
|
||||
int EndLine,
|
||||
int FirstUsedLine);
|
||||
|
||||
[GeneratedRegex(@"(?<method>[A-Z]{1}[A-Za-z_0-9]*)\(")]
|
||||
private static partial Regex CSharpMethodName();
|
||||
|
||||
[GeneratedRegex(@"\s[a-zA-Z_]*,")]
|
||||
private static partial Regex CSharpParameter();
|
||||
|
||||
[GeneratedRegex(@"\b(public|private|internal|protected)\s\b(static)?\s?\b(partial)?\s?\b(async)?\s?[[\]<,>?a-zA-Z()\s]*\s[A-Z]{1}[a-zA-Z_]+\(.*\)")]
|
||||
private static partial Regex CSharpMethodLine();
|
||||
|
||||
private static string? GetName(string line)
|
||||
{
|
||||
string? result;
|
||||
Match match = CSharpMethodName().Match(line);
|
||||
if (!match.Success)
|
||||
result = null;
|
||||
else
|
||||
result = match.Groups["method"].Value;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int GetStartLine(string[] lines, int i)
|
||||
{
|
||||
int result = i;
|
||||
string line;
|
||||
for (int j = i - 1; j > -1; j--)
|
||||
{
|
||||
line = lines[j].Trim();
|
||||
if (!line.StartsWith('[') && !line.StartsWith("/// "))
|
||||
break;
|
||||
result--;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int GetParameterCount(string line, string search)
|
||||
{
|
||||
int result;
|
||||
string after = line.Split(search)[^1];
|
||||
if (after.StartsWith(')'))
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
string[] segments = CSharpParameter().Split(after);
|
||||
result = segments.Length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int GetLineBlockCount(string line, bool isLinq)
|
||||
{
|
||||
int result = 0;
|
||||
bool ignore = false;
|
||||
for (int i = 0; i < line.Length; i++)
|
||||
{
|
||||
if (line[i] == '\'')
|
||||
i++;
|
||||
else if (!isLinq && !ignore && line[i] == '{')
|
||||
result++;
|
||||
else if (!isLinq && !ignore && line[i] == '}')
|
||||
result--;
|
||||
else if (isLinq && !ignore && line[i] == ';')
|
||||
result--;
|
||||
else if (i > 0 && line[i] == '"' && line[i - 1] != '\\')
|
||||
ignore = !ignore;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int? GetFirstUsedLine(string[] lines, int i, string search, string searchNot, string searchWrap, string searchDelegate, string searchConstructor, int parameterCount)
|
||||
{
|
||||
int? result = null;
|
||||
string[] segments;
|
||||
string[] afterSegments;
|
||||
string lastSegmentBeforeDot;
|
||||
for (int j = 0; j < lines.Length; j++)
|
||||
{
|
||||
if (j == i)
|
||||
continue;
|
||||
segments = lines[j].Split(search);
|
||||
if (segments.Length == 1)
|
||||
{
|
||||
segments = lines[j].Split(searchNot);
|
||||
if (segments.Length == 1)
|
||||
{
|
||||
segments = lines[j].Split(searchWrap);
|
||||
if (segments.Length == 1)
|
||||
{
|
||||
if (!lines[j].EndsWith(searchDelegate))
|
||||
{
|
||||
segments = lines[j].Split(searchConstructor);
|
||||
if (segments.Length == 1)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lines[j].EndsWith(searchDelegate))
|
||||
{
|
||||
result = j;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastSegmentBeforeDot = segments[^1].Split(").")[0];
|
||||
if (parameterCount == 0)
|
||||
{
|
||||
if (lastSegmentBeforeDot.Contains(','))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
afterSegments = lastSegmentBeforeDot.Split(',');
|
||||
if (afterSegments.Length != parameterCount)
|
||||
continue;
|
||||
}
|
||||
result = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<int> GetMethodLines(ReadOnlyCollection<Method> methods)
|
||||
{
|
||||
List<int> results = [];
|
||||
foreach (Method method in methods)
|
||||
{
|
||||
for (int i = method.StartLine; i < method.EndLine + 1; i++)
|
||||
results.Add(i);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Method> GetMethods(string cSharpFile, ILogger<Worker> logger, string[] lines)
|
||||
{
|
||||
List<Method> results = [];
|
||||
int blocks;
|
||||
bool isLinq;
|
||||
int endLine;
|
||||
string line;
|
||||
string? name;
|
||||
int startLine;
|
||||
string search;
|
||||
string innerLine;
|
||||
string searchNot;
|
||||
string searchWrap;
|
||||
int parameterCount;
|
||||
int? firstUsedLine;
|
||||
string searchDelegate;
|
||||
string lineSegmentFirst;
|
||||
string searchConstructor;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
line = lines[i].Trim();
|
||||
if (string.IsNullOrEmpty(line))
|
||||
continue;
|
||||
if (line.Length < 5)
|
||||
continue;
|
||||
if (line.EndsWith(','))
|
||||
continue;
|
||||
if (!CSharpMethodLine().Match(line).Success)
|
||||
continue;
|
||||
name = GetName(line);
|
||||
search = $" {name}(";
|
||||
searchNot = $"!{name}(";
|
||||
searchWrap = $"({name}(";
|
||||
searchDelegate = $" += {name};";
|
||||
if (string.IsNullOrEmpty(name))
|
||||
continue;
|
||||
blocks = 0;
|
||||
startLine = GetStartLine(lines, i);
|
||||
searchConstructor = $"{name.ToLower()} = new(";
|
||||
parameterCount = GetParameterCount(line, search);
|
||||
isLinq = lines[i + 1].Trim() != "{";
|
||||
if (isLinq)
|
||||
blocks++;
|
||||
for (int j = i + 1; j < lines.Length; j++)
|
||||
{
|
||||
innerLine = lines[j].Trim();
|
||||
if (isLinq && string.IsNullOrEmpty(innerLine))
|
||||
{
|
||||
if (line.EndsWith(';'))
|
||||
blocks--;
|
||||
}
|
||||
blocks += GetLineBlockCount(innerLine, isLinq);
|
||||
if (blocks == 0)
|
||||
{
|
||||
endLine = j;
|
||||
if (lines.Length > j + 1 && string.IsNullOrEmpty(lines[j + 1].Trim()))
|
||||
endLine++;
|
||||
firstUsedLine = GetFirstUsedLine(lines, i, search, searchNot, searchWrap, searchDelegate, searchConstructor, parameterCount);
|
||||
if (firstUsedLine is null)
|
||||
{
|
||||
lineSegmentFirst = line.Split(search)[0];
|
||||
if (!lines[i - 1].Trim().StartsWith("[Obsolete"))
|
||||
{
|
||||
if (lineSegmentFirst.StartsWith("private"))
|
||||
logger.LogWarning("<{cSharpFileName}> {name} with {parameterCount} parameter(s) <{line}>", Path.GetFileName(cSharpFile), name, parameterCount, lineSegmentFirst);
|
||||
else
|
||||
logger.LogInformation("<{cSharpFileName}> {name} with {parameterCount} parameter(s) <{line}>", Path.GetFileName(cSharpFile), name, parameterCount, lineSegmentFirst);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (j > lines.Length - 2)
|
||||
throw new Exception();
|
||||
results.Add(new(name, parameterCount, startLine, endLine, firstUsedLine.Value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(results.OrderBy(l => l.FirstUsedLine).ToArray());
|
||||
}
|
||||
|
||||
private static bool WriteAllLines(string cSharpFile, string[] lines, ReadOnlyCollection<Method> methods)
|
||||
{
|
||||
bool result;
|
||||
List<string> results = [];
|
||||
ReadOnlyCollection<int> methodLines = GetMethodLines(methods);
|
||||
int minMethodLines = methodLines.Min();
|
||||
for (int i = 0; i < minMethodLines; i++)
|
||||
results.Add(lines[i]);
|
||||
foreach (Method method in methods)
|
||||
{
|
||||
for (int i = method.StartLine; i < method.EndLine + 1; i++)
|
||||
results.Add(lines[i]);
|
||||
}
|
||||
for (int i = minMethodLines; i < lines.Length; i++)
|
||||
{
|
||||
if (methodLines.Contains(i))
|
||||
continue;
|
||||
results.Add(lines[i]);
|
||||
}
|
||||
string text = File.ReadAllText(cSharpFile);
|
||||
string join = string.Join(Environment.NewLine, results);
|
||||
if (join == text)
|
||||
result = false;
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
File.WriteAllText(cSharpFile, join);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool SortFile(ILogger<Worker> logger, string cSharpFile, string[] lines)
|
||||
{
|
||||
bool result;
|
||||
ReadOnlyCollection<Method> methods = GetMethods(cSharpFile, logger, lines);
|
||||
if (methods.Count == 0)
|
||||
result = false;
|
||||
else
|
||||
result = WriteAllLines(cSharpFile, lines, methods);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static void SortCodeMethods(ILogger<Worker> logger, List<string> args, CancellationToken cancellationToken)
|
||||
{
|
||||
bool result = false;
|
||||
bool check;
|
||||
string[] lines;
|
||||
bool usePathCombine = true;
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
logger.LogInformation("{ticks}", ticks);
|
||||
string directory = Path.GetFullPath(args[2]);
|
||||
string repositoryDirectory = Path.GetFullPath(args[0]);
|
||||
string[] cSharpFiles = Directory.GetFiles(directory, "*.cs", SearchOption.AllDirectories);
|
||||
ReadOnlyCollection<string> gitOthersModifiedAndDeletedExcludingStandardFiles = Helpers.HelperGit.GetOthersModifiedAndDeletedExcludingStandardFiles(repositoryDirectory, usePathCombine, cancellationToken);
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
foreach (string cSharpFile in cSharpFiles)
|
||||
{
|
||||
if (!gitOthersModifiedAndDeletedExcludingStandardFiles.Contains(cSharpFile))
|
||||
continue;
|
||||
lines = File.ReadAllLines(cSharpFile);
|
||||
check = SortFile(logger, cSharpFile, lines);
|
||||
if (check && !result)
|
||||
result = true;
|
||||
}
|
||||
if (!result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user