PHP 8 Update

- nullsafe operator (?->)
- Remove (real) cast
- Named arguments
- Remove (unset) cast
- Remove {} access
- match expression
- Union types in type hints and static typehint
- Block catch without variable
- Trailing comma in parameter lists
- throw can be used as an expression
- Concatenation precedence
- Declaring properties in the constructor
- Attributes
- Names in the namespace are treated as a single token
- Trailing comma in closure use list
- Check that ::class on object works
- Deferencable changes and arbitrary expressions in new/instanceof
This commit is contained in:
Makhnev Petr
2021-07-30 20:53:27 +03:00
committed by GitHub
parent 367eff9de6
commit 049ce7ddc6
40 changed files with 108754 additions and 264 deletions

View File

@@ -0,0 +1,62 @@
package tester
import (
"testing"
"github.com/z7zmey/php-parser/internal/php8"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/token"
"github.com/z7zmey/php-parser/pkg/version"
"gotest.tools/assert"
)
type Lexer interface {
Lex() *token.Token
}
type LexerTokenFreeFloatingTestSuite struct {
t *testing.T
Code string
Expected [][]*token.Token
Version version.Version
}
func NewLexerTokenFreeFloatingTestSuite(t *testing.T) *LexerTokenFreeFloatingTestSuite {
return &LexerTokenFreeFloatingTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
}
}
func (l *LexerTokenFreeFloatingTestSuite) UsePHP8() {
l.Version = version.Version{Major: 8, Minor: 0}
}
func (l *LexerTokenFreeFloatingTestSuite) Run() {
config := conf.Config{
Version: &l.Version,
}
var lexer Lexer
if l.Version.Less(&version.Version{Major: 8, Minor: 0}) {
lexer = scanner.NewLexer([]byte(l.Code), config)
} else {
lexer = php8.NewLexer([]byte(l.Code), config)
}
for _, expected := range l.Expected {
tkn := lexer.Lex()
actual := tkn.FreeFloating
for _, v := range actual {
v.Position = nil
}
assert.DeepEqual(l.t, expected, actual)
}
}

View File

@@ -0,0 +1,54 @@
package tester
import (
"testing"
"github.com/z7zmey/php-parser/internal/php8"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/version"
"gotest.tools/assert"
)
type LexerTokenStringTestSuite struct {
t *testing.T
Code string
Expected []string
Version version.Version
}
func NewLexerTokenStringTestSuite(t *testing.T) *LexerTokenStringTestSuite {
return &LexerTokenStringTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
}
}
func (l *LexerTokenStringTestSuite) UsePHP8() {
l.Version = version.Version{Major: 8, Minor: 0}
}
func (l *LexerTokenStringTestSuite) Run() {
config := conf.Config{
Version: &l.Version,
}
var lexer Lexer
if l.Version.Less(&version.Version{Major: 8, Minor: 0}) {
lexer = scanner.NewLexer([]byte(l.Code), config)
} else {
lexer = php8.NewLexer([]byte(l.Code), config)
}
for _, expected := range l.Expected {
tkn := lexer.Lex()
actual := string(tkn.Value)
assert.DeepEqual(l.t, expected, actual)
}
}

View File

@@ -0,0 +1,56 @@
package tester
import (
"testing"
"github.com/z7zmey/php-parser/internal/php8"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/token"
"github.com/z7zmey/php-parser/pkg/version"
"gotest.tools/assert"
)
type LexerTokenStructTestSuite struct {
t *testing.T
Code string
Expected []*token.Token
Version version.Version
}
func NewLexerTokenStructTestSuite(t *testing.T) *LexerTokenStructTestSuite {
return &LexerTokenStructTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
}
}
func (l *LexerTokenStructTestSuite) UsePHP8() {
l.Version = version.Version{Major: 8, Minor: 0}
}
func (l *LexerTokenStructTestSuite) Run() {
config := conf.Config{
Version: &l.Version,
}
var lexer Lexer
if l.Version.Less(&version.Version{Major: 8, Minor: 0}) {
lexer = scanner.NewLexer([]byte(l.Code), config)
} else {
lexer = php8.NewLexer([]byte(l.Code), config)
}
for _, expected := range l.Expected {
actual := lexer.Lex()
actual.Position = nil
actual.FreeFloating = nil
assert.DeepEqual(l.t, expected, actual)
}
}

View File

@@ -0,0 +1,60 @@
package tester
import (
"bytes"
"testing"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/parser"
"github.com/z7zmey/php-parser/pkg/version"
"github.com/z7zmey/php-parser/pkg/visitor/printer"
"gotest.tools/assert"
)
type ParserPrintTestSuite struct {
t *testing.T
Version version.Version
}
func NewParserPrintTestSuite(t *testing.T) *ParserPrintTestSuite {
return &ParserPrintTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
}
}
func (p *ParserPrintTestSuite) UsePHP8() *ParserPrintTestSuite {
p.Version = version.Version{Major: 8, Minor: 0}
return p
}
func (p *ParserPrintTestSuite) Run(code string) {
actual := p.print(p.parse(code))
assert.DeepEqual(p.t, code, actual)
}
func (p *ParserPrintTestSuite) parse(src string) ast.Vertex {
config := conf.Config{
Version: &p.Version,
}
root, err := parser.Parse([]byte(src), config)
if err != nil {
p.t.Fatal(err)
}
return root
}
func (p *ParserPrintTestSuite) print(n ast.Vertex) string {
o := bytes.NewBufferString("")
pr := printer.NewPrinter(o)
n.Accept(pr)
return o.String()
}

46
internal/tester/parser.go Normal file
View File

@@ -0,0 +1,46 @@
package tester
import (
"testing"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/parser"
"github.com/z7zmey/php-parser/pkg/version"
"gotest.tools/assert"
)
type ParserTestSuite struct {
t *testing.T
Code string
Expected ast.Vertex
Version version.Version
}
func NewParserTestSuite(t *testing.T) *ParserTestSuite {
return &ParserTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
}
}
func (p *ParserTestSuite) UsePHP8() {
p.Version = version.Version{Major: 8, Minor: 0}
}
func (p *ParserTestSuite) Run() {
config := conf.Config{
Version: &p.Version,
}
actual, err := parser.Parse([]byte(p.Code), config)
if err != nil {
p.t.Fatalf("Error parse: %v", err)
}
assert.DeepEqual(p.t, p.Expected, actual)
}

View File

@@ -0,0 +1,64 @@
package tester
import (
"bytes"
"testing"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/parser"
"github.com/z7zmey/php-parser/pkg/version"
"github.com/z7zmey/php-parser/pkg/visitor/dumper"
"gotest.tools/assert"
)
type ParserDumpTestSuite struct {
t *testing.T
Code string
Expected string
Version version.Version
actualDump *bytes.Buffer
dumper *dumper.Dumper
}
func NewParserDumpTestSuite(t *testing.T) *ParserDumpTestSuite {
actualDump := bytes.NewBuffer(nil)
return &ParserDumpTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
actualDump: actualDump,
dumper: dumper.NewDumper(actualDump),
}
}
func (p *ParserDumpTestSuite) WithTokens() {
p.dumper = p.dumper.WithTokens()
}
func (p *ParserDumpTestSuite) WithPositions() {
p.dumper = p.dumper.WithPositions()
}
func (p *ParserDumpTestSuite) UsePHP8() {
p.Version = version.Version{Major: 8, Minor: 0}
}
func (p *ParserDumpTestSuite) Run() {
config := conf.Config{
Version: &p.Version,
}
actual, err := parser.Parse([]byte(p.Code), config)
if err != nil {
p.t.Fatalf("Error parse: %v", err)
}
p.dumper.Dump(actual)
assert.DeepEqual(p.t, p.Expected+"\n", p.actualDump.String())
}

View File

@@ -0,0 +1,52 @@
package tester
import (
"testing"
"github.com/z7zmey/php-parser/pkg/conf"
"github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/pkg/parser"
"github.com/z7zmey/php-parser/pkg/version"
"gotest.tools/assert"
)
type ParserErrorTestSuite struct {
t *testing.T
Code string
Expected []*errors.Error
Version version.Version
}
func NewParserErrorTestSuite(t *testing.T) *ParserErrorTestSuite {
return &ParserErrorTestSuite{
t: t,
Version: version.Version{
Major: 7,
Minor: 4,
},
}
}
func (p *ParserErrorTestSuite) UsePHP8() {
p.Version = version.Version{Major: 8, Minor: 0}
}
func (p *ParserErrorTestSuite) Run() {
config := conf.Config{
Version: &p.Version,
}
var errs []*errors.Error
config.ErrorHandlerFunc = func(e *errors.Error) {
errs = append(errs, e)
}
_, err := parser.Parse([]byte(p.Code), config)
if err != nil {
p.t.Fatalf("Error parse: %v", err)
}
assert.DeepEqual(p.t, p.Expected, errs)
}