-
Notifications
You must be signed in to change notification settings - Fork 0
Description
To enable modern debugging and future proffing we must switch the entire code generation from IL emitting (with expression trees) to using the Roslyin SDK. We must generate a SyntaxTree (not raw C#) as this will prevent many mitakes that can occur with raw string generation.
The code currently doesn't work due to an upgrade to .net 10, it doesn't work in the IL code generation so the switch to Roslyin will fix it. We can completely remove the expression tree stuff, FastCompiler library and all.
Here is a complete description of work requirement :
Objective:
Refactor an existing Visual Programming Language (VPL) runtime. The current implementation uses System.Linq.Expressions to generate code. You must replace this with Roslyn SyntaxTree generation to enable "native" debugging (breakpoints, stepping, inspection) for in-memory compiled assemblies.
Architectural Pattern: Polymorphic Generation
Do not use a central giant converter/visitor class. You must implement a Distributed/Polymorphic pattern where each Node class is responsible for generating its own Roslyn syntax.
- The GenerationContext Class (New Requirement)
Since SyntaxNode objects do not automatically handle data flow like Expression trees, you must implement a GenerationContext class to pass between nodes. Validate if such class already exists and reuse/adapt it if so. Otherwise create a new one and pass it down during generation.
Responsibility:
Symbol Table: A dictionary mapping ConnectionID to string (Generated C# Variable Name).
Name Generator: A method to create unique variable names (e.g., GetUniqueName("node_1_out") -> node_1_out_x92).
Statement Buffer: A collection to hold auxiliary statements. (e.g., if a Node needs to emit 3 lines of setup code but return 1 variable name, it adds the setup lines here).
- The Abstract Node Update
Refactor the base node class/interfaces as required.
Remove: the previous expression generation
Add: public abstract SyntaxNode GenerateRoslynSyntax(GenerationContext ctx); (and any additionally required parameters)
Behavior:
Nodes must look up input variable names from the ctx.
Nodes must register their output variable names into the ctx.
Nodes return a StatementSyntax (for execution flow) or an ExpressionSyntax (for data calculation).
- The Compilation Service
Modify the existing compilation service
Input: The root CompilationUnitSyntax generated by the graph.
Source Embedding:
Convert the tree to a string: tree.GetRoot().NormalizeWhitespace().ToFullString().
Use EmbeddedText.FromSource(...) to embed this string into the PDB. This allows the debugger to show the code even though it exists only in RAM.
Emission:
Create CSharpCompilation with OptimizationLevel.Debug.
Emit to MemoryStream using DebugInformationFormat.PortablePdb.
Load using Assembly.Load(peBytes, pdbBytes).
- Constraints & Pitfalls to Avoid
Type Safety: Do not try to resolve complex types manually. Use var (Implicit Type) in generated C# variable declarations wherever possible.
Whitespace: You must call .NormalizeWhitespace() on the final root node before compilation. Without this, #line directives may collapse onto a single line, breaking the debugger mapping.
Scope: Be careful with variable scoping. If a variable is generated inside an if block (e.g., inside a Conditional Node), ensure it is declared outside the block if it is needed by subsequent nodes (Variable Hoisting).
Limit: limit the amount of code modified to minimum. Make sure you read how it is done before modifying any code
Test: Add as much testing as possible