#41 Namespace resolver: do not resolve build-in primitives

This commit is contained in:
z7zmey 2018-06-18 00:15:41 +03:00
parent e38db94f54
commit 063726aac4
3 changed files with 286 additions and 1 deletions

View File

@ -99,7 +99,7 @@ func ExampleDumper() {
//| "Constant":
//| [*name.Name]
//| "Position": Pos{Line: 5-5 Pos: 86-89};
//| "NamespacedName": Foo\null;
//| "NamespacedName": null;
//| "Parts":
//| [*name.NamePart]
//| "Position": Pos{Line: 5-5 Pos: 86-89};

View File

@ -286,6 +286,40 @@ func (ns *Namespace) ResolveName(nameNode node.Node, aliasType string) (string,
return ns.Namespace + "\\" + concatNameParts(n.Parts), nil
case *name.Name:
if aliasType == "const" && len(n.Parts) == 1 {
part := strings.ToLower(n.Parts[0].(*name.NamePart).Value)
if part == "true" || part == "false" || part == "null" {
return part, nil
}
}
if aliasType == "" && len(n.Parts) == 1 {
part := strings.ToLower(n.Parts[0].(*name.NamePart).Value)
switch part {
case "self":
fallthrough
case "static":
fallthrough
case "parent":
fallthrough
case "int":
fallthrough
case "float":
fallthrough
case "bool":
fallthrough
case "string":
fallthrough
case "void":
fallthrough
case "iterable":
fallthrough
case "object":
return part, nil
}
}
aliasName, err := ns.ResolveAlias(nameNode, aliasType)
if err != nil {
// resolve as relative name if alias not found

View File

@ -739,3 +739,254 @@ func TestResolveStaticCallDinamicClassName(t *testing.T) {
assertEqual(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)
assertEqual(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)
assertEqual(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)
assertEqual(t, expected, nsResolver.ResolvedNames)
}