Skip to content

Generic class constructor with generic-typed default parameter (= nil) fails to parse #347

Description

@mksjgj

Summary
DelphiAST cannot parse a syntactically valid unit where a generic class
constructor
has a parameter whose type depends on the generic parameter and a
default value, e.g. constructor Create(AFinProc: TProc<T> = nil);.
Removing = nil makes the identical unit parse fine.

Minimal reproducer (Repr.pas)

unit Repr;
interface
uses
  SysUtils;
type
  C<T> = class
    constructor Create(AFinProc: TProc<T> = nil);
  end;
implementation
end.

How to reproduce with DelphiAST
program t;
{$APPTYPE CONSOLE}
uses
  DelphiAST, DelphiAST.Classes;
var
  AST: TSyntaxNode;
begin
  try
    AST := TPasSyntaxTreeBuilder.Run('Repr.pas', False);
    Writeln('parsed OK');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);   // parse error
  end;
end.

Control (Ctrl.pas, parses fine — only = nil removed)
unit Ctrl;
interface
uses
  SysUtils;
type
  C<T> = class
    constructor Create(AFinProc: TProc<T>);
  end;
implementation
end.

Narrowing (all tested individually, only the failing combo fails)
- AFinProc: TProc<T> = nil (default on generic-typed param) → fails
- AFinProc: TProc<T> (no default) → parses
- FinType: Integer = 0 (default on non-generic param) → parses
- plain generic class / generic method / record with generic field / class helper /
  untyped const/out param / BOM / {$IFDEF} / {$IF CompilerVersion<36} /
  (* *) comments → all parse fine

Why it matters
I discovered this through a tool (delphi-indexer) that embeds DelphiAST: real
units using this pattern parse to 0 nodes and are silently dropped from the
index (e.g. TResHolder<T> = class(TInterfacedObject, IResHolder<T>) with
constructor Create(..., AFinProc: TProc<T> = nil);), leaving whole libraries
unsearchable. I assume the fault is in how the parser handles a default value
on a parameter whose type references the enclosing generic type.

Environment: Delphi 12.3 · DelphiAST current (bundled version in delphi-indexer).
Happy to help test a fix or provide the exact DelphiAST version/commit.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions