Compiler Diagnostics Overview

Tier 0 · Story 01Complete

The Tyhp compiler uses a structured diagnostic system to report errors, warnings, and informational messages during compilation. Every diagnostic has a unique code, a severity level, and a human-readable message that includes the source file location. This page explains how to read and interpret compiler diagnostics.

Diagnostic Format

Each diagnostic message follows a consistent format that includes the file path, line and column numbers, severity, diagnostic code, and a descriptive message:

filename(line,column): severity TYHPXXXX: message

For example, a type mismatch error would appear as:

src/Models/User.tyhp(42,5): error TYHP4008: Cannot assign type 'string' to type 'int'

The components are:

  • src/Models/User.tyhp -- the source file where the issue was detected
  • (42,5) -- line 42, column 5 (1-indexed)
  • error -- the severity level (error, warning, or info)
  • TYHP4008 -- the unique diagnostic code
  • Cannot assign type 'string' to type 'int' -- a human-readable description of the problem

Severity Levels

The Tyhp compiler uses three severity levels for diagnostics:

Diagnostic Code Numbering Scheme

Every diagnostic code follows the pattern TYHPXXXX where the first digit identifies the compiler phase that produced the diagnostic. This makes it easy to understand where in the compilation pipeline an issue was detected:

Example Error Output

Here is an example of what a typical build output looks like when there are errors and warnings:

src/Models/User.tyhp(15,10): error TYHP3003: Symbol 'InvalidUser' not found
src/Models/User.tyhp(42,5): error TYHP4008: Cannot assign type 'string' to type 'int'
src/Services/Auth.tyhp(23,1): error TYHP4002: Multiple visibility modifiers specified
src/Services/Auth.tyhp(67,12): warning TYHP4012: Unreachable code detected

Build failed with 3 errors and 1 warning.

  Files:     12 source files
  Duration:  0.91s (parse: 0.45s, bind: 0.12s, check: 0.34s)
  Errors:    3
  Warnings:  1

Enhanced Error Messages

Tier 1 · Story 14Complete

Beyond the basic file(line,column): severity CODE: message format, the Tyhp compiler renders diagnostics with rich, developer-focused detail. The renderer reuses the same diagnostic data carried by every phase, so text, JSON, and SARIF output stay consistent.

  • Source spans and underlines — The text renderer prints the offending source line with a caret/underline beneath the primary span, plus labeled secondary spans that point at related locations (similar to the Rust compiler). Output degrades gracefully to a single line when --quiet is set.
  • "Did you mean" suggestions — When the binder or checker reports an unknown symbol, type, or member, it attaches a Levenshtein-based suggestion drawn from the in-scope symbol table, surfaced as a help: hint in text output and as a machine-applicable fix in JSON and SARIF.
  • Actionable fixes — Suggestions carry a span and replacement text, providing the data contract that drives tyhp lint --fix. Language server code actions are planned.
  • The --explain command — Run tyhp --explain TYHP4008 to print the long-form explanation for any diagnostic code. The error index is generated directly from the compiler's code registry, so it always matches the codes the compiler emits.

Diagnostic messages follow a consistent style: present tense, the offending symbol or type named in backticks, and "expected X, found Y" framing. A build-time consistency gate enforces that every diagnostic code has conforming message text and vice versa.

tyhp --explain TYHP4008

How the Compilation Pipeline Works

Understanding the compilation pipeline helps in diagnosing errors. The Tyhp compiler processes your code through these sequential phases:

  1. Parse -- The ANTLR4 lexer and parser read your source files and produce parse trees. Syntax errors (TYHP1xxx) are detected here. Parsing continues for other files even if one file has syntax errors.
  2. Visit -- The visitor converts parse trees into Abstract Syntax Trees (AST). Unexpected grammar structures (TYHP2xxx) are detected here.
  3. Bind -- The binder walks the AST to build a symbol table, resolve names, and establish scope hierarchies. Duplicate declarations and unresolved symbols (TYHP3xxx) are detected here.
  4. Check -- The checker performs type checking and semantic analysis on the bound AST. Type mismatches, missing implementations, and all semantic violations (TYHP4xxx) are detected here.
  5. Emit -- The emitter transforms the checked AST into PHP source code. Unsupported constructs and output conflicts (TYHP5xxx) are detected here.
  6. Write -- The generated PHP files are written to disk. File system errors (TYHP7xxx) may occur at this stage.

If errors occur in an earlier phase, the compiler may skip later phases. For example, if there are parser errors in a file, that file will not proceed through binding and checking. However, other files in the project continue to be processed, so you can see as many errors as possible in a single build.

Common Error Categories and How to Fix Them

Here are the most common categories of errors you will encounter and general strategies for resolving them:

Tips for Debugging Compiler Errors

  1. Fix errors in order -- Earlier-phase errors (parser, binder) can cause cascading false positives in later phases. Fix TYHP1xxx and TYHP3xxx errors first, then rebuild to see if TYHP4xxx errors remain.
  2. Use the lint command for faster feedback -- Run tyhp lint instead of tyhp build when you only need to check for errors. Lint skips the emit and write phases, making it faster.
  3. Lint a single file -- Use tyhp lint --file src/MyClass.tyhp to check a single file while you are actively editing it.
  4. Look up the error code -- Use the Diagnostic Code Reference page to find detailed explanations and fix guidance for any error code.
  5. Check your tyhpdef files -- If you see TYHP3003 (symbol not found) for a PHP library class, ensure the corresponding tyhpdef files are loaded. Check your tyhp.json tyhpdef include paths.
  6. Use strict mode judiciously -- The --strict flag treats warnings as errors. This is useful for CI pipelines but may be noisy during active development.
  7. Check the target PHP version -- Some features require specific PHP versions (e.g., property hooks require PHP 8.4+, readonly properties require PHP 8.1+). Verify your output.phpVersion in tyhp.json.

JSON Output Format

For CI/CD integration, the tyhp lint command supports JSON output via the --format json flag. Each diagnostic is serialized as a JSON object:

JSON range coordinates are 0-based lines (text diagnostics are 1-based). Column is 0-based in both. Line 42 in text output is "line": 41 here:

{
  "severity": "error",
  "code": "TYHP4008",
  "file": "src/Models/User.tyhp",
  "range": {
    "start": { "line": 41, "column": 5 },
    "end": { "line": 41, "column": 15 }
  },
  "message": "Cannot assign type 'string' to type 'int'"
}

This format is compatible with common CI reporting tools and IDE integrations.