-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from dotnet-campus/t/lindexi/Compile
尝试对接源代码生成
- Loading branch information
Showing
15 changed files
with
361 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Localizations/en-US/Extension.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Extension: | ||
Name: Extension | ||
Extra: | ||
A: "Option A" | ||
B: "Option B" |
6 changes: 6 additions & 0 deletions
6
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Localizations/en-US/Main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
App: | ||
Name: dotnetCampus.YamlToCSharp.Sample.Wpf | ||
AboutUs: "About Us" | ||
Common: | ||
Yes: "Yes" | ||
No: "No" |
5 changes: 5 additions & 0 deletions
5
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Localizations/zh-CN/Extension.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Extension: | ||
Name: 扩展程序 | ||
Extra: | ||
A: "选项 A" | ||
B: "选项 B" |
6 changes: 6 additions & 0 deletions
6
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Localizations/zh-CN/Main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
App: | ||
Name: "WPF 版 YAML 转 C# 程序" | ||
AboutUs: "关于我们" | ||
Common: | ||
Yes: "是" | ||
No: "否" |
5 changes: 5 additions & 0 deletions
5
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Localizations/zh-TW/Extension.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Extension: | ||
Name: 擴展程序 | ||
Extra: | ||
A: "選項 A" | ||
B: "選項 B" |
6 changes: 6 additions & 0 deletions
6
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Localizations/zh-TW/Main.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
App: | ||
Name: "WPF 版 YAML 轉 C# 程序" | ||
AboutUs: "關於我們" | ||
Common: | ||
Yes: "是" | ||
No: "否" |
36 changes: 36 additions & 0 deletions
36
samples/dotnetCampus.YamlToCSharp.SourceGeneration.Sample/Program.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace dotnetCampus.YamlToCSharp.SourceGeneration.Sample | ||
{ | ||
class Program | ||
{ | ||
static void Main(string[] args) | ||
{ | ||
var languages = new Dictionary<string, Dictionary<string, string>[]>() | ||
{ | ||
{ | ||
"zh-CN", new[] | ||
{ | ||
new Localizations.zh_CN.Main().GetLang(), | ||
new Localizations.zh_CN.Extension().GetLang(), | ||
} | ||
}, | ||
{ | ||
"zh-TW", new[] | ||
{ | ||
new Localizations.zh_TW.Main().GetLang(), | ||
new Localizations.zh_TW.Extension().GetLang(), | ||
} | ||
}, | ||
{ | ||
"en-US", new[] | ||
{ | ||
new Localizations.en_US.Main().GetLang(), | ||
new Localizations.en_US.Extension().GetLang(), | ||
} | ||
}, | ||
}; | ||
|
||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...ToCSharp.SourceGeneration.Sample/dotnetCampus.YamlToCSharp.SourceGeneration.Sample.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>WinExe</OutputType> | ||
<TargetFramework>net6.0-windows</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<Import Project="..\..\src\dotnetCampus.YamlToCSharp.Analyzers\Assets\build\PackageId.props" /> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\dotnetCampus.YamlToCSharp.Analyzers\dotnetCampus.YamlToCSharp.Analyzers.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> | ||
</ItemGroup> | ||
|
||
</Project> |
16 changes: 16 additions & 0 deletions
16
src/dotnetCampus.YamlToCSharp.Analyzers/Assets/build/PackageId.props
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project> | ||
|
||
<!--<PropertyGroup> | ||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> | ||
</PropertyGroup>--> | ||
|
||
<ItemGroup> | ||
<YamlToCSharpCompile Include="**\*.yml;**\*.yaml" Exclude="obj\**\*.yml;obj\**\*.yaml;bin\**\*.yml;bin\**\*.yaml" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<AdditionalFiles Include="@(YamlToCSharpCompile)" /> | ||
<CompilerVisibleProperty Include="MSBuildProjectDirectory" /> | ||
<CompilerVisibleProperty Include="RootNamespace" /> | ||
</ItemGroup> | ||
|
||
</Project> |
3 changes: 3 additions & 0 deletions
3
src/dotnetCampus.YamlToCSharp.Analyzers/Assets/build/PackageId.targets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<Project> | ||
|
||
</Project> |
Binary file not shown.
153 changes: 153 additions & 0 deletions
153
src/dotnetCampus.YamlToCSharp.Analyzers/YamlToCSharpIncrementalGenerator.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
using System; | ||
using System.Collections.Immutable; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
|
||
using dotnetCampus.YamlToCSharp.Utils; | ||
|
||
using Microsoft.CodeAnalysis; | ||
|
||
namespace dotnetCampus.YamlToCSharp.Analyzers; | ||
|
||
[Generator(LanguageNames.CSharp)] | ||
public class YamlToCSharpIncrementalGenerator : IIncrementalGenerator | ||
{ | ||
public void Initialize(IncrementalGeneratorInitializationContext context) | ||
{ | ||
//Debugger.Launch(); | ||
//Debugger.Break(); | ||
IncrementalValueProvider<Compilation> compilationProvider = | ||
context.CompilationProvider.Select((compilation, token) => compilation); | ||
|
||
// 先找到所有感兴趣的文件 | ||
var yamlFileProvider = context.AdditionalTextsProvider.Where(t => | ||
{ | ||
var extension = Path.GetExtension(t.Path); | ||
return string.Equals(extension, ".yml", StringComparison.OrdinalIgnoreCase) || | ||
string.Equals(extension, ".yaml", StringComparison.OrdinalIgnoreCase); | ||
}) | ||
// 和配置合并,用来获取项目属性 | ||
.Combine(context.AnalyzerConfigOptionsProvider); | ||
; | ||
|
||
// 再进行处理,转换为代码。这一步能在底层提供缓存,减少重复转换 | ||
IncrementalValuesProvider<(string sourceFileName, string code)> csharpCodeProvider = yamlFileProvider.Select((args,token) => | ||
{ | ||
var (ymlText, analyzerConfigOptionsProvider) = args; | ||
|
||
DirectoryInfo projectDirectory; | ||
|
||
// 通过 csproj 等 PropertyGroup 里面获取 | ||
// 需要将可见的,放入到 CompilerVisibleProperty 里面 | ||
// 需要加上 `build_property.` 前缀 | ||
if (analyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.MSBuildProjectDirectory",out var msBuildProjectDirectory)) | ||
{ | ||
projectDirectory = new DirectoryInfo(msBuildProjectDirectory); | ||
} | ||
else | ||
{ | ||
// 应该不会找不到 | ||
projectDirectory = FindProjectDirectory(ymlText.Path); | ||
} | ||
|
||
if (!analyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.RootNamespace", out var rootNamespace)) | ||
{ | ||
// 尝试去获取配置的命名空间,如果能获取到,那么就使用配置的 | ||
// 获取不到,采用默认的 | ||
rootNamespace = "dotnetCampus.Localizations"; | ||
} | ||
|
||
var (classNamespace, className) = IdentifierHelper.MakeNamespaceAndClassName(projectDirectory, | ||
new FileInfo(ymlText.Path), rootNamespace); | ||
|
||
var sourceFileName = classNamespace + "." + className + ".yml" + ".cs"; | ||
|
||
var sourceText = ymlText.GetText(token); | ||
if (sourceText != null) | ||
{ | ||
TryLoadYamlDotNet(); | ||
|
||
var yamlText = sourceText.ToString(); | ||
var yamlFileToCSharpFile = new YamlFileToCSharpFile(); | ||
var code = yamlFileToCSharpFile.YamlToCsharpCode(yamlText, className, classNamespace, | ||
needAddPartial: false); | ||
return (sourceFileName, code); | ||
} | ||
|
||
return (sourceFileName, string.Empty); | ||
}); | ||
|
||
// 全部收集起来,再加入源代码,用来解决重复加入 | ||
IncrementalValueProvider<ImmutableArray<(string sourceFileName, string code)>> yamlCodeListProvider = csharpCodeProvider.Collect(); | ||
|
||
var resultProvider = yamlCodeListProvider.Combine(compilationProvider); | ||
|
||
// 添加到源代码 | ||
context.RegisterSourceOutput(resultProvider, (sourceProductionContext, provider) => | ||
{ | ||
var (yamlCodeList, compilation) = provider; | ||
|
||
foreach (var (sourceFileName, code) in yamlCodeList) | ||
{ | ||
if (!sourceProductionContext.CancellationToken.IsCancellationRequested) | ||
{ | ||
sourceProductionContext.AddSource(sourceFileName, code); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
private static void TryLoadYamlDotNet() | ||
{ | ||
// 尝试加上 YamlDotNet.dll 文件,由于源代码生成没有拷贝依赖,需要手动加载 | ||
// [Analyzer not working using Nuget · Issue #56076 · dotnet/roslyn](https://github.com/dotnet/roslyn/issues/56076) | ||
// [I can't use source generator with package reference · Issue #56024 · dotnet/roslyn](https://github.com/dotnet/roslyn/issues/56024) | ||
|
||
// YamlDotNet, Version=11.0.0.0, Culture=neutral, PublicKeyToken=ec19458f3c15af5e | ||
var yamlDotNetAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(t => t.FullName.Contains("YamlDotNet,")); | ||
if (yamlDotNetAssembly != null) | ||
{ | ||
// 加载成功 | ||
return; | ||
} | ||
|
||
var assembly = Assembly.GetExecutingAssembly(); | ||
var location = assembly.Location; | ||
var directory = Path.GetDirectoryName(location)!; | ||
var yamlDotNetStream = assembly.GetManifestResourceStream("dotnetCampus.YamlToCSharp.Analyzers.YamlDotNet.dll")!; | ||
var yamlDotNetFile = Path.Combine(directory, "YamlDotNet.dll"); | ||
using (var fileStream = File.OpenWrite(yamlDotNetFile)) | ||
{ | ||
yamlDotNetStream.CopyTo(fileStream); | ||
} | ||
|
||
Assembly.LoadFrom(yamlDotNetFile); | ||
} | ||
|
||
private DirectoryInfo FindProjectDirectory(string fileName) | ||
{ | ||
// 第一层的文件夹一定存在 | ||
var currentDirectory = Path.GetDirectoryName(fileName)!; | ||
|
||
var directory = currentDirectory; | ||
while (directory is not null) | ||
{ | ||
if (Directory.GetFiles(directory, "*.csproj", SearchOption.TopDirectoryOnly).Any()) | ||
{ | ||
// 如果能找到 csproj 文件,那就是项目所在文件夹了 | ||
return new DirectoryInfo(directory); | ||
} | ||
|
||
directory = Path.GetDirectoryName(directory); | ||
} | ||
|
||
return new DirectoryInfo(currentDirectory); | ||
} | ||
|
||
private string FileNameToClassName(string fileName) | ||
{ | ||
return fileName.Replace("-", "_").Replace(".", "_").Replace(" ", "_"); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
src/dotnetCampus.YamlToCSharp.Analyzers/dotnetCampus.YamlToCSharp.Analyzers.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="..\dotnetCampus.YamlToCSharp.Build\Utils\IdentifierHelper.cs" Link="IdentifierHelper.cs" /> | ||
<Compile Include="..\dotnetCampus.YamlToCSharp.Build\Utils\PathHelper.cs" Link="PathHelper.cs" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="..\dotnetCampus.YamlToCSharp\**\*.cs" Exclude="..\dotnetCampus.YamlToCSharp\obj\**\*.cs;..\dotnetCampus.YamlToCSharp\bin\**\*.cs" Link="YamlToCSharp\%(RecursiveDir)\%(FileName).cs" /> | ||
<None Remove="YamlDotNet.dll" /> | ||
<EmbeddedResource Include="YamlDotNet.dll" /> | ||
<PackageReference Include="YamlDotNet" Version="11.2.1" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" /> | ||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Oops, something went wrong.