hphp/hack/src/parser/.llms/rules/codegen.md
✅ Run generation when you change:
schema/schema_definition.ml - Core syntax tree structureschema/token_schema_definition.ml - Token definitions✅ CRITICAL - Use exactly this:
cd ~/fbsource/fbcode && buck run //hphp/hack/src:generate_full_fidelity
❌ DO NOT use alternatives mentioned in @generated files
✅ Basic parser test:
buck2 run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:hh_parse -- ~/test.php
✅ Show parse tree + errors:
buck2 run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:hh_parse -- --full-fidelity-json-parse-tree --full-fidelity-errors ~/test.php
✅ Debug AST output:
buck2 run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:hh_parse -- --full-fidelity-ast-s-expression ~/test.php
Schema → Generated Files:
OCaml files:
full_fidelity_syntax.ml - Core syntax treefull_fidelity_token_kind.ml - Token definitionssmart_constructors/*.ml - Constructor interfacesRust files:
syntax_type.rs - Core syntax typestoken_kind.rs - Token definitionssmart_constructors_generated.rs - Constructor implementationssyntax_by_ref/*.rs - Reference implementations✅ GOOD - Complete generation workflow:
# 1. Edit schema files
# 2. Generate immediately
cd ~/fbsource/fbcode && buck run //hphp/hack/src:generate_full_fidelity
# 3. Build to verify
buck2 build @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:hh_single_type_check
# 4. Test parsing
buck2 run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:hh_parse -- --full-fidelity-errors ~/test.php
✅ GOOD - Adding new syntax node:
(* File: schema/schema_definition.ml *)
let schema = [
(* ... existing nodes ... *)
{
kind_name = "MyNewStatement";
type_name = "my_new_statement";
description = "A new statement type";
prefix = "my_new";
aggregates = [Statement];
fields = [
Token;
(ZeroOrOne (Aggregate Expression));
Token;
]
};
(* ... *)
]
✅ GOOD - Adding new token:
(* File: schema/token_schema_definition.ml *)
let given_text_tokens = [
(* ... existing tokens ... *)
make_token_node "MyKeyword" "mykeyword" ~allowed_as_identifier:false ();
(* ... *)
]
❌ BAD - Editing generated files:
// DON'T DO THIS - edit schema instead
// File: token_kind.rs
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TokenKind {
// NEVER edit this directly
}
Key aggregate types:
TopLevelDeclaration - Classes, functionsExpression - Variables, calls, operatorsStatement - Control flow, assignmentsSpecifier - Type specificationsField specifications:
Token - Single token (most common)Just "NodeType" - Specific node referenceAggregate Type - Any node of aggregate typeZeroOrMore / ZeroOrOne - Repetition patternsGeneration fails?
Build fails after generation?
lowerer.rs updatesschema/)@generated fileshh_parse for parser verificationhh_single_type_check target