Skip to content

Commit e166717

Browse files
authored
php8.1: added intersection types support (#29)
1 parent 7f6cd25 commit e166717

21 files changed

+12860
-12047
lines changed

internal/php8/builder.go

+18
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,24 @@ func (b *Builder) NewUnionType(
789789
}
790790
}
791791

792+
func (b *Builder) NewIntersectionType(
793+
Types ast.Vertex,
794+
) *ast.Intersection {
795+
var types []ast.Vertex
796+
var sepTkns []*token.Token
797+
if Types != nil {
798+
cases := Types.(*ParserSeparatedList)
799+
types = cases.Items
800+
sepTkns = cases.SeparatorTkns
801+
}
802+
803+
return &ast.Intersection{
804+
Position: b.Pos.NewNodeListPosition(types),
805+
Types: types,
806+
SeparatorTkns: sepTkns,
807+
}
808+
}
809+
792810
func (b *Builder) NewReturnType(
793811
ColonTkn *token.Token,
794812
Type ast.Vertex,

internal/php8/lexer.go

+15
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,21 @@ func (lex *Lexer) ungetCnt(n int) {
227227
lex.te = lex.te - n
228228
}
229229

230+
func (lex *Lexer) ungetWhile(s byte) {
231+
for i := 0; i < 100; i++ {
232+
v := lex.data[lex.te]
233+
if v == s {
234+
break
235+
}
236+
237+
lex.te--
238+
lex.p--
239+
}
240+
241+
lex.te++
242+
lex.p++
243+
}
244+
230245
func (lex *Lexer) error(msg string) {
231246
if lex.errHandlerFunc == nil {
232247
return

internal/php8/parser_php8_1_test.go

+111
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,114 @@ enum C: int implements Bar {}
322322

323323
suite.Run()
324324
}
325+
326+
func TestIntersectionTypes(t *testing.T) {
327+
suite := tester.NewParserDumpTestSuite(t)
328+
suite.UsePHP8()
329+
suite.Code = `<?php
330+
class Test {
331+
public A&B $prop;
332+
}
333+
334+
function test(A&B $a): A&B {}
335+
`
336+
337+
suite.Expected = `&ast.Root{
338+
Stmts: []ast.Vertex{
339+
&ast.StmtClass{
340+
Name: &ast.Identifier{
341+
Val: []byte("Test"),
342+
},
343+
Stmts: []ast.Vertex{
344+
&ast.StmtPropertyList{
345+
Modifiers: []ast.Vertex{
346+
&ast.Identifier{
347+
Val: []byte("public"),
348+
},
349+
},
350+
Type: &ast.Intersection{
351+
Types: []ast.Vertex{
352+
&ast.Name{
353+
Parts: []ast.Vertex{
354+
&ast.NamePart{
355+
Val: []byte("A"),
356+
},
357+
},
358+
},
359+
&ast.Name{
360+
Parts: []ast.Vertex{
361+
&ast.NamePart{
362+
Val: []byte("B"),
363+
},
364+
},
365+
},
366+
},
367+
},
368+
Props: []ast.Vertex{
369+
&ast.StmtProperty{
370+
Var: &ast.ExprVariable{
371+
Name: &ast.Identifier{
372+
Val: []byte("$prop"),
373+
},
374+
},
375+
},
376+
},
377+
},
378+
},
379+
},
380+
&ast.StmtFunction{
381+
Name: &ast.Identifier{
382+
Val: []byte("test"),
383+
},
384+
Params: []ast.Vertex{
385+
&ast.Parameter{
386+
Type: &ast.Intersection{
387+
Types: []ast.Vertex{
388+
&ast.Name{
389+
Parts: []ast.Vertex{
390+
&ast.NamePart{
391+
Val: []byte("A"),
392+
},
393+
},
394+
},
395+
&ast.Name{
396+
Parts: []ast.Vertex{
397+
&ast.NamePart{
398+
Val: []byte("B"),
399+
},
400+
},
401+
},
402+
},
403+
},
404+
Var: &ast.ExprVariable{
405+
Name: &ast.Identifier{
406+
Val: []byte("$a"),
407+
},
408+
},
409+
},
410+
},
411+
ReturnType: &ast.Intersection{
412+
Types: []ast.Vertex{
413+
&ast.Name{
414+
Parts: []ast.Vertex{
415+
&ast.NamePart{
416+
Val: []byte("A"),
417+
},
418+
},
419+
},
420+
&ast.Name{
421+
Parts: []ast.Vertex{
422+
&ast.NamePart{
423+
Val: []byte("B"),
424+
},
425+
},
426+
},
427+
},
428+
},
429+
Stmts: []ast.Vertex{},
430+
},
431+
},
432+
},`
433+
434+
suite.Run()
435+
}

internal/php8/parser_php8_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -4177,7 +4177,7 @@ class Point {
41774177
},
41784178
},
41794179
AmpersandTkn: &token.Token{
4180-
ID: token.ID(38),
4180+
ID: token.ID(57492),
41814181
Val: []byte("&"),
41824182
FreeFloating: []*token.Token{
41834183
{
@@ -4302,7 +4302,7 @@ class Point {
43024302
},
43034303
},
43044304
AmpersandTkn: &token.Token{
4305-
ID: token.ID(38),
4305+
ID: token.ID(57492),
43064306
Val: []byte("&"),
43074307
FreeFloating: []*token.Token{
43084308
{

internal/php8/parser_test.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -1972,7 +1972,7 @@ func TestPhp8ParameterNode(t *testing.T) {
19721972
},
19731973
},
19741974
AmpersandTkn: &token.Token{
1975-
ID: token.ID(38),
1975+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
19761976
Value: []byte("&"),
19771977
Position: &position.Position{
19781978
StartLine: 2,
@@ -2453,7 +2453,7 @@ func TestPhp8ParameterNode(t *testing.T) {
24532453
},
24542454
},
24552455
AmpersandTkn: &token.Token{
2456-
ID: token.ID(38),
2456+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
24572457
Value: []byte("&"),
24582458
Position: &position.Position{
24592459
StartLine: 3,
@@ -2826,7 +2826,7 @@ func TestPhp8ParameterNode(t *testing.T) {
28262826
},
28272827
},
28282828
AmpersandTkn: &token.Token{
2829-
ID: token.ID(38),
2829+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
28302830
Value: []byte("&"),
28312831
Position: &position.Position{
28322832
StartLine: 4,
@@ -3212,7 +3212,7 @@ func TestPhp8ParameterNode(t *testing.T) {
32123212
},
32133213
},
32143214
AmpersandTkn: &token.Token{
3215-
ID: token.ID(38),
3215+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
32163216
Value: []byte("&"),
32173217
Position: &position.Position{
32183218
StartLine: 5,
@@ -10102,7 +10102,7 @@ func TestStmtClassMethod_Php8ClassMethod(t *testing.T) {
1010210102
},
1010310103
},
1010410104
AmpersandTkn: &token.Token{
10105-
ID: token.ID(38),
10105+
ID: token.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG,
1010610106
Value: []byte("&"),
1010710107
Position: &position.Position{
1010810108
StartLine: 1,
@@ -16870,7 +16870,7 @@ func TestStmtForeach_WithRef(t *testing.T) {
1687016870
},
1687116871
},
1687216872
AmpersandTkn: &token.Token{
16873-
ID: token.ID(38),
16873+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
1687416874
Value: []byte("&"),
1687516875
Position: &position.Position{
1687616876
StartLine: 1,
@@ -18087,7 +18087,7 @@ func TestStmtFunction_Ref(t *testing.T) {
1808718087
},
1808818088
},
1808918089
AmpersandTkn: &token.Token{
18090-
ID: token.ID(38),
18090+
ID: token.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG,
1809118091
Value: []byte("&"),
1809218092
Position: &position.Position{
1809318093
StartLine: 1,
@@ -18309,7 +18309,7 @@ func TestStmtFunction_ReturnType(t *testing.T) {
1830918309
},
1831018310
},
1831118311
AmpersandTkn: &token.Token{
18312-
ID: token.ID(38),
18312+
ID: token.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG,
1831318313
Value: []byte("&"),
1831418314
Position: &position.Position{
1831518315
StartLine: 1,
@@ -35439,7 +35439,7 @@ func TestExprArray_Items(t *testing.T) {
3543935439
EndPos: 18,
3544035440
},
3544135441
AmpersandTkn: &token.Token{
35442-
ID: token.ID(38),
35442+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
3544335443
Value: []byte("&"),
3544435444
Position: &position.Position{
3544535445
StartLine: 1,
@@ -35929,7 +35929,7 @@ func TestExprArrowFunction_ReturnType(t *testing.T) {
3592935929
},
3593035930
},
3593135931
AmpersandTkn: &token.Token{
35932-
ID: token.ID(38),
35932+
ID: token.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG,
3593335933
Value: []byte("&"),
3593435934
Position: &position.Position{
3593535935
StartLine: 1,
@@ -37273,7 +37273,7 @@ func TestExprClosure_Use(t *testing.T) {
3727337273
EndPos: 32,
3727437274
},
3727537275
AmpersandTkn: &token.Token{
37276-
ID: token.ID(38),
37276+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
3727737277
Value: []byte("&"),
3727837278
Position: &position.Position{
3727937279
StartLine: 1,
@@ -37633,7 +37633,7 @@ func TestExprClosure_Use2(t *testing.T) {
3763337633
EndPos: 28,
3763437634
},
3763537635
AmpersandTkn: &token.Token{
37636-
ID: token.ID(38),
37636+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
3763737637
Value: []byte("&"),
3763837638
Position: &position.Position{
3763937639
StartLine: 1,
@@ -45056,7 +45056,7 @@ func TestExprShortArray_Items(t *testing.T) {
4505645056
EndPos: 13,
4505745057
},
4505845058
AmpersandTkn: &token.Token{
45059-
ID: token.ID(38),
45059+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
4506045060
Value: []byte("&"),
4506145061
Position: &position.Position{
4506245062
StartLine: 1,
@@ -49734,7 +49734,7 @@ func TestExprAssign_Assign(t *testing.T) {
4973449734
},
4973549735
},
4973649736
AmpersandTkn: &token.Token{
49737-
ID: token.ID(38),
49737+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
4973849738
Value: []byte("&"),
4973949739
Position: &position.Position{
4974049740
StartLine: 3,
@@ -49870,7 +49870,7 @@ func TestExprAssign_Assign(t *testing.T) {
4987049870
},
4987149871
},
4987249872
AmpersandTkn: &token.Token{
49873-
ID: token.ID(38),
49873+
ID: token.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG,
4987449874
Value: []byte("&"),
4987549875
Position: &position.Position{
4987649876
StartLine: 4,
@@ -50038,7 +50038,7 @@ func TestExprAssign_Assign(t *testing.T) {
5003850038
},
5003950039
},
5004050040
AmpersandTkn: &token.Token{
50041-
ID: token.ID(38),
50041+
ID: token.T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG,
5004250042
Value: []byte("&"),
5004350043
Position: &position.Position{
5004450044
StartLine: 5,
@@ -51946,7 +51946,7 @@ func TestExprBinary_BitwiseAnd(t *testing.T) {
5194651946
},
5194751947
},
5194851948
OpTkn: &token.Token{
51949-
ID: token.ID(38),
51949+
ID: token.T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG,
5195051950
Value: []byte("&"),
5195151951
Position: &position.Position{
5195251952
StartLine: 2,

0 commit comments

Comments
 (0)