refactoring: update api

This commit is contained in:
Vadym Slizov
2020-12-29 21:23:22 +02:00
parent cb4b4e69c4
commit e3b133f3de
17 changed files with 4086 additions and 1094 deletions

11
pkg/cfg/cfg.go Normal file
View File

@@ -0,0 +1,11 @@
package cfg
import (
"github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/pkg/version"
)
type Config struct {
Version *version.Version
ErrorHandlerFunc func(e *errors.Error)
}

View File

@@ -1,12 +1,25 @@
package parser
import (
"errors"
"github.com/z7zmey/php-parser/internal/php5"
"github.com/z7zmey/php-parser/internal/php7"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/internal/version"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/pkg/cfg"
"github.com/z7zmey/php-parser/pkg/version"
)
var (
// ErrVersionOutOfRange is returned if the version is not supported
ErrVersionOutOfRange = errors.New("the version is out of supported range")
php5RangeStart = &version.Version{Major: 5}
php5RangeEnd = &version.Version{Major: 5, Minor: 6}
php7RangeStart = &version.Version{Major: 7}
php7RangeEnd = &version.Version{Major: 7, Minor: 4}
)
// Parser interface
@@ -15,29 +28,26 @@ type Parser interface {
GetRootNode() ast.Vertex
}
type Config struct {
WithTokens bool
WithPositions bool
ErrorHandlerFunc func(e *errors.Error)
}
func Parse(src []byte, ver string, cfg Config) (ast.Vertex, error) {
func Parse(src []byte, config cfg.Config) (ast.Vertex, error) {
var parser Parser
r, err := version.Compare(ver, "7.0")
if err != nil {
return nil, err
if config.Version == nil {
config.Version = php7RangeEnd
}
lexer := scanner.NewLexer(src, ver, cfg.ErrorHandlerFunc)
if r == -1 {
parser = php5.NewParser(lexer, cfg.ErrorHandlerFunc)
} else {
parser = php7.NewParser(lexer, cfg.ErrorHandlerFunc)
if config.Version.InRange(php5RangeStart, php5RangeEnd) {
lexer := scanner.NewLexer(src, config)
parser = php5.NewParser(lexer, config)
parser.Parse()
return parser.GetRootNode(), nil
}
parser.Parse()
if config.Version.InRange(php7RangeStart, php7RangeEnd) {
lexer := scanner.NewLexer(src, config)
parser = php7.NewParser(lexer, config)
parser.Parse()
return parser.GetRootNode(), nil
}
return parser.GetRootNode(), nil
return nil, ErrVersionOutOfRange
}

102
pkg/version/version.go Normal file
View File

@@ -0,0 +1,102 @@
package version
import (
"errors"
"strconv"
"strings"
)
type Version struct {
Major, Minor uint64
}
var (
// ErrInvalidSemVer is returned if a version can not be parsed
ErrInvalidSemVer = errors.New("invalid semantic version")
// ErrUnsupportedVer is returned if a version out of supported range
ErrUnsupportedVer = errors.New("the version is out of supported range")
php5RangeStart = &Version{Major: 5}
php5RangeEnd = &Version{Major: 5, Minor: 6}
php7RangeStart = &Version{Major: 7}
php7RangeEnd = &Version{Major: 7, Minor: 4}
)
func New(v string) (*Version, error) {
// Split the parts into [0]Major, [1]Minor
parts := strings.SplitN(v, ".", 2)
if len(parts) != 2 {
return nil, ErrInvalidSemVer
}
var ver = new(Version)
var err error
ver.Major, err = strconv.ParseUint(parts[0], 10, 64)
if err != nil {
return nil, err
}
ver.Minor, err = strconv.ParseUint(parts[1], 10, 64)
if err != nil {
return nil, err
}
return ver, nil
}
func (v *Version) Validate() error {
if !v.InRange(php5RangeStart, php5RangeEnd) && !v.InRange(php7RangeStart, php7RangeEnd) {
return ErrUnsupportedVer
}
return nil
}
// Less tests if one version is less than another one
func (v *Version) Less(o *Version) bool {
return v.Compare(o) < 0
}
// LessOrEqual tests if one version is less than another one or equal
func (v *Version) LessOrEqual(o *Version) bool {
return v.Compare(o) <= 0
}
// Greater tests if one version is greater than another one
func (v *Version) Greater(o *Version) bool {
return v.Compare(o) > 0
}
// GreaterOrEqual tests if one version is greater than another one or equal
func (v *Version) GreaterOrEqual(o *Version) bool {
return v.Compare(o) >= 0
}
// GreaterOrEqual tests if one version is greater than another one or equal
func (v *Version) InRange(s, e *Version) bool {
return v.Compare(s) >= 0 && v.Compare(e) <= 0
}
// Compare compares this version to another one. It returns -1, 0, or 1 if
// the version smaller, equal, or larger than the other version.
func (v *Version) Compare(o *Version) int {
if d := compareSegment(v.Major, o.Major); d != 0 {
return d
}
return compareSegment(v.Minor, o.Minor)
}
func compareSegment(v, o uint64) int {
if v < o {
return -1
}
if v > o {
return 1
}
return 0
}

View File

@@ -0,0 +1,48 @@
package version_test
import (
"gotest.tools/assert"
"testing"
"github.com/z7zmey/php-parser/pkg/version"
)
func Test(t *testing.T) {
ver, err := version.New("7.4")
assert.NilError(t, err)
assert.Equal(t, *ver, version.Version{
Major: 7,
Minor: 4,
})
}
func TestLeadingZero(t *testing.T) {
ver, err := version.New("07.04")
assert.NilError(t, err)
assert.Equal(t, *ver, version.Version{
Major: 7,
Minor: 4,
})
}
func TestInRange(t *testing.T) {
s, err := version.New("7.0")
assert.NilError(t, err)
e, err := version.New("7.4")
assert.NilError(t, err)
ver, err := version.New("7.0")
assert.NilError(t, err)
assert.Assert(t, ver.InRange(s, e))
ver, err = version.New("7.2")
assert.NilError(t, err)
assert.Assert(t, ver.InRange(s, e))
ver, err = version.New("7.4")
assert.NilError(t, err)
assert.Assert(t, ver.InRange(s, e))
}

View File

@@ -2,18 +2,25 @@ package printer_test
import (
"bytes"
printer2 "github.com/z7zmey/php-parser/pkg/visitor/printer"
"testing"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/internal/php5"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/cfg"
"github.com/z7zmey/php-parser/pkg/version"
"github.com/z7zmey/php-parser/pkg/visitor/printer"
)
func parsePhp5(src string) ast.Vertex {
lexer := scanner.NewLexer([]byte(src), "5.6", nil)
php5parser := php5.NewParser(lexer, nil)
config := cfg.Config{
Version: &version.Version{
Major: 5,
Minor: 6,
},
}
lexer := scanner.NewLexer([]byte(src), config)
php5parser := php5.NewParser(lexer, config)
php5parser.Parse()
return php5parser.GetRootNode()
@@ -22,8 +29,8 @@ func parsePhp5(src string) ast.Vertex {
func printPhp5(n ast.Vertex) string {
o := bytes.NewBufferString("")
printer := printer2.NewPrinter(o)
n.Accept(printer)
p := printer.NewPrinter(o)
n.Accept(p)
return o.String()
}

View File

@@ -2,13 +2,15 @@ package printer_test
import (
"bytes"
printer2 "github.com/z7zmey/php-parser/pkg/visitor/printer"
"os"
"testing"
"github.com/z7zmey/php-parser/internal/php7"
"github.com/z7zmey/php-parser/internal/scanner"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/cfg"
"github.com/z7zmey/php-parser/pkg/version"
"github.com/z7zmey/php-parser/pkg/visitor/printer"
)
func ExamplePrinter() {
@@ -28,8 +30,14 @@ abstract class Bar extends Baz
// parse
lexer := scanner.NewLexer([]byte(src), "7.4", nil)
php7parser := php7.NewParser(lexer, nil)
config := cfg.Config{
Version: &version.Version{
Major: 7,
Minor: 4,
},
}
lexer := scanner.NewLexer([]byte(src), config)
php7parser := php7.NewParser(lexer, config)
php7parser.Parse()
rootNode := php7parser.GetRootNode()
@@ -41,8 +49,8 @@ abstract class Bar extends Baz
// print
printer := printer2.NewPrinter(os.Stdout)
rootNode.Accept(printer)
p := printer.NewPrinter(os.Stdout)
rootNode.Accept(p)
// Output:
//<?php
@@ -60,8 +68,14 @@ abstract class Bar extends Baz
}
func parse(src string) ast.Vertex {
lexer := scanner.NewLexer([]byte(src), "7.4", nil)
php7parser := php7.NewParser(lexer, nil)
config := cfg.Config{
Version: &version.Version{
Major: 7,
Minor: 4,
},
}
lexer := scanner.NewLexer([]byte(src), config)
php7parser := php7.NewParser(lexer, config)
php7parser.Parse()
return php7parser.GetRootNode()
@@ -70,8 +84,8 @@ func parse(src string) ast.Vertex {
func print(n ast.Vertex) string {
o := bytes.NewBufferString("")
printer := printer2.NewPrinter(o)
n.Accept(printer)
p := printer.NewPrinter(o)
n.Accept(p)
return o.String()
}