php8.1: added readonly modifier (#6)
This commit is contained in:
@@ -899,7 +899,7 @@ func (b *Builder) NewThrowExpr(
|
||||
|
||||
func (b *Builder) NewParameter(
|
||||
AttrGroups []ast.Vertex,
|
||||
Visibility ast.Vertex,
|
||||
Modifiers []ast.Vertex,
|
||||
Type ast.Vertex,
|
||||
AmpersandTkn *token.Token,
|
||||
VariadicTkn *token.Token,
|
||||
@@ -913,8 +913,8 @@ func (b *Builder) NewParameter(
|
||||
if WithDefault {
|
||||
if AttrGroups != nil {
|
||||
pos = b.Pos.NewNodeListNodePosition(AttrGroups, DefaultValue)
|
||||
} else if Visibility != nil {
|
||||
pos = b.Pos.NewNodesPosition(Visibility, DefaultValue)
|
||||
} else if Modifiers != nil {
|
||||
pos = b.Pos.NewNodeListNodePosition(Modifiers, DefaultValue)
|
||||
} else if Type != nil {
|
||||
pos = b.Pos.NewNodesPosition(Type, DefaultValue)
|
||||
} else if AmpersandTkn != nil {
|
||||
@@ -927,8 +927,8 @@ func (b *Builder) NewParameter(
|
||||
} else {
|
||||
if AttrGroups != nil {
|
||||
pos = b.Pos.NewNodeListTokenPosition(AttrGroups, VarTkn)
|
||||
} else if Visibility != nil {
|
||||
pos = b.Pos.NewNodeTokenPosition(Visibility, VarTkn)
|
||||
} else if Modifiers != nil {
|
||||
pos = b.Pos.NewNodeListTokenPosition(Modifiers, VarTkn)
|
||||
} else if Type != nil {
|
||||
pos = b.Pos.NewNodeTokenPosition(Type, VarTkn)
|
||||
} else if AmpersandTkn != nil {
|
||||
@@ -943,7 +943,7 @@ func (b *Builder) NewParameter(
|
||||
return &ast.Parameter{
|
||||
Position: pos,
|
||||
AttrGroups: AttrGroups,
|
||||
Visibility: Visibility,
|
||||
Modifiers: Modifiers,
|
||||
Type: Type,
|
||||
AmpersandTkn: AmpersandTkn,
|
||||
VariadicTkn: VariadicTkn,
|
||||
|
||||
228
internal/php8/parser_php8_1_test.go
Normal file
228
internal/php8/parser_php8_1_test.go
Normal file
@@ -0,0 +1,228 @@
|
||||
package php8_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/VKCOM/php-parser/internal/tester"
|
||||
)
|
||||
|
||||
func TestReadonlyModifier(t *testing.T) {
|
||||
suite := tester.NewParserDumpTestSuite(t)
|
||||
suite.UsePHP8()
|
||||
suite.Code = `<?php
|
||||
class Foo {
|
||||
readonly string $a;
|
||||
private readonly string $a;
|
||||
private string $a;
|
||||
private readonly $a = 100;
|
||||
|
||||
public function __construct(
|
||||
readonly string $a,
|
||||
private readonly string $a,
|
||||
private string $a,
|
||||
private readonly $a = 100,
|
||||
) {}
|
||||
}
|
||||
`
|
||||
|
||||
suite.Expected = `&ast.Root{
|
||||
Stmts: []ast.Vertex{
|
||||
&ast.StmtClass{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("Foo"),
|
||||
},
|
||||
Stmts: []ast.Vertex{
|
||||
&ast.StmtPropertyList{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("readonly"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
&ast.NamePart{
|
||||
Val: []byte("string"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Props: []ast.Vertex{
|
||||
&ast.StmtProperty{
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.StmtPropertyList{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("private"),
|
||||
},
|
||||
&ast.Identifier{
|
||||
Val: []byte("readonly"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
&ast.NamePart{
|
||||
Val: []byte("string"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Props: []ast.Vertex{
|
||||
&ast.StmtProperty{
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.StmtPropertyList{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("private"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
&ast.NamePart{
|
||||
Val: []byte("string"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Props: []ast.Vertex{
|
||||
&ast.StmtProperty{
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.StmtPropertyList{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("private"),
|
||||
},
|
||||
&ast.Identifier{
|
||||
Val: []byte("readonly"),
|
||||
},
|
||||
},
|
||||
Props: []ast.Vertex{
|
||||
&ast.StmtProperty{
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
Expr: &ast.ScalarLnumber{
|
||||
Val: []byte("100"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.StmtClassMethod{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
},
|
||||
},
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("__construct"),
|
||||
},
|
||||
Params: []ast.Vertex{
|
||||
&ast.Parameter{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("readonly"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
&ast.NamePart{
|
||||
Val: []byte("string"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("private"),
|
||||
},
|
||||
&ast.Identifier{
|
||||
Val: []byte("readonly"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
&ast.NamePart{
|
||||
Val: []byte("string"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("private"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
&ast.NamePart{
|
||||
Val: []byte("string"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("private"),
|
||||
},
|
||||
&ast.Identifier{
|
||||
Val: []byte("readonly"),
|
||||
},
|
||||
},
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
Val: []byte("$a"),
|
||||
},
|
||||
},
|
||||
DefaultValue: &ast.ScalarLnumber{
|
||||
Val: []byte("100"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Stmt: &ast.StmtStmtList{
|
||||
Stmts: []ast.Vertex{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},`
|
||||
|
||||
suite.Run()
|
||||
}
|
||||
@@ -3883,8 +3883,10 @@ class Point {
|
||||
},
|
||||
Params: []ast.Vertex{
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
@@ -3903,8 +3905,10 @@ class Point {
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
@@ -3923,8 +3927,10 @@ class Point {
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
Val: []byte("public"),
|
||||
},
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
@@ -4057,18 +4063,20 @@ class Point {
|
||||
},
|
||||
Params: []ast.Vertex{
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
},
|
||||
},
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Var: &ast.ExprVariable{
|
||||
Name: &ast.Identifier{
|
||||
@@ -4087,18 +4095,20 @@ class Point {
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
},
|
||||
},
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
@@ -4134,18 +4144,20 @@ class Point {
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
},
|
||||
},
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
@@ -4185,18 +4197,20 @@ class Point {
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
},
|
||||
},
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
@@ -4255,18 +4269,20 @@ class Point {
|
||||
},
|
||||
},
|
||||
&ast.Parameter{
|
||||
Visibility: &ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
Modifiers: []ast.Vertex{
|
||||
&ast.Identifier{
|
||||
IdentifierTkn: &token.Token{
|
||||
ID: token.T_PUBLIC,
|
||||
Val: []byte("public"),
|
||||
FreeFloating: []*token.Token{
|
||||
{
|
||||
ID: token.T_WHITESPACE,
|
||||
Val: []byte("\n "),
|
||||
},
|
||||
},
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Val: []byte("public"),
|
||||
},
|
||||
Type: &ast.Name{
|
||||
Parts: []ast.Vertex{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -160,6 +160,7 @@ import (
|
||||
%token <token> T_NAME_RELATIVE
|
||||
%token <token> T_NAME_QUALIFIED
|
||||
%token <token> T_NAME_FULLY_QUALIFIED
|
||||
%token <token> T_READONLY
|
||||
%token <token> '"'
|
||||
%token <token> '`'
|
||||
%token <token> '{'
|
||||
@@ -223,7 +224,7 @@ import (
|
||||
%left T_ELSEIF
|
||||
%left T_ELSE
|
||||
%left T_ENDIF
|
||||
%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC
|
||||
%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC T_READONLY
|
||||
|
||||
%type <token> optional_arg_ref optional_ellipsis returns_ref
|
||||
|
||||
@@ -281,7 +282,7 @@ import (
|
||||
%type <node> expr_list_allow_comma non_empty_expr_list
|
||||
%type <node> match match_arm match_arm_list non_empty_match_arm_list
|
||||
%type <node> catch_list catch
|
||||
%type <node> optional_visibility_modifier
|
||||
%type <node> property_modifier
|
||||
%type <node> attribute_decl attribute_group attribute
|
||||
|
||||
%type <node> member_modifier
|
||||
@@ -293,6 +294,7 @@ import (
|
||||
%type <list> top_statement_list
|
||||
%type <list> inner_statement_list class_statement_list
|
||||
%type <list> method_modifiers variable_modifiers
|
||||
%type <list> optional_property_modifiers
|
||||
%type <list> non_empty_member_modifiers class_modifiers optional_class_modifiers
|
||||
%type <list> optional_attributes attributes
|
||||
|
||||
@@ -328,7 +330,8 @@ semi_reserved:
|
||||
{
|
||||
$$ = $1
|
||||
}
|
||||
| T_STATIC {$$=$1} | T_ABSTRACT {$$=$1} | T_FINAL {$$=$1} | T_PRIVATE {$$=$1} | T_PROTECTED {$$=$1} | T_PUBLIC {$$=$1}
|
||||
| T_STATIC {$$=$1} | T_ABSTRACT {$$=$1} | T_FINAL {$$=$1} | T_PRIVATE {$$=$1}
|
||||
| T_PROTECTED {$$=$1} | T_PUBLIC {$$=$1} | T_READONLY {$$=$1}
|
||||
;
|
||||
|
||||
identifier:
|
||||
@@ -1244,27 +1247,32 @@ alt_if_stmt:
|
||||
;
|
||||
|
||||
parameter_list:
|
||||
non_empty_parameter_list possible_comma { $$ = yylex.(*Parser).builder.AppendToSeparatedList($1, $2, nil) }
|
||||
| /* empty */ { $$ = yylex.(*Parser).builder.NewEmptySeparatedList() }
|
||||
non_empty_parameter_list possible_comma { $$ = yylex.(*Parser).builder.AppendToSeparatedList($1, $2, nil) }
|
||||
| /* empty */ { $$ = yylex.(*Parser).builder.NewEmptySeparatedList() }
|
||||
;
|
||||
|
||||
non_empty_parameter_list:
|
||||
parameter { $$ = yylex.(*Parser).builder.NewSeparatedList($1) }
|
||||
| non_empty_parameter_list ',' parameter { $$ = yylex.(*Parser).builder.AppendToSeparatedList($1, $2, $3) }
|
||||
parameter { $$ = yylex.(*Parser).builder.NewSeparatedList($1) }
|
||||
| non_empty_parameter_list ',' parameter { $$ = yylex.(*Parser).builder.AppendToSeparatedList($1, $2, $3) }
|
||||
;
|
||||
|
||||
optional_visibility_modifier:
|
||||
/* empty */ { $$ = nil; }
|
||||
| T_PUBLIC { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_PROTECTED { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_PRIVATE { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
optional_property_modifiers:
|
||||
/* empty */ { $$ = nil }
|
||||
| optional_property_modifiers property_modifier { $$ = append($1, $2) }
|
||||
;
|
||||
|
||||
property_modifier:
|
||||
T_PUBLIC { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_PROTECTED { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_PRIVATE { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_READONLY { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
;
|
||||
|
||||
parameter:
|
||||
optional_attributes optional_visibility_modifier optional_type_without_static
|
||||
optional_attributes optional_property_modifiers optional_type_without_static
|
||||
optional_arg_ref optional_ellipsis plain_variable
|
||||
{ $$ = yylex.(*Parser).builder.NewParameter($1, $2, $3, $4, $5, $6, nil, nil, false) }
|
||||
| optional_attributes optional_visibility_modifier optional_type_without_static
|
||||
| optional_attributes optional_property_modifiers optional_type_without_static
|
||||
optional_arg_ref optional_ellipsis plain_variable '=' expr
|
||||
{ $$ = yylex.(*Parser).builder.NewParameter($1, $2, $3, $4, $5, $6, $7, $8, true) }
|
||||
;
|
||||
@@ -1664,6 +1672,7 @@ member_modifier:
|
||||
| T_STATIC { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_ABSTRACT { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_FINAL { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
| T_READONLY { $$ = yylex.(*Parser).builder.NewIdentifier($1) }
|
||||
;
|
||||
|
||||
property_list:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -252,6 +252,7 @@ func (lex *Lexer) Lex() *token.Token {
|
||||
'print'i => {lex.setTokenPosition(tkn); tok = token.T_PRINT; fbreak;};
|
||||
'protected'i => {lex.setTokenPosition(tkn); tok = token.T_PROTECTED; fbreak;};
|
||||
'return'i => {lex.setTokenPosition(tkn); tok = token.T_RETURN; fbreak;};
|
||||
'readonly'i => {lex.setTokenPosition(tkn); tok = token.T_READONLY; fbreak;};
|
||||
'static'i => {lex.setTokenPosition(tkn); tok = token.T_STATIC; fbreak;};
|
||||
'switch'i => {lex.setTokenPosition(tkn); tok = token.T_SWITCH; fbreak;};
|
||||
'match'i => {lex.setTokenPosition(tkn); tok = token.T_MATCH; fbreak;};
|
||||
|
||||
33
internal/php8/scanner_php8_1_test.go
Normal file
33
internal/php8/scanner_php8_1_test.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package php8_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/VKCOM/php-parser/internal/tester"
|
||||
"github.com/VKCOM/php-parser/pkg/token"
|
||||
)
|
||||
|
||||
func TestReadonlyTokens(t *testing.T) {
|
||||
suite := tester.NewLexerTokenStructTestSuite(t)
|
||||
suite.UsePHP8()
|
||||
suite.Code = "<?php readonly public $a;"
|
||||
suite.Expected = []*token.Token{
|
||||
{
|
||||
ID: token.T_READONLY,
|
||||
Value: []byte("readonly"),
|
||||
},
|
||||
{
|
||||
ID: token.T_PUBLIC,
|
||||
Value: []byte("public"),
|
||||
},
|
||||
{
|
||||
ID: token.T_VARIABLE,
|
||||
Value: []byte("$a"),
|
||||
},
|
||||
{
|
||||
ID: ';',
|
||||
Value: []byte(";"),
|
||||
},
|
||||
}
|
||||
suite.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user