Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spaces in array keys break parser #142

Open
Bilge opened this issue Nov 22, 2023 · 4 comments
Open

Spaces in array keys break parser #142

Bilge opened this issue Nov 22, 2023 · 4 comments

Comments

@Bilge
Copy link

Bilge commented Nov 22, 2023

local -A foo=([bar baz]=bat)
echo "${foo[bar baz]}"
@jansorg
Copy link
Contributor

jansorg commented Nov 23, 2023

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" )

@Bilge
Copy link
Author

Bilge commented Nov 23, 2023

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.

@jansorg
Copy link
Contributor

jansorg commented Nov 23, 2023

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…

@jansorg
Copy link
Contributor

jansorg commented Nov 23, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants