summaryrefslogtreecommitdiff
path: root/src/pkg/try/try.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/try/try.go')
-rw-r--r--src/pkg/try/try.go174
1 files changed, 0 insertions, 174 deletions
diff --git a/src/pkg/try/try.go b/src/pkg/try/try.go
deleted file mode 100644
index 2a3dbf987..000000000
--- a/src/pkg/try/try.go
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package try contains the executable part of the gotry command.
-// It is not intended for general use.
-package try
-
-import (
- "fmt"
- "io"
- "os"
- "reflect"
- "unicode"
-)
-
-var output io.Writer = os.Stdout // redirected when testing
-
-// Main is called directly from the gotry-generated Go source file to perform
-// the evaluations.
-func Main(pkg, firstArg string, functions map[string]interface{}, args []interface{}) {
- switch len(args) {
- case 0:
- // Nothing to do.
- case 1:
- // Compiler has already evaluated the expression; just print the result.
- printSlice(firstArg, args)
- default:
- // See if methods satisfy the expressions.
- tryMethods(pkg, firstArg, args)
- // See if functions satisfy the expressions.
- for name, fn := range functions {
- tryFunction(pkg, name, fn, args)
- }
- }
-}
-
-// printSlice prints the zeroth element of the args slice, which should (by construction)
-// itself be a slice of interface{}.
-func printSlice(firstArg string, args []interface{}) {
- // Args should be length 1 and a slice.
- if len(args) != 1 {
- return
- }
- arg, ok := args[0].([]interface{})
- if !ok {
- return
- }
- fmt.Fprintf(output, "%s = ", firstArg)
- if len(arg) > 1 {
- fmt.Fprint(output, "(")
- }
- for i, a := range arg {
- if i > 0 {
- fmt.Fprint(output, ", ")
- }
- fmt.Fprintf(output, "%#v", a)
- }
- if len(arg) > 1 {
- fmt.Fprint(output, ")")
- }
- fmt.Fprint(output, "\n")
-}
-
-// tryMethods sees if the zeroth arg has methods, and if so treats them as potential
-// functions to satisfy the remaining arguments.
-func tryMethods(pkg, firstArg string, args []interface{}) {
- defer func() { recover() }()
- // Is the first argument something with methods?
- v := reflect.ValueOf(args[0])
- typ := v.Type()
- if typ.NumMethod() == 0 {
- return
- }
- for i := 0; i < typ.NumMethod(); i++ {
- if unicode.IsUpper(int(typ.Method(i).Name[0])) {
- tryMethod(pkg, firstArg, typ.Method(i), args)
- }
- }
-}
-
-// tryMethod converts a method to a function for tryOneFunction.
-func tryMethod(pkg, firstArg string, method reflect.Method, args []interface{}) {
- rfn := method.Func
- typ := method.Type
- name := method.Name
- tryOneFunction(pkg, firstArg, name, typ, rfn, args)
-}
-
-// tryFunction sees if fn satisfies the arguments.
-func tryFunction(pkg, name string, fn interface{}, args []interface{}) {
- defer func() { recover() }()
- rfn := reflect.ValueOf(fn)
- typ := rfn.Type()
- tryOneFunction(pkg, "", name, typ, rfn, args)
-}
-
-// tryOneFunction is the common code for tryMethod and tryFunction.
-func tryOneFunction(pkg, firstArg, name string, typ reflect.Type, rfn reflect.Value, args []interface{}) {
- // Any results?
- if typ.NumOut() == 0 {
- return // Nothing to do.
- }
- // Right number of arguments + results?
- if typ.NumIn()+typ.NumOut() != len(args) {
- return
- }
- // Right argument and result types?
- for i, a := range args {
- if i < typ.NumIn() {
- if !compatible(a, typ.In(i)) {
- return
- }
- } else {
- if !compatible(a, typ.Out(i-typ.NumIn())) {
- return
- }
- }
- }
- // Build the call args.
- argsVal := make([]reflect.Value, typ.NumIn()+typ.NumOut())
- for i, a := range args {
- argsVal[i] = reflect.ValueOf(a)
- }
- // Call the function and see if the results are as expected.
- resultVal := rfn.Call(argsVal[:typ.NumIn()])
- for i, v := range resultVal {
- if !reflect.DeepEqual(v.Interface(), args[i+typ.NumIn()]) {
- return
- }
- }
- // Present the result including a godoc command to get more information.
- firstIndex := 0
- if firstArg != "" {
- fmt.Fprintf(output, "%s.%s(", firstArg, name)
- firstIndex = 1
- } else {
- fmt.Fprintf(output, "%s.%s(", pkg, name)
- }
- for i := firstIndex; i < typ.NumIn(); i++ {
- if i > firstIndex {
- fmt.Fprint(output, ", ")
- }
- fmt.Fprintf(output, "%#v", args[i])
- }
- fmt.Fprint(output, ") = ")
- if typ.NumOut() > 1 {
- fmt.Fprint(output, "(")
- }
- for i := 0; i < typ.NumOut(); i++ {
- if i > 0 {
- fmt.Fprint(output, ", ")
- }
- fmt.Fprintf(output, "%#v", resultVal[i].Interface())
- }
- if typ.NumOut() > 1 {
- fmt.Fprint(output, ")")
- }
- fmt.Fprintf(output, " // godoc %s %s\n", pkg, name)
-}
-
-// compatible reports whether the argument is compatible with the type.
-func compatible(arg interface{}, typ reflect.Type) bool {
- if reflect.TypeOf(arg) == typ {
- return true
- }
- if arg == nil {
- // nil is OK if the type is an interface.
- if typ.Kind() == reflect.Interface {
- return true
- }
- }
- return false
-}