@@ -337,30 +337,73 @@ public function getDefaultValueString(): string {
337
337
}
338
338
}
339
339
340
- class FunctionName {
341
- /** @var string|null */
340
+ interface FunctionOrMethodName {
341
+ public function getDeclaration (): string ;
342
+ public function getArgInfoName (): string ;
343
+ public function __toString (): string ;
344
+ }
345
+
346
+ class FunctionName implements FunctionOrMethodName {
347
+ /** @var Name */
348
+ private $ name ;
349
+
350
+ public function __construct (Name $ name ) {
351
+ $ this ->name = $ name ;
352
+ }
353
+
354
+ public function getNamespace (): ?string {
355
+ if ($ this ->name ->isQualified ()) {
356
+ return $ this ->name ->slice (0 , -1 )->toString ();
357
+ }
358
+ return null ;
359
+ }
360
+
361
+ public function getShortName (): string {
362
+ return $ this ->name ->getLast ();
363
+ }
364
+
365
+ public function getNonNamespacedName (): string {
366
+ if ($ this ->name ->isQualified ()) {
367
+ throw new Exception ("Namespaced name not supported here " );
368
+ }
369
+ return $ this ->name ->toString ();
370
+ }
371
+
372
+ public function getDeclaration (): string {
373
+ return "ZEND_FUNCTION( {$ this ->name ->getLast ()}); \n" ;
374
+ }
375
+
376
+ public function getArgInfoName (): string {
377
+ $ underscoreName = implode ('_ ' , $ this ->name ->parts );
378
+ return "arginfo_ $ underscoreName " ;
379
+ }
380
+
381
+ public function __toString (): string {
382
+ return $ this ->name ->toString ();
383
+ }
384
+ }
385
+
386
+ class MethodName implements FunctionOrMethodName {
387
+ /** @var string */
342
388
public $ className ;
343
389
/** @var string */
344
390
public $ name ;
345
391
346
- public function __construct (?string $ className , string $ name )
347
- {
392
+ public function __construct (string $ className , string $ name ) {
348
393
$ this ->className = $ className ;
349
394
$ this ->name = $ name ;
350
395
}
351
396
352
- public function getDeclaration (): string
353
- {
354
- if ($ this ->className ) {
355
- return "ZEND_METHOD( $ this ->className , $ this ->name ); \n" ;
356
- }
397
+ public function getDeclaration (): string {
398
+ return "ZEND_METHOD( $ this ->className , $ this ->name ); \n" ;
399
+ }
357
400
358
- return "ZEND_FUNCTION( $ this ->name ); \n" ;
401
+ public function getArgInfoName (): string {
402
+ return "arginfo_class_ {$ this ->className }_ {$ this ->name }" ;
359
403
}
360
404
361
- public function __toString ()
362
- {
363
- return $ this ->className ? "$ this ->className :: $ this ->name " : $ this ->name ;
405
+ public function __toString (): string {
406
+ return "$ this ->className :: $ this ->name " ;
364
407
}
365
408
}
366
409
@@ -382,7 +425,7 @@ public function equals(ReturnInfo $other): bool {
382
425
}
383
426
384
427
class FuncInfo {
385
- /** @var FunctionName */
428
+ /** @var FunctionOrMethodName */
386
429
public $ name ;
387
430
/** @var int */
388
431
public $ flags ;
@@ -402,10 +445,10 @@ class FuncInfo {
402
445
public $ cond ;
403
446
404
447
public function __construct (
405
- FunctionName $ name ,
448
+ FunctionOrMethodName $ name ,
406
449
int $ flags ,
407
450
?string $ aliasType ,
408
- ?FunctionName $ alias ,
451
+ ?FunctionOrMethodName $ alias ,
409
452
bool $ isDeprecated ,
410
453
array $ args ,
411
454
ReturnInfo $ return ,
@@ -440,10 +483,7 @@ public function equalsApartFromName(FuncInfo $other): bool {
440
483
}
441
484
442
485
public function getArgInfoName (): string {
443
- if ($ this ->name ->className ) {
444
- return 'arginfo_class_ ' . $ this ->name ->className . '_ ' . $ this ->name ->name ;
445
- }
446
- return 'arginfo_ ' . $ this ->name ->name ;
486
+ return $ this ->name ->getArgInfoName ();
447
487
}
448
488
449
489
public function getDeclarationKey (): string
@@ -465,18 +505,21 @@ public function getDeclaration(): ?string
465
505
}
466
506
467
507
public function getFunctionEntry (): string {
468
- if ($ this ->name -> className ) {
508
+ if ($ this ->name instanceof MethodName ) {
469
509
if ($ this ->alias ) {
470
- if ($ this ->alias -> className ) {
510
+ if ($ this ->alias instanceof MethodName ) {
471
511
return sprintf (
472
512
"\tZEND_MALIAS(%s, %s, %s, %s, %s) \n" ,
473
513
$ this ->alias ->className , $ this ->name ->name , $ this ->alias ->name , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
474
514
);
475
- } else {
515
+ } else if ( $ this -> alias instanceof FunctionName) {
476
516
return sprintf (
477
517
"\tZEND_ME_MAPPING(%s, %s, %s, %s) \n" ,
478
- $ this ->name ->name , $ this ->alias ->name , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
518
+ $ this ->name ->name , $ this ->alias ->getNonNamespacedName (),
519
+ $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
479
520
);
521
+ } else {
522
+ throw new Error ("Cannot happen " );
480
523
}
481
524
} else {
482
525
if ($ this ->flags & Class_::MODIFIER_ABSTRACT ) {
@@ -491,26 +534,37 @@ public function getFunctionEntry(): string {
491
534
$ this ->name ->className , $ this ->name ->name , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
492
535
);
493
536
}
494
- } else {
537
+ } else if ($ this ->name instanceof FunctionName) {
538
+ $ namespace = $ this ->name ->getNamespace ();
539
+ $ shortName = $ this ->name ->getShortName ();
540
+
495
541
if ($ this ->alias && $ this ->isDeprecated ) {
496
542
return sprintf (
497
543
"\tZEND_DEP_FALIAS(%s, %s, %s) \n" ,
498
- $ this -> name , $ this ->alias ->name , $ this ->getArgInfoName ()
544
+ $ shortName , $ this ->alias ->getNonNamespacedName () , $ this ->getArgInfoName ()
499
545
);
500
546
}
501
547
502
548
if ($ this ->alias ) {
503
549
return sprintf (
504
550
"\tZEND_FALIAS(%s, %s, %s) \n" ,
505
- $ this -> name , $ this ->alias ->name , $ this ->getArgInfoName ()
551
+ $ shortName , $ this ->alias ->getNonNamespacedName () , $ this ->getArgInfoName ()
506
552
);
507
553
}
508
554
509
555
if ($ this ->isDeprecated ) {
510
- return sprintf ("\tZEND_DEP_FE(%s, %s) \n" , $ this -> name , $ this ->getArgInfoName ());
556
+ return sprintf ("\tZEND_DEP_FE(%s, %s) \n" , $ shortName , $ this ->getArgInfoName ());
511
557
}
512
558
513
- return sprintf ("\tZEND_FE(%s, %s) \n" , $ this ->name , $ this ->getArgInfoName ());
559
+ if ($ namespace ) {
560
+ return sprintf (
561
+ "\tZEND_NS_FE( \"%s \", %s, %s) \n" ,
562
+ $ namespace , $ shortName , $ this ->getArgInfoName ());
563
+ } else {
564
+ return sprintf ("\tZEND_FE(%s, %s) \n" , $ shortName , $ this ->getArgInfoName ());
565
+ }
566
+ } else {
567
+ throw new Error ("Cannot happen " );
514
568
}
515
569
}
516
570
@@ -565,18 +619,11 @@ public function __construct(string $name, array $funcInfos) {
565
619
566
620
class FileInfo {
567
621
/** @var FuncInfo[] */
568
- public $ funcInfos ;
622
+ public $ funcInfos = [] ;
569
623
/** @var ClassInfo[] */
570
- public $ classInfos ;
624
+ public $ classInfos = [] ;
571
625
/** @var bool */
572
- public $ generateFunctionEntries ;
573
-
574
- public function __construct (
575
- array $ funcInfos , array $ classInfos , bool $ generateFunctionEntries ) {
576
- $ this ->funcInfos = $ funcInfos ;
577
- $ this ->classInfos = $ classInfos ;
578
- $ this ->generateFunctionEntries = $ generateFunctionEntries ;
579
- }
626
+ public $ generateFunctionEntries = false ;
580
627
581
628
/**
582
629
* @return iterable<FuncInfo>
@@ -646,7 +693,7 @@ function parseDocComment(DocComment $comment): array {
646
693
647
694
function parseFunctionLike (
648
695
PrettyPrinterAbstract $ prettyPrinter ,
649
- FunctionName $ name ,
696
+ FunctionOrMethodName $ name ,
650
697
int $ flags ,
651
698
Node \FunctionLike $ func ,
652
699
?string $ cond
@@ -672,9 +719,9 @@ function parseFunctionLike(
672
719
$ aliasType = $ tag ->name ;
673
720
$ aliasParts = explode (":: " , $ tag ->getValue ());
674
721
if (count ($ aliasParts ) === 1 ) {
675
- $ alias = new FunctionName (null , $ aliasParts [0 ]);
722
+ $ alias = new FunctionName (new Name ( $ aliasParts [0 ]) );
676
723
} else {
677
- $ alias = new FunctionName ($ aliasParts [0 ], $ aliasParts [1 ]);
724
+ $ alias = new MethodName ($ aliasParts [0 ], $ aliasParts [1 ]);
678
725
}
679
726
} else if ($ tag ->name === 'deprecated ' ) {
680
727
$ isDeprecated = true ;
@@ -814,46 +861,27 @@ function getFileDocComment(array $stmts): ?DocComment {
814
861
return null ;
815
862
}
816
863
817
- function parseStubFile (string $ code ): FileInfo {
818
- $ lexer = new PhpParser \Lexer ();
819
- $ parser = new PhpParser \Parser \Php7 ($ lexer );
820
- $ nodeTraverser = new PhpParser \NodeTraverser ;
821
- $ nodeTraverser ->addVisitor (new PhpParser \NodeVisitor \NameResolver );
822
- $ prettyPrinter = new class extends Standard {
823
- protected function pName_FullyQualified (Name \FullyQualified $ node ) {
824
- return implode ('\\' , $ node ->parts );
825
- }
826
- };
827
-
828
- $ stmts = $ parser ->parse ($ code );
829
- $ nodeTraverser ->traverse ($ stmts );
830
-
831
- $ generateFunctionEntries = false ;
832
- $ fileDocComment = getFileDocComment ($ stmts );
833
- if ($ fileDocComment ) {
834
- if (strpos ($ fileDocComment ->getText (), '@generate-function-entries ' ) !== false ) {
835
- $ generateFunctionEntries = true ;
836
- }
837
- }
838
-
839
- $ funcInfos = [];
840
- $ classInfos = [];
864
+ function handleStatements (FileInfo $ fileInfo , array $ stmts , PrettyPrinterAbstract $ prettyPrinter ) {
841
865
$ conds = [];
842
866
foreach ($ stmts as $ stmt ) {
843
- $ cond = handlePreprocessorConditions ($ conds , $ stmt );
844
867
if ($ stmt instanceof Stmt \Nop) {
845
868
continue ;
846
869
}
847
870
871
+ if ($ stmt instanceof Stmt \Namespace_) {
872
+ handleStatements ($ fileInfo , $ stmt ->stmts , $ prettyPrinter );
873
+ continue ;
874
+ }
875
+
876
+ $ cond = handlePreprocessorConditions ($ conds , $ stmt );
848
877
if ($ stmt instanceof Stmt \Function_) {
849
- $ funcInfos [] = parseFunctionLike (
878
+ $ fileInfo -> funcInfos [] = parseFunctionLike (
850
879
$ prettyPrinter ,
851
- new FunctionName (null , $ stmt ->name -> toString () ),
880
+ new FunctionName ($ stmt ->namespacedName ),
852
881
0 ,
853
882
$ stmt ,
854
883
$ cond
855
884
);
856
-
857
885
continue ;
858
886
}
859
887
@@ -881,21 +909,45 @@ protected function pName_FullyQualified(Name\FullyQualified $node) {
881
909
882
910
$ methodInfos [] = parseFunctionLike (
883
911
$ prettyPrinter ,
884
- new FunctionName ($ className , $ classStmt ->name ->toString ()),
912
+ new MethodName ($ className , $ classStmt ->name ->toString ()),
885
913
$ flags ,
886
914
$ classStmt ,
887
915
$ cond
888
916
);
889
917
}
890
918
891
- $ classInfos [] = new ClassInfo ($ className , $ methodInfos );
919
+ $ fileInfo -> classInfos [] = new ClassInfo ($ className , $ methodInfos );
892
920
continue ;
893
921
}
894
922
895
923
throw new Exception ("Unexpected node {$ stmt ->getType ()}" );
896
924
}
925
+ }
926
+
927
+ function parseStubFile (string $ code ): FileInfo {
928
+ $ lexer = new PhpParser \Lexer ();
929
+ $ parser = new PhpParser \Parser \Php7 ($ lexer );
930
+ $ nodeTraverser = new PhpParser \NodeTraverser ;
931
+ $ nodeTraverser ->addVisitor (new PhpParser \NodeVisitor \NameResolver );
932
+ $ prettyPrinter = new class extends Standard {
933
+ protected function pName_FullyQualified (Name \FullyQualified $ node ) {
934
+ return implode ('\\' , $ node ->parts );
935
+ }
936
+ };
937
+
938
+ $ stmts = $ parser ->parse ($ code );
939
+ $ nodeTraverser ->traverse ($ stmts );
940
+
941
+ $ fileInfo = new FileInfo ;
942
+ $ fileDocComment = getFileDocComment ($ stmts );
943
+ if ($ fileDocComment ) {
944
+ if (strpos ($ fileDocComment ->getText (), '@generate-function-entries ' ) !== false ) {
945
+ $ fileInfo ->generateFunctionEntries = true ;
946
+ }
947
+ }
897
948
898
- return new FileInfo ($ funcInfos , $ classInfos , $ generateFunctionEntries );
949
+ handleStatements ($ fileInfo , $ stmts , $ prettyPrinter );
950
+ return $ fileInfo ;
899
951
}
900
952
901
953
function funcInfoToCode (FuncInfo $ funcInfo ): string {
0 commit comments