Skip to content

Commit

Permalink
重置目录,优化热执行,Main拦截实验.
Browse files Browse the repository at this point in the history
  • Loading branch information
NMSAzulX committed Jun 12, 2024
1 parent 01d17c4 commit a192e5c
Show file tree
Hide file tree
Showing 12 changed files with 137 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Diagnostics;
using System.Linq;

namespace Natasha.CSharp.Extension.HotExecutor.SG
{
[Generator]
public class HotExecutorGenerator : ISourceGenerator
{

public void Initialize(GeneratorInitializationContext context)
{
// No initialization required for this one
}

void ISourceGenerator.Execute(GeneratorExecutionContext context)
{
//Debugger.Launch();
var mainFile = string.Empty;
var lineNumber = 0;
var characterPosition = 0;
var syntaxTrees = context.Compilation.SyntaxTrees;
foreach (var tree in syntaxTrees)
{
var methods = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>();
if (methods.Any(method => method.Identifier.Text == "Main"))
{
var mainMethod = methods.FirstOrDefault(method => method.Identifier.Text == "Main");
mainFile = tree.FilePath;

var lineSpan = mainMethod.GetLocation().GetLineSpan();
lineNumber = lineSpan.StartLinePosition.Line + 1;
characterPosition = lineSpan.StartLinePosition.Character + 1;
//Debugger.Launch();
string proxyMethodContent = $@"
using System.Runtime.CompilerServices;
namespace System{{
public static class InterceptMain
{{
[InterceptsLocation(
filePath: @""{mainFile}"",
line: {lineNumber},
character: {characterPosition})]
public static void InterceptMethodMain(string args[])
{{
Console.WriteLine(11);
}}
}}
}}
// <auto-generated/>
namespace System.Runtime.CompilerServices
{{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute(string filePath, int line, int character) : Attribute
{{
}}
}}
";

context.AddSource($"NatashaHotExecutorProxy.g.cs", proxyMethodContent);
break;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>preview</LangVersion>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.8.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\Natasha.CSharp.Compiler\Natasha.CSharp.Compiler.csproj" />
<ProjectReference Include="..\..\..\Natasha.CSharp.Compiler\Natasha.CSharp.Compiler.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,14 @@ public static class ProjectDynamicProxy
private static Action? _endCallback;
private static readonly HESpinLock _buildLock;
private static readonly VSCSharpMainFileWatcher _mainWatcher;
private static string _commentTag = "//Once";
//private static readonly MethodDeclarationSyntax _emptyMainTree;
//private static string _callMethod;

public static void SetCommentTag(string comment)
{
_commentTag = comment;
}
static ProjectDynamicProxy()
{
NatashaManagement.Preheating(true, true);
Expand Down Expand Up @@ -196,13 +202,12 @@ public static void Run(string? argumentsMethodName = "ProxyMainArguments")

foreach (var file in srcCodeFiles)
{
if (_mainWatcher.CheckFileAvailiable(file))
if (VSCSharpFolder.CheckFileAvailiable(file))
{
var content = ReadFile(file);
var tree = HandleTree(content);
var root = tree.GetRoot();
_fileCache[file] = root.SyntaxTree;

}
}

Expand Down Expand Up @@ -244,7 +249,7 @@ private static SyntaxTree HandleTree(string content)
var trivias = statement.GetLeadingTrivia();
foreach (var trivia in trivias)
{
if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) && trivia.ToString().Trim().StartsWith("//Once"))
if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) && trivia.ToString().Trim().StartsWith(_commentTag))
{
removeIndexs.Add(i);
break;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using System.Xml;

namespace Natasha.CSharp.Extension.HotExecutor
{
Expand All @@ -13,8 +14,10 @@ public static class VSCSharpFolder
public static readonly string ExecuteName;
public static readonly string ExecutePath;
public static readonly string CSProjFilePath;
public static readonly HashSet<string> ExpectFiles;
static VSCSharpFolder()
{
ExpectFiles = [];
var currentExeFilePath = Process.GetCurrentProcess().MainModule.FileName;
ExecutePath = new FileInfo(currentExeFilePath).Directory!.FullName;
var currentDirectoryInfo = new DirectoryInfo(ExecutePath);
Expand All @@ -27,6 +30,25 @@ static VSCSharpFolder()
ReleasePath = Path.Combine(BinPath, "Release");
ExecuteName = Path.GetFileName(currentExeFilePath);
SlnPath = FindFileDirectory(currentDirectoryInfo,"*.sln");

XmlDocument doc = new XmlDocument();
doc.Load(CSProjFilePath);

XmlNodeList itemGroupNodes = doc.SelectNodes("//ItemGroup");

foreach (XmlNode itemGroupNode in itemGroupNodes)
{
XmlNodeList compileNodes = itemGroupNode.SelectNodes("Compile[@Remove]");

foreach (XmlNode compileNode in compileNodes)
{
string removedFile = compileNode.Attributes["Remove"].Value;
if (removedFile.EndsWith(".cs"))
{
ExpectFiles.Add(Path.Combine(MainCsprojPath,removedFile));
}
}
}
}

static string FindFileDirectory(DirectoryInfo csprojDirectory, string suffix)
Expand All @@ -42,5 +64,14 @@ static string FindFileDirectory(DirectoryInfo csprojDirectory, string suffix)
}
throw new Exception("没有找到 sln 根文件!");
}

public static bool CheckFileAvailiable(string file)
{
if (file.StartsWith(VSCSharpFolder.ObjPath) || file.StartsWith(VSCSharpFolder.BinPath) || VSCSharpFolder.ExpectFiles.Contains(file))
{
return false;
}
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void StartMonitor()
Console.WriteLine($"Created: {e.FullPath}");
#endif

if (CheckFileAvailiable(e.FullPath))
if (VSCSharpFolder.CheckFileAvailiable(e.FullPath))
{
_compileLock.GetAndWaitLock();
CreateFileAction(e.FullPath);
Expand All @@ -71,7 +71,7 @@ public void StartMonitor()
#if DEBUG
Console.WriteLine($"Deleted: {e.FullPath}");
#endif
if (CheckFileAvailiable(e.FullPath))
if (VSCSharpFolder.CheckFileAvailiable(e.FullPath))
{
_compileLock.GetAndWaitLock();
DeleteFileAction(e.FullPath);
Expand All @@ -95,11 +95,11 @@ public void StartMonitor()
if (e.FullPath.EndsWith(".cs"))
{
_compileLock.GetAndWaitLock();
if (CheckFileAvailiable(e.FullPath))
if (VSCSharpFolder.CheckFileAvailiable(e.FullPath))
{
CreateFileAction(e.FullPath);
}
if (CheckFileAvailiable(e.OldFullPath))
if (VSCSharpFolder.CheckFileAvailiable(e.OldFullPath))
{
DeleteFileAction(e.OldFullPath);
}
Expand All @@ -109,7 +109,7 @@ public void StartMonitor()
else if (e.FullPath.StartsWith(e.OldFullPath) && e.FullPath.EndsWith(".TMP"))
{

if (CheckFileAvailiable(e.OldFullPath))
if (VSCSharpFolder.CheckFileAvailiable(e.OldFullPath))
{
_compileLock.GetAndWaitLock();
ChangeFileAction(e.OldFullPath);
Expand All @@ -135,14 +135,7 @@ private async Task ExecuteAfterFunction()
}
#endif
}
public bool CheckFileAvailiable(string file)
{
if (file.StartsWith(VSCSharpFolder.ObjPath) || file.StartsWith(VSCSharpFolder.BinPath))
{
return false;
}
return true;
}

private static void Error(object sender, ErrorEventArgs e)
{
PrintException(e.GetException());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.10.0" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit a192e5c

Please sign in to comment.