Currently, all AST objects have static factory methods that contain the actual parsing logic.
While convenient at first, it turns out, it is better for maintenance, testing and the overall design to have all AST objects available as simple DTOs.
The parsing logic should be moved into dedicated service classes of the form:
final class {ASTConceptName}Parser
{
/**
* @param \Iterator<mixed,Token> $tokens
* @return null|{ASTConceptName}Node
*/
public function parse(\Iterator $tokens): ?{ASTConceptName}Node;
}
This leads to the following acceptance criteria for each AST concept:
- There is a class
{ASTConceptName}Node that consists entirely of public, readonly, constructor-promoted properties. The constructor is public.
- There is a class
{ASTConceptName}Parser with a method parse that accepts an \Iterator of Token objects and produces a (potentially nullable) {ASTConceptName}Node
- There is a unit test for
{ASTConceptName}Parser
Currently, all AST objects have static factory methods that contain the actual parsing logic.
While convenient at first, it turns out, it is better for maintenance, testing and the overall design to have all AST objects available as simple DTOs.
The parsing logic should be moved into dedicated service classes of the form:
This leads to the following acceptance criteria for each AST concept:
{ASTConceptName}Nodethat consists entirely of public, readonly, constructor-promoted properties. The constructor is public.{ASTConceptName}Parserwith a methodparsethat accepts an\IteratorofTokenobjects and produces a (potentially nullable){ASTConceptName}Node{ASTConceptName}Parser