Minor fixups for #1273.

Also fix a test broken by bad merge.
This commit is contained in:
Qi Xiao 2021-05-02 00:13:22 +01:00
parent 2f4a259091
commit 7b66e9f104
4 changed files with 11 additions and 7 deletions

View File

@ -134,7 +134,7 @@ func TestCommand_Assignment(t *testing.T) {
That("a true b = 1 2 3").Throws(errs.SetReadOnlyVar{VarName: "true"}, "true"),
That("@true = 1").Throws(errs.SetReadOnlyVar{VarName: "@true"}, "@true"),
// A readonly var as a target for the `except` clause should error.
That("try { fail reason } except nil { }").Throws(vars.ErrSetReadOnlyVar, "nil"),
That("try { fail reason } except nil { }").Throws(errs.SetReadOnlyVar{VarName: "nil"}, "nil"),
That("try { fail reason } except x { }").DoesNothing(),
// Evaluation of the assignability occurs at run-time so, if no exception is raised, this
// otherwise invalid use of `nil` is okay.

View File

@ -1,4 +1,4 @@
// Package errs declares Elvish error types that are not simple strings (i.e., the Go `error` type).
// Package errs declares error types used as exception causes.
package errs
import (
@ -14,6 +14,7 @@ type OutOfRange struct {
Actual string
}
// Error implements the error interface.
func (e OutOfRange) Error() string {
if e.ValidHigh < e.ValidLow {
return fmt.Sprintf(
@ -32,6 +33,7 @@ type BadValue struct {
Actual string
}
// Error implements the error interface.
func (e BadValue) Error() string {
return fmt.Sprintf(
"bad value: %v must be %v, but is %v", e.What, e.Valid, e.Actual)
@ -69,9 +71,12 @@ func nValues(n int) string {
// SetReadOnlyVar is returned by the Set method of a read-only variable.
type SetReadOnlyVar struct {
// Name of the read-only variable. This fiels is initially empty, and
// populated later when context information is available.
VarName string
}
// Error implements the error interface.
func (e SetReadOnlyVar) Error() string {
return fmt.Sprintf("cannot set read-only variable %q", e.VarName)
}

View File

@ -211,12 +211,11 @@ func (fm *Frame) errorp(r diag.Ranger, e error) Exception {
return nil
case Exception:
return e
case errs.SetReadOnlyVar:
ctx := diag.NewContext(fm.srcMeta.Name, fm.srcMeta.Code, r)
e.VarName = ctx.RelevantString()
return &exception{e, &StackTrace{Head: ctx, Next: fm.traceback}}
default:
ctx := diag.NewContext(fm.srcMeta.Name, fm.srcMeta.Code, r)
if _, ok := e.(errs.SetReadOnlyVar); ok {
e = errs.SetReadOnlyVar{VarName: ctx.RelevantString()}
}
return &exception{e, &StackTrace{Head: ctx, Next: fm.traceback}}
}
}

View File

@ -26,6 +26,6 @@ func TestNs(t *testing.T) {
func TestBuiltinFunctionsReadOnly(t *testing.T) {
Test(t,
That("return~ = { }").Throws(ErrorWithType(errs.SetReadOnlyVar{}), "return~"),
That("return~ = { }").Throws(errs.SetReadOnlyVar{VarName: "return~"}, "return~"),
)
}