@@ -32,19 +32,19 @@ final class Ast implements BuildMode
3232{
3333 /** @var array<string, array{name: string, type: string}> */
3434 public array $ stored = [];
35- /** @var array<string, true > */
35+ /** @var array<string, string > */
3636 public array $ storedNames = [];
3737 public int $ storedFlags = 0 ;
3838
3939 public ?string $ curKey = null ;
4040
4141 private array $ output = [];
42- private array $ outputSchema = [];
4342 private ?string $ needsParent = null ;
4443
4544 public function __construct (
4645 public readonly bool $ allowBackrefs ,
4746 public readonly bool $ allowUnpacking ,
47+ private array $ outputSchema = []
4848 ) {
4949 }
5050
@@ -62,6 +62,15 @@ public function getOutput(): string
6262 return $ serialized ;
6363 }
6464
65+ private static function stringifySchema (string $ constructor , array $ params ): string
66+ {
67+ $ paramsStr = "$ constructor " ;
68+ foreach ($ params as $ name => $ type ) {
69+ $ paramsStr .= "$ name: $ type " ;
70+ }
71+ $ paramsStr .= '= FileSource; ' ;
72+ return $ paramsStr ;
73+ }
6574 public function addNode (TLContext $ ctx , ?array $ action = null , ?string $ why = null ): void
6675 {
6776 $ out = [
@@ -80,24 +89,38 @@ public function addNode(TLContext $ctx, ?array $action = null, ?string $why = nu
8089
8190 $ constructor = $ action ['stored_constructor ' ];
8291
83- $ paramsStr = $ this ->storedFlags ? " $ constructor flags:# " : " $ constructor " ;
84- foreach ($ this ->stored as $ param ) {
85- $ paramsStr .= "{ $ param [ ' name ' ]} : { $ param [ ' type ' ]} " ;
92+ $ names = $ this ->storedNames ;
93+ if ($ this ->storedFlags ) {
94+ $ names [ ' flags ' ] = ' # ' ;
8695 }
87- $ paramsStr .= '= FileSource; ' ;
88-
89- $ this ->storedFlags = 0 ;
90- $ this ->stored = [];
91- $ this ->storedNames = [];
9296
9397 if (isset ($ this ->outputSchema [$ constructor ])) {
94- if ($ this ->outputSchema [$ constructor ] !== $ paramsStr ) {
95- echo ("Existing schema for $ constructor ( {$ this ->outputSchema [$ constructor ]}) does not match newly generated schema $ paramsStr \n" );
98+ foreach ($ this ->outputSchema [$ constructor ] as $ name => $ type ) {
99+ if (isset ($ names [$ name ])) {
100+ if ($ names [$ name ] === $ type ) {
101+ unset($ names [$ name ]);
102+ } else {
103+ throw new AssertionError ("Type mismatch for $ constructor. $ name: have {$ names [$ name ]}, need $ type " );
104+ }
105+ } else if (str_starts_with ($ type , 'flags. ' )) {
106+ if ($ this ->storedFlags ) {
107+ throw new AssertionError ("Have conflicting flag $ constructor. $ name: $ type; new schema is " .self ::stringifySchema ($ constructor , $ names ));
108+ }
109+ } elseif ($ name !== 'flags ' ) {
110+ throw new AssertionError ("Missing pre-existing parameter $ constructor. $ name for $ constructor " );
111+ }
112+ }
113+ foreach ($ names as $ name => $ type ) {
114+ throw new AssertionError ("Leftover parameter $ constructor. $ name: $ type for $ constructor " );
96115 }
97116 } else {
98- $ this ->outputSchema [$ constructor ] = $ paramsStr ;
117+ $ this ->outputSchema [$ constructor ] = $ names ;
99118 }
100119
120+
121+ $ this ->storedFlags = 0 ;
122+ $ this ->stored = [];
123+ $ this ->storedNames = [];
101124 Assert::null ($ why );
102125 } elseif ($ why !== null ) {
103126 $ out ['action ' ] = ['_ ' => 'noOp ' , 'why ' => $ why ];
0 commit comments