DEV Community

CrabPascal
CrabPascal

Posted on

Properties with Getters and Setters in CrabPascal (v2.14.0) | Properties com getters e setters no CrabPascal (v2.14.0)

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

Properties with Getters and Setters in CrabPascal (v2.14.0)

Delphi classes expose state through properties, not public fields. Sprint 6 (v2.14.0) wired properties end-to-end: parser AST, semantic binding, and runtime read/write with backing fields.

Classic backing-field property

type
  TCounter = class
  private
    FValue: Integer;
  public
    constructor Create;
    property Value: Integer read FValue write FValue;
  end;

constructor TCounter.Create;
begin
  inherited;
  FValue := 0;
end;
Enter fullscreen mode Exit fullscreen mode

Usage looks like a field but respects encapsulation:

var
  C: TCounter;
begin
  C := TCounter.Create;
  try
    C.Value := 42;
    WriteLn(C.Value);
  finally
    C.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Semantic typing matters

A subtle bug during development showed why infer_lvalue_type must understand properties. Assignment C.Value := N needs the type of Value, not the type of C. Without that, semantic errors pointed at the wrong symbol or accepted invalid assignments.

Run check before run:

crab-pascal check tests/fixtures/class_property.pas
Enter fullscreen mode Exit fullscreen mode

Parser support

Visibility sections now populate properties in the AST — public, private, and published blocks parse read/write clauses. Sprint 6 MVP focused on direct field backing (read F write F). Method-based getters (read GetValue) expanded in later sprints.

Runtime model

  • class_fields and class_properties tables on each class.
  • read_object_property / write_object_property dispatch at runtime.
  • TClass.Create generic constructor on the VMT allocates and initializes fields.

Test coverage

cargo test --test properties_runtime
Enter fullscreen mode Exit fullscreen mode

The fixture class_property.pas exercises read and write through a property named Value.

Codegen caveat

Property access in build-exe mode remained technical debt after Sprint 6. Application code using properties worked in run; native binaries caught up in parity sprints. Always verify critical paths with:

cargo test --test run_build_parity
Enter fullscreen mode Exit fullscreen mode

Design lesson

Properties are syntactic sugar with semantic teeth. They affect overload resolution, visibility, and assignment compatibility. Shipping them in Sprint 6 unlocked TStringList-style indexed properties later and made ported Delphi business objects compile with less rewriting.

If you maintain legacy Delphi DTOs with dozens of properties, v2.14.0 is the release where CrabPascal stops forcing you to replace them with public fields "just to make it run."


Português {#portugus}

Properties com getters e setters no CrabPascal (v2.14.0)

Classes Delphi expõem estado via properties, não campos públicos. A Sprint 6 (v2.14.0) ligou properties de ponta a ponta: AST do parser, binding semântico e leitura/escrita no runtime com backing fields.

Property clássica com backing field

type
  TCounter = class
  private
    FValue: Integer;
  public
    constructor Create;
    property Value: Integer read FValue write FValue;
  end;

constructor TCounter.Create;
begin
  inherited;
  FValue := 0;
end;
Enter fullscreen mode Exit fullscreen mode

O uso parece campo, mas respeita encapsulamento:

var
  C: TCounter;
begin
  C := TCounter.Create;
  try
    C.Value := 42;
    WriteLn(C.Value);
  finally
    C.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Tipagem semântica importa

Um bug sutil durante o desenvolvimento mostrou por que infer_lvalue_type precisa entender properties. A atribuição C.Value := N exige o tipo de Value, não o tipo de C. Sem isso, erros semânticos apontavam para o símbolo errado ou aceitavam atribuições inválidas.

Rode check antes de run:

crab-pascal check tests/fixtures/class_property.pas
Enter fullscreen mode Exit fullscreen mode

Suporte no parser

Seções de visibilidade agora preenchem properties na AST — blocos public, private e published parseiam cláusulas read/write. O MVP da Sprint 6 focou backing field direto (read F write F). Getters baseados em método (read GetValue) expandiram em sprints posteriores.

Modelo de runtime

  • Tabelas class_fields e class_properties em cada classe.
  • read_object_property / write_object_property fazem dispatch em runtime.
  • Construtor genérico TClass.Create na VMT aloca e inicializa fields.

Cobertura de testes

cargo test --test properties_runtime
Enter fullscreen mode Exit fullscreen mode

O fixture class_property.pas exercita leitura e escrita via property Value.

Ressalva de codegen

Acesso a properties no modo build-exe permaneceu débito técnico após a Sprint 6. Código de aplicação com properties funcionava no run; binários nativos alcançaram paridade nas sprints de paridade. Sempre valide caminhos críticos com:

cargo test --test run_build_parity
Enter fullscreen mode Exit fullscreen mode

Lição de design

Properties são açúcar sintático com dentes semânticos. Afetam resolução de overload, visibilidade e compatibilidade de atribuição. Entregá-las na Sprint 6 destravou properties indexadas estilo TStringList depois e fez DTOs Delphi portados compilarem com menos reescrita.

Se você mantém DTOs Delphi legados com dezenas de properties, a v2.14.0 é a release em que o CrabPascal para de forçar substituí-los por campos públicos "só para rodar".


Published on dev.to/@crabpascal · Código em CrabPascal

Top comments (0)