Skip to content

Commit 5281422

Browse files
committed
Improve reference contexts
1 parent 75e9c75 commit 5281422

1 file changed

Lines changed: 101 additions & 80 deletions

File tree

tools/gen_filerefmap.php

Lines changed: 101 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function validateParams(string $constructor, bool $isCons, array $params)
3333
Assert::notFalse($data, "Constructor or method not found for $constructor");
3434
foreach ($data['params'] as $param) {
3535
if (!isset($params[$param['name']])) {
36-
if (isset($param['pow'])) {
36+
if (isset($param['pow']) || $param['name'] === 'flags') {
3737
continue;
3838
}
3939
throw new AssertionError("Mandatory parameter {$param['name']} not found in constructor or method $constructor");
@@ -58,7 +58,7 @@ public function validateParams(string $constructor, bool $isCons, array $params)
5858
public function getTypeAtPosition(SimpleExtractorOp $_path): string
5959
{
6060
if ($_path instanceof ExtractFromHereOp) {
61-
Assert::eq($this->position, $_path->path[0], "Current constructor {$this->position} does not match expected constructor {$_path->path[0]}");
61+
Assert::eq($this->position, $_path->path[0], "getTypeAtPosition: Current constructor {$this->position} does not match expected constructor {$_path->path[0]}");
6262
}
6363
$path = $_path->path;
6464
$idx = 0;
@@ -82,9 +82,8 @@ public function getTypeAtPosition(SimpleExtractorOp $_path): string
8282
$n = $constructor['predicate'] ?? $constructor['method'];
8383
foreach ($constructor['params'] as $param) {
8484
if ($param['name'] === $path[$idx]) {
85-
Assert::false(isset($param['subtype']), "Got flag for parameter {$path[$idx]} in constructor or method $n");
8685
$hadFlag = $hadFlag || isset($param['pow']);
87-
$type = $param['type'];
86+
$type = isset($param['subtype']) ? "Vector<{$param['subtype']}>" : $param['type'];
8887
break;
8988
}
9089
}
@@ -147,6 +146,10 @@ interface ActionOp extends Op
147146

148147
final class Noop implements ActionOp
149148
{
149+
public function __construct(private readonly string $why)
150+
{
151+
}
152+
150153
public function getType(TLContext $tl): string
151154
{
152155
return '';
@@ -164,7 +167,7 @@ public function normalize(array $stack): ?Op
164167

165168
public function build(TLContext $tl): array
166169
{
167-
return ['op' => 'noop'];
170+
return ['op' => 'noop', 'why' => $this->why];
168171
}
169172
}
170173

@@ -348,15 +351,14 @@ final class ExtractStickerSetFromDocumentAttributesOp implements SimpleExtractor
348351
{
349352
public function __construct(
350353
private readonly SimpleExtractorOp $path,
351-
)
352-
{
354+
) {
353355
}
354356

355357
public function hasBackreference(): bool
356358
{
357359
return $this->path->hasBackreference();
358360
}
359-
361+
360362
public function normalize(array $stack): ?Op
361363
{
362364
$path = $this->path->normalize($stack);
@@ -368,7 +370,7 @@ public function normalize(array $stack): ?Op
368370
}
369371
return $this;
370372
}
371-
373+
372374
public function getType(TLContext $tl): string
373375
{
374376
return 'InputStickerSet';
@@ -534,15 +536,15 @@ public function hasBackreference(): bool
534536
public function normalize(array $stack): ?Op
535537
{
536538
$final = [];
537-
$isDifferent = false;
539+
$isDifferent = false;
538540
foreach ($this->values as $value) {
539541
$normalized = $value->normalize($stack);
540542
if ($normalized === null) {
541543
return null;
542544
}
543545
if ($normalized !== $value) {
544546
$isDifferent = true;
545-
}
547+
}
546548
$final[] = $normalized;
547549
}
548550
if ($isDifferent) {
@@ -573,7 +575,7 @@ final class LiteralOp implements ExtractorOrLiteralOp
573575
{
574576
public function __construct(private readonly string $type, private readonly mixed $value)
575577
{
576-
Assert::inArray($type, ['int', 'long', 'string', 'bool', 'float', '#'], "Invalid type '$type' for LiteralOp");
578+
Assert::inArray($type, ['int', 'long', 'string', 'bool', 'float'], "Invalid type '$type' for LiteralOp");
577579
}
578580

579581
public function hasBackreference(): bool
@@ -599,7 +601,7 @@ public function build(TLContext $tl): array
599601
}
600602
}
601603

602-
final class GetMessageOp implements ExtractorOrLiteralOp
604+
final class GetMessageOp implements ActionOp
603605
{
604606
public function __construct(
605607
private readonly Op $peer,
@@ -804,7 +806,6 @@ public function build(TLContext $tl): array
804806
'min_id' => new ExtractFromHereOp(['channelAdminLogEvent', 'id']),
805807
'limit' => new LiteralOp('int', 1),
806808
'q' => new LiteralOp('string', ''),
807-
'flags' => new LiteralOp('#', 0),
808809
]
809810
);
810811
$locations['bots.getPreviewInfo'][] = new CopyMethodCallOp('bots.getPreviewInfo');
@@ -834,18 +835,19 @@ public function build(TLContext $tl): array
834835
]
835836
);
836837
$locations['help.getPremiumPromo'][] = new CopyMethodCallOp('help.getPremiumPromo');
837-
foreach (TLContext::getConstructorsOfType($TL, 'StarsTransaction', false) as $method => $_) {
838-
$locations[$constructor][] = new CallOp(
839-
'payments.getStarsTransactionByID',
838+
foreach (TLContext::getConstructorsOfType($TL, 'payments.StarsStatus', true) as $method => $_) {
839+
$locations['starsTransaction'][] = new CallOp(
840+
'payments.getStarsTransactionsByID',
840841
[
841-
'peer' => new ExtractFromMethodCallOp([$constructor, 'peer']),
842-
'id' => new ConstructorOp(
842+
'peer' => new ExtractFromMethodCallOp([$method, 'peer']),
843+
...($method === 'payments.getStarsSubscriptions' ? [] : ['ton' => new ExtractFromMethodCallOp([$method, 'ton'], true)]),
844+
'id' => new ArrayOp(new ConstructorOp(
843845
'inputStarsTransaction',
844846
[
845-
'id' => new ExtractFromHereOp([$constructor, 'id']),
846-
'refund' => new ExtractFromHereOp([$constructor, 'refund']),
847+
'id' => new ExtractFromHereOp(['starsTransaction', 'id']),
848+
'refund' => new ExtractFromHereOp(['starsTransaction', 'refund'], true),
847849
]
848-
),
850+
)),
849851
]
850852
);
851853
}
@@ -947,7 +949,7 @@ public function build(TLContext $tl): array
947949
'limit' => new LiteralOp('int', 1),
948950
]
949951
);
950-
foreach (['photos.updateProfilePhoto', 'photos.updateProfilePhoto'] as $method) {
952+
foreach (['photos.updateProfilePhoto', 'photos.uploadProfilePhoto'] as $method) {
951953
$locations['photo'][] = new CallOp(
952954
'photos.getUserPhotos',
953955
[
@@ -965,6 +967,19 @@ public function build(TLContext $tl): array
965967
]
966968
);
967969
}
970+
$locations['photo'][] = new CallOp(
971+
'photos.getUserPhotos',
972+
[
973+
'user_id' => new ExtractFromMethodCallOp(
974+
['photos.uploadContactProfilePhoto', 'user_id'],
975+
),
976+
'offset' => new LiteralOp('int', -1),
977+
'max_id' => new ExtractFromHereOp(['photo', 'id']),
978+
'limit' => new LiteralOp('int', 1),
979+
]
980+
);
981+
982+
$locations['messages.uploadMedia'][]= new Noop('A freshly uploaded media file will obtain a context only once it is sent to a chat');
968983

969984
$locations['document'][] = new CallOp(
970985
'messages.getStickerSet',
@@ -974,69 +989,49 @@ public function build(TLContext $tl): array
974989
]
975990
);
976991
$locations['messages.getDocumentByHash'][] = new CopyMethodCallOp('messages.getDocumentByHash');
992+
$locations['updateServiceNotification'][] = new Noop('Cannot refetch service notifications');
977993

978994
// Ignore these for now
979995
foreach (['payments.ResaleStarGifts', 'payments.StarGiftUpgradePreview', 'StarGift'] as $type) {
980996
foreach (TLContext::getConstructorsOfType($TL, $type, false) as $constructor => $_) {
981-
$locations[$constructor][] = new Noop();
997+
$locations[$constructor][] = new Noop('Contexts for star gifts are not yet implemented');
982998
}
983999
}
9841000

985-
$recurse = static function (Closure $earlyReturn, Closure $onStackEnd, string $type, array $stack = []) use ($TL, &$recurse): void {
986-
if ($earlyReturn($type)) {
987-
return;
988-
}
1001+
$recurse = static function (Closure $onStackEnd, string $type, array &$stack, array &$stackTypes) use ($TL, &$recurse): void {
9891002
$pos = count($stack);
9901003
$found = false;
9911004
foreach ([...$TL->getConstructors()->by_id, ...$TL->getMethods()->by_id] as $constructor) {
9921005
$name = $constructor['predicate'] ?? $constructor['method'];
1006+
$t = $constructor['type'];
1007+
if (isset($stackTypes[$t])) {
1008+
continue;
1009+
}
1010+
$stackTypes[$t] = true;
9931011
foreach ($constructor['params'] as $param) {
994-
if ($param['type'] === $type && !in_array($name, $stack, true)) {
1012+
if ((
1013+
$param['type'] === $type ||
1014+
($param['subtype'] ?? null) === $type
1015+
)) {
9951016
$stack[$pos] = $name;
996-
$recurse($earlyReturn, $onStackEnd, $constructor['type'], $stack);
997-
$found = true;
998-
}
999-
if (isset($param['subtype'])
1000-
&& $param['subtype'] === $type
1001-
&& !in_array($name, $stack, true)
1002-
) {
1003-
$stack[$pos] = $name;
1004-
$recurse($earlyReturn, $onStackEnd, $constructor['type'], $stack);
1017+
$recurse($onStackEnd, $t, $stack, $stackTypes);
10051018
$found = true;
1019+
unset($stack[$pos]);
10061020
}
10071021
}
1022+
unset($stackTypes[$t]);
10081023
}
1009-
unset($stack[$pos]);
1010-
if (!$found
1011-
|| $type === 'Update'
1012-
|| $type === 'Updates'
1013-
|| TLContext::getConstructorsOfType($TL, $type, true, true)
1014-
) {
1015-
if (
1016-
(
1017-
in_array($stack[0], ['photo', 'document'], true)
1018-
&& ($stack[1] ?? null) === 'game'
1019-
&& in_array(end($stack), [
1020-
'messages.webPagePreview',
1021-
'payments.starsStatus',
1022-
'messages.invitedUsers',
1023-
'payments.paymentResult',
1024-
], true)
1025-
) || array_intersect(
1026-
[
1027-
'updateServiceNotification',
1028-
'updateShortSentMessage',
1029-
'updateShortMessage',
1030-
'updateShortChatMessage',
1031-
],
1032-
$stack,
1033-
) || end($stack) === 'messages.webPagePreview'
1034-
|| end($stack) === 'help.appUpdate'
1035-
) {
1036-
return;
1024+
if (!$found) {
1025+
foreach (TLContext::getConstructorsOfType($TL, $type, true, true) as $method => $data) {
1026+
$stack[$pos] = $method;
1027+
$onStackEnd($stack);
10371028
}
1029+
unset($stack[$pos]);
1030+
} elseif ($type === 'Update') {
1031+
unset($stack[$pos]);
10381032
$onStackEnd($stack);
10391033
}
1034+
10401035
};
10411036

10421037
$fileRefs = ['Document' => 'document', 'Photo' => 'photo'];
@@ -1077,23 +1072,56 @@ public function build(TLContext $tl): array
10771072
}
10781073
$locationTypes = array_filter($locationTypes);
10791074

1075+
foreach ($locations as $constructor => $ops) {
1076+
var_dump("Processing $constructor");
1077+
foreach ($ops as $op) {
1078+
$op->build(new TLContext($TL, $constructor));
1079+
}
1080+
}
1081+
var_dump("Finished initial validation");
1082+
10801083
$normalizedLocations = [];
10811084

10821085
foreach ($fileRefs as $type => $constructor) {
1086+
$stack = [$constructor];
1087+
$stackTypes = [$type => true];
10831088
$recurse(
1084-
static fn (string $type) => false,//isset($locationTypes[$type]),
10851089
static function (array $stack) use ($locations): void {
1086-
$stack = array_reverse($stack);
1090+
if (end($stack) === 'messages.getWebPagePreview'
1091+
|| end($stack) === 'help.appUpdate'
1092+
|| (
1093+
in_array($stack[0], ['photo', 'document'], true)
1094+
&& ($stack[1] ?? null) === 'game'
1095+
&& in_array(end($stack), [
1096+
'messages.getWebPagePreview',
1097+
'messages.invitedUsers',
1098+
'payments.paymentResult',
1099+
], true)
1100+
) || array_intersect(
1101+
[
1102+
'updateServiceNotification',
1103+
'updateShortSentMessage',
1104+
'updateShortMessage',
1105+
'updateShortChatMessage',
1106+
],
1107+
$stack,
1108+
)
1109+
) {
1110+
return;
1111+
}
1112+
$slice = [];
10871113
$had = false;
1088-
foreach ($stack as $constructor) {
1114+
for ($x = count($stack)-1; $x >= 0; $x--) {
1115+
$constructor = $stack[$x];
1116+
$slice[] = $constructor;
10891117
if (isset($locations[$constructor])) {
10901118
foreach ($locations[$constructor] as $op) {
1091-
$normalized = $op->normalize($stack);
1119+
$normalized = $op->normalize($slice);
10921120
if ($normalized === null) {
10931121
continue;
10941122
}
10951123
$had = true;
1096-
$normalizedLocations[$constructor] = $normalized;
1124+
$normalizedLocations[$constructor][] = $normalized;
10971125
}
10981126
}
10991127
}
@@ -1102,14 +1130,7 @@ static function (array $stack) use ($locations): void {
11021130
}
11031131
},
11041132
$type,
1105-
[$constructor]
1133+
$stack,
1134+
$stackTypes,
11061135
);
11071136
}
1108-
die;
1109-
1110-
foreach ($locations as $constructor => $ops) {
1111-
var_dump("Processing $constructor");
1112-
foreach ($ops as $op) {
1113-
var_dump([$constructor, $op->build(new TLContext($TL, $constructor))]);
1114-
}
1115-
}

0 commit comments

Comments
 (0)