Skip to content

Commit

Permalink
feat: support disjunctive normal form types
Browse files Browse the repository at this point in the history
  • Loading branch information
calebdw committed Jan 5, 2024
1 parent 657546d commit 36404bd
Show file tree
Hide file tree
Showing 8 changed files with 132,410 additions and 130,225 deletions.
16 changes: 13 additions & 3 deletions common/define-grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ module.exports = function defineGrammar(dialect) {
[$._array_destructing_element, $.array_element_initializer],
[$._primary_expression, $._array_destructing_element],

[$.union_type, $.intersection_type],
[$.union_type, $.intersection_type, $.disjunctive_normal_form_type],
[$.union_type, $.disjunctive_normal_form_type],
[$.intersection_type],
[$.if_statement],

Expand Down Expand Up @@ -517,7 +518,11 @@ module.exports = function defineGrammar(dialect) {
field('name', $.variable_name),
),

_type: $ => choice($.union_type, $.intersection_type),
_type: $ => choice(
$.union_type,
$.intersection_type,
$.disjunctive_normal_form_type,
),

_types: $ => choice(
$.optional_type,
Expand All @@ -537,10 +542,15 @@ module.exports = function defineGrammar(dialect) {

bottom_type: _ => 'never',

union_type: $ => prec.right(pipeSep1($._types)),
union_type: $ => prec.dynamic(1, pipeSep1($._types)),

intersection_type: $ => ampSep1($._types),

disjunctive_normal_form_type: $ => pipeSep1(choice(
seq('(', $.intersection_type, ')'),
$._types,
)),

primitive_type: _ => choice(
'array',
keyword('callable'), // not legal in property types
Expand Down
107 changes: 106 additions & 1 deletion common/test/corpus/types.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ function d(): never {}
(bottom_type)
(compound_statement)))


=======================
Intersection type
=======================
Expand Down Expand Up @@ -132,6 +131,112 @@ function test(Type&MoreTypes &$b) {}
)
)

=======================
Disjunctive Normal Form type
=======================
<?php

class Test {
public (A&B)|C|null $prop;
}

function test((A&B)|(A&C) $a): A|(A&B)|(A&C)|D {}

function test((Type&MoreTypes)|A|B &... $b) {}

function test(A|B|(Type&MoreTypes)|C &$b) {}
---
(program
(php_tag)
(class_declaration
(name)
(declaration_list
(property_declaration
(visibility_modifier)
(disjunctive_normal_form_type
(intersection_type
(named_type (name))
(named_type (name))
)
(named_type (name))
(primitive_type)
)
(property_element
(variable_name (name))
)
)
)
)
(function_definition
(name)
(formal_parameters
(simple_parameter
(disjunctive_normal_form_type
(intersection_type
(named_type (name))
(named_type (name))
)
(intersection_type
(named_type (name))
(named_type (name))
)
)
(variable_name (name))
)
)
(disjunctive_normal_form_type
(named_type (name))
(intersection_type
(named_type (name))
(named_type (name))
)
(intersection_type
(named_type (name))
(named_type (name))
)
(named_type (name))
)
(compound_statement)
)
(function_definition
(name)
(formal_parameters
(variadic_parameter
(disjunctive_normal_form_type
(intersection_type
(named_type (name))
(named_type (name))
)
(named_type (name))
(named_type (name))
)
(reference_modifier)
(variable_name (name))
)
)
(compound_statement)
)
(function_definition
(name)
(formal_parameters
(simple_parameter
(disjunctive_normal_form_type
(named_type (name))
(named_type (name))
(intersection_type
(named_type (name))
(named_type (name))
)
(named_type (name))
)
(reference_modifier)
(variable_name (name))
)
)
(compound_statement)
)
)

=======================
Optional types
=======================
Expand Down
84 changes: 81 additions & 3 deletions php/src/grammar.json
Original file line number Diff line number Diff line change
Expand Up @@ -2582,6 +2582,10 @@
{
"type": "SYMBOL",
"name": "intersection_type"
},
{
"type": "SYMBOL",
"name": "disjunctive_normal_form_type"
}
]
},
Expand Down Expand Up @@ -2642,8 +2646,8 @@
"value": "never"
},
"union_type": {
"type": "PREC_RIGHT",
"value": 0,
"type": "PREC_DYNAMIC",
"value": 1,
"content": {
"type": "SEQ",
"members": [
Expand Down Expand Up @@ -2698,6 +2702,75 @@
}
]
},
"disjunctive_normal_form_type": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "intersection_type"
},
{
"type": "STRING",
"value": ")"
}
]
},
{
"type": "SYMBOL",
"name": "_types"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "intersection_type"
},
{
"type": "STRING",
"value": ")"
}
]
},
{
"type": "SYMBOL",
"name": "_types"
}
]
}
]
}
}
]
},
"primitive_type": {
"type": "CHOICE",
"members": [
Expand Down Expand Up @@ -8945,7 +9018,12 @@
],
[
"union_type",
"intersection_type"
"intersection_type",
"disjunctive_normal_form_type"
],
[
"union_type",
"disjunctive_normal_form_type"
],
[
"intersection_type"
Expand Down
35 changes: 33 additions & 2 deletions php/src/node-types.json
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@
"type": "_type",
"named": true,
"subtypes": [
{
"type": "disjunctive_normal_form_type",
"named": true
},
{
"type": "intersection_type",
"named": true
Expand Down Expand Up @@ -1643,6 +1647,33 @@
]
}
},
{
"type": "disjunctive_normal_form_type",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "intersection_type",
"named": true
},
{
"type": "named_type",
"named": true
},
{
"type": "optional_type",
"named": true
},
{
"type": "primitive_type",
"named": true
}
]
}
},
{
"type": "do_statement",
"named": true,
Expand Down Expand Up @@ -5491,11 +5522,11 @@
},
{
"type": "null",
"named": true
"named": false
},
{
"type": "null",
"named": false
"named": true
},
{
"type": "or",
Expand Down
Loading

0 comments on commit 36404bd

Please sign in to comment.