IIncrementalGenerator 判断程序集的引用关系
本文将告诉大家如何在 IIncrementalGenerator 增量 Source Generator 生成代码里面,在 Roslyn 分析器里面判断两个程序集是否存在引用关系
先上核心代码实现,核心代码就是调用以下代码进行判断程序集的引用关系
private static bool IsReference(IAssemblySymbol currentAssemblySymbol, IAssemblySymbol requiredAssemblySymbol,
Dictionary<IAssemblySymbol, bool /*是否引用*/> visited)
{
if (SymbolEqualityComparer.Default.Equals(currentAssemblySymbol, requiredAssemblySymbol))
{
// 这个就看业务了,如果两个程序集是相同的,是否判断为引用关系
return true;
}
foreach (var moduleSymbol in currentAssemblySymbol.Modules)
{
foreach (var referencedAssemblySymbol in moduleSymbol.ReferencedAssemblySymbols)
{
if (SymbolEqualityComparer.Default.Equals(referencedAssemblySymbol, requiredAssemblySymbol))
{
// 记录当前程序集存在引用关系
visited[currentAssemblySymbol] = true;
return true;
}
else
{
if (visited.TryGetValue(referencedAssemblySymbol, out var isReference))
{
// 这个是访问过的,那就从字典获取缓存,不需要再访问一次
// 同时也能解决程序集循环引用问题
}
else
{
// 没有访问过的,获取引用的程序集是否存在引用关系
isReference = IsReference(referencedAssemblySymbol, requiredAssemblySymbol, visited);
visited[referencedAssemblySymbol] = isReference;
}
if (isReference)
{
// 如果这个程序集有引用,那也算上
return true;
}
}
}
}
return false;
}
核心判断逻辑就是获取当前程序集的 Modules 从而获取到 ReferencedAssemblySymbols 也就是当前程序集所引用的所有程序集,再判断引用的程序集里面是否包含期望被引用的程序集
对于间接引用的程序集来说,需要进行遍历才可以判断到,但是此时需要处理程序集循环引用问题。本文这里采用传入一个字典的方法解决这个问题
获取当前分析器所分析的项目的引用程序集,可以通过 Compilation 的 SourceModule 的 ReferencedAssemblySymbols 拿到,如以下代码
context.CompilationProvider.Select((compilation, _) =>
{
var sourceModuleReferencedAssemblySymbols = compilation.SourceModule.ReferencedAssemblySymbols;
... // 忽略代码
});
本文所有代码放在 github 和 gitee 上,可以通过以下方式获取整个项目的代码
先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin c87c7e78b068956f3f8f4640a85c04a3af9e07fc
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin c87c7e78b068956f3f8f4640a85c04a3af9e07fc
获取代码之后,进入 HulanucerbeljuChaijacemjarga 文件夹
IIncrementalGenerator 判断程序集的引用关系的更多相关文章
- 【C#进阶系列】03 配置文件管理与程序集的引用版本重定向
先来点与标题不相关的: CLR支持两种程序集:弱命名程序集和强命名程序集. 两者的区别在于强命名程序集使用发布者的公钥和私钥进行签名.由于程序集被唯一性地标识,所以当应用程序绑定到强命名程序集时,CL ...
- 【转】Unity3D中脚本的执行顺序和编译顺序(vs工程引用关系)
http://www.cnblogs.com/champ/p/execorder.html 在Unity中可以同时创建很多脚本,并且可以分别绑定到不同的游戏对象上,它们各自都在自己的生命周期中运行.与 ...
- (转)Unity3D中脚本的执行顺序和编译顺序(vs工程引用关系)
自:http://www.cnblogs.com/champ/p/execorder.html 在Unity中可以同时创建很多脚本,并且可以分别绑定到不同的游戏对象上,它们各自都在自己的生命周期中运行 ...
- c#实例化继承类,必须对被继承类的程序集做引用 .net core Redis分布式缓存客户端实现逻辑分析及示例demo 数据库笔记之索引和事务 centos 7下安装python 3.6笔记 你大波哥~ C#开源框架(转载) JSON C# Class Generator ---由json字符串生成C#实体类的工具
c#实例化继承类,必须对被继承类的程序集做引用 0x00 问题 类型“Model.NewModel”在未被引用的程序集中定义.必须添加对程序集“Model, Version=1.0.0.0, Cu ...
- [转载] Java的四种引用关系
目录 1 强引用 (Final Reference) 2 软引用 (Soft Reference) 2.1 案例1: 软引用的垃圾回收 2.2 案例2: 软引用缓存的使用 2.3 软引用的应用场景 3 ...
- Js的引用关系示例和总结
三种引用(指针引用)关系,借助引用关系可以形成复杂的链关系,巧妙借助链关系可以实现收放自如,形散神不散的神奇效果,jquery就是其中一例: 1.对象指向属性; 2.a=b(b是对象,a ...
- matlab练习程序(射线法判断点与多边形关系)
依然是计算几何. 射线法判断点与多边形关系原理如下: 从待判断点引出一条射线,射线与多边形相交,如果交点为偶数,则点不在多边形内,如果交点为奇数,则点在多边形内. 原理虽是这样,有些细节还是要注意一下 ...
- Oracle查找表的外键引用关系
Oracle查找表的外键引用关系 select t1.table_name, t2.table_name as "TABLE_NAME(R)", t1.constraint_nam ...
- CI源码引用使用--php引用demo,静态变量和引用关系
CI源码引用使用在Common.php中,加载配置和类的方法 function &test() { static $a = ''; if (!$a) { $a ...
- SQL Server 查看对象之间的引用关系
前期准备: use studioA; go create table T(X int,Y int); insert into T(X,Y) values(1,1),(2,2); ...
随机推荐
- uni-app开发经验分享二十二: uni-app大转盘思路解析
最近在研究uni-app,制作了一个很有意思的集合项目demo,这里给大家分享下大转盘的前端设计思路 需求案例:大转盘抽奖 线上demo查看: 案例效果: 制作思路: 前端大转盘使用css3动画来做, ...
- Elasticsearch按照某个字段去重查询
索引较多: index-1_t_order index-2_t_order index-32_t_order 根据pay_amount排序,order_no去重,最后分页. 说明:1.collapse ...
- OpenCV常量值含义表
色彩空间转换常量 常量值 说明 cv2.COLOR_BGR2GRAY 从 BGR 色彩空间转换到 GRAY 色彩空间 cv2.COLOR_RGB2GRAY 从 RGB 色彩空间转换到 GRAY 色彩空 ...
- KingbaseES 行级安全策略介绍
本文详细介绍了KingbaseES中通过CREATE POLICY为一个表定义一条行级安全性策略.注意为了应用已被创建的策略,在表上必须启用行级安全性. 策略名称是针对每个表的.因此,一个策略名称可以 ...
- KingbaseES 参数设置优先级别
Oracle的参数可以设置system和session级别,当设置了session级别的参数时,会覆盖值system级别. KingbaseES除了该两个级别外,还有database级别.user/r ...
- 2024-03-30:用go语言,集团里有 n 名员工,他们可以完成各种各样的工作创造利润, 第 i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与, 如果成员参与
2024-03-30:用go语言,集团里有 n 名员工,他们可以完成各种各样的工作创造利润, 第 i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与, 如果成员参与 ...
- Spring Bean 的一生
Spring Bean 的一生包括其从创建到消亡的整个过程: 实例创建 => 填充 => 初始化 => 使用 => 销毁. 这里需要注意的是,从 bean 实例的创建到可以使用 ...
- 11 JavaScript关于时间
11 JavaScript关于时间 获取js的时间使用内置的Date函数完成 var d = new Date(); // 获取系统时间 // var d = new Date('2023-08-15 ...
- Go 实战|使用 Wails 构建轻量级的桌面应用:仿微信登录界面 Demo
概述 本文探讨 Wails 框架的使用,从搭建环境到开发,再到最终的构建打包,本项目源码 GitHub 地址:https://github.com/mazeyqian/go-run-wechat-de ...
- C++ 字符串完全指南:学习基础知识到掌握高级应用技巧
C++ 字符串 字符串用于存储文本. 一个字符串变量包含由双引号括起来的一组字符: 示例 创建一个 string 类型的变量并为其赋值: string greeting = "Hello&q ...