加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala宏注释:带注释类型的c.TypeCheck会导致StackOverflowError

发布时间:2020-12-16 09:06:26 所属栏目:安全 来源:网络整理
导读:我有一个宏注释,旨在应用于类定义.它的目的是一个几乎但不是很完整的序列化工具.它检查类的构造函数参数,然后在随播对象上创建一个工厂方法,该方法又为参数提供值.为了做到这一点,它需要知道参数的类型,所以我一直在调用Context.typeCheck. 当带注释的类的构
我有一个宏注释,旨在应用于类定义.它的目的是一个几乎但不是很完整的序列化工具.它检查类的构造函数参数,然后在随播对象上创建一个工厂方法,该方法又为参数提供值.为了做到这一点,它需要知道参数的类型,所以我一直在调用Context.typeCheck.

当带注释的类的构造函数采用与其自身相同类型的参数时,或者在其他类似情况下(例如,如果类型A和类型B都注释,并且A具有参数B,并且B具有参数),则会出现问题A.类型参数应用于形式参数计数也).任何这些情况都会导致注释被递归调用,直到发生StackOverflowError.

我尝试使用“withMacrosDisabled = true”作为c.typeCheck的参数,虽然这解决了问题,但它引入了另一个问题.如果之前未检查过要检查的类型,则编译器会记住其定义,并且根本不会调用其宏.对于自引用情况,这不是问题,但它确实发生在相互参考的情况下.

所以我被卡住了.有解决方法吗?我可以用c.openMacros来解决这个问题吗?

另一个选项,如果可用的话,我并不严格需要类型的完整定义,我可以使用它的完全限定名称(scala.xml.NodeSeq而不仅仅是NodeSeq).我在AST中获得TypeName,但这些很少是完全限定的,并且我不知道如何在不执行完整的typeCheck的情况下获取完全限定的名称.

作为一个侧面问题,什么是“withMacrosDisabled”有用?如果使用它会阻止所有宏扩展永远在传递树中找到的类型,而不仅仅是当前的c.typeCheck,这似乎是一个太大的锤子.即使这实际上是你想要的,你也不能真正使用它,因为宏评估将取决于在他们自己的源中遇到类型的顺序.

编辑:考虑一下,我认为编译器应该确保每个宏只扩展一次.在循环的情况下,如在我的示例中,所涉及的宏中的至少一个仍将看到未完全处理的类,这在这样的情况下似乎是不可避免的,因为它实际上是循环依赖性.我想,结果Type上的一个标志表示宏处理不是最终的将是处理它的最佳方法,但这可能无法在Paradise中完成.

解决方法

这似乎与 Can’t access Parent’s Members while dealing with Macro Annotations开始的讨论非常相关(在我的答案中也看到了更详细的阐述链接).

如果可能的话,我想避免宏看到半扩展或半填充类型的情况,以减少混淆的可能性.上个月我一直在考虑如何避免这种情况,但是有一些优先级更高的分心,所以我还没有走得太远.

我正在思考的两个潜在想法是:1)提出一个符号来指定宏注释的效果,这样我们就不必扩展宏来了解哪些类和成员构成了我们的程序(如果这样做的话),然后宏引擎可以首先预先计算成员列表,然后才启动宏扩展),2)找出一种指定宏如何依赖于程序元素的机制,以便正确地排序扩展.就在昨天,我还了解了Backstage Java和David Herman关于打字卫生宏的工作 – 这也应该是相关的.您如何看待这些思路?

与此同时,在我试图找出依赖关系问题的原则解决方案的同时,我也有兴趣通过提供一个解决方案或天堂补丁来立即使用来解锁您的用例.你能详细说明你的项目,以便我们能够提出修复方案吗?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读