Skip to content

Commit

Permalink
[oil-language] Turn off bare assignment (parse_equals) by default
Browse files Browse the repository at this point in the history
This addresses #937, which was also noted by a user.

Bare assignment like 'x = 42' was equivalent to 'const x = 42'.

However this causes inconsistency in programs.  We only want bare
assignment for config dialects like:

    server www.example.com {
      root = '/'
      port = 8080
    }

On the other hand we don't want

    proc p {
      const x = 42
      y = 43  # inconsistent
    }

Also add a failing test for bare assignment in blocks.  This is another
issue -- some blocks will introduce a new scope, and some won't.

So we don't want the static check for 'const already defined in scope'.
Instead bare assignment will only do DYNAMIC checks (similar to the top
level), and 'const' will do STATIC checks.
  • Loading branch information
Andy C committed Apr 30, 2022
1 parent 10fefce commit 9fe9583
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 12 deletions.
8 changes: 6 additions & 2 deletions frontend/option_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,11 @@ def DoneWithImplementedOptions(self):

# Extra stuff that breaks too many programs.
_AGGRESSIVE_PARSE_OPTIONS = [
('parse_equals', False), # x = 'var'
('parse_at_all', False), # @ starting any word, e.g. @[] @{} @@ @_ @-

# Legacy syntax that is removed
# Legacy syntax that is removed. These options are distinct from strict_*
# because they don't help you avoid bugs in bash programs. They just makes
# the language more consistent.
('parse_backslash', True),
('parse_backticks', True),
('parse_dollar', True),
Expand Down Expand Up @@ -301,6 +302,9 @@ def _Init(opt_def):
for name, default in _AGGRESSIVE_RUNTIME_OPTIONS:
opt_def.Add(name, default=default, groups=['oil:all'])

# For configuration files. bin/oven?
opt_def.Add('parse_equals')

# Off by default.
opt_def.Add('parse_tea')

Expand Down
1 change: 1 addition & 0 deletions osh/cmd_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,7 @@ def ParseCommand(self):
# NOTE: tok.id should be Lit_Chars, but that check is redundant
if (match.IsValidVarName(tok.val) and
self.w_parser.LookPastSpace() == Id.Lit_Equals):
# bare declaration is equivalent to 'const'
self.var_checker.Check(Id.KW_Const, tok)

enode = self.w_parser.ParseBareDecl()
Expand Down
12 changes: 8 additions & 4 deletions spec/oil-assign.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ proc f {
## END

#### top-level dynamic check: const can't be be mutated
shopt -s oil:all
shopt -s oil:all parse_equals

x = 'foo'
echo x=$x
Expand Down Expand Up @@ -215,7 +215,7 @@ write --sep ' ' @mylist
## END

#### mixing assignment builtins and Oil assignment
shopt -s oil:all
shopt -s oil:all parse_equals

proc local-var {
local x=1
Expand Down Expand Up @@ -309,7 +309,11 @@ setvar L[0] = L
## END


#### exit code of var, const, setvar
#### exit code of var, const, setvar with command sub

# NOTE: This feels PROBLEMATIC without command_sub_errexit feels like it should
# be the last one ...

var x = $(false)
echo x=$x status=$?

Expand All @@ -322,5 +326,5 @@ echo y=$y status=$?
## STDOUT:
x= status=1
x=/42 status=1
x=/43/44 status=1
y=/43/44 status=1
## END
33 changes: 33 additions & 0 deletions spec/oil-blocks.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,36 @@ command echo 2
builtin echo 2
pushd 2
## END

#### Block with Bare Assignments

# oil:all has parse_equals
# is there any way to turn on parse_equals only in config blocks?
# but we don't know what's a block ahead of time
# I think we would have to check at runtime. Look at VarChecker

shopt --set oil:all

proc rule(s, b Block) {
echo "rule $s"
}

proc myrules(name) {
rule $name-python {
kind = 'python'
}

rule $name-cc {
kind = 'cc' # should NOT conflict
}
}

myrules foo
myrules bar

## STDOUT:
rule foo-python
rule foo-cc
rule bar-ypthon
rule bar-cc
## END
2 changes: 1 addition & 1 deletion spec/oil-keywords.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ _ append(strs, 'c')
write -- @strs

# integer types too
L = [5, 6]
const L = [5, 6]
_ append(L, 7)
write -- @L

Expand Down
6 changes: 3 additions & 3 deletions spec/oil-options.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -503,21 +503,21 @@ k2
## END

#### parse_equals: allows bare assignment
shopt -s oil:all # including nice options
shopt -s parse_equals
x = 1 + 2*3
echo $x
## STDOUT:
7
## END

#### parse_equals: disallows ENV=val mycommand
shopt -s oil:all
shopt -s parse_equals
ENV=val echo hi
## status: 2
## stdout-json: ""

#### parse_equals: disallows var=val
shopt -s oil:all
shopt -s parse_equals
var=val
## status: 2
## stdout-json: ""
Expand Down
2 changes: 1 addition & 1 deletion spec/oil-regex.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ echo $pat
# octdigit ::= "0"..."7"
# hexdigit ::= digit | "a"..."f" | "A"..."F"
shopt -s oil:all
shopt -s oil:all parse_equals # Hm will need 'const'
DecDigit = / [0-9] /
BinDigit = / [0-1] /
Expand Down
2 changes: 1 addition & 1 deletion test/spec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -889,7 +889,7 @@ oil-assign() {
}

oil-blocks() {
sh-spec spec/oil-blocks.test.sh --osh-failures-allowed 2 \
sh-spec spec/oil-blocks.test.sh --osh-failures-allowed 3 \
$OSH_LIST "$@"
}

Expand Down

0 comments on commit 9fe9583

Please sign in to comment.