Skip to content

Commit

Permalink
分离项目,重整结构。
Browse files Browse the repository at this point in the history
1. 分离编译引擎与模板.
2. 增加编译单元的 using  加载行为.
3. 修改部分枚举名称.
4. 重建 workflow.
5. 屏蔽 RS1014;CS1591; 警告.
  • Loading branch information
NMSAzulX committed Oct 29, 2023
1 parent a74f9bf commit d4081e7
Show file tree
Hide file tree
Showing 162 changed files with 12,910 additions and 111 deletions.
12 changes: 12 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
46 changes: 46 additions & 0 deletions .github/project.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
14 changes: 14 additions & 0 deletions Natasha.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down
4 changes: 2 additions & 2 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
<Company>.NET Core Community</Company>
<Authors>NMSAzulx</Authors>
<LangVersion>preview</LangVersion>

<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
<PackageIcon>19404084.png</PackageIcon>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<AssemblyOriginatorKeyFile>$([MSBuild]::NormalizeDirectory('$(SolutionDir)', 'resources'))natasha.snk</AssemblyOriginatorKeyFile>
<IncludeSymbols>true</IncludeSymbols>
<NoWarn>1701;1702;0168;NETSDK1138;IDE0060;xUnit2000;CS0067;CS8321;CS0649;CS8604;CA1822;</NoWarn>
<NoWarn>1701;1702;0168;NETSDK1138;IDE0060;xUnit2000;CS0067;CS8321;CS0649;CS8604;CA1822;RS1014;CS1591;</NoWarn>

</PropertyGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
/// <summary>
/// 程序集编译构建器 - 编译选项
/// </summary>
public sealed partial class AssemblyCSharpBuilder
{

private PluginLoadBehavior _compileReferenceBehavior;
private PluginLoadBehavior _compileAssemblyBehavior;
private Func<AssemblyName, AssemblyName, AssemblyLoadVersionResult>? _referencePickFunc;
private Func<IEnumerable<MetadataReference>, IEnumerable<MetadataReference>>? _referencesFilter;
private bool _combineReferences;

public AssemblyCSharpBuilder WithReferenceCombine()
{
_combineReferences = true;
return this;
}
public AssemblyCSharpBuilder WithoutReferenceCombine()
{
_combineReferences = false;
return this;
}
/// <summary>
/// 配置主域及当前域的加载行为, Default 使用主域引用, Custom 使用当前域引用
/// </summary>
/// <param name="loadBehavior"></param>
/// <returns></returns>
public AssemblyCSharpBuilder CompileWithReferenceLoadBehavior(PluginLoadBehavior loadBehavior)
{
_compileReferenceBehavior = loadBehavior;
return this;
}
/// <summary>
/// 配置当前域程序集的加载行为
/// </summary>
/// <param name="loadBehavior"></param>
/// <returns></returns>
public AssemblyCSharpBuilder CompileWithAssemblyLoadBehavior(PluginLoadBehavior loadBehavior)
{
_compileAssemblyBehavior = loadBehavior;
return this;
}

public AssemblyCSharpBuilder CompileWithSameNameReferencesFilter(Func<AssemblyName, AssemblyName, AssemblyLoadVersionResult>? useAssemblyNameFunc = null)
{
_referencePickFunc = useAssemblyNameFunc;
return this;
}


public AssemblyCSharpBuilder CompileWithReferencesFilter(Func<IEnumerable<MetadataReference>, IEnumerable<MetadataReference>>? referencesFilter)
{
_referencesFilter = referencesFilter;
return this;
}

/// <summary>
/// 流编译成功之后触发的事件
/// </summary>
public event Action<CSharpCompilation, Assembly>? CompileSucceedEvent;



/// <summary>
/// 流编译失败之后触发的事件
/// </summary>
public event Action<CSharpCompilation, ImmutableArray<Diagnostic>>? CompileFailedEvent;


public CSharpCompilation GetAvailableCompilation(Func<CSharpCompilationOptions, CSharpCompilationOptions>? 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<MetadataReference> 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;
}

/// <summary>
/// 将 SyntaxTrees 中的语法树编译到程序集.如果不成功会抛出 NatashaException.
/// </summary>
/// <remarks>
/// <example>
/// <code>
///
/// //程序集的域加载行为, 该行为决定了编译后的程序集随着依赖加载到域中的处理结果.
/// //和加载插件原理相同.
/// builder.CompileWithAssemblyLoadBehavior(enum);
///
/// //编译单元的引用加载行为, 遇到同名不同版本的引用该如何处理.
/// builder.CompileWithReferenceLoadBehavior(enum);
/// builder.CompileWithReferencesFilter(func);
///
/// </code>
/// </example>
/// </remarks>
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


Loading

0 comments on commit d4081e7

Please sign in to comment.