diff --git a/pkg/edit/completion_test.go b/pkg/edit/completion_test.go index 245d7c2a..96165846 100644 --- a/pkg/edit/completion_test.go +++ b/pkg/edit/completion_test.go @@ -7,7 +7,6 @@ import ( "github.com/elves/elvish/pkg/eval" . "github.com/elves/elvish/pkg/eval/evaltest" "github.com/elves/elvish/pkg/eval/vals" - "github.com/elves/elvish/pkg/prog" "github.com/elves/elvish/pkg/testutil" ) @@ -63,9 +62,6 @@ func TestCompleteFilename(t *testing.T) { } func TestComplexCandidate(t *testing.T) { - restore := prog.SetShowDeprecations(true) - defer restore() - TestWithSetup(t, func(ev *eval.Evaler) { ev.AddGlobal(eval.NsBuilder{}.AddGoFn("", "cc", complexCandidate).Ns()) }, diff --git a/pkg/eval/builtin_special_test.go b/pkg/eval/builtin_special_test.go index 44889cf4..5126db62 100644 --- a/pkg/eval/builtin_special_test.go +++ b/pkg/eval/builtin_special_test.go @@ -273,7 +273,7 @@ func TestUse(t *testing.T) { // Regression test for #1072 func TestUse_WarnsAboutDeprecatedFeatures(t *testing.T) { - restore := prog.SetShowDeprecations(true) + restore := prog.SetDeprecationLevel(15) defer restore() libdir, cleanup := testutil.InTestDir() defer cleanup() diff --git a/pkg/eval/compile_value.go b/pkg/eval/compile_value.go index eac141d6..d2714fb2 100644 --- a/pkg/eval/compile_value.go +++ b/pkg/eval/compile_value.go @@ -245,9 +245,10 @@ func (op *indexingOp) exec(fm *Frame) ([]interface{}, Exception) { if err != nil { return nil, fm.errorp(op, err) } + // Check the legacy low:high slice syntax deprecated since 0.15. deprecation := vals.CheckDeprecatedIndex(v, index) if deprecation != "" { - fm.Deprecate(deprecation, diag.NewContext(fm.srcMeta.Name, fm.srcMeta.Code, indexOp)) + fm.Deprecate(deprecation, indexOp, 15) } newvs = append(newvs, result) } diff --git a/pkg/eval/eval_test.go b/pkg/eval/eval_test.go index 5c1218cb..1e6d13d1 100644 --- a/pkg/eval/eval_test.go +++ b/pkg/eval/eval_test.go @@ -41,14 +41,14 @@ func TestArgs(t *testing.T) { } func TestEvalTimeDeprecate(t *testing.T) { - restore := prog.SetShowDeprecations(true) + restore := prog.SetDeprecationLevel(42) defer restore() _, cleanup := testutil.InTestDir() defer cleanup() TestWithSetup(t, func(ev *Evaler) { ev.AddGlobal(NsBuilder{}.AddGoFn("", "dep", func(fm *Frame) { - fm.Deprecate("deprecated", nil) + fm.Deprecate("deprecated", nil, 42) }).Ns()) }, That("dep").PrintsStderrWith("deprecated"), @@ -58,7 +58,7 @@ func TestEvalTimeDeprecate(t *testing.T) { } func TestCompileTimeDeprecation(t *testing.T) { - restore := prog.SetShowDeprecations(true) + restore := prog.SetDeprecationLevel(15) defer restore() ev := NewEvaler() diff --git a/pkg/eval/frame.go b/pkg/eval/frame.go index 310f3720..b1a29a4f 100644 --- a/pkg/eval/frame.go +++ b/pkg/eval/frame.go @@ -209,12 +209,15 @@ func (fm *Frame) errorpf(r diag.Ranger, format string, args ...interface{}) Exce // Deprecate shows a deprecation message. The message is not shown if the same // deprecation message has been shown for the same location before. -func (fm *Frame) Deprecate(msg string, ctx *diag.Context) { - if ctx == nil { +func (fm *Frame) Deprecate(msg string, r diag.Ranger, minLevel int) { + var ctx *diag.Context + if r == nil { ctx = fm.traceback.Head + } else { + ctx = diag.NewContext(fm.srcMeta.Name, fm.srcMeta.Code, r) } dep := deprecation{ctx.Name, ctx.Ranging, msg} - if prog.ShowDeprecations && fm.Evaler.registerDeprecation(dep) { + if prog.DeprecationLevel >= minLevel && fm.Evaler.registerDeprecation(dep) { err := diag.Error{ Type: "deprecation", Message: dep.message, Context: *ctx} fm.ErrorFile().WriteString(err.Show("") + "\n") diff --git a/pkg/eval/var_ref.go b/pkg/eval/var_ref.go index cf7cff2e..4d856a92 100644 --- a/pkg/eval/var_ref.go +++ b/pkg/eval/var_ref.go @@ -192,6 +192,7 @@ func (cp *compiler) checkDeprecatedBuiltin(name string, r diag.Ranger) { return } msg := "" + minLevel := 15 switch name { case "-source~": msg = `the "source" command is deprecated; use "eval" instead` @@ -223,7 +224,7 @@ func (cp *compiler) checkDeprecatedBuiltin(name string, r diag.Ranger) { return } dep := deprecation{cp.srcMeta.Name, r.Range(), msg} - if prog.ShowDeprecations && cp.deprecations.register(dep) { + if prog.DeprecationLevel >= minLevel && cp.deprecations.register(dep) { err := diag.Error{ Type: "deprecation", Message: msg, Context: diag.Context{ diff --git a/pkg/prog/prog.go b/pkg/prog/prog.go index b7682cb8..0cc0b20e 100644 --- a/pkg/prog/prog.go +++ b/pkg/prog/prog.go @@ -20,15 +20,17 @@ import ( // resembles "elvi". const defaultWebPort = 3171 -// ShowDeprecations is a global flag that controls whether to show deprecations. -var ShowDeprecations = false +// DeprecationLevel is a global flag that controls which deprecations to show. +// If its value is X, Elvish shows deprecations that should be shown for version +// 0.X. +var DeprecationLevel = 14 -// SetShowDeprecations sets ShowDeprecations to the given value, and returns a +// SetDeprecationLevel sets ShowDeprecations to the given value, and returns a // function to restore the old value. -func SetShowDeprecations(b bool) func() { - save := ShowDeprecations - ShowDeprecations = b - return func() { ShowDeprecations = save } +func SetDeprecationLevel(level int) func() { + save := DeprecationLevel + DeprecationLevel = level + return func() { DeprecationLevel = save } } // Flags keeps command-line flags. @@ -74,7 +76,7 @@ func newFlagSet(stderr io.Writer, f *Flags) *flag.FlagSet { fs.StringVar(&f.DB, "db", "", "path to the database") fs.StringVar(&f.Sock, "sock", "", "path to the daemon socket") - fs.BoolVar(&ShowDeprecations, "show-deprecations", ShowDeprecations, "whether to show deprecations") + fs.IntVar(&DeprecationLevel, "deprecation-level", DeprecationLevel, "show warnings for all features deprecated as of version 0.X") return fs } diff --git a/pkg/prog/prog_test.go b/pkg/prog/prog_test.go index 23ee08cf..270c4752 100644 --- a/pkg/prog/prog_test.go +++ b/pkg/prog/prog_test.go @@ -50,14 +50,14 @@ func TestHelp(t *testing.T) { } func TestShowDeprecations(t *testing.T) { - restore := SetShowDeprecations(false) + restore := SetDeprecationLevel(0) defer restore() f := Setup() defer f.Cleanup() - Run(f.Fds(), Elvish("-show-deprecations"), testProgram{shouldRun: true}) - if !ShowDeprecations { - t.Errorf("ShowDeprecations = false, want true") + Run(f.Fds(), Elvish("-deprecation-level", "42"), testProgram{shouldRun: true}) + if DeprecationLevel != 42 { + t.Errorf("ShowDeprecations = %d, want 42", DeprecationLevel) } }