@@ -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,13 @@ 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 ;
627
+ /** @var string */
628
+ public $ declarationPrefix = "" ;
580
629
581
630
/**
582
631
* @return iterable<FuncInfo>
@@ -646,7 +695,7 @@ function parseDocComment(DocComment $comment): array {
646
695
647
696
function parseFunctionLike (
648
697
PrettyPrinterAbstract $ prettyPrinter ,
649
- FunctionName $ name ,
698
+ FunctionOrMethodName $ name ,
650
699
int $ flags ,
651
700
Node \FunctionLike $ func ,
652
701
?string $ cond
@@ -672,9 +721,9 @@ function parseFunctionLike(
672
721
$ aliasType = $ tag ->name ;
673
722
$ aliasParts = explode (":: " , $ tag ->getValue ());
674
723
if (count ($ aliasParts ) === 1 ) {
675
- $ alias = new FunctionName (null , $ aliasParts [0 ]);
724
+ $ alias = new FunctionName (new Name ( $ aliasParts [0 ]) );
676
725
} else {
677
- $ alias = new FunctionName ($ aliasParts [0 ], $ aliasParts [1 ]);
726
+ $ alias = new MethodName ($ aliasParts [0 ], $ aliasParts [1 ]);
678
727
}
679
728
} else if ($ tag ->name === 'deprecated ' ) {
680
729
$ isDeprecated = true ;
@@ -814,46 +863,27 @@ function getFileDocComment(array $stmts): ?DocComment {
814
863
return null ;
815
864
}
816
865
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 = [];
866
+ function handleStatements (FileInfo $ fileInfo , array $ stmts , PrettyPrinterAbstract $ prettyPrinter ) {
841
867
$ conds = [];
842
868
foreach ($ stmts as $ stmt ) {
843
- $ cond = handlePreprocessorConditions ($ conds , $ stmt );
844
869
if ($ stmt instanceof Stmt \Nop) {
845
870
continue ;
846
871
}
847
872
873
+ if ($ stmt instanceof Stmt \Namespace_) {
874
+ handleStatements ($ fileInfo , $ stmt ->stmts , $ prettyPrinter );
875
+ continue ;
876
+ }
877
+
878
+ $ cond = handlePreprocessorConditions ($ conds , $ stmt );
848
879
if ($ stmt instanceof Stmt \Function_) {
849
- $ funcInfos [] = parseFunctionLike (
880
+ $ fileInfo -> funcInfos [] = parseFunctionLike (
850
881
$ prettyPrinter ,
851
- new FunctionName (null , $ stmt ->name -> toString () ),
882
+ new FunctionName ($ stmt ->namespacedName ),
852
883
0 ,
853
884
$ stmt ,
854
885
$ cond
855
886
);
856
-
857
887
continue ;
858
888
}
859
889
@@ -881,21 +911,49 @@ protected function pName_FullyQualified(Name\FullyQualified $node) {
881
911
882
912
$ methodInfos [] = parseFunctionLike (
883
913
$ prettyPrinter ,
884
- new FunctionName ($ className , $ classStmt ->name ->toString ()),
914
+ new MethodName ($ className , $ classStmt ->name ->toString ()),
885
915
$ flags ,
886
916
$ classStmt ,
887
917
$ cond
888
918
);
889
919
}
890
920
891
- $ classInfos [] = new ClassInfo ($ className , $ methodInfos );
921
+ $ fileInfo -> classInfos [] = new ClassInfo ($ className , $ methodInfos );
892
922
continue ;
893
923
}
894
924
895
925
throw new Exception ("Unexpected node {$ stmt ->getType ()}" );
896
926
}
927
+ }
897
928
898
- return new FileInfo ($ funcInfos , $ classInfos , $ generateFunctionEntries );
929
+ function parseStubFile (string $ code ): FileInfo {
930
+ $ lexer = new PhpParser \Lexer ();
931
+ $ parser = new PhpParser \Parser \Php7 ($ lexer );
932
+ $ nodeTraverser = new PhpParser \NodeTraverser ;
933
+ $ nodeTraverser ->addVisitor (new PhpParser \NodeVisitor \NameResolver );
934
+ $ prettyPrinter = new class extends Standard {
935
+ protected function pName_FullyQualified (Name \FullyQualified $ node ) {
936
+ return implode ('\\' , $ node ->parts );
937
+ }
938
+ };
939
+
940
+ $ stmts = $ parser ->parse ($ code );
941
+ $ nodeTraverser ->traverse ($ stmts );
942
+
943
+ $ fileInfo = new FileInfo ;
944
+ $ fileDocComment = getFileDocComment ($ stmts );
945
+ if ($ fileDocComment ) {
946
+ $ fileTags = parseDocComment ($ fileDocComment );
947
+ foreach ($ fileTags as $ tag ) {
948
+ if ($ tag ->name === 'generate-function-entries ' ) {
949
+ $ fileInfo ->generateFunctionEntries = true ;
950
+ $ fileInfo ->declarationPrefix = $ tag ->value ? $ tag ->value . " " : "" ;
951
+ }
952
+ }
953
+ }
954
+
955
+ handleStatements ($ fileInfo , $ stmts , $ prettyPrinter );
956
+ return $ fileInfo ;
899
957
}
900
958
901
959
function funcInfoToCode (FuncInfo $ funcInfo ): string {
@@ -1058,15 +1116,14 @@ function (FuncInfo $funcInfo) use(&$generatedFuncInfos) {
1058
1116
$ generatedFunctionDeclarations = [];
1059
1117
$ code .= generateCodeWithConditions (
1060
1118
$ fileInfo ->getAllFuncInfos (), "" ,
1061
- function (FuncInfo $ funcInfo ) use (&$ generatedFunctionDeclarations ) {
1119
+ function (FuncInfo $ funcInfo ) use ($ fileInfo , &$ generatedFunctionDeclarations ) {
1062
1120
$ key = $ funcInfo ->getDeclarationKey ();
1063
1121
if (isset ($ generatedFunctionDeclarations [$ key ])) {
1064
1122
return null ;
1065
1123
}
1066
1124
1067
1125
$ generatedFunctionDeclarations [$ key ] = true ;
1068
-
1069
- return $ funcInfo ->getDeclaration ();
1126
+ return $ fileInfo ->declarationPrefix . $ funcInfo ->getDeclaration ();
1070
1127
}
1071
1128
);
1072
1129
0 commit comments