@@ -357,6 +357,7 @@ interface FunctionOrMethodName {
357357 public function getDeclaration (): string ;
358358 public function getArgInfoName (): string ;
359359 public function __toString (): string ;
360+ public function isMagicMethod (): bool ;
360361}
361362
362363class FunctionName implements FunctionOrMethodName {
@@ -374,19 +375,19 @@ public function getNamespace(): ?string {
374375 return null ;
375376 }
376377
377- public function getShortName (): string {
378- return $ this ->name ->getLast ();
379- }
380-
381378 public function getNonNamespacedName (): string {
382379 if ($ this ->name ->isQualified ()) {
383380 throw new Exception ("Namespaced name not supported here " );
384381 }
385382 return $ this ->name ->toString ();
386383 }
387384
385+ public function getDeclarationName (): string {
386+ return $ this ->name ->getLast ();
387+ }
388+
388389 public function getDeclaration (): string {
389- return "ZEND_FUNCTION( {$ this ->name -> getLast ()}); \n" ;
390+ return "ZEND_FUNCTION( {$ this ->getDeclarationName ()}); \n" ;
390391 }
391392
392393 public function getArgInfoName (): string {
@@ -397,29 +398,41 @@ public function getArgInfoName(): string {
397398 public function __toString (): string {
398399 return $ this ->name ->toString ();
399400 }
401+
402+ public function isMagicMethod (): bool {
403+ return false ;
404+ }
400405}
401406
402407class MethodName implements FunctionOrMethodName {
408+ /** @var Name */
409+ private $ className ;
403410 /** @var string */
404- public $ className ;
405- /** @var string */
406- public $ name ;
411+ public $ methodName ;
407412
408- public function __construct (string $ className , string $ name ) {
413+ public function __construct (Name $ className , string $ methodName ) {
409414 $ this ->className = $ className ;
410- $ this ->name = $ name ;
415+ $ this ->methodName = $ methodName ;
416+ }
417+
418+ public function getDeclarationClassName (): string {
419+ return implode ('_ ' , $ this ->className ->parts );
411420 }
412421
413422 public function getDeclaration (): string {
414- return "ZEND_METHOD( $ this ->className , $ this ->name ); \n" ;
423+ return "ZEND_METHOD( { $ this ->getDeclarationClassName ()} , $ this ->methodName ); \n" ;
415424 }
416425
417426 public function getArgInfoName (): string {
418- return "arginfo_class_ {$ this ->className }_ {$ this ->name }" ;
427+ return "arginfo_class_ {$ this ->getDeclarationClassName () }_ {$ this ->methodName }" ;
419428 }
420429
421430 public function __toString (): string {
422- return "$ this ->className :: $ this ->name " ;
431+ return "$ this ->className :: $ this ->methodName " ;
432+ }
433+
434+ public function isMagicMethod (): bool {
435+ return strpos ($ this ->methodName , '__ ' ) === 0 ;
423436 }
424437}
425438
@@ -526,58 +539,63 @@ public function getFunctionEntry(): string {
526539 if ($ this ->alias instanceof MethodName) {
527540 return sprintf (
528541 "\tZEND_MALIAS(%s, %s, %s, %s, %s) \n" ,
529- $ this ->alias ->className , $ this ->name ->name , $ this ->alias ->name , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
542+ $ this ->alias ->getDeclarationClassName (), $ this ->name ->methodName ,
543+ $ this ->alias ->methodName , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
530544 );
531545 } else if ($ this ->alias instanceof FunctionName) {
532546 return sprintf (
533547 "\tZEND_ME_MAPPING(%s, %s, %s, %s) \n" ,
534- $ this ->name ->name , $ this ->alias ->getNonNamespacedName (),
548+ $ this ->name ->methodName , $ this ->alias ->getNonNamespacedName (),
535549 $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
536550 );
537551 } else {
538552 throw new Error ("Cannot happen " );
539553 }
540554 } else {
555+ $ declarationClassName = $ this ->name ->getDeclarationClassName ();
541556 if ($ this ->flags & Class_::MODIFIER_ABSTRACT ) {
542557 return sprintf (
543558 "\tZEND_ABSTRACT_ME_WITH_FLAGS(%s, %s, %s, %s) \n" ,
544- $ this ->name ->className , $ this ->name ->name , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
559+ $ declarationClassName , $ this ->name ->methodName , $ this ->getArgInfoName (),
560+ $ this ->getFlagsAsString ()
545561 );
546562 }
547563
548564 return sprintf (
549565 "\tZEND_ME(%s, %s, %s, %s) \n" ,
550- $ this ->name ->className , $ this ->name ->name , $ this ->getArgInfoName (), $ this ->getFlagsAsString ()
566+ $ declarationClassName , $ this ->name ->methodName , $ this ->getArgInfoName (),
567+ $ this ->getFlagsAsString ()
551568 );
552569 }
553570 } else if ($ this ->name instanceof FunctionName) {
554571 $ namespace = $ this ->name ->getNamespace ();
555- $ shortName = $ this ->name ->getShortName ();
572+ $ declarationName = $ this ->name ->getDeclarationName ();
556573
557574 if ($ this ->alias && $ this ->isDeprecated ) {
558575 return sprintf (
559576 "\tZEND_DEP_FALIAS(%s, %s, %s) \n" ,
560- $ shortName , $ this ->alias ->getNonNamespacedName (), $ this ->getArgInfoName ()
577+ $ declarationName , $ this ->alias ->getNonNamespacedName (), $ this ->getArgInfoName ()
561578 );
562579 }
563580
564581 if ($ this ->alias ) {
565582 return sprintf (
566583 "\tZEND_FALIAS(%s, %s, %s) \n" ,
567- $ shortName , $ this ->alias ->getNonNamespacedName (), $ this ->getArgInfoName ()
584+ $ declarationName , $ this ->alias ->getNonNamespacedName (), $ this ->getArgInfoName ()
568585 );
569586 }
570587
571588 if ($ this ->isDeprecated ) {
572- return sprintf ("\tZEND_DEP_FE(%s, %s) \n" , $ shortName , $ this ->getArgInfoName ());
589+ return sprintf (
590+ "\tZEND_DEP_FE(%s, %s) \n" , $ declarationName , $ this ->getArgInfoName ());
573591 }
574592
575593 if ($ namespace ) {
576594 return sprintf (
577595 "\tZEND_NS_FE( \"%s \", %s, %s) \n" ,
578- $ namespace , $ shortName , $ this ->getArgInfoName ());
596+ $ namespace , $ declarationName , $ this ->getArgInfoName ());
579597 } else {
580- return sprintf ("\tZEND_FE(%s, %s) \n" , $ shortName , $ this ->getArgInfoName ());
598+ return sprintf ("\tZEND_FE(%s, %s) \n" , $ declarationName , $ this ->getArgInfoName ());
581599 }
582600 } else {
583601 throw new Error ("Cannot happen " );
@@ -622,12 +640,12 @@ public function discardInfoForOldPhpVersions(): void {
622640}
623641
624642class ClassInfo {
625- /** @var string */
643+ /** @var Name */
626644 public $ name ;
627645 /** @var FuncInfo[] */
628646 public $ funcInfos ;
629647
630- public function __construct (string $ name , array $ funcInfos ) {
648+ public function __construct (Name $ name , array $ funcInfos ) {
631649 $ this ->name = $ name ;
632650 $ this ->funcInfos = $ funcInfos ;
633651 }
@@ -741,7 +759,7 @@ function parseFunctionLike(
741759 if (count ($ aliasParts ) === 1 ) {
742760 $ alias = new FunctionName (new Name ($ aliasParts [0 ]));
743761 } else {
744- $ alias = new MethodName ($ aliasParts [0 ], $ aliasParts [1 ]);
762+ $ alias = new MethodName (new Name ( $ aliasParts [0 ]) , $ aliasParts [1 ]);
745763 }
746764 } else if ($ tag ->name === 'deprecated ' ) {
747765 $ isDeprecated = true ;
@@ -814,7 +832,7 @@ function parseFunctionLike(
814832 }
815833
816834 $ returnType = $ func ->getReturnType ();
817- if ($ returnType === null && !$ haveDocReturnType && strpos ( $ name ->name , ' __ ' ) !== 0 ) {
835+ if ($ returnType === null && !$ haveDocReturnType && ! $ name ->isMagicMethod () ) {
818836 throw new Exception ("Missing return type for function $ name() " );
819837 }
820838
@@ -906,7 +924,7 @@ function handleStatements(FileInfo $fileInfo, array $stmts, PrettyPrinterAbstrac
906924 }
907925
908926 if ($ stmt instanceof Stmt \ClassLike) {
909- $ className = $ stmt ->name -> toString () ;
927+ $ className = $ stmt ->namespacedName ;
910928 $ methodInfos = [];
911929 foreach ($ stmt ->stmts as $ classStmt ) {
912930 $ cond = handlePreprocessorConditions ($ conds , $ classStmt );
@@ -1160,10 +1178,14 @@ function (FuncInfo $funcInfo) use($fileInfo, &$generatedFunctionDeclarations) {
11601178}
11611179
11621180/** @param FuncInfo[] $funcInfos */
1163- function generateFunctionEntries (?string $ className , array $ funcInfos ): string {
1181+ function generateFunctionEntries (?Name $ className , array $ funcInfos ): string {
11641182 $ code = "" ;
11651183
1166- $ functionEntryName = $ className ? "class_ {$ className }_methods " : "ext_functions " ;
1184+ $ functionEntryName = "ext_functions " ;
1185+ if ($ className ) {
1186+ $ underscoreName = implode ("_ " , $ className ->parts );
1187+ $ functionEntryName = "class_ {$ underscoreName }_methods " ;
1188+ }
11671189
11681190 $ code .= "\n\nstatic const zend_function_entry {$ functionEntryName }[] = { \n" ;
11691191 $ code .= generateCodeWithConditions ($ funcInfos , "" , function (FuncInfo $ funcInfo ) {
0 commit comments