@@ -20,12 +20,18 @@ converting it into the TypeLang AST Nodes.
2020
2121## Usage
2222
23- Package supports one reader class .
23+ Package supports two reader classes .
2424
2525<deflist >
2626 <def title="TypeLang\Reader\ReflectionReader">
2727 Used to read types metadata from reflection objects.
2828 </def>
29+ <def title="TypeLang\Reader\AttributeReader">
30+ Used to read types metadata from attributes.
31+ <tip>
32+ Available since <code>type-lang/reader: ^1.1</code>
33+ </tip>
34+ </def>
2935</deflist >
3036
3137Any reader implements the ` TypeLang\Reader\ReaderInterface ` interface, which
@@ -40,6 +46,9 @@ contains several methods:
4046
4147Method ` findConstantType() ` is used to read types from constants.
4248
49+ <tabs >
50+ <tab title =" ReflectionReader " >
51+
4352``` php
4453class Example
4554{
@@ -74,10 +83,87 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
7483```
7584{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
7685
86+ </tab >
87+ <tab title =" AttributeReader " >
88+
89+ ``` php
90+ class Example
91+ {
92+ #[TypeLang\Reader\Attribute\MapType('int<0 , max >')]
93+ public const int EXAMPLE = 0xDEAD_BEEF;
94+ }
95+
96+ $reader = new \TypeLang\Reader\AttributeReader();
97+
98+ $result = $reader->findConstantType(
99+ constant: new \ReflectionClassConstant(
100+ class: Example::class,
101+ constant: 'EXAMPLE',
102+ ),
103+ );
104+ ```
105+
106+ ``` php
107+ TypeLang\Parser\Node\Stmt\NamedTypeNode {
108+ +offset: 0
109+ +name: TypeLang\Parser\Node\Name {
110+ +offset: 0
111+ +parts: array:1 [
112+ 0 => TypeLang\Parser\Node\Identifier {
113+ +offset: 0
114+ +value: "int"
115+ }
116+ ]
117+ }
118+ +arguments: TypeLang\Parser\Node\Stmt\Template\TemplateArgumentsListNode {
119+ +offset: 3
120+ +items: array:2 [
121+ 0 => TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode {
122+ +offset: 4
123+ +hint: null
124+ +value: TypeLang\Parser\Node\Literal\IntLiteralNode {#798
125+ +offset: 4
126+ +raw: "0"
127+ +value: 0
128+ }
129+ +attributes: null
130+ }
131+ 1 => TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode {
132+ +offset: 7
133+ +hint: null
134+ +value: TypeLang\Parser\Node\Stmt\NamedTypeNode {
135+ +offset: 7
136+ +name: TypeLang\Parser\Node\Name {
137+ +offset: 7
138+ +parts: array:1 [
139+ 0 => TypeLang\Parser\Node\Identifier {
140+ +offset: 7
141+ +value: "max"
142+ }
143+ ]
144+ }
145+ +arguments: null
146+ +fields: null
147+ }
148+ +attributes: null
149+ }
150+ ]
151+ }
152+ +fields: null
153+ }
154+ ```
155+ {collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
156+
157+ </tab >
158+ </tabs >
159+
77160### Properties
78161
79162Method ` findPropertyType() ` is used to read types from class properties.
80163
164+ <tabs >
165+ <tab title =" ReflectionReader " >
166+
81167``` php
82168class Example
83169{
@@ -111,12 +197,54 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
111197}
112198```
113199{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
200+ </tab >
201+ <tab title =" AttributeReader " >
202+
203+ ``` php
204+ class Example
205+ {
206+ #[TypeLang\Reader\Attribute\MapType('non-empty-string')]
207+ public readonly string $test;
208+ }
209+
210+ $reader = new \TypeLang\Reader\AttributeReader();
211+
212+ $result = $reader->findPropertyType(
213+ property: new \ReflectionProperty(
214+ class: Example::class,
215+ property: 'test',
216+ ),
217+ );
218+ ```
219+
220+ ``` php
221+ TypeLang\Parser\Node\Stmt\NamedTypeNode {
222+ +offset: 0
223+ +name: TypeLang\Parser\Node\Name {
224+ +offset: 0
225+ +parts: array:1 [
226+ 0 => TypeLang\Parser\Node\Identifier {
227+ +offset: 0
228+ +value: "non-empty-string"
229+ }
230+ ]
231+ }
232+ +arguments: null
233+ +fields: null
234+ }
235+ ```
236+ {collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
237+ </tab >
238+ </tabs >
114239
115240### Functions
116241
117242Method ` findFunctionType() ` is used to read return types from
118243functions and class methods.
119244
245+ <tabs >
246+ <tab title =" ReflectionReader " >
247+
120248``` php
121249$example = function(): void {};
122250
@@ -145,11 +273,49 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
145273```
146274{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
147275
276+ </tab >
277+ <tab title =" AttributeReader " >
278+
279+ ``` php
280+ $example = #[TypeLang\Reader\Attribute\MapType('never')]
281+ function(): void {};
282+
283+ $reader = new \TypeLang\Reader\AttributeReader();
284+
285+ $result = $reader->findFunctionType(
286+ function: new \ReflectionFunction($example),
287+ );
288+ ```
289+
290+ ``` php
291+ TypeLang\Parser\Node\Stmt\NamedTypeNode {
292+ +offset: 0
293+ +name: TypeLang\Parser\Node\Name {
294+ +offset: 0
295+ -parts: array:1 [
296+ 0 => TypeLang\Parser\Node\Identifier {
297+ +offset: 0
298+ +value: "never"
299+ }
300+ ]
301+ }
302+ +arguments: null
303+ +fields: null
304+ }
305+ ```
306+ {collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
307+
308+ </tab >
309+ </tabs >
310+
148311### Parameters
149312
150313Method ` findParameterType() ` is used to read types from
151314function and method parameters.
152315
316+ <tabs >
317+ <tab title =" ReflectionReader " >
318+
153319``` php
154320$example = function(bool $param) {};
155321
@@ -181,6 +347,93 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
181347```
182348{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
183349
350+ </tab >
351+ <tab title =" AttributeReader " >
352+
353+ ``` php
354+ $example = function(
355+ #[TypeLang\Reader\Attribute\MapType('true')] bool $param,
356+ ) {};
357+
358+ $reader = new \TypeLang\Reader\AttributeReader();
359+
360+ $result = $reader->findParameterType(
361+ parameter: new \ReflectionParameter(
362+ function: $example,
363+ param: 'param',
364+ ),
365+ );
366+ ```
367+
368+ ``` php
369+ TypeLang\Parser\Node\Stmt\NamedTypeNode {
370+ +offset: 0
371+ +name: TypeLang\Parser\Node\Name {
372+ +offset: 0
373+ -parts: array:1 [
374+ 0 => TypeLang\Parser\Node\Identifier {
375+ +offset: 0
376+ +value: "true"
377+ }
378+ ]
379+ }
380+ +arguments: null
381+ +fields: null
382+ }
383+ ```
384+ {collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
385+
386+ </tab >
387+ </tabs >
388+
389+ ## Attribute Reader
390+
391+ <secondary-label ref =" r1.1 " />
392+
393+ The ` TypeLang\Reader\AttributeReader ` provides the ability to modify its behavior.
394+ To do this, you should pass the ` TypeLang\Reader\AttributeReader\AttributeProviderInterface `
395+ implementation to the constructor of this class.
396+
397+ ``` php
398+ use TypeLang\Reader\AttributeReader;
399+ use TypeLang\Reader\AttributeReader\AttributeProviderInterface;
400+
401+ $reader = new AttributeReader(
402+ provider: new class implements AttributeProviderInterface {
403+ public function getAttribute(): string
404+ {
405+ //
406+ // The class of the attribute to be
407+ // read should be returned.
408+ //
409+ return AttributeClassName::class;
410+ }
411+
412+ public function getTypeFromAttribute(
413+ object $attribute,
414+ ): string {
415+ //
416+ // A value with a type description from
417+ // the attribute should be returned.
418+ //
419+ return $attribute->propertyWithTypeDefinition;
420+ }
421+
422+ public function process(
423+ object $attribute,
424+ TypeStatement $statement,
425+ ): TypeStatement {
426+ //
427+ // You can also modify the return type based
428+ // on information from the attribute.
429+ //
430+ return $statement;
431+ }
432+ },
433+ );
434+ ```
435+
436+
184437## Complex Example
185438
186439Complete example for reading and printing types from an entire class.
0 commit comments