@@ -411,7 +411,7 @@ protected function fixDocBlockIndentation(&$lines)
411411 }
412412 $ docLine = preg_replace ('/\s+/ ' , ' ' , $ docLine );
413413 $ docLine = $ this ->fixParamTypes ($ docLine );
414- } elseif (preg_match ( ' /^(~~~| ```)/ ' , $ docLine ) ) {
414+ } elseif (strpos ( $ docLine , ' ``` ' ) !== false ) {
415415 $ codeBlock = !$ codeBlock ;
416416 $ listIndent = '' ;
417417 } elseif (preg_match ('/^(\s*)([0-9]+\.|-|\*|\+) / ' , $ docLine , $ matches )) {
@@ -676,7 +676,7 @@ protected function cleanDocComment($doc)
676676 $ n = \count ($ lines );
677677 for ($ i = 0 ; $ i < $ n ; $ i ++) {
678678 $ lines [$ i ] = rtrim ($ lines [$ i ]);
679- if (trim ($ lines [$ i ]) == '* ' && trim ($ lines [$ i + 1 ]) == '* ' ) {
679+ if (trim ($ lines [$ i ]) == '* ' && isset ( $ lines [ $ i + 1 ]) && trim ($ lines [$ i + 1 ]) == '* ' ) {
680680 unset($ lines [$ i ]);
681681 }
682682 }
@@ -702,10 +702,15 @@ protected function updateDocComment($doc, $properties, $className)
702702 foreach ($ lines as $ i => $ line ) {
703703 $ line = trim ($ line );
704704 if (strncmp ($ line , '* @property ' , 11 ) === 0 ) {
705+ if ($ propertyPosition === false ) {
706+ $ propertyPosition = $ i - 1 ;
707+ }
705708 $ propertyPart = true ;
706709 } elseif ($ propertyPart && $ line === '* ' ) {
707710 $ propertyPosition = $ i ;
708711 $ propertyPart = false ;
712+ } elseif ($ propertyPart && $ line === '*/ ' ) {
713+ $ propertyPart = false ;
709714 }
710715 if (strncmp ($ line , '* @author ' , 10 ) === 0 && $ propertyPosition === false ) {
711716 $ propertyPosition = $ i - 1 ;
@@ -833,7 +838,7 @@ protected function generateClassPropertyDocs($fileName)
833838 continue ;
834839 }
835840
836- $ acr ['comment ' ] = trim (preg_replace ('#(^|\n)\s +\*\s ?# ' , '$1 * ' , $ acr ['comment ' ]));
841+ $ acr ['comment ' ] = trim (preg_replace ('#(^|\n)\h +\*\h ?# ' , '$1 * ' , $ acr ['comment ' ]));
837842 $ props [$ acr ['name ' ]][$ acr ['kind ' ]] = [
838843 'type ' => $ acr ['type ' ],
839844 'comment ' => $ this ->fixSentence ($ acr ['comment ' ]),
@@ -847,33 +852,41 @@ protected function generateClassPropertyDocs($fileName)
847852 ksort ($ props );
848853
849854 foreach ($ props as $ propName => &$ prop ) {
850- $ docLine = ' * @property ' ;
851- $ note = '' ;
855+ $ annotationSuffix = '' ;
852856 if (isset ($ prop ['get ' ], $ prop ['set ' ])) {
853857 if ($ prop ['get ' ]['type ' ] !== $ prop ['set ' ]['type ' ]) {
854- $ note = ' Note that the type of this property differs in getter and setter. '
855- . ' See [[get ' . ucfirst ($ propName ) . '()]] '
856- . ' and [[set ' . ucfirst ($ propName ) . '()]] for details. ' ;
858+ $ phpdoc .= $ this ->generatePropertyDocLine (
859+ '-read ' ,
860+ $ propName ,
861+ $ prop ['get ' ]['type ' ],
862+ $ prop ['get ' ]['comment ' ]
863+ );
864+ $ phpdoc .= $ this ->generatePropertyDocLine (
865+ '-write ' ,
866+ $ propName ,
867+ $ prop ['set ' ]['type ' ],
868+ $ prop ['set ' ]['comment ' ]
869+ );
870+ continue ;
857871 }
858872 } elseif (isset ($ prop ['get ' ])) {
859873 if (!$ this ->hasSetterInParents ($ className , $ propName )) {
860- $ docLine . = '-read ' ;
874+ $ annotationSuffix = '-read ' ;
861875 }
862876 } elseif (isset ($ prop ['set ' ])) {
863877 if (!$ this ->hasGetterInParents ($ className , $ propName )) {
864- $ docLine . = '-write ' ;
878+ $ annotationSuffix = '-write ' ;
865879 }
866880 } else {
867881 continue ;
868882 }
869- $ docLine .= ' ' . $ this ->getPropParam ($ prop , 'type ' ) . " $ $ propName " ;
870- $ comment = explode ("\n" , $ this ->getPropParam ($ prop , 'comment ' ) . $ note );
871- foreach ($ comment as &$ cline ) {
872- $ cline = ltrim (rtrim ($ cline ), '* ' );
873- }
874- $ docLine = wordwrap ($ docLine . implode (' ' , $ comment ), 110 , "\n * " ) . "\n" ;
875883
876- $ phpdoc .= $ docLine ;
884+ $ phpdoc .= $ this ->generatePropertyDocLine (
885+ $ annotationSuffix ,
886+ $ propName ,
887+ $ this ->getPropParam ($ prop , 'type ' ),
888+ $ this ->getPropParam ($ prop , 'comment ' )
889+ );
877890 }
878891 }
879892
@@ -918,14 +931,70 @@ protected function fixSentence($str)
918931 return '' ;
919932 }
920933
921- return strtoupper (substr ($ str , 0 , 1 )) . substr ($ str , 1 ) . ($ str [\strlen ($ str ) - 1 ] !== '. ' ? '. ' : '' );
934+ $ endsWithCodeFence = substr ($ str , -3 ) === '``` ' ;
935+ $ suffix = !$ endsWithCodeFence && $ str [\strlen ($ str ) - 1 ] !== '. ' ? '. ' : '' ;
936+
937+ return strtoupper (substr ($ str , 0 , 1 )) . substr ($ str , 1 ) . $ suffix ;
922938 }
923939
924940 protected function getPropParam ($ prop , $ param )
925941 {
926942 return isset ($ prop ['property ' ]) ? $ prop ['property ' ][$ param ] : (isset ($ prop ['get ' ]) ? $ prop ['get ' ][$ param ] : $ prop ['set ' ][$ param ]);
927943 }
928944
945+ private function generatePropertyDocLine (
946+ string $ annotationSuffix ,
947+ string $ propName ,
948+ string $ type ,
949+ string $ comment
950+ ): string {
951+ $ docLine = " * @property {$ annotationSuffix } {$ type } \${$ propName } " ;
952+
953+ $ isExample = false ;
954+ $ commentLines = [];
955+ $ exampleLines = [];
956+ $ rawCommentLines = explode ("\n" , $ comment );
957+
958+ foreach ($ rawCommentLines as $ lineIndex => $ line ) {
959+ $ isCodeFence = strpos ($ line , '* ``` ' ) !== false ;
960+ $ formattedLine = ltrim (rtrim ($ line ), '* ' );
961+
962+ if ($ isCodeFence ) {
963+ if (!$ isExample ) {
964+ $ isExample = true ;
965+ $ exampleLines [] = "\n * {$ formattedLine }" ;
966+ continue ;
967+ }
968+
969+ $ exampleLines [] = " * {$ formattedLine }" ;
970+ $ example = implode ("\n" , $ exampleLines );
971+
972+ foreach (array_slice ($ rawCommentLines , $ lineIndex + 1 ) as $ remainingLine ) {
973+ if (ltrim (rtrim ($ remainingLine ), '* ' ) !== '' ) {
974+ $ example .= "\n * " ;
975+ break ;
976+ }
977+ }
978+
979+ $ commentLines [] = $ example ;
980+ $ exampleLines = [];
981+ $ isExample = false ;
982+ continue ;
983+ }
984+
985+ if ($ isExample ) {
986+ $ exampleLines [] = rtrim ($ line );
987+ } elseif ($ formattedLine !== '' ) {
988+ $ commentLines [] = $ formattedLine ;
989+ }
990+ }
991+
992+ $ propertyDoc = wordwrap ($ docLine . implode (' ' , $ commentLines ), 110 , "\n * " );
993+ $ propertyDoc = preg_replace ('/\h+\n/ ' , "\n" , $ propertyDoc ) ?? $ propertyDoc ;
994+
995+ return $ propertyDoc . "\n" ;
996+ }
997+
929998 /**
930999 * Generate a hash value (message digest)
9311000 * @param string $string message to be hashed.
0 commit comments