php-parser/pkg/visitor/nsresolver/namespace_resolver_test.go

1121 lines
27 KiB
Go
Raw Permalink Normal View History

2020-12-28 19:13:08 +00:00
package nsresolver_test
2020-05-13 18:05:15 +00:00
import (
"testing"
2023-12-09 21:36:19 +00:00
"git.maride.cc/maride/php-parser/pkg/visitor/nsresolver"
"git.maride.cc/maride/php-parser/pkg/visitor/traverser"
2020-05-13 18:05:15 +00:00
"gotest.tools/assert"
2023-12-09 21:36:19 +00:00
"git.maride.cc/maride/php-parser/pkg/ast"
2020-05-13 18:05:15 +00:00
)
func TestResolveStaticCall(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprStaticCall{
Class: nameBC,
Call: &ast.Identifier{Value: []byte("foo")},
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{
nameBC: "A\\B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveStaticPropertyFetch(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprStaticPropertyFetch{
2020-12-28 21:01:02 +00:00
Class: nameBC,
Prop: &ast.Identifier{Value: []byte("foo")},
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{
nameBC: "A\\B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveClassConstFetch(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprClassConstFetch{
2020-12-28 21:01:02 +00:00
Class: nameBC,
Const: &ast.Identifier{Value: []byte("FOO")},
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{
nameBC: "A\\B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveNew(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprNew{
2020-12-11 11:28:16 +00:00
Class: nameBC,
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{
nameBC: "A\\B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveInstanceOf(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprInstanceOf{
2020-12-28 21:01:02 +00:00
Expr: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("foo")}},
2020-05-13 18:05:15 +00:00
Class: nameBC,
},
},
}
expected := map[ast.Vertex]string{
nameBC: "A\\B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveInstanceCatch(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
2020-12-28 21:01:02 +00:00
nameDE := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("D")}, &ast.NamePart{Value: []byte("E")}}}
nameF := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("F")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
},
2020-12-28 21:01:02 +00:00
&ast.StmtUse{
Use: nameDE,
Alias: &ast.Identifier{Value: []byte("F")},
2020-05-13 18:05:15 +00:00
},
},
},
&ast.StmtTry{
Stmts: []ast.Vertex{},
Catches: []ast.Vertex{
&ast.StmtCatch{
Types: []ast.Vertex{
nameBC,
nameF,
},
2020-12-28 21:01:02 +00:00
Var: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("foo")}},
2020-05-17 19:56:32 +00:00
Stmts: []ast.Vertex{},
2020-05-13 18:05:15 +00:00
},
},
},
},
}
expected := map[ast.Vertex]string{
nameBC: "A\\B\\C",
nameF: "D\\E",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveFunctionCall(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Type: &ast.Identifier{Value: []byte("function")},
2020-12-28 21:01:02 +00:00
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprFunctionCall{
2020-12-11 11:28:16 +00:00
Function: nameB,
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{
nameB: "A\\B",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveConstFetch(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Type: &ast.Identifier{Value: []byte("const")},
2020-12-28 21:01:02 +00:00
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprConstFetch{
Const: nameB,
},
},
}
expected := map[ast.Vertex]string{
nameB: "A\\B",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveGroupUse(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBD := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("D")}}}
nameE := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("E")}}}
nameC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}}}
nameF := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("F")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtGroupUseList{
Prefix: nameAB,
2020-12-28 21:01:02 +00:00
Uses: []ast.Vertex{
&ast.StmtUse{
Type: &ast.Identifier{Value: []byte("Function")},
Use: nameF,
},
2020-12-28 21:01:02 +00:00
&ast.StmtUse{
Type: &ast.Identifier{Value: []byte("const")},
Use: nameC,
2020-05-13 18:05:15 +00:00
},
},
},
2020-12-28 21:01:02 +00:00
&ast.StmtGroupUseList{
Prefix: nameBD,
Type: &ast.Identifier{Value: []byte("Function")},
2020-12-28 21:01:02 +00:00
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameE,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprConstFetch{
Const: nameC,
},
&ast.ExprFunctionCall{
2020-12-11 11:28:16 +00:00
Function: nameF,
2020-05-13 18:05:15 +00:00
},
&ast.ExprFunctionCall{
2020-12-11 11:28:16 +00:00
Function: nameE,
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{
nameC: "A\\B\\C",
nameF: "A\\B\\F",
nameE: "B\\D\\E",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveTraitUse(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}}}
nameD := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("D")}}}
2020-05-13 18:05:15 +00:00
2020-12-28 21:01:02 +00:00
fullyQualifiedNameB := &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}}}
fullyQualifiedNameBC := &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
relativeNameB := &ast.NameRelative{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}}}
relativeNameBC := &ast.NameRelative{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAB,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.StmtTraitUse{
Traits: []ast.Vertex{
nameB,
relativeNameB,
},
Adaptations: []ast.Vertex{
&ast.StmtTraitUsePrecedence{
Trait: fullyQualifiedNameB,
Method: &ast.Identifier{Value: []byte("foo")},
Insteadof: []ast.Vertex{fullyQualifiedNameBC},
},
&ast.StmtTraitUseAlias{
Trait: relativeNameBC,
Method: &ast.Identifier{Value: []byte("foo")},
Alias: &ast.Identifier{Value: []byte("bar")},
2020-05-13 18:05:15 +00:00
},
},
},
&ast.StmtTraitUse{
Traits: []ast.Vertex{
nameD,
},
},
},
}
expected := map[ast.Vertex]string{
nameB: "A\\B",
nameD: "D",
relativeNameB: "B",
fullyQualifiedNameB: "B",
fullyQualifiedNameBC: "B\\C",
relativeNameBC: "B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveClassName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
nameCD := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}, &ast.NamePart{Value: []byte("D")}}}
2020-05-13 18:05:15 +00:00
class := &ast.StmtClass{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("A")},
Extends: nameAB,
Implements: []ast.Vertex{
nameBC,
2020-05-13 18:05:15 +00:00
},
AttrGroups: []ast.Vertex{
&ast.AttributeGroup{
Attrs: []ast.Vertex{
&ast.Attribute{Name: nameCD},
},
},
},
2020-05-13 18:05:15 +00:00
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
class,
},
}
expected := map[ast.Vertex]string{
class: "A",
nameAB: "A\\B",
nameBC: "B\\C",
nameCD: "C\\D",
2020-05-13 18:05:15 +00:00
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveInterfaceName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
interfaceNode := &ast.StmtInterface{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("A")},
Extends: []ast.Vertex{
nameAB,
nameBC,
2020-05-13 18:05:15 +00:00
},
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
interfaceNode,
},
}
expected := map[ast.Vertex]string{
interfaceNode: "A",
nameAB: "A\\B",
nameBC: "B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveTraitName(t *testing.T) {
traitNode := &ast.StmtTrait{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("A")},
Stmts: []ast.Vertex{},
2020-05-13 18:05:15 +00:00
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
traitNode,
},
}
expected := map[ast.Vertex]string{
traitNode: "A",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveEnumName(t *testing.T) {
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
enum := &ast.StmtEnum{
Name: &ast.Identifier{Value: []byte("A")},
Type: nameAB,
Implements: []ast.Vertex{
nameBC,
},
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
enum,
},
}
expected := map[ast.Vertex]string{
enum: "A",
nameAB: "A\\B",
nameBC: "B\\C",
}
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
2020-05-13 18:05:15 +00:00
func TestResolveFunctionName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
functionNode := &ast.StmtFunction{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("A")},
2020-05-13 18:05:15 +00:00
Params: []ast.Vertex{
&ast.Parameter{
Type: nameAB,
2020-12-28 21:01:02 +00:00
Var: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("foo")}},
2020-05-13 18:05:15 +00:00
},
},
ReturnType: &ast.Nullable{Expr: nameBC},
Stmts: []ast.Vertex{},
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
functionNode,
},
}
expected := map[ast.Vertex]string{
functionNode: "A",
nameAB: "A\\B",
nameBC: "B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveMethodName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
nameCD := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}, &ast.NamePart{Value: []byte("D")}}}
nameDE := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("D")}, &ast.NamePart{Value: []byte("E")}}}
nameEF := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("E")}, &ast.NamePart{Value: []byte("F")}}}
nameFG := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("F")}, &ast.NamePart{Value: []byte("G")}}}
2020-05-13 18:05:15 +00:00
methodNode := &ast.StmtClassMethod{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("A")},
2020-05-13 18:05:15 +00:00
Params: []ast.Vertex{
&ast.Parameter{
Type: nameAB,
2020-12-28 21:01:02 +00:00
Var: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("foo")}},
2020-05-13 18:05:15 +00:00
},
&ast.Parameter{
Type: &ast.Union{Types: []ast.Vertex{nameCD, nameDE}},
Var: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("all")}},
},
&ast.Parameter{
Type: &ast.Intersection{Types: []ast.Vertex{nameEF, nameFG}},
Var: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("any")}},
},
2020-05-13 18:05:15 +00:00
},
ReturnType: &ast.Nullable{Expr: nameBC},
Stmt: &ast.StmtStmtList{
Stmts: []ast.Vertex{},
},
}
expected := map[ast.Vertex]string{
nameAB: "A\\B",
nameBC: "B\\C",
nameCD: "C\\D",
nameDE: "D\\E",
nameEF: "E\\F",
nameFG: "F\\G",
2020-05-13 18:05:15 +00:00
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(methodNode)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveClosureName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameBC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("B")}, &ast.NamePart{Value: []byte("C")}}}
2020-05-13 18:05:15 +00:00
closureNode := &ast.ExprClosure{
Params: []ast.Vertex{
&ast.Parameter{
Type: nameAB,
2020-12-28 21:01:02 +00:00
Var: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("foo")}},
2020-05-13 18:05:15 +00:00
},
},
ReturnType: &ast.Nullable{Expr: nameBC},
Stmts: []ast.Vertex{},
}
expected := map[ast.Vertex]string{
nameAB: "A\\B",
nameBC: "B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(closureNode)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveConstantsName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
2020-05-13 18:05:15 +00:00
constantB := &ast.StmtConstant{
Name: &ast.Identifier{Value: []byte("B")},
Expr: &ast.ScalarLnumber{Value: []byte("1")},
2020-05-13 18:05:15 +00:00
}
constantC := &ast.StmtConstant{
Name: &ast.Identifier{Value: []byte("C")},
Expr: &ast.ScalarLnumber{Value: []byte("1")},
2020-05-13 18:05:15 +00:00
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNamespace{
Name: nameAB,
2020-05-13 18:05:15 +00:00
},
&ast.StmtConstList{
Consts: []ast.Vertex{
constantB,
constantC,
},
},
},
}
expected := map[ast.Vertex]string{
constantB: "A\\B\\B",
constantC: "A\\B\\C",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveNamespaces(t *testing.T) {
2020-12-28 21:01:02 +00:00
namespaceAB := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
namespaceCD := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}, &ast.NamePart{Value: []byte("D")}}}
2020-05-13 18:05:15 +00:00
2020-12-28 21:01:02 +00:00
nameAC := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("C")}}}
nameCF := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}, &ast.NamePart{Value: []byte("F")}}}
nameFG := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("F")}, &ast.NamePart{Value: []byte("G")}}}
relativeNameCE := &ast.NameRelative{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}, &ast.NamePart{Value: []byte("E")}}}
2020-05-13 18:05:15 +00:00
relativeNameCA := &ast.NameRelative{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("C")}, &ast.NamePart{Value: []byte("A")}}}
classA := &ast.StmtClass{
Name: &ast.Identifier{Value: []byte("A")},
AttrGroups: []ast.Vertex{
&ast.AttributeGroup{
Attrs: []ast.Vertex{
&ast.Attribute{Name: relativeNameCA},
},
},
},
}
2020-05-13 18:05:15 +00:00
constantB := &ast.StmtConstant{
Name: &ast.Identifier{Value: []byte("B")},
Expr: &ast.ScalarLnumber{Value: []byte("1")},
2020-05-13 18:05:15 +00:00
}
constantC := &ast.StmtConstant{
Name: &ast.Identifier{Value: []byte("C")},
Expr: &ast.ScalarLnumber{Value: []byte("1")},
2020-05-13 18:05:15 +00:00
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNamespace{
Name: namespaceAB,
2020-05-13 18:05:15 +00:00
},
classA,
2020-05-13 18:05:15 +00:00
&ast.StmtConstList{
Consts: []ast.Vertex{
constantB,
constantC,
},
},
&ast.ExprStaticCall{
2020-12-11 11:28:16 +00:00
Class: nameFG,
Call: &ast.Identifier{Value: []byte("foo")},
2020-05-13 18:05:15 +00:00
},
2020-05-13 18:05:15 +00:00
&ast.StmtNamespace{
Stmts: []ast.Vertex{},
},
&ast.StmtNamespace{
Name: namespaceCD,
2020-05-13 18:05:15 +00:00
Stmts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.StmtUseList{
Uses: []ast.Vertex{
&ast.StmtUse{
Use: nameAC,
2020-05-13 18:05:15 +00:00
},
},
},
&ast.ExprStaticCall{
2020-12-11 11:28:16 +00:00
Class: relativeNameCE,
Call: &ast.Identifier{Value: []byte("foo")},
2020-05-13 18:05:15 +00:00
},
&ast.ExprStaticCall{
2020-12-11 11:28:16 +00:00
Class: nameCF,
Call: &ast.Identifier{Value: []byte("foo")},
2020-05-13 18:05:15 +00:00
},
},
},
},
}
expected := map[ast.Vertex]string{
classA: "A\\B\\A",
relativeNameCA: "A\\B\\C\\A",
2020-05-13 18:05:15 +00:00
constantB: "A\\B\\B",
constantC: "A\\B\\C",
nameFG: "A\\B\\F\\G",
relativeNameCE: "C\\D\\C\\E",
nameCF: "A\\C\\F",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestResolveStaticCallDinamicClassName(t *testing.T) {
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.ExprStaticCall{
2020-12-28 21:01:02 +00:00
Class: &ast.ExprVariable{Name: &ast.Identifier{Value: []byte("foo")}},
2020-12-11 11:28:16 +00:00
Call: &ast.Identifier{Value: []byte("foo")},
2020-05-13 18:05:15 +00:00
},
},
}
expected := map[ast.Vertex]string{}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestDoNotResolveReservedConstants(t *testing.T) {
2020-12-28 21:01:02 +00:00
namespaceName := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("Foo")}}}
2020-05-13 18:05:15 +00:00
2020-12-28 21:01:02 +00:00
constantTrue := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("True")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
constantFalse := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("False")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
constantNull := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("NULL")},
2020-05-13 18:05:15 +00:00
},
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNamespace{
Name: namespaceName,
2020-05-13 18:05:15 +00:00
},
&ast.StmtExpression{
Expr: &ast.ExprConstFetch{
Const: constantTrue,
},
},
&ast.StmtExpression{
Expr: &ast.ExprConstFetch{
Const: constantFalse,
},
},
&ast.StmtExpression{
Expr: &ast.ExprConstFetch{
Const: constantNull,
},
},
},
}
expected := map[ast.Vertex]string{
constantTrue: "true",
constantFalse: "false",
constantNull: "null",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestDoNotResolveReservedNames(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameInt := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("int")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameFloat := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("float")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameBool := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("bool")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameString := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("string")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameVoid := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("void")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameIterable := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("iterable")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameObject := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("object")},
2020-05-13 18:05:15 +00:00
},
}
nameMixed := &ast.Name{
Parts: []ast.Vertex{
&ast.NamePart{Value: []byte("mixed")},
},
}
nameNever := &ast.Name{
Parts: []ast.Vertex{
&ast.NamePart{Value: []byte("never")},
},
}
nameTrue := &ast.Name{
Parts: []ast.Vertex{
&ast.NamePart{Value: []byte("true")},
},
}
nameFalse := &ast.Name{
Parts: []ast.Vertex{
&ast.NamePart{Value: []byte("false")},
},
}
nameNull := &ast.Name{
Parts: []ast.Vertex{
&ast.NamePart{Value: []byte("null")},
},
}
2020-05-13 18:05:15 +00:00
function := &ast.StmtFunction{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("bar")},
2020-05-13 18:05:15 +00:00
Params: []ast.Vertex{
&ast.Parameter{
Type: nameInt,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Int")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameFloat,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Float")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameBool,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Bool")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameString,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("String")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameVoid,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Void")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameIterable,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Iterable")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameObject,
Var: &ast.ExprVariable{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Object")},
2020-05-13 18:05:15 +00:00
},
},
&ast.Parameter{
Type: nameMixed,
Var: &ast.ExprVariable{
Name: &ast.Identifier{Value: []byte("Mixed")},
},
},
&ast.Parameter{
Type: nameNever,
Var: &ast.ExprVariable{
Name: &ast.Identifier{Value: []byte("Never")},
},
},
&ast.Parameter{
Type: nameTrue,
Var: &ast.ExprVariable{
Name: &ast.Identifier{Value: []byte("True")},
},
},
&ast.Parameter{
Type: nameFalse,
Var: &ast.ExprVariable{
Name: &ast.Identifier{Value: []byte("False")},
},
},
&ast.Parameter{
Type: nameNull,
Var: &ast.ExprVariable{
Name: &ast.Identifier{Value: []byte("Null")},
},
},
2020-05-13 18:05:15 +00:00
},
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNamespace{
2020-12-28 21:01:02 +00:00
Name: &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("Foo")},
2020-05-13 18:05:15 +00:00
},
},
},
function,
},
}
expected := map[ast.Vertex]string{
function: "Foo\\bar",
nameInt: "int",
nameFloat: "float",
nameBool: "bool",
nameString: "string",
nameVoid: "void",
nameIterable: "iterable",
nameObject: "object",
nameMixed: "mixed",
nameNever: "never",
nameTrue: "true",
nameFalse: "false",
nameNull: "null",
2020-05-13 18:05:15 +00:00
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
func TestDoNotResolveReservedSpecialNames(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameSelf := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("Self")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameStatic := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("Static")},
2020-05-13 18:05:15 +00:00
},
}
2020-12-28 21:01:02 +00:00
nameParent := &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("Parent")},
2020-05-13 18:05:15 +00:00
},
}
cls := &ast.StmtClass{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Bar")},
2020-05-13 18:05:15 +00:00
Stmts: []ast.Vertex{
&ast.StmtExpression{
Expr: &ast.ExprStaticCall{
2020-12-11 11:28:16 +00:00
Class: nameSelf,
Call: &ast.Identifier{Value: []byte("func")},
2020-05-13 18:05:15 +00:00
},
},
&ast.StmtExpression{
Expr: &ast.ExprStaticCall{
2020-12-11 11:28:16 +00:00
Class: nameStatic,
Call: &ast.Identifier{Value: []byte("func")},
2020-05-13 18:05:15 +00:00
},
},
&ast.StmtExpression{
Expr: &ast.ExprStaticCall{
2020-12-11 11:28:16 +00:00
Class: nameParent,
Call: &ast.Identifier{Value: []byte("func")},
2020-05-13 18:05:15 +00:00
},
},
},
}
stxTree := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNamespace{
2020-12-28 21:01:02 +00:00
Name: &ast.Name{
2020-05-13 18:05:15 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("Foo")},
2020-05-13 18:05:15 +00:00
},
},
},
cls,
},
}
expected := map[ast.Vertex]string{
cls: "Foo\\Bar",
nameSelf: "self",
nameStatic: "static",
nameParent: "parent",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stxTree)
2020-05-13 18:05:15 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}
2020-07-29 20:23:44 +00:00
func TestResolvePropertyTypeName(t *testing.T) {
2020-12-28 21:01:02 +00:00
nameSimple := &ast.Name{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameRelative := &ast.NameRelative{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
nameFullyQualified := &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NamePart{Value: []byte("A")}, &ast.NamePart{Value: []byte("B")}}}
2020-07-29 20:23:44 +00:00
propertyNodeSimple := &ast.StmtPropertyList{
Type: nameSimple,
}
propertyNodeRelative := &ast.StmtPropertyList{
Type: nameRelative,
}
propertyNodeFullyQualified := &ast.StmtPropertyList{
Type: nameFullyQualified,
}
classNode := &ast.StmtClass{
2020-12-28 21:01:02 +00:00
Name: &ast.Identifier{Value: []byte("Bar")},
2020-07-29 20:23:44 +00:00
Stmts: []ast.Vertex{
propertyNodeSimple,
propertyNodeRelative,
propertyNodeFullyQualified,
},
}
stmts := &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNamespace{
2020-12-28 21:01:02 +00:00
Name: &ast.Name{
2020-07-29 20:23:44 +00:00
Parts: []ast.Vertex{
2020-12-28 21:01:02 +00:00
&ast.NamePart{Value: []byte("Foo")},
2020-07-29 20:23:44 +00:00
},
},
},
classNode,
},
}
expected := map[ast.Vertex]string{
nameSimple: "Foo\\A\\B",
nameRelative: "Foo\\A\\B",
nameFullyQualified: "A\\B",
classNode: "Foo\\Bar",
}
2020-12-28 19:13:08 +00:00
nsResolver := nsresolver.NewNamespaceResolver()
traverser.NewTraverser(nsResolver).Traverse(stmts)
2020-07-29 20:23:44 +00:00
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
}