Skip to content

Mago 2.0 - Tracking Issue #1931

Description

@azjezz

Mago 2.0 - Tracking Issue

Meta issue for the 2.0 release. 2.0 is a ground-up rework of the analysis pipeline plus the tooling and stability commitments that ride on top of it. This issue tracks the whole effort; each box links to (or will spawn) a dedicated issue/PR.

Why 2.0

PHP is effectively two languages: the surface syntax, and the type language embedded in docblocks (@var, @param, @template, @method, @psalm-type, ...). They have different grammars and, in 1.x, are parsed by different code at different times, the syntax tree as one artifact, docblocks re-parsed on demand across a multiple scattered call sites.

2.0 fuses them. A single lowering pass turns the syntax tree into one typed IR that already has docblocks parsed, names resolved, and sugar normalized — and analysis is split into honest phases (scan → inference → check) that hand a typed program forward instead of re-deriving it. As a side effect we stop lying about the tree: what 1.x calls the "AST" is really a lossless CST (it keeps trivia and spans, which is why the formatter round-trips), so 2.0 names it a CST and reserves "the real, lowered tree" for the IR.

The new pipeline

    source
      │ parse
      ▼
    CST            (mago_syntax::cst — lossless: trivia, spans, round-trips)
      │ lower      (per-file, NO cross-file info: name resolution + docblock parse + desugar)
      ▼
    IR<(), ()>     (typed-in-node tree, generic over context C and type T)
      │ scan
      ├─▶ linter
      ▼
    CodebaseMetadata
      │            IR + CodebaseMetadata
      ▼ inference
    IR<(), T>      (type info filled in the nodes)
      │ check
      ▼
    IR<C, T>       (context / "Env" filled: cross-references resolved, etc.)
      │
      ├─▶ security / taint analysis
      └─▶ reporting

Key decisions already settled in design:

  • The IR is arena-allocated, generic over C (context) and T (type), with annotationion** (no interior mutability), the generics encode the analysis phase in the type system.
  • Lowering is fully local, no codebase access. Linking a name to another file is the checker's on-demand job, not lowering's.
  • The IR must be retained and movable across phase boundaries (inference output is the check input), so it lives in a cross-phase arena (bumpalo-herd) or as owned-per-file values, not borrowed from a transient per-thread bump.

Workstreams

1. Compiler core (critical path — roughly in order)

2. Type-system features

3. New commands

4. Linter & formatter

5. Editor & LSP

6. Extensibility & stability

  • Plugin system — let users write plugins (host language TBD: PHP / JS / Rust / WAS / Something else).
  • Stabilize the Rust API. From 2.0.0, mago crates follow semver - no more frequent breaking changes to the Rust API.

Open questions

  • Name of the context generic: Ctx vs Env?
  • Plugin host language: PHP / JS / Rust / WASM / Something else? (feature: allow creating custom linting rules using PHP. #177)
  • Linter on the IR, or keep it on the CST?
  • Taint analysis: dedicated mago security-analysis subcommand vs --with-taint-analysis
  • Do mago analyze / mago lint get deprecated in favor of mago check, or kept as alias
  • IR retention across phases: central bumpalo-herd vs owned-per-file (self_cell)?

Metadata

Metadata

Assignees

Labels

bc-breakBreaking changec-analyzerPHP static analyzer and type error detectionc-codexType system representation and codebase metadatac-databaseIn-memory database for source code analysisc-docblockPHPDoc annotation and tag extractionc-formatterPHP code reformatting and style rulesc-guardPHP dependencies guard for clean architecturec-linterPHP linting for errors, style, and bugsc-orchestratorCoordination of Mago componentsc-semanticsPHP semantics checkerc-syntaxPHP lexer, parser, and ASTc-type-syntaxPHPDoc type syntax parsingcliCommand-line interfaceconfigurationConfiguration loading and validationlanguage-serverExperimental Mago Language ServerrustWritten in Rustt-enhancementNew feature or request

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions