我有一个用C#编写的.NET程序集,它引用Microsoft.CodeAnalysis
,Microsoft.CodeAnalysis.CSharp
和System.Collections.Immutable
程序集并包含此函数:
public string GetFirstNamespace(string code)
{
var tree = CSharpSyntaxTree.ParseText (code);
var root = tree.GetRoot ();
var @using = root.DescendantNodes ().OfType<UsingDirectiveSyntax> ();
var @types = root.DescendantNodes ().OfType<TypeDeclarationSyntax> ();
var @enums = root.DescendantNodes ().OfType<EnumDeclarationSyntax> ();
var @namespaces = root.DescendantNodes ().OfType<NamespaceDeclarationSyntax> ();
return @namespaces.First ().GetText ().ToString();
}
我可以用C#编写的命令行程序调用此函数:
public static void Main(string[] args)
{
string code = "using System; namespace Foo { public class Program { public static void Main(string[] args) { Console.WriteLine(\"Hello, World\"); } } }";
Utilities u = new Utilities();
string ns = u.GetFirstNamespace(code);
Console.WriteLine (ns);
}
但是如果我尝试从T4模板调用相同的方法,使用TextTransform.exe运行,我会遇到各种麻烦。最初,有一长串的程序集无法找到:
$ /usr/lib/monodevelop/AddIns/MonoDevelop.TextTemplating/TextTransform.exe -P=./bin/Debug T4Template.tt
Processing 'T4Template.tt' failed.
(0,0): ERROR Metadata file `System.Runtime.dll' could not be found
(0,0): ERROR Metadata file `System.Collections.dll' could not be found
(0,0): ERROR Metadata file `System.Runtime.InteropServices.dll' could not be found
(0,0): ERROR Metadata file `System.Resources.ResourceManager.dll' could not be found
(0,0): ERROR Metadata file `System.Globalization.dll' could not be found
(0,0): ERROR Metadata file `System.Linq.dll' could not be found
(0,0): ERROR Metadata file `System.Diagnostics.Debug.dll' could not be found
(0,0): ERROR Metadata file `System.Runtime.Extensions.dll' could not be found
(0,0): ERROR Metadata file `System.Threading.dll' could not be found
(0,0): ERROR Metadata file `System.Diagnostics.Tools.dll' could not be found
(0,0): ERROR Metadata file `System.Reflection.dll' could not be found
将已安装的Mono目录之一添加到程序集搜索路径可修复这些问题,但会导致其他问题:
$ /usr/lib/monodevelop/AddIns/MonoDevelop.TextTemplating/TextTransform.exe -P=./bin/Debug -P=/usr/lib/mono/4.5/Facades T4Template.tt
Invalid type Microsoft.CodeAnalysis.SyntaxTree for instance field Microsoft.CodeAnalysis.SyntaxNode:_syntaxTree
Processing 'T4Template.tt' failed.
(0,0): ERROR Error running transform: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeLoadException: Failure has occurred while loading a type.
at T4CSTest.Utilities.GetFirstNamespace (System.String code) <0x4047b4e0 + 0x0002f> in <filename unknown>:0
at Microsoft.VisualStudio.TextTemplating.GeneratedTextTransformation21eb083a.TransformText () <0x4047afa0 + 0x0009b> in <filename unknown>:0
at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x7f7d1d530780 + 0x000a1> in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) <0x7f7d1d530780 + 0x000ef> in <filename unknown>:0
at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) <0x7f7d1d368cf0 + 0x0002a> in <filename unknown>:0
at Mono.TextTemplating.CompiledTemplate.Process () <0x4047a520 + 0x0036f> in <filename unknown>:0
同样的事情适用于Windows上的Visual Studio 2013。
我尝试使用从NuGet获得的引用程序集,并使用来自https://github.com/mono/roslyn的Microsoft.CodeAnalysis。*程序集,使用Mono 4.2.1构建(使用单行修补程序修复构建错误)。
我的基本问题是,我怎样才能让它发挥作用?
一个附属问题是,为什么没有帮助它找不到所有那些System。*组件?无论如何都不应该找到它们吗?这是因为那些Microsoft.CodeAnalysis。*程序集是针对PCL构建的吗?将PCL目录添加到搜索路径会导致更长的问题列表,主要是使用多重定义的类(实际上并不太意外)。
提供了完整的演示代码