【问题标题】:How to load referenced script libraries from a Roslyn script file?如何从 Roslyn 脚本文件加载引用的脚本库?
【发布时间】:2012-11-13 10:59:49
【问题描述】:

我发现我无法轻松地从另一个脚本库加载一个脚本库:

模块.csx

string SomeFunction() {
   return "something";
}

script.csx

ExecuteFile("module.csx");
SomeFunction() <-- causes compile error "SomeFunction" does not exist

这是因为编译器在编译 script.csx afaiu 时并不知道 module.csx。我可以添加另一个脚本来从该脚本加载两个文件,这样就可以了。但是,那不是那么漂亮。

相反,我喜欢让我的脚本主机检查我的脚本中的特殊语法“加载模块”,并在实际执行脚本之前执行这些模块。

script.csx

// load "module.csx"
SomeFunction()

现在,通过一些基本的字符串处理,我可以确定要加载哪些模块(包含 // load ... 的行)并加载该文件(此处为要点https://gist.github.com/4147064):

foreach(var module in scriptModules) {
   session.ExecuteFile(module);
}
return session.Execute(script)

但是 - 因为我们在谈论 Roslyn,所以应该有一些很好的方法来解析我正在寻找的语法的脚本,对吧?

它甚至可能存在一种处理模块库代码的方法?

【问题讨论】:

标签: c# roslyn


【解决方案1】:

目前在 Roslyn 中无法引用另一个脚本文件。我们正在考虑将 #load 从交互窗口的宿主命令转移到语言的一部分(如 #r),但目前尚未实现。

至于如何处理字符串,你可以正常解析它,然后寻找未知类型的预处理器指令并以此方式深入研究结构。

【讨论】:

  • 谢谢,所以我将为我自己的指令(例如#load)分析语法树,然后创建一个没有该指令的新树,并执行新树?还是我应该更好地使用 Compilation.Create... 而不是 Scripting Execute?
  • 重写树然后调用 Execute 听起来是一个合理的计划。
【解决方案2】:

https://github.com/dotnet/roslyn/commit/f1702c 开始,添加了对脚本文件中 #load 的支持。

此功能将在 Visual Studio 2015 Update 1 中提供。

【讨论】:

    【解决方案3】:

    包含脚本:

    #load "common.csx"
    ...
    

    并在运行脚本时配置源解析器

    Script<object> script = CSharpScript.Create(code, ...);
    var options = ScriptOptions.Default.WithSourceResolver(new SourceFileResolver(new string[] { }, baseDirectory));
    var func = script.WithOptions(options).CreateDelegate()
    ...
    

    【讨论】:

      猜你喜欢
      • 2012-12-31
      • 2012-02-18
      • 1970-01-01
      • 2010-09-29
      • 2016-02-18
      • 1970-01-01
      • 2011-04-05
      • 2013-10-13
      相关资源
      最近更新 更多