首页 > 其他分享 >.NET Compiler Platform SDK

.NET Compiler Platform SDK

时间:2023-06-20 09:47:45浏览次数:53  
标签:标记 代码 语法 Platform 编译器 API NET 节点 SDK

.NET Compiler Platform SDK

.NET Compiler Platform 是什么?

通过学习该模型可以更快的了解Roslyn,或者说更快的了解c#编译器的相关知识。

编译器管道

编译器管道是什么

如上图所示,编译器管在每个阶段会进行不同的操作,这些操作我们可以理解为一个独立的组件或者模块,是一个黑盒结构。

  • Parser 分析模块

    转化为编译器能读懂的语言语法,遵循编译器的规则解析代码,这里会判断是否有编译问题。

  • Symbols 声明模块

    分析转换后的代码,将其进行拆分,将非元数据部分按照一定的规则进行重新组合,形成标识符。

  • Metadata Import 元数据导入模块

    将分析后的代码中数据部分进行保存,形成符号。

  • Binder 绑定模块

    将符号和标识符匹配起来。

  • IL Emitter 最终产物-IL代码

    通过Emitter编译为IL代码。

Compiler Api在编译过程的作用

Compiler Api在每个阶段都提供一个对象模型,让开发者可以在该阶段访问该模型来改变编译中的数据。

  • Syntax Tree API

    提供一个语法树(代码大纲和格式)

  • Symbol API

    分层符号表(对象浏览器和导航功能)

  • Binding and Flow Analysis APIs

    语义模型(重构和定义)

  • Emit API

    IL字节码的API

开发API

.NET编译器对外暴漏了多个API:编译器API,诊断API,脚本API和工作区API。

编译器API

涵盖了编译器的各个阶段,主要涉及对象模型(语法模型和语义模型),还包含最原始的程序集引用,编译器选项和源代码文件,该部分不可变。

诊断API

在编译器分析过程中,会产生一组诊断信息,包括对于语法,语义的警告或者诊断性信息。此时,用户可通过诊断API获得诊断信息,也可将用户定义的分析器插入编译过程,例如StyleCOp等。

脚本API

按照脚本语言的方式进行交互式执行代码

  • REPL(读取-评估-打印-循环)

    Read(读取用户输入)-Eval(执行输入内容)-Print(打印输出结果)-Loop(循环)

工作区API

可直接访问编译器层对象模型。

Syntax Tree(语法树)

每个语法树都由节点,标记和其他项组成,用于编译,代码分析,绑定,重构,IDE功能和代码生成的主要结构。

  • 完全保真的保存所有源信息。
  • 生成分析源的确切文本。
  • 只读且线程安全。
SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();

语法节点

表示了声明,语句,子句和表达式等语法结构,每个类别都派生自Microsoft.CodeAnalysis.SyntaxNode来表示,不可扩展。

语法节点为语法树的非终端节点,终端为语法标记,可通过SyntaxNode.Parent访问父节点,根的父节点为null。

语法标记

语法树的终端,表示代码自小的语法片段。包含关键字,标识符,文本和标点,都采用同一结构,但是属性不同,取决于表示的标记类型。

语法其他项

包含了空格,注释和预处理的指令,Microsoft.CodeAnalysis.SyntaxTrivia类型描述琐碎的内容。

可通过SyntaxToken.LeadingTrivia 或 SyntaxToken.TrailingTrivia 集合来访问语法的其他项。 源文件中的第一个标记可获取所有初始琐碎内容,而最后一个琐碎内容序列附加到 文件尾标记,否则其宽度为零。

无父级,每个其他项都与一个标记关联,可使用SyntaxTrivia.Token属性访问关联的标记。

范围

每个节点、标记或其他项都知道其在源文本内的位置和包含的字符数。 文本位置表示为一个 32 位整数,是一个从零开始的 char 索引。 TextSpan 对象表示开始位置和字符计数,都表示为整数。

每个节点具有两个TextSpan属性:Span和FullSpan

  • Span

    从节点子树中第一个标记的开头到最后一个标记末尾的文本范围。 此范围不包括任何其他项内容。

  • FullSpan

    文本范围包括节点的正常范围,加上语法其他项的内容。

种类

Syntax Node.RawKing属性,标识所表示的确切语法元素。此数值可强转换为枚举类型(Microsoft.CodeAnalysis.CSharp.SyntaxKing)。

RawKind属性可轻松消除共享同一节点的语法节点类型的歧义。

错误

主要是语法错误,当分析程序遇到不符合语言定义的代码时,会创建语法树:

  1. 需要特定种类的标记,未找到,会在所需标记的位置插入缺失的标记,SyntaxNode.IsMissing属性返回true。
  2. 跳过一些标记,知道发现可继续分析的标记,跳过的内容为SkippedTokensTrivia类型的其他项目的内容节点。

语法分析

查询符号

//CSharpCompilation.AddReferences 方法将引用添加到编译。
//MetadataReference.CreateFromFile 方法加载程序集作为引用。
SyntaxTree tree = CSharpSyntaxTree.ParseText(programText);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
var compilation = CSharpCompilation.Create("HelloWorld").AddReferences(MetadataReference.CreateFromFile(typeof(string).Assembly.Location))	.AddSyntaxTrees(tree);

查询语义模型

SemanticModel model = compilation.GetSemanticModel(tree);

绑定名称

// 使用解析树找到了"using System;"
UsingDirectiveSyntax usingSystem = root.Usings[0];
NameSyntax systemName = usingSystem.Name;
// Use the semantic model for symbol information:
SymbolInfo nameInfo = model.GetSymbolInfo(systemName);
// Microsoft.CodeAnalysis.TypeInfo结构包括 TypeInfo.Type 属性,此属性可启用对关于文本类型的语义信息的访问。
var stringTypeSymbol = (INamedTypeSymbol?)literalInfo.Type;
// 使用 LINQ 查询语法生成完整查询,然后在控制台中显示所有方法名称
foreach (string name in (from method in stringTypeSymbol?.GetMembers().OfType<IMethodSymbol>()
 		where
			SymbolEqualityComparer.Default.Equals(method.ReturnType, stringTypeSymbol)
                         &&
			method.DeclaredAccessibility == Accessibility.Public select method.Name).Distinct())
{
 Console.WriteLine(name);
}

源生成器

编译用户代码时检查用户代码,动态的创建新的源文件并将这些文件添加到用户的编译中。

目前 .NET Standard 2.0 程序集只能用作源生成器

运行时反射

应用启动时对用户代码进行一定分析,并使用这些数据生成内容。

例如:ASP.NET Core在Web服务首次运行时可以使用反射来发现已定义的构造

标签:标记,代码,语法,Platform,编译器,API,NET,节点,SDK
From: https://www.cnblogs.com/wanghun315/p/17492788.html

相关文章

  • Kubernetes——构建平台工程的利器
    作者|LoftTeam翻译|Seal软件链接|https://loft.sh/blog/why-platform-engineering-teams-should-standardize-on-kubernetes/ 在当今快节奏、不断变化的技术环境中,平台工程团队一直面临着交付新的创新解决方案以满足不断变化的业务需求的压力。最大挑战之一则是管理支持这些......
  • 安装部署 Kubernetes 仪表板(Dashboard)
    简介Kubernetes仪表板(Dashboard)是基于网页的Kubernetes用户界面。你可以使用仪表板:展示了Kubernetes集群中的资源状态信息和所有报错信息。把容器应用部署到Kubernetes集群中。对容器应用排错。管理集群资源。获取运行在集群中的应用的概览信息。创建或者修改Kub......
  • Neutral Network Notes
    TableofContents卷积Let'sgetstarted卷积1.卷积公式\[\int_{-\infty}^{+\infty}f(\tau)g(x-\tau)d\tau\]2.卷积公式的理解   符号意义\(f(t)\)\(t\)时刻的进食量\(\int_{0}^{t}f(t)dt\)截止\(t\)时刻的总进食量\(g(t)\)某一时刻进食......
  • ASP.NET Core Identity 系列之二
    转自:https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486148&idx=1&sn=dae55b414e123c6718e470c21c8c8c21桂迹,微信公众号这节我们主要演示在ASP.NETCoreIdentity中创建、修改、删除、查询用户1.ASP.NETCoreIdentityUserManager类UserManager类位于Microsof......
  • ASP.NET Core MVC 从入门到精通之日志管理
    随着技术的发展,ASP.NETCoreMVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NETCoreMVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NETCoreMVC系统开发的人员。经过前几篇文章的讲解,初步了解ASP.NETCore......
  • ASP.NET Core Identity 系列之一
    转自:https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486141&idx=1&sn=f77635080994c6295cb801e846427a15桂迹,微信公众号https://mp.weixin.qq.com/s?__biz=MzA3NDM1MzIyMQ==&mid=2247486318&idx=1&sn=1f06f6de690ba6df16ed812de9588709ASP.N......
  • calico 网络流量 过程 分析 apt-get install telnet
    1.caliconode容器在kubernetes中以DaemonSet的方式运行,容器的网络模式为hostNetwor,与host共享网络栈,拥有相同的Ip和hostname 2.查看某个pod:[root@bserver40~]#kubectlgetpods-owide-nkube-system|grep-itillertiller-deploy-5dfffddb8d-n4vp6 1/1    Runn......
  • Kubernetes哪一点最打动你?或者,它发布过的哪一项特性让你认为最厉害?
    kubernates打动我的地方应该是他解决了docker的一个痛点,各个docker之间的通信以及集成管理。因为这跟微服务很像,微服务之间也是需要通信和统一管理。知识总是相同的,在这里就体现出来了。用一个例子来演示会更加清晰......
  • kubernetes 生命周期问题分析
    1.Failed --pod里至少一个容器以非0code退出,说明应用有问题,需要debug应用容器2.pending--说明API对象已经被创建和保存在etcd数据库里,但是创建过程出了问题,可能是imagepull出问题,也可能是调度出了问题3.Unknow--说明pod的状态不能持续地被Kubelet发送给kubeapi,这很可能是......
  • kubernetes 资源请求和限制
    1.spec:containers:-name:exampleresources:requests:cpu:100mmemory:64Milimits:cpu:200mmemory:128Mi   例如,一个带有3个容器的pod,每个容器请求0......