Skip to content

Compiler

Edgar Mesquita edited this page Jan 29, 2026 · 10 revisions

The Compiler (CSharpToJs)

The compiler is the core component that enables the magic of eQuantic.UI. It transforms C# semantics into efficient and readable TypeScript code.

🛠️ Compiler Components

1. TypeScriptEmitter

The TypeScriptEmitter is the entry point for generating .ts files. It organizes imports, defines classes, and uses the CSharpToJsConverter to convert method bodies.

2. CSharpToJsConverter

A implementation based on the Strategy pattern that traverses the Roslyn syntax tree (AST).

  • Each type of C# expression or statement has a dedicated strategy (e.g., BinaryExpressionStrategy, IfStatementStrategy).

3. SourceMapGenerator

Generates standard V3 Source Maps with Base64 VLQ encoding, mapping generated JavaScript/TypeScript back to the original .cs or .eqx source lines.

4. Identifier Heuristics

The converter applies intelligent heuristics to decide how to map variable names:

  • C# properties and fields are mapped to this.propertyName in JS.
  • Local variables and parameters retain their original names.
  • System methods like Console.WriteLine are automatically mapped to console.log.

🔄 Supported Strategies

Currently, the compiler supports a wide range of C# constructs:

  • Expressions: Arithmetic, Logical, Ternary, String Interpolation, Null-coalescing (??), Conditional Access (?., ?[]).
  • Control Flow: if, switch, for, foreach, while, do-while, break, continue, throw.
  • Modern Patterns: Full support for Recursive, Property, Positional, Relational, and Logical patterns (C# 9.0 - 12.0).
  • Resource Management: Support for using statements and using var declarations.
  • Exceptions: Full support for try-catch-finally and throw statements (Exception → Error).
  • Indexes and Ranges: Support for index-from-end operator (array[^1]array[array.length - 1]).
  • LINQ: Direct conversion of LINQ methods to JS equivalents:
    • Projection: Selectmap, SelectManyflatMap
    • Filtering: Wherefilter, Distinct[...new Set()]
    • Ordering: OrderBy/OrderByDescendingsort, Reverse[...arr].reverse()
    • Partitioning: Skipslice(n), Takeslice(0, n)
    • Element: First/FirstOrDefaultfind/[0], Last/LastOrDefaultarr[arr.length-1], Single/SingleOrDefaultfind/[0]
    • Quantifiers: Anysome/length > 0, Allevery, Containsincludes
    • Aggregation: Countlength/filter().length, Sumreduce((a,b) => a+b, 0), Averagereduce()/length, MinMath.min(...), MaxMath.max(...)
  • Async/Await: Mapping of Task to Promise and native await support.

📝 Conversion Example

C# Source:

private void Increment() {
    Count++;
    if (Count > 10) Console.WriteLine("Max reached");
}

TypeScript Output:

increment() {
    this.count++;
    if (this.count > 10) console.log("Max reached");
}

Clone this wiki locally