Open Bilge opened 1 year ago
It's complicated with Bash...
man bash
says:
Indexed arrays are referenced using integers (including arithmetic expressions) and are zero-based; associative arrays are referenced using arbitrary strings. Unless otherwise noted, indexed array indices must be non-negative integers.
That means that the type of the key and how it's interpreted is runtime behavior. Keys are currently parsed as arithmetic expressions, i.e. the parser assumes an indexed array. Unfortunately it's not possible to track the type of array in the parser.
For the current version of BashSupport Pro (3.x), I recommend the workaround to use a string key:
local -A foo=(["bar baz"]=bat)
echo "${foo["bar baz"]}"
I'll try to find a better way to handle this for the next major version. I could be possible to not show an error for array keys, but that might be too much if it's actually an indexed array :( Please let me know what you'd expect as a developer here. Thanks!
Here's an example:
a=1
b=2
declare -a plainArray=()
declare -A assocArray=()
plainArray[a + b]="value"
assocArray[a + b]="value"
declare -p plainArray assocArray
prints this:
declare -a plainArray=([3]="value")
declare -A assocArray=(["a + b"]="value" )
Unfortunately it's not possible to track the type of array in the parser.
Why is that the case? Although (indexed) arrays can be declared implicitly with foo=()
, one cannot possibly create an associative array without either delcare -A
or local -A
, and arrays cannot be passed around, so it has to be explicitly declared in the current scope.
There‘s a separation of lexing/parsing (i.e. the text-based syntax analysis) and the semantic analysis (e.g. „unused variable“, tracking of variable flags), which happens based on the parsed syntax tree.
Even with the semantic analysis, flag „associative array“ can‘t be reliably tracked, e.g. for declarations which are nested in conditional commands or access to global array variables in functions, which could be called from any context.
static analysis of syntax, which relies on runtime information, isn‘t possible in a reliable way. I hope to find good enough solution to accept most values with whitespace.
most likely shfmt and ShellCheck have their own workarounds for this, I‘ll investigate what they‘re doing…
There‘s already tracking of flags, it‘s shown by quick documentation on a variable. But it doesn‘t work yet with conditional commands, etc.