1717use Latte \PhpHelpers ;
1818use Latte \PhpWriter ;
1919
20-
2120/**
2221 * Basic macros for Latte.
2322 */
@@ -813,15 +812,20 @@ public function macroParameters(MacroNode $node, PhpWriter $writer): void
813812 $ tokens = $ node ->tokenizer ;
814813 $ params = [];
815814 while ($ tokens ->isNext ()) {
816- if ($ tokens ->nextToken ($ tokens ::T_SYMBOL , '? ' , 'null ' , '\\' )) { // type
817- $ tokens ->nextAll ($ tokens ::T_SYMBOL , '\\' , '| ' , '[ ' , '] ' , 'null ' );
815+ $ type = $ tokens ->nextValue ($ tokens ::T_SYMBOL , '? ' , 'null ' , '\\' );
816+ if ($ type ) {
817+ $ type .= $ tokens ->joinAll ($ tokens ::T_SYMBOL , '\\' , '| ' , '[ ' , '] ' , 'null ' );
818818 }
819819 $ param = $ tokens ->consumeValue ($ tokens ::T_VARIABLE );
820820 $ default = $ tokens ->nextToken ('= ' )
821821 ? $ tokens ->joinUntilSameDepth (', ' )
822822 : 'null ' ;
823+ $ mask ='%raw = $this->params[%var] ?? $this->params[%var] ?? %raw; ' ;
824+ if ($ type ) {
825+ $ mask = "/** @var $ type $ param */ \n" . $ mask ;
826+ }
823827 $ params [] = $ writer ->write (
824- ' %raw = $this->params[%var] ?? $this->params[%var] ?? %raw; ' ,
828+ $ mask ,
825829 $ param ,
826830 count ($ params ),
827831 substr ($ param , 1 ),
@@ -838,7 +842,7 @@ public function macroParameters(MacroNode $node, PhpWriter $writer): void
838842 /**
839843 * {varType type $var}
840844 */
841- public function macroVarType (MacroNode $ node ): void
845+ public function macroVarType (MacroNode $ node, PhpWriter $ writer ): string
842846 {
843847 if ($ node ->modifiers ) {
844848 $ node ->setArgs ($ node ->args . $ node ->modifiers );
@@ -847,10 +851,17 @@ public function macroVarType(MacroNode $node): void
847851 $ node ->validate (true );
848852
849853 $ type = trim ($ node ->tokenizer ->joinUntil ($ node ->tokenizer ::T_VARIABLE ));
850- $ variable = $ node ->tokenizer ->nextToken ($ node ->tokenizer ::T_VARIABLE );
854+ $ variable = $ node ->tokenizer ->nextValue ($ node ->tokenizer ::T_VARIABLE );
851855 if (!$ type || !$ variable ) {
852856 throw new CompileException ('Unexpected content, expecting {varType type $var}. ' );
853857 }
858+ $ comment = "/** @var $ type $ variable */ \n" ;
859+ if ($ this ->getCompiler ()->isInHead ()) {
860+ $ this ->getCompiler ()->paramsExtraction .= $ comment ;
861+ return "" ;
862+ } else {
863+ return $ writer ->write ($ comment );
864+ }
854865 }
855866
856867
@@ -869,12 +880,38 @@ public function macroVarPrint(MacroNode $node): string
869880 /**
870881 * {templateType ClassName}
871882 */
872- public function macroTemplateType (MacroNode $ node ): void
883+ public function macroTemplateType (MacroNode $ node )
873884 {
874885 if (!$ this ->getCompiler ()->isInHead ()) {
875886 throw new CompileException ($ node ->getNotation () . ' is allowed only in template header. ' );
876887 }
877888 $ node ->validate ('class name ' );
889+ try {
890+ $ reflectionClass = new \ReflectionClass ($ node ->args );
891+ foreach ($ reflectionClass ->getProperties () as $ property ) {
892+ if (!$ property ->isPublic ()) {
893+ continue ;
894+ }
895+ $ propertyName = $ property ->getName ();
896+ $ type = $ property ->getType ();
897+ $ typeName = null ;
898+ if ($ type instanceof \ReflectionNamedType) {
899+ $ typeName = ($ type ->allowsNull () ? "? " : "" ) . $ type ->getName ();
900+ } elseif ($ type instanceof \ReflectionUnionType) {
901+ $ typeName = implode ("| " , array_map (
902+ function (\ReflectionNamedType $ type ) { return $ type ->getName (); },
903+ $ type ->getTypes ()
904+ ));
905+ }
906+ if (!$ typeName ) {
907+ $ typeName = "mixed " ;
908+ }
909+ $ comment = "/** @var $ typeName \$$ propertyName ( {$ node ->args }) */ \n" ;
910+ $ this ->getCompiler ()->paramsExtraction .= $ comment ;
911+ }
912+ } catch (\ReflectionException $ e ) {
913+
914+ }
878915 }
879916
880917
0 commit comments