mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-12 17:27:50 +08:00
eval: Fix lint errors.
This commit is contained in:
parent
a8a6c71fbd
commit
c8e767b2fd
|
@ -11,7 +11,13 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
ErrArgs = errors.New("args error")
|
||||
// ErrArgs is thrown when a builtin function gets erroneous arguments.
|
||||
//
|
||||
// TODO(xiaq): Replace this single error type with multiple types that carry
|
||||
// richer error information.
|
||||
ErrArgs = errors.New("args error")
|
||||
// ErrNoOptAccepted is thrown when a builtin function that does not accept
|
||||
// any options gets passed options.
|
||||
ErrNoOptAccepted = errors.New("function does not accept any options")
|
||||
)
|
||||
|
||||
|
@ -73,6 +79,9 @@ type optionsPtr interface {
|
|||
SetDefaultOptions()
|
||||
}
|
||||
|
||||
// Inputs is the type that the last parameter of a builtin function can take.
|
||||
// When that is the case, it is a callback to get inputs. See the doc of
|
||||
// BuiltinFn for details.
|
||||
type Inputs func(func(interface{}))
|
||||
|
||||
var (
|
||||
|
|
|
@ -9,8 +9,6 @@ import (
|
|||
|
||||
// Command and process control.
|
||||
|
||||
var ErrNotInSameGroup = errors.New("not in the same process group")
|
||||
|
||||
func init() {
|
||||
addBuiltinFns(map[string]interface{}{
|
||||
// Command resolution
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
package eval
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
|
@ -12,6 +13,10 @@ import (
|
|||
"github.com/elves/elvish/sys"
|
||||
)
|
||||
|
||||
// ErrNotInSameProcessGroup is thrown when the process IDs passed to fg are not
|
||||
// in the same process group.
|
||||
var ErrNotInSameProcessGroup = errors.New("not in the same process group")
|
||||
|
||||
func execFn(fm *Frame, args ...interface{}) error {
|
||||
var argstrings []string
|
||||
if len(args) == 0 {
|
||||
|
@ -47,7 +52,7 @@ func fg(pids ...int) error {
|
|||
if i == 0 {
|
||||
thepgid = pgid
|
||||
} else if pgid != thepgid {
|
||||
return ErrNotInSameGroup
|
||||
return ErrNotInSameProcessGroup
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -177,17 +177,16 @@ func hasKey(container, key interface{}) (bool, error) {
|
|||
// XXX(xiaq): Not all types that implement Lener have numerical indices
|
||||
_, err := vals.ConvertListIndex(key, len)
|
||||
return err == nil, nil
|
||||
} else {
|
||||
var found bool
|
||||
err := vals.IterateKeys(container, func(k interface{}) bool {
|
||||
if key == k {
|
||||
found = true
|
||||
}
|
||||
return !found
|
||||
})
|
||||
if err == nil {
|
||||
return found, nil
|
||||
}
|
||||
var found bool
|
||||
err := vals.IterateKeys(container, func(k interface{}) bool {
|
||||
if key == k {
|
||||
found = true
|
||||
}
|
||||
return !found
|
||||
})
|
||||
if err == nil {
|
||||
return found, nil
|
||||
}
|
||||
return false, fmt.Errorf("couldn't get key or index of type '%s'", vals.Kind(container))
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
// Filesystem.
|
||||
|
||||
// ErrStoreNotConnected is thrown by dir-history when the store is not connected.
|
||||
var ErrStoreNotConnected = errors.New("store not connected")
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -208,7 +208,7 @@ func toJSON(fm *Frame, inputs Inputs) error {
|
|||
func fopen(fm *Frame, name string) (vals.File, error) {
|
||||
// TODO support opening files for writing etc as well.
|
||||
f, err := os.Open(name)
|
||||
return vals.File{f}, err
|
||||
return vals.NewFile(f), err
|
||||
}
|
||||
|
||||
func fclose(f vals.File) error {
|
||||
|
@ -217,7 +217,7 @@ func fclose(f vals.File) error {
|
|||
|
||||
func pipe() (vals.Pipe, error) {
|
||||
r, w, err := os.Pipe()
|
||||
return vals.Pipe{r, w}, err
|
||||
return vals.NewPipe(r, w), err
|
||||
}
|
||||
|
||||
func prclose(p vals.Pipe) error {
|
||||
|
|
|
@ -69,14 +69,12 @@ func resolve(fm *Frame, head string) string {
|
|||
_, special := builtinSpecials[head]
|
||||
if special {
|
||||
return "special"
|
||||
} else {
|
||||
explode, ns, name := ParseVariableRef(head)
|
||||
if !explode && fm.ResolveVar(ns, name+FnSuffix) != nil {
|
||||
return "$" + head + FnSuffix
|
||||
} else {
|
||||
return "(external " + parse.Quote(head) + ")"
|
||||
}
|
||||
}
|
||||
explode, ns, name := ParseVariableRef(head)
|
||||
if !explode && fm.ResolveVar(ns, name+FnSuffix) != nil {
|
||||
return "$" + head + FnSuffix
|
||||
}
|
||||
return "(external " + parse.Quote(head) + ")"
|
||||
}
|
||||
|
||||
func source(fm *Frame, fname string) error {
|
||||
|
|
|
@ -15,7 +15,8 @@ import (
|
|||
|
||||
// String operations.
|
||||
|
||||
var ErrInput = errors.New("input error")
|
||||
// ErrInputOfEawkMustBeString is thrown when eawk gets a non-string input.
|
||||
var ErrInputOfEawkMustBeString = errors.New("input of eawk must be string")
|
||||
|
||||
func init() {
|
||||
addBuiltinFns(map[string]interface{}{
|
||||
|
@ -145,7 +146,7 @@ func eawk(fm *Frame, f Callable, inputs Inputs) error {
|
|||
line, ok := v.(string)
|
||||
if !ok {
|
||||
broken = true
|
||||
err = ErrInput
|
||||
err = ErrInputOfEawkMustBeString
|
||||
return
|
||||
}
|
||||
args := []interface{}{line}
|
||||
|
|
|
@ -427,7 +427,7 @@ func (op *ifOp) invoke(fm *Frame) error {
|
|||
for i, bodyOp := range op.bodyOps {
|
||||
bodies[i] = bodyOp.execlambdaOp(fm)
|
||||
}
|
||||
else_ := op.elseOp.execlambdaOp(fm)
|
||||
elseFn := op.elseOp.execlambdaOp(fm)
|
||||
for i, condOp := range op.condOps {
|
||||
condValues, err := condOp.exec(fm.fork("if cond"))
|
||||
if err != nil {
|
||||
|
@ -438,7 +438,7 @@ func (op *ifOp) invoke(fm *Frame) error {
|
|||
}
|
||||
}
|
||||
if op.elseOp.body != nil {
|
||||
return else_.Call(fm.fork("if else"), NoArgs, NoOpts)
|
||||
return elseFn.Call(fm.fork("if else"), NoArgs, NoOpts)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -624,7 +624,7 @@ func (op *tryOp) invoke(fm *Frame) error {
|
|||
return err
|
||||
}
|
||||
except := op.exceptOp.execlambdaOp(fm)
|
||||
else_ := op.elseOp.execlambdaOp(fm)
|
||||
elseFn := op.elseOp.execlambdaOp(fm)
|
||||
finally := op.finallyOp.execlambdaOp(fm)
|
||||
|
||||
err = fm.fork("try body").Call(body, NoArgs, NoOpts)
|
||||
|
@ -639,8 +639,8 @@ func (op *tryOp) invoke(fm *Frame) error {
|
|||
err = fm.fork("try except").Call(except, NoArgs, NoOpts)
|
||||
}
|
||||
} else {
|
||||
if else_ != nil {
|
||||
err = fm.fork("try else").Call(else_, NoArgs, NoOpts)
|
||||
if elseFn != nil {
|
||||
err = fm.fork("try else").Call(elseFn, NoArgs, NoOpts)
|
||||
}
|
||||
}
|
||||
if finally != nil {
|
||||
|
|
|
@ -16,7 +16,8 @@ import (
|
|||
// supplies does not match with what is required.
|
||||
var ErrArityMismatch = errors.New("arity mismatch")
|
||||
|
||||
// Closure is a closure defined in elvish script.
|
||||
// Closure is a closure defined in Elvish script. Each closure has its unique
|
||||
// identity.
|
||||
type Closure struct {
|
||||
ArgNames []string
|
||||
// The name for the rest argument. If empty, the function has fixed arity.
|
||||
|
@ -37,11 +38,12 @@ func (*Closure) Kind() string {
|
|||
return "fn"
|
||||
}
|
||||
|
||||
// Equal compares by identity.
|
||||
// Equal compares by address.
|
||||
func (c *Closure) Equal(rhs interface{}) bool {
|
||||
return c == rhs
|
||||
}
|
||||
|
||||
// Hash returns the hash of the address of the closure.
|
||||
func (c *Closure) Hash() uint32 {
|
||||
return hash.Pointer(unsafe.Pointer(c))
|
||||
}
|
||||
|
@ -51,6 +53,9 @@ func (c *Closure) Repr(int) string {
|
|||
return fmt.Sprintf("<closure %p>", c)
|
||||
}
|
||||
|
||||
// Index supports the introspection of the closure. Supported keys are
|
||||
// "arg-names", "rest-arg", "opt-names", "opt-defaults", "body", "def" and
|
||||
// "src".
|
||||
func (c *Closure) Index(k interface{}) (interface{}, bool) {
|
||||
switch k {
|
||||
case "arg-names":
|
||||
|
@ -71,6 +76,7 @@ func (c *Closure) Index(k interface{}) (interface{}, bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
// IterateKeys calls f with all the valid keys that can be used for Index.
|
||||
func (c *Closure) IterateKeys(f func(interface{}) bool) {
|
||||
util.Feed(f, "arg-names", "rest-arg",
|
||||
"opt-names", "opt-defaults", "body", "def", "src")
|
||||
|
|
|
@ -7,12 +7,13 @@ import (
|
|||
"github.com/elves/elvish/diag"
|
||||
)
|
||||
|
||||
// CompilationError represents a compilation error and can pretty print it.
|
||||
// CompilationError represents a compilation error. It can be pretty-printed.
|
||||
type CompilationError struct {
|
||||
Message string
|
||||
Context diag.SourceRange
|
||||
}
|
||||
|
||||
// Error returns a plain text representation of the compilation error.
|
||||
func (ce *CompilationError) Error() string {
|
||||
return fmt.Sprintf("compilation error: %d-%d in %s: %s",
|
||||
ce.Context.Begin, ce.Context.End, ce.Context.Name, ce.Message)
|
||||
|
@ -23,7 +24,7 @@ func (ce *CompilationError) Range() diag.Ranging {
|
|||
return ce.Context.Range()
|
||||
}
|
||||
|
||||
// PPrint pretty-prints a compilation error.
|
||||
// PPrint pretty-prints the compilation error.
|
||||
func (ce *CompilationError) PPrint(indent string) string {
|
||||
var buf bytes.Buffer
|
||||
|
||||
|
|
|
@ -134,10 +134,9 @@ func (op *pipelineOp) invoke(fm *Frame) error {
|
|||
}
|
||||
}()
|
||||
return nil
|
||||
} else {
|
||||
wg.Wait()
|
||||
return ComposeExceptionsFromPipeline(errors)
|
||||
}
|
||||
wg.Wait()
|
||||
return ComposeExceptionsFromPipeline(errors)
|
||||
}
|
||||
|
||||
func (cp *compiler) form(n *parse.Form) effectOpBody {
|
||||
|
@ -344,9 +343,8 @@ func (op *formOp) invoke(fm *Frame) (errRet error) {
|
|||
|
||||
if headFn != nil {
|
||||
return headFn.Call(fm, args, convertedOpts)
|
||||
} else {
|
||||
return op.spaceyAssignOp.exec(fm)
|
||||
}
|
||||
return op.spaceyAssignOp.exec(fm)
|
||||
}
|
||||
|
||||
func allTrue(vs []interface{}) bool {
|
||||
|
|
|
@ -175,9 +175,8 @@ func (op *elemOp) invoke(fm *Frame) ([]vars.Var, error) {
|
|||
level := vars.ElementErrorLevel(err)
|
||||
if level < 0 {
|
||||
return nil, fm.errorpf(op.begin, op.end, "%s", err)
|
||||
} else {
|
||||
return nil, fm.errorpf(op.begin, op.ends[level], "%s", err)
|
||||
}
|
||||
return nil, fm.errorpf(op.begin, op.ends[level], "%s", err)
|
||||
}
|
||||
return []vars.Var{elemVar}, nil
|
||||
}
|
||||
|
|
|
@ -35,10 +35,12 @@ func Cause(err error) error {
|
|||
// exception.
|
||||
var OK = &Exception{}
|
||||
|
||||
// Error returns the message of the cause of the exception.
|
||||
func (exc *Exception) Error() string {
|
||||
return exc.Cause.Error()
|
||||
}
|
||||
|
||||
// PPrint pretty-prints the exception.
|
||||
func (exc *Exception) PPrint(indent string) string {
|
||||
buf := new(bytes.Buffer)
|
||||
|
||||
|
@ -73,10 +75,13 @@ func (exc *Exception) PPrint(indent string) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// Kind returns "exception".
|
||||
func (exc *Exception) Kind() string {
|
||||
return "exception"
|
||||
}
|
||||
|
||||
// Repr returns a representation of the exception. It is lossy in that it does
|
||||
// not preserve the stacktrace.
|
||||
func (exc *Exception) Repr(indent int) string {
|
||||
if exc.Cause == nil {
|
||||
return "$ok"
|
||||
|
@ -87,19 +92,23 @@ func (exc *Exception) Repr(indent int) string {
|
|||
return "?(fail " + parse.Quote(exc.Cause.Error()) + ")"
|
||||
}
|
||||
|
||||
// Equal compares by identity.
|
||||
// Equal compares by address.
|
||||
func (exc *Exception) Equal(rhs interface{}) bool {
|
||||
return exc == rhs
|
||||
}
|
||||
|
||||
// Hash returns the hash of the address.
|
||||
func (exc *Exception) Hash() uint32 {
|
||||
return hash.Pointer(unsafe.Pointer(exc))
|
||||
}
|
||||
|
||||
// Bool returns whether this exception has a nil cause; that is, it is $ok.
|
||||
func (exc *Exception) Bool() bool {
|
||||
return exc.Cause == nil
|
||||
}
|
||||
|
||||
// Index supports introspection of the exception. Currently the only supported
|
||||
// key is "cause".
|
||||
func (exc *Exception) Index(k interface{}) (interface{}, bool) {
|
||||
// TODO: Access to Traceback
|
||||
switch k {
|
||||
|
@ -110,6 +119,7 @@ func (exc *Exception) Index(k interface{}) (interface{}, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// IterateKeys calls f with all the valid keys that can be used in Index.
|
||||
func (exc *Exception) IterateKeys(f func(interface{}) bool) {
|
||||
util.Feed(f, "cause")
|
||||
}
|
||||
|
@ -120,6 +130,7 @@ type PipelineError struct {
|
|||
Errors []*Exception
|
||||
}
|
||||
|
||||
// Repr returns a representation of the pipeline error, using the multi-error builtin.
|
||||
func (pe PipelineError) Repr(indent int) string {
|
||||
// TODO Make a more generalized ListReprBuilder and use it here.
|
||||
b := new(bytes.Buffer)
|
||||
|
@ -137,6 +148,7 @@ func (pe PipelineError) Repr(indent int) string {
|
|||
return b.String()
|
||||
}
|
||||
|
||||
// Error returns a plain text representation of the pipeline error.
|
||||
func (pe PipelineError) Error() string {
|
||||
b := new(bytes.Buffer)
|
||||
b.WriteString("(")
|
||||
|
@ -197,6 +209,7 @@ var flowNames = [...]string{
|
|||
"return", "break", "continue",
|
||||
}
|
||||
|
||||
// Repr returns a representation of the flow "error".
|
||||
func (f Flow) Repr(int) string {
|
||||
return "?(" + f.Error() + ")"
|
||||
}
|
||||
|
@ -208,6 +221,7 @@ func (f Flow) Error() string {
|
|||
return flowNames[f]
|
||||
}
|
||||
|
||||
// PPrint pretty-prints the flow "error".
|
||||
func (f Flow) PPrint(string) string {
|
||||
return "\033[33;1m" + f.Error() + "\033[m"
|
||||
}
|
||||
|
@ -221,6 +235,8 @@ type ExternalCmdExit struct {
|
|||
Pid int
|
||||
}
|
||||
|
||||
// NewExternalCmdExit constructs an error for representing a non-zero exit from
|
||||
// an external command.
|
||||
func NewExternalCmdExit(name string, ws syscall.WaitStatus, pid int) error {
|
||||
if ws.Exited() && ws.ExitStatus() == 0 {
|
||||
return nil
|
||||
|
|
|
@ -14,8 +14,13 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
// ErrExternalCmdOpts is thrown when an external command is passed Elvish
|
||||
// options.
|
||||
//
|
||||
// TODO: Catch this kind of errors at compilation time.
|
||||
ErrExternalCmdOpts = errors.New("external commands don't accept elvish options")
|
||||
ErrCdNoArg = errors.New("implicit cd accepts no arguments")
|
||||
// ErrImplicitCdNoArg is thrown when an implicit cd form is passed arguments.
|
||||
ErrImplicitCdNoArg = errors.New("implicit cd accepts no arguments")
|
||||
)
|
||||
|
||||
// ExternalCmd is an external command.
|
||||
|
@ -49,7 +54,7 @@ func (e ExternalCmd) Call(fm *Frame, argVals []interface{}, opts map[string]inte
|
|||
if err == nil && stat.IsDir() {
|
||||
// implicit cd
|
||||
if len(argVals) > 0 {
|
||||
return ErrCdNoArg
|
||||
return ErrImplicitCdNoArg
|
||||
}
|
||||
return fm.Chdir(e.Name)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ func (fm *Frame) Interrupts() <-chan struct{} {
|
|||
return fm.intCh
|
||||
}
|
||||
|
||||
// ErrInterrupted is thrown when the execution is interrupted by a signal.
|
||||
var ErrInterrupted = errors.New("interrupted")
|
||||
|
||||
// IsInterrupted reports whether there has been an interrupt.
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"github.com/elves/elvish/util"
|
||||
)
|
||||
|
||||
// RawOptions is the type of an argument a builtin function can take to declare
|
||||
// that it wants to parse options itself. See the doc of BuiltinFn for details.
|
||||
type RawOptions map[string]interface{}
|
||||
|
||||
// Takes a raw option map and a pointer to a struct, and populate the struct
|
||||
|
|
|
@ -38,7 +38,7 @@ var (
|
|||
BlackholeChan = make(chan interface{})
|
||||
// DevNull is /dev/null.
|
||||
DevNull *os.File
|
||||
// DevNullClosedInput is a port made up from DevNull and ClosedChan,
|
||||
// DevNullClosedChan is a port made up from DevNull and ClosedChan,
|
||||
// suitable as placeholder input port.
|
||||
DevNullClosedChan *Port
|
||||
)
|
||||
|
|
|
@ -5,12 +5,13 @@ import "syscall"
|
|||
// Nop on Windows.
|
||||
func putSelfInFg() error { return nil }
|
||||
|
||||
const DETACHED_PROCESS = 0x00000008
|
||||
// The bitmask for CreationFlags in SysProcAttr to start a process in background.
|
||||
const detachedProcess = 0x00000008
|
||||
|
||||
func makeSysProcAttr(bg bool) *syscall.SysProcAttr {
|
||||
flags := uint32(0)
|
||||
if bg {
|
||||
flags |= DETACHED_PROCESS
|
||||
flags |= detachedProcess
|
||||
}
|
||||
return &syscall.SysProcAttr{CreationFlags: flags}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ type PwdVariable struct {
|
|||
|
||||
var _ vars.Var = PwdVariable{}
|
||||
|
||||
// Get returns the current working directory. It returns /unknown/pwd when it
|
||||
// cannot be determined.
|
||||
func (PwdVariable) Get() interface{} {
|
||||
pwd, err := os.Getwd()
|
||||
// TODO: Deprecate the $pwd variable.
|
||||
|
@ -23,6 +25,7 @@ func (PwdVariable) Get() interface{} {
|
|||
return pwd
|
||||
}
|
||||
|
||||
// Set changes the current working directory.
|
||||
func (pwd PwdVariable) Set(v interface{}) error {
|
||||
path, ok := v.(string)
|
||||
if !ok {
|
||||
|
|
|
@ -69,8 +69,8 @@ func (t TestCase) Puts(vs ...interface{}) TestCase {
|
|||
return t
|
||||
}
|
||||
|
||||
// Puts returns an altered Test that requires the source code to produce the
|
||||
// specified strings in the value channel when evaluated.
|
||||
// PutsStrings returns an altered Test that requires the source code to produce
|
||||
// the specified strings in the value channel when evaluated.
|
||||
func (t TestCase) PutsStrings(ss []string) TestCase {
|
||||
t.want.out = make([]interface{}, len(ss))
|
||||
for i, s := range ss {
|
||||
|
@ -105,8 +105,8 @@ func Test(t *testing.T, tests ...TestCase) {
|
|||
TestWithSetup(t, func(*Evaler) {}, tests...)
|
||||
}
|
||||
|
||||
// Test runs test cases. For each test case, a new Evaler is created with
|
||||
// NewEvaler and passed to the setup function.
|
||||
// TestWithSetup runs test cases. For each test case, a new Evaler is created
|
||||
// with NewEvaler and passed to the setup function.
|
||||
func TestWithSetup(t *testing.T, setup func(*Evaler), tests ...TestCase) {
|
||||
for _, tt := range tests {
|
||||
ev := NewEvaler()
|
||||
|
|
Loading…
Reference in New Issue
Block a user