977 lines
22 KiB
Go
977 lines
22 KiB
Go
package visitor_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/name"
|
|
"github.com/z7zmey/php-parser/node/scalar"
|
|
"github.com/z7zmey/php-parser/node/stmt"
|
|
"github.com/z7zmey/php-parser/visitor"
|
|
)
|
|
|
|
func TestResolveStaticCall(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.StaticCall{
|
|
Class: nameBC,
|
|
Call: &node.Identifier{Value: "foo"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameBC: "A\\B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveStaticPropertyFetch(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.StaticPropertyFetch{
|
|
Class: nameBC,
|
|
Property: &node.Identifier{Value: "foo"},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameBC: "A\\B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveClassConstFetch(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.ClassConstFetch{
|
|
Class: nameBC,
|
|
ConstantName: &node.Identifier{Value: "FOO"},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameBC: "A\\B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveNew(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.New{
|
|
Class: nameBC,
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameBC: "A\\B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveInstanceOf(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.InstanceOf{
|
|
Expr: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
|
Class: nameBC,
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameBC: "A\\B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveInstanceCatch(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
nameDE := &name.Name{Parts: []node.Node{&name.NamePart{Value: "D"}, &name.NamePart{Value: "E"}}}
|
|
nameF := &name.Name{Parts: []node.Node{&name.NamePart{Value: "F"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
&stmt.Use{
|
|
Use: nameDE,
|
|
Alias: &node.Identifier{Value: "F"},
|
|
},
|
|
},
|
|
},
|
|
&stmt.Try{
|
|
Stmts: []node.Node{},
|
|
Catches: []node.Node{
|
|
&stmt.Catch{
|
|
Types: []node.Node{
|
|
nameBC,
|
|
nameF,
|
|
},
|
|
Variable: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
|
Stmts: []node.Node{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameBC: "A\\B\\C",
|
|
nameF: "D\\E",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveFunctionCall(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
UseType: &node.Identifier{Value: "function"},
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.FunctionCall{
|
|
Function: nameB,
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameB: "A\\B",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveConstFetch(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
UseType: &node.Identifier{Value: "const"},
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&expr.ConstFetch{
|
|
Constant: nameB,
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameB: "A\\B",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveGroupUse(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBD := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "D"}}}
|
|
nameE := &name.Name{Parts: []node.Node{&name.NamePart{Value: "E"}}}
|
|
nameC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "C"}}}
|
|
nameF := &name.Name{Parts: []node.Node{&name.NamePart{Value: "F"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.GroupUse{
|
|
Prefix: nameAB,
|
|
UseList: []node.Node{
|
|
&stmt.Use{
|
|
UseType: &node.Identifier{Value: "Function"},
|
|
Use: nameF,
|
|
},
|
|
&stmt.Use{
|
|
UseType: &node.Identifier{Value: "const"},
|
|
Use: nameC,
|
|
},
|
|
},
|
|
},
|
|
&stmt.GroupUse{
|
|
Prefix: nameBD,
|
|
UseType: &node.Identifier{Value: "Function"},
|
|
UseList: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameE,
|
|
},
|
|
},
|
|
},
|
|
&expr.ConstFetch{
|
|
Constant: nameC,
|
|
},
|
|
&expr.FunctionCall{
|
|
Function: nameF,
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
&expr.FunctionCall{
|
|
Function: nameE,
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameC: "A\\B\\C",
|
|
nameF: "A\\B\\F",
|
|
nameE: "B\\D\\E",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveTraitUse(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}}}
|
|
nameD := &name.Name{Parts: []node.Node{&name.NamePart{Value: "D"}}}
|
|
|
|
fullyQualifiedNameB := &name.FullyQualified{Parts: []node.Node{&name.NamePart{Value: "B"}}}
|
|
fullyQualifiedNameBC := &name.FullyQualified{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
relativeNameB := &name.Relative{Parts: []node.Node{&name.NamePart{Value: "B"}}}
|
|
relativeNameBC := &name.Relative{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAB,
|
|
},
|
|
},
|
|
},
|
|
&stmt.TraitUse{
|
|
Traits: []node.Node{
|
|
nameB,
|
|
relativeNameB,
|
|
},
|
|
TraitAdaptationList: &stmt.TraitAdaptationList{
|
|
Adaptations: []node.Node{
|
|
&stmt.TraitUsePrecedence{
|
|
Ref: &stmt.TraitMethodRef{
|
|
Trait: fullyQualifiedNameB,
|
|
Method: &node.Identifier{Value: "foo"},
|
|
},
|
|
Insteadof: []node.Node{fullyQualifiedNameBC},
|
|
},
|
|
&stmt.TraitUseAlias{
|
|
Ref: &stmt.TraitMethodRef{
|
|
Trait: relativeNameBC,
|
|
Method: &node.Identifier{Value: "foo"},
|
|
},
|
|
Alias: &node.Identifier{Value: "bar"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
&stmt.TraitUse{
|
|
Traits: []node.Node{
|
|
nameD,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameB: "A\\B",
|
|
nameD: "D",
|
|
relativeNameB: "B",
|
|
fullyQualifiedNameB: "B",
|
|
fullyQualifiedNameBC: "B\\C",
|
|
relativeNameBC: "B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveClassName(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
class := &stmt.Class{
|
|
PhpDocComment: "",
|
|
ClassName: &node.Identifier{Value: "A"},
|
|
Extends: &stmt.ClassExtends{
|
|
ClassName: nameAB,
|
|
},
|
|
Implements: &stmt.ClassImplements{
|
|
InterfaceNames: []node.Node{
|
|
nameBC,
|
|
},
|
|
},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
class,
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
class: "A",
|
|
nameAB: "A\\B",
|
|
nameBC: "B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveInterfaceName(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
interfaceNode := &stmt.Interface{
|
|
PhpDocComment: "",
|
|
InterfaceName: &node.Identifier{Value: "A"},
|
|
Extends: &stmt.InterfaceExtends{
|
|
InterfaceNames: []node.Node{
|
|
nameAB,
|
|
nameBC,
|
|
},
|
|
},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
interfaceNode,
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
interfaceNode: "A",
|
|
nameAB: "A\\B",
|
|
nameBC: "B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveTraitName(t *testing.T) {
|
|
traitNode := &stmt.Trait{
|
|
PhpDocComment: "",
|
|
TraitName: &node.Identifier{Value: "A"},
|
|
Stmts: []node.Node{},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
traitNode,
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
traitNode: "A",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveFunctionName(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
functionNode := &stmt.Function{
|
|
ReturnsRef: false,
|
|
PhpDocComment: "",
|
|
FunctionName: &node.Identifier{Value: "A"},
|
|
Params: []node.Node{
|
|
&node.Parameter{
|
|
ByRef: false,
|
|
Variadic: false,
|
|
VariableType: nameAB,
|
|
Variable: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
|
},
|
|
},
|
|
ReturnType: &node.Nullable{Expr: nameBC},
|
|
Stmts: []node.Node{},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
functionNode,
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
functionNode: "A",
|
|
nameAB: "A\\B",
|
|
nameBC: "B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveMethodName(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
methodNode := &stmt.ClassMethod{
|
|
ReturnsRef: false,
|
|
PhpDocComment: "",
|
|
MethodName: &node.Identifier{Value: "A"},
|
|
Params: []node.Node{
|
|
&node.Parameter{
|
|
ByRef: false,
|
|
Variadic: false,
|
|
VariableType: nameAB,
|
|
Variable: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
|
},
|
|
},
|
|
ReturnType: &node.Nullable{Expr: nameBC},
|
|
Stmt: &stmt.StmtList{
|
|
Stmts: []node.Node{},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameAB: "A\\B",
|
|
nameBC: "B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
methodNode.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveClosureName(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
nameBC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "B"}, &name.NamePart{Value: "C"}}}
|
|
|
|
closureNode := &expr.Closure{
|
|
ReturnsRef: false,
|
|
Static: false,
|
|
PhpDocComment: "",
|
|
Params: []node.Node{
|
|
&node.Parameter{
|
|
ByRef: false,
|
|
Variadic: false,
|
|
VariableType: nameAB,
|
|
Variable: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
|
},
|
|
},
|
|
ReturnType: &node.Nullable{Expr: nameBC},
|
|
Stmts: []node.Node{},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
nameAB: "A\\B",
|
|
nameBC: "B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
closureNode.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveConstantsName(t *testing.T) {
|
|
nameAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
|
|
constantB := &stmt.Constant{
|
|
PhpDocComment: "",
|
|
ConstantName: &node.Identifier{Value: "B"},
|
|
Expr: &scalar.Lnumber{Value: "1"},
|
|
}
|
|
constantC := &stmt.Constant{
|
|
PhpDocComment: "",
|
|
ConstantName: &node.Identifier{Value: "C"},
|
|
Expr: &scalar.Lnumber{Value: "1"},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.Namespace{
|
|
NamespaceName: nameAB,
|
|
},
|
|
&stmt.ConstList{
|
|
Consts: []node.Node{
|
|
constantB,
|
|
constantC,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
constantB: "A\\B\\B",
|
|
constantC: "A\\B\\C",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveNamespaces(t *testing.T) {
|
|
namespaceAB := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "B"}}}
|
|
namespaceCD := &name.Name{Parts: []node.Node{&name.NamePart{Value: "C"}, &name.NamePart{Value: "D"}}}
|
|
|
|
nameAC := &name.Name{Parts: []node.Node{&name.NamePart{Value: "A"}, &name.NamePart{Value: "C"}}}
|
|
nameCF := &name.Name{Parts: []node.Node{&name.NamePart{Value: "C"}, &name.NamePart{Value: "F"}}}
|
|
nameFG := &name.Name{Parts: []node.Node{&name.NamePart{Value: "F"}, &name.NamePart{Value: "G"}}}
|
|
relativeNameCE := &name.Relative{Parts: []node.Node{&name.NamePart{Value: "C"}, &name.NamePart{Value: "E"}}}
|
|
|
|
constantB := &stmt.Constant{
|
|
PhpDocComment: "",
|
|
ConstantName: &node.Identifier{Value: "B"},
|
|
Expr: &scalar.Lnumber{Value: "1"},
|
|
}
|
|
constantC := &stmt.Constant{
|
|
PhpDocComment: "",
|
|
ConstantName: &node.Identifier{Value: "C"},
|
|
Expr: &scalar.Lnumber{Value: "1"},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.Namespace{
|
|
NamespaceName: namespaceAB,
|
|
},
|
|
&stmt.ConstList{
|
|
Consts: []node.Node{
|
|
constantB,
|
|
constantC,
|
|
},
|
|
},
|
|
&expr.StaticCall{
|
|
Class: nameFG,
|
|
Call: &node.Identifier{Value: "foo"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
&stmt.Namespace{
|
|
Stmts: []node.Node{},
|
|
},
|
|
&stmt.Namespace{
|
|
NamespaceName: namespaceCD,
|
|
Stmts: []node.Node{
|
|
&stmt.UseList{
|
|
Uses: []node.Node{
|
|
&stmt.Use{
|
|
Use: nameAC,
|
|
},
|
|
},
|
|
},
|
|
&expr.StaticCall{
|
|
Class: relativeNameCE,
|
|
Call: &node.Identifier{Value: "foo"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
&expr.StaticCall{
|
|
Class: nameCF,
|
|
Call: &node.Identifier{Value: "foo"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
constantB: "A\\B\\B",
|
|
constantC: "A\\B\\C",
|
|
nameFG: "A\\B\\F\\G",
|
|
relativeNameCE: "C\\D\\C\\E",
|
|
nameCF: "A\\C\\F",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestResolveStaticCallDinamicClassName(t *testing.T) {
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&expr.StaticCall{
|
|
Class: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
|
|
Call: &node.Identifier{Value: "foo"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestDoNotResolveReservedConstants(t *testing.T) {
|
|
namespaceName := &name.Name{Parts: []node.Node{&name.NamePart{Value: "Foo"}}}
|
|
|
|
constantTrue := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "True"},
|
|
},
|
|
}
|
|
|
|
constantFalse := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "False"},
|
|
},
|
|
}
|
|
|
|
constantNull := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "NULL"},
|
|
},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.Namespace{
|
|
NamespaceName: namespaceName,
|
|
},
|
|
&stmt.Expression{
|
|
Expr: &expr.ConstFetch{
|
|
Constant: constantTrue,
|
|
},
|
|
},
|
|
&stmt.Expression{
|
|
Expr: &expr.ConstFetch{
|
|
Constant: constantFalse,
|
|
},
|
|
},
|
|
&stmt.Expression{
|
|
Expr: &expr.ConstFetch{
|
|
Constant: constantNull,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
constantTrue: "true",
|
|
constantFalse: "false",
|
|
constantNull: "null",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestDoNotResolveReservedNames(t *testing.T) {
|
|
|
|
nameInt := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "int"},
|
|
},
|
|
}
|
|
|
|
nameFloat := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "float"},
|
|
},
|
|
}
|
|
|
|
nameBool := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "bool"},
|
|
},
|
|
}
|
|
|
|
nameString := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "string"},
|
|
},
|
|
}
|
|
|
|
nameVoid := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "void"},
|
|
},
|
|
}
|
|
|
|
nameIterable := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "iterable"},
|
|
},
|
|
}
|
|
|
|
nameObject := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "object"},
|
|
},
|
|
}
|
|
|
|
function := &stmt.Function{
|
|
FunctionName: &node.Identifier{Value: "bar"},
|
|
Params: []node.Node{
|
|
&node.Parameter{
|
|
VariableType: nameInt,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "Int"},
|
|
},
|
|
},
|
|
&node.Parameter{
|
|
VariableType: nameFloat,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "Float"},
|
|
},
|
|
},
|
|
&node.Parameter{
|
|
VariableType: nameBool,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "Bool"},
|
|
},
|
|
},
|
|
&node.Parameter{
|
|
VariableType: nameString,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "String"},
|
|
},
|
|
},
|
|
&node.Parameter{
|
|
VariableType: nameVoid,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "Void"},
|
|
},
|
|
},
|
|
&node.Parameter{
|
|
VariableType: nameIterable,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "Iterable"},
|
|
},
|
|
},
|
|
&node.Parameter{
|
|
VariableType: nameObject,
|
|
Variable: &expr.Variable{
|
|
VarName: &node.Identifier{Value: "Object"},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.Namespace{
|
|
NamespaceName: &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "Foo"},
|
|
},
|
|
},
|
|
},
|
|
function,
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
function: "Foo\\bar",
|
|
nameInt: "int",
|
|
nameFloat: "float",
|
|
nameBool: "bool",
|
|
nameString: "string",
|
|
nameVoid: "void",
|
|
nameIterable: "iterable",
|
|
nameObject: "object",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|
|
|
|
func TestDoNotResolveReservedSpecialNames(t *testing.T) {
|
|
|
|
nameSelf := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "Self"},
|
|
},
|
|
}
|
|
|
|
nameStatic := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "Static"},
|
|
},
|
|
}
|
|
|
|
nameParent := &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "Parent"},
|
|
},
|
|
}
|
|
|
|
cls := &stmt.Class{
|
|
ClassName: &node.Identifier{Value: "Bar"},
|
|
Stmts: []node.Node{
|
|
&stmt.Expression{
|
|
Expr: &expr.StaticCall{
|
|
Class: nameSelf,
|
|
Call: &node.Identifier{Value: "func"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
&stmt.Expression{
|
|
Expr: &expr.StaticCall{
|
|
Class: nameStatic,
|
|
Call: &node.Identifier{Value: "func"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
&stmt.Expression{
|
|
Expr: &expr.StaticCall{
|
|
Class: nameParent,
|
|
Call: &node.Identifier{Value: "func"},
|
|
ArgumentList: &node.ArgumentList{},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
ast := &stmt.StmtList{
|
|
Stmts: []node.Node{
|
|
&stmt.Namespace{
|
|
NamespaceName: &name.Name{
|
|
Parts: []node.Node{
|
|
&name.NamePart{Value: "Foo"},
|
|
},
|
|
},
|
|
},
|
|
cls,
|
|
},
|
|
}
|
|
|
|
expected := map[node.Node]string{
|
|
cls: "Foo\\Bar",
|
|
nameSelf: "self",
|
|
nameStatic: "static",
|
|
nameParent: "parent",
|
|
}
|
|
|
|
nsResolver := visitor.NewNamespaceResolver()
|
|
ast.Walk(nsResolver)
|
|
|
|
assert.DeepEqual(t, expected, nsResolver.ResolvedNames)
|
|
}
|