Merge pull request #117 from z7zmey/refactoring

Refactoring
This commit is contained in:
Vadym Slizov 2020-12-29 21:31:14 +02:00 committed by GitHub
commit 4d6130d98d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
357 changed files with 145717 additions and 127615 deletions

6
.gitattributes vendored Normal file
View File

@ -0,0 +1,6 @@
internal/php5/php5.go -diff -merge
internal/php5/php5.go linguist-generated=true
internal/php7/php7.go -diff -merge
internal/php7/php7.go linguist-generated=true
internal/scanner/scanner.go -diff -merge
internal/scanner/scanner.go linguist-generated=true

View File

@ -1,16 +1,13 @@
PHPFILE=example.php PHPFILE=example.php
all: compile fmt build run all: compile fmt build
fmt: fmt:
find . -type f -iregex '.*\.go' -exec gofmt -l -s -w '{}' + find . -type f -iregex '.*\.go' -exec gofmt -l -s -w '{}' +
build: build:
go generate ./... go generate ./...
go build go build ./cmd/...
run:
./php-parser -d go $(PHPFILE)
test: test:
go test ./... go test ./...
@ -19,38 +16,38 @@ cover:
go test ./... --cover go test ./... --cover
bench: bench:
go test -benchmem -bench=. ./php5 go test -benchmem -bench=. ./internal/php5
go test -benchmem -bench=. ./php7 go test -benchmem -bench=. ./internal/php7
compile: ./php5/php5.go ./php7/php7.go ./scanner/scanner.go fmt compile: ./internal/php5/php5.go ./internal/php7/php7.go ./internal/scanner/scanner.go
sed -i '' -e 's/yyErrorVerbose = false/yyErrorVerbose = true/g' ./php7/php7.go sed -i '' -e 's/yyErrorVerbose = false/yyErrorVerbose = true/g' ./internal/php7/php7.go
sed -i '' -e 's/yyErrorVerbose = false/yyErrorVerbose = true/g' ./php5/php5.go sed -i '' -e 's/yyErrorVerbose = false/yyErrorVerbose = true/g' ./internal/php5/php5.go
sed -i '' -e 's/\/\/line/\/\/ line/g' ./php5/php5.go sed -i '' -e 's/\/\/line/\/\/ line/g' ./internal/php5/php5.go
sed -i '' -e 's/\/\/line/\/\/ line/g' ./php7/php7.go sed -i '' -e 's/\/\/line/\/\/ line/g' ./internal/php7/php7.go
sed -i '' -e 's/\/\/line/\/\/ line/g' ./scanner/scanner.go sed -i '' -e 's/\/\/line/\/\/ line/g' ./internal/scanner/scanner.go
rm -f y.output rm -f y.output
./scanner/scanner.go: ./scanner/scanner.rl ./internal/scanner/scanner.go: ./internal/scanner/scanner.rl
ragel -Z -G2 -o $@ $< ragel -Z -G2 -o $@ $<
./php5/php5.go: ./php5/php5.y ./internal/php5/php5.go: ./internal/php5/php5.y
goyacc -o $@ $< goyacc -o $@ $<
./php7/php7.go: ./php7/php7.y ./internal/php7/php7.go: ./internal/php7/php7.y
goyacc -o $@ $< goyacc -o $@ $<
cpu_pprof: cpu_pprof:
go test -cpuprofile cpu.pprof -bench=. -benchtime=20s ./php7 go test -cpuprofile cpu.pprof -bench=. -benchtime=20s ./internal/php7
go tool pprof ./php7.test cpu.pprof go tool pprof ./php7.test cpu.pprof
mem_pprof: mem_pprof:
go test -memprofile mem.pprof -bench=. -benchtime=20s -benchmem ./php7 go test -memprofile mem.pprof -bench=. -benchtime=20s -benchmem ./internal/php7
go tool pprof -alloc_objects ./php7.test mem.pprof go tool pprof -alloc_objects ./php7.test mem.pprof
cpu_pprof_php5: cpu_pprof_php5:
go test -cpuprofile cpu.prof -bench=. -benchtime=20s ./php5 go test -cpuprofile cpu.prof -bench=. -benchtime=20s ./internal/php5
go tool pprof ./php5.test cpu.prof go tool pprof ./php5.test cpu.prof
mem_pprof_php5: mem_pprof_php5:
go test -memprofile mem.prof -bench=. -benchtime=20s -benchmem ./php5 go test -memprofile mem.prof -bench=. -benchtime=20s -benchmem ./internal/php5
go tool pprof -alloc_objects ./php5.test mem.prof go tool pprof -alloc_objects ./php5.test mem.prof

View File

@ -4,28 +4,39 @@ import (
"bytes" "bytes"
"flag" "flag"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv"
"sync" "sync"
"time"
"github.com/pkg/profile" "github.com/pkg/profile"
"github.com/yookoala/realpath" "github.com/yookoala/realpath"
"github.com/z7zmey/php-parser/parser"
"github.com/z7zmey/php-parser/printer" "github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/visitor" "github.com/z7zmey/php-parser/pkg/cfg"
"github.com/z7zmey/php-parser/pkg/errors"
"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 dumpType string
var profiler string var profiler string
var withFreeFloating *bool var dump *bool
var showResolvedNs *bool var showResolvedNs *bool
var printBack *bool var printBack *bool
var printPath *bool var printPath *bool
var printErrors *bool
var printExecTime *bool
type file struct { type file struct {
path string path string
@ -33,21 +44,33 @@ type file struct {
} }
type result struct { type result struct {
path string path string
parser parser.Parser rootNode ast.Vertex
errors []*errors.Error
} }
func main() { func main() {
withFreeFloating = flag.Bool("ff", false, "parse and show free floating strings") start := time.Now()
var phpVer string
printExecTime = flag.Bool("time", false, "print execution time")
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")
flag.StringVar(&dumpType, "d", "", "dump format: [custom, go, json, pretty_json]") printErrors = flag.Bool("e", false, "print errors")
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
@ -82,6 +105,11 @@ func main() {
wg.Wait() wg.Wait()
close(fileCh) close(fileCh)
close(resultCh) close(resultCh)
elapsed := time.Since(start)
if *printExecTime {
log.Printf("took: %s", elapsed)
}
} }
func processPath(pathList []string, fileCh chan<- *file) { func processPath(pathList []string, fileCh chan<- *file) {
@ -109,18 +137,19 @@ func parserWorker(fileCh <-chan *file, r chan<- result) {
return return
} }
parserWorker, err := parser.NewParser(f.content, phpVersion) var parserErrors []*errors.Error
rootNode, err := parser.Parse(f.content, cfg.Config{
Version: phpVersion,
ErrorHandlerFunc: func(e *errors.Error) {
parserErrors = append(parserErrors, e)
},
})
if err != nil { if err != nil {
panic(err.Error()) fmt.Println("Error:" + err.Error())
os.Exit(1)
} }
if *withFreeFloating { r <- result{path: f.path, rootNode: rootNode, errors: parserErrors}
parserWorker.WithFreeFloating()
}
parserWorker.Parse()
r <- result{path: f.path, parser: parserWorker}
} }
} }
@ -136,51 +165,34 @@ func printerWorker(r <-chan result) {
counter++ counter++
if *printPath { if *printPath {
fmt.Fprintf(os.Stdout, "==> [%d] %s\n", counter, res.path) _, _ = io.WriteString(os.Stderr, "==> ["+strconv.Itoa(counter)+"] "+res.path+"\n")
} }
for _, e := range res.parser.GetErrors() { if *printErrors {
fmt.Fprintf(os.Stdout, "==> %s\n", e) for _, e := range res.errors {
_, _ = io.WriteString(os.Stderr, "==> "+e.String()+"\n")
}
} }
if *printBack { if *printBack {
o := bytes.NewBuffer([]byte{}) o := bytes.NewBuffer([]byte{})
p := printer.NewPrinter(o) p := printer.NewPrinter(o)
p.Print(res.parser.GetRootNode()) res.rootNode.Accept(p)
err := ioutil.WriteFile(res.path, o.Bytes(), 0644) err := ioutil.WriteFile(res.path, o.Bytes(), 0644)
checkErr(err) checkErr(err)
} }
var nsResolver *visitor.NamespaceResolver
if *showResolvedNs { if *showResolvedNs {
nsResolver = visitor.NewNamespaceResolver() v := nsresolver.NewNamespaceResolver()
res.parser.GetRootNode().Walk(nsResolver) traverser.NewTraverser(v).Traverse(res.rootNode)
for _, n := range v.ResolvedNames {
_, _ = io.WriteString(os.Stderr, "===> "+n+"\n")
}
} }
switch dumpType { if *dump == true {
case "custom": dumper.NewDumper(os.Stdout).WithPositions().WithTokens().Dump(res.rootNode)
dumper := &visitor.Dumper{
Writer: os.Stdout,
Indent: "| ",
NsResolver: nsResolver,
}
res.parser.GetRootNode().Walk(dumper)
case "json":
dumper := &visitor.JsonDumper{
Writer: os.Stdout,
NsResolver: nsResolver,
}
res.parser.GetRootNode().Walk(dumper)
case "pretty_json":
dumper := &visitor.PrettyJsonDumper{
Writer: os.Stdout,
NsResolver: nsResolver,
}
res.parser.GetRootNode().Walk(dumper)
case "go":
dumper := &visitor.GoDumper{Writer: os.Stdout}
res.parser.GetRootNode().Walk(dumper)
} }
wg.Done() wg.Done()

View File

@ -1,98 +0,0 @@
// Code generated by "stringer -type=Position -output ./position_string.go"; DO NOT EDIT.
package freefloating
import "strconv"
func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
_ = x[Start-0]
_ = x[End-1]
_ = x[Slash-2]
_ = x[Colon-3]
_ = x[SemiColon-4]
_ = x[AltEnd-5]
_ = x[Dollar-6]
_ = x[Ampersand-7]
_ = x[Name-8]
_ = x[Prefix-9]
_ = x[Key-10]
_ = x[Var-11]
_ = x[UseType-12]
_ = x[ReturnType-13]
_ = x[OptionalType-14]
_ = x[CaseSeparator-15]
_ = x[LexicalVars-16]
_ = x[Params-17]
_ = x[Ref-18]
_ = x[Cast-19]
_ = x[Expr-20]
_ = x[InitExpr-21]
_ = x[CondExpr-22]
_ = x[IncExpr-23]
_ = x[True-24]
_ = x[Cond-25]
_ = x[HaltCompiller-26]
_ = x[Namespace-27]
_ = x[Static-28]
_ = x[Class-29]
_ = x[Use-30]
_ = x[While-31]
_ = x[For-32]
_ = x[Switch-33]
_ = x[Break-34]
_ = x[Foreach-35]
_ = x[Declare-36]
_ = x[Label-37]
_ = x[Finally-38]
_ = x[List-39]
_ = x[Default-40]
_ = x[If-41]
_ = x[ElseIf-42]
_ = x[Else-43]
_ = x[Variadic-44]
_ = x[Function-45]
_ = x[DoubleArrow-46]
_ = x[Alias-47]
_ = x[As-48]
_ = x[Equal-49]
_ = x[Exit-50]
_ = x[Array-51]
_ = x[Isset-52]
_ = x[Empty-53]
_ = x[Eval-54]
_ = x[Echo-55]
_ = x[Try-56]
_ = x[Catch-57]
_ = x[Unset-58]
_ = x[Stmts-59]
_ = x[VarList-60]
_ = x[ConstList-61]
_ = x[NameList-62]
_ = x[ParamList-63]
_ = x[ModifierList-64]
_ = x[ArrayPairList-65]
_ = x[CaseListStart-66]
_ = x[CaseListEnd-67]
_ = x[ArgumentList-68]
_ = x[PropertyList-69]
_ = x[ParameterList-70]
_ = x[AdaptationList-71]
_ = x[LexicalVarList-72]
_ = x[UseDeclarationList-73]
_ = x[OpenParenthesisToken-74]
_ = x[CloseParenthesisToken-75]
}
const _Position_name = "StartEndSlashColonSemiColonAltEndDollarAmpersandNamePrefixKeyVarUseTypeReturnTypeOptionalTypeCaseSeparatorLexicalVarsParamsRefCastExprInitExprCondExprIncExprTrueCondHaltCompillerNamespaceStaticClassUseWhileForSwitchBreakForeachDeclareLabelFinallyListDefaultIfElseIfElseVariadicFunctionDoubleArrowAliasAsEqualExitArrayIssetEmptyEvalEchoTryCatchUnsetStmtsVarListConstListNameListParamListModifierListArrayPairListCaseListStartCaseListEndArgumentListPropertyListParameterListAdaptationListLexicalVarListUseDeclarationListOpenParenthesisTokenCloseParenthesisToken"
var _Position_index = [...]uint16{0, 5, 8, 13, 18, 27, 33, 39, 48, 52, 58, 61, 64, 71, 81, 93, 106, 117, 123, 126, 130, 134, 142, 150, 157, 161, 165, 178, 187, 193, 198, 201, 206, 209, 215, 220, 227, 234, 239, 246, 250, 257, 259, 265, 269, 277, 285, 296, 301, 303, 308, 312, 317, 322, 327, 331, 335, 338, 343, 348, 353, 360, 369, 377, 386, 398, 411, 424, 435, 447, 459, 472, 486, 500, 518, 538, 559}
func (i Position) String() string {
if i < 0 || i >= Position(len(_Position_index)-1) {
return "Position(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _Position_name[_Position_index[i]:_Position_index[i+1]]
}

View File

@ -1,113 +0,0 @@
package freefloating
import "github.com/z7zmey/php-parser/position"
type StringType int
const (
WhiteSpaceType StringType = iota
CommentType
TokenType
)
type Position int
//go:generate stringer -type=Position -output ./position_string.go
const (
Start Position = iota
End
Slash
Colon
SemiColon
AltEnd
Dollar
Ampersand
Name
Prefix
Key
Var
UseType
ReturnType
OptionalType
CaseSeparator
LexicalVars
Params
Ref
Cast
Expr
InitExpr
CondExpr
IncExpr
True
Cond
HaltCompiller
Namespace
Static
Class
Use
While
For
Switch
Break
Foreach
Declare
Label
Finally
List
Default
If
ElseIf
Else
Variadic
Function
DoubleArrow
Alias
As
Equal
Exit
Array
Isset
Empty
Eval
Echo
Try
Catch
Unset
Stmts
VarList
ConstList
NameList
ParamList
ModifierList
ArrayPairList
CaseListStart
CaseListEnd
ArgumentList
PropertyList
ParameterList
AdaptationList
LexicalVarList
UseDeclarationList
OpenParenthesisToken
CloseParenthesisToken
)
type String struct {
StringType StringType
Value string
Position *position.Position
}
type Collection map[Position][]String
func (c Collection) IsEmpty() bool {
for _, v := range c {
if len(v) > 0 {
return false
}
}
return true
}

1
go.mod
View File

@ -7,6 +7,5 @@ require (
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/profile v1.4.0 github.com/pkg/profile v1.4.0
github.com/yookoala/realpath v1.0.0 github.com/yookoala/realpath v1.0.0
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41 // indirect
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
) )

16
go.sum
View File

@ -6,22 +6,6 @@ github.com/pkg/profile v1.4.0 h1:uCmaf4vVbWAOZz36k1hrQD7ijGRzLwaME8Am/7a4jZI=
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE= github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
github.com/yookoala/realpath v1.0.0 h1:7OA9pj4FZd+oZDsyvXWQvjn5oBdcHRTV44PpdMSuImQ= github.com/yookoala/realpath v1.0.0 h1:7OA9pj4FZd+oZDsyvXWQvjn5oBdcHRTV44PpdMSuImQ=
github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE= github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41 h1:9Di9iYgOt9ThCipBxChBVhgNipDoE5mxO84rQV7D0FE=
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=

85
internal/php5/node.go Normal file
View File

@ -0,0 +1,85 @@
package php5
import (
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/position"
"github.com/z7zmey/php-parser/pkg/token"
)
type ParserBrackets struct {
Position *position.Position
OpenBracketTkn *token.Token
Child ast.Vertex
CloseBracketTkn *token.Token
}
func (n *ParserBrackets) Accept(v ast.Visitor) {
// do nothing
}
func (n *ParserBrackets) GetPosition() *position.Position {
return n.Position
}
type ParserSeparatedList struct {
Position *position.Position
Items []ast.Vertex
SeparatorTkns []*token.Token
}
func (n *ParserSeparatedList) Accept(v ast.Visitor) {
// do nothing
}
func (n *ParserSeparatedList) GetPosition() *position.Position {
return n.Position
}
// TraitAdaptationList node
type TraitAdaptationList struct {
Position *position.Position
OpenCurlyBracketTkn *token.Token
Adaptations []ast.Vertex
CloseCurlyBracketTkn *token.Token
}
func (n *TraitAdaptationList) Accept(v ast.Visitor) {
// do nothing
}
func (n *TraitAdaptationList) GetPosition() *position.Position {
return n.Position
}
// ArgumentList node
type ArgumentList struct {
Position *position.Position
OpenParenthesisTkn *token.Token
Arguments []ast.Vertex
SeparatorTkns []*token.Token
CloseParenthesisTkn *token.Token
}
func (n *ArgumentList) Accept(v ast.Visitor) {
// do nothing
}
func (n *ArgumentList) GetPosition() *position.Position {
return n.Position
}
// TraitMethodRef node
type TraitMethodRef struct {
Position *position.Position
Trait ast.Vertex
DoubleColonTkn *token.Token
Method ast.Vertex
}
func (n *TraitMethodRef) Accept(v ast.Visitor) {
// do nothing
}
func (n *TraitMethodRef) GetPosition() *position.Position {
return n.Position
}

66
internal/php5/parser.go Normal file
View File

@ -0,0 +1,66 @@
package php5
import (
"github.com/z7zmey/php-parser/internal/position"
"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/errors"
"github.com/z7zmey/php-parser/pkg/token"
)
// Parser structure
type Parser struct {
Lexer *scanner.Lexer
currentToken *token.Token
rootNode ast.Vertex
errHandlerFunc func(*errors.Error)
builder *position.Builder
}
// NewParser creates and returns new Parser
func NewParser(lexer *scanner.Lexer, config cfg.Config) *Parser {
return &Parser{
Lexer: lexer,
errHandlerFunc: config.ErrorHandlerFunc,
builder: position.NewBuilder(),
}
}
// Lex proxy to scanner Lex
func (p *Parser) Lex(lval *yySymType) int {
t := p.Lexer.Lex()
p.currentToken = t
lval.token = t
return int(t.ID)
}
func (p *Parser) Error(msg string) {
if p.errHandlerFunc == nil {
return
}
p.errHandlerFunc(errors.NewError(msg, p.currentToken.Position))
}
// Parse the php7 Parser entrypoint
func (p *Parser) Parse() int {
p.rootNode = nil
return yyParse(p)
}
// GetRootNode returns root node
func (p *Parser) GetRootNode() ast.Vertex {
return p.rootNode
}
// helpers
func lastNode(nn []ast.Vertex) ast.Vertex {
if len(nn) == 0 {
return nil
}
return nn[len(nn)-1]
}

50781
internal/php5/parser_test.go Normal file

File diff suppressed because it is too large Load Diff

BIN
internal/php5/php5.go generated Normal file

Binary file not shown.

5697
internal/php5/php5.y Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
package php5_test
import (
"io/ioutil"
"testing"
"github.com/z7zmey/php-parser/internal/php5"
"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) {
src, err := ioutil.ReadFile("test.php")
if err != nil {
b.Fatal("can not read test.php: " + err.Error())
}
for n := 0; n < b.N; n++ {
config := cfg.Config{
Version: &version.Version{
Major: 5,
Minor: 6,
},
}
lexer := scanner.NewLexer(src, config)
php5parser := php5.NewParser(lexer, config)
php5parser.Parse()
}
}

381
internal/php5/test.php Normal file
View File

@ -0,0 +1,381 @@
<?
foo($a, ...$b);
$foo($a, ...$b);
$foo->bar($a, ...$b);
foo::bar($a, ...$b);
$foo::bar($a, ...$b);
new foo($a, ...$b);
function foo(bar $bar=null, baz &...$baz) {}
class foo {public function foo(bar $bar=null, baz &...$baz) {}}
function(bar $bar=null, baz &...$baz) {};
static function(bar $bar=null, baz &...$baz) {};
1234567890123456789;
12345678901234567890;
0.;
0b0111111111111111111111111111111111111111111111111111111111111111;
0b1111111111111111111111111111111111111111111111111111111111111111;
0x007111111111111111;
0x8111111111111111;
__CLASS__;
__DIR__;
__FILE__;
__FUNCTION__;
__LINE__;
__NAMESPACE__;
__METHOD__;
__TRAIT__;
"test $var";
"test $var[1]";
"test $var[1234567890123456789012345678901234567890]";
"test $var[bar]";
"test $var[$bar]";
"$foo $bar";
"test $foo->bar()";
"test ${foo}";
"test ${foo[0]}";
"test {$foo->bar()}";
if ($a) :
endif;
if ($a) :
elseif ($b):
endif;
if ($a) :
else:
endif;
if ($a) :
elseif ($b):
elseif ($c):
else:
endif;
while (1) { break; }
while (1) { break 2; }
while (1) : break(3); endwhile;
class foo{ const FOO = 1, BAR = 2; }
class foo{ function bar() {} }
class foo{ public static function &bar() {} }
class foo{ final private function bar() {} protected function baz() {} }
abstract class foo{ abstract public function bar(); }
final class foo extends bar { }
final class foo implements bar { }
final class foo implements bar, baz { }
const FOO = 1, BAR = 2;
while (1) { continue; }
while (1) { continue 2; }
while (1) { continue(3); }
declare(ticks=1);
declare(ticks=1, strict_types=1) {}
declare(ticks=1): enddeclare;
do {} while(1);
echo $a, 1;
echo($a);
for($i = 0; $i < 10; $i++, $i++) {}
for(; $i < 10; $i++) : endfor;
foreach ($a as $v) {}
foreach ([] as $v) {}
foreach ($a as $v) : endforeach;
foreach ($a as $k => $v) {}
foreach ([] as $k => $v) {}
foreach ($a as $k => &$v) {}
foreach ($a as $k => list($v)) {}
function foo() {}
function foo() {
function bar() {}
class Baz {}
return $a;
}
function foo(array $a, callable $b) {return;}
function &foo() {return 1;}
function &foo() {}
global $a, $b, $$c, ${foo()};
a:
goto a;
if ($a) {}
if ($a) {} elseif ($b) {}
if ($a) {} else {}
if ($a) {} elseif ($b) {} elseif ($c) {} else {}
if ($a) {} elseif ($b) {} else if ($c) {} else {}
?> <div></div> <?
interface Foo {}
interface Foo extends Bar {}
interface Foo extends Bar, Baz {}
namespace Foo;
namespace Foo\Bar {}
namespace {}
class foo {var $a;}
class foo {public static $a, $b = 1;}
class foo {public static $a = 1, $b;}
static $a, $b = 1;
static $a = 1, $b;
switch (1) :
case 1:
default:
case 2:
endswitch;
switch (1) :;
case 1;
case 2;
endswitch;
switch (1) {
case 1: break;
case 2: break;
}
switch (1) {;
case 1; break;
case 2; break;
}
throw $e;
trait Foo {}
class Foo { use Bar; }
class Foo { use Bar, Baz {} }
class Foo { use Bar, Baz { one as public; } }
class Foo { use Bar, Baz { one as public two; } }
class Foo { use Bar, Baz { Bar::one insteadof Baz, Quux; Baz::one as two; } }
try {}
try {} catch (Exception $e) {}
try {} catch (Exception $e) {} catch (RuntimeException $e) {}
try {} catch (Exception $e) {} catch (\RuntimeException $e) {} catch (namespace\AdditionException $e) {}
try {} catch (Exception $e) {} finally {}
unset($a, $b);
use Foo;
use \Foo;
use \Foo as Bar;
use Foo, Bar;
use Foo, Bar as Baz;
use function Foo, \Bar;
use function Foo as foo, \Bar as bar;
use const Foo, \Bar;
use const Foo as foo, \Bar as bar;
$a[1];
$a[1][2];
array();
array(1);
array(1=>1, &$b,);
array(3 =>&$b);
array(&$b, 1=>1, 1, 3 =>&$b);
~$a;
!$a;
Foo::Bar;
clone($a);
clone $a;
function(){};
function($a, $b) use ($c, &$d) {};
function($a, $b) use (&$c, $d) {};
function() {};
foo;
namespace\foo;
\foo;
empty($a);
empty(Foo);
@$a;
eval($a);
exit;
exit($a);
die();
die($a);
foo();
namespace\foo(&$a);
\foo([]);
$foo(yield $a);
$a--;
$a++;
--$a;
++$a;
include $a;
include_once $a;
require $a;
require_once $a;
$a instanceof Foo;
$a instanceof namespace\Foo;
$a instanceof \Foo;
isset($a, $b);
isset(Foo);
list() = $b;
list($a, $b) = $b;
list($a[]) = $b;
list(list($a)) = $b;
$a->foo();
new Foo;
new namespace\Foo();
new \Foo();
print($a);
$a->foo;
$a->foo[1];
$a->foo->bar->baz()->quux[0];
$a->foo()[1][1];
`cmd $a`;
`cmd`;
``;
[];
[1];
[1=>1, &$b,];
Foo::bar();
namespace\Foo::bar();
\Foo::bar();
Foo::$bar();
$foo::$bar();
Foo::$bar;
namespace\Foo::$bar;
\Foo::$bar;
$a ? $b : $c;
$a ? : $c;
$a ? $b ? $c : $d : $e;
$a ? $b : $c ? $d : $e;
-$a;
+$a;
$$a;
$$$a;
yield;
yield $a;
yield $a => $b;
yield Foo::class;
yield $a => Foo::class;
(array)$a;
(boolean)$a;
(bool)$a;
(double)$a;
(float)$a;
(integer)$a;
(int)$a;
(object)$a;
(string)$a;
(unset)$a;
$a & $b;
$a | $b;
$a ^ $b;
$a && $b;
$a || $b;
$a . $b;
$a / $b;
$a == $b;
$a >= $b;
$a > $b;
$a === $b;
$a and $b;
$a or $b;
$a xor $b;
$a - $b;
$a % $b;
$a * $b;
$a != $b;
$a !== $b;
$a + $b;
$a ** $b;
$a << $b;
$a >> $b;
$a <= $b;
$a < $b;
$a =& $b;
$a =& new Foo;
$a =& new Foo($b);
$a = $b;
$a &= $b;
$a |= $b;
$a ^= $b;
$a .= $b;
$a /= $b;
$a -= $b;
$a %= $b;
$a *= $b;
$a += $b;
$a **= $b;
$a <<= $b;
$a >>= $b;
(new \Foo());
(new \Foo())->bar()->baz;
(new \Foo())[0][0];
(new \Foo())[0]->bar();
array([0])[0][0];
"foo"[0];
foo[0];
static::foo;
new $foo;
new $foo::$bar;
new $a->b[0];
new $a->b{$b ?: null}->$c->d[0];static $a = [1][0];
static $a = !1;
static $a = ~1;
static $a = +1;
static $a = -1;
static $a = (1);
static $a = 1 ?: 2;
static $a = 1 ? 2 : 3;
static $a = 1 & 2;
static $a = 1 | 2;
static $a = 1 ^ 2;
static $a = 1 && 2;
static $a = 1 || 2;
static $a = 1 . 2;
static $a = 1 / 2;
static $a = 1 == 2;
static $a = 1 >= 2;
static $a = 1 > 2;
static $a = 1 === 2;
static $a = 1 and 2;
static $a = 1 or 2;
static $a = 1 xor 2;
static $a = 1 - 2;
static $a = 1 % 2;
static $a = 1 * 2;
static $a = 1 != 2;
static $a = 1 !== 2;
static $a = 1 + 2;
static $a = 1 ** 2;
static $a = 1 << 2;
static $a = 1 >> 2;
static $a = 1 <= 2;
static $a = 1 < 2;
static $a = Foo::bar;
static $a = Foo::class;
static $a = __CLASS__;
static $a = Foo;
static $a = namespace\Foo;
static $a = \Foo;
static $a = array();
static $a = array(1 => 1, 2);
static $a = [1, 2 => 2][0];
if (yield 1) {}
Foo::$$bar;
$foo();
$foo()[0][0];
$a{$b};
${$a};
$foo::{$bar}();
$foo::bar;
__halt_compiler();
parsing process must be terminated

99
internal/php7/node.go Normal file
View File

@ -0,0 +1,99 @@
package php7
import (
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/position"
"github.com/z7zmey/php-parser/pkg/token"
)
type ParserBrackets struct {
Position *position.Position
OpenBracketTkn *token.Token
Child ast.Vertex
CloseBracketTkn *token.Token
}
func (n *ParserBrackets) Accept(v ast.Visitor) {
// do nothing
}
func (n *ParserBrackets) GetPosition() *position.Position {
return n.Position
}
type ParserSeparatedList struct {
Position *position.Position
Items []ast.Vertex
SeparatorTkns []*token.Token
}
func (n *ParserSeparatedList) Accept(v ast.Visitor) {
// do nothing
}
func (n *ParserSeparatedList) GetPosition() *position.Position {
return n.Position
}
// TraitAdaptationList node
type TraitAdaptationList struct {
Position *position.Position
OpenCurlyBracketTkn *token.Token
Adaptations []ast.Vertex
CloseCurlyBracketTkn *token.Token
}
func (n *TraitAdaptationList) Accept(v ast.Visitor) {
// do nothing
}
func (n *TraitAdaptationList) GetPosition() *position.Position {
return n.Position
}
// ArgumentList node
type ArgumentList struct {
Position *position.Position
OpenParenthesisTkn *token.Token
Arguments []ast.Vertex
SeparatorTkns []*token.Token
CloseParenthesisTkn *token.Token
}
func (n *ArgumentList) Accept(v ast.Visitor) {
// do nothing
}
func (n *ArgumentList) GetPosition() *position.Position {
return n.Position
}
type ReturnType struct {
Position *position.Position
ColonTkn *token.Token
Type ast.Vertex
}
func (n *ReturnType) Accept(v ast.Visitor) {
// do nothing
}
func (n *ReturnType) GetPosition() *position.Position {
return n.Position
}
// TraitMethodRef node
type TraitMethodRef struct {
Position *position.Position
Trait ast.Vertex
DoubleColonTkn *token.Token
Method ast.Vertex
}
func (n *TraitMethodRef) Accept(v ast.Visitor) {
// do nothing
}
func (n *TraitMethodRef) GetPosition() *position.Position {
return n.Position
}

66
internal/php7/parser.go Normal file
View File

@ -0,0 +1,66 @@
package php7
import (
"github.com/z7zmey/php-parser/internal/position"
"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/errors"
"github.com/z7zmey/php-parser/pkg/token"
)
// Parser structure
type Parser struct {
Lexer *scanner.Lexer
currentToken *token.Token
rootNode ast.Vertex
errHandlerFunc func(*errors.Error)
builder *position.Builder
}
// NewParser creates and returns new Parser
func NewParser(lexer *scanner.Lexer, config cfg.Config) *Parser {
return &Parser{
Lexer: lexer,
errHandlerFunc: config.ErrorHandlerFunc,
builder: position.NewBuilder(),
}
}
func (p *Parser) Lex(lval *yySymType) int {
t := p.Lexer.Lex()
p.currentToken = t
lval.token = t
return int(t.ID)
}
func (p *Parser) Error(msg string) {
if p.errHandlerFunc == nil {
return
}
p.errHandlerFunc(errors.NewError(msg, p.currentToken.Position))
}
// Parse the php7 Parser entrypoint
func (p *Parser) Parse() int {
p.rootNode = nil
return yyParse(p)
}
// GetRootNode returns root node
func (p *Parser) GetRootNode() ast.Vertex {
return p.rootNode
}
// helpers
func lastNode(nn []ast.Vertex) ast.Vertex {
if len(nn) == 0 {
return nil
}
return nn[len(nn)-1]
}

57013
internal/php7/parser_test.go Normal file

File diff suppressed because it is too large Load Diff

BIN
internal/php7/php7.go generated Normal file

Binary file not shown.

4428
internal/php7/php7.y Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
package php7_test
import (
"io/ioutil"
"testing"
"github.com/z7zmey/php-parser/internal/php7"
"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) {
src, err := ioutil.ReadFile("test.php")
if err != nil {
b.Fatal("can not read test.php: " + err.Error())
}
for n := 0; n < b.N; n++ {
config := cfg.Config{
Version: &version.Version{
Major: 7,
Minor: 4,
},
}
lexer := scanner.NewLexer(src, config)
php7parser := php7.NewParser(lexer, config)
php7parser.Parse()
}
}

350
internal/php7/test.php Normal file
View File

@ -0,0 +1,350 @@
<?
foo($a, ...$b);
$foo($a, ...$b);
$foo->bar($a, ...$b);
foo::bar($a, ...$b);
$foo::bar($a, ...$b);
new foo($a, ...$b);
/** anonymous class */
new class ($a, ...$b) {};
new class {};
new $foo;
new $foo[1];
new $foo{$bar};
new $foo->bar;
new $foo::$bar;
new static::$bar;
function foo(?bar $bar=null, baz &...$baz) {}
class foo {public function foo(?bar $bar=null, baz &...$baz) {}}
function(?bar $bar=null, baz &...$baz) {};
static function(?bar $bar=null, baz &...$baz) {};
1234567890123456789;
12345678901234567890;
0.;
0b0111111111111111111111111111111111111111111111111111111111111111;
0b1111111111111111111111111111111111111111111111111111111111111111;
0x007111111111111111;
0x8111111111111111;
__CLASS__;
__DIR__;
__FILE__;
__FUNCTION__;
__LINE__;
__NAMESPACE__;
__METHOD__;
__TRAIT__;
"test $var";
"test $var[1]";
"test $var[-1]";
"test $var[1234567890123456789012345678901234567890]";
"test $var[-1234567890123456789012345678901234567890]";
"test $var[bar]";
"test $var[$bar]";
"$foo $bar";
"test $foo->bar()";
"test ${foo}";
"test ${foo[0]}";
"test ${$foo}";
"test {$foo->bar()}";
if ($a) :
endif;
if ($a) :
elseif ($b):
endif;
if ($a) :
else:
endif;
if ($a) :
elseif ($b):
elseif ($c):
else:
endif;
while (1) { break; }
while (1) { break 2; }
while (1) : break(3); endwhile;
class foo{ public const FOO = 1, BAR = 2; }
class foo{ const FOO = 1, BAR = 2; }
class foo{ function bar() {} }
class foo{ public static function &bar() {} }
class foo{ public static function &bar(): void {} }
abstract class foo{ }
final class foo extends bar { }
final class foo implements bar { }
final class foo implements bar, baz { }
new class() extends foo implements bar, baz { };
const FOO = 1, BAR = 2;
while (1) { continue; }
while (1) { continue 2; }
while (1) { continue(3); }
declare(ticks=1);
declare(ticks=1) {}
declare(ticks=1): enddeclare;
do {} while(1);
echo $a, 1;
echo($a);
for($i = 0; $i < 10; $i++, $i++) {}
for(; $i < 10; $i++, $i++) : endfor;
foreach ($a as $v) {}
foreach ($a as $v) : endforeach;
foreach ($a as $k => $v) {}
foreach ($a as $k => &$v) {}
foreach ($a as $k => list($v)) {}
foreach ($a as $k => [$v]) {}
function foo() {}
function foo() {return;}
function &foo() {return 1;}
function &foo(): void {}
global $a, $b;
a:
goto a;
if ($a) {}
if ($a) {} elseif ($b) {}
if ($a) {} else {}
if ($a) {} elseif ($b) {} elseif ($c) {} else {}
if ($a) {} elseif ($b) {} else if ($c) {} else {}
?> <div></div> <?
interface Foo {}
interface Foo extends Bar {}
interface Foo extends Bar, Baz {}
namespace Foo;
namespace Foo {}
namespace {}
class foo {var $a;}
class foo {public static $a, $b = 1;}
static $a, $b = 1;
switch (1) :
case 1:
default:
case 2:
endswitch;
switch (1) :;
case 1;
case 2;
endswitch;
switch (1) {
case 1: break;
case 2: break;
}
switch (1) {;
case 1; break;
case 2; break;
}
throw $e;
trait Foo {}
class Foo { use Bar; }
class Foo { use Bar, Baz {} }
class Foo { use Bar, Baz { one as include; } }
class Foo { use Bar, Baz { one as public; } }
class Foo { use Bar, Baz { one as public two; } }
class Foo { use Bar, Baz { Bar::one insteadof Baz, Quux; Baz::one as two; } }
try {}
try {} catch (Exception $e) {}
try {} catch (Exception|RuntimeException $e) {}
try {} catch (Exception $e) {} catch (RuntimeException $e) {}
try {} catch (Exception $e) {} finally {}
unset($a, $b,);
use Foo;
use \Foo;
use \Foo as Bar;
use Foo, Bar;
use Foo, Bar as Baz;
use function Foo, \Bar;
use function Foo as foo, \Bar as bar;
use const Foo, \Bar;
use const Foo as foo, \Bar as bar;
use \Foo\{Bar, Baz};
use Foo\{Bar, Baz as quux};
use function Foo\{Bar, Baz};
use const \Foo\{Bar, Baz};
use Foo\{const Bar, function Baz};
$a[1];
$a[1][2];
array();
array(1);
array(1=>1, &$b,);
~$a;
!$a;
Foo::Bar;
$foo::Bar;
clone($a);
clone $a;
function(){};
function($a, $b) use ($c, &$d) {};
function(): void {};
foo;
namespace\foo;
\foo;
empty($a);
@$a;
eval($a);
exit;
exit($a);
die;
die($a);
foo();
namespace\foo();
\foo();
$foo();
$a--;
$a++;
--$a;
++$a;
include $a;
include_once $a;
require $a;
require_once $a;
$a instanceof Foo;
$a instanceof namespace\Foo;
$a instanceof \Foo;
isset($a, $b);
list($a) = $b;
list($a[]) = $b;
list(list($a)) = $b;
$a->foo();
new Foo();
new namespace\Foo();
new \Foo();
new class ($a, ...$b) {};
print($a);
$a->foo;
`cmd $a`;
`cmd`;
``;
[];
[1];
[1=>1, &$b,];
[$a] = $b;
[$a[]] = $b;
[list($a)] = $b;
Foo::bar();
namespace\Foo::bar();
\Foo::bar();
Foo::$bar;
$foo::$bar;
namespace\Foo::$bar;
\Foo::$bar;
$a ? $b : $c;
$a ? : $c;
$a ? $b ? $c : $d : $e;
$a ? $b : $c ? $d : $e;
-$a;
+$a;
$$a;
yield;
yield $a;
yield $a => $b;
yield from $a;
(array)$a;
(boolean)$a;
(bool)$a;
(double)$a;
(float)$a;
(integer)$a;
(int)$a;
(object)$a;
(string)$a;
(unset)$a;
$a & $b;
$a | $b;
$a ^ $b;
$a && $b;
$a || $b;
$a ?? $b;
$a . $b;
$a / $b;
$a == $b;
$a >= $b;
$a > $b;
$a === $b;
$a and $b;
$a or $b;
$a xor $b;
$a - $b;
$a % $b;
$a * $b;
$a != $b;
$a !== $b;
$a + $b;
$a ** $b;
$a << $b;
$a >> $b;
$a <= $b;
$a < $b;
$a <=> $b;
$a =& $b;
$a = $b;
$a &= $b;
$a |= $b;
$a ^= $b;
$a .= $b;
$a /= $b;
$a -= $b;
$a %= $b;
$a *= $b;
$a += $b;
$a **= $b;
$a <<= $b;
$a >>= $b;
class foo {public function class() {} }
\foo\bar();
function foo(&$a, ...$b) {
function bar() {}
class Baz {}
trait Quux{}
interface Quuux {}
}
function foo(&$a = 1, ...$b = 1, $c = 1) {}
function foo(array $a, callable $b) {}
abstract final class foo { abstract protected static function bar(); final private function baz() {} }
(new Foo)->bar;
(new Foo)();
[$foo][0]();
foo[1]();
"foo"();
[1]{$foo}();
${foo()};
Foo::$bar();
Foo::{$bar[0]}();
$foo->$bar;
$foo->{$bar[0]};
[1=>&$a, 2=>list($b)];
__halt_compiler();
parsing process must be terminated

View File

@ -0,0 +1,237 @@
package position
import (
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/position"
"github.com/z7zmey/php-parser/pkg/token"
)
type startPos struct {
startLine int
startPos int
}
type endPos struct {
endLine int
endPos int
}
type Builder struct {
pool *position.Pool
}
func NewBuilder() *Builder {
return &Builder{
pool: position.NewPool(position.DefaultBlockSize),
}
}
func getListStartPos(l []ast.Vertex) startPos {
if l == nil {
return startPos{-1, -1}
}
if len(l) == 0 {
return startPos{-1, -1}
}
return getNodeStartPos(l[0])
}
func getNodeStartPos(n ast.Vertex) startPos {
sl := -1
sp := -1
if n == nil {
return startPos{-1, -1}
}
p := n.GetPosition()
if p != nil {
sl = p.StartLine
sp = p.StartPos
}
return startPos{sl, sp}
}
func getListEndPos(l []ast.Vertex) endPos {
if l == nil {
return endPos{-1, -1}
}
if len(l) == 0 {
return endPos{-1, -1}
}
return getNodeEndPos(l[len(l)-1])
}
func getNodeEndPos(n ast.Vertex) endPos {
el := -1
ep := -1
if n == nil {
return endPos{-1, -1}
}
p := n.GetPosition()
if p != nil {
el = p.EndLine
ep = p.EndPos
}
return endPos{el, ep}
}
// NewNodeListPosition returns new Position
func (b *Builder) NewNodeListPosition(list []ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = getListStartPos(list).startLine
pos.EndLine = getListEndPos(list).endLine
pos.StartPos = getListStartPos(list).startPos
pos.EndPos = getListEndPos(list).endPos
return pos
}
// NewNodePosition returns new Position
func (b *Builder) NewNodePosition(n ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = getNodeStartPos(n).startLine
pos.EndLine = getNodeEndPos(n).endLine
pos.StartPos = getNodeStartPos(n).startPos
pos.EndPos = getNodeEndPos(n).endPos
return pos
}
// NewTokenPosition returns new Position
func (b *Builder) NewTokenPosition(t *token.Token) *position.Position {
pos := b.pool.Get()
pos.StartLine = t.Position.StartLine
pos.EndLine = t.Position.EndLine
pos.StartPos = t.Position.StartPos
pos.EndPos = t.Position.EndPos
return pos
}
// NewTokensPosition returns new Position
func (b *Builder) NewTokensPosition(startToken *token.Token, endToken *token.Token) *position.Position {
pos := b.pool.Get()
pos.StartLine = startToken.Position.StartLine
pos.EndLine = endToken.Position.EndLine
pos.StartPos = startToken.Position.StartPos
pos.EndPos = endToken.Position.EndPos
return pos
}
// NewTokenNodePosition returns new Position
func (b *Builder) NewTokenNodePosition(t *token.Token, n ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = t.Position.StartLine
pos.EndLine = getNodeEndPos(n).endLine
pos.StartPos = t.Position.StartPos
pos.EndPos = getNodeEndPos(n).endPos
return pos
}
// NewNodeTokenPosition returns new Position
func (b *Builder) NewNodeTokenPosition(n ast.Vertex, t *token.Token) *position.Position {
pos := b.pool.Get()
pos.StartLine = getNodeStartPos(n).startLine
pos.EndLine = t.Position.EndLine
pos.StartPos = getNodeStartPos(n).startPos
pos.EndPos = t.Position.EndPos
return pos
}
// NewNodesPosition returns new Position
func (b *Builder) NewNodesPosition(startNode ast.Vertex, endNode ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = getNodeStartPos(startNode).startLine
pos.EndLine = getNodeEndPos(endNode).endLine
pos.StartPos = getNodeStartPos(startNode).startPos
pos.EndPos = getNodeEndPos(endNode).endPos
return pos
}
// NewNodeListTokenPosition returns new Position
func (b *Builder) NewNodeListTokenPosition(list []ast.Vertex, t *token.Token) *position.Position {
pos := b.pool.Get()
pos.StartLine = getListStartPos(list).startLine
pos.EndLine = t.Position.EndLine
pos.StartPos = getListStartPos(list).startPos
pos.EndPos = t.Position.EndPos
return pos
}
// NewTokenNodeListPosition returns new Position
func (b *Builder) NewTokenNodeListPosition(t *token.Token, list []ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = t.Position.StartLine
pos.EndLine = getListEndPos(list).endLine
pos.StartPos = t.Position.StartPos
pos.EndPos = getListEndPos(list).endPos
return pos
}
// NewNodeNodeListPosition returns new Position
func (b *Builder) NewNodeNodeListPosition(n ast.Vertex, list []ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = getNodeStartPos(n).startLine
pos.EndLine = getListEndPos(list).endLine
pos.StartPos = getNodeStartPos(n).startPos
pos.EndPos = getListEndPos(list).endPos
return pos
}
// NewNodeListNodePosition returns new Position
func (b *Builder) NewNodeListNodePosition(list []ast.Vertex, n ast.Vertex) *position.Position {
pos := b.pool.Get()
pos.StartLine = getListStartPos(list).startLine
pos.EndLine = getNodeEndPos(n).endLine
pos.StartPos = getListStartPos(list).startPos
pos.EndPos = getNodeEndPos(n).endPos
return pos
}
// NewOptionalListTokensPosition returns new Position
func (b *Builder) NewOptionalListTokensPosition(list []ast.Vertex, t *token.Token, endToken *token.Token) *position.Position {
pos := b.pool.Get()
if list == nil {
pos.StartLine = t.Position.StartLine
pos.EndLine = endToken.Position.EndLine
pos.StartPos = t.Position.StartPos
pos.EndPos = endToken.Position.EndPos
return pos
}
pos.StartLine = getListStartPos(list).startLine
pos.EndLine = endToken.Position.EndLine
pos.StartPos = getListStartPos(list).startPos
pos.EndPos = endToken.Position.EndPos
return pos
}

View File

@ -0,0 +1,431 @@
package position_test
import (
"gotest.tools/assert"
"testing"
builder "github.com/z7zmey/php-parser/internal/position"
"github.com/z7zmey/php-parser/pkg/ast"
"github.com/z7zmey/php-parser/pkg/position"
"github.com/z7zmey/php-parser/pkg/token"
)
func TestNewTokenPosition(t *testing.T) {
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
pos := builder.NewBuilder().NewTokenPosition(tkn)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 1, EndPos: 3}, pos)
}
func TestNewTokensPosition(t *testing.T) {
token1 := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
token2 := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 4,
EndPos: 6,
},
}
pos := builder.NewBuilder().NewTokensPosition(token1, token2)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 2, EndPos: 6}, pos)
}
func TestNewNodePosition(t *testing.T) {
n := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
pos := builder.NewBuilder().NewNodePosition(n)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 1, EndPos: 3}, pos)
}
func TestNewTokenNodePosition(t *testing.T) {
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
n := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 4,
EndPos: 12,
},
}
pos := builder.NewBuilder().NewTokenNodePosition(tkn, n)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 2, EndPos: 12}, pos)
}
func TestNewNodeTokenPosition(t *testing.T) {
n := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 9,
},
}
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 10,
EndPos: 12,
},
}
pos := builder.NewBuilder().NewNodeTokenPosition(n, tkn)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 2, EndPos: 12}, pos)
}
func TestNewNodeListPosition(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 9,
},
}
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 10,
EndPos: 19,
},
}
pos := builder.NewBuilder().NewNodeListPosition([]ast.Vertex{n1, n2})
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 2, EndPos: 19}, pos)
}
func TestNewNodesPosition(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 9,
},
}
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 10,
EndPos: 19,
},
}
pos := builder.NewBuilder().NewNodesPosition(n1, n2)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 2, EndPos: 19}, pos)
}
func TestNewNodeListTokenPosition(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 9,
},
}
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 10,
EndPos: 19,
},
}
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 20,
EndPos: 22,
},
}
pos := builder.NewBuilder().NewNodeListTokenPosition([]ast.Vertex{n1, n2}, tkn)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 3, EndPos: 22}, pos)
}
func TestNewTokenNodeListPosition(t *testing.T) {
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 2,
},
}
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 3,
EndPos: 10,
},
}
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 11,
EndPos: 20,
},
}
pos := builder.NewBuilder().NewTokenNodeListPosition(tkn, []ast.Vertex{n1, n2})
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 3, EndPos: 20}, pos)
}
func TestNewNodeNodeListPosition(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 8,
},
}
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 9,
EndPos: 17,
},
}
n3 := &ast.Identifier{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 18,
EndPos: 26,
},
}
pos := builder.NewBuilder().NewNodeNodeListPosition(n1, []ast.Vertex{n2, n3})
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 3, EndPos: 26}, pos)
}
func TestNewNodeListNodePosition(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 8,
},
}
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 9,
EndPos: 17,
},
}
n3 := &ast.Identifier{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 18,
EndPos: 26,
},
}
pos := builder.NewBuilder().NewNodeListNodePosition([]ast.Vertex{n1, n2}, n3)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 3, EndPos: 26}, pos)
}
func TestNewOptionalListTokensPosition(t *testing.T) {
token1 := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
token2 := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 4,
EndPos: 6,
},
}
pos := builder.NewBuilder().NewOptionalListTokensPosition(nil, token1, token2)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: 2, EndPos: 6}, pos)
}
func TestNewOptionalListTokensPosition2(t *testing.T) {
n2 := &ast.Identifier{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 9,
EndPos: 17,
},
}
n3 := &ast.Identifier{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 18,
EndPos: 26,
},
}
token1 := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 27,
EndPos: 29,
},
}
token2 := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 30,
EndPos: 32,
},
}
pos := builder.NewBuilder().NewOptionalListTokensPosition([]ast.Vertex{n2, n3}, token1, token2)
assert.DeepEqual(t, &position.Position{StartLine: 2, EndLine: 5, StartPos: 9, EndPos: 32}, pos)
}
func TestNilNodePos(t *testing.T) {
pos := builder.NewBuilder().NewNodesPosition(nil, nil)
assert.DeepEqual(t, &position.Position{StartLine: -1, EndLine: -1, StartPos: -1, EndPos: -1}, pos)
}
func TestNilNodeListPos(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 8,
},
}
pos := builder.NewBuilder().NewNodeNodeListPosition(n1, nil)
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: -1, EndPos: -1}, pos)
}
func TestNilNodeListTokenPos(t *testing.T) {
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
pos := builder.NewBuilder().NewNodeListTokenPosition(nil, tkn)
assert.DeepEqual(t, &position.Position{StartLine: -1, EndLine: 1, StartPos: -1, EndPos: 3}, pos)
}
func TestEmptyNodeListPos(t *testing.T) {
n1 := &ast.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 8,
},
}
pos := builder.NewBuilder().NewNodeNodeListPosition(n1, []ast.Vertex{})
assert.DeepEqual(t, &position.Position{StartLine: 1, EndLine: -1, EndPos: -1}, pos)
}
func TestEmptyNodeListTokenPos(t *testing.T) {
tkn := &token.Token{
Value: []byte(`foo`),
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 3,
},
}
pos := builder.NewBuilder().NewNodeListTokenPosition([]ast.Vertex{}, tkn)
assert.DeepEqual(t, &position.Position{StartLine: -1, EndLine: 1, StartPos: -1, EndPos: 3}, pos)
}

View File

@ -4,103 +4,71 @@ import (
"bytes" "bytes"
"strings" "strings"
"github.com/z7zmey/php-parser/errors" "github.com/z7zmey/php-parser/pkg/cfg"
"github.com/z7zmey/php-parser/freefloating" "github.com/z7zmey/php-parser/pkg/errors"
"github.com/z7zmey/php-parser/position" "github.com/z7zmey/php-parser/pkg/position"
"github.com/z7zmey/php-parser/version" "github.com/z7zmey/php-parser/pkg/token"
"github.com/z7zmey/php-parser/pkg/version"
) )
type Scanner interface {
Lex(lval Lval) int
ReturnTokenToPool(t *Token)
GetPhpDocComment() string
SetPhpDocComment(string)
GetErrors() []*errors.Error
GetWithFreeFloating() bool
SetWithFreeFloating(bool)
AddError(e *errors.Error)
SetErrors(e []*errors.Error)
}
// Lval parsers yySymType must implement this interface
type Lval interface {
Token(tkn *Token)
}
type Lexer struct { type Lexer struct {
data []byte data []byte
p, pe, cs int phpVersion *version.Version
ts, te, act int errHandlerFunc func(*errors.Error)
stack []int
top int p, pe, cs int
ts, te, act int
stack []int
top int
heredocLabel []byte heredocLabel []byte
tokenPool *token.Pool
TokenPool *TokenPool positionPool *position.Pool
FreeFloating []freefloating.String newLines NewLines
WithFreeFloating bool
PhpDocComment string
lastToken *Token
Errors []*errors.Error
NewLines NewLines
PHPVersion string
} }
func (l *Lexer) ReturnTokenToPool(t *Token) { func NewLexer(data []byte, config cfg.Config) *Lexer {
l.TokenPool.Put(t) lex := &Lexer{
} data: data,
phpVersion: config.Version,
errHandlerFunc: config.ErrorHandlerFunc,
func (l *Lexer) GetPhpDocComment() string { pe: len(data),
return l.PhpDocComment stack: make([]int, 0),
}
func (l *Lexer) SetPhpDocComment(s string) { tokenPool: token.NewPool(position.DefaultBlockSize),
l.PhpDocComment = s positionPool: position.NewPool(token.DefaultBlockSize),
} newLines: NewLines{make([]int, 0, 128)},
func (l *Lexer) GetErrors() []*errors.Error {
return l.Errors
}
func (l *Lexer) GetWithFreeFloating() bool {
return l.WithFreeFloating
}
func (l *Lexer) SetWithFreeFloating(b bool) {
l.WithFreeFloating = b
}
func (l *Lexer) AddError(e *errors.Error) {
l.Errors = append(l.Errors, e)
}
func (l *Lexer) SetErrors(e []*errors.Error) {
l.Errors = e
}
func (lex *Lexer) setTokenPosition(token *Token) {
token.StartLine = lex.NewLines.GetLine(lex.ts)
token.EndLine = lex.NewLines.GetLine(lex.te - 1)
token.StartPos = lex.ts
token.EndPos = lex.te
}
func (lex *Lexer) addFreeFloating(t freefloating.StringType, ps, pe int) {
if !lex.WithFreeFloating {
return
} }
pos := position.NewPosition( initLexer(lex)
lex.NewLines.GetLine(lex.ts),
lex.NewLines.GetLine(lex.te-1),
lex.ts,
lex.te,
)
lex.FreeFloating = append(lex.FreeFloating, freefloating.String{ return lex
StringType: t, }
Value: string(lex.data[ps:pe]),
Position: pos, func (lex *Lexer) setTokenPosition(token *token.Token) {
}) pos := lex.positionPool.Get()
pos.StartLine = lex.newLines.GetLine(lex.ts)
pos.EndLine = lex.newLines.GetLine(lex.te - 1)
pos.StartPos = lex.ts
pos.EndPos = lex.te
token.Position = pos
}
func (lex *Lexer) addFreeFloatingToken(t *token.Token, id token.ID, ps, pe int) {
skippedTkn := lex.tokenPool.Get()
skippedTkn.ID = id
skippedTkn.Value = lex.data[ps:pe]
lex.setTokenPosition(skippedTkn)
if t.FreeFloating == nil {
t.FreeFloating = make([]*token.Token, 0, 2)
}
t.FreeFloating = append(t.FreeFloating, skippedTkn)
} }
func (lex *Lexer) isNotStringVar() bool { func (lex *Lexer) isNotStringVar() bool {
@ -134,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 {
@ -255,21 +223,25 @@ func (lex *Lexer) ungetCnt(n int) {
lex.te = lex.te - n lex.te = lex.te - n
} }
func (lex *Lexer) Error(msg string) { func (lex *Lexer) error(msg string) {
if lex.errHandlerFunc == nil {
return
}
pos := position.NewPosition( pos := position.NewPosition(
lex.NewLines.GetLine(lex.ts), lex.newLines.GetLine(lex.ts),
lex.NewLines.GetLine(lex.te-1), lex.newLines.GetLine(lex.te-1),
lex.ts, lex.ts,
lex.te, lex.te,
) )
lex.Errors = append(lex.Errors, errors.NewError(msg, pos)) lex.errHandlerFunc(errors.NewError(msg, pos))
} }
func isValidVarNameStart(r byte) bool { func isValidVarNameStart(r byte) bool {
return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || r == '_' || (r >= 0x80 && r <= 0xff) return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || r == '_' || r >= 0x80
} }
func isValidVarName(r byte) bool { func isValidVarName(r byte) bool {
return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || (r >= 0x80 && r <= 0xff) return (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r >= 0x80
} }

Binary file not shown.

View File

@ -5,7 +5,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/z7zmey/php-parser/freefloating" "github.com/z7zmey/php-parser/pkg/token"
) )
%%{ %%{
@ -16,27 +16,15 @@ import (
variable pe lex.pe; variable pe lex.pe;
}%% }%%
func NewLexer(data []byte) *Lexer { func initLexer(lex *Lexer) {
lex := &Lexer{
data: data,
pe: len(data),
stack: make([]int, 0),
TokenPool: &TokenPool{},
NewLines: NewLines{make([]int, 0, 128)},
}
%% write init; %% write init;
return lex
} }
func (lex *Lexer) Lex(lval Lval) int { func (lex *Lexer) Lex() *token.Token {
lex.FreeFloating = nil
eof := lex.pe eof := lex.pe
var tok TokenID var tok token.ID
token := lex.TokenPool.Get() tkn := lex.tokenPool.Get()
token.FreeFloating = lex.FreeFloating
token.Value = string(lex.data[0:0])
lblStart := 0 lblStart := 0
lblEnd := 0 lblEnd := 0
@ -49,11 +37,11 @@ func (lex *Lexer) Lex(lval Lval) int {
action new_line { action new_line {
if lex.data[lex.p] == '\n' { if lex.data[lex.p] == '\n' {
lex.NewLines.Append(lex.p+1) lex.newLines.Append(lex.p+1)
} }
if lex.data[lex.p] == '\r' && lex.data[lex.p+1] != '\n' { if lex.data[lex.p] == '\r' && lex.data[lex.p+1] != '\n' {
lex.NewLines.Append(lex.p+1) lex.newLines.Append(lex.p+1)
} }
} }
@ -127,16 +115,17 @@ func (lex *Lexer) Lex(lval Lval) int {
| '"' -> final | '"' -> final
), ),
double_qoute_nonvarname: ( double_qoute_nonvarname: (
(any - [\\{"\r\n] - varname_first) -> double_qoute (any - [\\${"\r\n] - varname_first) -> double_qoute
| "\r" @new_line -> double_qoute | "\r" @new_line -> double_qoute
| "\n" @new_line -> double_qoute | "\n" @new_line -> double_qoute
| "\\" -> double_qoute_any | "\\" -> double_qoute_any
| '"' -> final | '$' -> double_qoute_nonvarname
| '"' -> final
); );
main := |* main := |*
"#!" any* :>> newline => { "#!" any* :>> newline => {
lex.addFreeFloating(freefloating.CommentType, lex.ts, lex.te) lex.addFreeFloatingToken(tkn, token.T_COMMENT, lex.ts, lex.te)
}; };
any => { any => {
fnext html; fnext html;
@ -147,42 +136,42 @@ func (lex *Lexer) Lex(lval Lval) int {
html := |* html := |*
any_line+ -- '<?' => { any_line+ -- '<?' => {
lex.ungetStr("<") lex.ungetStr("<")
lex.setTokenPosition(token) lex.setTokenPosition(tkn)
tok = T_INLINE_HTML; tok = token.T_INLINE_HTML;
fbreak; fbreak;
}; };
'<?' => { '<?' => {
lex.addFreeFloating(freefloating.TokenType, lex.ts, lex.te) lex.addFreeFloatingToken(tkn, token.T_OPEN_TAG, lex.ts, lex.te)
fnext php; fnext php;
}; };
'<?php'i ( [ \t] | newline ) => { '<?php'i ( [ \t] | newline ) => {
lex.ungetCnt(lex.te - lex.ts - 5) lex.ungetCnt(lex.te - lex.ts - 5)
lex.addFreeFloating(freefloating.TokenType, lex.ts, lex.ts+5) lex.addFreeFloatingToken(tkn, token.T_OPEN_TAG, lex.ts, lex.ts+5)
fnext php; fnext php;
}; };
'<?='i => { '<?='i => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_ECHO; tok = token.T_ECHO;
fnext php; fnext php;
fbreak; fbreak;
}; };
*|; *|;
php := |* php := |*
whitespace_line* => {lex.addFreeFloating(freefloating.WhiteSpaceType, lex.ts, lex.te)}; whitespace_line* => {lex.addFreeFloatingToken(tkn, token.T_WHITESPACE, lex.ts, lex.te)};
'?>' newline? => {lex.setTokenPosition(token); tok = TokenID(int(';')); fnext html; fbreak;}; '?>' newline? => {lex.setTokenPosition(tkn); tok = token.ID(int(';')); fnext html; fbreak;};
';' whitespace_line* '?>' newline? => {lex.setTokenPosition(token); tok = TokenID(int(';')); fnext html; fbreak;}; ';' whitespace_line* '?>' newline? => {lex.setTokenPosition(tkn); tok = token.ID(int(';')); fnext html; fbreak;};
(dnum | exponent_dnum) => {lex.setTokenPosition(token); tok = T_DNUMBER; fbreak;}; (dnum | exponent_dnum) => {lex.setTokenPosition(tkn); tok = token.T_DNUMBER; fbreak;};
bnum => { bnum => {
s := strings.Replace(string(lex.data[lex.ts+2:lex.te]), "_", "", -1) s := strings.Replace(string(lex.data[lex.ts+2:lex.te]), "_", "", -1)
_, err := strconv.ParseInt(s, 2, 0) _, err := strconv.ParseInt(s, 2, 0)
if err == nil { if err == nil {
lex.setTokenPosition(token); tok = T_LNUMBER; fbreak; lex.setTokenPosition(tkn); tok = token.T_LNUMBER; fbreak;
} }
lex.setTokenPosition(token); tok = T_DNUMBER; fbreak; lex.setTokenPosition(tkn); tok = token.T_DNUMBER; fbreak;
}; };
lnum => { lnum => {
base := 10 base := 10
@ -194,180 +183,179 @@ func (lex *Lexer) Lex(lval Lval) int {
_, err := strconv.ParseInt(s, base, 0) _, err := strconv.ParseInt(s, base, 0)
if err == nil { if err == nil {
lex.setTokenPosition(token); tok = T_LNUMBER; fbreak; lex.setTokenPosition(tkn); tok = token.T_LNUMBER; fbreak;
} }
lex.setTokenPosition(token); tok = T_DNUMBER; fbreak; lex.setTokenPosition(tkn); tok = token.T_DNUMBER; fbreak;
}; };
hnum => { hnum => {
s := strings.Replace(string(lex.data[lex.ts+2:lex.te]), "_", "", -1) s := strings.Replace(string(lex.data[lex.ts+2:lex.te]), "_", "", -1)
_, err := strconv.ParseInt(s, 16, 0) _, err := strconv.ParseInt(s, 16, 0)
if err == nil { if err == nil {
lex.setTokenPosition(token); tok = T_LNUMBER; fbreak; lex.setTokenPosition(tkn); tok = token.T_LNUMBER; fbreak;
} }
lex.setTokenPosition(token); tok = T_DNUMBER; fbreak; lex.setTokenPosition(tkn); tok = token.T_DNUMBER; fbreak;
}; };
'abstract'i => {lex.setTokenPosition(token); tok = T_ABSTRACT; fbreak;}; 'abstract'i => {lex.setTokenPosition(tkn); tok = token.T_ABSTRACT; fbreak;};
'array'i => {lex.setTokenPosition(token); tok = T_ARRAY; fbreak;}; 'array'i => {lex.setTokenPosition(tkn); tok = token.T_ARRAY; fbreak;};
'as'i => {lex.setTokenPosition(token); tok = T_AS; fbreak;}; 'as'i => {lex.setTokenPosition(tkn); tok = token.T_AS; fbreak;};
'break'i => {lex.setTokenPosition(token); tok = T_BREAK; fbreak;}; 'break'i => {lex.setTokenPosition(tkn); tok = token.T_BREAK; fbreak;};
'callable'i => {lex.setTokenPosition(token); tok = T_CALLABLE; fbreak;}; 'callable'i => {lex.setTokenPosition(tkn); tok = token.T_CALLABLE; fbreak;};
'case'i => {lex.setTokenPosition(token); tok = T_CASE; fbreak;}; 'case'i => {lex.setTokenPosition(tkn); tok = token.T_CASE; fbreak;};
'catch'i => {lex.setTokenPosition(token); tok = T_CATCH; fbreak;}; 'catch'i => {lex.setTokenPosition(tkn); tok = token.T_CATCH; fbreak;};
'class'i => {lex.setTokenPosition(token); tok = T_CLASS; fbreak;}; 'class'i => {lex.setTokenPosition(tkn); tok = token.T_CLASS; fbreak;};
'clone'i => {lex.setTokenPosition(token); tok = T_CLONE; fbreak;}; 'clone'i => {lex.setTokenPosition(tkn); tok = token.T_CLONE; fbreak;};
'const'i => {lex.setTokenPosition(token); tok = T_CONST; fbreak;}; 'const'i => {lex.setTokenPosition(tkn); tok = token.T_CONST; fbreak;};
'continue'i => {lex.setTokenPosition(token); tok = T_CONTINUE; fbreak;}; 'continue'i => {lex.setTokenPosition(tkn); tok = token.T_CONTINUE; fbreak;};
'declare'i => {lex.setTokenPosition(token); tok = T_DECLARE; fbreak;}; 'declare'i => {lex.setTokenPosition(tkn); tok = token.T_DECLARE; fbreak;};
'default'i => {lex.setTokenPosition(token); tok = T_DEFAULT; fbreak;}; 'default'i => {lex.setTokenPosition(tkn); tok = token.T_DEFAULT; fbreak;};
'do'i => {lex.setTokenPosition(token); tok = T_DO; fbreak;}; 'do'i => {lex.setTokenPosition(tkn); tok = token.T_DO; fbreak;};
'echo'i => {lex.setTokenPosition(token); tok = T_ECHO; fbreak;}; 'echo'i => {lex.setTokenPosition(tkn); tok = token.T_ECHO; fbreak;};
'else'i => {lex.setTokenPosition(token); tok = T_ELSE; fbreak;}; 'else'i => {lex.setTokenPosition(tkn); tok = token.T_ELSE; fbreak;};
'elseif'i => {lex.setTokenPosition(token); tok = T_ELSEIF; fbreak;}; 'elseif'i => {lex.setTokenPosition(tkn); tok = token.T_ELSEIF; fbreak;};
'empty'i => {lex.setTokenPosition(token); tok = T_EMPTY; fbreak;}; 'empty'i => {lex.setTokenPosition(tkn); tok = token.T_EMPTY; fbreak;};
'enddeclare'i => {lex.setTokenPosition(token); tok = T_ENDDECLARE; fbreak;}; 'enddeclare'i => {lex.setTokenPosition(tkn); tok = token.T_ENDDECLARE; fbreak;};
'endfor'i => {lex.setTokenPosition(token); tok = T_ENDFOR; fbreak;}; 'endfor'i => {lex.setTokenPosition(tkn); tok = token.T_ENDFOR; fbreak;};
'endforeach'i => {lex.setTokenPosition(token); tok = T_ENDFOREACH; fbreak;}; 'endforeach'i => {lex.setTokenPosition(tkn); tok = token.T_ENDFOREACH; fbreak;};
'endif'i => {lex.setTokenPosition(token); tok = T_ENDIF; fbreak;}; 'endif'i => {lex.setTokenPosition(tkn); tok = token.T_ENDIF; fbreak;};
'endswitch'i => {lex.setTokenPosition(token); tok = T_ENDSWITCH; fbreak;}; 'endswitch'i => {lex.setTokenPosition(tkn); tok = token.T_ENDSWITCH; fbreak;};
'endwhile'i => {lex.setTokenPosition(token); tok = T_ENDWHILE; fbreak;}; 'endwhile'i => {lex.setTokenPosition(tkn); tok = token.T_ENDWHILE; fbreak;};
'eval'i => {lex.setTokenPosition(token); tok = T_EVAL; fbreak;}; 'eval'i => {lex.setTokenPosition(tkn); tok = token.T_EVAL; fbreak;};
'exit'i | 'die'i => {lex.setTokenPosition(token); tok = T_EXIT; fbreak;}; 'exit'i | 'die'i => {lex.setTokenPosition(tkn); tok = token.T_EXIT; fbreak;};
'extends'i => {lex.setTokenPosition(token); tok = T_EXTENDS; fbreak;}; 'extends'i => {lex.setTokenPosition(tkn); tok = token.T_EXTENDS; fbreak;};
'final'i => {lex.setTokenPosition(token); tok = T_FINAL; fbreak;}; 'final'i => {lex.setTokenPosition(tkn); tok = token.T_FINAL; fbreak;};
'finally'i => {lex.setTokenPosition(token); tok = T_FINALLY; fbreak;}; 'finally'i => {lex.setTokenPosition(tkn); tok = token.T_FINALLY; fbreak;};
'for'i => {lex.setTokenPosition(token); tok = T_FOR; fbreak;}; 'for'i => {lex.setTokenPosition(tkn); tok = token.T_FOR; fbreak;};
'foreach'i => {lex.setTokenPosition(token); tok = T_FOREACH; fbreak;}; 'foreach'i => {lex.setTokenPosition(tkn); tok = token.T_FOREACH; fbreak;};
'function'i | 'cfunction'i => {lex.setTokenPosition(token); tok = T_FUNCTION; fbreak;}; 'function'i | 'cfunction'i => {lex.setTokenPosition(tkn); tok = token.T_FUNCTION; fbreak;};
'fn'i => {lex.setTokenPosition(token); tok = T_FN; fbreak;}; 'fn'i => {lex.setTokenPosition(tkn); tok = token.T_FN; fbreak;};
'global'i => {lex.setTokenPosition(token); tok = T_GLOBAL; fbreak;}; 'global'i => {lex.setTokenPosition(tkn); tok = token.T_GLOBAL; fbreak;};
'goto'i => {lex.setTokenPosition(token); tok = T_GOTO; fbreak;}; 'goto'i => {lex.setTokenPosition(tkn); tok = token.T_GOTO; fbreak;};
'if'i => {lex.setTokenPosition(token); tok = T_IF; fbreak;}; 'if'i => {lex.setTokenPosition(tkn); tok = token.T_IF; fbreak;};
'isset'i => {lex.setTokenPosition(token); tok = T_ISSET; fbreak;}; 'isset'i => {lex.setTokenPosition(tkn); tok = token.T_ISSET; fbreak;};
'implements'i => {lex.setTokenPosition(token); tok = T_IMPLEMENTS; fbreak;}; 'implements'i => {lex.setTokenPosition(tkn); tok = token.T_IMPLEMENTS; fbreak;};
'instanceof'i => {lex.setTokenPosition(token); tok = T_INSTANCEOF; fbreak;}; 'instanceof'i => {lex.setTokenPosition(tkn); tok = token.T_INSTANCEOF; fbreak;};
'insteadof'i => {lex.setTokenPosition(token); tok = T_INSTEADOF; fbreak;}; 'insteadof'i => {lex.setTokenPosition(tkn); tok = token.T_INSTEADOF; fbreak;};
'interface'i => {lex.setTokenPosition(token); tok = T_INTERFACE; fbreak;}; 'interface'i => {lex.setTokenPosition(tkn); tok = token.T_INTERFACE; fbreak;};
'list'i => {lex.setTokenPosition(token); tok = T_LIST; fbreak;}; 'list'i => {lex.setTokenPosition(tkn); tok = token.T_LIST; fbreak;};
'namespace'i => {lex.setTokenPosition(token); tok = T_NAMESPACE; fbreak;}; 'namespace'i => {lex.setTokenPosition(tkn); tok = token.T_NAMESPACE; fbreak;};
'private'i => {lex.setTokenPosition(token); tok = T_PRIVATE; fbreak;}; 'private'i => {lex.setTokenPosition(tkn); tok = token.T_PRIVATE; fbreak;};
'public'i => {lex.setTokenPosition(token); tok = T_PUBLIC; fbreak;}; 'public'i => {lex.setTokenPosition(tkn); tok = token.T_PUBLIC; fbreak;};
'print'i => {lex.setTokenPosition(token); tok = T_PRINT; fbreak;}; 'print'i => {lex.setTokenPosition(tkn); tok = token.T_PRINT; fbreak;};
'protected'i => {lex.setTokenPosition(token); tok = T_PROTECTED; fbreak;}; 'protected'i => {lex.setTokenPosition(tkn); tok = token.T_PROTECTED; fbreak;};
'return'i => {lex.setTokenPosition(token); tok = T_RETURN; fbreak;}; 'return'i => {lex.setTokenPosition(tkn); tok = token.T_RETURN; fbreak;};
'static'i => {lex.setTokenPosition(token); tok = T_STATIC; fbreak;}; 'static'i => {lex.setTokenPosition(tkn); tok = token.T_STATIC; fbreak;};
'switch'i => {lex.setTokenPosition(token); tok = T_SWITCH; fbreak;}; 'switch'i => {lex.setTokenPosition(tkn); tok = token.T_SWITCH; fbreak;};
'throw'i => {lex.setTokenPosition(token); tok = T_THROW; fbreak;}; 'throw'i => {lex.setTokenPosition(tkn); tok = token.T_THROW; fbreak;};
'trait'i => {lex.setTokenPosition(token); tok = T_TRAIT; fbreak;}; 'trait'i => {lex.setTokenPosition(tkn); tok = token.T_TRAIT; fbreak;};
'try'i => {lex.setTokenPosition(token); tok = T_TRY; fbreak;}; 'try'i => {lex.setTokenPosition(tkn); tok = token.T_TRY; fbreak;};
'unset'i => {lex.setTokenPosition(token); tok = T_UNSET; fbreak;}; 'unset'i => {lex.setTokenPosition(tkn); tok = token.T_UNSET; fbreak;};
'use'i => {lex.setTokenPosition(token); tok = T_USE; fbreak;}; 'use'i => {lex.setTokenPosition(tkn); tok = token.T_USE; fbreak;};
'var'i => {lex.setTokenPosition(token); tok = T_VAR; fbreak;}; 'var'i => {lex.setTokenPosition(tkn); tok = token.T_VAR; fbreak;};
'while'i => {lex.setTokenPosition(token); tok = T_WHILE; fbreak;}; 'while'i => {lex.setTokenPosition(tkn); tok = token.T_WHILE; fbreak;};
'yield'i whitespace_line* 'from'i => {lex.setTokenPosition(token); tok = T_YIELD_FROM; fbreak;}; 'yield'i whitespace_line+ 'from'i => {lex.setTokenPosition(tkn); tok = token.T_YIELD_FROM; fbreak;};
'yield'i => {lex.setTokenPosition(token); tok = T_YIELD; fbreak;}; 'yield'i => {lex.setTokenPosition(tkn); tok = token.T_YIELD; fbreak;};
'include'i => {lex.setTokenPosition(token); tok = T_INCLUDE; fbreak;}; 'include'i => {lex.setTokenPosition(tkn); tok = token.T_INCLUDE; fbreak;};
'include_once'i => {lex.setTokenPosition(token); tok = T_INCLUDE_ONCE; fbreak;}; 'include_once'i => {lex.setTokenPosition(tkn); tok = token.T_INCLUDE_ONCE; fbreak;};
'require'i => {lex.setTokenPosition(token); tok = T_REQUIRE; fbreak;}; 'require'i => {lex.setTokenPosition(tkn); tok = token.T_REQUIRE; fbreak;};
'require_once'i => {lex.setTokenPosition(token); tok = T_REQUIRE_ONCE; fbreak;}; 'require_once'i => {lex.setTokenPosition(tkn); tok = token.T_REQUIRE_ONCE; fbreak;};
'__CLASS__'i => {lex.setTokenPosition(token); tok = T_CLASS_C; fbreak;}; '__CLASS__'i => {lex.setTokenPosition(tkn); tok = token.T_CLASS_C; fbreak;};
'__DIR__'i => {lex.setTokenPosition(token); tok = T_DIR; fbreak;}; '__DIR__'i => {lex.setTokenPosition(tkn); tok = token.T_DIR; fbreak;};
'__FILE__'i => {lex.setTokenPosition(token); tok = T_FILE; fbreak;}; '__FILE__'i => {lex.setTokenPosition(tkn); tok = token.T_FILE; fbreak;};
'__FUNCTION__'i => {lex.setTokenPosition(token); tok = T_FUNC_C; fbreak;}; '__FUNCTION__'i => {lex.setTokenPosition(tkn); tok = token.T_FUNC_C; fbreak;};
'__LINE__'i => {lex.setTokenPosition(token); tok = T_LINE; fbreak;}; '__LINE__'i => {lex.setTokenPosition(tkn); tok = token.T_LINE; fbreak;};
'__NAMESPACE__'i => {lex.setTokenPosition(token); tok = T_NS_C; fbreak;}; '__NAMESPACE__'i => {lex.setTokenPosition(tkn); tok = token.T_NS_C; fbreak;};
'__METHOD__'i => {lex.setTokenPosition(token); tok = T_METHOD_C; fbreak;}; '__METHOD__'i => {lex.setTokenPosition(tkn); tok = token.T_METHOD_C; fbreak;};
'__TRAIT__'i => {lex.setTokenPosition(token); tok = T_TRAIT_C; fbreak;}; '__TRAIT__'i => {lex.setTokenPosition(tkn); tok = token.T_TRAIT_C; fbreak;};
'__halt_compiler'i => {lex.setTokenPosition(token); tok = T_HALT_COMPILER; fnext halt_compiller_open_parenthesis; fbreak;}; '__halt_compiler'i => {lex.setTokenPosition(tkn); tok = token.T_HALT_COMPILER; fnext halt_compiller_open_parenthesis; fbreak;};
'new'i => {lex.setTokenPosition(token); tok = T_NEW; fbreak;}; 'new'i => {lex.setTokenPosition(tkn); tok = token.T_NEW; fbreak;};
'and'i => {lex.setTokenPosition(token); tok = T_LOGICAL_AND; fbreak;}; 'and'i => {lex.setTokenPosition(tkn); tok = token.T_LOGICAL_AND; fbreak;};
'or'i => {lex.setTokenPosition(token); tok = T_LOGICAL_OR; fbreak;}; 'or'i => {lex.setTokenPosition(tkn); tok = token.T_LOGICAL_OR; fbreak;};
'xor'i => {lex.setTokenPosition(token); tok = T_LOGICAL_XOR; fbreak;}; 'xor'i => {lex.setTokenPosition(tkn); tok = token.T_LOGICAL_XOR; fbreak;};
'\\' => {lex.setTokenPosition(token); tok = T_NS_SEPARATOR; fbreak;}; '\\' => {lex.setTokenPosition(tkn); tok = token.T_NS_SEPARATOR; fbreak;};
'...' => {lex.setTokenPosition(token); tok = T_ELLIPSIS; fbreak;}; '...' => {lex.setTokenPosition(tkn); tok = token.T_ELLIPSIS; fbreak;};
'::' => {lex.setTokenPosition(token); tok = T_PAAMAYIM_NEKUDOTAYIM; fbreak;}; '::' => {lex.setTokenPosition(tkn); tok = token.T_PAAMAYIM_NEKUDOTAYIM; fbreak;};
'&&' => {lex.setTokenPosition(token); tok = T_BOOLEAN_AND; fbreak;}; '&&' => {lex.setTokenPosition(tkn); tok = token.T_BOOLEAN_AND; fbreak;};
'||' => {lex.setTokenPosition(token); tok = T_BOOLEAN_OR; fbreak;}; '||' => {lex.setTokenPosition(tkn); tok = token.T_BOOLEAN_OR; fbreak;};
'&=' => {lex.setTokenPosition(token); tok = T_AND_EQUAL; fbreak;}; '&=' => {lex.setTokenPosition(tkn); tok = token.T_AND_EQUAL; fbreak;};
'|=' => {lex.setTokenPosition(token); tok = T_OR_EQUAL; fbreak;}; '|=' => {lex.setTokenPosition(tkn); tok = token.T_OR_EQUAL; fbreak;};
'.=' => {lex.setTokenPosition(token); tok = T_CONCAT_EQUAL; fbreak;}; '.=' => {lex.setTokenPosition(tkn); tok = token.T_CONCAT_EQUAL; fbreak;};
'*=' => {lex.setTokenPosition(token); tok = T_MUL_EQUAL; fbreak;}; '*=' => {lex.setTokenPosition(tkn); tok = token.T_MUL_EQUAL; fbreak;};
'**=' => {lex.setTokenPosition(token); tok = T_POW_EQUAL; fbreak;}; '**=' => {lex.setTokenPosition(tkn); tok = token.T_POW_EQUAL; fbreak;};
'/=' => {lex.setTokenPosition(token); tok = T_DIV_EQUAL; fbreak;}; '/=' => {lex.setTokenPosition(tkn); tok = token.T_DIV_EQUAL; fbreak;};
'+=' => {lex.setTokenPosition(token); tok = T_PLUS_EQUAL; fbreak;}; '+=' => {lex.setTokenPosition(tkn); tok = token.T_PLUS_EQUAL; fbreak;};
'-=' => {lex.setTokenPosition(token); tok = T_MINUS_EQUAL; fbreak;}; '-=' => {lex.setTokenPosition(tkn); tok = token.T_MINUS_EQUAL; fbreak;};
'^=' => {lex.setTokenPosition(token); tok = T_XOR_EQUAL; fbreak;}; '^=' => {lex.setTokenPosition(tkn); tok = token.T_XOR_EQUAL; fbreak;};
'%=' => {lex.setTokenPosition(token); tok = T_MOD_EQUAL; fbreak;}; '%=' => {lex.setTokenPosition(tkn); tok = token.T_MOD_EQUAL; fbreak;};
'--' => {lex.setTokenPosition(token); tok = T_DEC; fbreak;}; '--' => {lex.setTokenPosition(tkn); tok = token.T_DEC; fbreak;};
'++' => {lex.setTokenPosition(token); tok = T_INC; fbreak;}; '++' => {lex.setTokenPosition(tkn); tok = token.T_INC; fbreak;};
'=>' => {lex.setTokenPosition(token); tok = T_DOUBLE_ARROW; fbreak;}; '=>' => {lex.setTokenPosition(tkn); tok = token.T_DOUBLE_ARROW; fbreak;};
'<=>' => {lex.setTokenPosition(token); tok = T_SPACESHIP; fbreak;}; '<=>' => {lex.setTokenPosition(tkn); tok = token.T_SPACESHIP; fbreak;};
'!=' | '<>' => {lex.setTokenPosition(token); tok = T_IS_NOT_EQUAL; fbreak;}; '!=' | '<>' => {lex.setTokenPosition(tkn); tok = token.T_IS_NOT_EQUAL; fbreak;};
'!==' => {lex.setTokenPosition(token); tok = T_IS_NOT_IDENTICAL; fbreak;}; '!==' => {lex.setTokenPosition(tkn); tok = token.T_IS_NOT_IDENTICAL; fbreak;};
'==' => {lex.setTokenPosition(token); tok = T_IS_EQUAL; fbreak;}; '==' => {lex.setTokenPosition(tkn); tok = token.T_IS_EQUAL; fbreak;};
'===' => {lex.setTokenPosition(token); tok = T_IS_IDENTICAL; fbreak;}; '===' => {lex.setTokenPosition(tkn); tok = token.T_IS_IDENTICAL; fbreak;};
'<<=' => {lex.setTokenPosition(token); tok = T_SL_EQUAL; fbreak;}; '<<=' => {lex.setTokenPosition(tkn); tok = token.T_SL_EQUAL; fbreak;};
'>>=' => {lex.setTokenPosition(token); tok = T_SR_EQUAL; fbreak;}; '>>=' => {lex.setTokenPosition(tkn); tok = token.T_SR_EQUAL; fbreak;};
'>=' => {lex.setTokenPosition(token); tok = T_IS_GREATER_OR_EQUAL; fbreak;}; '>=' => {lex.setTokenPosition(tkn); tok = token.T_IS_GREATER_OR_EQUAL; fbreak;};
'<=' => {lex.setTokenPosition(token); tok = T_IS_SMALLER_OR_EQUAL; fbreak;}; '<=' => {lex.setTokenPosition(tkn); tok = token.T_IS_SMALLER_OR_EQUAL; fbreak;};
'**' => {lex.setTokenPosition(token); tok = T_POW; fbreak;}; '**' => {lex.setTokenPosition(tkn); tok = token.T_POW; fbreak;};
'<<' => {lex.setTokenPosition(token); tok = T_SL; fbreak;}; '<<' => {lex.setTokenPosition(tkn); tok = token.T_SL; fbreak;};
'>>' => {lex.setTokenPosition(token); tok = T_SR; fbreak;}; '>>' => {lex.setTokenPosition(tkn); tok = token.T_SR; fbreak;};
'??' => {lex.setTokenPosition(token); tok = T_COALESCE; fbreak;}; '??' => {lex.setTokenPosition(tkn); tok = token.T_COALESCE; fbreak;};
'??=' => {lex.setTokenPosition(token); tok = T_COALESCE_EQUAL; fbreak;}; '??=' => {lex.setTokenPosition(tkn); tok = token.T_COALESCE_EQUAL; fbreak;};
'(' whitespace* 'array'i whitespace* ')' => {lex.setTokenPosition(token); tok = T_ARRAY_CAST; fbreak;}; '(' whitespace* 'array'i whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_ARRAY_CAST; fbreak;};
'(' whitespace* ('bool'i|'boolean'i) whitespace* ')' => {lex.setTokenPosition(token); tok = T_BOOL_CAST; fbreak;}; '(' whitespace* ('bool'i|'boolean'i) whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_BOOL_CAST; fbreak;};
'(' whitespace* ('real'i|'double'i|'float'i) whitespace* ')' => {lex.setTokenPosition(token); tok = T_DOUBLE_CAST; fbreak;}; '(' whitespace* ('real'i|'double'i|'float'i) whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_DOUBLE_CAST; fbreak;};
'(' whitespace* ('int'i|'integer'i) whitespace* ')' => {lex.setTokenPosition(token); tok = T_INT_CAST; fbreak;}; '(' whitespace* ('int'i|'integer'i) whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_INT_CAST; fbreak;};
'(' whitespace* 'object'i whitespace* ')' => {lex.setTokenPosition(token); tok = T_OBJECT_CAST; fbreak;}; '(' whitespace* 'object'i whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_OBJECT_CAST; fbreak;};
'(' whitespace* ('string'i|'binary'i) whitespace* ')' => {lex.setTokenPosition(token); tok = T_STRING_CAST; fbreak;}; '(' whitespace* ('string'i|'binary'i) whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_STRING_CAST; fbreak;};
'(' whitespace* 'unset'i whitespace* ')' => {lex.setTokenPosition(token); tok = T_UNSET_CAST; fbreak;}; '(' whitespace* 'unset'i whitespace* ')' => {lex.setTokenPosition(tkn); tok = token.T_UNSET_CAST; fbreak;};
('#' | '//') any_line* when is_not_comment_end => { ('#' | '//') any_line* when is_not_comment_end => {
lex.ungetStr("?>") lex.ungetStr("?>")
lex.addFreeFloating(freefloating.CommentType, lex.ts, lex.te) lex.addFreeFloatingToken(tkn, token.T_COMMENT, lex.ts, lex.te)
}; };
'/*' any_line* :>> '*/' { '/*' any_line* :>> '*/' {
isDocComment := false; isDocComment := false;
if lex.te - lex.ts > 4 && string(lex.data[lex.ts:lex.ts+3]) == "/**" { if lex.te - lex.ts > 4 && string(lex.data[lex.ts:lex.ts+3]) == "/**" {
isDocComment = true; isDocComment = true;
} }
lex.addFreeFloating(freefloating.CommentType, lex.ts, lex.te)
if isDocComment { if isDocComment {
lex.PhpDocComment = string(lex.data[lex.ts:lex.te]) lex.addFreeFloatingToken(tkn, token.T_DOC_COMMENT, lex.ts, lex.te)
} else {
lex.addFreeFloatingToken(tkn, token.T_COMMENT, lex.ts, lex.te)
} }
}; };
operators => { operators => {
// rune, _ := utf8.DecodeRune(lex.data[lex.ts:lex.te]); lex.setTokenPosition(tkn);
// tok = TokenID(Rune2Class(rune)); tok = token.ID(int(lex.data[lex.ts]));
lex.setTokenPosition(token);
tok = TokenID(int(lex.data[lex.ts]));
fbreak; fbreak;
}; };
"{" => { lex.setTokenPosition(token); tok = TokenID(int('{')); lex.call(ftargs, fentry(php)); goto _out; }; "{" => { lex.setTokenPosition(tkn); tok = token.ID(int('{')); lex.call(ftargs, fentry(php)); goto _out; };
"}" => { lex.setTokenPosition(token); tok = TokenID(int('}')); lex.ret(1); lex.PhpDocComment = ""; goto _out;}; "}" => { lex.setTokenPosition(tkn); tok = token.ID(int('}')); lex.ret(1); goto _out;};
"$" varname => { lex.setTokenPosition(token); tok = T_VARIABLE; fbreak; }; "$" varname => { lex.setTokenPosition(tkn); tok = token.T_VARIABLE; fbreak; };
varname => { lex.setTokenPosition(token); tok = T_STRING; fbreak; }; varname => { lex.setTokenPosition(tkn); tok = token.T_STRING; fbreak; };
"->" => { lex.setTokenPosition(token); tok = T_OBJECT_OPERATOR; fnext property; fbreak; }; "->" => { lex.setTokenPosition(tkn); tok = token.T_OBJECT_OPERATOR; fnext property; fbreak; };
constant_string => { constant_string => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_CONSTANT_ENCAPSED_STRING; tok = token.T_CONSTANT_ENCAPSED_STRING;
fbreak; fbreak;
}; };
"b"i? "<<<" [ \t]* ( heredoc_label | ("'" heredoc_label "'") | ('"' heredoc_label '"') ) newline => { "b"i? "<<<" [ \t]* ( heredoc_label | ("'" heredoc_label "'") | ('"' heredoc_label '"') ) newline => {
lex.heredocLabel = lex.data[lblStart:lblEnd] lex.heredocLabel = lex.data[lblStart:lblEnd]
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_START_HEREDOC; tok = token.T_START_HEREDOC;
if lex.isHeredocEnd(lex.p+1) { if lex.isHeredocEnd(lex.p+1) {
fnext heredoc_end; fnext heredoc_end;
@ -378,38 +366,38 @@ func (lex *Lexer) Lex(lval Lval) int {
} }
fbreak; fbreak;
}; };
"`" => {lex.setTokenPosition(token); tok = TokenID(int('`')); fnext backqote; fbreak;}; "`" => {lex.setTokenPosition(tkn); tok = token.ID(int('`')); fnext backqote; fbreak;};
'"' => {lex.setTokenPosition(token); tok = TokenID(int('"')); fnext template_string; fbreak;}; '"' => {lex.setTokenPosition(tkn); tok = token.ID(int('"')); fnext template_string; fbreak;};
any_line => { any_line => {
c := lex.data[lex.p] c := lex.data[lex.p]
lex.Error(fmt.Sprintf("WARNING: Unexpected character in input: '%c' (ASCII=%d)", c, c)); lex.error(fmt.Sprintf("WARNING: Unexpected character in input: '%c' (ASCII=%d)", c, c));
}; };
*|; *|;
property := |* property := |*
whitespace_line* => {lex.addFreeFloating(freefloating.WhiteSpaceType, lex.ts, lex.te)}; whitespace_line* => {lex.addFreeFloatingToken(tkn, token.T_WHITESPACE, lex.ts, lex.te)};
"->" => {lex.setTokenPosition(token); tok = T_OBJECT_OPERATOR; fbreak;}; "->" => {lex.setTokenPosition(tkn); tok = token.T_OBJECT_OPERATOR; fbreak;};
varname => {lex.setTokenPosition(token); tok = T_STRING; fnext php; fbreak;}; varname => {lex.setTokenPosition(tkn); tok = token.T_STRING; fnext php; fbreak;};
any => {lex.ungetCnt(1); fgoto php;}; any => {lex.ungetCnt(1); fgoto php;};
*|; *|;
nowdoc := |* nowdoc := |*
any_line* when is_not_heredoc_end => { any_line* when is_not_heredoc_end => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_ENCAPSED_AND_WHITESPACE; tok = token.T_ENCAPSED_AND_WHITESPACE;
fnext heredoc_end; fnext heredoc_end;
fbreak; fbreak;
}; };
*|; *|;
heredoc := |* heredoc := |*
"{$" => {lex.ungetCnt(1); lex.setTokenPosition(token); tok = T_CURLY_OPEN; lex.call(ftargs, fentry(php)); goto _out;}; "{$" => {lex.ungetCnt(1); lex.setTokenPosition(tkn); tok = token.T_CURLY_OPEN; lex.call(ftargs, fentry(php)); goto _out;};
"${" => {lex.setTokenPosition(token); tok = T_DOLLAR_OPEN_CURLY_BRACES; lex.call(ftargs, fentry(string_var_name)); goto _out;}; "${" => {lex.setTokenPosition(tkn); tok = token.T_DOLLAR_OPEN_CURLY_BRACES; lex.call(ftargs, fentry(string_var_name)); goto _out;};
"$" => {lex.ungetCnt(1); fcall string_var;}; "$" => {lex.ungetCnt(1); fcall string_var;};
any_line* when is_not_heredoc_end_or_var => { any_line* when is_not_heredoc_end_or_var => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_ENCAPSED_AND_WHITESPACE; tok = token.T_ENCAPSED_AND_WHITESPACE;
if len(lex.data) > lex.p+1 && lex.data[lex.p+1] != '$' && lex.data[lex.p+1] != '{' { if len(lex.data) > lex.p+1 && lex.data[lex.p+1] != '$' && lex.data[lex.p+1] != '{' {
fnext heredoc_end; fnext heredoc_end;
@ -419,99 +407,97 @@ func (lex *Lexer) Lex(lval Lval) int {
*|; *|;
backqote := |* backqote := |*
"{$" => {lex.ungetCnt(1); lex.setTokenPosition(token); tok = T_CURLY_OPEN; lex.call(ftargs, fentry(php)); goto _out;}; "{$" => {lex.ungetCnt(1); lex.setTokenPosition(tkn); tok = token.T_CURLY_OPEN; lex.call(ftargs, fentry(php)); goto _out;};
"${" => {lex.setTokenPosition(token); tok = T_DOLLAR_OPEN_CURLY_BRACES; lex.call(ftargs, fentry(string_var_name)); goto _out;}; "${" => {lex.setTokenPosition(tkn); tok = token.T_DOLLAR_OPEN_CURLY_BRACES; lex.call(ftargs, fentry(string_var_name)); goto _out;};
"$" varname_first => {lex.ungetCnt(2); fcall string_var;}; "$" varname_first => {lex.ungetCnt(2); fcall string_var;};
'`' => {lex.setTokenPosition(token); tok = TokenID(int('`')); fnext php; fbreak;}; '`' => {lex.setTokenPosition(tkn); tok = token.ID(int('`')); fnext php; fbreak;};
any_line* when is_not_backqoute_end_or_var => { any_line* when is_not_backqoute_end_or_var => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_ENCAPSED_AND_WHITESPACE; tok = token.T_ENCAPSED_AND_WHITESPACE;
fbreak; fbreak;
}; };
*|; *|;
template_string := |* template_string := |*
"{$" => {lex.ungetCnt(1); lex.setTokenPosition(token); tok = T_CURLY_OPEN; lex.call(ftargs, fentry(php)); goto _out;}; "{$" => {lex.ungetCnt(1); lex.setTokenPosition(tkn); tok = token.T_CURLY_OPEN; lex.call(ftargs, fentry(php)); goto _out;};
"${" => {lex.setTokenPosition(token); tok = T_DOLLAR_OPEN_CURLY_BRACES; lex.call(ftargs, fentry(string_var_name)); goto _out;}; "${" => {lex.setTokenPosition(tkn); tok = token.T_DOLLAR_OPEN_CURLY_BRACES; lex.call(ftargs, fentry(string_var_name)); goto _out;};
"$" varname_first => {lex.ungetCnt(2); fcall string_var;}; "$" varname_first => {lex.ungetCnt(2); fcall string_var;};
'"' => {lex.setTokenPosition(token); tok = TokenID(int('"')); fnext php; fbreak;}; '"' => {lex.setTokenPosition(tkn); tok = token.ID(int('"')); fnext php; fbreak;};
any_line* when is_not_string_end_or_var => { any_line* when is_not_string_end_or_var => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_ENCAPSED_AND_WHITESPACE; tok = token.T_ENCAPSED_AND_WHITESPACE;
fbreak; fbreak;
}; };
*|; *|;
heredoc_end := |* heredoc_end := |*
varname -- ";" => { varname -- ";" => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_END_HEREDOC; tok = token.T_END_HEREDOC;
fnext php; fnext php;
fbreak; fbreak;
}; };
varname => { varname => {
lex.setTokenPosition(token); lex.setTokenPosition(tkn);
tok = T_END_HEREDOC; tok = token.T_END_HEREDOC;
fnext php; fnext php;
fbreak; fbreak;
}; };
*|; *|;
string_var := |* string_var := |*
'$' varname => {lex.setTokenPosition(token); tok = T_VARIABLE; fbreak;}; '$' varname => {lex.setTokenPosition(tkn); tok = token.T_VARIABLE; fbreak;};
'->' varname_first => {lex.ungetCnt(1); lex.setTokenPosition(token); tok = T_OBJECT_OPERATOR; fbreak;}; '->' varname_first => {lex.ungetCnt(1); lex.setTokenPosition(tkn); tok = token.T_OBJECT_OPERATOR; fbreak;};
varname => {lex.setTokenPosition(token); tok = T_STRING; fbreak;}; varname => {lex.setTokenPosition(tkn); tok = token.T_STRING; fbreak;};
'[' => {lex.setTokenPosition(token); tok = TokenID(int('[')); lex.call(ftargs, fentry(string_var_index)); goto _out;}; '[' => {lex.setTokenPosition(tkn); tok = token.ID(int('[')); lex.call(ftargs, fentry(string_var_index)); goto _out;};
any => {lex.ungetCnt(1); fret;}; any => {lex.ungetCnt(1); fret;};
*|; *|;
string_var_index := |* string_var_index := |*
lnum | hnum | bnum => {lex.setTokenPosition(token); tok = T_NUM_STRING; fbreak;}; lnum | hnum | bnum => {lex.setTokenPosition(tkn); tok = token.T_NUM_STRING; fbreak;};
'$' varname => {lex.setTokenPosition(token); tok = T_VARIABLE; fbreak;}; '$' varname => {lex.setTokenPosition(tkn); tok = token.T_VARIABLE; fbreak;};
varname => {lex.setTokenPosition(token); tok = T_STRING; fbreak;}; varname => {lex.setTokenPosition(tkn); tok = token.T_STRING; fbreak;};
whitespace_line | [\\'#] => {lex.setTokenPosition(token); tok = T_ENCAPSED_AND_WHITESPACE; lex.ret(2); goto _out;}; whitespace_line | [\\'#] => {lex.setTokenPosition(tkn); tok = token.T_ENCAPSED_AND_WHITESPACE; lex.ret(2); goto _out;};
operators > (svi, 1) => {lex.setTokenPosition(token); tok = TokenID(int(lex.data[lex.ts])); fbreak;}; operators > (svi, 1) => {lex.setTokenPosition(tkn); tok = token.ID(int(lex.data[lex.ts])); fbreak;};
']' > (svi, 2) => {lex.setTokenPosition(token); tok = TokenID(int(']')); lex.ret(2); goto _out;}; ']' > (svi, 2) => {lex.setTokenPosition(tkn); tok = token.ID(int(']')); lex.ret(2); goto _out;};
any_line => { any_line => {
c := lex.data[lex.p] c := lex.data[lex.p]
lex.Error(fmt.Sprintf("WARNING: Unexpected character in input: '%c' (ASCII=%d)", c, c)); lex.error(fmt.Sprintf("WARNING: Unexpected character in input: '%c' (ASCII=%d)", c, c));
}; };
*|; *|;
string_var_name := |* string_var_name := |*
varname ("[" | "}") => {lex.ungetCnt(1); lex.setTokenPosition(token); tok = T_STRING_VARNAME; fnext php; fbreak;}; varname ("[" | "}") => {lex.ungetCnt(1); lex.setTokenPosition(tkn); tok = token.T_STRING_VARNAME; fnext php; fbreak;};
any => {lex.ungetCnt(1); fnext php;}; any => {lex.ungetCnt(1); fnext php;};
*|; *|;
halt_compiller_open_parenthesis := |* halt_compiller_open_parenthesis := |*
whitespace_line* => {lex.addFreeFloating(freefloating.WhiteSpaceType, lex.ts, lex.te)}; whitespace_line* => {lex.addFreeFloatingToken(tkn, token.T_WHITESPACE, lex.ts, lex.te)};
"(" => {lex.setTokenPosition(token); tok = TokenID(int('(')); fnext halt_compiller_close_parenthesis; fbreak;}; "(" => {lex.setTokenPosition(tkn); tok = token.ID(int('(')); fnext halt_compiller_close_parenthesis; fbreak;};
any => {lex.ungetCnt(1); fnext php;}; any => {lex.ungetCnt(1); fnext php;};
*|; *|;
halt_compiller_close_parenthesis := |* halt_compiller_close_parenthesis := |*
whitespace_line* => {lex.addFreeFloating(freefloating.WhiteSpaceType, lex.ts, lex.te)}; whitespace_line* => {lex.addFreeFloatingToken(tkn, token.T_WHITESPACE, lex.ts, lex.te)};
")" => {lex.setTokenPosition(token); tok = TokenID(int(')')); fnext halt_compiller_close_semicolon; fbreak;}; ")" => {lex.setTokenPosition(tkn); tok = token.ID(int(')')); fnext halt_compiller_close_semicolon; fbreak;};
any => {lex.ungetCnt(1); fnext php;}; any => {lex.ungetCnt(1); fnext php;};
*|; *|;
halt_compiller_close_semicolon := |* halt_compiller_close_semicolon := |*
whitespace_line* => {lex.addFreeFloating(freefloating.WhiteSpaceType, lex.ts, lex.te)}; whitespace_line* => {lex.addFreeFloatingToken(tkn, token.T_WHITESPACE, lex.ts, lex.te)};
";" => {lex.setTokenPosition(token); tok = TokenID(int(';')); fnext halt_compiller_end; fbreak;}; ";" => {lex.setTokenPosition(tkn); tok = token.ID(int(';')); fnext halt_compiller_end; fbreak;};
any => {lex.ungetCnt(1); fnext php;}; any => {lex.ungetCnt(1); fnext php;};
*|; *|;
halt_compiller_end := |* halt_compiller_end := |*
any_line* => { lex.addFreeFloating(freefloating.TokenType, lex.ts, lex.te); }; any_line* => { lex.addFreeFloatingToken(tkn, token.T_HALT_COMPILER, lex.ts, lex.te); };
*|; *|;
write exec; write exec;
}%% }%%
token.FreeFloating = lex.FreeFloating tkn.Value = lex.data[lex.ts:lex.te]
token.Value = string(lex.data[lex.ts:lex.te]) tkn.ID = token.ID(tok)
lval.Token(token) return tkn
return int(tok);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Assign node
type Assign struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewAssign node constructor
func NewAssign(Variable node.Node, Expression node.Node) *Assign {
return &Assign{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Assign) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Assign) GetPosition() *position.Position {
return n.Position
}
func (n *Assign) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Assign) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Assign) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Reference node
type Reference struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewReference node constructor
func NewReference(Variable node.Node, Expression node.Node) *Reference {
return &Reference{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Reference) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Reference) GetPosition() *position.Position {
return n.Position
}
func (n *Reference) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Reference) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Reference) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseAnd node
type BitwiseAnd struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewBitwiseAnd node constructor
func NewBitwiseAnd(Variable node.Node, Expression node.Node) *BitwiseAnd {
return &BitwiseAnd{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseAnd) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseAnd) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseAnd) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseAnd) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseAnd) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseOr node
type BitwiseOr struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewBitwiseOr node constructor
func NewBitwiseOr(Variable node.Node, Expression node.Node) *BitwiseOr {
return &BitwiseOr{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseOr) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseOr) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseOr) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseOr) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseOr) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseXor node
type BitwiseXor struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewBitwiseXor node constructor
func NewBitwiseXor(Variable node.Node, Expression node.Node) *BitwiseXor {
return &BitwiseXor{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseXor) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseXor) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseXor) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseXor) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseXor) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Coalesce node
type Coalesce struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewCoalesce node constructor
func NewCoalesce(Variable node.Node, Expression node.Node) *Coalesce {
return &Coalesce{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Coalesce) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Coalesce) GetPosition() *position.Position {
return n.Position
}
func (n *Coalesce) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Coalesce) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Coalesce) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Concat node
type Concat struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewConcat node constructor
func NewConcat(Variable node.Node, Expression node.Node) *Concat {
return &Concat{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Concat) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Concat) GetPosition() *position.Position {
return n.Position
}
func (n *Concat) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Concat) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Concat) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Div node
type Div struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewDiv node constructor
func NewDiv(Variable node.Node, Expression node.Node) *Div {
return &Div{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Div) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Div) GetPosition() *position.Position {
return n.Position
}
func (n *Div) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Div) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Div) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Minus node
type Minus struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewMinus node constructor
func NewMinus(Variable node.Node, Expression node.Node) *Minus {
return &Minus{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Minus) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Minus) GetPosition() *position.Position {
return n.Position
}
func (n *Minus) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Minus) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Minus) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Mod node
type Mod struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewMod node constructor
func NewMod(Variable node.Node, Expression node.Node) *Mod {
return &Mod{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Mod) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Mod) GetPosition() *position.Position {
return n.Position
}
func (n *Mod) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Mod) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Mod) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Mul node
type Mul struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewMul node constructor
func NewMul(Variable node.Node, Expression node.Node) *Mul {
return &Mul{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Mul) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Mul) GetPosition() *position.Position {
return n.Position
}
func (n *Mul) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Mul) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Mul) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Plus node
type Plus struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewPlus node constructor
func NewPlus(Variable node.Node, Expression node.Node) *Plus {
return &Plus{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Plus) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Plus) GetPosition() *position.Position {
return n.Position
}
func (n *Plus) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Plus) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Plus) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Pow node
type Pow struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewPow node constructor
func NewPow(Variable node.Node, Expression node.Node) *Pow {
return &Pow{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *Pow) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Pow) GetPosition() *position.Position {
return n.Position
}
func (n *Pow) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Pow) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Pow) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ShiftLeft node
type ShiftLeft struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewShiftLeft node constructor
func NewShiftLeft(Variable node.Node, Expression node.Node) *ShiftLeft {
return &ShiftLeft{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *ShiftLeft) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ShiftLeft) GetPosition() *position.Position {
return n.Position
}
func (n *ShiftLeft) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ShiftLeft) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ShiftLeft) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package assign
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ShiftRight node
type ShiftRight struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Expression node.Node
}
// NewShiftRight node constructor
func NewShiftRight(Variable node.Node, Expression node.Node) *ShiftRight {
return &ShiftRight{
FreeFloating: nil,
Variable: Variable,
Expression: Expression,
}
}
// SetPosition sets node position
func (n *ShiftRight) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ShiftRight) GetPosition() *position.Position {
return n.Position
}
func (n *ShiftRight) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ShiftRight) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ShiftRight) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Expression != nil {
v.EnterChildNode("Expression", n)
n.Expression.Walk(v)
v.LeaveChildNode("Expression", n)
}
v.LeaveNode(n)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +0,0 @@
package assign_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr/assign"
)
var expected freefloating.Collection = freefloating.Collection{
freefloating.Start: []freefloating.String{
{
StringType: freefloating.WhiteSpaceType,
Value: " ",
Position: nil,
},
{
StringType: freefloating.CommentType,
Value: "//comment\n",
Position: nil,
},
},
}
var nodes = []node.Node{
&assign.Reference{
FreeFloating: expected,
},
&assign.Assign{
FreeFloating: expected,
},
&assign.BitwiseAnd{
FreeFloating: expected,
},
&assign.BitwiseOr{
FreeFloating: expected,
},
&assign.BitwiseXor{
FreeFloating: expected,
},
&assign.Coalesce{
FreeFloating: expected,
},
&assign.Concat{
FreeFloating: expected,
},
&assign.Div{
FreeFloating: expected,
},
&assign.Minus{
FreeFloating: expected,
},
&assign.Mod{
FreeFloating: expected,
},
&assign.Mul{
FreeFloating: expected,
},
&assign.Plus{
FreeFloating: expected,
},
&assign.Pow{
FreeFloating: expected,
},
&assign.ShiftLeft{
FreeFloating: expected,
},
&assign.ShiftRight{
FreeFloating: expected,
},
&assign.ShiftRight{
FreeFloating: expected,
},
}
func TestMeta(t *testing.T) {
for _, n := range nodes {
actual := *n.GetFreeFloating()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,18 +0,0 @@
package assign_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/position"
)
func TestPosition(t *testing.T) {
expected := position.NewPosition(1, 1, 1, 1)
for _, n := range nodes {
n.SetPosition(expected)
actual := n.GetPosition()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,190 +0,0 @@
package assign_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node/expr/assign"
"github.com/z7zmey/php-parser/walker"
)
var nodesToTest = []struct {
node node.Node // node
expectedVisitedKeys []string // visited keys
expectedAttributes map[string]interface{}
}{
{
&assign.Reference{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Assign{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.BitwiseAnd{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.BitwiseOr{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.BitwiseXor{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Coalesce{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Concat{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Div{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Minus{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Mod{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Mul{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Plus{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.Pow{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.ShiftLeft{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
{
&assign.ShiftRight{
Variable: &expr.Variable{},
Expression: &expr.Variable{},
},
[]string{"Variable", "Expression"},
nil,
},
}
type visitorMock struct {
visitChildren bool
visitedKeys []string
}
func (v *visitorMock) EnterNode(n walker.Walkable) bool { return v.visitChildren }
func (v *visitorMock) LeaveNode(n walker.Walkable) {}
func (v *visitorMock) EnterChildNode(key string, w walker.Walkable) {
v.visitedKeys = append(v.visitedKeys, key)
}
func (v *visitorMock) LeaveChildNode(key string, w walker.Walkable) {}
func (v *visitorMock) EnterChildList(key string, w walker.Walkable) {
v.visitedKeys = append(v.visitedKeys, key)
}
func (v *visitorMock) LeaveChildList(key string, w walker.Walkable) {}
func TestVisitorDisableChildren(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{false, []string{}}
tt.node.Walk(v)
expected := []string{}
actual := v.visitedKeys
assert.DeepEqual(t, expected, actual)
}
}
func TestVisitor(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{true, []string{}}
tt.node.Walk(v)
expected := tt.expectedVisitedKeys
actual := v.visitedKeys
assert.DeepEqual(t, expected, actual)
}
}
// test Attributes()
func TestNameAttributes(t *testing.T) {
for _, tt := range nodesToTest {
expected := tt.expectedAttributes
actual := tt.node.Attributes()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseAnd node
type BitwiseAnd struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewBitwiseAnd node constructor
func NewBitwiseAnd(Variable node.Node, Expression node.Node) *BitwiseAnd {
return &BitwiseAnd{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseAnd) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseAnd) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseAnd) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseAnd) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseAnd) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseOr node
type BitwiseOr struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewBitwiseOr node constructor
func NewBitwiseOr(Variable node.Node, Expression node.Node) *BitwiseOr {
return &BitwiseOr{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseOr) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseOr) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseOr) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseOr) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseOr) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseXor node
type BitwiseXor struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewBitwiseXor node constructor
func NewBitwiseXor(Variable node.Node, Expression node.Node) *BitwiseXor {
return &BitwiseXor{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseXor) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseXor) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseXor) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseXor) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseXor) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BooleanAnd node
type BooleanAnd struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewBooleanAnd node constructor
func NewBooleanAnd(Variable node.Node, Expression node.Node) *BooleanAnd {
return &BooleanAnd{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *BooleanAnd) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BooleanAnd) GetPosition() *position.Position {
return n.Position
}
func (n *BooleanAnd) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BooleanAnd) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BooleanAnd) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BooleanOr node
type BooleanOr struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewBooleanOr node constructor
func NewBooleanOr(Variable node.Node, Expression node.Node) *BooleanOr {
return &BooleanOr{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *BooleanOr) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BooleanOr) GetPosition() *position.Position {
return n.Position
}
func (n *BooleanOr) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BooleanOr) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BooleanOr) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Coalesce node
type Coalesce struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewCoalesce node constructor
func NewCoalesce(Variable node.Node, Expression node.Node) *Coalesce {
return &Coalesce{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Coalesce) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Coalesce) GetPosition() *position.Position {
return n.Position
}
func (n *Coalesce) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Coalesce) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Coalesce) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Concat node
type Concat struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewConcat node constructor
func NewConcat(Variable node.Node, Expression node.Node) *Concat {
return &Concat{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Concat) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Concat) GetPosition() *position.Position {
return n.Position
}
func (n *Concat) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Concat) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Concat) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Div node
type Div struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewDiv node constructor
func NewDiv(Variable node.Node, Expression node.Node) *Div {
return &Div{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Div) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Div) GetPosition() *position.Position {
return n.Position
}
func (n *Div) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Div) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Div) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Equal node
type Equal struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewEqual node constructor
func NewEqual(Variable node.Node, Expression node.Node) *Equal {
return &Equal{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Equal) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Equal) GetPosition() *position.Position {
return n.Position
}
func (n *Equal) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Equal) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Equal) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Greater node
type Greater struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewGreater node constructor
func NewGreater(Variable node.Node, Expression node.Node) *Greater {
return &Greater{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Greater) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Greater) GetPosition() *position.Position {
return n.Position
}
func (n *Greater) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Greater) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Greater) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// GreaterOrEqual node
type GreaterOrEqual struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewGreaterOrEqual node constructor
func NewGreaterOrEqual(Variable node.Node, Expression node.Node) *GreaterOrEqual {
return &GreaterOrEqual{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *GreaterOrEqual) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *GreaterOrEqual) GetPosition() *position.Position {
return n.Position
}
func (n *GreaterOrEqual) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *GreaterOrEqual) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *GreaterOrEqual) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Identical node
type Identical struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewIdentical node constructor
func NewIdentical(Variable node.Node, Expression node.Node) *Identical {
return &Identical{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Identical) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Identical) GetPosition() *position.Position {
return n.Position
}
func (n *Identical) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Identical) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Identical) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// LogicalAnd node
type LogicalAnd struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewLogicalAnd node constructor
func NewLogicalAnd(Variable node.Node, Expression node.Node) *LogicalAnd {
return &LogicalAnd{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *LogicalAnd) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *LogicalAnd) GetPosition() *position.Position {
return n.Position
}
func (n *LogicalAnd) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *LogicalAnd) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *LogicalAnd) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// LogicalOr node
type LogicalOr struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewLogicalOr node constructor
func NewLogicalOr(Variable node.Node, Expression node.Node) *LogicalOr {
return &LogicalOr{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *LogicalOr) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *LogicalOr) GetPosition() *position.Position {
return n.Position
}
func (n *LogicalOr) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *LogicalOr) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *LogicalOr) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// LogicalXor node
type LogicalXor struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewLogicalXor node constructor
func NewLogicalXor(Variable node.Node, Expression node.Node) *LogicalXor {
return &LogicalXor{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *LogicalXor) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *LogicalXor) GetPosition() *position.Position {
return n.Position
}
func (n *LogicalXor) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *LogicalXor) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *LogicalXor) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Minus node
type Minus struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewMinus node constructor
func NewMinus(Variable node.Node, Expression node.Node) *Minus {
return &Minus{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Minus) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Minus) GetPosition() *position.Position {
return n.Position
}
func (n *Minus) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Minus) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Minus) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Mod node
type Mod struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewMod node constructor
func NewMod(Variable node.Node, Expression node.Node) *Mod {
return &Mod{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Mod) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Mod) GetPosition() *position.Position {
return n.Position
}
func (n *Mod) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Mod) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Mod) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Mul node
type Mul struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewMul node constructor
func NewMul(Variable node.Node, Expression node.Node) *Mul {
return &Mul{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Mul) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Mul) GetPosition() *position.Position {
return n.Position
}
func (n *Mul) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Mul) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Mul) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// NotEqual node
type NotEqual struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewNotEqual node constructor
func NewNotEqual(Variable node.Node, Expression node.Node) *NotEqual {
return &NotEqual{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *NotEqual) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *NotEqual) GetPosition() *position.Position {
return n.Position
}
func (n *NotEqual) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *NotEqual) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *NotEqual) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// NotIdentical node
type NotIdentical struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewNotIdentical node constructor
func NewNotIdentical(Variable node.Node, Expression node.Node) *NotIdentical {
return &NotIdentical{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *NotIdentical) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *NotIdentical) GetPosition() *position.Position {
return n.Position
}
func (n *NotIdentical) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *NotIdentical) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *NotIdentical) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Plus node
type Plus struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewPlus node constructor
func NewPlus(Variable node.Node, Expression node.Node) *Plus {
return &Plus{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Plus) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Plus) GetPosition() *position.Position {
return n.Position
}
func (n *Plus) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Plus) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Plus) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Pow node
type Pow struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewPow node constructor
func NewPow(Variable node.Node, Expression node.Node) *Pow {
return &Pow{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Pow) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Pow) GetPosition() *position.Position {
return n.Position
}
func (n *Pow) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Pow) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Pow) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ShiftLeft node
type ShiftLeft struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewShiftLeft node constructor
func NewShiftLeft(Variable node.Node, Expression node.Node) *ShiftLeft {
return &ShiftLeft{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *ShiftLeft) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ShiftLeft) GetPosition() *position.Position {
return n.Position
}
func (n *ShiftLeft) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ShiftLeft) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ShiftLeft) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ShiftRight node
type ShiftRight struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewShiftRight node constructor
func NewShiftRight(Variable node.Node, Expression node.Node) *ShiftRight {
return &ShiftRight{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *ShiftRight) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ShiftRight) GetPosition() *position.Position {
return n.Position
}
func (n *ShiftRight) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ShiftRight) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ShiftRight) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Smaller node
type Smaller struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewSmaller node constructor
func NewSmaller(Variable node.Node, Expression node.Node) *Smaller {
return &Smaller{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Smaller) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Smaller) GetPosition() *position.Position {
return n.Position
}
func (n *Smaller) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Smaller) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Smaller) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// SmallerOrEqual node
type SmallerOrEqual struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewSmallerOrEqual node constructor
func NewSmallerOrEqual(Variable node.Node, Expression node.Node) *SmallerOrEqual {
return &SmallerOrEqual{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *SmallerOrEqual) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *SmallerOrEqual) GetPosition() *position.Position {
return n.Position
}
func (n *SmallerOrEqual) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *SmallerOrEqual) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *SmallerOrEqual) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package binary
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Spaceship node
type Spaceship struct {
FreeFloating freefloating.Collection
Position *position.Position
Left node.Node
Right node.Node
}
// NewSpaceship node constructor
func NewSpaceship(Variable node.Node, Expression node.Node) *Spaceship {
return &Spaceship{
FreeFloating: nil,
Left: Variable,
Right: Expression,
}
}
// SetPosition sets node position
func (n *Spaceship) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Spaceship) GetPosition() *position.Position {
return n.Position
}
func (n *Spaceship) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Spaceship) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Spaceship) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Left != nil {
v.EnterChildNode("Left", n)
n.Left.Walk(v)
v.LeaveChildNode("Left", n)
}
if n.Right != nil {
v.EnterChildNode("Right", n)
n.Right.Walk(v)
v.LeaveChildNode("Right", n)
}
v.LeaveNode(n)
}

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +0,0 @@
package binary_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr/binary"
)
var expected freefloating.Collection = freefloating.Collection{
freefloating.Start: []freefloating.String{
{
StringType: freefloating.WhiteSpaceType,
Value: " ",
Position: nil,
},
{
StringType: freefloating.CommentType,
Value: "//comment\n",
Position: nil,
},
},
}
var nodes = []node.Node{
&binary.BitwiseAnd{
FreeFloating: expected,
},
&binary.BitwiseOr{
FreeFloating: expected,
},
&binary.BitwiseXor{
FreeFloating: expected,
},
&binary.BooleanAnd{
FreeFloating: expected,
},
&binary.BooleanOr{
FreeFloating: expected,
},
&binary.Coalesce{
FreeFloating: expected,
},
&binary.Concat{
FreeFloating: expected,
},
&binary.Div{
FreeFloating: expected,
},
&binary.Equal{
FreeFloating: expected,
},
&binary.GreaterOrEqual{
FreeFloating: expected,
},
&binary.Greater{
FreeFloating: expected,
},
&binary.Identical{
FreeFloating: expected,
},
&binary.LogicalAnd{
FreeFloating: expected,
},
&binary.LogicalOr{
FreeFloating: expected,
},
&binary.LogicalXor{
FreeFloating: expected,
},
&binary.Minus{
FreeFloating: expected,
},
&binary.Mod{
FreeFloating: expected,
},
&binary.Mul{
FreeFloating: expected,
},
&binary.NotEqual{
FreeFloating: expected,
},
&binary.NotIdentical{
FreeFloating: expected,
},
&binary.Plus{
FreeFloating: expected,
},
&binary.Pow{
FreeFloating: expected,
},
&binary.ShiftLeft{
FreeFloating: expected,
},
&binary.ShiftRight{
FreeFloating: expected,
},
&binary.SmallerOrEqual{
FreeFloating: expected,
},
&binary.Smaller{
FreeFloating: expected,
},
&binary.Spaceship{
FreeFloating: expected,
},
}
func TestMeta(t *testing.T) {
for _, n := range nodes {
actual := *n.GetFreeFloating()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,18 +0,0 @@
package binary_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/position"
)
func TestPosition(t *testing.T) {
expected := position.NewPosition(1, 1, 1, 1)
for _, n := range nodes {
n.SetPosition(expected)
actual := n.GetPosition()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,285 +0,0 @@
package binary_test
import (
"testing"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node/expr/binary"
"github.com/z7zmey/php-parser/walker"
"gotest.tools/assert"
)
var nodesToTest = []struct {
node node.Node // node
expectedVisitedKeys []string // visited keys
expectedAttributes map[string]interface{}
}{
{
&binary.BitwiseAnd{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.BitwiseOr{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.BitwiseXor{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.BooleanAnd{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.BooleanOr{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Coalesce{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Concat{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Div{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Equal{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.GreaterOrEqual{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Greater{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Identical{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.LogicalAnd{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.LogicalOr{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.LogicalXor{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Minus{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Mod{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Mul{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.NotEqual{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.NotIdentical{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Plus{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Pow{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.ShiftLeft{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.ShiftRight{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.SmallerOrEqual{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Smaller{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
{
&binary.Spaceship{
Left: &expr.Variable{},
Right: &expr.Variable{},
},
[]string{"Left", "Right"},
nil,
},
}
type visitorMock struct {
visitChildren bool
visitedKeys []string
}
func (v *visitorMock) EnterNode(n walker.Walkable) bool { return v.visitChildren }
func (v *visitorMock) LeaveNode(n walker.Walkable) {}
func (v *visitorMock) EnterChildNode(key string, w walker.Walkable) {
v.visitedKeys = append(v.visitedKeys, key)
}
func (v *visitorMock) LeaveChildNode(key string, w walker.Walkable) {}
func (v *visitorMock) EnterChildList(key string, w walker.Walkable) {
v.visitedKeys = append(v.visitedKeys, key)
}
func (v *visitorMock) LeaveChildList(key string, w walker.Walkable) {}
func TestVisitorDisableChildren(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{false, []string{}}
tt.node.Walk(v)
expected := []string{}
actual := v.visitedKeys
assert.DeepEqual(t, expected, actual)
}
}
func TestVisitor(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{true, []string{}}
tt.node.Walk(v)
expected := tt.expectedVisitedKeys
actual := v.visitedKeys
assert.DeepEqual(t, expected, actual)
}
}
// test Attributes()
func TestNameAttributes(t *testing.T) {
for _, tt := range nodesToTest {
expected := tt.expectedAttributes
actual := tt.node.Attributes()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Array node
type Array struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewArray node constructor
func NewArray(Expr node.Node) *Array {
return &Array{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Array) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Array) GetPosition() *position.Position {
return n.Position
}
func (n *Array) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Array) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Array) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Bool node
type Bool struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewBool node constructor
func NewBool(Expr node.Node) *Bool {
return &Bool{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Bool) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Bool) GetPosition() *position.Position {
return n.Position
}
func (n *Bool) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Bool) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Bool) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Double node
type Double struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewDouble node constructor
func NewDouble(Expr node.Node) *Double {
return &Double{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Double) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Double) GetPosition() *position.Position {
return n.Position
}
func (n *Double) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Double) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Double) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Int node
type Int struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewInt node constructor
func NewInt(Expr node.Node) *Int {
return &Int{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Int) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Int) GetPosition() *position.Position {
return n.Position
}
func (n *Int) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Int) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Int) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Object node
type Object struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewObject node constructor
func NewObject(Expr node.Node) *Object {
return &Object{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Object) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Object) GetPosition() *position.Position {
return n.Position
}
func (n *Object) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Object) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Object) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// String node
type String struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewString node constructor
func NewString(Expr node.Node) *String {
return &String{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *String) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *String) GetPosition() *position.Position {
return n.Position
}
func (n *String) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *String) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *String) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package cast
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Unset node
type Unset struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewUnset node constructor
func NewUnset(Expr node.Node) *Unset {
return &Unset{
FreeFloating: nil,
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Unset) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Unset) GetPosition() *position.Position {
return n.Position
}
func (n *Unset) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Unset) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Unset) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,653 +0,0 @@
package cast_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node/expr/cast"
"github.com/z7zmey/php-parser/node/stmt"
"github.com/z7zmey/php-parser/php5"
"github.com/z7zmey/php-parser/php7"
"github.com/z7zmey/php-parser/position"
)
func TestArray(t *testing.T) {
src := `<? (array)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &cast.Array{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 12,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 10,
EndPos: 12,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 10,
EndPos: 12,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestBool(t *testing.T) {
src := `<? (boolean)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 15,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 15,
},
Expr: &cast.Bool{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 12,
EndPos: 14,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 12,
EndPos: 14,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestBoolShort(t *testing.T) {
src := `<? (bool)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 12,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 12,
},
Expr: &cast.Bool{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 11,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 9,
EndPos: 11,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 9,
EndPos: 11,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestDouble(t *testing.T) {
src := `<? (double)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Expr: &cast.Double{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestCastFloat(t *testing.T) {
src := `<? (float)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &cast.Double{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 12,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 10,
EndPos: 12,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 10,
EndPos: 12,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestInt(t *testing.T) {
src := `<? (integer)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 15,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 15,
},
Expr: &cast.Int{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 12,
EndPos: 14,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 12,
EndPos: 14,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestIntShort(t *testing.T) {
src := `<? (int)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 11,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 11,
},
Expr: &cast.Int{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 10,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 8,
EndPos: 10,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 8,
EndPos: 10,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestObject(t *testing.T) {
src := `<? (object)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Expr: &cast.Object{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestString(t *testing.T) {
src := `<? (string)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Expr: &cast.String{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestBinaryString(t *testing.T) {
src := `<? (binary)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 14,
},
Expr: &cast.String{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 11,
EndPos: 13,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}
func TestUnset(t *testing.T) {
src := `<? (unset)$a;`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 13,
},
Expr: &cast.Unset{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 3,
EndPos: 12,
},
Expr: &expr.Variable{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 10,
EndPos: 12,
},
VarName: &node.Identifier{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 10,
EndPos: 12,
},
Value: "a",
},
},
},
},
},
}
php7parser := php7.NewParser([]byte(src), "7.4")
php7parser.Parse()
actual := php7parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
php5parser := php5.NewParser([]byte(src), "5.6")
php5parser.Parse()
actual = php5parser.GetRootNode()
assert.DeepEqual(t, expected, actual)
}

View File

@ -1,57 +0,0 @@
package cast_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr/cast"
)
var expected freefloating.Collection = freefloating.Collection{
freefloating.Start: []freefloating.String{
{
StringType: freefloating.WhiteSpaceType,
Value: " ",
Position: nil,
},
{
StringType: freefloating.CommentType,
Value: "//comment\n",
Position: nil,
},
},
}
var nodes = []node.Node{
&cast.Array{
FreeFloating: expected,
},
&cast.Bool{
FreeFloating: expected,
},
&cast.Double{
FreeFloating: expected,
},
&cast.Int{
FreeFloating: expected,
},
&cast.Object{
FreeFloating: expected,
},
&cast.String{
FreeFloating: expected,
},
&cast.Unset{
FreeFloating: expected,
},
}
func TestMeta(t *testing.T) {
for _, n := range nodes {
actual := *n.GetFreeFloating()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,18 +0,0 @@
package cast_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/position"
)
func TestPosition(t *testing.T) {
expected := position.NewPosition(1, 1, 1, 1)
for _, n := range nodes {
n.SetPosition(expected)
actual := n.GetPosition()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,119 +0,0 @@
package cast_test
import (
"testing"
"gotest.tools/assert"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node/expr/cast"
"github.com/z7zmey/php-parser/walker"
)
var nodesToTest = []struct {
node node.Node // node
expectedVisitedKeys []string // visited keys
expectedAttributes map[string]interface{}
}{
{
&cast.Array{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
{
&cast.Bool{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
{
&cast.Double{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
{
&cast.Int{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
{
&cast.Object{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
{
&cast.String{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
{
&cast.Unset{
Expr: &expr.Variable{},
},
[]string{"Expr"},
nil,
},
}
type visitorMock struct {
visitChildren bool
visitedKeys []string
}
func (v *visitorMock) EnterNode(n walker.Walkable) bool { return v.visitChildren }
func (v *visitorMock) LeaveNode(n walker.Walkable) {}
func (v *visitorMock) EnterChildNode(key string, w walker.Walkable) {
v.visitedKeys = append(v.visitedKeys, key)
}
func (v *visitorMock) LeaveChildNode(key string, w walker.Walkable) {}
func (v *visitorMock) EnterChildList(key string, w walker.Walkable) {
v.visitedKeys = append(v.visitedKeys, key)
}
func (v *visitorMock) LeaveChildList(key string, w walker.Walkable) {}
func TestVisitorDisableChildren(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{false, []string{}}
tt.node.Walk(v)
expected := []string{}
actual := v.visitedKeys
assert.DeepEqual(t, expected, actual)
}
}
func TestVisitor(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{true, []string{}}
tt.node.Walk(v)
expected := tt.expectedVisitedKeys
actual := v.visitedKeys
assert.DeepEqual(t, expected, actual)
}
}
// test Attributes()
func TestNameAttributes(t *testing.T) {
for _, tt := range nodesToTest {
expected := tt.expectedAttributes
actual := tt.node.Attributes()
assert.DeepEqual(t, expected, actual)
}
}

View File

@ -1,62 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Array node
type Array struct {
FreeFloating freefloating.Collection
Position *position.Position
Items []node.Node
}
// NewArray node constructor
func NewArray(Items []node.Node) *Array {
return &Array{
FreeFloating: nil,
Items: Items,
}
}
// SetPosition sets node position
func (n *Array) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Array) GetPosition() *position.Position {
return n.Position
}
func (n *Array) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Array) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Array) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Items != nil {
v.EnterChildList("Items", n)
for _, nn := range n.Items {
if nn != nil {
nn.Walk(v)
}
}
v.LeaveChildList("Items", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ArrayDimFetch node
type ArrayDimFetch struct {
FreeFloating freefloating.Collection
Position *position.Position
Variable node.Node
Dim node.Node
}
// NewArrayDimFetch node constructor
func NewArrayDimFetch(Variable node.Node, Dim node.Node) *ArrayDimFetch {
return &ArrayDimFetch{
FreeFloating: nil,
Variable: Variable,
Dim: Dim,
}
}
// SetPosition sets node position
func (n *ArrayDimFetch) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ArrayDimFetch) GetPosition() *position.Position {
return n.Position
}
func (n *ArrayDimFetch) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ArrayDimFetch) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ArrayDimFetch) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
v.EnterChildNode("Variable", n)
n.Variable.Walk(v)
v.LeaveChildNode("Variable", n)
}
if n.Dim != nil {
v.EnterChildNode("Dim", n)
n.Dim.Walk(v)
v.LeaveChildNode("Dim", n)
}
v.LeaveNode(n)
}

View File

@ -1,70 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ArrayItem node
type ArrayItem struct {
FreeFloating freefloating.Collection
Position *position.Position
Key node.Node
Val node.Node
Unpack bool
}
// NewArrayItem node constructor
func NewArrayItem(Key node.Node, Val node.Node, Unpack bool) *ArrayItem {
return &ArrayItem{
FreeFloating: nil,
Key: Key,
Val: Val,
Unpack: Unpack,
}
}
// SetPosition sets node position
func (n *ArrayItem) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ArrayItem) GetPosition() *position.Position {
return n.Position
}
func (n *ArrayItem) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ArrayItem) Attributes() map[string]interface{} {
return map[string]interface{}{
"Unpack": n.Unpack,
}
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ArrayItem) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Key != nil {
v.EnterChildNode("Key", n)
n.Key.Walk(v)
v.LeaveChildNode("Key", n)
}
if n.Val != nil {
v.EnterChildNode("Val", n)
n.Val.Walk(v)
v.LeaveChildNode("Val", n)
}
v.LeaveNode(n)
}

View File

@ -1,88 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ArrowFunction node
type ArrowFunction struct {
FreeFloating freefloating.Collection
Position *position.Position
ReturnsRef bool
Static bool
PhpDocComment string
Params []node.Node
ReturnType node.Node
Expr node.Node
}
// NewArrowFunction node constructor
func NewArrowFunction(Params []node.Node, ReturnType node.Node, Stmt node.Node, Static bool, ReturnsRef bool, PhpDocComment string) *ArrowFunction {
return &ArrowFunction{
FreeFloating: nil,
ReturnsRef: ReturnsRef,
Static: Static,
PhpDocComment: PhpDocComment,
Params: Params,
ReturnType: ReturnType,
Expr: Stmt,
}
}
// SetPosition sets node position
func (n *ArrowFunction) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ArrowFunction) GetPosition() *position.Position {
return n.Position
}
func (n *ArrowFunction) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ArrowFunction) Attributes() map[string]interface{} {
return map[string]interface{}{
"ReturnsRef": n.ReturnsRef,
"Static": n.Static,
"PhpDocComment": n.PhpDocComment,
}
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ArrowFunction) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Params != nil {
v.EnterChildList("Params", n)
for _, nn := range n.Params {
if nn != nil {
nn.Walk(v)
}
}
v.LeaveChildList("Params", n)
}
if n.ReturnType != nil {
v.EnterChildNode("ReturnType", n)
n.ReturnType.Walk(v)
v.LeaveChildNode("ReturnType", n)
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BitwiseNot node
type BitwiseNot struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewBitwiseNot node constructor
func NewBitwiseNot(Expression node.Node) *BitwiseNot {
return &BitwiseNot{
FreeFloating: nil,
Expr: Expression,
}
}
// SetPosition sets node position
func (n *BitwiseNot) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BitwiseNot) GetPosition() *position.Position {
return n.Position
}
func (n *BitwiseNot) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BitwiseNot) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BitwiseNot) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// BooleanNot node
type BooleanNot struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewBooleanNot node constructor
func NewBooleanNot(Expression node.Node) *BooleanNot {
return &BooleanNot{
FreeFloating: nil,
Expr: Expression,
}
}
// SetPosition sets node position
func (n *BooleanNot) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *BooleanNot) GetPosition() *position.Position {
return n.Position
}
func (n *BooleanNot) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *BooleanNot) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *BooleanNot) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,66 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ClassConstFetch node
type ClassConstFetch struct {
FreeFloating freefloating.Collection
Position *position.Position
Class node.Node
ConstantName node.Node
}
// NewClassConstFetch node constructor
func NewClassConstFetch(Class node.Node, ConstantName node.Node) *ClassConstFetch {
return &ClassConstFetch{
FreeFloating: nil,
Class: Class,
ConstantName: ConstantName,
}
}
// SetPosition sets node position
func (n *ClassConstFetch) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ClassConstFetch) GetPosition() *position.Position {
return n.Position
}
func (n *ClassConstFetch) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ClassConstFetch) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ClassConstFetch) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Class != nil {
v.EnterChildNode("Class", n)
n.Class.Walk(v)
v.LeaveChildNode("Class", n)
}
if n.ConstantName != nil {
v.EnterChildNode("ConstantName", n)
n.ConstantName.Walk(v)
v.LeaveChildNode("ConstantName", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Clone node
type Clone struct {
FreeFloating freefloating.Collection
Position *position.Position
Expr node.Node
}
// NewClone node constructor
func NewClone(Expression node.Node) *Clone {
return &Clone{
FreeFloating: nil,
Expr: Expression,
}
}
// SetPosition sets node position
func (n *Clone) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Clone) GetPosition() *position.Position {
return n.Position
}
func (n *Clone) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Clone) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Clone) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -1,100 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Closure node
type Closure struct {
FreeFloating freefloating.Collection
Position *position.Position
ReturnsRef bool
Static bool
PhpDocComment string
Params []node.Node
ClosureUse *ClosureUse
ReturnType node.Node
Stmts []node.Node
}
// NewClosure node constructor
func NewClosure(Params []node.Node, ClosureUse *ClosureUse, ReturnType node.Node, Stmts []node.Node, Static bool, ReturnsRef bool, PhpDocComment string) *Closure {
return &Closure{
FreeFloating: nil,
ReturnsRef: ReturnsRef,
Static: Static,
PhpDocComment: PhpDocComment,
Params: Params,
ClosureUse: ClosureUse,
ReturnType: ReturnType,
Stmts: Stmts,
}
}
// SetPosition sets node position
func (n *Closure) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Closure) GetPosition() *position.Position {
return n.Position
}
func (n *Closure) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *Closure) Attributes() map[string]interface{} {
return map[string]interface{}{
"ReturnsRef": n.ReturnsRef,
"Static": n.Static,
"PhpDocComment": n.PhpDocComment,
}
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Closure) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Params != nil {
v.EnterChildList("Params", n)
for _, nn := range n.Params {
if nn != nil {
nn.Walk(v)
}
}
v.LeaveChildList("Params", n)
}
if n.ClosureUse != nil {
v.EnterChildNode("ClosureUse", n)
n.ClosureUse.Walk(v)
v.LeaveChildNode("ClosureUse", n)
}
if n.ReturnType != nil {
v.EnterChildNode("ReturnType", n)
n.ReturnType.Walk(v)
v.LeaveChildNode("ReturnType", n)
}
if n.Stmts != nil {
v.EnterChildList("Stmts", n)
for _, nn := range n.Stmts {
if nn != nil {
nn.Walk(v)
}
}
v.LeaveChildList("Stmts", n)
}
v.LeaveNode(n)
}

View File

@ -1,62 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ClosureUse node
type ClosureUse struct {
FreeFloating freefloating.Collection
Position *position.Position
Uses []node.Node
}
// NewClosureUse node constructor
func NewClosureUse(Uses []node.Node) *ClosureUse {
return &ClosureUse{
FreeFloating: nil,
Uses: Uses,
}
}
// SetPosition sets node position
func (n *ClosureUse) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ClosureUse) GetPosition() *position.Position {
return n.Position
}
func (n *ClosureUse) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ClosureUse) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ClosureUse) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Uses != nil {
v.EnterChildList("Uses", n)
for _, nn := range n.Uses {
if nn != nil {
nn.Walk(v)
}
}
v.LeaveChildList("Uses", n)
}
v.LeaveNode(n)
}

View File

@ -1,58 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// ConstFetch node
type ConstFetch struct {
FreeFloating freefloating.Collection
Position *position.Position
Constant node.Node
}
// NewConstFetch node constructor
func NewConstFetch(Constant node.Node) *ConstFetch {
return &ConstFetch{
FreeFloating: nil,
Constant: Constant,
}
}
// SetPosition sets node position
func (n *ConstFetch) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *ConstFetch) GetPosition() *position.Position {
return n.Position
}
func (n *ConstFetch) GetFreeFloating() *freefloating.Collection {
return &n.FreeFloating
}
// Attributes returns node attributes as map
func (n *ConstFetch) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *ConstFetch) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Constant != nil {
v.EnterChildNode("Constant", n)
n.Constant.Walk(v)
v.LeaveChildNode("Constant", n)
}
v.LeaveNode(n)
}

Some files were not shown because too many files have changed in this diff Show More