You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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.
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.
Summary
detector.py's "THE LINEAGE EXTRACTOR" (~line 1520-1523) unconditionally treats aclass_startmatch's capture group 2 as an inheritance parent whenever the pattern has 2+ groups:This is correct for the common shape (
class Foo extends Bar-> group1=Foo name, group2=Bar parent), but several languages'class_startregexes 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
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 bareTYPE foodeclaration's own name (group 2) gets swept intoextracted_parentsand shows up as that file'sparent_entitymetadata -- not really "foo's parent," just foo's own name being double-counted as if it were a lineage relationship.class_start=FROM image AS (ALIAS)|FROM (BARE_IMAGE)-- same shape. A bareFROM <image>(noASalias) sweeps the base image reference intoextracted_parents. Confirmed empirically:syscall.Dockerfile'sparent_entityfield is literallydebian:${BASE_DEBIAN_DISTRO}-slim, identical to its own (only)class_data.class_namevalue.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_LANGSlanguages an explicit, opt-in way to mark theirclass_startpattern as "alternation-shaped" (name-OR-name, not name-then-parent) -- mirroring how_resolve_class_start_matchalready distinguishes these shapes for the named-extraction path -- and have THE LINEAGE EXTRACTOR consult the same flag instead of a blanketpattern.groups >= 2check. 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-ishparent_entitymetadata field.