diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index f729a341..595a794a 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -18,6 +18,18 @@ updates:
- dependency-name: "System.Reflection.MetadataLoadContext"
- dependency-name: "Microsoft.Extensions.DependencyModel"
+ - package-ecosystem: "nuget"
+ directory: "src/Natasha.CSharp/Natasha.CSharp.Compiler"
+ schedule:
+ interval: "daily"
+ commit-message:
+ prefix: "[DEPENDENCY SRC]"
+ labels:
+ - "dependencies"
+ ignore:
+ - dependency-name: "System.Reflection.MetadataLoadContext"
+ - dependency-name: "Microsoft.Extensions.DependencyModel"
+
- package-ecosystem: "github-actions"
directory: ".github"
schedule:
diff --git a/.github/project.yml b/.github/project.yml
index 92edc089..106f40a8 100644
--- a/.github/project.yml
+++ b/.github/project.yml
@@ -134,6 +134,52 @@ src:
- name: Microsoft.Extensions.DependencyModel
versions:
versions_type:
+ - using_output:
+ enable: true
+ ignores:
+ - System
+ - System.Runtime.CompilerServices
+ - System.Reflection
+ id: D7EDD106-B744-4E0C-9CCE-D88F29EBC983
+ is_ignored: false
+ is_folded: false
+ relative_path: src/Natasha.CSharp/Natasha.CSharp.Compiler/Natasha.CSharp.Compiler.csproj
+ project_name: Natasha.CSharp.Compiler
+ package_name: DotNetCore.Natasha.CSharp.Compiler
+ project_folder: src/Natasha.CSharp/Natasha.CSharp.Compiler
+ labels:
+ dependency_config:
+ type: nuget
+ interval: daily
+ commit_prefix: '[DEPENDENCY SRC]'
+ special_time:
+ special_time_zone:
+ labels:
+ - name: dependencies
+ description: 有依赖需要升级
+ color: 4E04B0
+ ignore:
+ - name: System.Reflection.MetadataLoadContext
+ versions:
+ versions_type:
+ - name: Microsoft.Extensions.DependencyModel
+ versions:
+ versions_type:
+ - using_output:
+ enable: true
+ ignores:
+ - System
+ - System.Runtime.CompilerServices
+ - System.Reflection
+ id: 84A54AF4-0683-48D4-B9D2-465B851E1EF1
+ is_ignored: false
+ is_folded: false
+ relative_path: src/Natasha.CSharp/Natasha.CSharp.Template/Natasha.CSharp.Template.csproj
+ project_name: Natasha.CSharp.Template
+ package_name: DotNetCore.Natasha.CSharp.Template
+ project_folder: src/Natasha.CSharp/Natasha.CSharp.Template
+ labels:
+ dependency_config:
test:
folded_projects: []
global_labels:
diff --git a/Natasha.sln b/Natasha.sln
index d81c55f6..be2aba79 100644
--- a/Natasha.sln
+++ b/Natasha.sln
@@ -193,6 +193,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scanner", "scanner", "{B7AA
scanner.sh = scanner.sh
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Natasha.CSharp.Compiler", "src\Natasha.CSharp\Natasha.CSharp.Compiler\Natasha.CSharp.Compiler.csproj", "{D7EDD106-B744-4E0C-9CCE-D88F29EBC983}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Natasha.CSharp.Template", "src\Natasha.CSharp\Natasha.CSharp.Template\Natasha.CSharp.Template.csproj", "{84A54AF4-0683-48D4-B9D2-465B851E1EF1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -343,6 +347,14 @@ Global
{199906B2-7FED-4DFF-8364-C5C66A787F02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{199906B2-7FED-4DFF-8364-C5C66A787F02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{199906B2-7FED-4DFF-8364-C5C66A787F02}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D7EDD106-B744-4E0C-9CCE-D88F29EBC983}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D7EDD106-B744-4E0C-9CCE-D88F29EBC983}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D7EDD106-B744-4E0C-9CCE-D88F29EBC983}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D7EDD106-B744-4E0C-9CCE-D88F29EBC983}.Release|Any CPU.Build.0 = Release|Any CPU
+ {84A54AF4-0683-48D4-B9D2-465B851E1EF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {84A54AF4-0683-48D4-B9D2-465B851E1EF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {84A54AF4-0683-48D4-B9D2-465B851E1EF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {84A54AF4-0683-48D4-B9D2-465B851E1EF1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -408,6 +420,8 @@ Global
{CF373547-E278-4940-B5F8-DB548D76EC75} = {4EC5B87C-1343-4247-8A6A-A63C9BFEFEDD}
{199906B2-7FED-4DFF-8364-C5C66A787F02} = {4EC5B87C-1343-4247-8A6A-A63C9BFEFEDD}
{B7AA9686-44B7-4170-82B2-BF8E3B892887} = {DD0B729A-C1D5-41E1-AE1B-FE66F4BC651E}
+ {D7EDD106-B744-4E0C-9CCE-D88F29EBC983} = {8C9B862A-B569-460C-8B74-E74C6DF0CAB3}
+ {84A54AF4-0683-48D4-B9D2-465B851E1EF1} = {8C9B862A-B569-460C-8B74-E74C6DF0CAB3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3004E730-B231-40FA-B75C-58D7DDE17679}
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index ca44eb5c..a4597d52 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -14,12 +14,12 @@
.NET Core Community
NMSAzulx
preview
-
+ true
19404084.png
LICENSE
$([MSBuild]::NormalizeDirectory('$(SolutionDir)', 'resources'))natasha.snk
true
- 1701;1702;0168;NETSDK1138;IDE0060;xUnit2000;CS0067;CS8321;CS0649;CS8604;CA1822;
+ 1701;1702;0168;NETSDK1138;IDE0060;xUnit2000;CS0067;CS8321;CS0649;CS8604;CA1822;RS1014;CS1591;
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Compile.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Compile.cs
new file mode 100644
index 00000000..dec37db3
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Compile.cs
@@ -0,0 +1,250 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Emit;
+using Natasha.CSharp.Component.Exception;
+using Natasha.CSharp.Extension.Inner;
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Diagnostics;
+
+#if MULTI
+using System.IO;
+using System.Reflection;
+using Natasha.CSharp.Component.Domain;
+///
+/// 程序集编译构建器 - 编译选项
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ private PluginLoadBehavior _compileReferenceBehavior;
+ private PluginLoadBehavior _compileAssemblyBehavior;
+ private Func? _referencePickFunc;
+ private Func, IEnumerable>? _referencesFilter;
+ private bool _combineReferences;
+
+ public AssemblyCSharpBuilder WithReferenceCombine()
+ {
+ _combineReferences = true;
+ return this;
+ }
+ public AssemblyCSharpBuilder WithoutReferenceCombine()
+ {
+ _combineReferences = false;
+ return this;
+ }
+ ///
+ /// 配置主域及当前域的加载行为, Default 使用主域引用, Custom 使用当前域引用
+ ///
+ ///
+ ///
+ public AssemblyCSharpBuilder CompileWithReferenceLoadBehavior(PluginLoadBehavior loadBehavior)
+ {
+ _compileReferenceBehavior = loadBehavior;
+ return this;
+ }
+ ///
+ /// 配置当前域程序集的加载行为
+ ///
+ ///
+ ///
+ public AssemblyCSharpBuilder CompileWithAssemblyLoadBehavior(PluginLoadBehavior loadBehavior)
+ {
+ _compileAssemblyBehavior = loadBehavior;
+ return this;
+ }
+
+ public AssemblyCSharpBuilder CompileWithSameNameReferencesFilter(Func? useAssemblyNameFunc = null)
+ {
+ _referencePickFunc = useAssemblyNameFunc;
+ return this;
+ }
+
+
+ public AssemblyCSharpBuilder CompileWithReferencesFilter(Func, IEnumerable>? referencesFilter)
+ {
+ _referencesFilter = referencesFilter;
+ return this;
+ }
+
+ ///
+ /// 流编译成功之后触发的事件
+ ///
+ public event Action? CompileSucceedEvent;
+
+
+
+ ///
+ /// 流编译失败之后触发的事件
+ ///
+ public event Action>? CompileFailedEvent;
+
+
+ public CSharpCompilation GetAvailableCompilation(Func? initOptionsFunc = null)
+ {
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+
+ //Mark : 26ms
+ if (_compileReferenceBehavior == PluginLoadBehavior.None)
+ {
+ _compilerOptions.SetSupersedeLowerVersions(true);
+ }
+
+ var options = _compilerOptions.GetCompilationOptions();
+ if (initOptionsFunc != null)
+ {
+ options = initOptionsFunc(options);
+ }
+ IEnumerable references;
+ if (_combineReferences)
+ {
+ references = Domain.GetReferences(_compileReferenceBehavior, _referencePickFunc);
+ }
+ else
+ {
+ references = Domain.References.GetReferences();
+ }
+
+ if (_referencesFilter != null)
+ {
+ references = _referencesFilter(references);
+ }
+ _compilation = CSharpCompilation.Create(AssemblyName, SyntaxTrees, references, options);
+
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Compiler]", "获取编译单元", 2);
+#endif
+
+ if (EnableSemanticHandler)
+ {
+ foreach (var item in _semanticAnalysistor)
+ {
+ _compilation = item(this, _compilation, _semanticCheckIgnoreAccessibility);
+ }
+ }
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[Semantic]", "语义处理", 2);
+#endif
+ return _compilation;
+ }
+
+ ///
+ /// 将 SyntaxTrees 中的语法树编译到程序集.如果不成功会抛出 NatashaException.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// //程序集的域加载行为, 该行为决定了编译后的程序集随着依赖加载到域中的处理结果.
+ /// //和加载插件原理相同.
+ /// builder.CompileWithAssemblyLoadBehavior(enum);
+ ///
+ /// //编译单元的引用加载行为, 遇到同名不同版本的引用该如何处理.
+ /// builder.CompileWithReferenceLoadBehavior(enum);
+ /// builder.CompileWithReferencesFilter(func);
+ ///
+ ///
+ ///
+ ///
+ public Assembly GetAssembly(Assembly? currentAssembly = null)
+ {
+
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+ Stream dllStream;
+ Stream pdbStream;
+ Stream? xmlStream = null;
+ if (DllFilePath != string.Empty)
+ {
+ dllStream = File.Create(DllFilePath);
+ }
+ else
+ {
+ dllStream = new MemoryStream();
+ }
+
+ if (PdbFilePath != string.Empty)
+ {
+ pdbStream = File.Create(PdbFilePath);
+ }
+ else
+ {
+ pdbStream = new MemoryStream();
+ }
+
+ if (XmlFilePath != string.Empty)
+ {
+ xmlStream = File.Create(XmlFilePath);
+ }
+
+ if (currentAssembly != null)
+ {
+ _compilation =
+ GetAvailableCompilation(opt=>opt
+ .WithModuleName(AssemblyName)
+ .WithOutputKind(OutputKind.NetModule));
+
+ }
+ else if (_compilation == null)
+ {
+ _compilation = GetAvailableCompilation();
+ }
+
+
+ var compileResult = _compilation.Emit(
+ dllStream,
+ pdbStream: pdbStream,
+ xmlDocumentationStream: xmlStream,
+ options: new EmitOptions(pdbFilePath: PdbFilePath == string.Empty ? null : PdbFilePath, debugInformationFormat: DebugInformationFormat.PortablePdb));
+
+
+ LogCompilationEvent?.Invoke(_compilation.GetNatashaLog());
+
+ Assembly? assembly = currentAssembly;
+ if (compileResult.Success)
+ {
+ dllStream.Seek(0, SeekOrigin.Begin);
+ if (assembly == null)
+ {
+
+ pdbStream?.Seek(0, SeekOrigin.Begin);
+ Domain.SetAssemblyLoadBehavior(_compileAssemblyBehavior);
+ assembly = Domain.LoadAssemblyFromStream(dllStream, pdbStream);
+ }
+ else
+ {
+ byte[] rawStream = new byte[dllStream.Length];
+ dllStream.Read(rawStream.AsSpan());
+ assembly.LoadModule(AssemblyName, rawStream);
+ }
+ CompileSucceedEvent?.Invoke(_compilation, assembly!);
+
+ }
+ dllStream.Dispose();
+ pdbStream?.Dispose();
+ xmlStream?.Dispose();
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[ Emit ]", "编译时长", 2);
+#endif
+
+ if (!compileResult.Success)
+ {
+ CompileFailedEvent?.Invoke(_compilation, compileResult.Diagnostics);
+ throw NatashaExceptionAnalyzer.GetCompileException(_compilation, compileResult.Diagnostics);
+ }
+
+ return assembly!;
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Domain.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Domain.cs
new file mode 100644
index 00000000..499de64f
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Domain.cs
@@ -0,0 +1,54 @@
+#if MULTI
+using System.Runtime.Loader;
+
+///
+/// 程序集编译构建器 - 域
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+ private NatashaReferenceDomain? _domain;
+
+
+ ///
+ /// 编译单元所在域.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// //程序集默认加载行为, 遇到同名不同版本的依赖也加载.
+ /// domain.SetAssemblyLoadBehavior();
+ ///
+ ///
+ ///
+ ///
+ public NatashaReferenceDomain Domain
+ {
+ get
+ {
+ if (_domain == null)
+ {
+
+ if (AssemblyLoadContext.CurrentContextualReflectionContext != default)
+ {
+ _domain = (NatashaReferenceDomain)(AssemblyLoadContext.CurrentContextualReflectionContext);
+ }
+ else
+ {
+ _domain = NatashaReferenceDomain.DefaultDomain;
+ }
+
+ }
+ return _domain;
+ }
+ set
+ {
+ if (value == default)
+ {
+ value = NatashaReferenceDomain.DefaultDomain;
+ }
+ _domain = value;
+ }
+ }
+}
+#endif
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Ouput.Multi.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Ouput.Multi.cs
new file mode 100644
index 00000000..1a87c1c1
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Ouput.Multi.cs
@@ -0,0 +1,37 @@
+#if MULTI
+using System;
+using System.IO;
+
+///
+/// 程序集编译构建器-输出
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ public AssemblyCSharpBuilder UseNatashaFileOut(string? folder = null)
+ {
+ if (folder == null)
+ {
+ if (OutputFolder == GlobalOutputFolder)
+ {
+ OutputFolder = Path.Combine(GlobalOutputFolder, Domain.Name!);
+ }
+ }
+ else
+ {
+ OutputFolder = folder;
+ }
+ if (!Directory.Exists(OutputFolder))
+ {
+ Directory.CreateDirectory(OutputFolder);
+ }
+ DllFilePath = Path.Combine(OutputFolder, $"{AssemblyName}.dll");
+ PdbFilePath = Path.Combine(OutputFolder, $"{AssemblyName}.pdb");
+ XmlFilePath = Path.Combine(OutputFolder, $"{AssemblyName}.xml");
+ return this;
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Syntax.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Syntax.cs
new file mode 100644
index 00000000..e193b3ad
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.Syntax.cs
@@ -0,0 +1,49 @@
+#if MULTI
+using System.Text;
+///
+/// 程序集编译构建器 - 语法树相关
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+ ///
+ /// 注入代码并拼接using
+ ///
+ /// 脚本代码
+ /// using 拼接行为
+ ///
+ public AssemblyCSharpBuilder Add(string script, UsingLoadBehavior usingLoadBehavior)
+ {
+ switch (usingLoadBehavior)
+ {
+ case UsingLoadBehavior.WithDefault:
+ return AddScript(DefaultUsing.UsingScript + script);
+ case UsingLoadBehavior.WithCurrent:
+ if (Domain == NatashaReferenceDomain.DefaultDomain)
+ {
+ return AddScript(DefaultUsing.UsingScript + script);
+ }
+ return AddScript(Domain.UsingRecorder + script);
+ case UsingLoadBehavior.WithAll:
+ if (Domain == NatashaReferenceDomain.DefaultDomain)
+ {
+ return AddScript(DefaultUsing.UsingScript + script);
+ }
+ StringBuilder usingBuilder = new();
+ foreach (var item in Domain.UsingRecorder._usings)
+ {
+ if (!DefaultUsing.HasElement(item))
+ {
+ usingBuilder.AppendLine($"using {item};");
+ }
+ }
+ return AddScript(DefaultUsing.UsingScript + usingBuilder + script);
+ default:
+ return AddScript(script);
+ }
+ }
+}
+#endif
+
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.cs
new file mode 100644
index 00000000..95c1158e
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/CompileUnit/AssemblyCSharpBuilder.cs
@@ -0,0 +1,43 @@
+#if MULTI
+using Natasha.CSharp.Compiler.SemanticAnalaysis;
+using System;
+using System.Runtime.CompilerServices;
+
+///
+/// 程序集编译构建器
+/// 默认开启语义过滤
+/// 默认域内引用优先
+/// 默认GUID作为程序集名
+///
+[assembly: InternalsVisibleTo("NatashaFunctionUT, PublicKey=002400000480000094000000060200000024000052534131000400000100010069acb31dd0d9918441d6ed2b49cd67ae17d15fd6ded4ccd2f99b4a88df8cddacbf72d5897bb54f406b037688d99f482ff1c3088638b95364ef614f01c3f3f2a2a75889aa53286865463fb1803876056c8b98ec57f0b3cf2b1185de63d37041ba08f81ddba0dccf81efcdbdc912032e8d2b0efa21accc96206c386b574b9d9cb8")]
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ public AssemblyCSharpBuilder():this(Guid.NewGuid().ToString("N"))
+ {
+
+ }
+ public AssemblyCSharpBuilder(string assemblyName)
+ {
+ EnableSemanticHandler = true;
+ _semanticCheckIgnoreAccessibility = true;
+ _combineReferences = true;
+ _compileReferenceBehavior = PluginLoadBehavior.UseDefault;
+ _parsingBehavior = UsingLoadBehavior.None;
+ OutputFolder = GlobalOutputFolder;
+ _compilerOptions = new();
+ _semanticAnalysistor = new()
+ {
+ UsingAnalysistor._usingSemanticDelegate
+ };
+ SyntaxTrees = new();
+ AssemblyName = assemblyName;
+ DllFilePath = string.Empty;
+ PdbFilePath = string.Empty;
+ XmlFilePath = string.Empty;
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/DomainManagement.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/DomainManagement.cs
new file mode 100644
index 00000000..150b043b
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/DomainManagement.cs
@@ -0,0 +1,114 @@
+#if MULTI
+using System;
+using System.Collections.Concurrent;
+using static System.Runtime.Loader.AssemblyLoadContext;
+
+public sealed class DomainManagement
+{
+
+ public static readonly ConcurrentDictionary Cache;
+
+ static DomainManagement()
+ {
+ Cache = new ConcurrentDictionary();
+ }
+
+
+ public static NatashaReferenceDomain Random()
+ {
+ return Create("N" + Guid.NewGuid().ToString("N"));
+ }
+
+
+ public static NatashaReferenceDomain Create(string key)
+ {
+ if (Cache.ContainsKey(key))
+ {
+ return (NatashaReferenceDomain)(Cache[key].Target!);
+ }
+ else
+ {
+ Clear();
+ var domain = new NatashaReferenceDomain(key);
+ Add(key, domain);
+ return domain;
+ }
+ }
+
+
+ public static void Clear()
+ {
+ foreach (var item in Cache)
+ {
+ if (!item.Value.IsAlive)
+ {
+ Cache!.Remove(item.Key);
+ }
+ }
+ }
+
+
+
+ public static void Add(string key, NatashaReferenceDomain domain)
+ {
+ if (Cache.ContainsKey(key))
+ {
+ if (!Cache[key].IsAlive)
+ {
+ Cache[key] = new WeakReference(domain);
+ }
+ }
+ else
+ {
+ Cache[key] = new WeakReference(domain, trackResurrection: true);
+ }
+ }
+
+ public static NatashaReferenceDomain CurrentDomain
+ {
+ get
+ {
+ return CurrentContextualReflectionContext == default ?
+ NatashaReferenceDomain.DefaultDomain :
+ (NatashaReferenceDomain)CurrentContextualReflectionContext;
+ }
+ }
+
+
+ public static WeakReference Remove(string key)
+ {
+ if (Cache.ContainsKey(key))
+ {
+ var result = Cache!.Remove(key);
+ if (result != default)
+ {
+ ((NatashaReferenceDomain)(result.Target!)).Dispose();
+ }
+ return result!;
+ }
+
+ throw new System.Exception($"Can't find key : {key}!");
+ }
+
+
+ public static bool IsDeleted(string key)
+ {
+ if (Cache.TryGetValue(key,out var value))
+ {
+ return !value!.IsAlive;
+ }
+ return true;
+ }
+
+
+ public static NatashaReferenceDomain? Get(string key)
+ {
+ if (Cache.ContainsKey(key))
+ {
+ return (NatashaReferenceDomain)Cache[key].Target!;
+ }
+ return null;
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/NatashaReferenceCache.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/NatashaReferenceCache.cs
new file mode 100644
index 00000000..a7bc26ab
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/NatashaReferenceCache.cs
@@ -0,0 +1,147 @@
+#if MULTI
+using Microsoft.CodeAnalysis;
+using Natasha.CSharp.Component.Domain;
+using Natasha.Domain.Extension;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Reflection.PortableExecutable;
+
+namespace Natasha.CSharp.Component
+{
+ //与元数据相关
+ //数据值与程序集及内存相关
+ public sealed class NatashaReferenceCache
+ {
+ ///
+ /// 存放内存流编译过来的程序集与引用
+ ///
+ private readonly ConcurrentDictionary _referenceCache;
+ private readonly ConcurrentDictionary _referenceNameCache;
+ public NatashaReferenceCache()
+ {
+ _referenceCache = new();
+ _referenceNameCache = new();
+ }
+
+ public int Count { get { return _referenceCache.Count; } }
+ public void AddReference(AssemblyName assemblyName, MetadataReference reference, PluginLoadBehavior loadReferenceBehavior)
+ {
+
+ var name = assemblyName.GetUniqueName();
+ if (loadReferenceBehavior != PluginLoadBehavior.None)
+ {
+ if (_referenceNameCache.TryGetValue(name, out var oldAssemblyName))
+ {
+ if (assemblyName.CompareWithDefault(oldAssemblyName, loadReferenceBehavior) == AssemblyLoadVersionResult.UseCustomer)
+ {
+ _referenceCache!.Remove(oldAssemblyName);
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+ _referenceNameCache[name] = assemblyName;
+ _referenceCache[assemblyName] = reference;
+
+ }
+ public void AddReference(AssemblyName assemblyName, Stream stream, PluginLoadBehavior loadReferenceBehavior = PluginLoadBehavior.None)
+ {
+ AddReference(assemblyName, MetadataReference.CreateFromStream(stream), loadReferenceBehavior);
+ }
+ public void AddReference(AssemblyName assemblyName, string path, PluginLoadBehavior loadReferenceBehavior = PluginLoadBehavior.None)
+ {
+ AddReference(assemblyName, CreateMetadataReference(path), loadReferenceBehavior);
+ }
+
+ public void AddReference(Assembly assembly, PluginLoadBehavior loadReferenceBehavior = PluginLoadBehavior.None)
+ {
+ if (!assembly.IsDynamic && !string.IsNullOrEmpty(assembly.Location))
+ {
+ AddReference(assembly.GetName(), CreateMetadataReference(assembly.Location), loadReferenceBehavior);
+ }
+ }
+ public void RemoveReference(AssemblyName assemblyName)
+ {
+ _referenceCache!.Remove(assemblyName);
+ var name = assemblyName.Name;
+ if (name != null)
+ {
+ _referenceNameCache!.Remove(name);
+ }
+ }
+ public void RemoveReference(string name)
+ {
+ if (_referenceNameCache.TryGetValue(name, out var assemblyName))
+ {
+ RemoveReference(assemblyName);
+ }
+ }
+ public void Clear()
+ {
+ _referenceCache.Clear();
+ _referenceNameCache.Clear();
+ }
+ public IEnumerable GetReferences()
+ {
+ return _referenceCache.Values;
+ }
+ internal HashSet CombineWithDefaultReferences(NatashaReferenceCache defaultCache, PluginLoadBehavior loadBehavior = PluginLoadBehavior.None, Func? useAssemblyNameFunc = null)
+ {
+ var sets = new HashSet(_referenceCache.Values);
+ var excludeNods = new HashSet();
+ var defaultReferences = defaultCache._referenceCache;
+ var defaultNameReferences = defaultCache._referenceNameCache; ;
+ if (loadBehavior != PluginLoadBehavior.None || useAssemblyNameFunc != null)
+ {
+ foreach (var item in _referenceNameCache)
+ {
+ if (defaultNameReferences.TryGetValue(item.Key, out var defaultAssemblyName))
+ {
+ AssemblyLoadVersionResult funcResult;
+ if (useAssemblyNameFunc != null)
+ {
+ funcResult = useAssemblyNameFunc(defaultAssemblyName, item.Value);
+ if (funcResult == AssemblyLoadVersionResult.PassToNextHandler)
+ {
+ funcResult = item.Value.CompareWithDefault(defaultAssemblyName, loadBehavior);
+ }
+ }
+ else
+ {
+ funcResult = item.Value.CompareWithDefault(defaultAssemblyName, loadBehavior);
+ }
+
+ if (funcResult == AssemblyLoadVersionResult.UseDefault)
+ {
+ excludeNods.Add(_referenceCache[item.Value]);
+ }
+ else if (funcResult == AssemblyLoadVersionResult.UseCustomer)
+ {
+ excludeNods.Add(defaultReferences[defaultAssemblyName]);
+ }
+
+ }
+ }
+ }
+ sets.UnionWith(defaultReferences.Values);
+ sets.ExceptWith(excludeNods);
+ return sets;
+ }
+
+ private static MetadataReference CreateMetadataReference(string path)
+ {
+ using (var stream = File.OpenRead(path))
+ {
+ var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata);
+ var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);
+ return assemblyMetadata.GetReference(filePath: path);
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/NatashaReferenceDomain.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/NatashaReferenceDomain.cs
new file mode 100644
index 00000000..70bdbb17
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Component/Domain/NatashaReferenceDomain.cs
@@ -0,0 +1,110 @@
+#if MULTI
+using Microsoft.CodeAnalysis;
+using Natasha.CSharp.Component;
+using Natasha.CSharp.Component.Domain;
+using Natasha.CSharp.Using;
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+public sealed class NatashaReferenceDomain : NatashaDomain
+{
+ public static new readonly NatashaReferenceDomain DefaultDomain;
+ static NatashaReferenceDomain()
+ {
+
+ DefaultDomain = new NatashaReferenceDomain();
+ DomainManagement.Add("Default", DefaultDomain);
+
+ }
+
+
+ public static void AddDefaultReferenceAndUsing(AssemblyName assemblyName, string path)
+ {
+ DefaultDomain.References.AddReference(assemblyName, path);
+ DefaultUsing.AddUsing(assemblyName);
+ }
+
+
+ public IEnumerable GetReferences(PluginLoadBehavior loadBehavior = PluginLoadBehavior.None, Func? useAssemblyNameFunc = null)
+ {
+ if (Name == DefaultDomain.Name)
+ {
+ return References.GetReferences();
+ }
+ else
+ {
+ return References.CombineWithDefaultReferences(DefaultDomain.References, loadBehavior, useAssemblyNameFunc);
+ }
+ }
+
+ ///
+ /// 引用 记录
+ ///
+ public readonly NatashaReferenceCache References;
+ ///
+ /// Using 记录
+ ///
+ public readonly NatashaUsingCache UsingRecorder;
+ private NatashaReferenceDomain() : base()
+ {
+ References = new();
+ UsingRecorder = new();
+ LoadAssemblyReferencsWithPath += NatashaReferenceDomain_LoadAssemblyReferencsWithPath;
+ LoadAssemblyReferenceWithStream += NatashaReferenceDomain_LoadAssemblyReferenceWithStream;
+ }
+
+
+ public NatashaReferenceDomain(string key) : base(key)
+ {
+ References = new();
+ UsingRecorder = new();
+ LoadAssemblyReferencsWithPath += NatashaReferenceDomain_LoadAssemblyReferencsWithPath;
+ LoadAssemblyReferenceWithStream += NatashaReferenceDomain_LoadAssemblyReferenceWithStream;
+ }
+
+
+ private void NatashaReferenceDomain_LoadAssemblyReferenceWithStream(Assembly assembly, System.IO.Stream stream)
+ {
+
+ References.AddReference(assembly.GetName(), stream);
+ if (Name == "Default")
+ {
+ DefaultUsing.AddUsing(assembly);
+ }
+ else
+ {
+ DefaultUsing.AddUsing(assembly);
+ }
+ //UsingRecorder.Using(assembly);
+
+ }
+
+
+ private void NatashaReferenceDomain_LoadAssemblyReferencsWithPath(Assembly assembly, string path)
+ {
+ References.AddReference(assembly.GetName(), path);
+ if (Name == "Default")
+ {
+ DefaultUsing.AddUsing(assembly);
+ }
+ else
+ {
+ UsingRecorder.Using(assembly);
+ }
+ }
+
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ if (disposing)
+ {
+ LoadAssemblyReferencsWithPath -= NatashaReferenceDomain_LoadAssemblyReferencsWithPath;
+ LoadAssemblyReferenceWithStream -= NatashaReferenceDomain_LoadAssemblyReferenceWithStream;
+ //References.Clear();
+ }
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/Inner/CSharpCompilationExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/Inner/CSharpCompilationExtension.cs
new file mode 100644
index 00000000..92c29716
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/Inner/CSharpCompilationExtension.cs
@@ -0,0 +1,126 @@
+#if MULTI
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Natasha.CSharp.Extension.Inner
+{
+
+ internal static class CSharpCompilationExtension
+ {
+ internal static NatashaCompilationLog GetNatashaLog(this CSharpCompilation compilation)
+ {
+ NatashaCompilationLog natashaCompilation = new();
+ natashaCompilation.AddCompilationInfo("AssemblyName", compilation.AssemblyName ?? string.Empty);
+ natashaCompilation.AddCompilationInfo("Language", compilation.Language);
+ natashaCompilation.AddCompilationInfo("LanguageVersion", compilation.LanguageVersion.ToString());
+ natashaCompilation.AddCompilationInfo("SyntaxTreeCount", compilation.SyntaxTrees.Length.ToString());
+ natashaCompilation.AddCompilationInfo("ReferencesCount", compilation.References.Count().ToString());
+ var errors = compilation.GetDiagnostics();
+ if (errors.Length > 0)
+ {
+ Dictionary> syntaxCache = new();
+ foreach (var item in compilation.GetDiagnostics())
+ {
+ if (item.Location.SourceTree != null)
+ {
+ var tree = item.Location.SourceTree;
+ if (!syntaxCache.ContainsKey(tree))
+ {
+ syntaxCache[tree] = new List();
+ }
+ syntaxCache[tree].Add(item);
+ }
+ }
+ natashaCompilation.HasError = true;
+ foreach (var item in syntaxCache)
+ {
+ var codeText = item.Key.ToString();
+ StringBuilder errorMessage = new();
+ foreach (var error in item.Value)
+ {
+ var span = error.Location.GetLineSpan();
+ errorMessage.AppendLine($"第{span.StartLinePosition.Line + 1}行,第{span.StartLinePosition.Character}个字符: 内容【{GetErrorMessage(codeText, error.Location.GetLineSpan())}】 {error.GetMessage()}");
+ }
+ natashaCompilation.AddMessage(item.Value.Count, AddLineNumber(codeText), errorMessage.ToString());
+ }
+ }
+ else
+ {
+ natashaCompilation.HasError = false;
+ foreach (var item in compilation.SyntaxTrees)
+ {
+ natashaCompilation.AddMessage(0, AddLineNumber(item.ToString()), item.GetFirstOopName());
+ }
+ }
+ return natashaCompilation;
+ }
+ private static string GetErrorMessage(string content, FileLinePositionSpan linePositionSpan)
+ {
+
+ var start = linePositionSpan.StartLinePosition;
+ var end = linePositionSpan.EndLinePosition;
+
+
+ var arrayLines = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+ var currentErrorLine = arrayLines[start.Line];
+
+
+ if (start.Line == end.Line)
+ {
+
+ if (start.Character == end.Character)
+ {
+
+ return currentErrorLine.Trim();
+
+ }
+ else
+ {
+
+ return currentErrorLine[start.Character..end.Character].Trim();
+
+ }
+
+ }
+ else
+ {
+
+ StringBuilder builder = new();
+ builder.AppendLine(currentErrorLine[start.Character..]);
+ for (int i = start.Line; i < end.Line - 1; i += 1)
+ {
+
+ builder.AppendLine(arrayLines[i]);
+
+ }
+ currentErrorLine = arrayLines[end.Line];
+ builder.AppendLine(currentErrorLine[..end.Character]);
+ return builder.ToString();
+
+ }
+
+ }
+ private static string AddLineNumber(string code)
+ {
+
+ StringBuilder builder = new();
+ var arrayLines = code.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+ for (int i = 0; i < arrayLines.Length; i += 1)
+ {
+
+ builder.AppendLine($"{i + 1}\t{arrayLines[i]}");
+
+ }
+ return builder.ToString();
+
+ }
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaAssemblyExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaAssemblyExtension.cs
new file mode 100644
index 00000000..3685ed59
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaAssemblyExtension.cs
@@ -0,0 +1,35 @@
+#if MULTI
+using System.Reflection;
+using System.Runtime.Loader;
+
+
+public static class NatashaAssemblyDomainExtension
+{
+
+
+ public static NatashaReferenceDomain GetDomain(this Assembly assembly)
+ {
+
+ var assemblyDomain = AssemblyLoadContext.GetLoadContext(assembly);
+ if (assemblyDomain == AssemblyLoadContext.Default)
+ {
+ return NatashaReferenceDomain.DefaultDomain!;
+ }
+ return (NatashaReferenceDomain)assemblyDomain!;
+
+ }
+
+
+ public static void DisposeDomain(this Assembly assembly)
+ {
+
+ var domain = GetDomain(assembly);
+ if (domain.Name != "Default")
+ {
+ domain.Dispose();
+ }
+
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaDelegateExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaDelegateExtension.cs
new file mode 100644
index 00000000..7f79043e
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaDelegateExtension.cs
@@ -0,0 +1,25 @@
+#if MULTI
+using System;
+
+
+public static class NatashaDelegateExtension
+{
+
+ public static NatashaReferenceDomain GetDomain(this Delegate @delegate)
+ {
+
+ return @delegate.Method.Module.Assembly.GetDomain();
+
+ }
+
+
+
+ public static void DisposeDomain(this Delegate @delegate)
+ {
+
+ @delegate.Method.Module.Assembly.DisposeDomain();
+
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaDomainExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaDomainExtension.cs
new file mode 100644
index 00000000..ab7a4e42
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaDomainExtension.cs
@@ -0,0 +1,24 @@
+#if MULTI
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using static System.Runtime.Loader.AssemblyLoadContext;
+
+public static class NatashaDomainExtension
+{
+
+
+ ///
+ /// 创建一个以该字符串命名的域并锁定
+ ///
+ ///
+ ///
+ public static ContextualReflectionScope NatashaDomainScope(this string domain)
+ {
+ return DomainManagement.Create(domain).EnterContextualReflection();
+ }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaTypeDomainExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaTypeDomainExtension.cs
new file mode 100644
index 00000000..623a8d0d
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/Extension/NatashaTypeDomainExtension.cs
@@ -0,0 +1,23 @@
+#if MULTI
+using System;
+public static class NatashaTypeDomainExtension
+{
+
+ public static NatashaReferenceDomain GetDomain(this Type type)
+ {
+
+ return type.Assembly.GetDomain();
+
+ }
+
+
+
+ public static void DisposeDomain(this Type type)
+ {
+
+ type.Assembly.DisposeDomain();
+
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/NatashaInitializer.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/NatashaInitializer.cs
new file mode 100644
index 00000000..f11fcfb8
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/NatashaInitializer.cs
@@ -0,0 +1,204 @@
+#if MULTI
+using Microsoft.CodeAnalysis;
+using Microsoft.Extensions.DependencyModel;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net.Http.Headers;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+public static class NatashaInitializer
+{
+ private static readonly object _lock = new();
+
+ private static bool _isCompleted = false;
+ public static void Preheating(Func? excludeReferencesFunc = null
+ , bool useRuntimeUsing = false
+ , bool useRuntimeReference = false
+ )
+ {
+
+ if (!_isCompleted)
+ {
+ lock (_lock)
+ {
+ if (_isCompleted)
+ {
+ return;
+ }
+
+ _isCompleted = true;
+
+ excludeReferencesFunc ??= (_, _) => false;
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+
+ DefaultUsing.SetDefaultUsingFilter(excludeReferencesFunc);
+ NatashaDomain.SetDefaultAssemblyFilter(excludeReferencesFunc);
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[ Domain ]", "默认信息初始化", 1);
+#endif
+ IEnumerable? paths = null;
+ Queue parallelLoopResults = new Queue();
+
+ var assemblies = AppDomain.CurrentDomain.GetAssemblies();
+ CacheRuntimeAssembly(assemblies);
+
+ var namespaceCacheFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Natasha.Namespace.cache");
+
+ if (useRuntimeReference)
+ {
+ parallelLoopResults.Enqueue(InitReferenceFromRuntime(assemblies));
+ }
+ else
+ {
+ paths = NatashaReferencePathsHelper.GetReferenceFiles(excludeReferencesFunc);
+ if (paths != null && paths.Any())
+ {
+ parallelLoopResults.Enqueue(InitReferenceFromPath(paths));
+ }
+ }
+ if (useRuntimeUsing)
+ {
+ parallelLoopResults.Enqueue(InitUsingFromRuntime(assemblies));
+ }
+ else
+ {
+ paths ??= NatashaReferencePathsHelper.GetReferenceFiles(excludeReferencesFunc);
+ if (paths != null && paths.Any())
+ {
+ //更新缓存
+ parallelLoopResults.Enqueue(InitUsingFromPath(paths));
+ }
+ else if(File.Exists(namespaceCacheFilePath))
+ {
+ //从缓存文件中读取
+ var namespaceCache = File.ReadAllText(namespaceCacheFilePath, Encoding.UTF8);
+ var namespaceText = namespaceCache.Split("+?", StringSplitOptions.RemoveEmptyEntries);
+ DefaultUsing.AddUsing(false, namespaceText);
+ }
+ }
+
+ while (parallelLoopResults.Count>0)
+ {
+ var result = parallelLoopResults.Dequeue();
+ while (!result.IsCompleted)
+ {
+ Thread.Sleep(100);
+ }
+ }
+ DefaultUsing.ReBuildUsingScript();
+ if (!useRuntimeUsing && paths != null && paths.Any())
+ {
+ var namespaceCache = new StringBuilder();
+ foreach (var preNamespace in DefaultUsing._defaultNamesapce)
+ {
+ namespaceCache.Append($"{preNamespace}+?");
+ }
+ File.WriteAllText(namespaceCacheFilePath, namespaceCache.ToString(), Encoding.UTF8);
+ }
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Reference]", "引用初始化", 1);
+#endif
+
+ AssemblyCSharpBuilder cSharpBuilder = new();
+ cSharpBuilder.ConfigCompilerOption(item => item.AddSupperess("CS8019").UseSuppressReportor(false));
+ using (DomainManagement.Random().CreateScope())
+ {
+ cSharpBuilder.EnableSemanticHandler = true;
+ cSharpBuilder.Add("public class A{}", UsingLoadBehavior.WithDefault);
+ //Mark : 22.0M (Memory:2023-02-27)
+ var assembly = cSharpBuilder.GetAssembly();
+ }
+ cSharpBuilder.Domain.Dispose();
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[FirstCompile]", "编译初始化", 1);
+#endif
+ GC.Collect();
+ }
+ }
+
+ }
+
+#if DEBUG
+ private static readonly object _showLock = new object();
+ public static void Show(Assembly assembly)
+ {
+ lock (_showLock)
+ {
+ Console.WriteLine("Asssembly : " + assembly.FullName);
+ Console.WriteLine("Attribute : " + string.Join(",", assembly.CustomAttributes.Select(item => item.AttributeType.Name)));
+ Console.WriteLine("ReferenceLength : " + assembly?.GetReferencedAssemblies().Length);
+ Console.WriteLine("ReferenceAsssembly : " + string.Join(",", assembly?.GetReferencedAssemblies().Select(asm => asm.Name)));
+ }
+ }
+#endif
+
+
+ private unsafe static ParallelLoopResult InitReferenceFromRuntime(Assembly[] assemblies)
+ {
+ return Parallel.ForEach(assemblies, assembly =>
+ {
+ if (assembly.TryGetRawMetadata(out var blob, out var length))
+ {
+ var metadata = AssemblyMetadata.Create(ModuleMetadata.CreateFromMetadata((IntPtr)blob, length));
+ var metadataReference = metadata.GetReference();
+ NatashaReferenceDomain.DefaultDomain.References.AddReference(assembly.GetName(), metadataReference, PluginLoadBehavior.None);
+ }
+ });
+ }
+ //*
+ private static ParallelLoopResult InitUsingFromRuntime(Assembly[] assemblies)
+ {
+ return Parallel.ForEach(assemblies, assembly =>
+ {
+ DefaultUsing.AddUsingWithoutCheckingkAndInternalUsing(assembly, false);
+ });
+ }
+
+ private static ParallelLoopResult CacheRuntimeAssembly(Assembly[] assemblies)
+ {
+ return Parallel.ForEach(assemblies, assembly =>
+ {
+ NatashaDomain.AddAssemblyToDefaultCache(assembly);
+ });
+ }
+ ///*
+ private unsafe static ParallelLoopResult InitUsingFromPath(IEnumerable paths)
+ {
+ var resolver = new PathAssemblyResolver(paths);
+ using var mlc = new MetadataLoadContext(resolver);
+ return Parallel.ForEach(paths, (path) =>
+ {
+
+ Assembly assembly = mlc.LoadFromAssemblyPath(path);
+ DefaultUsing.AddUsingWithoutCheck(assembly, false);
+
+ });
+ }
+ private unsafe static ParallelLoopResult InitReferenceFromPath(IEnumerable paths)
+ {
+ var resolver = new PathAssemblyResolver(paths);
+ using var mlc = new MetadataLoadContext(resolver);
+ return Parallel.ForEach(paths, (path) =>
+ {
+ Assembly assembly = mlc.LoadFromAssemblyPath(path);
+ NatashaReferenceDomain.DefaultDomain.References.AddReference(assembly.GetName(), path);
+
+ });
+ }
+
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/NatashaManagement.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/NatashaManagement.cs
new file mode 100644
index 00000000..3c8e312d
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/MultiDomain/NatashaManagement.cs
@@ -0,0 +1,67 @@
+# if MULTI
+using System;
+
+
+public static partial class NatashaManagement
+{
+
+ ///
+ /// 获取系统域
+ ///
+ ///
+ public static NatashaReferenceDomain GetDefaultDomain()
+ {
+ return NatashaReferenceDomain.DefaultDomain;
+ }
+ ///
+ /// 新建一个域
+ ///
+ ///
+ ///
+ public static NatashaReferenceDomain CreateDomain(string domainName)
+ {
+ return DomainManagement.Create(domainName);
+ }
+ ///
+ /// 新建一个随机域
+ ///
+ ///
+ public static NatashaReferenceDomain CreateRandomDomain()
+ {
+ return DomainManagement.Random();
+ }
+
+ ///
+ /// 增加元数据引用,编译需要元数据支持.
+ ///
+ ///
+ /// 加载行为,如果有相同类型的引用, 那么此枚举会比较新旧程序集版本
+ ///
+ public static bool AddGlobalReference(Type type, PluginLoadBehavior loadBehavior = PluginLoadBehavior.None)
+ {
+ if (type.Assembly.IsDynamic || type.Assembly.Location == null)
+ {
+ return false;
+ }
+ NatashaReferenceDomain.DefaultDomain.References.AddReference(type.Assembly, loadBehavior);
+ return true;
+ }
+
+ ///
+ /// 移除元数据引用,编译需要元数据支持.
+ ///
+ ///
+ /// 加载行为,如果有相同类型的引用, 那么此枚举会比较新旧程序集版本
+ ///
+ public static bool RemoveGlobalReference(Type type, PluginLoadBehavior loadBehavior = PluginLoadBehavior.None)
+ {
+ if (type.Assembly.IsDynamic || type.Assembly.GetName() == null)
+ {
+ return false;
+ }
+ NatashaReferenceDomain.DefaultDomain.References.RemoveReference(type.Assembly.GetName());
+ return true;
+ }
+}
+
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Natasha.CSharp.Compiler.csproj b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Natasha.CSharp.Compiler.csproj
new file mode 100644
index 00000000..e59ead60
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Natasha.CSharp.Compiler.csproj
@@ -0,0 +1,46 @@
+
+
+
+ netstandard2.0;netcoreapp3.1;net5.0;net6.0;net7.0
+ Natasha 的 C# 版编译器
+ DotNetCore.Natasha.CSharp.Compiler
+ 升级到最新版.
+ Roslyn;IL;Script;Dynamic;Natasha;NMS;Compiler;
+ true
+ 5.2.2.1
+ 5.2.2.1
+ 5.2.2.1
+
+
+
+ MULTI;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.CompileOption.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.CompileOption.cs
new file mode 100644
index 00000000..79da8383
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.CompileOption.cs
@@ -0,0 +1,51 @@
+using Microsoft.CodeAnalysis.CSharp;
+using Natasha.CSharp.Compiler;
+using System;
+
+///
+/// 程序集编译构建器 - 编译选项
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+ private readonly NatashaCSharpCompilerOptions _compilerOptions;
+ private CSharpCompilation? _compilation;
+ public CSharpCompilation? Compilation { get { return _compilation; } }
+ ///
+ /// 配置编译选项. 此方法传入的实例 instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// //默认配置
+ ///
+ /// //关闭空引用支持
+ /// opt=>opt.SetNullableCompile(NullableContextOptions.Disable)
+ ///
+ /// //不处理同名不同版本的引用
+ /// .SetSupersedeLowerVersions(false)
+ ///
+ /// //输出方式为dll
+ /// .SetOutputKind(OutputKind.DynamicallyLinkedLibrary)
+ ///
+ /// //启用 Release 优化
+ /// .CompileAsRelease()
+ ///
+ /// //支持 Unsafe 编译
+ /// .SetUnsafeCompiler(true)
+ ///
+ /// //任何 CPU 平台
+ /// .SetPlatform(Platform.AnyCpu);
+ ///
+ ///
+ ///
+ ///
+ public AssemblyCSharpBuilder ConfigCompilerOption(Action action)
+ {
+ action(_compilerOptions);
+ return this;
+ }
+}
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Log.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Log.cs
new file mode 100644
index 00000000..6baf6501
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Log.cs
@@ -0,0 +1,14 @@
+using System;
+
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ public event Action? LogCompilationEvent;
+ public AssemblyCSharpBuilder SetLogEvent(Action logAction)
+ {
+ LogCompilationEvent = logAction;
+ return this;
+ }
+
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Ouput.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Ouput.cs
new file mode 100644
index 00000000..450742aa
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Ouput.cs
@@ -0,0 +1,40 @@
+using System;
+using System.IO;
+
+///
+/// 程序集编译构建器-输出
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ #region 输出设置相关
+ public string AssemblyName;
+ public string DllFilePath;
+ public string PdbFilePath;
+ public string XmlFilePath;
+ public string OutputFolder;
+ ///
+ /// 默认的输出文件夹
+ ///
+ public static readonly string GlobalOutputFolder;
+ static AssemblyCSharpBuilder()
+ {
+
+ GlobalOutputFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory!, "DynamicLibraryFolders");
+ if (!Directory.Exists(GlobalOutputFolder))
+ {
+ Directory.CreateDirectory(GlobalOutputFolder);
+ }
+
+ }
+ public AssemblyCSharpBuilder SetAssemblyName(string asmName)
+ {
+ AssemblyName = asmName;
+ return this;
+ }
+ #endregion
+
+}
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Semantic.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Semantic.cs
new file mode 100644
index 00000000..a9a05b76
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Semantic.cs
@@ -0,0 +1,77 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Natasha.CSharp.Compiler;
+using Natasha.CSharp.Compiler.SemanticAnalaysis;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+
+///
+/// 程序集编译构建器 - 语义
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ private readonly List> _semanticAnalysistor;
+ private bool _semanticCheckIgnoreAccessibility;
+
+
+
+ ///
+ /// 在语义分析时检测 可访问性问题, 默认分析. 降低性能.
+ ///
+ ///
+ [Obsolete("Use WithAnalysisAccessibility", true)]
+ public AssemblyCSharpBuilder AnalysisIgnoreAccessibility()
+ {
+ _semanticCheckIgnoreAccessibility = false;
+ return this;
+ }
+ public AssemblyCSharpBuilder WithAnalysisAccessibility()
+ {
+ _semanticCheckIgnoreAccessibility = false;
+ return this;
+ }
+
+ ///
+ /// 不在语义分析时检测 可访问性问题, 可提升性能.
+ ///
+ ///
+ [Obsolete("Use WithoutAnalysisAccessibility", true)]
+ public AssemblyCSharpBuilder NotAnalysisIgnoreAccessibility()
+ {
+ _semanticCheckIgnoreAccessibility = true;
+ return this;
+ }
+ public AssemblyCSharpBuilder WithoutAnalysisAccessibility()
+ {
+ _semanticCheckIgnoreAccessibility = true;
+ return this;
+ }
+
+ public AssemblyCSharpBuilder AddSemanticAnalysistor(Func func)
+ {
+ _semanticAnalysistor.Add(func);
+ return this;
+ }
+
+ public AssemblyCSharpBuilder RemoveSemanticAnalysistor(Func func)
+ {
+ _semanticAnalysistor.Remove(func);
+ return this;
+ }
+
+ public bool EnableSemanticHandler;
+
+ public AssemblyCSharpBuilder ClearInnerSemanticAnalysistor()
+ {
+ _semanticAnalysistor.Remove(UsingAnalysistor._usingSemanticDelegate);
+ return this;
+ }
+
+
+}
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Share.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Share.cs
new file mode 100644
index 00000000..711fd904
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Share.cs
@@ -0,0 +1,39 @@
+using System;
+
+public sealed partial class AssemblyCSharpBuilder
+{
+ ///
+ /// 清空编译信息, 下次编译重组 Compilation 和语法树.
+ ///
+ ///
+ public AssemblyCSharpBuilder ClearCompilationCache()
+ {
+ _compilation = null;
+ return this;
+ }
+
+ ///
+ /// 清空所有记录,包括编译信息和脚本记录,以及程序集名称.
+ ///
+ ///
+ public AssemblyCSharpBuilder Clear()
+ {
+ _compilation = null;
+ SyntaxTrees.Clear();
+ AssemblyName = string.Empty;
+ return this;
+ }
+
+ ///
+ /// 自动使用 GUID 作为程序集名称.
+ ///
+ ///
+ public AssemblyCSharpBuilder WithRandomAssenblyName()
+ {
+ AssemblyName = Guid.NewGuid().ToString("N");
+ return this;
+ }
+
+
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Syntax.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Syntax.cs
new file mode 100644
index 00000000..d5a3e718
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/AssemblyCSharpBuilder.Syntax.cs
@@ -0,0 +1,107 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Natasha.CSharp.Component.Exception;
+using Natasha.CSharp.Syntax;
+using System;
+using System.Collections.Generic;
+
+///
+/// 程序集编译构建器 - 语法树相关
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ public readonly List SyntaxTrees;
+ private CSharpParseOptions? _options;
+ private UsingLoadBehavior _parsingBehavior;
+ ///
+ /// 配置语法树选项
+ ///
+ ///
+ ///
+ public AssemblyCSharpBuilder ConfigSyntaxOptions(CSharpParseOptions cSharpParseOptions)
+ {
+ _options = cSharpParseOptions;
+ return this;
+ }
+ ///
+ /// 配置语法树选项
+ ///
+ ///
+ ///
+ public AssemblyCSharpBuilder ConfigSyntaxOptions(Func cSharpParseOptionsAction)
+ {
+ _options = cSharpParseOptionsAction(new CSharpParseOptions());
+ return this;
+ }
+
+ public AssemblyCSharpBuilder ConfigUsingOptions(UsingLoadBehavior usingLoadBehavior)
+ {
+ _parsingBehavior = usingLoadBehavior;
+ return this;
+ }
+
+ ///
+ /// 注入脚本
+ ///
+ /// 脚本代码
+ ///
+ public AssemblyCSharpBuilder Add(string script)
+ {
+ return Add(script, _parsingBehavior);
+ }
+
+
+ ///
+ /// 添加脚本
+ ///
+ ///
+ private AssemblyCSharpBuilder AddScript(string script)
+ {
+ var tree = NatashaCSharpSyntax.ParseTree(script, _options);
+ var exception = NatashaExceptionAnalyzer.GetSyntaxException(tree);
+ if (exception != null)
+ {
+ throw exception;
+ }
+ else
+ {
+ lock (SyntaxTrees)
+ {
+ SyntaxTrees.Add(tree);
+ }
+ }
+ return this;
+ }
+ ///
+ /// 添加语法树
+ ///
+ ///
+ public AssemblyCSharpBuilder Add(SyntaxTree tree)
+ {
+ tree = NatashaCSharpSyntax.FormartTree(tree, _options);
+ var exception = NatashaExceptionAnalyzer.GetSyntaxException(tree);
+ if (exception != null)
+ {
+ throw exception;
+ }
+ else
+ {
+ lock (SyntaxTrees)
+ {
+ SyntaxTrees.Add(tree);
+ }
+ }
+ return this;
+ }
+
+ public AssemblyCSharpBuilder ClearScript()
+ {
+ SyntaxTrees.Clear();
+ return this;
+ }
+
+}
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/SemanticAnalaysis/UsingAnalysistor.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/SemanticAnalaysis/UsingAnalysistor.cs
new file mode 100644
index 00000000..120db0db
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/CompileUnit/SemanticAnalaysis/UsingAnalysistor.cs
@@ -0,0 +1,93 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Natasha.CSharp.Extension.Inner;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+namespace Natasha.CSharp.Compiler.SemanticAnalaysis
+{
+ internal static class UsingAnalysistor
+ {
+ internal static readonly Func _usingSemanticDelegate;
+ static UsingAnalysistor()
+ {
+
+ _usingSemanticDelegate = (builder, compilation, ignoreAccessibility) =>
+ {
+
+ var trees = compilation.SyntaxTrees;
+ foreach (var tree in trees)
+ {
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+ CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
+
+ SemanticModel semantiModel = compilation.GetSemanticModel(tree, ignoreAccessibility);
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Semantic]", "语义节点获取", 3);
+#endif
+
+ var errors = semantiModel.GetDiagnostics();
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[Semantic]", "语义诊断获取", 3);
+ stopwatch.Restart();
+#endif
+
+ if (errors.Length > 0)
+ {
+ var errorNodes = new HashSet();
+ for (int i = 0; i < errors.Length; i++)
+ {
+ var error = errors[i];
+ if (error.Id == "CS0434")
+ {
+ error.RemoveDefaultUsingAndUsingNode(root, errorNodes);
+ }
+ else if (error.Id == "CS8019")
+ {
+ var node = error.GetTypeSyntaxNode(root);
+ if (node != null)
+ {
+ errorNodes.Add(node);
+ }
+
+ }
+ else if (error.Id == "CS0246")
+ {
+ var node = error.GetTypeSyntaxNode(root);
+ if (node != null)
+ {
+ NatashaDiagnosticsExtension.RemoveUsingAndNode(node, errorNodes);
+ }
+ }
+ else if (error.Id == "CS0234")
+ {
+ error.RemoveUsingAndNodesFromStartName(root, errorNodes);
+ }
+ }
+
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Semantic]", "语义节点筛查", 3);
+
+#endif
+ if (errorNodes.Count > 0)
+ {
+ compilation = compilation.ReplaceSyntaxTree(tree, root.RemoveNodes(errorNodes, SyntaxRemoveOptions.KeepNoTrivia)!.SyntaxTree);
+ }
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[Semantic]", "语义节点替换", 3);
+#endif
+ }
+
+ }
+ return compilation;
+ };
+ }
+
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/GlobalSupperessCache.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/GlobalSupperessCache.cs
new file mode 100644
index 00000000..1fab6bbd
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/GlobalSupperessCache.cs
@@ -0,0 +1,45 @@
+using Microsoft.CodeAnalysis;
+using System.Collections.Concurrent;
+
+namespace Natasha.CSharp.Component.Compiler
+{
+ internal static class GlobalSupperessCache
+ {
+ internal static readonly ConcurrentDictionary _globalSuppressDiagnostics;
+ static GlobalSupperessCache()
+ {
+ _globalSuppressDiagnostics = new();
+ AddGlobalSupperess("CA1050");
+ AddGlobalSupperess("CA1822");
+ AddGlobalSupperess("CS1701");
+ AddGlobalSupperess("CS1702");
+ AddGlobalSupperess("CS1705");
+ AddGlobalSupperess("CS2008");
+ AddGlobalSupperess("CS162");
+ AddGlobalSupperess("CS0219");
+ AddGlobalSupperess("CS0414");
+ AddGlobalSupperess("CS0616");
+ AddGlobalSupperess("CS0649");
+ AddGlobalSupperess("CS0693");
+ AddGlobalSupperess("CS1591");
+ AddGlobalSupperess("CS1998");
+ //AddGlobalSupperess("RS1014");
+ //AddGlobalSupperess("CA1822");
+ //AddGlobalSupperess("CS8604");
+ // CS8019
+ // CS0162 - Unreachable code detected.
+ // CS0219 - The variable 'V' is assigned but its value is never used.
+ // CS0414 - The private field 'F' is assigned but its value is never used.
+ // CS0616 - Member is obsolete.
+ // CS0649 - Field 'F' is never assigned to, and will always have its default value.
+ // CS0693 - Type parameter 'type parameter' has the same name as the type parameter from outer type 'T'
+ // CS1591 - Missing XML comment for publicly visible type or member 'Type_or_Member'
+ // CS1998 - This async method lacks 'await' operators and will run synchronously
+
+ }
+ public static void AddGlobalSupperess(string errorcode)
+ {
+ _globalSuppressDiagnostics[errorcode] = ReportDiagnostic.Suppress;
+ }
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/CompilerBinderFlags.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/CompilerBinderFlags.cs
new file mode 100644
index 00000000..26ba9290
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/CompilerBinderFlags.cs
@@ -0,0 +1,111 @@
+using System;
+
+namespace Natasha.CSharp.Compiler
+{
+
+ [Flags]
+ public enum CompilerBinderFlags : uint
+ {
+ None, // No specific location
+ SuppressConstraintChecks = 1 << 0,
+ SuppressObsoleteChecks = 1 << 1,
+ ConstructorInitializer = 1 << 2,
+ FieldInitializer = 1 << 3,
+ ObjectInitializerMember = 1 << 4, // object initializer field/property access
+ CollectionInitializerAddMethod = 1 << 5, // used for collection initializer add method overload resolution diagnostics
+ AttributeArgument = 1 << 6,
+ GenericConstraintsClause = 1 << 7, // "where" clause (used for cycle checking)
+ Cref = 1 << 8, // documentation comment cref
+ CrefParameterOrReturnType = 1 << 9, // Same as Cref, but lookup considers inherited members
+
+ ///
+ /// Indicates that the current context allows unsafe constructs.
+ ///
+ ///
+ /// NOTE: Dev10 doesn't seem to treat attributes as being within the unsafe region.
+ /// Fortunately, not following this behavior should not be a breaking change since
+ /// attribute arguments have to be constants and there are no constants of unsafe
+ /// types.
+ ///
+ UnsafeRegion = 1 << 10,
+
+ ///
+ /// Indicates that the unsafe diagnostics are not reported in the current context, regardless
+ /// of whether or not it is (part of) an unsafe region.
+ ///
+ SuppressUnsafeDiagnostics = 1 << 11,
+
+ ///
+ /// Indicates that this binder is being used to answer SemanticModel questions (i.e. not
+ /// for batch compilation).
+ ///
+ ///
+ /// Imports touched by a binder with this flag set are not consider "used".
+ ///
+ SemanticModel = 1 << 12,
+
+ EarlyAttributeBinding = 1 << 13,
+
+ /// Remarks, mutually exclusive with .
+ CheckedRegion = 1 << 14,
+ /// Remarks, mutually exclusive with .
+ UncheckedRegion = 1 << 15,
+
+ // Each of these produces a different diagnostic, so we need separate flags.
+ InLockBody = 1 << 16, // body, not the expression
+ InCatchBlock = 1 << 17,
+ InFinallyBlock = 1 << 18,
+ InTryBlockOfTryCatch = 1 << 19, // try block must have at least one catch clause
+ InCatchFilter = 1 << 20,
+
+ // Indicates that this binder is inside of a finally block that is nested inside
+ // of a catch block. This flag resets at every catch clause in the binder chain.
+ // This flag is only used to support CS0724. Implies that InFinallyBlock and
+ // InCatchBlock are also set.
+ InNestedFinallyBlock = 1 << 21,
+
+ IgnoreAccessibility = 1 << 22,
+
+ ParameterDefaultValue = 1 << 23,
+
+ ///
+ /// In the debugger, one can take the address of a managed object.
+ ///
+ AllowManagedAddressOf = 1 << 24,
+
+ ///
+ /// In the debugger, the context is always unsafe, but one can still await.
+ ///
+ AllowAwaitInUnsafeContext = 1 << 25,
+
+ ///
+ /// Ignore duplicate types from the cor library.
+ ///
+ IgnoreCorLibraryDuplicatedTypes = 1 << 26,
+
+ ///
+ /// This is a , or has as its parent.
+ ///
+ InContextualAttributeBinder = 1 << 27,
+
+ ///
+ /// Are we binding for the purpose of an Expression Evaluator
+ ///
+ InEEMethodBinder = 1 << 28,
+
+ ///
+ /// Skip binding type arguments (we use instead).
+ /// For example, currently used when type constraints are bound in some scenarios.
+ ///
+ SuppressTypeArgumentBinding = 1 << 29,
+
+ ///
+ /// The current context is an expression tree
+ ///
+ InExpressionTree = 1 << 30,
+
+
+ // Groups
+ AllClearedAtExecutableCodeBoundary = InLockBody | InCatchBlock | InCatchFilter | InFinallyBlock | InTryBlockOfTryCatch | InNestedFinallyBlock,
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/Core31Supplement.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/Core31Supplement.cs
new file mode 100644
index 00000000..652d7fef
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/Core31Supplement.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace System.Runtime.CompilerServices
+{
+
+#if !NET5_0_OR_GREATER
+ public sealed class SkipLocalsInitAttribute : Attribute { }
+#endif
+
+}
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/UsingLoadBehavior.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/UsingLoadBehavior.cs
new file mode 100644
index 00000000..20bc36cf
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Model/UsingLoadBehavior.cs
@@ -0,0 +1,8 @@
+public enum UsingLoadBehavior
+{
+ None = 0,
+ WithDefault = 1,
+ WithCurrent = 2,
+ WithAll = 3
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/NatashaCSharpCompilerOptions.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/NatashaCSharpCompilerOptions.cs
new file mode 100644
index 00000000..2868058d
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/NatashaCSharpCompilerOptions.cs
@@ -0,0 +1,191 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Natasha.CSharp.Component.Compiler;
+using Natasha.CSharp.Component.Compiler.Utils;
+using System;
+using System.Collections.Concurrent;
+
+
+namespace Natasha.CSharp.Compiler
+{
+ public sealed class NatashaCSharpCompilerOptions
+ {
+
+ public NatashaCSharpCompilerOptions()
+ {
+ _suppressDiagnostics = new ConcurrentDictionary(GlobalSupperessCache._globalSuppressDiagnostics);
+#if DEBUG
+ this.SetCompilerFlag(CompilerBinderFlags.IgnoreCorLibraryDuplicatedTypes | CompilerBinderFlags.IgnoreAccessibility)
+#else
+ this.SetCompilerFlag(CompilerBinderFlags.IgnoreCorLibraryDuplicatedTypes)
+#endif
+ .SetNullableCompile(NullableContextOptions.Disable)
+ .SetSupersedeLowerVersions(false)
+ .SetOutputKind(OutputKind.DynamicallyLinkedLibrary)
+ .CompileAsRelease()
+ .SetUnsafeCompiler(true)
+ .SetPlatform(Platform.AnyCpu);
+
+ }
+
+ private readonly ConcurrentDictionary _suppressDiagnostics;
+
+ public NatashaCSharpCompilerOptions AddSupperess(string errorcode)
+ {
+ _suppressDiagnostics[errorcode] = ReportDiagnostic.Suppress;
+ return this;
+ }
+ public NatashaCSharpCompilerOptions IgnoreWarning(string errorcode)
+ {
+ _suppressDiagnostics[errorcode] = ReportDiagnostic.Suppress;
+ return this;
+ }
+ public NatashaCSharpCompilerOptions RemoveSupperess(string errorcode)
+ {
+ _suppressDiagnostics.Remove(errorcode);
+ return this;
+ }
+
+
+ private bool _suppressReportShut;
+ public NatashaCSharpCompilerOptions UseSuppressReportor(bool shut)
+ {
+ _suppressReportShut = shut;
+ return this;
+ }
+
+
+ private NullableContextOptions _nullableCompileOption;
+ public NatashaCSharpCompilerOptions SetNullableCompile(NullableContextOptions flag)
+ {
+ _nullableCompileOption = flag;
+ return this;
+ }
+
+
+ private OptimizationLevel _codeOptimizationLevel;
+ public NatashaCSharpCompilerOptions CompileAsDebug()
+ {
+ _codeOptimizationLevel = OptimizationLevel.Debug;
+ return this;
+ }
+ public NatashaCSharpCompilerOptions CompileAsRelease()
+ {
+ _codeOptimizationLevel = OptimizationLevel.Release;
+ return this;
+ }
+
+
+ private Platform _processorPlatform;
+ public NatashaCSharpCompilerOptions SetPlatform(Platform flag)
+ {
+ _processorPlatform = flag;
+ return this;
+ }
+
+ private OutputKind _assemblyKind;
+ public NatashaCSharpCompilerOptions SetOutputKind(OutputKind flag)
+ {
+ _assemblyKind = flag;
+ return this;
+ }
+
+ private bool _allowUnsafe;
+ public NatashaCSharpCompilerOptions SetUnsafeCompiler(bool shut)
+ {
+ _allowUnsafe = shut;
+ return this;
+ }
+
+
+ private bool _referencesSupersedeLowerVersions;
+ ///
+ /// 自动禁用低版本程序集
+ ///
+ ///
+ public NatashaCSharpCompilerOptions SetSupersedeLowerVersions(bool shut)
+ {
+ _referencesSupersedeLowerVersions = shut;
+ return this;
+ }
+
+
+ private CompilerBinderFlags _compileFlags;
+ ///
+ /// 绑定编译标识
+ ///
+ ///
+ public NatashaCSharpCompilerOptions SetCompilerFlag(CompilerBinderFlags flags)
+ {
+ _compileFlags = flags;
+ return this;
+ }
+
+ ///
+ /// 移除 IgnoreAccessibility 标识
+ ///
+ ///
+ public NatashaCSharpCompilerOptions RemoveIgnoreAccessibility()
+ {
+ if (_compileFlags.HasFlag(CompilerBinderFlags.IgnoreAccessibility))
+ {
+ _compileFlags = (uint)_compileFlags - CompilerBinderFlags.IgnoreAccessibility;
+ }
+ return this;
+ }
+
+ ///
+ /// 获取构建编译信息的选项
+ ///
+ ///
+ internal CSharpCompilationOptions GetCompilationOptions()
+ {
+
+ var compilationOptions = new CSharpCompilationOptions(
+ nullableContextOptions: _nullableCompileOption,
+ //strongNameProvider: a,
+ deterministic: false,
+ concurrentBuild: true,
+ moduleName: Guid.NewGuid().ToString(),
+ reportSuppressedDiagnostics: _suppressReportShut,
+ metadataImportOptions: MetadataImportOptions.All,
+ outputKind: _assemblyKind,
+ optimizationLevel: _codeOptimizationLevel,
+ allowUnsafe: _allowUnsafe,
+ platform: _processorPlatform,
+ checkOverflow: false,
+ assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default,
+ specificDiagnosticOptions: _suppressDiagnostics);
+ if (_compileFlags != 0)
+ {
+ CompilerInnerHelper.SetTopLevelBinderFlagDelegate(compilationOptions, (uint)_compileFlags);
+ }
+ //CS1704
+ CompilerInnerHelper.SetReferencesSupersedeLowerVersionsDelegate(compilationOptions, _referencesSupersedeLowerVersions);
+ return compilationOptions;
+
+ }
+
+
+ /////
+ ///// 获取编译选项
+ /////
+ /////
+ /////
+ //public CSharpCompilation GetCompilation()
+ //{
+ // if (_compilation==default)
+ // {
+ // _compilation = CSharpCompilation.Create(AssemblyName, null, Domain.GetCompileReferences(), GetCompilationOptions());
+ // }
+ // return _compilation.RemoveAllSyntaxTrees();
+
+ //}
+
+
+ }
+}
+
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Utils/CompilerInnerHelper.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Utils/CompilerInnerHelper.cs
new file mode 100644
index 00000000..ce1c2aa1
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Compiler/Utils/CompilerInnerHelper.cs
@@ -0,0 +1,26 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Reflection;
+
+namespace Natasha.CSharp.Component.Compiler.Utils
+{
+ internal static class CompilerInnerHelper
+ {
+ internal static readonly Action SetTopLevelBinderFlagDelegate;
+ internal static readonly Action SetReferencesSupersedeLowerVersionsDelegate;
+
+ static CompilerInnerHelper()
+ {
+ SetTopLevelBinderFlagDelegate = (Action)Delegate.CreateDelegate(
+ typeof(Action), typeof(CSharpCompilationOptions)
+ .GetProperty("TopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic)!
+ .SetMethod!);
+
+ SetReferencesSupersedeLowerVersionsDelegate = (Action)Delegate.CreateDelegate(
+ typeof(Action), typeof(CompilationOptions)
+ .GetProperty("ReferencesSupersedeLowerVersions", BindingFlags.Instance | BindingFlags.NonPublic)!
+ .SetMethod!);
+ }
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/Model/ExceptionKind.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/Model/ExceptionKind.cs
new file mode 100644
index 00000000..66d4b7fa
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/Model/ExceptionKind.cs
@@ -0,0 +1,11 @@
+public enum NatashaExceptionKind
+{
+ None,
+ Assembly,
+ Type,
+ Method,
+ Delegate,
+ Syntax,
+ Compile
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/Model/NatashaException.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/Model/NatashaException.cs
new file mode 100644
index 00000000..448ad0d0
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/Model/NatashaException.cs
@@ -0,0 +1,36 @@
+using Microsoft.CodeAnalysis;
+using System;
+using System.Collections.Generic;
+
+
+
+[Serializable]
+public sealed class NatashaException : Exception
+{
+
+ public NatashaException(string message) : base(message)
+ {
+ Formatter = string.Empty;
+ Diagnostics = new List();
+ ErrorKind = NatashaExceptionKind.None;
+ CompileMessage = string.Empty;
+ }
+
+ //格式化后的脚本字符串
+ public string Formatter;
+
+ //错误类型
+ public NatashaExceptionKind ErrorKind;
+
+ //roslyn诊断集合
+ public List Diagnostics;
+
+ ///
+ /// 详细的编译信息
+ ///
+ public string CompileMessage;
+
+}
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/NatashaExceptionAnalyzer.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/NatashaExceptionAnalyzer.cs
new file mode 100644
index 00000000..05b69919
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Exception/NatashaExceptionAnalyzer.cs
@@ -0,0 +1,43 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using System.Collections.Immutable;
+using System.Linq;
+
+namespace Natasha.CSharp.Component.Exception
+{
+ internal sealed class NatashaExceptionAnalyzer
+ {
+
+ internal static NatashaException? GetSyntaxException(SyntaxTree tree)
+ {
+
+ var diagnostics = tree.GetDiagnostics();
+ var errors = diagnostics.Where(item => !item.IsSuppressed).ToArray();
+ if (errors.Length>0)
+ {
+ var first = errors[0];
+ var exception = new NatashaException(first.GetMessage());
+ exception.Diagnostics.AddRange(errors);
+ exception.Formatter = tree.ToString();
+ exception.ErrorKind = NatashaExceptionKind.Syntax;
+ return exception;
+ }
+ return null;
+
+ }
+
+ internal static NatashaException GetCompileException(CSharpCompilation compilation, ImmutableArray errors)
+ {
+ var first = errors[0];
+ var exception = new NatashaException(first.GetMessage());
+ exception.Diagnostics.AddRange(errors);
+ if (first.Location.SourceTree!=null)
+ {
+ exception.Formatter = first.Location.SourceTree.ToString();
+ }
+ exception.CompileMessage = $"编译程序集为:{compilation.AssemblyName};CSharp版本:{compilation.LanguageVersion};";
+ exception.ErrorKind = NatashaExceptionKind.Compile;
+ return exception;
+ }
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/NLog/NatashaCompilationLog.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/NLog/NatashaCompilationLog.cs
new file mode 100644
index 00000000..7a14a084
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/NLog/NatashaCompilationLog.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+public sealed class NatashaCompilationLog
+{
+ public NatashaCompilationLog()
+ {
+ _csInfo = string.Empty;
+ Messages = new();
+ CompilationInfomations = new();
+ }
+
+ public bool HasError;
+
+ private string _csInfo;
+
+ public string CompilationsSerializableInfomation
+ {
+ get
+ {
+ if (_csInfo == string.Empty)
+ {
+ _csInfo = $"AssemblyName:{CompilationInfomations["AssemblyName"]};Time:{DateTime.Now:yyyy-MM-dd HH:mm:ss};Language:{CompilationInfomations["Language"]};LanguageVersion:{CompilationInfomations["LanguageVersion"]};ReferencesCount:{CompilationInfomations["ReferencesCount"]}";
+ }
+ return _csInfo;
+ }
+ }
+
+ public readonly List Messages;
+
+ public readonly Dictionary CompilationInfomations;
+
+ internal void AddCompilationInfo(string key, string value)
+ {
+ CompilationInfomations[key] = value;
+ }
+
+ internal void AddMessage(int count,string code,string message)
+ {
+ Messages.Add(new(count, code, message));
+ }
+
+ public override string ToString()
+ {
+ StringBuilder result = new StringBuilder();
+ result.AppendLine($"{Environment.NewLine}============================== {(HasError?"ERROR":"SUCCEED")} : {CompilationInfomations["AssemblyName"]} ==============================");
+ if (HasError)
+ {
+ foreach (var item in Messages)
+ {
+ result.AppendLine($"{Environment.NewLine}------------------------------------------------------------------------------------------------------{Environment.NewLine}");
+ result.AppendLine(item.Code);
+ result.AppendLine($"{Environment.NewLine}{item.Message}");
+ }
+
+ }
+ else
+ {
+ foreach (var item in Messages)
+ {
+ result.AppendLine($"{Environment.NewLine}------------------------------------------------- {item.Message} -------------------------------------------{Environment.NewLine}");
+ result.AppendLine(item.Code);
+ }
+ }
+
+ result.AppendLine($"{Environment.NewLine}------------------------------------------------------------------------------------------------------");
+ result.AppendLine($"{Environment.NewLine} Time :\t{DateTime.Now:yyyy-MM-dd HH:mm:ss}");
+ result.AppendLine($"{Environment.NewLine} Language :\t{CompilationInfomations["Language"]} & {CompilationInfomations["LanguageVersion"]}");
+ result.AppendLine($"{Environment.NewLine} TreeCount:\t共 {CompilationInfomations["SyntaxTreeCount"]} 个");
+ result.AppendLine($"{Environment.NewLine} RefCount :\t共 {CompilationInfomations["ReferencesCount"]} 个");
+ result.AppendLine($"{Environment.NewLine}------------------------------------------------------------------------------------------------------");
+ result.AppendLine($"{Environment.NewLine}======================================================================================================");
+ return result.ToString();
+ }
+
+
+}
+
+public class NatashaCompilationMessage
+{
+ private readonly int _count;
+ private readonly string _code;
+ private readonly string _message;
+ public NatashaCompilationMessage(int count, string code,string message)
+ {
+ _count = count;
+ _code = code;
+ _message = message;
+ }
+ public int ErrorCount { get { return _count; } }
+ public string Code { get { return _code; } }
+ public string Message { get { return _message; } }
+
+}
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Syntax/NatashaCSharpSyntax.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Syntax/NatashaCSharpSyntax.cs
new file mode 100644
index 00000000..786e42f2
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Syntax/NatashaCSharpSyntax.cs
@@ -0,0 +1,107 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+
+namespace Natasha.CSharp.Syntax
+{
+ internal static class NatashaCSharpSyntax
+ {
+
+ //private readonly static AdhocWorkspace _workSpace;
+ private readonly static CSharpParseOptions _options;
+ //private readonly static OptionSet _formartOptions;
+ static NatashaCSharpSyntax()
+ {
+
+ _options = new CSharpParseOptions(LanguageVersion.Preview);
+ #region Settings
+ //var workspace = new AdhocWorkspace();
+ //_formartOptions = workspace.Options;
+ ////_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.IndentBraces, true);
+ ////_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.IndentBlock, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.IndentSwitchCaseSection, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.IndentSwitchCaseSectionWhenBlock, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.IndentSwitchSection, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.LabelPositioning, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLineForCatch, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLineForClausesInQuery, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLineForElse, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLineForFinally, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLineForMembersInAnonymousTypes, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLineForMembersInObjectInit, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInAccessors, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousMethods, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInAnonymousTypes, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInControlBlocks, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInLambdaExpressionBody, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInMethods, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInObjectCollectionArrayInitializers, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInProperties, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.NewLinesForBracesInTypes, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterCast, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterColonInBaseTypeDeclaration, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterComma, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterControlFlowStatementKeyword, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterDot, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterMethodCallName, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceAfterSemicolonsInForStatement, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBeforeColonInBaseTypeDeclaration, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBeforeComma, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBeforeDot, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBeforeOpenSquareBracket, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBeforeSemicolonsInForStatement, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBetweenEmptyMethodCallParentheses, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBetweenEmptyMethodDeclarationParentheses, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceBetweenEmptySquareBrackets, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpacesIgnoreAroundVariableDeclaration, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceWithinCastParentheses, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceWithinExpressionParentheses, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceWithinMethodCallParentheses, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceWithinMethodDeclarationParenthesis, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceWithinOtherParentheses, false);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpaceWithinSquareBrackets, false);
+ ////_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpacingAfterMethodDeclarationName, true);
+ ////_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.SpacingAroundBinaryOperator, _options.Language);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.WrappingKeepStatementsOnSingleLine, true);
+ //_formartOptions = _formartOptions.WithChangedOption(CSharpFormattingOptions.WrappingPreserveSingleLine, true);
+ #endregion
+
+ }
+
+
+ internal static SyntaxTree ParseTree(string script, CSharpParseOptions? options)
+ {
+ if (options==null)
+ {
+ options = _options;
+ }
+ //Mark1 : 647ms
+ //Mark2 : 128ms
+ //Mark : 5.0M (Memory:2023-02-27)
+ var tree = CSharpSyntaxTree.ParseText(script.Trim(), _options);
+ return FormartTree(tree, options);
+
+ }
+
+
+ ///
+ /// 直接加载树,并缓存
+ ///
+ ///
+ ///
+ internal static SyntaxTree FormartTree(SyntaxTree tree, CSharpParseOptions? options)
+ {
+ if (options == null)
+ {
+ options = _options;
+ }
+ //return tree.GetRoot().NormalizeWhitespace().SyntaxTree;
+ //Console.ReadKey();
+ //Mark : 0.3M (Memory:2023-02-27)
+ //Roslyn BUG https://github.com/dotnet/roslyn/issues/58150
+ return CSharpSyntaxTree.ParseText(tree.GetRoot().NormalizeWhitespace().SyntaxTree.ToString(), options);
+ }
+ }
+}
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Using/DefaultUsing.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Using/DefaultUsing.cs
new file mode 100644
index 00000000..ea5ecdd9
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Using/DefaultUsing.cs
@@ -0,0 +1,444 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+///
+/// 全局 using, 初始化时会通过 DependencyModel 获取主域所需的引用 using 字符串.
+///
+public static class DefaultUsing
+{
+
+ internal readonly static HashSet _defaultNamesapce;
+ private static Func _excludeDefaultAssembliesFunc;
+ private static StringBuilder _usingScriptCache;
+ public static string UsingScript;
+ static DefaultUsing()
+ {
+ UsingScript = string.Empty;
+ _usingScriptCache = new StringBuilder();
+ _defaultNamesapce = new HashSet();
+ _excludeDefaultAssembliesFunc = (_, _) => false;
+
+ }
+
+ public static void SetDefaultUsingFilter(Func excludeDefaultAssembliesFunc)
+ {
+ _excludeDefaultAssembliesFunc = excludeDefaultAssembliesFunc;
+ }
+
+ public static int Count { get { return _defaultNamesapce.Count; } }
+
+ internal static void AddUsing(IEnumerable usings, bool autoRebuildScript = true)
+ {
+ try
+ {
+ lock (_defaultNamesapce)
+ {
+ foreach (var name in usings)
+ {
+ if (name.IndexOf('<') == -1)
+ {
+ _defaultNamesapce.Add(name);
+ _usingScriptCache.AppendLine($"using {name!};");
+ }
+ }
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+#if DEBUG
+ Console.WriteLine(ex.Message);
+#endif
+ }
+ }
+
+ internal static void AddUsingWithoutCheck(Assembly assembly, bool autoRebuildScript = true)
+ {
+ try
+ {
+ var tempSets = new HashSet();
+ var types = assembly.ExportedTypes;
+ if (types.Count() > 16)
+ {
+ var result = Parallel.ForEach(types, type =>
+ {
+
+ if (type.IsNested && !type.IsNestedPublic)
+ {
+ return;
+ }
+
+ var name = type.Namespace;
+ lock (tempSets)
+ {
+ if (tempSets.Contains(name))
+ {
+ return;
+ }
+ }
+ if (!string.IsNullOrEmpty(name)
+ && name.IndexOf('<') == -1)
+ {
+ if (!_excludeDefaultAssembliesFunc(default!, name))
+ {
+ lock (tempSets)
+ {
+ tempSets.Add(name);
+ }
+ }
+#if DEBUG
+ else
+ {
+ System.Diagnostics.Debug.WriteLine("[排除程序集]:" + name);
+ }
+#endif
+
+ }
+ });
+ while (!result.IsCompleted)
+ {
+ Thread.Sleep(100);
+ }
+ }
+ else
+ {
+ foreach (var type in types)
+ {
+
+ if (type.IsNested && !type.IsNestedPublic)
+ {
+ continue;
+ }
+
+ var name = type.Namespace;
+
+
+ if (!string.IsNullOrEmpty(name)
+ && !tempSets.Contains(name)
+ && name.IndexOf('<') == -1)
+ {
+
+ if (!_excludeDefaultAssembliesFunc(default!, name))
+ {
+
+ tempSets.Add(name);
+ }
+#if DEBUG
+ else
+ {
+ System.Diagnostics.Debug.WriteLine("[排除程序集]:" + name);
+ }
+#endif
+ }
+ }
+ }
+
+ //*/
+
+ lock (_defaultNamesapce)
+ {
+ foreach (var name in tempSets)
+ {
+ if (_defaultNamesapce.Add(name))
+ {
+ _usingScriptCache.AppendLine($"using {name};");
+ }
+ }
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+#if DEBUG
+ Console.WriteLine(assembly.FullName + ex.Message);
+#endif
+ }
+ }
+
+ internal static void AddUsingWithoutCheckingkAndInternalUsing(Assembly assembly, bool autoRebuildScript = true)
+ {
+ try
+ {
+ var tempSets = new HashSet();
+ var types = assembly.ExportedTypes;
+ if (types.Count() > 16)
+ {
+ var result = Parallel.ForEach(types, type =>
+ {
+
+ if (type.IsNested && !type.IsNestedPublic)
+ {
+ return;
+ }
+
+ var name = type.Namespace;
+
+ lock (tempSets)
+ {
+ if (tempSets.Contains(name))
+ {
+ return;
+ }
+ }
+
+ if (!string.IsNullOrEmpty(name)
+ && !name.StartsWith("Internal")
+ && name.IndexOf('<') == -1)
+ {
+
+ if (!_excludeDefaultAssembliesFunc(default!, name))
+ {
+ lock (tempSets)
+ {
+ tempSets.Add(name);
+ }
+ }
+#if DEBUG
+ else
+ {
+ System.Diagnostics.Debug.WriteLine("[排除程序集]:" + name);
+ }
+#endif
+ }
+ });
+ while (!result.IsCompleted)
+ {
+ Thread.Sleep(100);
+ }
+ }
+ else
+ {
+ foreach (var type in types)
+ {
+
+ if (type.IsNested && !type.IsNestedPublic)
+ {
+ continue;
+ }
+
+ var name = type.Namespace;
+ if (!string.IsNullOrEmpty(name)
+ && !name.StartsWith("Internal")
+ && !tempSets.Contains(name)
+ && name.IndexOf('<') == -1)
+ {
+
+ if (!_excludeDefaultAssembliesFunc(default!, name))
+ {
+ tempSets.Add(name);
+ }
+#if DEBUG
+ else
+ {
+ System.Diagnostics.Debug.WriteLine("[排除程序集]:" + name);
+ }
+#endif
+ }
+ }
+ }
+
+ //*/
+
+ lock (_defaultNamesapce)
+ {
+ foreach (var name in tempSets)
+ {
+ if (_defaultNamesapce.Add(name))
+ {
+ _usingScriptCache.AppendLine($"using {name};");
+ }
+ }
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+#if DEBUG
+ Console.WriteLine(assembly.FullName + ex.Message);
+#endif
+ }
+ }
+
+ ///
+ /// 添加引用
+ ///
+ ///
+ public static void AddUsing(Assembly assembly, bool autoRebuildScript = true)
+ {
+ try
+ {
+ var types = assembly.ExportedTypes;
+ lock (_defaultNamesapce)
+ {
+ foreach (var type in types)
+ {
+ if (type.IsNested && !type.IsNestedPublic)
+ {
+ continue;
+ }
+
+ var name = type.Namespace;
+ if (!string.IsNullOrEmpty(name)
+ && name.IndexOf('<') == -1
+ && !_defaultNamesapce.Contains(name)
+ )
+ {
+
+ if (!_excludeDefaultAssembliesFunc(default!, name))
+ {
+
+ _defaultNamesapce.Add(name);
+ _usingScriptCache.AppendLine($"using {name!};");
+
+ }
+#if DEBUG
+ else
+ {
+
+ System.Diagnostics.Debug.WriteLine("[排除程序集]:" + name);
+
+ }
+#endif
+
+ }
+ }
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+
+ }
+ catch (Exception ex)
+ {
+#if DEBUG
+ Console.WriteLine(assembly.FullName + ex.Message);
+#endif
+ }
+ }
+
+ public static void ReBuildUsingScript()
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+
+ ///
+ /// 添加引用
+ ///
+ ///
+ internal static void AddUsing(AssemblyName assemblyName, bool autoRebuildScript = true)
+ {
+ try
+ {
+ lock (_defaultNamesapce)
+ {
+ var name = assemblyName.Name;
+ if (!string.IsNullOrEmpty(name) && name.IndexOf('<') == -1 && !_defaultNamesapce.Contains(name))
+ {
+ _defaultNamesapce.Add(name);
+ _usingScriptCache.AppendLine($"using {name};");
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+
+ }
+ }
+ catch (Exception ex)
+ {
+#if DEBUG
+ Console.WriteLine(assemblyName.FullName + ex.Message);
+#endif
+ }
+ }
+
+ public static void AddUsing(bool autoRebuildScript = true, params string[] namespaceText)
+ {
+ lock (_defaultNamesapce)
+ {
+ for (int i = 0; i < namespaceText.Length; i++)
+ {
+ var name = namespaceText[i];
+ if (!string.IsNullOrEmpty(name) && name.IndexOf('<') == -1 && !_defaultNamesapce.Contains(name))
+ {
+ _defaultNamesapce.Add(name);
+ _usingScriptCache.AppendLine($"using {name};");
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+ }
+
+
+ }
+ }
+
+ ///
+ /// 查询是否存在该命名空间
+ ///
+ ///
+ ///
+ public static bool HasElement(string @namespace)
+ {
+ lock (_defaultNamesapce)
+ {
+ return _defaultNamesapce.Contains(@namespace);
+ }
+ }
+
+
+ ///
+ /// 移除命名空间
+ ///
+ ///
+ public static void Remove(string @namespace, bool autoRebuildScript = true)
+ {
+ lock (_defaultNamesapce)
+ {
+ if (_defaultNamesapce.Contains(@namespace))
+ {
+ _defaultNamesapce.Remove(@namespace);
+ _usingScriptCache = _usingScriptCache.Replace($"using {@namespace};{Environment.NewLine}", string.Empty);
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+ }
+ }
+ public static void Remove(IEnumerable namespaces, bool autoRebuildScript = true)
+ {
+
+ lock (_defaultNamesapce)
+ {
+ _defaultNamesapce.ExceptWith(namespaces);
+ foreach (var item in namespaces)
+ {
+ _usingScriptCache = _usingScriptCache.Replace($"using {item};{Environment.NewLine}", string.Empty);
+ if (autoRebuildScript)
+ {
+ UsingScript = _usingScriptCache.ToString();
+ }
+ }
+ }
+
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Using/NatashaUsingCache.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Using/NatashaUsingCache.cs
new file mode 100644
index 00000000..a476c5cf
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Component/Using/NatashaUsingCache.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+
+namespace Natasha.CSharp.Using
+{
+ ///
+ /// 引用模板
+ ///
+ public sealed class NatashaUsingCache
+ {
+
+ public readonly HashSet _usings;
+ //internal readonly HashSet _usingTypes;
+ //private static readonly Regex _using_regex;
+
+ //static NatashaUsingCache()
+ //{
+ // _using_regex = new Regex("[a-zA-Z.]+")
+ //}
+ public NatashaUsingCache()
+ {
+
+ _usings = new HashSet();
+
+ }
+
+ public int Count { get { return _usings.Count; } }
+
+
+
+ public bool HasUsing(string @using)
+ {
+ return _usings.Contains(@using);
+ }
+
+
+
+ public NatashaUsingCache Using(string? @using)
+ {
+
+ if (!string.IsNullOrEmpty(@using) && @using!.IndexOf('<') == -1)
+ {
+
+ _usings.Add(@using);
+
+ }
+ return this;
+
+ }
+
+ public NatashaUsingCache Using(IEnumerable @using)
+ {
+
+ _usings.UnionWith(@using);
+ return this;
+
+ }
+
+
+
+
+ ///
+ /// 从程序集里获取引用
+ ///
+ /// 程序集
+ ///
+ public NatashaUsingCache Using(Assembly assembly)
+ {
+
+ if (assembly != default)
+ {
+ try
+ {
+ Using(assembly.GetTypes());
+ }
+ catch
+ {
+
+ }
+
+ }
+ return this;
+
+ }
+
+
+
+ ///
+ /// 设置命名空间
+ ///
+ /// 命名空间
+ ///
+ public NatashaUsingCache Using(params Assembly[] namespaces)
+ {
+
+ for (int i = 0; i < namespaces.Length; i++)
+ {
+
+ Using(namespaces[i]);
+
+ }
+ return this;
+
+ }
+ public NatashaUsingCache Using(IEnumerable namespaces)
+ {
+
+ foreach (var item in namespaces)
+ {
+ Using(item);
+ }
+ return this;
+
+ }
+
+
+
+
+ public NatashaUsingCache Using(IEnumerable namespaces)
+ {
+
+ foreach (var item in namespaces)
+ {
+
+ Using(item);
+
+ }
+ return this;
+
+ }
+
+
+
+
+ public NatashaUsingCache Using(Type type)
+ {
+
+ return Using(type.Namespace);
+
+ }
+
+
+ public override string ToString()
+ {
+ StringBuilder usings = new();
+ foreach (var item in _usings)
+ {
+ usings.AppendLine($"using {item};");
+ }
+ return usings.ToString();
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/ConcurrentDictionaryExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/ConcurrentDictionaryExtension.cs
new file mode 100644
index 00000000..3b0f92c6
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/ConcurrentDictionaryExtension.cs
@@ -0,0 +1,18 @@
+using System.Collections.Concurrent;
+
+static class ConcurrentDictionaryExtension
+{
+ public static S? Remove(this ConcurrentDictionary dict, T key) where T : notnull where S : notnull
+ {
+
+ while (!dict.TryRemove(key, out var result))
+ {
+ if (!dict.ContainsKey(key))
+ {
+ return result;
+ }
+ }
+ return default;
+
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/StopwatchExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/StopwatchExtension.cs
new file mode 100644
index 00000000..b84e1c1e
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/StopwatchExtension.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+
+
+internal static class StopwatchExtension
+{
+ private static readonly ConcurrentDictionary _colorCache;
+ static StopwatchExtension()
+ {
+ _colorCache = new ConcurrentDictionary();
+ _colorCache[new ScoreRange(0, 20)] = ConsoleColor.Green;
+ _colorCache[new ScoreRange(20, 100)] = ConsoleColor.Cyan;
+ _colorCache[new ScoreRange(100, 500)] = ConsoleColor.Yellow;
+ _colorCache[new ScoreRange(500, 1000)] = ConsoleColor.Magenta;
+ _colorCache[new ScoreRange(1000, 100000)] = ConsoleColor.Red;
+ }
+ internal static void StopAndShowCategoreInfo(this Stopwatch stopwatch, string nodeName, string info, int level)
+ {
+ stopwatch.Stop();
+ ShowCategoreInfo(stopwatch, nodeName, info, level);
+ }
+
+
+ internal static void RestartAndShowCategoreInfo(this Stopwatch stopwatch, string nodeName, string info, int level)
+ {
+ stopwatch.Stop();
+ ShowCategoreInfo(stopwatch, nodeName, info, level);
+ stopwatch.Restart();
+ }
+
+
+
+ internal static void ShowCategoreInfo(Stopwatch stopwatch, string nodeName, string info, int level)
+ {
+ var color = Console.ForegroundColor;
+ foreach (var item in _colorCache)
+ {
+ if (item.Key.IsInRange(stopwatch.ElapsedMilliseconds))
+ {
+ Console.ForegroundColor = item.Value;
+ for (int i = 0; i < level; i += 1)
+ {
+ Console.Write("\t");
+ }
+ Console.WriteLine($"---{nodeName}\t{info} : {stopwatch.ElapsedMilliseconds}ms");
+ }
+ }
+ Console.ForegroundColor = color;
+ }
+
+
+
+ ///
+ /// 设置颜色等级
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static Stopwatch SetLevel(this Stopwatch stopwatch, ScoreRange scoreRange, ConsoleColor color)
+ {
+ _colorCache[scoreRange] = color;
+ return stopwatch;
+ }
+}
+
+///
+/// 分数模型
+///
+internal class ScoreRange
+{
+ private readonly long _min;
+ private readonly long _max;
+
+ internal ScoreRange(long min, long max)
+ {
+ _min = min;
+ _max = max;
+ }
+ ///
+ /// 判断得分是否在范围内
+ ///
+ ///
+ ///
+ internal bool IsInRange(long score)
+ {
+ return _min <= score && score <= _max;
+ }
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/SyntaxNodeExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/SyntaxNodeExtension.cs
new file mode 100644
index 00000000..8162af36
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/Inner/SyntaxNodeExtension.cs
@@ -0,0 +1,194 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Natasha.CSharp.Extension.Inner
+{
+ internal static class SyntaxNodeExtension
+ {
+
+ //internal static CompilationUnitSyntax GetRoot(string content)
+ //{
+
+ // SyntaxTree tree = CSharpSyntaxTree.ParseText(content, new CSharpParseOptions(LanguageVersion.Latest));
+ // return tree.GetCompilationUnitRoot();
+
+ //}
+
+ private static IEnumerable GetNodes(SyntaxNode node)
+ {
+ return node.DescendantNodes().OfType();
+ }
+
+
+
+
+ ///
+ /// 根据命名空间和类的位置获取类型
+ ///
+ /// 命名空间节点
+ /// 命名空间里的第index-1个 类
+ ///
+ internal static string? GetClassName(this SyntaxNode namespaceNode, int index = 0)
+ {
+
+ return GetDataStructString(namespaceNode, index);
+
+ }
+
+
+
+
+ ///
+ /// 根据命名空间和结构体的位置获取类型
+ ///
+ /// 命名空间节点
+ /// 命名空间里的第index-1个 结构体
+ ///
+ internal static string? GetStructName(this SyntaxNode namespaceNode, int index = 0)
+ {
+
+ return GetDataStructString(namespaceNode, index);
+
+ }
+
+
+ ///
+ /// 根据命名空间和记录的位置获取类型
+ ///
+ /// 命名空间节点
+ /// 命名空间里的第index-1个 Record
+ ///
+ internal static string? GetRecordName(this SyntaxNode namespaceNode, int index = 0)
+ {
+
+ return GetDataStructString(namespaceNode, index);
+
+ }
+
+
+
+
+ ///
+ /// 根据命名空间和接口的位置获取类型
+ ///
+ /// 命名空间节点
+ /// 命名空间里的第index-1个接口
+ ///
+ internal static string GetInterfaceName(this SyntaxNode namespaceNode, int index = 0)
+ {
+
+ return GetDataStructString(namespaceNode, index);
+
+ }
+
+
+
+
+ ///
+ /// 根据命名空间和枚举的位置获取类型
+ ///
+ /// 命名空间节点
+ /// 命名空间里的第index-1个枚举
+ ///
+ internal static string GetEnumName(this SyntaxNode namespaceNode, int index = 0)
+ {
+
+ return GetDataStructString(namespaceNode, index);
+
+ }
+
+
+
+
+
+ ///
+ /// 获取命名空间
+ ///
+ ///
+ ///
+ ///
+ internal static SyntaxNode NamespaceNode(this SyntaxTree tree, int namespaceIndex = 0)
+ {
+ var root = tree.GetCompilationUnitRoot();
+ var namespaceDeclarationSyntaxes = GetNodes(root);
+
+ if (namespaceDeclarationSyntaxes.Any())
+ {
+ return namespaceDeclarationSyntaxes.ElementAt(namespaceIndex);
+ }
+ else
+ {
+ return root;
+ }
+ }
+
+
+
+ private static string GetDataStructString(SyntaxNode namespaceNode, int index = 0) where T : BaseTypeDeclarationSyntax
+ {
+
+ var nodes = GetNodes(namespaceNode);
+ var node = nodes.ElementAtOrDefault(index);
+ if (node != null)
+ {
+ return node.Identifier.Text;
+ }
+ return string.Empty;
+
+ }
+
+
+
+ ///
+ /// 根据命名空间和方法的位置获取类型
+ ///
+ /// 命名空间节点
+ /// 命名空间里的第index-1个方法
+ internal static string GetMethodName(this SyntaxNode namespaceNode, int index = 0)
+ {
+
+ var nodes = GetNodes(namespaceNode);
+ var node = nodes.ElementAtOrDefault(index);
+ if (node != null)
+ {
+ return node.Identifier.Text;
+ }
+ return string.Empty;
+
+ }
+
+
+ internal static string GetFirstOopName(this SyntaxTree syntaxTree)
+ {
+ var node = syntaxTree.NamespaceNode();
+ var result = node.GetClassName();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = node.GetStructName();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = node.GetRecordName();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = node.GetInterfaceName();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = node.GetEnumName();
+ if (string.IsNullOrEmpty(result))
+ {
+ result = "Not found oop name!";
+ }
+ }
+ }
+ }
+ }
+ return result!;
+ }
+
+
+ }
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaAssemblyBuilderExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaAssemblyBuilderExtension.cs
new file mode 100644
index 00000000..ceff6bde
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaAssemblyBuilderExtension.cs
@@ -0,0 +1,50 @@
+using Microsoft.CodeAnalysis;
+
+
+public static class NatashaAssemblyBuilderExtension
+{
+
+ public static AssemblyCSharpBuilder EnableNullableCompile(this AssemblyCSharpBuilder builder)
+ {
+ builder.ConfigCompilerOption(opt => opt.SetNullableCompile(NullableContextOptions.Enable));
+ return builder;
+ }
+ public static AssemblyCSharpBuilder DisableNullableCompile(this AssemblyCSharpBuilder builder)
+ {
+ builder.ConfigCompilerOption(opt => opt.SetNullableCompile(NullableContextOptions.Disable));
+ return builder;
+ }
+
+ public static AssemblyCSharpBuilder SetOutputFolder(this AssemblyCSharpBuilder builder, string folder)
+ {
+ builder.OutputFolder = folder;
+ return builder;
+ }
+ public static AssemblyCSharpBuilder SetDllFilePath(this AssemblyCSharpBuilder builder, string dllFilePath)
+ {
+ builder.DllFilePath = dllFilePath;
+ return builder;
+ }
+ public static AssemblyCSharpBuilder SetPdbFilePath(this AssemblyCSharpBuilder builder, string pdbFilePath)
+ {
+ builder.PdbFilePath = pdbFilePath;
+ return builder;
+ }
+ public static AssemblyCSharpBuilder SetXmlFilePath(this AssemblyCSharpBuilder builder, string xmlFilePath)
+ {
+ builder.XmlFilePath = xmlFilePath;
+ return builder;
+ }
+
+ public static AssemblyCSharpBuilder DisableSemanticCheck(this AssemblyCSharpBuilder builder)
+ {
+ builder.EnableSemanticHandler = false;
+ return builder;
+ }
+ public static AssemblyCSharpBuilder EnableSemanticCheck(this AssemblyCSharpBuilder builder)
+ {
+ builder.EnableSemanticHandler = true;
+ return builder;
+ }
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaAssemblyExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaAssemblyExtension.cs
new file mode 100644
index 00000000..f5507795
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaAssemblyExtension.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+
+public static class NatashaAssemblyExtension
+{
+
+ ///
+ /// 为统一 Exception 报错, 为 Assembly 封装扩展方法, 反射出类型.
+ ///
+ /// 要反射的程序集
+ /// 反射的短类名
+ ///
+ public static Type GetTypeFromShortName(this Assembly assembly, string typeName)
+ {
+ try
+ {
+ return assembly.GetTypes().First(item => item.Name == typeName);
+ }
+ catch (Exception ex)
+ {
+ throw new NatashaException($"无法在程序集 {assembly.FullName} 中找到该类型 {typeName}!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Type
+ };
+ }
+
+ }
+ ///
+ /// 为统一 Exception 报错, 为 Assembly 封装扩展方法, 反射出类中的方法.
+ ///
+ /// 要反射的程序集
+ /// 反射的短类名
+ /// 类中的方法名
+ ///
+ public static MethodInfo GetMethodFromShortName(this Assembly assembly, string typeName, string methodName)
+ {
+
+ var type = GetTypeFromShortName(assembly, typeName);
+ try
+ {
+ var info = type.GetMethod(methodName);
+ if (info == null)
+ {
+ throw new Exception("获取方法返回空!");
+ }
+ return info!;
+ }
+ catch (Exception ex)
+ {
+
+ throw new NatashaException($"无法在程序集 {assembly.FullName} 中找到类型 {typeName} 对应的 {methodName} 方法!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Method
+ };
+ }
+
+ }
+ ///
+ /// 为统一 Exception 报错, 为 Assembly 封装扩展方法, 反射出类中的方法委托.
+ ///
+ /// 要反射的程序集
+ /// 反射的短类名
+ /// 类中的方法名
+ /// 委托类型
+ /// 绑定信息
+ ///
+ public static Delegate GetDelegateFromShortName(this Assembly assembly, string typeName, string methodName, Type delegateType, object? target = null)
+ {
+
+ var info = GetMethodFromShortName(assembly, typeName, methodName);
+
+ try
+ {
+
+ return info.CreateDelegate(delegateType, target);
+
+ }
+ catch (Exception ex)
+ {
+
+ throw new NatashaException($"无法将程序集 {assembly.FullName} 类型为 {typeName} 的 {methodName} 方法转成委托 {delegateType.Name}!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Delegate
+ };
+
+ }
+
+ }
+ public static T GetDelegateFromShortName(this Assembly assembly, string typeName, string methodName, object? target = null) where T : Delegate
+ {
+ return (T)GetDelegateFromShortName(assembly, typeName, methodName, typeof(T), target);
+ }
+
+ ///
+ /// 为统一 Exception 报错, 为 Assembly 封装扩展方法, 反射出类型.
+ ///
+ /// 要反射的程序集
+ /// 反射的完整类名
+ ///
+ public static Type GetTypeFromFullName(this Assembly assembly, string typeName)
+ {
+
+ try
+ {
+ return assembly.GetTypes().First(item => item.GetDevelopName() == typeName);
+ }
+ catch (Exception ex)
+ {
+ throw new NatashaException($"无法在程序集 {assembly.FullName} 中找到该类型 {typeName}!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Type
+ };
+ }
+
+ }
+
+ ///
+ /// 为统一 Exception 报错, 为 Assembly 封装扩展方法, 反射出类中的方法.
+ ///
+ /// 要反射的程序集
+ /// 反射的完整类名
+ /// 类中的方法名
+ ///
+ public static MethodInfo GetMethodFromFullName(this Assembly assembly, string typeName, string methodName)
+ {
+
+ var type = GetTypeFromFullName(assembly, typeName);
+ try
+ {
+ var info = type.GetMethod(methodName);
+ if (info == null)
+ {
+ throw new Exception("获取方法返回空!");
+ }
+ return info!;
+ }
+ catch (Exception ex)
+ {
+
+ throw new NatashaException($"无法在程序集 {assembly.FullName} 中找到类型 {typeName} 对应的 {methodName} 方法!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Method
+ };
+
+ }
+
+ }
+
+ ///
+ /// 为统一 Exception 报错, 为 Assembly 封装扩展方法, 反射出类中的方法委托.
+ ///
+ /// 要反射的程序集
+ /// 反射的完整类名
+ /// 类中的方法名
+ /// 委托类型
+ /// 绑定信息
+ ///
+ public static Delegate GetDelegateFromFullName(this Assembly assembly, string typeName, string methodName, Type delegateType, object? target = null)
+ {
+
+ var info = GetMethodFromFullName(assembly, typeName, methodName);
+
+ try
+ {
+
+ return info.CreateDelegate(delegateType, target);
+
+ }
+ catch (Exception ex)
+ {
+
+ throw new NatashaException($"无法将程序集 {assembly.FullName} 类型为 {typeName} 的 {methodName} 方法转成委托 {delegateType.Name}!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Delegate
+ };
+
+ }
+
+ }
+ public static T GetDelegateFromFullName(this Assembly assembly, string typeName, string methodName, object? target = null) where T : Delegate
+ {
+ return (T)GetDelegateFromFullName(assembly, typeName, methodName, typeof(T), target);
+ }
+
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaDiagnosticsExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaDiagnosticsExtension.cs
new file mode 100644
index 00000000..91e87e8f
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaDiagnosticsExtension.cs
@@ -0,0 +1,59 @@
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Natasha.CSharp
+{
+ public static class NatashaDiagnosticsExtension
+ {
+ public static SyntaxNode GetSyntaxNode(this Diagnostic diagnostic, CompilationUnitSyntax root)
+ {
+ return root.FindNode(diagnostic.Location.SourceSpan);
+ }
+ public static T? GetTypeSyntaxNode(this Diagnostic diagnostic, CompilationUnitSyntax root) where T : class
+ {
+ var node = GetSyntaxNode(diagnostic, root);
+ while (node is not T && node.Parent != null)
+ {
+ node = node!.Parent;
+ }
+ return node as T;
+ }
+ public static void RemoveDefaultUsingAndUsingNode(this Diagnostic diagnostic, CompilationUnitSyntax root, HashSet removeCollection)
+ {
+ var usingNode = GetTypeSyntaxNode(diagnostic, root);
+ if (usingNode != null)
+ {
+ RemoveUsingAndNode(usingNode, removeCollection);
+ }
+ }
+
+ public static void RemoveUsingAndNode(this UsingDirectiveSyntax usingDirectiveSyntax, HashSet removeCollection)
+ {
+ removeCollection.Add(usingDirectiveSyntax);
+ var name = usingDirectiveSyntax.Name;
+ if (name!=null)
+ {
+ DefaultUsing.Remove(name.ToString());
+ }
+
+ }
+
+ public static void RemoveUsingAndNodesFromStartName(this Diagnostic diagnostic, CompilationUnitSyntax root, HashSet removeCollection)
+ {
+ var usingNode = GetTypeSyntaxNode(diagnostic, root);
+ if (usingNode!=null)
+ {
+ var usingNodes = (from usingDeclaration in root.Usings
+ where usingDeclaration.Name != null && usingDeclaration.Name.ToString().StartsWith(usingNode.Name!.ToString())
+ select usingDeclaration).ToList();
+
+ removeCollection.UnionWith(usingNodes);
+ DefaultUsing.Remove(usingNodes.Select(item => item.Name!.ToString()));
+ }
+ }
+ }
+}
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaStringExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaStringExtension.cs
new file mode 100644
index 00000000..144a8430
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaStringExtension.cs
@@ -0,0 +1,12 @@
+public static class NatashaStringExtension
+{
+
+ public static string ToReadonlyScript(this string field)
+ {
+
+ return $"Unsafe.AsRef({field})";
+
+ }
+
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaTypeExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaTypeExtension.cs
new file mode 100644
index 00000000..89050c91
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Extension/NatashaTypeExtension.cs
@@ -0,0 +1,37 @@
+using System;
+
+
+public static class NatashaTypeExtension
+{
+
+ public static Delegate GetDelegateFromType(this Type type, string methodName, Type delegateType, object? target = null)
+ {
+ var info = type.GetMethod(methodName);
+ try
+ {
+ if (info == null)
+ {
+ throw new Exception($"未从{type.FullName}中反射出{methodName}方法!");
+ }
+ return info.CreateDelegate(delegateType, target);
+
+ }
+ catch (Exception ex)
+ {
+
+ NatashaException exception = new($"类型为 {type.FullName} 的 {methodName} 方法无法转成委托 {delegateType.Name}!错误信息:{ex.Message}")
+ {
+ ErrorKind = NatashaExceptionKind.Delegate
+ };
+ throw exception;
+
+ }
+
+ }
+ public static T GetDelegateFromType(this Type type, string methodName, object? target = null) where T : Delegate
+ {
+ return (T)GetDelegateFromType(type, methodName, typeof(T), target);
+ }
+
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/NatashaManagement.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/NatashaManagement.cs
new file mode 100644
index 00000000..1ab34646
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/NatashaManagement.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Reflection;
+
+public static partial class NatashaManagement
+{
+#if MULTI
+ ///
+ /// 和 NatashaInitializer.Preheating(); 一样
+ ///
+ public static void Preheating(
+ Func? excludeReferencesFunc = null,
+ bool useRuntimeUsing = false,
+ bool useRuntimeReference = false)
+ {
+ NatashaInitializer.Preheating(excludeReferencesFunc, useRuntimeUsing, useRuntimeReference);
+ }
+ public static void Preheating(
+ bool useRuntimeUsing = false,
+ bool useRuntimeReference = false)
+ {
+ NatashaInitializer.Preheating(null, useRuntimeUsing, useRuntimeReference);
+ }
+#else
+ public static void Preheating(
+ Func? excludeReferencesFunc = null)
+ {
+ NatashaInitializer.Preheating(excludeReferencesFunc);
+ }
+#endif
+
+
+ ///
+ /// 增加全局 Using 引用,其他编译将默认添加该 Using
+ /// 例如: AddGlobalUsing("System.IO");
+ ///
+ ///
+ public static void AddGlobalUsing(params string[] @namespaces)
+ {
+ DefaultUsing.AddUsing(@namespaces);
+ }
+
+ ///
+ /// 增加全局 Using 引用,其他编译将默认添加该 Using
+ /// 例如: AddGlobalUsing("System.IO");
+ ///
+ ///
+ public static void AddGlobalUsing(params Assembly[] @namespaces)
+ {
+ foreach (var item in @namespaces)
+ {
+ DefaultUsing.AddUsing(item);
+ }
+ }
+
+ ///
+ /// 移除全局 Using 引用
+ /// 例如: RemoveGlobalUsing("System.IO");
+ ///
+ ///
+ public static void RemoveGlobalUsing(params string[] @namespaces)
+ {
+ DefaultUsing.Remove(@namespaces);
+ }
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/NatashaReferencePathsHelper.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/NatashaReferencePathsHelper.cs
new file mode 100644
index 00000000..782fc2fd
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/NatashaReferencePathsHelper.cs
@@ -0,0 +1,80 @@
+
+using Microsoft.CodeAnalysis;
+using Microsoft.Extensions.DependencyModel;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.PortableExecutable;
+
+public static class NatashaReferencePathsHelper
+{
+ public static IEnumerable? GetReferenceFiles(Func excludeReferencesFunc)
+ {
+
+
+ IEnumerable? paths = null;
+ try
+ {
+ paths = DependencyContext.Default?
+ .CompileLibraries.SelectMany(cl => cl.ResolveReferencePaths().Where(asmPath =>
+ {
+ try
+ {
+ //#ISSUE:178
+ using var peStream = File.OpenRead(asmPath);
+ PEReader pEReader = new PEReader(peStream);
+ if (!pEReader.HasMetadata)
+ {
+ return false;
+ }
+
+ var asmName = AssemblyName.GetAssemblyName(asmPath);
+ return !excludeReferencesFunc(asmName, asmName.Name);
+ }
+ catch
+ {
+ return false;
+ }
+ })).ToList();
+ }
+ catch
+ {
+
+ }
+
+ if (paths == null || !paths.Any())
+ {
+ var refsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "refs");
+ if (Directory.Exists(refsFolder))
+ {
+ paths = Directory.GetFiles(refsFolder);
+ }
+
+ refsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ref");
+ if (Directory.Exists(refsFolder))
+ {
+ if (paths != null)
+ {
+
+ var tempPaths = Directory.GetFiles(refsFolder);
+ if (tempPaths != null && tempPaths!.Count() > 0)
+ {
+ paths = paths.Concat(tempPaths);
+ }
+
+ }
+ else
+ {
+
+ paths = Directory.GetFiles(refsFolder);
+
+ }
+ }
+ }
+ return paths;
+
+ }
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/AvailableNameReverser.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/AvailableNameReverser.cs
new file mode 100644
index 00000000..c6dbf204
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/AvailableNameReverser.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace Natasha.CSharp.Reverser
+{
+ ///
+ /// 文件可用名反解
+ ///
+ public class AvailableNameReverser
+ {
+
+ ///
+ /// 根据类型获取可用名
+ ///
+ /// 类型
+ ///
+ public static string GetAvailableName(Type type)
+ {
+
+ return type.GetDevelopName().Replace('<', '_').Replace('>', '_').Replace(',', '_').Replace("[", "@").Replace("]", "@");
+
+ }
+
+ }
+
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/TypeNameReverser.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/TypeNameReverser.cs
new file mode 100644
index 00000000..5cf48573
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/TypeNameReverser.cs
@@ -0,0 +1,240 @@
+using System;
+using System.Text;
+
+namespace Natasha.CSharp.Reverser
+{
+ ///
+ /// 类名反解器
+ ///
+ public static class TypeNameReverser
+ {
+ //private static readonly Func _nullableAttrCheck;
+
+ //static TypeNameReverser()
+ //{
+ // _nullableAttrCheck = (name) =>
+ // {
+ // return name.Contains("MaybeNullAttribute")
+ // || name.Contains("AllowNullAttribute")
+ // //|| name.Contains("NullableAttribute");
+ // || name.Contains("NullableContextAttribute");
+ // };
+
+ //}
+
+ ///
+ /// 类名反解
+ ///
+ /// 类型
+ ///
+ internal static string ReverseFullName(Type type, bool ignoreFlag = false)
+ {
+
+ string fatherString = string.Empty;
+ //外部类处理
+ if (type.DeclaringType != null && type.FullName != null)
+ {
+ fatherString = ReverseFullName(type.DeclaringType, ignoreFlag) + ".";
+ }
+
+
+ //后缀
+ StringBuilder Suffix = new StringBuilder();
+
+
+ //数组判别
+ while (type!.HasElementType)
+ {
+
+ if (type.IsArray)
+ {
+
+ int count = type.GetArrayRank();
+
+ Suffix.Append("[");
+ for (int i = 0; i < count - 1; i++)
+ {
+ Suffix.Append(",");
+ }
+ Suffix.Append("]");
+
+ }
+ type = type.GetElementType()!;
+
+ }
+
+
+ //泛型判别
+ if (type.IsGenericType)
+ {
+
+ StringBuilder result = new StringBuilder();
+ if (string.IsNullOrEmpty(fatherString) && !string.IsNullOrEmpty(type.Namespace) && !string.IsNullOrEmpty(type.FullName))
+ {
+ result.Append(type.Namespace + ".");
+ }
+ result.Append($"{type.Name.Split('`')[0]}<");
+ bool HasWriteArguments = false;
+
+
+ if (type.GenericTypeArguments.Length > 0)
+ {
+
+ HasWriteArguments = true;
+ result.Append(ReverseFullName(type.GenericTypeArguments[0], ignoreFlag));
+ for (int i = 1; i < type.GenericTypeArguments.Length; i++)
+ {
+
+ result.Append(',');
+ result.Append(ReverseFullName(type.GenericTypeArguments[i], ignoreFlag));
+
+ }
+
+ }
+ if (!HasWriteArguments)
+ {
+
+ var types = ((System.Reflection.TypeInfo)type).GenericTypeParameters;
+ if (types.Length > 0)
+ {
+
+ if (!ignoreFlag)
+ {
+ result.Append(ReverseFullName(types[0], ignoreFlag));
+ }
+
+ for (int i = 1; i < types.Length; i++)
+ {
+
+ result.Append(',');
+ if (!ignoreFlag)
+ {
+ result.Append(ReverseFullName(types[i], ignoreFlag));
+ }
+
+ }
+
+ }
+
+ }
+
+
+ result.Append('>');
+ result.Append(Suffix);
+ return fatherString + result.ToString();
+
+ }
+ else
+ {
+
+ //特殊类型判别
+ if (type == typeof(void))
+ {
+
+ return "void";
+
+ }
+ if (string.IsNullOrEmpty(fatherString) && !string.IsNullOrEmpty(type.Namespace) && !string.IsNullOrEmpty(type.FullName))
+ {
+ return type.Namespace + "." + type.Name + Suffix;
+ }
+ return fatherString + type.Name + Suffix;
+
+ }
+ }
+
+
+ ///
+ /// 类名反解
+ ///
+ /// 类型
+ ///
+ public static string ReverseTypeName(Type type)
+ {
+
+ string fatherString = string.Empty;
+ //外部类处理
+ if (type.DeclaringType != null && type.FullName != null)
+ {
+ fatherString = ReverseTypeName(type.DeclaringType) + ".";
+ }
+
+
+ //后缀
+ StringBuilder Suffix = new StringBuilder();
+
+
+ //数组判别
+ while (type.HasElementType)
+ {
+
+ if (type.IsArray)
+ {
+
+ int count = type.GetArrayRank();
+
+ Suffix.Append("[");
+ for (int i = 0; i < count - 1; i++)
+ {
+ Suffix.Append(",");
+ }
+ Suffix.Append("]");
+
+ }
+ type = type.GetElementType()!;
+
+ }
+
+ //if (type.CustomAttributes.Any(item => _nullableAttrCheck(item.AttributeType.Name)))
+ //{
+ // Suffix.Append('?');
+ //}
+
+ //泛型判别
+ if (type.IsGenericType)
+ {
+
+ StringBuilder result = new StringBuilder();
+ result.Append($"{type.Name.Split('`')[0]}<");
+
+ if (type.GenericTypeArguments.Length > 0)
+ {
+
+ result.Append(ReverseTypeName(type.GenericTypeArguments[0]));
+ for (int i = 1; i < type.GenericTypeArguments.Length; i++)
+ {
+
+ result.Append(',');
+ result.Append(ReverseTypeName(type.GenericTypeArguments[i]));
+
+ }
+
+ }
+
+ result.Append('>');
+ result.Append(Suffix);
+ return fatherString + result.ToString();
+
+ }
+ else
+ {
+
+ //特殊类型判别
+ if (type == typeof(void))
+ {
+
+ return "void";
+
+ }
+ if (string.IsNullOrEmpty(fatherString) && !string.IsNullOrEmpty(type.Namespace) && !string.IsNullOrEmpty(type.FullName))
+ {
+ return type.Name + Suffix;
+ }
+ return fatherString + type.Name + Suffix;
+
+ }
+
+ }
+ }
+
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/TypeNatashaExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/TypeNatashaExtension.cs
new file mode 100644
index 00000000..aec501a5
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Public/Reverser/TypeNatashaExtension.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using Natasha.CSharp.Reverser;
+
+public static class TypeNatashaExtension
+{
+
+ ///
+ /// 判断是否为值类型,字符串类型,委托类型,Type类型,及委托的子类型其中之一
+ ///
+ ///
+ ///
+ public static bool IsSimpleType(this Type type)
+ {
+ return type.IsValueType ||
+ type == typeof(string) ||
+ type.IsSubclassOf(typeof(Delegate)) ||
+ type == typeof(Delegate) ||
+ type.IsSubclassOf(typeof(MulticastDelegate)) ||
+ type == typeof(MulticastDelegate) ||
+ type == typeof(Type);
+ }
+
+
+ ///
+ /// 当前类是否实现了某接口
+ ///
+ /// 要判断的类型
+ /// 接口类型
+ ///
+ public static bool IsImplementFrom(this Type type, Type iType)
+ {
+ return new HashSet(type.GetInterfaces()).Contains(iType);
+ }
+
+
+ ///
+ /// 当前类是否实现了某接口
+ ///
+ /// 要判断的类型
+ /// 接口类型
+ ///
+ public static bool IsImplementFrom(this Type type)
+ {
+ return new HashSet(type.GetInterfaces()).Contains(typeof(T));
+ }
+
+ public static HashSet GetAllTypes(this Type type)
+ {
+ HashSet result = new();
+ type.GetAllTypes(result);
+ return result;
+ }
+ ///
+ /// 获取与该类型相关的所有类型,例如 List => List<> / int32
+ ///
+ ///
+ ///
+ internal static void GetAllTypes(this Type type, HashSet result)
+ {
+
+ result.Add(type);
+ if (type.HasElementType)
+ {
+ var temp = type.GetElementType();
+ temp?.GetAllTypes(result);
+
+ }
+ else if (type.IsGenericType && type.FullName != null)
+ {
+ foreach (var item in type.GetGenericArguments())
+ {
+ item.GetAllTypes(result);
+ }
+ }
+
+ }
+
+
+ ///
+ /// 获取所有该类所含的类 List 则返回 List<> , Int32
+ ///
+ ///
+ ///
+ public static HashSet GetAllTypes()
+ {
+ return typeof(T).GetAllTypes();
+ }
+
+
+
+ ///
+ /// 将类名替换成 文件名可使用的名字
+ ///
+ ///
+ ///
+ public static string GetAvailableName(this Type type)
+ {
+ return AvailableNameReverser.GetAvailableName(type);
+ }
+
+
+ ///
+ /// 获取运行时完整类名
+ /// 例如: System.Collections.Generic
+ /// 例如: System.Collections.Generic
+ ///
+ ///
+ ///
+ public static string GetDevelopName(this Type type)
+ {
+ return TypeNameReverser.ReverseFullName(type);
+ }
+
+
+ ///
+ /// 获取运行时类名, 例如: List
+ ///
+ ///
+ ///
+ public static string GetRuntimeName(this Type type)
+ {
+ return TypeNameReverser.ReverseTypeName(type);
+ }
+
+
+ ///
+ /// 获取运行时类名,无标识
+ /// System.Collections.Generic.List<>
+ ///
+ ///
+ ///
+ public static string GetDevelopNameWithoutFlag(this Type type)
+ {
+ return TypeNameReverser.ReverseFullName(type, true);
+ }
+
+
+ //
+ /// 制作范型类型
+ ///
+ /// IType
+ /// T,S,D
+ ///
+ public static Type With(this Type type, params Type[] types)
+ {
+ return type.MakeGenericType(types);
+ }
+
+}
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Compile.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Compile.cs
new file mode 100644
index 00000000..d6c9db5c
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Compile.cs
@@ -0,0 +1,156 @@
+#if !MULTI
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.Emit;
+using Natasha.CSharp.Component;
+using Natasha.CSharp.Component.Exception;
+using Natasha.CSharp.Extension.Inner;
+using System;
+using System.Collections.Immutable;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+
+///
+/// 程序集编译构建器 - 编译选项
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ ///
+ /// 流编译成功之后触发的事件
+ ///
+ public event Action? CompileSucceedEvent;
+
+
+ ///
+ /// 流编译失败之后触发的事件
+ ///
+ public event Action>? CompileFailedEvent;
+
+
+ public CSharpCompilation GetAvailableCompilation()
+ {
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+
+ var options = _compilerOptions.GetCompilationOptions();
+ var references = NatashaReferenceCache.GetReferences();
+ _compilation = CSharpCompilation.Create(AssemblyName, SyntaxTrees, references, options);
+
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Compiler]", "获取编译单元", 2);
+#endif
+
+
+ if (EnableSemanticHandler)
+ {
+ foreach (var item in _semanticAnalysistor)
+ {
+ _compilation = item(this, _compilation, _semanticCheckIgnoreAccessibility);
+ }
+ }
+
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Semantic]", "语义处理", 2);
+#endif
+ return _compilation;
+ }
+
+
+ ///
+ /// 将 SyntaxTrees 中的语法树编译到程序集.如果不成功会抛出 NatashaException.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// //程序集的域加载行为, 该行为决定了编译后的程序集随着依赖加载到域中的处理结果.
+ /// //和加载插件原理相同.
+ /// builder.CompileWithAssemblyLoadBehavior(enum);
+ ///
+ /// //编译单元的引用加载行为, 遇到同名不同版本的引用该如何处理.
+ /// builder.CompileWithReferenceLoadBehavior(enum);
+ /// builder.CompileWithReferencesFilter(func);
+ ///
+ ///
+ ///
+ ///
+ public Assembly GetAssembly()
+ {
+
+ if (_compilation == null)
+ {
+ _compilation = GetAvailableCompilation();
+ }
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+ Stream dllStream;
+ Stream pdbStream;
+ Stream? xmlStream = null;
+ if (DllFilePath != string.Empty)
+ {
+ dllStream = File.Create(DllFilePath);
+ }
+ else
+ {
+ dllStream = new MemoryStream();
+ }
+
+ if (PdbFilePath != string.Empty)
+ {
+ pdbStream = File.Create(PdbFilePath);
+ }
+ else
+ {
+ pdbStream = new MemoryStream();
+ }
+
+ if (XmlFilePath != string.Empty)
+ {
+ xmlStream = File.Create(XmlFilePath);
+ }
+
+ var compileResult = _compilation.Emit(
+ dllStream,
+ pdbStream: pdbStream,
+ xmlDocumentationStream: xmlStream,
+ options: new EmitOptions(pdbFilePath: PdbFilePath == string.Empty ? null : PdbFilePath, debugInformationFormat: DebugInformationFormat.PortablePdb));
+
+
+ LogCompilationEvent?.Invoke(_compilation.GetNatashaLog());
+
+ dllStream.Dispose();
+ pdbStream?.Dispose();
+ xmlStream?.Dispose();
+
+ Assembly? assembly = null;
+ if (compileResult.Success)
+ {
+ assembly = Assembly.LoadFrom(DllFilePath);
+ DefaultUsing.AddUsing(assembly);
+ NatashaReferenceCache.AddReference(DllFilePath);
+ CompileSucceedEvent?.Invoke(_compilation, assembly!);
+ }
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[ Emit ]", "编译时长", 2);
+#endif
+
+ if (!compileResult.Success)
+ {
+ CompileFailedEvent?.Invoke(_compilation, compileResult.Diagnostics);
+ throw NatashaExceptionAnalyzer.GetCompileException(_compilation, compileResult.Diagnostics);
+ }
+
+ return assembly!;
+ }
+
+}
+
+#endif
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Ouput.Single.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Ouput.Single.cs
new file mode 100644
index 00000000..0a1e5429
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Ouput.Single.cs
@@ -0,0 +1,37 @@
+#if !MULTI
+using System;
+using System.IO;
+
+///
+/// 程序集编译构建器-输出
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ public AssemblyCSharpBuilder UseNatashaFileOut(string? folder = null)
+ {
+ if (folder == null)
+ {
+ if (OutputFolder == GlobalOutputFolder)
+ {
+ OutputFolder = Path.Combine(GlobalOutputFolder,"Default");
+ }
+ }
+ else
+ {
+ OutputFolder = folder;
+ }
+ if (!Directory.Exists(OutputFolder))
+ {
+ Directory.CreateDirectory(OutputFolder);
+ }
+ DllFilePath = Path.Combine(OutputFolder, $"{AssemblyName}.dll");
+ PdbFilePath = Path.Combine(OutputFolder, $"{AssemblyName}.pdb");
+ XmlFilePath = Path.Combine(OutputFolder, $"{AssemblyName}.xml");
+ return this;
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Syntax.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Syntax.cs
new file mode 100644
index 00000000..ba76625c
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.Syntax.cs
@@ -0,0 +1,29 @@
+#if !MULTI
+///
+/// 程序集编译构建器 - 语法树相关
+///
+public sealed partial class AssemblyCSharpBuilder
+{
+ ///
+ /// 注入代码并拼接using
+ ///
+ /// 脚本代码
+ /// using 拼接行为
+ ///
+ public AssemblyCSharpBuilder Add(string script, UsingLoadBehavior usingLoadBehavior)
+ {
+ switch (usingLoadBehavior)
+ {
+ case UsingLoadBehavior.WithDefault:
+ case UsingLoadBehavior.WithAll:
+ return AddScript(DefaultUsing.UsingScript + script);
+ default:
+ return AddScript(script);
+ }
+ }
+}
+#endif
+
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.cs
new file mode 100644
index 00000000..dfd06dbf
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/CompileUnit/AssemblyCSharpBuilder.cs
@@ -0,0 +1,42 @@
+#if !MULTI
+using Natasha.CSharp.Compiler.SemanticAnalaysis;
+using System;
+using System.Runtime.CompilerServices;
+
+///
+/// 程序集编译构建器
+/// 默认开启语义过滤
+/// 默认域内引用优先
+/// 默认GUID作为程序集名
+///
+[assembly: InternalsVisibleTo("FrameworkFunctionUT, PublicKey=002400000480000094000000060200000024000052534131000400000100010069acb31dd0d9918441d6ed2b49cd67ae17d15fd6ded4ccd2f99b4a88df8cddacbf72d5897bb54f406b037688d99f482ff1c3088638b95364ef614f01c3f3f2a2a75889aa53286865463fb1803876056c8b98ec57f0b3cf2b1185de63d37041ba08f81ddba0dccf81efcdbdc912032e8d2b0efa21accc96206c386b574b9d9cb8")]
+public sealed partial class AssemblyCSharpBuilder
+{
+
+ public AssemblyCSharpBuilder():this(Guid.NewGuid().ToString("N"))
+ {
+
+ }
+ public AssemblyCSharpBuilder(string assemblyName)
+ {
+ EnableSemanticHandler = true;
+ _semanticCheckIgnoreAccessibility = true;
+ OutputFolder = GlobalOutputFolder;
+ _parsingBehavior = UsingLoadBehavior.None;
+ _compilerOptions = new();
+ _semanticAnalysistor = new()
+ {
+ UsingAnalysistor._usingSemanticDelegate
+ };
+ SyntaxTrees = new();
+ AssemblyName = assemblyName;
+ DllFilePath = string.Empty;
+ PdbFilePath = string.Empty;
+ XmlFilePath = string.Empty;
+ this.UseNatashaFileOut();
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/Component/NatashaReferenceCache.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/Component/NatashaReferenceCache.cs
new file mode 100644
index 00000000..403c0ffb
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/Component/NatashaReferenceCache.cs
@@ -0,0 +1,72 @@
+#if !MULTI
+using Microsoft.CodeAnalysis;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+
+namespace Natasha.CSharp.Component
+{
+ //与元数据相关
+ //数据值与程序集及内存相关
+ public static class NatashaReferenceCache
+ {
+ ///
+ /// 存放内存流编译过来的程序集与引用
+ ///
+ private static readonly HashSet _referenceCache;
+ static NatashaReferenceCache()
+ {
+ _referenceCache = new();
+ }
+
+ public static int Count { get { return _referenceCache.Count; } }
+
+ public static void AddReference(string path)
+ {
+ DefaultUsing.AddUsing(Assembly.ReflectionOnlyLoadFrom(path));
+ AddReference(MetadataReference.CreateFromFile(path));
+ }
+ public static void AddReference(Assembly assembly)
+ {
+ DefaultUsing.AddUsing(assembly);
+ if (!string.IsNullOrEmpty(assembly.Location))
+ {
+ AddReference(MetadataReference.CreateFromFile(assembly.Location));
+ }
+ }
+ public static void RemoveReference(string path)
+ {
+ RemoveReference(MetadataReference.CreateFromFile(path));
+ }
+ public static void RemoveReference(Assembly assembly)
+ {
+ if (!string.IsNullOrEmpty(assembly.Location))
+ {
+ RemoveReference(MetadataReference.CreateFromFile(assembly.Location));
+ }
+ }
+
+ private static void RemoveReference(MetadataReference reference)
+ {
+ lock (_referenceCache)
+ {
+ _referenceCache.Remove(reference);
+ }
+ }
+
+ private static void AddReference(MetadataReference reference)
+ {
+ lock (_referenceCache)
+ {
+ _referenceCache.Add(reference);
+ }
+ }
+
+ public static IEnumerable GetReferences()
+ {
+ return _referenceCache;
+ }
+
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/Extension/Inner/CSharpCompilationExtension.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/Extension/Inner/CSharpCompilationExtension.cs
new file mode 100644
index 00000000..311ed16b
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/Extension/Inner/CSharpCompilationExtension.cs
@@ -0,0 +1,126 @@
+#if !MULTI
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Natasha.CSharp.Extension.Inner
+{
+
+ internal static class CSharpCompilationExtension
+ {
+ internal static NatashaCompilationLog GetNatashaLog(this CSharpCompilation compilation)
+ {
+ NatashaCompilationLog natashaCompilation = new();
+ natashaCompilation.AddCompilationInfo("AssemblyName", compilation.AssemblyName ?? string.Empty);
+ natashaCompilation.AddCompilationInfo("Language", compilation.Language);
+ natashaCompilation.AddCompilationInfo("LanguageVersion", compilation.LanguageVersion.ToString());
+ natashaCompilation.AddCompilationInfo("SyntaxTreeCount", compilation.SyntaxTrees.Length.ToString());
+ natashaCompilation.AddCompilationInfo("ReferencesCount", compilation.References.Count().ToString());
+ var errors = compilation.GetDiagnostics();
+ if (errors.Length > 0)
+ {
+ Dictionary> syntaxCache = new();
+ foreach (var item in compilation.GetDiagnostics())
+ {
+ if (item.Location.SourceTree != null)
+ {
+ var tree = item.Location.SourceTree;
+ if (!syntaxCache.ContainsKey(tree))
+ {
+ syntaxCache[tree] = new List();
+ }
+ syntaxCache[tree].Add(item);
+ }
+ }
+ natashaCompilation.HasError = true;
+ foreach (var item in syntaxCache)
+ {
+ var codeText = item.Key.ToString();
+ StringBuilder errorMessage = new();
+ foreach (var error in item.Value)
+ {
+ var span = error.Location.GetLineSpan();
+ errorMessage.AppendLine($"第{span.StartLinePosition.Line + 1}行,第{span.StartLinePosition.Character}个字符: 内容【{GetErrorMessage(codeText, error.Location.GetLineSpan())}】 {error.GetMessage()}");
+ }
+ natashaCompilation.AddMessage(item.Value.Count, AddLineNumber(codeText), errorMessage.ToString());
+ }
+ }
+ else
+ {
+ natashaCompilation.HasError = false;
+ foreach (var item in compilation.SyntaxTrees)
+ {
+ natashaCompilation.AddMessage(0, AddLineNumber(item.ToString()), item.GetFirstOopName());
+ }
+ }
+ return natashaCompilation;
+ }
+ private static string GetErrorMessage(string content, FileLinePositionSpan linePositionSpan)
+ {
+
+ var start = linePositionSpan.StartLinePosition;
+ var end = linePositionSpan.EndLinePosition;
+
+
+ var arrayLines = content.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+ var currentErrorLine = arrayLines[start.Line];
+
+
+ if (start.Line == end.Line)
+ {
+
+ if (start.Character == end.Character)
+ {
+
+ return currentErrorLine.Trim();
+
+ }
+ else
+ {
+
+ return currentErrorLine.Substring(start.Character, end.Character - start.Character).Trim();
+
+ }
+
+ }
+ else
+ {
+
+ StringBuilder builder = new();
+ builder.AppendLine(currentErrorLine.Substring(start.Character, currentErrorLine.Length-start.Character));
+ for (int i = start.Line; i < end.Line - 1; i += 1)
+ {
+
+ builder.AppendLine(arrayLines[i]);
+
+ }
+ currentErrorLine = arrayLines[end.Line];
+ builder.AppendLine(currentErrorLine.Substring(0, end.Character));
+ return builder.ToString();
+
+ }
+
+ }
+ private static string AddLineNumber(string code)
+ {
+
+ StringBuilder builder = new();
+ var arrayLines = code.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
+ for (int i = 0; i < arrayLines.Length; i += 1)
+ {
+
+ builder.AppendLine($"{i + 1}\t{arrayLines[i]}");
+
+ }
+ return builder.ToString();
+
+ }
+ }
+
+}
+#endif
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/NatashaInitializer.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/NatashaInitializer.cs
new file mode 100644
index 00000000..3b3c8b4d
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/NatashaInitializer.cs
@@ -0,0 +1,99 @@
+#if !MULTI
+using Microsoft.CodeAnalysis;
+using Microsoft.Extensions.DependencyModel;
+using Natasha.CSharp;
+using Natasha.CSharp.Component;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+
+public static class NatashaInitializer
+{
+ private static readonly object _lock = new();
+
+ private static bool _isCompleted = false;
+ public static void Preheating(Func? excludeReferencesFunc = null, bool useLowMemeory = false)
+ {
+
+ if (!_isCompleted)
+ {
+ lock (_lock)
+ {
+ if (_isCompleted)
+ {
+ return;
+ }
+
+ _isCompleted = true;
+
+ if (excludeReferencesFunc == null)
+ {
+ excludeReferencesFunc = (_, _) => false;
+ }
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+
+ DefaultUsing.SetDefaultUsingFilter(excludeReferencesFunc);
+ IEnumerable? paths = NatashaReferencePathsHelper.GetReferenceFiles(excludeReferencesFunc);
+
+
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[Reference]", "过滤初始化引用", 1);
+#endif
+ if (paths != null && paths.Count() > 0)
+ {
+ ResolverMetadata(paths);
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[ Domain ]", "默认信息初始化", 1);
+#endif
+
+ AssemblyCSharpBuilder cSharpBuilder = new();
+ cSharpBuilder.UseNatashaFileOut();
+ cSharpBuilder.ConfigCompilerOption(item => item.AddSupperess("CS8019").UseSuppressReportor(false));
+ cSharpBuilder.EnableSemanticHandler = true;
+ cSharpBuilder.Add(DefaultUsing.UsingScript + "public class A{}", UsingLoadBehavior.WithDefault);
+ var assembly = cSharpBuilder.GetAssembly();
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[FirstCompile]", "初始化编译", 1);
+#endif
+ }
+
+ }
+ }
+
+ }
+ private static void ResolverMetadata(IEnumerable paths)
+ {
+
+ var result = Parallel.ForEach(paths, (path) =>
+ {
+ //Assembly? assembly = null;
+ try
+ {
+ Assembly assembly = Assembly.ReflectionOnlyLoadFrom(path);
+ NatashaReferenceCache.AddReference(path);
+ DefaultUsing.AddUsingWithoutCheck(assembly);
+ }
+ catch
+ {
+ //Console.WriteLine(assembly?.FullName);
+ }
+ });
+ while (!result.IsCompleted)
+ {
+ Thread.Sleep(100);
+ }
+ DefaultUsing.ReBuildUsingScript();
+
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/NatashaManagement.cs b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/NatashaManagement.cs
new file mode 100644
index 00000000..a6de7239
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/SingleDomain/NatashaManagement.cs
@@ -0,0 +1,78 @@
+#if !MULTI
+using Natasha.CSharp.Component;
+using System;
+using System.Reflection;
+
+public static partial class NatashaManagement
+{
+
+
+ ///
+ /// 增加元数据引用,编译需要元数据支持.
+ ///
+ /// 程序集
+ ///
+ public static bool AddGlobalReference(Assembly assembly)
+ {
+ NatashaReferenceCache.AddReference(assembly);
+ return true;
+ }
+ ///
+ /// 增加元数据引用,编译需要元数据支持.
+ ///
+ /// 类型
+ ///
+ public static bool AddGlobalReference(Type type)
+ {
+ if (type.Assembly.IsDynamic || type.Assembly.Location == null)
+ {
+ return false;
+ }
+ NatashaReferenceCache.AddReference(type.Assembly);
+ return true;
+ }
+ ///
+ /// 增加元数据引用,编译需要元数据支持.
+ ///
+ /// 程序集路径
+ ///
+ public static bool AddGlobalReference(string path)
+ {
+ NatashaReferenceCache.AddReference(path);
+ return true;
+ }
+
+ ///
+ /// 移除元数据引用,编译需要元数据支持.
+ ///
+ /// 程序集
+ ///
+ public static bool RemoveGlobalReference(Assembly assembly)
+ {
+ NatashaReferenceCache.AddReference(assembly);
+ return true;
+ }
+
+ ///
+ /// 移除元数据引用,编译需要元数据支持.
+ ///
+ /// 类型
+ ///
+ public static bool RemoveGlobalReference(Type type)
+ {
+ NatashaReferenceCache.AddReference(type.Assembly);
+ return true;
+ }
+
+ ///
+ /// 移除元数据引用,编译需要元数据支持.
+ ///
+ /// 程序集路径
+ ///
+ public static bool RemoveGlobalReference(string path)
+ {
+ NatashaReferenceCache.AddReference(path);
+ return true;
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Compiler/Targets/Project.Usings.targets b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Targets/Project.Usings.targets
new file mode 100644
index 00000000..2f3edd5a
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Compiler/Targets/Project.Usings.targets
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Builder/OopBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Builder/OopBuilder.cs
new file mode 100644
index 00000000..61637eb2
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Builder/OopBuilder.cs
@@ -0,0 +1,17 @@
+#if MULTI
+using Natasha.CSharp.Template;
+
+namespace Natasha.CSharp.Builder
+{
+
+ public partial class OopBuilder : UsingTemplate where T : OopBuilder, new()
+ {
+ protected internal void BuildTree()
+ {
+ LoadCurrentDomainUsing();
+ AssemblyBuilder.Add(this.GetScript());
+ }
+ }
+
+}
+#endif
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Level2/NHandler.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Level2/NHandler.cs
new file mode 100644
index 00000000..536b1605
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Level2/NHandler.cs
@@ -0,0 +1,42 @@
+#if MULTI
+using Natasha.CSharp.Builder;
+using System;
+
+namespace Natasha.CSharp
+{
+ public class NHandler : OopBuilder where T : OopBuilder , new()
+ {
+
+ public NDelegate DelegateHandler
+ {
+ get { return NDelegate.UseDomain(AssemblyBuilder.Domain); }
+ }
+
+
+ public NClass ClassHandler
+ {
+ get { return NClass.UseDomain(AssemblyBuilder.Domain).Using(NamespaceScript); }
+ }
+
+
+ public NInterface InterfaceHandler
+ {
+ get { return NInterface.UseDomain(AssemblyBuilder.Domain).Using(NamespaceScript); }
+ }
+
+
+ public NEnum EnumHandler
+ {
+ get { return NEnum.UseDomain(AssemblyBuilder.Domain).Using(NamespaceScript); }
+ }
+
+
+ public Func Creator()
+ {
+ return DelegateHandler.Func($"return new {NameScript}();");
+ }
+
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Level3/NInstance.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Level3/NInstance.cs
new file mode 100644
index 00000000..6d8bb62e
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/API/Level3/NInstance.cs
@@ -0,0 +1,33 @@
+#if MULTI
+using System;
+
+namespace Natasha.CSharp
+{
+ public static class NInstance
+ {
+
+ public static Func Creator()
+ {
+
+ return NDelegate.UseDomain(typeof(T).GetDomain()).Func($"return new {typeof(T).GetDevelopName()}();");
+
+ }
+
+
+
+
+ public static Delegate Creator(Type type)
+ {
+
+ return FastMethodOperator
+ .UseDomain(type.GetDomain())
+ .Body($"return new {type.GetDevelopName()}();")
+ .Return(type)
+ .Compile();
+
+ }
+
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Oop/UsingTemplate.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Oop/UsingTemplate.cs
new file mode 100644
index 00000000..4c53e039
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Oop/UsingTemplate.cs
@@ -0,0 +1,17 @@
+#if MULTI
+namespace Natasha.CSharp.Template
+{
+
+ public partial class UsingTemplate : FlagTemplate where T : UsingTemplate, new()
+ {
+
+
+ protected T LoadCurrentDomainUsing()
+ {
+ return Using(AssemblyBuilder.Domain.UsingRecorder._usings);
+ }
+
+ }
+
+}
+#endif
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Standard/ComplierTemplate.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Standard/ComplierTemplate.cs
new file mode 100644
index 00000000..9d2e427a
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Standard/ComplierTemplate.cs
@@ -0,0 +1,125 @@
+#if MULTI
+using System;
+
+namespace Natasha.CSharp.Template
+{
+
+ public partial class CompilerTemplate : ALinkTemplate where T : CompilerTemplate, new()
+ {
+
+ #region 指定编译器的域进行创建
+
+ ///
+ /// 用传入的编译单元域来初始化编译单元.
+ ///
+ ///
+ public static T UseCompiler(AssemblyCSharpBuilder builder, Action? option = default)
+ {
+
+ return UseDomain(builder.Domain, option);
+
+ }
+ #endregion
+ #region 指定字符串域创建以及参数
+
+ ///
+ /// 创建一个域来初始化编译单元. 此方法创建的实例 instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// //使用 NoGlobalUsing 来禁用全局 using 覆盖.(默认开启)
+ /// instance.NoGlobalUsing();
+ ///
+ /// //使用 NotLoadDomainUsing 来禁用域内 using 覆盖.(默认开启)
+ /// instance.NotLoadDomainUsing();
+ ///
+ /// //使用 ConfigBuilder 方法来配置编译单元.
+ /// instance.ConfigBuilder(bld=>bld);
+ ///
+ /// //使用 ConfigCompilerOption 方法来配置编译选项.
+ /// bld=>bld.ConfigCompilerOption(opt=>opt.xxx);
+ ///
+ /// //使用 ConfigSyntaxOptions 方法来配置语法选项
+ /// bld=>bld.ConfigSyntaxOptions(opt=>opt.xxx).
+ ///
+ ///
+ ///
+ ///
+ public static T CreateDomain(string domainName, Action? option = default)
+ {
+
+ if (domainName.ToLower() == "default")
+ {
+ return UseDomain(NatashaReferenceDomain.DefaultDomain, option);
+ }
+ else
+ {
+ return UseDomain(DomainManagement.Create(domainName), option);
+ }
+
+ }
+ #endregion
+ #region 指定域创建以及参数
+
+
+ ///
+ /// 使用作用域中的 Domain
+ ///
+ ///
+ public static T UseScope()
+ {
+ return new();
+ }
+
+
+
+ ///
+ /// 使用一个域来初始化编译单元
+ ///
+ ///
+ public static T UseDomain(NatashaReferenceDomain domain, Action? option = default)
+ {
+
+ T instance = new();
+ instance.AssemblyBuilder.Domain = domain;
+ instance.OptionAction = option;
+ option?.Invoke(instance.AssemblyBuilder);
+ return instance;
+
+ }
+ #endregion
+ #region Default 默认域创建以及参数
+
+
+ ///
+ /// 使用默认域来初始化编译单元.
+ ///
+ ///
+ public static T DefaultDomain(Action? option = default)
+ {
+
+ return UseDomain(NatashaReferenceDomain.DefaultDomain, option);
+
+ }
+
+
+ #endregion
+ #region 随机域创建以及参数
+
+ ///
+ /// 使用随机域来初始化编译单元.
+ ///
+ ///
+ public static T RandomDomain(Action? option = default)
+ {
+
+ return UseDomain(DomainManagement.Random(), option);
+
+ }
+ #endregion
+
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Standard/GlobalUsingTemplate.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Standard/GlobalUsingTemplate.cs
new file mode 100644
index 00000000..11974d52
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/MultiDomain/Standard/GlobalUsingTemplate.cs
@@ -0,0 +1,109 @@
+#if MULTI
+using System.Text;
+
+namespace Natasha.CSharp.Template
+{
+ ///
+ /// 记录模板
+ ///
+ /// LINK返回的类型
+ public partial class GlobalUsingTemplate : ScriptTemplate where T : GlobalUsingTemplate, new()
+ {
+
+ public GlobalUsingTemplate()
+ {
+ _useGlobalUsing = true;
+ _autoLoadDomainUsing = true;
+ UsingRecorder = new();
+ _script = new StringBuilder(200);
+
+ }
+
+ private bool _autoLoadDomainUsing;
+ public T LoadDomainUsing()
+ {
+ _autoLoadDomainUsing = true;
+ return Link;
+ }
+ public T NotLoadDomainUsing()
+ {
+ _autoLoadDomainUsing = false;
+ return Link;
+ }
+
+ public StringBuilder GetUsingBuilder()
+ {
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+ var usingScript = new StringBuilder();
+
+ //如果用户想使用自定义的Using
+ if (!_useGlobalUsing)
+ {
+
+
+ foreach (var @using in UsingRecorder._usings)
+ {
+
+ usingScript.AppendLine($"using {@using};");
+
+ }
+ //使用全局Using
+ if (_autoLoadDomainUsing)
+ {
+ foreach (var @using in AssemblyBuilder.Domain.UsingRecorder._usings)
+ {
+ if (!UsingRecorder.HasUsing(@using))
+ {
+
+ usingScript.AppendLine($"using {@using};");
+
+ }
+ }
+ }
+
+ }
+ else
+ {
+
+ //使用全局Using
+ if (_autoLoadDomainUsing && AssemblyBuilder.Domain.Name != "Default")
+ {
+ foreach (var @using in AssemblyBuilder.Domain.UsingRecorder._usings)
+ {
+ if (!DefaultUsing.HasElement(@using) && !UsingRecorder.HasUsing(@using))
+ {
+
+ usingScript.AppendLine($"using {@using};");
+
+ }
+ }
+ }
+
+ //把当前域中的using全部加上
+ foreach (var @using in UsingRecorder._usings)
+ {
+
+ //如果全局已经存在using了,就不加了
+ if (!DefaultUsing.HasElement(@using))
+ {
+
+ usingScript.AppendLine($"using {@using};");
+
+ }
+
+ }
+ usingScript.Append(DefaultUsing.UsingScript);
+
+ }
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[using]", "using 组合", 3);
+#endif
+ return usingScript;
+ }
+ }
+
+}
+#endif
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Natasha.CSharp.Template.csproj b/src/Natasha.CSharp/Natasha.CSharp.Template/Natasha.CSharp.Template.csproj
new file mode 100644
index 00000000..127830ed
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Natasha.CSharp.Template.csproj
@@ -0,0 +1,41 @@
+
+
+
+ netstandard2.0;netcoreapp3.1;net5.0;net6.0;net7.0
+ Natasha 的编译模板
+ DotNetCore.Natasha.CSharp.Template
+ 升级到最新版.
+ Roslyn;IL;Script;Dynamic;Natasha;NMS;Template
+ true
+ 5.2.2.1
+ 5.2.2.1
+ 5.2.2.1
+
+
+
+ MULTI;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/ConstraintBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/ConstraintBuilder.cs
new file mode 100644
index 00000000..24c16ece
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/ConstraintBuilder.cs
@@ -0,0 +1,90 @@
+using Natasha.CSharp.Template.Reverser;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Natasha.CSharp.Builder
+{
+ public class ConstraintBuilder
+ {
+
+ private string _typeName;
+ private readonly HashSet _types;
+ private readonly HashSet _enums;
+
+ public ConstraintBuilder()
+ {
+ _typeName = string.Empty;
+ _types = new HashSet();
+ _enums = new HashSet();
+ }
+
+ public ConstraintBuilder SetType(string typeName)
+ {
+ _typeName = typeName;
+ return this;
+ }
+
+
+ public ConstraintBuilder Constraint(ConstraintFlags constraint)
+ {
+
+ _enums.Add(constraint);
+ return this;
+
+ }
+
+ public ConstraintBuilder Constraint()
+ {
+
+ return Constraint(typeof(TConstraint));
+
+ }
+ public ConstraintBuilder Constraint(Type type)
+ {
+
+ _types.Add(type);
+ return this;
+
+ }
+
+ public string GetScript()
+ {
+
+ StringBuilder builder = new StringBuilder();
+ if (_types.Count > 0 || _enums.Count > 0)
+ {
+
+
+ foreach (var item in _enums)
+ {
+ if (item == ConstraintFlags.Class || item == ConstraintFlags.Struct)
+ {
+
+ builder.Insert(0, GenericConstraintReverser.GetConstraint(item) + ",");
+
+ }
+ else
+ {
+
+ builder.Append(GenericConstraintReverser.GetConstraint(item) + ",");
+
+ }
+
+ }
+ foreach (var item in _types)
+ {
+
+ builder.Append(item.GetDevelopName()+",");
+
+ }
+ builder.Insert(0, $"where {_typeName} : ");
+ builder.Length -= 1;
+ }
+ return builder.ToString();
+
+ }
+
+
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/CtorBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/CtorBuilder.cs
new file mode 100644
index 00000000..d6a0f4b0
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/CtorBuilder.cs
@@ -0,0 +1,17 @@
+using Natasha.CSharp.Template;
+
+namespace Natasha.CSharp.Builder
+{
+ public class CtorBuilder : DelegateTemplate
+ {
+
+ public CtorBuilder()
+ {
+
+ Link = this;
+ NoUseType();
+
+ }
+
+ }
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/DelegateBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/DelegateBuilder.cs
new file mode 100644
index 00000000..e8032070
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/DelegateBuilder.cs
@@ -0,0 +1,105 @@
+using System;
+using System.Collections.Generic;
+
+namespace Natasha.CSharp.Builder
+{
+
+ ///
+ /// 委托构建器,动态构建Func和Action委托
+ ///
+ public class DelegateBuilder
+ {
+
+ private static readonly Type[] FuncMaker;
+ private static readonly Type[] ActionMaker;
+
+ static DelegateBuilder()
+ {
+ FuncMaker = new Type[9];
+ FuncMaker[0] = typeof(Func<>);
+ FuncMaker[1] = typeof(Func<,>);
+ FuncMaker[2] = typeof(Func<,,>);
+ FuncMaker[3] = typeof(Func<,,,>);
+ FuncMaker[4] = typeof(Func<,,,,>);
+ FuncMaker[5] = typeof(Func<,,,,,>);
+ FuncMaker[6] = typeof(Func<,,,,,,>);
+ FuncMaker[7] = typeof(Func<,,,,,,,>);
+ FuncMaker[8] = typeof(Func<,,,,,,,,>);
+
+ ActionMaker = new Type[9];
+ ActionMaker[0] = typeof(Action);
+ ActionMaker[1] = typeof(Action<>);
+ ActionMaker[2] = typeof(Action<,>);
+ ActionMaker[3] = typeof(Action<,,>);
+ ActionMaker[4] = typeof(Action<,,,>);
+ ActionMaker[5] = typeof(Action<,,,,>);
+ ActionMaker[6] = typeof(Action<,,,,,>);
+ ActionMaker[7] = typeof(Action<,,,,,,>);
+ ActionMaker[8] = typeof(Action<,,,,,,,>);
+ }
+
+
+
+
+ ///
+ /// 获取函数委托
+ ///
+ /// 泛型参数
+ /// 返回类型
+ /// 函数委托
+ public static Type GetDelegate(Type[]? parametersTypes = null, Type? returnType = null)
+ {
+ if (returnType == null || returnType == typeof(void))
+ {
+ return GetAction(parametersTypes);
+ }
+
+ return GetFunc(returnType, parametersTypes);
+ }
+
+
+
+
+ ///
+ /// 根据类型动态生成Func委托
+ ///
+ /// 返回类型
+ /// 泛型类型
+ /// Func委托类型
+ public static Type GetFunc(Type returnType, params Type[]? parametersTypes)
+ {
+ if (parametersTypes == null || parametersTypes.Length == 0)
+ {
+ return FuncMaker[0].MakeGenericType(returnType);
+ }
+
+ var list = new Type[parametersTypes.Length+1];
+ for (int i = 0; i < parametersTypes.Length; i++)
+ {
+ list[i] = parametersTypes[i];
+ }
+ list[parametersTypes.Length] = returnType;
+ return FuncMaker[parametersTypes.Length].MakeGenericType(list);
+ }
+
+
+
+
+ ///
+ /// 根据类型动态生成Action委托
+ ///
+ /// 泛型参数类型
+ /// Action委托类型
+ public static Type GetAction(params Type[]? parametersTypes)
+ {
+ if (parametersTypes == null || parametersTypes.Length == 0)
+ {
+ return ActionMaker[0];
+ }
+
+ return ActionMaker[parametersTypes.Length].MakeGenericType(parametersTypes);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/FieldBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/FieldBuilder.cs
new file mode 100644
index 00000000..ea6e9832
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/FieldBuilder.cs
@@ -0,0 +1,16 @@
+using Natasha.CSharp.Template;
+
+namespace Natasha.CSharp.Builder
+{
+
+ public class FieldBuilder : FieldTemplate
+ {
+
+ public FieldBuilder()
+ {
+ Link = this;
+ }
+
+ }
+
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/MethodBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/MethodBuilder.cs
new file mode 100644
index 00000000..ccf50400
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/MethodBuilder.cs
@@ -0,0 +1,214 @@
+using Natasha.CSharp.Template;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+namespace Natasha.CSharp.Builder
+{
+
+ public class MethodBuilder : MethodBuilder
+ {
+
+ public MethodBuilder()
+ {
+ Link = this;
+ }
+
+ }
+
+
+ public class MethodBuilder : DelegateTemplate where T : MethodBuilder, new()
+ {
+
+
+ public readonly OopBuilder OopHandler;
+
+ public MethodBuilder()
+ {
+ OopHandler = new OopBuilder();
+ Init();
+
+ }
+
+
+
+ public T SkipInit()
+ {
+
+ this.OopHandler.AssemblyBuilder.ConfigCompilerOption(item => item.RemoveIgnoreAccessibility());
+ this.AttributeAppend();
+ return Link;
+ }
+
+
+
+ public T Using()
+ {
+
+ OopHandler.Using();
+ return Link;
+
+ }
+ public T Using(Type @using)
+ {
+
+ OopHandler.Using(@using);
+ return Link;
+
+ }
+ public T Using(string @using)
+ {
+
+ OopHandler.Using(@using);
+ return Link;
+
+ }
+
+ public T Using(HashSet @using)
+ {
+
+ OopHandler.Using(@using);
+ return Link;
+
+ }
+ public T Using(NamespaceConverter @using)
+ {
+
+ OopHandler.Using(@using);
+ return Link;
+
+ }
+ public T Using(NamespaceConverter[]? @using)
+ {
+
+ OopHandler.Using(@using);
+ return Link;
+
+ }
+
+
+
+
+ public virtual void Init()
+ {
+
+ }
+
+
+
+
+ public T ClassOptions(Action acion)
+ {
+
+ acion?.Invoke(OopHandler);
+ return Link;
+
+ }
+
+
+
+
+ ///
+ /// 设置类名
+ ///
+ /// 类名
+ ///
+ public T ClassName(string className)
+ {
+
+ OopHandler.Name(className);
+ return Link;
+
+ }
+
+
+
+
+ ///
+ /// 设置命名空间
+ ///
+ /// 命名空间字符串
+ ///
+ public T Namesapce(string @namespace)
+ {
+
+ OopHandler.Namespace(@namespace);
+ return Link;
+
+ }
+
+
+
+
+ public Delegate Compile(object? target = null)
+ {
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+ OopHandler.AssemblyBuilder = this.AssemblyBuilder;
+ if (OopHandler.NamespaceScript == default)
+ {
+ OopHandler.HiddenNamespace();
+ }
+
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[ Using ]", "Using填充耗时", 1);
+#endif
+ OopHandler.BodyAppend(GetScript());
+ AssemblyBuilder.Add(OopHandler.GetScript());
+ var assembly = AssemblyBuilder.GetAssembly();
+ return assembly.GetDelegateFromShortName(OopHandler.NameScript, NameScript, DelegateType, target);
+
+ }
+
+
+
+
+
+ public S Compile(object? target = null) where S : Delegate
+ {
+#if DEBUG
+ Stopwatch stopwatch = new();
+ stopwatch.Start();
+#endif
+
+ OopHandler.AssemblyBuilder = this.AssemblyBuilder;
+ if (OopHandler.NamespaceScript == default)
+ {
+ OopHandler.HiddenNamespace();
+ }
+#if DEBUG
+ stopwatch.RestartAndShowCategoreInfo("[ Using ]", "Using填充耗时", 1);
+#endif
+ //自动判别是否有手动指定方法参数,若没有则使用方法的参数
+ var method = typeof(S).GetMethods()[0]!;
+ if (ParametersScript.Length == 0)
+ {
+
+ Param(method);
+
+ }
+ //自动判别返回值类型,若没有则使用委托的返回类型
+ if (_type != method.ReturnType)
+ {
+
+ this.Return(method.ReturnType);
+
+ }
+#if DEBUG
+ stopwatch.StopAndShowCategoreInfo("[Delegate]", "委托信息反解耗时", 1);
+ Console.WriteLine();
+#endif
+ //Mark : 11M Memory
+ OopHandler.BodyAppend(GetScript());
+ AssemblyBuilder.Add(OopHandler.GetScript());
+ var assembly = AssemblyBuilder.GetAssembly();
+ return assembly.GetDelegateFromShortName(OopHandler.NameScript, NameScript, target);
+
+ }
+
+ }
+
+}
diff --git a/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/OopBuilder.cs b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/OopBuilder.cs
new file mode 100644
index 00000000..cb70cba8
--- /dev/null
+++ b/src/Natasha.CSharp/Natasha.CSharp.Template/Public/API/Builder/OopBuilder.cs
@@ -0,0 +1,500 @@
+using Natasha.CSharp.Extension.Inner;
+using Natasha.CSharp.Template;
+using System;
+using System.Runtime.CompilerServices;
+
+namespace Natasha.CSharp.Builder
+{
+
+
+ public class OopBuilder : OopBuilder
+ {
+
+ public OopBuilder()
+ {
+ Link = this;
+ }
+
+ }
+
+
+
+ public partial class OopBuilder : UsingTemplate where T : OopBuilder, new()
+ {
+
+ //rivate readonly ConcurrentQueue