Skip to content

THE LINEAGE EXTRACTOR treats any class_start group 2 as an inheritance parent, even when group 1/2 are alternation-exclusive (not name+parent) #1983

Description

@squid-protocol

Summary

detector.py's "THE LINEAGE EXTRACTOR" (~line 1520-1523) unconditionally treats a class_start match's capture group 2 as an inheritance parent whenever the pattern has 2+ groups:

if rule_name == "class_start" and pattern.groups >= 2:
    extracted_parents.extend(m.group(2).strip() for m in matches if m.group(2))

This is correct for the common shape (class Foo extends Bar -> group1=Foo name, group2=Bar parent), but several languages' class_start regexes use group 1 and group 2 as mutually-exclusive alternation branches instead (the name lands in EITHER group 1 OR group 2 depending on which branch of the pattern fired -- _resolve_class_start_match's own docstring already documents this shape for "Fortran/Lua/ABAP-shaped patterns"). For those, group 2 is never really "the parent of group 1" -- it's an alternative NAME capture for a differently-shaped declaration that has no name at all in group 1 for that match.

Confirmed instances

  • fortran (already shipped, status: production): class_start = (?:MODULE|INTERFACE|SUBMODULE)\s+(NAME1)|TYPE\s+(NAME2) -- group 1 fires for MODULE/INTERFACE/SUBMODULE, group 2 fires for TYPE, never both. A bare TYPE foo declaration's own name (group 2) gets swept into extracted_parents and shows up as that file's parent_entity metadata -- not really "foo's parent," just foo's own name being double-counted as if it were a lineage relationship.
  • dockerfile (added in the dockerfile has no named class (build-stage) extraction -- class_start regex captures the FROM keyword, not the stage alias #1974 fix): class_start = FROM image AS (ALIAS)|FROM (BARE_IMAGE) -- same shape. A bare FROM <image> (no AS alias) sweeps the base image reference into extracted_parents. Confirmed empirically: syscall.Dockerfile's parent_entity field is literally debian:${BASE_DEBIAN_DISTRO}-slim, identical to its own (only) class_data.class_name value.

Why this isn't blocking #1974

This is a pre-existing, already-in-production behavior pattern (confirmed live for fortran today), not something #1974 introduced -- #1974 just makes dockerfile the second language to exhibit it. It's also not obviously wrong for dockerfile's specific case (a Dockerfile stage's base image is loosely a real "parent" of that stage, image-inheritance-wise) -- more a case of an accidental side effect nobody explicitly designed than a clear defect.

Suggested fix (future work, not urgent)

Give _CLASS_START_NAMED_EXTRACTION_LANGS languages an explicit, opt-in way to mark their class_start pattern as "alternation-shaped" (name-OR-name, not name-then-parent) -- mirroring how _resolve_class_start_match already distinguishes these shapes for the named-extraction path -- and have THE LINEAGE EXTRACTOR consult the same flag instead of a blanket pattern.groups >= 2 check. Low priority: the current behavior isn't causing incorrect class extraction (that path already handles the alternation correctly via _resolve_class_start_match), only a secondary, cosmetic-ish parent_entity metadata field.

Activity

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

    bugUnintended behavior or logic failure in the enginecore-engineModifications to the central physics and parsing enginepriority: lowUI tweaks, documentation, and minor optimizations

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions