diff --git a/node.go b/node.go index 8315f77..6e007f3 100644 --- a/node.go +++ b/node.go @@ -42,6 +42,22 @@ func (pe parseErr) Unwrap() error { // +type arityErr struct { + funcName string + got int + expected, expectedUpperRange int +} + +func (ae arityErr) Error() string { + if ae.expected != ae.expectedUpperRange { + return fmt.Sprintf("Call to '%s' expected %d to %d argument(s), got %d", ae.funcName, ae.expected, ae.expectedUpperRange, ae.got) + } else { + return fmt.Sprintf("Call to '%s' expected %d argument(s), got %d", ae.funcName, ae.expected, ae.got) + } +} + +// + type ParseContext int const ( @@ -678,7 +694,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) // define() gets converted to const if len(fncall.ArgumentList.Arguments) != 2 { - return "", parseErr{fncall, fmt.Errorf("expected define() to have 2 arguments, found %d", len(fncall.ArgumentList.Arguments))} + return "", parseErr{fncall, arityErr{"define", len(fncall.ArgumentList.Arguments), 2, 2}} } defineName := fncall.ArgumentList.Arguments[0].(*node.Argument).Expr // that much is always possible @@ -1115,7 +1131,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `explode` { if len(callParams) != 2 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 2, 2}} } this.importPackages["strings"] = struct{}{} funcName = `strings.Split` @@ -1123,7 +1139,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `implode` { if len(callParams) != 2 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 2, 2}} } this.importPackages["strings"] = struct{}{} @@ -1136,7 +1152,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `trim` { if len(callParams) != 1 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 2, 2}} } this.importPackages["strings"] = struct{}{} @@ -1144,7 +1160,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `rtrim` { if len(callParams) != 1 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 1 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 1, 1}} } this.importPackages["strings"] = struct{}{} @@ -1154,7 +1170,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `ltrim` { if len(callParams) != 1 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 1 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 1, 1}} } this.importPackages["strings"] = struct{}{} @@ -1164,7 +1180,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `strtolower` { if len(callParams) != 1 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 1, 1}} } this.importPackages["strings"] = struct{}{} @@ -1172,7 +1188,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `strtoupper` { if len(callParams) != 1 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 1, 1}} } this.importPackages["strings"] = struct{}{} @@ -1180,7 +1196,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) } else if funcName == `file_put_contents` { if len(callParams) != 2 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 2, 2}} } this.importPackages["io/ioutil"] = struct{}{} @@ -1193,7 +1209,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) // str_replace( mixed $search , mixed $replace , mixed $subject [, int &$count ] ) // n.b. str_replace also supports arrays, that strings.Replace() doesn't do if !(len(callParams) == 3 || len(callParams) == 4) { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 3 or 4 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 3, 4}} } this.importPackages["strings"] = struct{}{} @@ -1240,7 +1256,7 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) funcName = `fmt.Sprintf` } else { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 3 or 4 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 3, 4}} } @@ -1260,16 +1276,15 @@ func (this *conversionState) convertNoFreeFloating(n_ node.Node) (string, error) // WARNING: We are doubling up on the first parameter // This is a problem if it's not necessarily constant - return "(" + callParams[0] + ")[" + callParams[1] + ":" + callParams[1] + `+` + callParams[2] + "]", nil } else { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 or 3 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 2, 3}} } } else if funcName == `rename` { if len(callParams) != 2 { - return "", parseErr{n, fmt.Errorf("Call to '%s' expected 2 argument(s), got %d", funcName, len(callParams))} + return "", parseErr{n, arityErr{funcName, len(callParams), 2, 2}} } this.importPackages["os"] = struct{}{}