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;
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.
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
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_fieldsandclass_propertiestables on each class. -
read_object_property/write_object_propertydispatch at runtime. -
TClass.Creategeneric constructor on the VMT allocates and initializes fields.
Test coverage
cargo test --test properties_runtime
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
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;
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.
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
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_fieldseclass_propertiesem cada classe. -
read_object_property/write_object_propertyfazem dispatch em runtime. - Construtor genérico
TClass.Createna VMT aloca e inicializa fields.
Cobertura de testes
cargo test --test properties_runtime
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
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)