Skip to content

Commit

Permalink
Upgrade reader component information
Browse files Browse the repository at this point in the history
  • Loading branch information
SerafimArts committed Sep 27, 2024
1 parent 8bc2b9d commit 0a48c69
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 6 deletions.
5 changes: 3 additions & 2 deletions Writerside/labels.list
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

<secondary-label id="wip" name="WIP" color="red">Work in progress</secondary-label>
<secondary-label id="beta" name="β" color="tangerine">Beta</secondary-label>
<secondary-label id="1.1" name="TypeLang 1.1" color="strawberry">Since type-lang/parser v1.1</secondary-label>
<secondary-label id="1.2" name="TypeLang 1.2" color="strawberry">Since type-lang/parser v1.2</secondary-label>
<secondary-label id="tl1.1" name="TypeLang 1.1" color="strawberry">Since type-lang/parser v1.1</secondary-label>
<secondary-label id="tl1.2" name="TypeLang 1.2" color="strawberry">Since type-lang/parser v1.2</secondary-label>
<secondary-label id="r1.1" name="Reader Component 1.1" color="strawberry">Since type-lang/reader v1.1</secondary-label>
</labels>
2 changes: 1 addition & 1 deletion Writerside/topics/language/callable-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ _before the type_ or _before the parameter name._
## Attributes
<secondary-label ref="1.2"/>
<secondary-label ref="tl1.2"/>
Each callable parameter allows you to define list of additional attributes.
An attribute is additional metadata for a parameter.
Expand Down
2 changes: 1 addition & 1 deletion Writerside/topics/language/generic-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ In addition to modern list declarations such as `list<int>` or
## Attributes
<secondary-label ref="1.1"/>
<secondary-label ref="tl1.1"/>
Each template argument allows you to define list of additional attributes.
An attribute is additional metadata for an argument.
Expand Down
2 changes: 1 addition & 1 deletion Writerside/topics/language/shape-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ array{

## Attributes

<secondary-label ref="1.1"/>
<secondary-label ref="tl1.1"/>

Each shape field allows you to define list of additional attributes.
An attribute is additional metadata for a field.
Expand Down
255 changes: 254 additions & 1 deletion Writerside/topics/reader.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ converting it into the TypeLang AST Nodes.

## Usage

Package supports one reader class.
Package supports two reader classes.

<deflist>
<def title="TypeLang\Reader\ReflectionReader">
Used to read types metadata from reflection objects.
</def>
<def title="TypeLang\Reader\AttributeReader">
Used to read types metadata from attributes.
<tip>
Available since <code>type-lang/reader: ^1.1</code>
</tip>
</def>
</deflist>

Any reader implements the `TypeLang\Reader\ReaderInterface` interface, which
Expand All @@ -40,6 +46,9 @@ contains several methods:

Method `findConstantType()` is used to read types from constants.

<tabs>
<tab title="ReflectionReader">

```php
class Example
{
Expand Down Expand Up @@ -74,10 +83,87 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}

</tab>
<tab title="AttributeReader">

```php
class Example
{
#[TypeLang\Reader\Attribute\MapType('int<0, max>')]
public const int EXAMPLE = 0xDEAD_BEEF;
}

$reader = new \TypeLang\Reader\AttributeReader();

$result = $reader->findConstantType(
constant: new \ReflectionClassConstant(
class: Example::class,
constant: 'EXAMPLE',
),
);
```

```php
TypeLang\Parser\Node\Stmt\NamedTypeNode {
+offset: 0
+name: TypeLang\Parser\Node\Name {
+offset: 0
+parts: array:1 [
0 => TypeLang\Parser\Node\Identifier {
+offset: 0
+value: "int"
}
]
}
+arguments: TypeLang\Parser\Node\Stmt\Template\TemplateArgumentsListNode {
+offset: 3
+items: array:2 [
0 => TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode {
+offset: 4
+hint: null
+value: TypeLang\Parser\Node\Literal\IntLiteralNode {#798
+offset: 4
+raw: "0"
+value: 0
}
+attributes: null
}
1 => TypeLang\Parser\Node\Stmt\Template\TemplateArgumentNode {
+offset: 7
+hint: null
+value: TypeLang\Parser\Node\Stmt\NamedTypeNode {
+offset: 7
+name: TypeLang\Parser\Node\Name {
+offset: 7
+parts: array:1 [
0 => TypeLang\Parser\Node\Identifier {
+offset: 7
+value: "max"
}
]
}
+arguments: null
+fields: null
}
+attributes: null
}
]
}
+fields: null
}
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}

</tab>
</tabs>

### Properties

Method `findPropertyType()` is used to read types from class properties.

<tabs>
<tab title="ReflectionReader">

```php
class Example
{
Expand Down Expand Up @@ -111,12 +197,54 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
}
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
</tab>
<tab title="AttributeReader">

```php
class Example
{
#[TypeLang\Reader\Attribute\MapType('non-empty-string')]
public readonly string $test;
}

$reader = new \TypeLang\Reader\AttributeReader();

$result = $reader->findPropertyType(
property: new \ReflectionProperty(
class: Example::class,
property: 'test',
),
);
```

```php
TypeLang\Parser\Node\Stmt\NamedTypeNode {
+offset: 0
+name: TypeLang\Parser\Node\Name {
+offset: 0
+parts: array:1 [
0 => TypeLang\Parser\Node\Identifier {
+offset: 0
+value: "non-empty-string"
}
]
}
+arguments: null
+fields: null
}
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}
</tab>
</tabs>

### Functions

Method `findFunctionType()` is used to read return types from
functions and class methods.

<tabs>
<tab title="ReflectionReader">

```php
$example = function(): void {};

Expand Down Expand Up @@ -145,11 +273,49 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}

</tab>
<tab title="AttributeReader">

```php
$example = #[TypeLang\Reader\Attribute\MapType('never')]
function(): void {};

$reader = new \TypeLang\Reader\AttributeReader();

$result = $reader->findFunctionType(
function: new \ReflectionFunction($example),
);
```

```php
TypeLang\Parser\Node\Stmt\NamedTypeNode {
+offset: 0
+name: TypeLang\Parser\Node\Name {
+offset: 0
-parts: array:1 [
0 => TypeLang\Parser\Node\Identifier {
+offset: 0
+value: "never"
}
]
}
+arguments: null
+fields: null
}
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}

</tab>
</tabs>

### Parameters

Method `findParameterType()` is used to read types from
function and method parameters.

<tabs>
<tab title="ReflectionReader">

```php
$example = function(bool $param) {};

Expand Down Expand Up @@ -181,6 +347,93 @@ TypeLang\Parser\Node\Stmt\NamedTypeNode {
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}

</tab>
<tab title="AttributeReader">

```php
$example = function(
#[TypeLang\Reader\Attribute\MapType('true')] bool $param,
) {};

$reader = new \TypeLang\Reader\AttributeReader();

$result = $reader->findParameterType(
parameter: new \ReflectionParameter(
function: $example,
param: 'param',
),
);
```

```php
TypeLang\Parser\Node\Stmt\NamedTypeNode {
+offset: 0
+name: TypeLang\Parser\Node\Name {
+offset: 0
-parts: array:1 [
0 => TypeLang\Parser\Node\Identifier {
+offset: 0
+value: "true"
}
]
}
+arguments: null
+fields: null
}
```
{collapsible="true" collapsed-title="TypeLang\Parser\Node\Stmt\NamedTypeNode"}

</tab>
</tabs>

## Attribute Reader

<secondary-label ref="r1.1"/>

The `TypeLang\Reader\AttributeReader` provides the ability to modify its behavior.
To do this, you should pass the `TypeLang\Reader\AttributeReader\AttributeProviderInterface`
implementation to the constructor of this class.

```php
use TypeLang\Reader\AttributeReader;
use TypeLang\Reader\AttributeReader\AttributeProviderInterface;

$reader = new AttributeReader(
provider: new class implements AttributeProviderInterface {
public function getAttribute(): string
{
//
// The class of the attribute to be
// read should be returned.
//
return AttributeClassName::class;
}

public function getTypeFromAttribute(
object $attribute,
): string {
//
// A value with a type description from
// the attribute should be returned.
//
return $attribute->propertyWithTypeDefinition;
}

public function process(
object $attribute,
TypeStatement $statement,
): TypeStatement {
//
// You can also modify the return type based
// on information from the attribute.
//
return $statement;
}
},
);
```


## Complex Example

Complete example for reading and printing types from an entire class.
Expand Down

0 comments on commit 0a48c69

Please sign in to comment.