InspecTree is a library for inspecting entire syntax trees of lambda functions in C#. Expression<T>
is commonly used for this purpose, but it is limited to single expressions unless you manually construct a BlockExpression
. InspecTree allows you to inspect entire syntax trees of lambda functions, including entire statement bodies.
This library was initially created with the intention of transpiling C# code to GLSL. Here's a small example of how to access the syntax tree of a lambda function to transpile it to GLSL.
// Partial required due to source generator
// creating an overload in the same class
public partial class Program
{
public static void Main(string[] args)
{
var glslCode = TranspileToGLSL(() =>
{
var x = 2 + 5f;
var color = new Vector4(1.0f);
if (x > 4)
{
color = new Vector4(0.2f, 0.3f, x, 1.0f);
}
return color;
});
}
// Overload of this method is generated by source generator that
// accepts a Func<Vector4>, and therefore accepts a lambda function
public static string TranspileToGLSL(InspecTree<Func<Vector4>> shader)
{
var transpiler = new GLSLTranspiler();
return transpiler.Transpile(shader.SyntaxTree);
}
}
If you want a more complete example of where this is done, check out the InspecTree.Example project.
InspecTree uses two source generators to make it possible to access both the syntax tree and semantic model of a lambda.
-
For each method that accepts an
InspecTree<Func<T>
parameter, it generates an overload that accepts aFunc<T>
parameter instead. This allows you to pass a lambda function to your method since there is no way to implicitly convert a lambda to a user-defined type. -
For each invocation to one of the generated overloads, it generates an interceptor method that will be invoked instead. This interceptor method will create an
InspecTree<Func<T>>
object from theFunc<T>
parameter and store the lambda function's syntax tree and semantic model.