refactoring: update api
This commit is contained in:
parent
cb4b4e69c4
commit
e3b133f3de
@ -3,10 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"github.com/z7zmey/php-parser/pkg/visitor/dumper"
|
"fmt"
|
||||||
"github.com/z7zmey/php-parser/pkg/visitor/nsresolver"
|
|
||||||
"github.com/z7zmey/php-parser/pkg/visitor/printer"
|
|
||||||
"github.com/z7zmey/php-parser/pkg/visitor/traverser"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@ -21,15 +18,20 @@ import (
|
|||||||
"github.com/yookoala/realpath"
|
"github.com/yookoala/realpath"
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/pkg/ast"
|
"github.com/z7zmey/php-parser/pkg/ast"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
"github.com/z7zmey/php-parser/pkg/errors"
|
"github.com/z7zmey/php-parser/pkg/errors"
|
||||||
"github.com/z7zmey/php-parser/pkg/parser"
|
"github.com/z7zmey/php-parser/pkg/parser"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/version"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/visitor/dumper"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/visitor/nsresolver"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/visitor/printer"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/visitor/traverser"
|
||||||
)
|
)
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var phpVersion string
|
var phpVersion *version.Version
|
||||||
var profiler string
|
var profiler string
|
||||||
var dump *bool
|
var dump *bool
|
||||||
var withFreeFloating *bool
|
|
||||||
var showResolvedNs *bool
|
var showResolvedNs *bool
|
||||||
var printBack *bool
|
var printBack *bool
|
||||||
var printPath *bool
|
var printPath *bool
|
||||||
@ -49,19 +51,26 @@ type result struct {
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
var phpVer string
|
||||||
|
|
||||||
printExecTime = flag.Bool("time", false, "print execution time")
|
printExecTime = flag.Bool("time", false, "print execution time")
|
||||||
withFreeFloating = flag.Bool("ff", false, "parse and show free floating strings")
|
|
||||||
showResolvedNs = flag.Bool("r", false, "resolve names")
|
showResolvedNs = flag.Bool("r", false, "resolve names")
|
||||||
printBack = flag.Bool("pb", false, "print AST back into the parsed file")
|
printBack = flag.Bool("pb", false, "print AST back into the parsed file")
|
||||||
printPath = flag.Bool("p", false, "print filepath")
|
printPath = flag.Bool("p", false, "print filepath")
|
||||||
printErrors = flag.Bool("e", false, "print errors")
|
printErrors = flag.Bool("e", false, "print errors")
|
||||||
dump = flag.Bool("d", false, "dump")
|
dump = flag.Bool("d", false, "dump")
|
||||||
flag.StringVar(&profiler, "prof", "", "start profiler: [cpu, mem, trace]")
|
flag.StringVar(&profiler, "prof", "", "start profiler: [cpu, mem, trace]")
|
||||||
flag.StringVar(&phpVersion, "phpver", "7.4", "php version")
|
flag.StringVar(&phpVer, "phpver", "7.4", "php version")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
phpVersion, err = version.New(phpVer)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error: " + err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
if len(flag.Args()) == 0 {
|
if len(flag.Args()) == 0 {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
return
|
return
|
||||||
@ -128,16 +137,16 @@ func parserWorker(fileCh <-chan *file, r chan<- result) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
parserErrors := []*errors.Error{}
|
var parserErrors []*errors.Error
|
||||||
cfg := parser.Config{
|
rootNode, err := parser.Parse(f.content, cfg.Config{
|
||||||
WithTokens: *withFreeFloating,
|
Version: phpVersion,
|
||||||
ErrorHandlerFunc: func(e *errors.Error) {
|
ErrorHandlerFunc: func(e *errors.Error) {
|
||||||
parserErrors = append(parserErrors, e)
|
parserErrors = append(parserErrors, e)
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
rootNode, err := parser.Parse(f.content, phpVersion, cfg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
fmt.Println("Error:" + err.Error())
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
r <- result{path: f.path, rootNode: rootNode, errors: parserErrors}
|
r <- result{path: f.path, rootNode: rootNode, errors: parserErrors}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package php5
|
package php5
|
||||||
|
|
||||||
import (
|
import (
|
||||||
builder "github.com/z7zmey/php-parser/internal/position"
|
"github.com/z7zmey/php-parser/internal/position"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"github.com/z7zmey/php-parser/internal/scanner"
|
||||||
"github.com/z7zmey/php-parser/pkg/ast"
|
"github.com/z7zmey/php-parser/pkg/ast"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
"github.com/z7zmey/php-parser/pkg/errors"
|
"github.com/z7zmey/php-parser/pkg/errors"
|
||||||
"github.com/z7zmey/php-parser/pkg/token"
|
"github.com/z7zmey/php-parser/pkg/token"
|
||||||
)
|
)
|
||||||
@ -14,15 +15,15 @@ type Parser struct {
|
|||||||
currentToken *token.Token
|
currentToken *token.Token
|
||||||
rootNode ast.Vertex
|
rootNode ast.Vertex
|
||||||
errHandlerFunc func(*errors.Error)
|
errHandlerFunc func(*errors.Error)
|
||||||
builder *builder.Builder
|
builder *position.Builder
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewParser creates and returns new Parser
|
// NewParser creates and returns new Parser
|
||||||
func NewParser(lexer *scanner.Lexer, errHandlerFunc func(*errors.Error)) *Parser {
|
func NewParser(lexer *scanner.Lexer, config cfg.Config) *Parser {
|
||||||
return &Parser{
|
return &Parser{
|
||||||
Lexer: lexer,
|
Lexer: lexer,
|
||||||
errHandlerFunc: errHandlerFunc,
|
errHandlerFunc: config.ErrorHandlerFunc,
|
||||||
builder: builder.NewBuilder(),
|
builder: position.NewBuilder(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/php5"
|
"github.com/z7zmey/php-parser/internal/php5"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"github.com/z7zmey/php-parser/internal/scanner"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkPhp5(b *testing.B) {
|
func BenchmarkPhp5(b *testing.B) {
|
||||||
@ -15,8 +17,14 @@ func BenchmarkPhp5(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
lexer := scanner.NewLexer([]byte(src), "5.6", nil)
|
config := cfg.Config{
|
||||||
php5parser := php5.NewParser(lexer, nil)
|
Version: &version.Version{
|
||||||
|
Major: 5,
|
||||||
|
Minor: 6,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := scanner.NewLexer(src, config)
|
||||||
|
php5parser := php5.NewParser(lexer, config)
|
||||||
php5parser.Parse()
|
php5parser.Parse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
package php7
|
package php7
|
||||||
|
|
||||||
import (
|
import (
|
||||||
builder "github.com/z7zmey/php-parser/internal/position"
|
"github.com/z7zmey/php-parser/internal/position"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"github.com/z7zmey/php-parser/internal/scanner"
|
||||||
"github.com/z7zmey/php-parser/pkg/ast"
|
"github.com/z7zmey/php-parser/pkg/ast"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
"github.com/z7zmey/php-parser/pkg/errors"
|
"github.com/z7zmey/php-parser/pkg/errors"
|
||||||
"github.com/z7zmey/php-parser/pkg/token"
|
"github.com/z7zmey/php-parser/pkg/token"
|
||||||
)
|
)
|
||||||
@ -14,15 +15,15 @@ type Parser struct {
|
|||||||
currentToken *token.Token
|
currentToken *token.Token
|
||||||
rootNode ast.Vertex
|
rootNode ast.Vertex
|
||||||
errHandlerFunc func(*errors.Error)
|
errHandlerFunc func(*errors.Error)
|
||||||
builder *builder.Builder
|
builder *position.Builder
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewParser creates and returns new Parser
|
// NewParser creates and returns new Parser
|
||||||
func NewParser(lexer *scanner.Lexer, errHandlerFunc func(*errors.Error)) *Parser {
|
func NewParser(lexer *scanner.Lexer, config cfg.Config) *Parser {
|
||||||
return &Parser{
|
return &Parser{
|
||||||
Lexer: lexer,
|
Lexer: lexer,
|
||||||
errHandlerFunc: errHandlerFunc,
|
errHandlerFunc: config.ErrorHandlerFunc,
|
||||||
builder: builder.NewBuilder(),
|
builder: position.NewBuilder(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,6 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/php7"
|
"github.com/z7zmey/php-parser/internal/php7"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"github.com/z7zmey/php-parser/internal/scanner"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BenchmarkPhp7(b *testing.B) {
|
func BenchmarkPhp7(b *testing.B) {
|
||||||
@ -16,8 +18,14 @@ func BenchmarkPhp7(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for n := 0; n < b.N; n++ {
|
for n := 0; n < b.N; n++ {
|
||||||
lexer := scanner.NewLexer(src, "7.4", nil)
|
config := cfg.Config{
|
||||||
php7parser := php7.NewParser(lexer, nil)
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := scanner.NewLexer(src, config)
|
||||||
|
php7parser := php7.NewParser(lexer, config)
|
||||||
php7parser.Parse()
|
php7parser.Parse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,16 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/version"
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
"github.com/z7zmey/php-parser/pkg/errors"
|
"github.com/z7zmey/php-parser/pkg/errors"
|
||||||
"github.com/z7zmey/php-parser/pkg/position"
|
"github.com/z7zmey/php-parser/pkg/position"
|
||||||
"github.com/z7zmey/php-parser/pkg/token"
|
"github.com/z7zmey/php-parser/pkg/token"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Lexer struct {
|
type Lexer struct {
|
||||||
data []byte
|
data []byte
|
||||||
phpVersion string
|
phpVersion *version.Version
|
||||||
errHandlerFunc func(*errors.Error)
|
errHandlerFunc func(*errors.Error)
|
||||||
|
|
||||||
p, pe, cs int
|
p, pe, cs int
|
||||||
@ -26,11 +27,11 @@ type Lexer struct {
|
|||||||
newLines NewLines
|
newLines NewLines
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLexer(data []byte, phpVersion string, errHandlerFunc func(*errors.Error)) *Lexer {
|
func NewLexer(data []byte, config cfg.Config) *Lexer {
|
||||||
lex := &Lexer{
|
lex := &Lexer{
|
||||||
data: data,
|
data: data,
|
||||||
phpVersion: phpVersion,
|
phpVersion: config.Version,
|
||||||
errHandlerFunc: errHandlerFunc,
|
errHandlerFunc: config.ErrorHandlerFunc,
|
||||||
|
|
||||||
pe: len(data),
|
pe: len(data),
|
||||||
stack: make([]int, 0),
|
stack: make([]int, 0),
|
||||||
@ -101,16 +102,16 @@ func (lex *Lexer) isNotStringEnd(s byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (lex *Lexer) isHeredocEnd(p int) bool {
|
func (lex *Lexer) isHeredocEnd(p int) bool {
|
||||||
r, err := version.Compare(lex.phpVersion, "7.3")
|
o, err := version.New("7.3")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if lex.phpVersion.GreaterOrEqual(o) {
|
||||||
return lex.isHeredocEndSince73(p)
|
return lex.isHeredocEndSince73(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
if r == -1 {
|
return lex.isHeredocEndBefore73(p)
|
||||||
return lex.isHeredocEndBefore73(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return lex.isHeredocEndSince73(p)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lex *Lexer) isHeredocEndBefore73(p int) bool {
|
func (lex *Lexer) isHeredocEndBefore73(p int) bool {
|
||||||
|
@ -4,9 +4,11 @@ import (
|
|||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/z7zmey/php-parser/pkg/cfg"
|
||||||
"github.com/z7zmey/php-parser/pkg/errors"
|
"github.com/z7zmey/php-parser/pkg/errors"
|
||||||
"github.com/z7zmey/php-parser/pkg/position"
|
"github.com/z7zmey/php-parser/pkg/position"
|
||||||
"github.com/z7zmey/php-parser/pkg/token"
|
"github.com/z7zmey/php-parser/pkg/token"
|
||||||
|
"github.com/z7zmey/php-parser/pkg/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTokens(t *testing.T) {
|
func TestTokens(t *testing.T) {
|
||||||
@ -353,7 +355,13 @@ func TestTokens(t *testing.T) {
|
|||||||
token.T_UNSET_CAST.String(),
|
token.T_UNSET_CAST.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -380,7 +388,13 @@ func TestShebang(t *testing.T) {
|
|||||||
"\n",
|
"\n",
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
@ -399,7 +413,13 @@ func TestShebangHtml(t *testing.T) {
|
|||||||
0.1
|
0.1
|
||||||
`
|
`
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
assert.Equal(t, tkn.ID, token.T_INLINE_HTML)
|
assert.Equal(t, tkn.ID, token.T_INLINE_HTML)
|
||||||
@ -448,7 +468,13 @@ func TestNumberTokens(t *testing.T) {
|
|||||||
token.T_DNUMBER.String(),
|
token.T_DNUMBER.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -504,7 +530,13 @@ func TestConstantStrings(t *testing.T) {
|
|||||||
token.T_CONSTANT_ENCAPSED_STRING.String(),
|
token.T_CONSTANT_ENCAPSED_STRING.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -550,7 +582,13 @@ func TestSingleQuoteStringTokens(t *testing.T) {
|
|||||||
token.T_CONSTANT_ENCAPSED_STRING.String(),
|
token.T_CONSTANT_ENCAPSED_STRING.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -644,7 +682,13 @@ func TestTeplateStringTokens(t *testing.T) {
|
|||||||
token.ID(int('"')).String(),
|
token.ID(int('"')).String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -734,7 +778,13 @@ func TestBackquoteStringTokens(t *testing.T) {
|
|||||||
token.ID(int('`')).String(),
|
token.ID(int('`')).String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -827,7 +877,13 @@ CAT;
|
|||||||
token.ID(int(';')).String(),
|
token.ID(int(';')).String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -899,7 +955,13 @@ CAT
|
|||||||
token.T_END_HEREDOC.String(),
|
token.T_END_HEREDOC.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -937,7 +999,13 @@ CAT;
|
|||||||
token.ID(int(';')).String(),
|
token.ID(int(';')).String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -967,7 +1035,13 @@ func TestHereDocTokens73(t *testing.T) {
|
|||||||
token.T_VARIABLE.String(),
|
token.T_VARIABLE.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -996,8 +1070,13 @@ CAT;`
|
|||||||
token.ID(int(';')).String(),
|
token.ID(int(';')).String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
lexer.phpVersion = "7.2"
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -1028,7 +1107,13 @@ func TestInlineHtmlNopTokens(t *testing.T) {
|
|||||||
token.T_INLINE_HTML.String(),
|
token.T_INLINE_HTML.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -1062,7 +1147,13 @@ func TestStringTokensAfterVariable(t *testing.T) {
|
|||||||
"\"",
|
"\"",
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
actualTokens := []string{}
|
actualTokens := []string{}
|
||||||
|
|
||||||
@ -1095,7 +1186,13 @@ func TestSlashAfterVariable(t *testing.T) {
|
|||||||
"3",
|
"3",
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
actual := []string{}
|
actual := []string{}
|
||||||
actualTokens := []string{}
|
actualTokens := []string{}
|
||||||
|
|
||||||
@ -1132,7 +1229,13 @@ func TestCommentEnd(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1163,7 +1266,13 @@ func TestCommentNewLine(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1194,7 +1303,13 @@ func TestCommentNewLine1(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1225,7 +1340,13 @@ func TestCommentNewLine2(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1257,7 +1378,13 @@ func TestCommentWithPhpEndTag(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1289,7 +1416,13 @@ func TestInlineComment(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1321,7 +1454,13 @@ func TestInlineComment2(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1357,7 +1496,13 @@ func TestEmptyInlineComment(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1389,7 +1534,13 @@ func TestEmptyInlineComment2(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
|
||||||
@ -1405,7 +1556,13 @@ func TestMethodCallTokens(t *testing.T) {
|
|||||||
src := `<?php
|
src := `<?php
|
||||||
$a -> bar ( '' ) ;`
|
$a -> bar ( '' ) ;`
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
expected := []*token.Token{
|
expected := []*token.Token{
|
||||||
{
|
{
|
||||||
@ -1507,7 +1664,13 @@ func TestYieldFromTokens(t *testing.T) {
|
|||||||
src := `<?php
|
src := `<?php
|
||||||
yield from $a`
|
yield from $a`
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
expected := []*token.Token{
|
expected := []*token.Token{
|
||||||
{
|
{
|
||||||
@ -1543,7 +1706,13 @@ func TestYieldFromTokens(t *testing.T) {
|
|||||||
func TestVarNameByteChars(t *testing.T) {
|
func TestVarNameByteChars(t *testing.T) {
|
||||||
src := "<?php $\x80 $\xff"
|
src := "<?php $\x80 $\xff"
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
assert.Equal(t, "$\x80", string(tkn.Value))
|
assert.Equal(t, "$\x80", string(tkn.Value))
|
||||||
@ -1555,7 +1724,13 @@ func TestVarNameByteChars(t *testing.T) {
|
|||||||
func TestStringVarNameByteChars(t *testing.T) {
|
func TestStringVarNameByteChars(t *testing.T) {
|
||||||
src := "<?php \"$\x80 $\xff\""
|
src := "<?php \"$\x80 $\xff\""
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
assert.Equal(t, "\"", string(tkn.Value))
|
assert.Equal(t, "\"", string(tkn.Value))
|
||||||
@ -1577,9 +1752,16 @@ func TestIgnoreControllCharacters(t *testing.T) {
|
|||||||
src := "<?php \004 echo $b;"
|
src := "<?php \004 echo $b;"
|
||||||
|
|
||||||
var actualErr *errors.Error
|
var actualErr *errors.Error
|
||||||
lexer := NewLexer([]byte(src), "7.4", func(e *errors.Error) {
|
config := cfg.Config{
|
||||||
actualErr = e
|
Version: &version.Version{
|
||||||
})
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
ErrorHandlerFunc: func(e *errors.Error) {
|
||||||
|
actualErr = e
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
expected := "echo"
|
expected := "echo"
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
@ -1601,7 +1783,13 @@ func TestIgnoreControllCharacters(t *testing.T) {
|
|||||||
func TestIgnoreControllCharactersAtStringVarOffset(t *testing.T) {
|
func TestIgnoreControllCharactersAtStringVarOffset(t *testing.T) {
|
||||||
src := "<?php \"$a[test\004]\";"
|
src := "<?php \"$a[test\004]\";"
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
expected := "\""
|
expected := "\""
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
@ -1632,7 +1820,13 @@ func TestIgnoreControllCharactersAtStringVarOffset(t *testing.T) {
|
|||||||
func TestDoubleDollar(t *testing.T) {
|
func TestDoubleDollar(t *testing.T) {
|
||||||
src := `<?php "$$a";`
|
src := `<?php "$$a";`
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
expected := "\""
|
expected := "\""
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
@ -1653,7 +1847,13 @@ func TestDoubleDollar(t *testing.T) {
|
|||||||
func TestTripleDollar(t *testing.T) {
|
func TestTripleDollar(t *testing.T) {
|
||||||
src := `<?php "$$$a";`
|
src := `<?php "$$$a";`
|
||||||
|
|
||||||
lexer := NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := NewLexer([]byte(src), config)
|
||||||
|
|
||||||
expected := "\""
|
expected := "\""
|
||||||
tkn := lexer.Lex()
|
tkn := lexer.Lex()
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
package version
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type version struct {
|
|
||||||
major int
|
|
||||||
minor int
|
|
||||||
}
|
|
||||||
|
|
||||||
func Compare(a string, b string) (int, error) {
|
|
||||||
first, err := parse(a)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
second, err := parse(b)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if first.major < second.major {
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if first.major > second.major {
|
|
||||||
return 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if first.minor < second.minor {
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if first.minor > second.minor {
|
|
||||||
return 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse(v string) (version, error) {
|
|
||||||
i := strings.Index(v, ".")
|
|
||||||
if i == -1 {
|
|
||||||
return version{}, errors.New("version must contain major and minor parts")
|
|
||||||
}
|
|
||||||
|
|
||||||
major, err := strconv.Atoi(v[:i])
|
|
||||||
if err != nil {
|
|
||||||
return version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
minor, err := strconv.Atoi(v[i+1:])
|
|
||||||
if err != nil {
|
|
||||||
return version{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return version{major, minor}, nil
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package version_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"gotest.tools/assert"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSmaller(t *testing.T) {
|
|
||||||
r, err := version.Compare("7.3", "5.6")
|
|
||||||
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, 1, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGreater(t *testing.T) {
|
|
||||||
r, err := version.Compare("5.6", "7.3")
|
|
||||||
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, -1, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEqual(t *testing.T) {
|
|
||||||
r, err := version.Compare("7.3", "7.3")
|
|
||||||
|
|
||||||
assert.NilError(t, err)
|
|
||||||
assert.Equal(t, 0, r)
|
|
||||||
}
|
|
11
pkg/cfg/cfg.go
Normal file
11
pkg/cfg/cfg.go
Normal 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)
|
||||||
|
}
|
@ -1,12 +1,25 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/php5"
|
"github.com/z7zmey/php-parser/internal/php5"
|
||||||
"github.com/z7zmey/php-parser/internal/php7"
|
"github.com/z7zmey/php-parser/internal/php7"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"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/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
|
// Parser interface
|
||||||
@ -15,29 +28,26 @@ type Parser interface {
|
|||||||
GetRootNode() ast.Vertex
|
GetRootNode() ast.Vertex
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
func Parse(src []byte, config cfg.Config) (ast.Vertex, error) {
|
||||||
WithTokens bool
|
|
||||||
WithPositions bool
|
|
||||||
ErrorHandlerFunc func(e *errors.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Parse(src []byte, ver string, cfg Config) (ast.Vertex, error) {
|
|
||||||
var parser Parser
|
var parser Parser
|
||||||
|
|
||||||
r, err := version.Compare(ver, "7.0")
|
if config.Version == nil {
|
||||||
if err != nil {
|
config.Version = php7RangeEnd
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lexer := scanner.NewLexer(src, ver, cfg.ErrorHandlerFunc)
|
if config.Version.InRange(php5RangeStart, php5RangeEnd) {
|
||||||
|
lexer := scanner.NewLexer(src, config)
|
||||||
if r == -1 {
|
parser = php5.NewParser(lexer, config)
|
||||||
parser = php5.NewParser(lexer, cfg.ErrorHandlerFunc)
|
parser.Parse()
|
||||||
} else {
|
return parser.GetRootNode(), nil
|
||||||
parser = php7.NewParser(lexer, cfg.ErrorHandlerFunc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
102
pkg/version/version.go
Normal 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
|
||||||
|
}
|
48
pkg/version/version_test.go
Normal file
48
pkg/version/version_test.go
Normal 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))
|
||||||
|
}
|
@ -2,18 +2,25 @@ package printer_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
printer2 "github.com/z7zmey/php-parser/pkg/visitor/printer"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/pkg/ast"
|
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/php5"
|
"github.com/z7zmey/php-parser/internal/php5"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"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 {
|
func parsePhp5(src string) ast.Vertex {
|
||||||
lexer := scanner.NewLexer([]byte(src), "5.6", nil)
|
config := cfg.Config{
|
||||||
php5parser := php5.NewParser(lexer, nil)
|
Version: &version.Version{
|
||||||
|
Major: 5,
|
||||||
|
Minor: 6,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := scanner.NewLexer([]byte(src), config)
|
||||||
|
php5parser := php5.NewParser(lexer, config)
|
||||||
php5parser.Parse()
|
php5parser.Parse()
|
||||||
|
|
||||||
return php5parser.GetRootNode()
|
return php5parser.GetRootNode()
|
||||||
@ -22,8 +29,8 @@ func parsePhp5(src string) ast.Vertex {
|
|||||||
func printPhp5(n ast.Vertex) string {
|
func printPhp5(n ast.Vertex) string {
|
||||||
o := bytes.NewBufferString("")
|
o := bytes.NewBufferString("")
|
||||||
|
|
||||||
printer := printer2.NewPrinter(o)
|
p := printer.NewPrinter(o)
|
||||||
n.Accept(printer)
|
n.Accept(p)
|
||||||
|
|
||||||
return o.String()
|
return o.String()
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@ package printer_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
printer2 "github.com/z7zmey/php-parser/pkg/visitor/printer"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/internal/php7"
|
"github.com/z7zmey/php-parser/internal/php7"
|
||||||
"github.com/z7zmey/php-parser/internal/scanner"
|
"github.com/z7zmey/php-parser/internal/scanner"
|
||||||
"github.com/z7zmey/php-parser/pkg/ast"
|
"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() {
|
func ExamplePrinter() {
|
||||||
@ -28,8 +30,14 @@ abstract class Bar extends Baz
|
|||||||
|
|
||||||
// parse
|
// parse
|
||||||
|
|
||||||
lexer := scanner.NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
php7parser := php7.NewParser(lexer, nil)
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := scanner.NewLexer([]byte(src), config)
|
||||||
|
php7parser := php7.NewParser(lexer, config)
|
||||||
php7parser.Parse()
|
php7parser.Parse()
|
||||||
|
|
||||||
rootNode := php7parser.GetRootNode()
|
rootNode := php7parser.GetRootNode()
|
||||||
@ -41,8 +49,8 @@ abstract class Bar extends Baz
|
|||||||
|
|
||||||
// print
|
// print
|
||||||
|
|
||||||
printer := printer2.NewPrinter(os.Stdout)
|
p := printer.NewPrinter(os.Stdout)
|
||||||
rootNode.Accept(printer)
|
rootNode.Accept(p)
|
||||||
|
|
||||||
// Output:
|
// Output:
|
||||||
//<?php
|
//<?php
|
||||||
@ -60,8 +68,14 @@ abstract class Bar extends Baz
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parse(src string) ast.Vertex {
|
func parse(src string) ast.Vertex {
|
||||||
lexer := scanner.NewLexer([]byte(src), "7.4", nil)
|
config := cfg.Config{
|
||||||
php7parser := php7.NewParser(lexer, nil)
|
Version: &version.Version{
|
||||||
|
Major: 7,
|
||||||
|
Minor: 4,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
lexer := scanner.NewLexer([]byte(src), config)
|
||||||
|
php7parser := php7.NewParser(lexer, config)
|
||||||
php7parser.Parse()
|
php7parser.Parse()
|
||||||
|
|
||||||
return php7parser.GetRootNode()
|
return php7parser.GetRootNode()
|
||||||
@ -70,8 +84,8 @@ func parse(src string) ast.Vertex {
|
|||||||
func print(n ast.Vertex) string {
|
func print(n ast.Vertex) string {
|
||||||
o := bytes.NewBufferString("")
|
o := bytes.NewBufferString("")
|
||||||
|
|
||||||
printer := printer2.NewPrinter(o)
|
p := printer.NewPrinter(o)
|
||||||
n.Accept(printer)
|
n.Accept(p)
|
||||||
|
|
||||||
return o.String()
|
return o.String()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user