Skip to content

truonglv95/angular-rust-compiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

231 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Angular Rust Compiler

High-performance Angular AOT compiler written in Rust, providing full static compilation of Angular components and directives.

๐ŸŽฏ Project Status

Overall Progress: ~85% Complete
Status: โœ… Functional - Can compile Angular components to JavaScript


๐Ÿš€ Quick Start

Prerequisites

  • Rust 1.70+
  • Cargo

Build & Run

# Build the compiler
cargo build -p angular-compiler-cli --release

# Compile an Angular project
cargo run -p angular-compiler-cli --bin ngc -- -p demo-app/tsconfig.json

Output files will be generated in demo-app/rust-output/.


โœ… What's Working

Core Compilation Features

Feature Status Description
Component Compilation โœ… @Component decorator parsing and Ivy compilation
Directive Compilation โœ… @Directive support with ษตdir emission
Template Parsing โœ… Full HTML/Angular template parsing
Template Pipeline โœ… IR generation and optimization phases
Code Generation โœ… JavaScript emission with ษตcmp definitions
Inline Styles โœ… Style extraction and scoping ([_ngcontent-%COMP%])
External Templates โœ… templateUrl resolution
External Styles โœ… styleUrls loading

Angular Template Syntax

Syntax Status Example
Text Interpolation โœ… {{ expression }}
Property Binding โœ… [property]="value"
Event Binding โœ… (click)="handler()" with ษตษตlistener()
Two-way Binding โœ… [(ngModel)]="value"
@for Loops โœ… @for (item of items; track item.id)
@if Conditionals โœ… @if (condition) { ... }
@switch โœ… @switch (value) { @case ... }
@let Declarations โœ… @let name = expression
*ngFor Directive โœ… *ngFor="let item of items; index as i"
*ngIf Directive โœ… *ngIf="condition"
ng-content โœ… Content projection
Template References โœ… #ref

Metadata Extraction

Property Status Details
selector โœ… Component/Directive selector
inputs โœ… @Input() and input() signal
outputs โœ… @Output() and output() signal
changeDetection โœ… ChangeDetectionStrategy.OnPush (emits as 0)
standalone โœ… Standalone components
imports โœ… Component imports
hostDirectives โณ Pending

Signal Support

Signal Type Status
input() โœ…
input.required() โœ…
output() โœ…
signal() โœ…
computed() โœ…

๐Ÿ“ Project Structure

rust-compiler/
โ”œโ”€โ”€ packages/
โ”‚   โ”œโ”€โ”€ compiler/                  # Core Angular compiler
โ”‚   โ”‚   โ”œโ”€โ”€ src/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ expression_parser/ # Expression parsing
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ ml_parser/         # HTML/template parsing
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ template/          # Template pipeline
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ pipeline/      # IR & optimization phases
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ render3/           # Render3 code generation
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ output/            # AST & JavaScript emission
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ shadow_css/        # CSS scoping
โ”‚   โ”‚   โ””โ”€โ”€ Cargo.toml
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ compiler-cli/              # CLI interface
โ”‚       โ”œโ”€โ”€ src/
โ”‚       โ”‚   โ”œโ”€โ”€ ngtsc/             # Angular TypeScript Compiler
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ core/          # Core compilation logic
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ metadata/      # Metadata extraction
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ annotations/   # Decorator handlers
โ”‚       โ”‚   โ””โ”€โ”€ main.rs            # CLI entry point
โ”‚       โ””โ”€โ”€ Cargo.toml
โ”‚
โ”œโ”€โ”€ demo-app/                      # Example Angular app
โ”‚   โ”œโ”€โ”€ src/app/
โ”‚   โ”‚   โ”œโ”€โ”€ app.ts                 # Main component
โ”‚   โ”‚   โ””โ”€โ”€ app.html               # Template
โ”‚   โ”œโ”€โ”€ rust-output/               # Compiled output
โ”‚   โ””โ”€โ”€ tsconfig.json
โ”‚
โ””โ”€โ”€ Cargo.toml                     # Workspace config

๏ฟฝ Usage Examples

Compile a Project

cargo run -p angular-compiler-cli --bin ngc -- -p path/to/tsconfig.json

Example Input

// app.ts
@Component({
  selector: "app-root",
  templateUrl: "./app.html",
  styleUrls: ["./app.css"],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [CommonModule],
})
export class App {
  title = input<string>("Hello");
  count = signal(0);
  items = signal([{ id: 1, name: "Item 1" }]);

  clicked = output<void>();
}
<!-- app.html -->
<h1>{{ title() }}</h1>
@for (item of items(); track item.id; let idx = $index) {
<div>{{ idx + 1 }}. {{ item.name }}</div>
}

Example Output

// app.js
import * as i0 from "@angular/core";

function App_For_1_Template(rf, ctx) {
  if (rf & 1) {
    i0.ษตษตelementStart(0, "div");
    i0.ษตษตtext(1);
    i0.ษตษตelementEnd();
  }
  if (rf & 2) {
    const item_r1 = ctx.$implicit;
    const $index_r2 = ctx.$index;
    i0.ษตษตadvance();
    i0.ษตษตtextInterpolate2("", $index_r2 + 1, ". ", item_r1.name, "");
  }
}

export class App {
  // ... class body
  static ษตcmp = i0.ษตษตdefineComponent({
    type: App,
    selectors: [["app-root"]],
    inputs: { title: [1, "title"] },
    outputs: { clicked: "clicked" },
    changeDetection: 0,
    standalone: true,
    // ...
  });
}

๐Ÿ“ˆ Performance

Metric Rust Compiler NGTSC (TypeScript)
Full Build (123 files) ~2.88s ~3.70s
Speedup ~1.3x faster Baseline
Memory Usage Low (Native) High (V8 Heap)

๐Ÿงช Running Tests

# All compiler tests
cargo test -p angular-compiler

# All compiler-cli tests
cargo test -p angular-compiler-cli

# Specific test suite
cargo test -p angular-compiler ml_parser
cargo test -p angular-compiler expression_parser

๐Ÿ› ๏ธ Recent Improvements

December 2024 (Latest)

Control Flow - @for Loops

Feature Status Notes
Basic @for โœ… @for (item of items; track item.id)
Context Variables โœ… $index, $count, $first, $last, $even, $odd
Local Aliases โœ… let idx = $index, first = $first
Nested @for โœ… Multiple levels with correct context
@empty Block โœ… Fallback when collection is empty
Track By Function โœ… track item.id or track trackFn($index, item)
Event Handlers โš ๏ธ Works but has view hierarchy issue in nested conditionals

Known Issue: @for inside @if/@else blocks may cause nextContext() to return undefined in event handlers. Investigating.

Control Flow - @if Conditionals

Feature Status Notes
Basic @if โœ… @if (condition) { ... }
@else Block โœ… @if (condition) { ... } @else { ... }
@else if โœ… Chained conditionals
Template Chaining โœ… conditionalCreate() fluent API

NgFor Directive (*ngFor)

  • โœ… Full Template Syntax: *ngFor="let item of items; index as i; first as isFirst; last as isLast; even as isEven; odd as isOdd; trackBy: trackFn"
  • โœ… Context Variables: All loop variables ($implicit, index, count, first, last, even, odd) correctly mapped
  • โœ… Source-Span Sorting: Attributes in consts array are sorted by their source position in the template, ensuring parity with NGTSC
  • โœ… Nested Loops: Full support for nested *ngFor with correct view restoration
  • โœ… Event Handlers Inside Loops: Proper getCurrentView()/restoreView() emission for event handlers within loop bodies

NgIf Directive (*ngIf)

  • โœ… Basic Conditionals: *ngIf="condition"
  • โœ… Else Template: *ngIf="condition; else elseTemplate" with TemplateRef extraction
  • โœ… Then/Else Templates: *ngIf="condition; then thenTpl; else elseTpl"
  • โœ… As Syntax: *ngIf="user$ | async as user" with local variable binding
  • โœ… Nested NgIf: Complex nested conditionals with proper context isolation

Two-Way Binding ([(ngModel)])

  • โœ… ษตษตtwoWayListener: Proper two-way listener emission
  • โœ… ษตษตtwoWayProperty: Property binding for two-way data flow
  • โœ… ษตษตtwoWayBindingSet: Setter with fallback assignment

Optimizations & Parity

  • โœ… RestoreView Optimization: Single-usage context variables are inlined (const user = restoreView().$implicit) while multi-usage retains separate statements
  • โœ… Variable Naming Parity: Global monotonic variable naming (_r1, _r2, ...) matches NGTSC exactly
  • โœ… Consts Array Parity: Attribute ordering and marker values (3 for bindings, 4 for template directives) match NGTSC
  • โœ… OnPush Optimization: Root view listeners skip unnecessary restoreView()/resetView() calls for OnPush components
  • โœ… Listener Element Association: Correctly associates listeners with their parent elements for proper consts array ordering

Other Improvements

  • โœ… Event Binding Emission: Full support for (click)="handler()" with proper ษตษตlistener() emission
  • โœ… Rolldown/Vite Integration: Angular Linker plugin for Rolldown bundler compatibility
  • โœ… Deterministic Build Output: HashMap โ†’ IndexMap for consistent ordering of inputs, outputs
  • โœ… Signal Inputs/Outputs: Full support for input(), input.required(), and output() signals

๐Ÿ“ Known Limitations

  • i18n: Not fully implemented
  • Lazy Loading: Deferred blocks partially supported
  • Animations: Basic support only
  • View Encapsulation: Only Emulated mode
  • Source Maps: Not yet implemented

๐ŸŽฏ Roadmap

  • Complete i18n support
  • Full animation support
  • Source map generation
  • Angular CLI integration
  • Incremental compilation
  • Watch mode

๐Ÿ“ License

MIT - Same as Angular


Built with โค๏ธ using Rust

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors