alias resolving
This commit is contained in:
parent
90f451293d
commit
fbeffe7d29
2
main.go
2
main.go
@ -42,6 +42,8 @@ func main() {
|
|||||||
nsResolver := visitor.NewNsResolver()
|
nsResolver := visitor.NewNsResolver()
|
||||||
nodes.Walk(nsResolver)
|
nodes.Walk(nsResolver)
|
||||||
|
|
||||||
|
fmt.Printf("%+v \n", nsResolver.ResolvedNames)
|
||||||
|
|
||||||
dumper := visitor.Dumper{
|
dumper := visitor.Dumper{
|
||||||
Indent: " | ",
|
Indent: " | ",
|
||||||
Comments: comments,
|
Comments: comments,
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
package visitor
|
package visitor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/z7zmey/php-parser/node"
|
"github.com/z7zmey/php-parser/node"
|
||||||
@ -10,6 +11,22 @@ import (
|
|||||||
"github.com/z7zmey/php-parser/walker"
|
"github.com/z7zmey/php-parser/walker"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func concatNameParts(parts ...[]node.Node) string {
|
||||||
|
str := ""
|
||||||
|
|
||||||
|
for _, p := range parts {
|
||||||
|
for _, n := range p {
|
||||||
|
if str == "" {
|
||||||
|
str = n.(*name.NamePart).Value
|
||||||
|
} else {
|
||||||
|
str = str + "\\" + n.(*name.NamePart).Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
Namespace string
|
Namespace string
|
||||||
Aliases map[string]map[string]string
|
Aliases map[string]map[string]string
|
||||||
@ -17,7 +34,7 @@ type Namespace struct {
|
|||||||
|
|
||||||
func NewNamespace(NSName string) *Namespace {
|
func NewNamespace(NSName string) *Namespace {
|
||||||
return &Namespace{
|
return &Namespace{
|
||||||
Namespace: "",
|
Namespace: NSName,
|
||||||
Aliases: map[string]map[string]string{
|
Aliases: map[string]map[string]string{
|
||||||
"": {},
|
"": {},
|
||||||
"const": {},
|
"const": {},
|
||||||
@ -36,6 +53,53 @@ func (ns *Namespace) AddAlias(aliasType string, aliasName string, alias string)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ns *Namespace) resolveName(nameNode node.Node, aliasType string) string {
|
||||||
|
switch n := nameNode.(type) {
|
||||||
|
case *name.FullyQualified:
|
||||||
|
return concatNameParts(n.Parts)
|
||||||
|
|
||||||
|
case *name.Relative:
|
||||||
|
return ns.Namespace + "\\" + concatNameParts(n.Parts)
|
||||||
|
|
||||||
|
case *name.Name:
|
||||||
|
aliasName, err := ns.resolveAlias(nameNode, aliasType)
|
||||||
|
if err != nil {
|
||||||
|
return ns.Namespace + "\\" + concatNameParts(n.Parts)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(n.Parts) > 1 {
|
||||||
|
return aliasName + "\\" + concatNameParts(n.Parts[1:])
|
||||||
|
}
|
||||||
|
|
||||||
|
return aliasName
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("invalid nameNode variable type")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ns *Namespace) resolveAlias(nameNode node.Node, aliasType string) (string, error) {
|
||||||
|
aliasType = strings.ToLower(aliasType)
|
||||||
|
nameParts := nameNode.(*name.Name).Parts
|
||||||
|
|
||||||
|
firstPartStr := nameParts[0].(*name.NamePart).Value
|
||||||
|
|
||||||
|
if len(nameParts) > 1 { // resolve aliases for qualified names, always against class alias table
|
||||||
|
firstPartStr = strings.ToLower(firstPartStr)
|
||||||
|
aliasType = ""
|
||||||
|
} else {
|
||||||
|
if aliasType != "const" { // constans are case-sensitive
|
||||||
|
firstPartStr = strings.ToLower(firstPartStr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aliasName, ok := ns.Aliases[aliasType][firstPartStr]
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("Not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
return aliasName, nil
|
||||||
|
}
|
||||||
|
|
||||||
type NsResolver struct {
|
type NsResolver struct {
|
||||||
Namespace *Namespace
|
Namespace *Namespace
|
||||||
ResolvedNames map[node.Node]string
|
ResolvedNames map[node.Node]string
|
||||||
@ -86,11 +150,36 @@ func (nsr *NsResolver) EnterNode(w walker.Walkable) bool {
|
|||||||
// no reason to iterate into depth
|
// no reason to iterate into depth
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
case *stmt.Class:
|
||||||
|
if n.Extends != nil {
|
||||||
|
nsr.resolveName(n.Extends, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, _ = range n.Implements {
|
||||||
|
// todo resolve inteface name
|
||||||
|
}
|
||||||
|
|
||||||
|
nsr.addNamespacedName(n, n.ClassName.(*node.Identifier).Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetChildrenVisitor is invoked at every node parameter that contains children nodes
|
||||||
|
func (nsr *NsResolver) GetChildrenVisitor(key string) walker.Visitor {
|
||||||
|
return nsr
|
||||||
|
}
|
||||||
|
|
||||||
|
// LeaveNode is invoked after node process
|
||||||
|
func (nsr *NsResolver) LeaveNode(w walker.Walkable) {
|
||||||
|
switch n := w.(type) {
|
||||||
|
case *stmt.Namespace:
|
||||||
|
if n.Stmts != nil {
|
||||||
|
nsr.Namespace = NewNamespace("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (nsr *NsResolver) AddAlias(useType string, nn node.Node, prefix []node.Node) {
|
func (nsr *NsResolver) AddAlias(useType string, nn node.Node, prefix []node.Node) {
|
||||||
switch use := nn.(type) {
|
switch use := nn.(type) {
|
||||||
case *stmt.Use:
|
case *stmt.Use:
|
||||||
@ -110,33 +199,14 @@ func (nsr *NsResolver) AddAlias(useType string, nn node.Node, prefix []node.Node
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetChildrenVisitor is invoked at every node parameter that contains children nodes
|
func (nsr *NsResolver) addNamespacedName(nn node.Node, nodeName string) {
|
||||||
func (nsr *NsResolver) GetChildrenVisitor(key string) walker.Visitor {
|
if nsr.Namespace.Namespace == "" {
|
||||||
return nsr
|
nsr.ResolvedNames[nn] = nodeName
|
||||||
}
|
|
||||||
|
|
||||||
// LeaveNode is invoked after node process
|
|
||||||
func (nsr *NsResolver) LeaveNode(w walker.Walkable) {
|
|
||||||
switch n := w.(type) {
|
|
||||||
case *stmt.Namespace:
|
|
||||||
if n.Stmts != nil {
|
|
||||||
nsr.Namespace = NewNamespace("")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func concatNameParts(parts ...[]node.Node) string {
|
|
||||||
str := ""
|
|
||||||
|
|
||||||
for _, p := range parts {
|
|
||||||
for _, n := range p {
|
|
||||||
if str == "" {
|
|
||||||
str = n.(*name.NamePart).Value
|
|
||||||
} else {
|
} else {
|
||||||
str = str + "\\" + n.(*name.NamePart).Value
|
nsr.ResolvedNames[nn] = nsr.Namespace.Namespace + "\\" + nodeName
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return str
|
func (nsr *NsResolver) resolveName(nameNode node.Node, aliasType string) {
|
||||||
|
nsr.ResolvedNames[nameNode] = nsr.Namespace.resolveName(nameNode, aliasType)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user