Skip to content

Commit 515c6e7

Browse files
committed
Improve packages readme
1 parent 74e5d42 commit 515c6e7

1 file changed

Lines changed: 39 additions & 115 deletions

File tree

README.md

Lines changed: 39 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -14,138 +14,62 @@
1414

1515
---
1616

17-
Reference implementation for TypeLang Parser.
17+
The reference parser for **TypeLang** — a declarative type language inspired by
18+
static analyzers like [PHPStan](https://phpstan.org/) and [Psalm](https://psalm.dev/docs/).
1819

19-
**TypeLang** is a declarative type language inspired by static analyzers
20-
like [PHPStan](https://phpstan.org/) and [Psalm](https://psalm.dev/docs/).
20+
It reads a type declaration string and builds an AST of `TypeLang\Type\*` nodes,
21+
checking the grammar along the way. The node classes themselves live in the
22+
separate [`type-lang/types`](https://packagist.org/packages/type-lang/types) package.
2123

22-
Read [documentation pages](https://typelang.dev) for more information.
24+
- Full documentation is [available at typelang.dev](https://typelang.dev).
25+
- Language specification is [available here](https://typelang.dev/static/spec.html).
2326

2427
## Installation
2528

26-
TypeLang Parser is available as Composer repository and can be installed
27-
using the following command in a root of your project:
29+
Install the package via [Composer](https://getcomposer.org):
2830

2931
```sh
3032
composer require type-lang/parser
3133
```
3234

33-
## Quick Start
35+
**Requirements:**
36+
- PHP 8.4+
37+
38+
## Usage
39+
40+
`TypeLang\Parser\TypeParser` is the entry point. Its `parse()` method turns a
41+
type declaration into a `TypeLang\Type\TypeNode`:
3442

3543
```php
36-
$parser = new \TypeLang\Parser\TypeParser();
44+
$parser = new TypeLang\Parser\TypeParser();
3745

38-
$type = $parser->parse(<<<'PHP'
39-
array{
40-
key: callable(Example, int): mixed,
41-
...
42-
}
43-
PHP);
46+
$type = $parser->parse('array{ key: int }');
4447

4548
var_dump($type);
49+
// object(TypeLang\Type\NamedTypeNode) {
50+
// ["name"] => "array"
51+
// ["fields"] => object(TypeLang\Type\Shape\FieldsListNode) { ... }
52+
// ...
53+
// }
4654
```
4755

48-
Expected Output:
56+
Every node exposes an `$offset` (byte offset in the source) plus a handful of
57+
properties describing its kind.
58+
59+
### Strict vs. Tolerant Parsing
60+
61+
- `parse(): TypeNode` — strict mode; requires the whole input to be a valid
62+
type and throws a `ParserExceptionInterface` on the first error.
63+
- `parseTolerant(): ParsedResult` — parses as much as it can and reports how far
64+
it consumed the source. Useful for phpdoc, where a type is followed by a
65+
free-text description.
4966

5067
```php
51-
TypeLang\Type\NamedTypeNode {
52-
+offset: 0
53-
+name: TypeLang\Type\Name {
54-
+offset: 0
55-
-parts: array:1 [
56-
0 => TypeLang\Type\Identifier {
57-
+offset: 0
58-
+value: "array"
59-
}
60-
]
61-
}
62-
+arguments: null
63-
+fields: TypeLang\Type\Shape\FieldsListNode {
64-
+offset: 11
65-
+items: array:1 [
66-
0 => TypeLang\Type\Shape\NamedFieldNode {
67-
+offset: 11
68-
+type: TypeLang\Type\CallableTypeNode {
69-
+offset: 16
70-
+name: TypeLang\Type\Name {
71-
+offset: 16
72-
-parts: array:1 [
73-
0 => TypeLang\Type\Identifier {
74-
+offset: 16
75-
+value: "callable"
76-
}
77-
]
78-
}
79-
+parameters: TypeLang\Type\Callable\ParametersListNode {
80-
+offset: 25
81-
+items: array:2 [
82-
0 => TypeLang\Type\Callable\ParameterNode {
83-
+offset: 25
84-
+type: TypeLang\Type\NamedTypeNode {
85-
+offset: 25
86-
+name: TypeLang\Type\Name {
87-
+offset: 25
88-
-parts: array:1 [
89-
0 => TypeLang\Type\Identifier {
90-
+offset: 25
91-
+value: "Example"
92-
}
93-
]
94-
}
95-
+arguments: null
96-
+fields: null
97-
}
98-
+name: null
99-
+output: false
100-
+variadic: false
101-
+optional: false
102-
}
103-
1 => TypeLang\Type\Callable\ParameterNode {
104-
+offset: 34
105-
+type: TypeLang\Type\NamedTypeNode {
106-
+offset: 34
107-
+name: TypeLang\Type\Name {
108-
+offset: 34
109-
-parts: array:1 [
110-
0 => TypeLang\Type\Identifier {
111-
+offset: 34
112-
+value: "int"
113-
}
114-
]
115-
}
116-
+arguments: null
117-
+fields: null
118-
}
119-
+name: null
120-
+output: false
121-
+variadic: false
122-
+optional: false
123-
}
124-
]
125-
}
126-
+type: TypeLang\Type\NamedTypeNode {
127-
+offset: 40
128-
+name: TypeLang\Type\Name {
129-
+offset: 40
130-
-parts: array:1 [
131-
0 => TypeLang\Type\Identifier {
132-
+offset: 40
133-
+value: "mixed"
134-
}
135-
]
136-
}
137-
+arguments: null
138-
+fields: null
139-
}
140-
}
141-
+optional: false
142-
+key: TypeLang\Type\Identifier {
143-
+offset: 11
144-
+value: "key"
145-
}
146-
}
147-
]
148-
+sealed: false
149-
}
150-
}
68+
$result = $parser->parseTolerant('int and some trailing description');
69+
70+
$result->type; // TypeLang\Type\NamedTypeNode ("int")
71+
$result->offset; // offset where parsing stopped
15172
```
73+
74+
See the [documentation](https://typelang.dev) for feature toggling, visitors and
75+
name resolution.

0 commit comments

Comments
 (0)