Skip to content

PHP : les constantes de classe typées disparaissent du graphe #17

Closed

Description

@alexwrite

Context

Pilote du 2026-10-11 sur projet A (PHP 8.4) et projet B (PHP 8.5). La grammaire tree-sitter-php (0.24.1 embarquée, 0.25.1 dernière) ne reconnaît pas les constantes de classe typées (PHP 8.3) : public const string X = '...';.

  • Toute constante typée est absente du graphe : 427 fichiers sur 3 219 dans projet A, 157 sur 517 dans projet B.
  • Une classe qui ne contient que des constantes typées disparaît entièrement : la déclaration de classe devient un nœud ERROR (cas réel : src/Http/UserAgents.php de projet A).
  • Test isolé : la même classe sans le type ne produit aucune erreur. La PR amont tree-sitter-php#214 (« PHP 8.3 support ») couvre la lecture dynamique de constante, pas le type. Aucune issue ouverte en amont.

Outcome attendu

Une constante typée est un nœud du graphe, rattaché à sa classe, quel que soit le reste du contenu de la classe.

Acceptance criteria

  • Une classe ne contenant que des constantes typées apparaît dans le graphe, avec ses constantes
  • graphify extract sur projet A n'émet plus d'avertissement « syntax error » pour UserAgents.php
  • Test de régression avec une fixture PHP qui échoue avant le correctif
  • La grammaire corrigée est figée par commit (pas de branche flottante)

Hints

  • Cause : grammar.js de tree-sitter/tree-sitter-php, règle const_declaration sans type optionnel
  • Correctif dans un fork de la grammaire, référencé par pyproject.toml, puis proposé en amont
  • graphify/extractors/engine.py:8693 : enregistrement de parse_errors

Hors scope

  • Autres syntaxes PHP 8.4 / 8.5 non vérifiées (property hooks, visibilité asymétrique) : issue séparée si constatées

Activity

  1. added
    bugSomething isn't working
    p2Défaut visible par l'utilisateur
    on Oct 11, 2026
  2. github-actions commented on Oct 11, 2026

    @github-actions

    Thanks for opening this issue, @alexwrite. A maintainer will take a look soon.

    If you would like to discuss it in real time, come say hi on our Discord server. For longer-form questions and ideas there is also GitHub Discussions.

    To help us triage, please make sure the report includes what you expected, what actually happened, and the steps (and a small sample) to reproduce it.

  3. alexwrite commented on Oct 11, 2026

    @alexwrite
    OwnerAuthor

    Prise en charge.

    Le diagnostic initial est à corriger, constaté par test isolé (tree-sitter-php 0.24.1) :

    Affirmation de l'issue Constat
    La grammaire ne connaît pas le type des constantes Faux : supporté depuis tree-sitter/tree-sitter-php#205 (2024). public const string X, ?string, union, classe, enum, interface, trait : 0 erreur
    Toute constante typée est absente du graphe Vrai, mais aussi pour les non typées : Graphify ne crée pas de nœud de constante PHP, un accès Foo::BAR devient une arête references_constant vers la classe. Choix de conception, hors de cette issue
    427 et 157 fichiers touchés Ce sont les fichiers qui contiennent une constante typée, pas ceux en erreur

    Vrai défaut : une constante de classe dont le nom est un mot réservé (DEFAULT, PRIVATE, CLASS, NEW...). 61 mots cassent quand la constante est typée, 7 même sans type (VOID, TRUE...). Selon la récupération d'erreur, la classe entière devient un nœud ERROR et disparaît du graphe. Projet A : 2 fichiers en erreur sur 2 943, dont une classe perdue. Projet B : 0 sur 476.

    Amont : tree-sitter/tree-sitter-php#295 (issue) et Graphify-Labs#307 (PR ouverte le 2026-10-08, CI verte, en attente de relecture) corrigent exactement ce cas. Pas de correctif maison ni de PR amont en doublon.

    Périmètre de fichiers visé :

  4. alexwrite commented on Oct 11, 2026

    @alexwrite
    OwnerAuthor

    Fait

    • Une classe PHP dont les constantes portent un nom de mot réservé (DEFAULT, PRIVATE, CLASS, VOID...), typées ou non, s'analyse sans erreur : la classe reste dans le graphe, avec ses arêtes contains, imports et references_constant.
    • PR : fix(php): parse class constants named after reserved keywords #46 (fermera cette issue à la fusion).

    Comment

    • pyproject.toml:40 : tree-sitter-php figé sur alexwrite/tree-sitter-php@9678351 (branche fix/keyword-constant-names = commits de fix: parse keyword identifiers in expressions and constants tree-sitter/tree-sitter-php#307, auteur conservé, plus un test de corpus).
    • uv.lock : seulement les deux blocs tree-sitter-php.
    • tests/test_php_keyword_constant_names.py : 7 déclarations à nom réservé sans parse_errors, et une classe ne contenant que des constantes qui garde son nœud et son arête references_constant.
    • Fork de la grammaire : test/corpus/bugs.txt, cas « Reserved keywords as typed class constant names » (final, optionnel, union, type nommé ; classe, interface, enum).

    Pourquoi ce choix

    Apprentissages

    • Le diagnostic de départ était faux : les constantes typées sont supportées depuis feat: support typed class constants tree-sitter/tree-sitter-php#205 (2024). Seul le nom réservé casse : 61 des 83 mots-clés testés en typé, 7 en non typé.
    • Graphify ne crée pas de nœud de constante PHP, typée ou non. L'objectif « de 0 à toutes les constantes typées » ne pouvait donc pas être atteint par la grammaire.
    • Selon le contenu des chaînes (;, parenthèses), la récupération d'erreur avale soit la constante, soit toute la classe. La fixture reproduit le second cas.
    • Les 2 fichiers en erreur sur le projet A étaient l'un « 0 symbole » (avertissement affiché), l'autre silencieux parce que le seuil d'avertissement n'a rien vu disparaître.

    Faiblesses restantes

    Quality

    • Test de régression : 8 échecs avec tree-sitter-php 0.24.1, 8 réussites avec le commit figé
    • Suite complète : 7536 passed, 14 skipped, 0 failed (référence main : 7528 + 8 nouveaux)
    • ruff : All checks passed ; pyright sur le nouveau fichier : 0 erreur
    • Grammaire, tree-sitter test (CLI 0.27.0) : 157/157 ; le nouveau cas échoue sur le master amont
    • Mesure, avant puis après, différentiel complet des nœuds et des arêtes : projet A, 2 fichiers en erreur de syntaxe deviennent 0 ; la classe disparue revient (1 nœud, contains + 8 imports qui visaient un nœud sans source), une position de constructeur corrigée, rien d'autre ne change. Projet B : 0 fichier en erreur avant comme après, graphe identique.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingp2Défaut visible par l'utilisateur

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions