我想从给定的Scala项目中提取所有方法的调用图,这些方法是项目自己的源代码的一部分.
据我所知,演示编译器没有启用它,它需要一直向下到实际的编译器(或编译器插件?).
您能否建议完整的代码,这些代码可以安全地用于大多数scala项目,但是那些使用最古怪的动态语言功能的代码?对于调用图,我的意思是包含class/trait + method顶点的有向(可能是循环的)图,其中边A-> B表示A可以调用B.
应避免或"标记"来自/来自图书馆的呼叫在项目自己的来源之外.
编辑:
看看我的宏天堂衍生原型解决方案,基于@ dk14的主角,作为下面的答案.在https://github.com/matanster/sbt-example-paradise上的github上托管.
我有一个Scala 2.9编译器插件(源代码),在2.9中运行得很好但是甚至不用2.10编译.有许多(可能是100多个)错误都属于同一类,例如:
[scalac] C:\***.scala:31: error: illegal cyclic reference involving class Global
[scalac] val fileSeparator = System.getProperty("file.separator");
[scalac] ^
Run Code Online (Sandbox Code Playgroud)
......最终终止于:
[scalac] scala.reflect.internal.Types$TypeError: illegal cyclic reference involving class Global
[scalac] at scala.reflect.internal.Types$class.defineBaseClassesOfCompoundType(Types.scala:1731)
[scalac] at scala.reflect.internal.SymbolTable.defineBaseClassesOfCompoundType(SymbolTable.scala:12)
[scalac] at scala.reflect.internal.Types$CompoundType.baseClasses(Types.scala:1581)
[scalac] at scala.reflect.internal.Types$TypeRef.baseClasses(Types.scala:2369)
[scalac] at scala.reflect.internal.Types$SimpleTypeProxy$class.baseClasses(Types.scala:248)
[scalac] at scala.reflect.internal.Types$SingletonType.baseClasses(Types.scala:1292)
[scalac] at scala.reflect.internal.Types$Type.findMembers(Types.scala:1058)
[scalac] at scala.reflect.internal.Types$Type.membersBasedOnFlags(Types.scala:683)
[scalac] at scala.reflect.internal.Types$Type.implicitMembers(Types.scala:637)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.collect$1(Contexts.scala:630)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.collectImplicitImports(Contexts.scala:642)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.implicitss(Contexts.scala:670)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.implicitss(Contexts.scala:675)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.implicitss(Contexts.scala:675)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.implicitss(Contexts.scala:675)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.implicitss(Contexts.scala:675)
[scalac] at scala.tools.nsc.typechecker.Contexts$Context.implicitss(Contexts.scala:675)
[scalac] at …Run Code Online (Sandbox Code Playgroud) Test.test中的错误似乎没有道理:
sealed trait A[-K, +V]
case class B[+V]() extends A[Option[Unit], V]
case class Test[U]() {
def test[V](t: A[Option[U], V]) = t match {
case B() => null // constructor cannot be instantiated to expected type; found : B[V] required: A[Option[U],?V1] where type ?V1 <: V (this is a GADT skolem)
}
def test2[V](t: A[Option[U], V]) = Test2.test2(t)
}
object Test2 {
def test2[U, V](t: A[Option[U], V]) = t match {
case B() => null // This works
}
}
Run Code Online (Sandbox Code Playgroud)
有几种方法可以改变错误,或者消失: …
我希望我的Scala代码将Scala类作为输入,编译并执行该类.如何以编程方式调用Scala编译器?我将使用最新的Scala版本,即2.10.
所以我googl'ed了一点,但除了稀疏之外没有其他信息:
-Yrangepos Use range positions for syntax trees.
Run Code Online (Sandbox Code Playgroud)
好.而且我知道如果我想在宏中捕获源片段,我需要使用它.
现在我的两个问题是:
我正在尝试运行作为JAR打包的Scala应用程序(包括依赖项),但是在使用该-Xbootclasspath/p选项添加Scala库之前,这会失败.
调用失败:
java -jar /path/to/target/scala-2.10/application-assembly-1.0.jar
Run Code Online (Sandbox Code Playgroud)
在应用程序执行了一些预期输出后,控制台显示:
线程"main"中的异常scala.reflect.internal.MissingRequirementError:找不到编译器镜像中的对象scala.runtime.at scala.reflect.internal.MissingRequirementError $ .signal(MissingRequirementError.scala:16)at scala.reflect.internal.MissingRequirementError $ .notFound(MissingRequirementError.scala:17)at scala.reflect.internal.Mirrors $ RootsBase.getModuleOrClass(Mirrors .scala:48)scala.reflect.internal.Mirrors $ RootsBase.getModuleOrClass(Mirrors.scala:40)at scala.reflect.internal.Mirrors $ RootsBase.getModuleOrClass(Mirrors.scala:61)at scala.reflect.internal.镜像$ RootsBase.getPackage(Mirrors.scala:172)at scala.reflect.internal.Mirrors $ RootsBase.getRequiredPackage(Mirrors.scala:175)at scala.reflect.internal.Definitions $ DefinitionsClass.RuntimePackage $ lzycompute(Definitions.scala: 181)scala.reflect.internal.Definitions上的scala.reflect.internal.Definitions $ DefinitionsClass.RuntimePackage(Definitions.scala:181)scala.reflect.internal.Definitions $ DefinitionsClass.RuntimePackageClass $ lzycompute(Definitions.scala:182)at scala.reflect.internal.Definitions scala.reflect上的$ DefinitionsClass.RuntimePackageClass(Definitions.scala:182).在scala.reflect.internal.Definitions $ DefinitionsClass.AnnotationDefaultAttr(Definitions.scala:1014)的scala.reflect.internal.Definitions $ DefinitionsClass.syntheticCoreClasses $ lzycompute中的internal.Definitions $ DefinitionsClass.AnnotationDefaultAttr $ lzycompute(Definitions.scala:1015)定义.scala:1144)scala.reflect.internal.Definitions $ DefinitionsClass.syntheticCoreClasses(Definitions.scala:1143)scala.reflect.internal.Definitions $ DefinitionsClass.symbolsNotPresentInBytecode $ lzycompute(Definitions.scala:1187)at scala.reflect .internal.Definitions $ DefinitionsClass.symbolsNotPresentInBytecode(Definitions.scala:1187)at scala.reflect.internal.Definitions $ DefinitionsClass.init(Definitions.scala:1252)at scala.tools.nsc.Global $ Run.(Global.scala: 1290)在extract.ScalaExtractor $ Compiler $ 2 $.(ScalaExtractor.scala:24)
工作调用:
java -Xbootclasspath/p:/path/to/home/.sbt/boot/scala-2.10.2/lib/scala-library.jar -jar …Run Code Online (Sandbox Code Playgroud) 我想设计一个Scala程序,它接受Scala文件作为参数,可以自定义程序的执行.特别是,我想在运行时提供包含将由程序调用的方法的实现的文件.如何正确依赖外部文件并在运行时动态调用其方法?理想情况下,我还希望这些文件能够依赖于我的程序中的方法和类.
示例场景:我有一个包含该行的函数val p: Plant = Greenhouse.getPlant(),并且Greenhouse该getPlant方法的类在将在运行时提供的其中一个文件中定义.在该文件中,该方法getPlant返回a Rose,where Rose <: Plant和Plant在原始程序中定义.假设文件仅在运行时加入而不是在编译时加入,我如何实现(或近似)这种相互依赖性?
运行带有Java 7的简单SBT项目(详情如下)并sbt run在命令行调用(无IntelliJ或任何东西)
资源
import scala.tools.nsc.{ Global, Settings }
object Playground extends App {
val compiler = new Global(new Settings())
val testFiles = List("Test.scala")
val runner = new compiler.Run()
val result = runner.compile(testFiles)
println(result)
}
Run Code Online (Sandbox Code Playgroud)
错误
error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by /Library/Java/JavaVirtualMachines/jdk1.7.0_60.jdk/Contents/Home/jre/lib/rt.jar(java/lang/Object.class)
[error] (run-main-0) scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:17)
at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:18)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:53)
at scala.reflect.internal.Mirrors$RootsBase.getModuleOrClass(Mirrors.scala:66)
at …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码段:
trait X[-T]
object Y extends X[Nothing]
def a[T](x: X[T]): X[T] = x
a(Y)
Run Code Online (Sandbox Code Playgroud)
上述(2.12.3)的汇编失败了:
type mismatch;
found : Y.type
required: X[T]
a(Y)
^
Run Code Online (Sandbox Code Playgroud)
如果符合以下情况,这将编
Nothing(例如object Y extends X[String])a不在T其返回类型中使用(例如def a[T](x: X[T]): Unit = {})a明确给出了类型参数(即a[Nothing](Y))T 是协变的,而不是逆变的(如果它是不变的也会失败)这是编译器中的一些特例Nothing吗?
作为一个"有趣"的解决方案,以下似乎工作正常:
trait X[-T]
object Y extends X[Nothing]
def a[T, U <: T](x: X[T]): X[U] = x
a(Y)
Run Code Online (Sandbox Code Playgroud)