mirror of
https://github.com/go-sylixos/elvish.git
synced 2024-12-12 17:27:50 +08:00
pkg/eval: Move implementation of compile-time deprecation to compiler.go.
This commit is contained in:
parent
47d9766f5c
commit
fbfbef8531
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/elves/elvish/pkg/diag"
|
||||
"github.com/elves/elvish/pkg/eval/vars"
|
||||
"github.com/elves/elvish/pkg/parse"
|
||||
"github.com/elves/elvish/pkg/prog"
|
||||
)
|
||||
|
||||
// compiler maintains the set of states needed when compiling a single source
|
||||
|
@ -124,3 +125,53 @@ func (cp *compiler) popScope() {
|
|||
cp.captures[len(cp.captures)-1] = nil
|
||||
cp.captures = cp.captures[:len(cp.captures)-1]
|
||||
}
|
||||
|
||||
func (cp *compiler) checkDeprecatedBuiltin(name string, r diag.Ranger) {
|
||||
msg := ""
|
||||
minLevel := 15
|
||||
switch name {
|
||||
case "-source~":
|
||||
msg = `the "source" command is deprecated; use "eval" instead`
|
||||
case "ord~":
|
||||
msg = `the "ord" command is deprecated; use "str:to-codepoints" instead`
|
||||
case "chr~":
|
||||
msg = `the "chr" command is deprecated; use "str:from-codepoints" instead`
|
||||
case "has-prefix~":
|
||||
msg = `the "has-prefix" command is deprecated; use "str:has-prefix" instead`
|
||||
case "has-suffix~":
|
||||
msg = `the "has-suffix" command is deprecated; use "str:has-suffix" instead`
|
||||
case "esleep~":
|
||||
msg = `the "esleep" command is deprecated; use "sleep" instead`
|
||||
case "eval-symlinks~":
|
||||
msg = `the "eval-symlinks" command is deprecated; use "path:eval-symlinks" instead`
|
||||
case "path-abs~":
|
||||
msg = `the "path-abs" command is deprecated; use "path:abs" instead`
|
||||
case "path-base~":
|
||||
msg = `the "path-base" command is deprecated; use "path:base" instead`
|
||||
case "path-clean~":
|
||||
msg = `the "path-clean" command is deprecated; use "path:clean" instead`
|
||||
case "path-dir~":
|
||||
msg = `the "path-dir" command is deprecated; use "path:dir" instead`
|
||||
case "path-ext~":
|
||||
msg = `the "path-ext" command is deprecated; use "path:ext" instead`
|
||||
case "-is-dir~":
|
||||
msg = `the "-is-dir" command is deprecated; use "path:is-dir" instead`
|
||||
default:
|
||||
return
|
||||
}
|
||||
cp.deprecate(r, msg, minLevel)
|
||||
}
|
||||
|
||||
func (cp *compiler) deprecate(r diag.Ranger, msg string, minLevel int) {
|
||||
if cp.warn == nil || r == nil {
|
||||
return
|
||||
}
|
||||
dep := deprecation{cp.srcMeta.Name, r.Range(), msg}
|
||||
if prog.DeprecationLevel >= minLevel && cp.deprecations.register(dep) {
|
||||
err := diag.Error{
|
||||
Type: "deprecation", Message: msg,
|
||||
Context: diag.Context{
|
||||
Name: cp.srcMeta.Name, Source: cp.srcMeta.Code, Ranging: r.Range()}}
|
||||
fmt.Fprintln(cp.warn, err.Show(""))
|
||||
}
|
||||
}
|
||||
|
|
38
pkg/eval/compiler_test.go
Normal file
38
pkg/eval/compiler_test.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package eval_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/elves/elvish/pkg/eval"
|
||||
"github.com/elves/elvish/pkg/parse"
|
||||
"github.com/elves/elvish/pkg/prog"
|
||||
)
|
||||
|
||||
func TestDeprecatedBuiltin(t *testing.T) {
|
||||
testCompileTimeDeprecation(t, "ord a", `the "ord" command is deprecated`, 15)
|
||||
// Deprecations of other builtins are implemented in the same way, so we
|
||||
// don't test them repeatedly
|
||||
}
|
||||
|
||||
func testCompileTimeDeprecation(t *testing.T, code, wantWarning string, level int) {
|
||||
restore := prog.SetDeprecationLevel(level)
|
||||
defer restore()
|
||||
|
||||
ev := NewEvaler()
|
||||
errOutput := new(bytes.Buffer)
|
||||
|
||||
parseErr, compileErr := ev.Check(parse.Source{Code: code}, errOutput)
|
||||
if parseErr != nil {
|
||||
t.Errorf("got parse err %v", parseErr)
|
||||
}
|
||||
if compileErr != nil {
|
||||
t.Errorf("got compile err %v", compileErr)
|
||||
}
|
||||
|
||||
warning := errOutput.String()
|
||||
if !strings.Contains(warning, wantWarning) {
|
||||
t.Errorf("got warning %q, want warning containing %q", warning, wantWarning)
|
||||
}
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
package eval_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"testing"
|
||||
|
@ -57,28 +55,6 @@ func TestEvalTimeDeprecate(t *testing.T) {
|
|||
)
|
||||
}
|
||||
|
||||
func TestCompileTimeDeprecation(t *testing.T) {
|
||||
restore := prog.SetDeprecationLevel(15)
|
||||
defer restore()
|
||||
|
||||
ev := NewEvaler()
|
||||
errOutput := new(bytes.Buffer)
|
||||
|
||||
parseErr, compileErr := ev.Check(parse.Source{Code: "ord a"}, errOutput)
|
||||
if parseErr != nil {
|
||||
t.Errorf("got parse err %v", parseErr)
|
||||
}
|
||||
if compileErr != nil {
|
||||
t.Errorf("got compile err %v", compileErr)
|
||||
}
|
||||
|
||||
warning := errOutput.String()
|
||||
wantWarning := `the "ord" command is deprecated`
|
||||
if !strings.Contains(warning, wantWarning) {
|
||||
t.Errorf("got warning %q, want warning containing %q", warning, wantWarning)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleEval(t *testing.T) {
|
||||
Test(t,
|
||||
That("x = hello").Then("put $x").Puts("hello"),
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package eval
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/elves/elvish/pkg/diag"
|
||||
"github.com/elves/elvish/pkg/eval/vars"
|
||||
"github.com/elves/elvish/pkg/prog"
|
||||
)
|
||||
|
||||
// This file implements variable resolution. Elvish has fully static lexical
|
||||
|
@ -187,52 +185,6 @@ func (cp *compiler) searchBuiltin(k string, r diag.Ranger) int {
|
|||
return index
|
||||
}
|
||||
|
||||
func (cp *compiler) checkDeprecatedBuiltin(name string, r diag.Ranger) {
|
||||
if cp.warn == nil || r == nil {
|
||||
return
|
||||
}
|
||||
msg := ""
|
||||
minLevel := 15
|
||||
switch name {
|
||||
case "-source~":
|
||||
msg = `the "source" command is deprecated; use "eval" instead`
|
||||
case "ord~":
|
||||
msg = `the "ord" command is deprecated; use "str:to-codepoints" instead`
|
||||
case "chr~":
|
||||
msg = `the "chr" command is deprecated; use "str:from-codepoints" instead`
|
||||
case "has-prefix~":
|
||||
msg = `the "has-prefix" command is deprecated; use "str:has-prefix" instead`
|
||||
case "has-suffix~":
|
||||
msg = `the "has-suffix" command is deprecated; use "str:has-suffix" instead`
|
||||
case "esleep~":
|
||||
msg = `the "esleep" command is deprecated; use "sleep" instead`
|
||||
case "eval-symlinks~":
|
||||
msg = `the "eval-symlinks" command is deprecated; use "path:eval-symlinks" instead`
|
||||
case "path-abs~":
|
||||
msg = `the "path-abs" command is deprecated; use "path:abs" instead`
|
||||
case "path-base~":
|
||||
msg = `the "path-base" command is deprecated; use "path:base" instead`
|
||||
case "path-clean~":
|
||||
msg = `the "path-clean" command is deprecated; use "path:clean" instead`
|
||||
case "path-dir~":
|
||||
msg = `the "path-dir" command is deprecated; use "path:dir" instead`
|
||||
case "path-ext~":
|
||||
msg = `the "path-ext" command is deprecated; use "path:ext" instead`
|
||||
case "-is-dir~":
|
||||
msg = `the "-is-dir" command is deprecated; use "path:is-dir" instead`
|
||||
default:
|
||||
return
|
||||
}
|
||||
dep := deprecation{cp.srcMeta.Name, r.Range(), msg}
|
||||
if prog.DeprecationLevel >= minLevel && cp.deprecations.register(dep) {
|
||||
err := diag.Error{
|
||||
Type: "deprecation", Message: msg,
|
||||
Context: diag.Context{
|
||||
Name: cp.srcMeta.Name, Source: cp.srcMeta.Code, Ranging: r.Range()}}
|
||||
fmt.Fprintln(cp.warn, err.Show(""))
|
||||
}
|
||||
}
|
||||
|
||||
func (fm *Frame) searchLocal(k string) int {
|
||||
return fm.local.lookup(k)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user