使用Scala编译器插件黑名单一些方法调用

使用Scala编译器插件黑名单一些方法调用,scala,compiler-construction,Scala,Compiler Construction,我想创建一个scala编译器插件,防止调用某些函数。例如System.exit。 这个场景背后的想法是让人们编写Scala脚本,并在运行中进行解释。但我想确保一些危险的行为是被禁止的——这样做的方式肯定可以讨论 我从中的示例开始,并开始替换Apply部分。 通过进行一些模式匹配,我能够为编译单元的正确部分提取一个类符号。 然后我想做一些类似于示例中的事情: classSymbol.tpe =:= global.typeOf[System] 不幸的是,它们不匹配,我得到System.type在一

我想创建一个scala编译器插件,防止调用某些函数。例如System.exit。 这个场景背后的想法是让人们编写Scala脚本,并在运行中进行解释。但我想确保一些危险的行为是被禁止的——这样做的方式肯定可以讨论

我从中的示例开始,并开始替换Apply部分。 通过进行一些模式匹配,我能够为编译单元的正确部分提取一个类符号。 然后我想做一些类似于示例中的事情:

classSymbol.tpe =:= global.typeOf[System]
不幸的是,它们不匹配,我得到System.type在一边,System在另一边

当然,我可以比较字符串值,但我认为可能有更好的方法来实现这一点。 有人有什么建议吗

以防万一,代码的大部分:

  def apply(unit: global.CompilationUnit) {

    for (global.Apply(fun, _) <- unit.body) {
      fun.symbol match {
        case method: global.MethodSymbol =>
          val classSymbol = method.owner
          println(classSymbol.fullName)
          println(classSymbol.tpe =:= global.typeOf[System])
        case _ => ()
      }
    }
def应用(单位:global.CompilationUnit){
适用于(全局应用)(乐趣,u41;
val classSymbol=method.owner
println(classSymbol.fullName)
println(classSymbol.tpe=:=global.typeOf[System])
案例u=>()
}
}
也许

val jls = global.findMemberFromRoot(TermName("java.lang.System"))
也许,

val jls = global.findMemberFromRoot(TermName("java.lang.System"))

一个建议是在scalac的源代码中查找
=:=
的用法。哦,以及它的实现。如果你做了这些事情,请提供反馈。推测:如果系统位于编译器类路径中,它可能由另一个用于编译的类加载器加载。这将使它们在JVM中呈现不同的类型。为什么不只是使用JVM的SecurityManager工具?我可以使用JVM安全管理器(参见我在帖子中所说的,它的实现方式可能会受到挑战)。事实上,这个想法是,在提交代码之前,有人可以在本地编写和编译脚本(我的意思是它将被重新编译/评估)。我希望能够在用户提交脚本之前通知她。因此,如果我能尽快警告她并避免无用的步骤。这也是一个深入了解Scala类型系统如何工作的机会。一个建议是在scalac的源代码中查找
=:=
的用法。哦,及其实现。提供推测:如果系统位于编译器类路径中,它可能由另一个用于编译的类加载器加载。从JVM的角度来看,这将使它们具有不同的类型。为什么不使用JVM的SecurityManager功能呢?我可以使用JVM安全管理器(参见我在帖子中所说的,它的实现方式可能会受到挑战)。事实上,这个想法是有人可以在提交代码之前在本地编写和编译脚本(我的意思是它将被重新编译/评估)。我希望能够在用户提交脚本之前通知她。因此,如果我能尽快警告她并避免无用的步骤。这也是一个深入了解Scala类型系统如何工作的机会。你确定“java.lang.system”吗是一个术语名称吗?@pedrofurla怎么样?对我来说很有用。谢谢,这个答案对我来说很有用。不知道这是否是最好的方法,但它解决了我的问题。它还帮助我在scala lang网站上“发现”了一些与此主题相关的好文档:(看看周围,有有趣的页面).再次感谢你的邀请suggestion@user2595797当然,这是最好的方法。定义已经知道java.lang,所以您可以
global.Definitions.JavaLangPackageClass.typeSignature.member(TermName(“System”))
,但这看起来像是额外的键入(在键盘上)对我来说。我浏览了我上面分享的链接,你是对的!-对不起-顺便问一下,你知道插件中使用的“全局”包和反射中使用的通用包之间的差距是什么吗?你确定“java.lang.System”是一个术语名称吗?@pedrofurla怎么样?对我来说很有用。谢谢,这个答案对我来说很有用。不知道这是否是最好的方法,但它解决了我的问题。它还帮助我在scala lang网站上“发现”了一些与此主题相关的好文档:(看看周围,有有趣的页面).再次感谢你的邀请suggestion@user2595797当然,这是最好的方法。定义已经知道java.lang,所以您可以
global.Definitions.JavaLangPackageClass.typeSignature.member(TermName(“System”))
,但这看起来像是额外的键入(在键盘上)对我来说。我浏览了我在上面分享的链接,你是对的!-对不起-顺便问一下,你知道插件中使用的“全局”包和反射中使用的宇宙之间的差距是什么吗?