55namespace TypeLang \PHPDoc \DocBlock \Tag \MethodTag ;
66
77use TypeLang \Parser \Node \Stmt \CallableTypeNode ;
8+ use TypeLang \Parser \Node \Stmt \NamedTypeNode ;
89use TypeLang \Parser \Parser as TypesParser ;
910use TypeLang \Parser \ParserInterface as TypesParserInterface ;
1011use TypeLang \PHPDoc \DocBlock \Tag \Factory \TagFactoryInterface ;
12+ use TypeLang \PHPDoc \Exception \InvalidTagException ;
1113use TypeLang \PHPDoc \Parser \Content \OptionalTypeReader ;
1214use TypeLang \PHPDoc \Parser \Content \OptionalValueReader ;
1315use TypeLang \PHPDoc \Parser \Content \Stream ;
@@ -30,39 +32,55 @@ public function create(string $tag, string $content, DescriptionParserInterface
3032 $ stream = new Stream ($ tag , $ content );
3133
3234 $ isStatic = $ stream ->apply (new OptionalValueReader ('static ' )) !== null ;
33- $ returnType = $ stream ->apply (new TypeReader ($ this ->parser ));
34- $ callableType = $ stream ->apply (new OptionalTypeReader ($ this ->parser ));
35+
36+ try {
37+ $ type = $ stream ->apply (new TypeReader ($ this ->parser ));
38+ } catch (InvalidTagException $ e ) {
39+ $ type = $ isStatic ? new NamedTypeNode ('static ' ) : throw $ e ;
40+ }
41+
42+ $ callable = null ;
43+
44+ if (!$ type instanceof CallableTypeNode) {
45+ $ callable = $ stream ->apply (new OptionalTypeReader ($ this ->parser ));
46+ }
3547
3648 // In case of return type has not been defined then we swap first
3749 // defined type as method signature definition.
38- if ($ callableType === null ) {
39- $ callableType = $ returnType ;
40- $ returnType = null ;
50+ if ($ callable === null ) {
51+ $ callable = $ type ;
52+ $ type = null ;
4153 }
4254
43- if (!$ callableType instanceof CallableTypeNode) {
44- throw $ stream ->toException (
45- message: \sprintf (
46- 'The @%s annotation must contain the method signature ' ,
47- $ tag ,
48- ),
49- );
55+ if (!$ callable instanceof CallableTypeNode) {
56+ throw $ stream ->toException (\sprintf (
57+ 'Tag @%s must contain the method signature ' ,
58+ $ tag ,
59+ ));
5060 }
5161
52- if ($ callableType ->type !== null && $ returnType !== null ) {
53- throw $ stream ->toException (
54- message: \sprintf ( 'You can specify the return type of '
55- . 'a method of the @%s annotation before or after the '
56- . ' method`s signature, but not both ' , $ tag) ,
57- );
62+ if ($ callable ->type !== null && $ type !== null ) {
63+ throw $ stream ->toException (\sprintf (
64+ 'You can specify the return type of the @%s tag before or '
65+ . 'after the method`s signature, but not both ' ,
66+ $ tag ,
67+ )) ;
5868 }
5969
60- $ callableType ->type ??= $ returnType ;
70+ if (!$ callable ->name ->isSimple ()) {
71+ throw $ stream ->toException (\sprintf (
72+ 'Tag @%s must contain the method name, but FQN "%s" given ' ,
73+ $ tag ,
74+ $ callable ->name ->toString (),
75+ ));
76+ }
6177
6278 return new MethodTag (
6379 name: $ tag ,
64- type: $ callableType ,
65- static: $ isStatic ,
80+ method: $ callable ->name ->toString (),
81+ type: $ callable ->type ?? $ type ,
82+ parameters: $ callable ->parameters ,
83+ isStatic: $ isStatic ,
6684 description: $ stream ->toOptionalDescription ($ descriptions ),
6785 );
6886 }
0 commit comments