node: convert use of strlen/cound/sizeof/explode/implode

This commit is contained in:
mappu 2020-04-10 20:08:40 +12:00
parent 92abcfe5b9
commit 7461bfe187
1 changed files with 33 additions and 9 deletions

42
node.go
View File

@ -610,7 +610,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
// No need to use a child scope for the temporary name -
// super() is a reserved name in PHP anyway
ret := "super, err := " + constructorName(this.currentClassParentName) + funcArgs + "\n"
ret := "super, err := " + constructorName(this.currentClassParentName) + "(" + strings.Join(funcArgs, ", ") + ")\n"
ret += "if err != nil {\n"
ret += this.currentErrHandler //"return err\n"
ret += "}\n"
@ -931,7 +931,31 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
// FIXME need to support `this.currentErrHandler`
return funcName + callParams, nil // expr only, no semicolon/newline
// Transform some PHP standard library functions to their Go equivalents
// TODO check namespacing for collision prevention
if funcName == `strlen` || funcName == `count` || funcName == `sizeof` {
funcName = `len`
} else if funcName == `explode` {
if len(callParams) != 2 {
return "", parseErr{n, fmt.Errorf("Call to \\explode() should have 2 arguments, got %d", len(callParams))}
}
this.importPackages["strings"] = struct{}{}
funcName = `strings.Split`
callParams[0], callParams[1] = callParams[1], callParams[2] // need to reverse function argument order
} else if funcName == `implode` {
if len(callParams) != 2 {
return "", parseErr{n, fmt.Errorf("Call to \\implode() should have 2 arguments, got %d", len(callParams))}
}
this.importPackages["strings"] = struct{}{}
funcName = `strings.Join`
callParams[0], callParams[1] = callParams[1], callParams[2] // need to reverse function argument order
}
return funcName + "(" + strings.Join(callParams, ", ") + ")", nil // expr only, no semicolon/newline
case *expr.StaticCall:
className, err := this.resolveName(n.Class)
@ -960,7 +984,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
// FIXME need to support `this.currentErrHandler`
return callTarget + callParams, nil // expr only, no semicolon/newline
return callTarget + "(" + strings.Join(callParams, ", ") + ")", nil // expr only, no semicolon/newline
case *expr.New:
// new foo(xx)
@ -1054,7 +1078,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error)
// FIXME need to support `this.currentErrHandler`
return parent + "." + child + args, nil
return parent + "." + child + "(" + strings.Join(args, ", ") + ")", nil
case *expr.PropertyFetch:
// Foo->Bar
@ -1397,7 +1421,7 @@ func constructorName(className string) string {
// This is only safe in cases where there is ambiguously a single rvalue wanted,
// e.g. between ( and , in a function call argument
func removeParens(expr string) string {
for len(expr) > 2 && expr[0] == '(' && expr[len(expr)-1] == ')' {
for len(expr) > 2 && expr[0] == '(' && expr[len(expr)-1] == ')' && !strings.HasSuffix(expr, `()`) {
expr = expr[1 : len(expr)-1]
}
return expr
@ -1567,18 +1591,18 @@ func (this *conversionState) convertBinaryCommon(left, right node.Node, goBinary
return "(" + lhs + " " + goBinaryOperator + " " + rhs + ")", nil
}
func (this *conversionState) convertFuncCallArgsCommon(args *node.ArgumentList) (string, error) {
func (this *conversionState) convertFuncCallArgsCommon(args *node.ArgumentList) ([]string, error) {
callParams := make([]string, 0, len(args.Arguments))
for _, arg_ := range args.Arguments {
arg, ok := arg_.(*node.Argument)
if !ok {
return "", parseErr{arg_, fmt.Errorf("expected node.Argument")}
return nil, parseErr{arg_, fmt.Errorf("expected node.Argument")}
}
rvalue, err := this.convert(arg.Expr)
if err != nil {
return "", parseErr{arg, err}
return nil, parseErr{arg, err}
}
if arg.IsReference {
rvalue = "&" + rvalue
@ -1590,7 +1614,7 @@ func (this *conversionState) convertFuncCallArgsCommon(args *node.ArgumentList)
callParams = append(callParams, removeParens(rvalue))
}
return "(" + strings.Join(callParams, `, `) + ")", nil // expr only, no semicolon/newline
return callParams, nil
}
func (this *conversionState) convertArrayLiteralCommon(items []node.Node) (string, error) {