Follow-up to #166, which lowercased syntax-option implicit locals at registration. The deferred half is the c_local/global macro-creating-option detection path, which still uses verbatim casing.
Where
src/analyzer/index.ts:
Repro
program define myprog
syntax, Cache(string)
c_local \`cache' "value" // lowercase to mirror Stata's implicit-local casing
end
myprog, cache(result) // call-site uses any valid abbreviation
display \`result' // should be defined; flagged as undefined
extract_syntax_option_names yields {\"Cache\"}; the c_local matcher looks up \"cache\" and misses, so macro_creating_local_options is empty and the caller-side definition is never registered.
Suggested fix
Mirror PR #166: normalize both sides of these matches to lowercase (the runtime form Stata actually creates). That means:
- Lowercase what
extract_syntax_option_names stores.
- Lowercase
inner_name before syntax_option_names.has(...).
- Lowercase
option.name before local_option_names.has(...) / global_option_names.has(...).
Update the comment block at lines 739–744 once the asymmetry is gone.
Tests should cover: capitalised option declared with syntax, c_local using lowercase backticked name, and a caller using the option with a different abbreviation/casing — with display of the resulting local not flagged as undefined.
Follow-up to #166, which lowercased syntax-option implicit locals at registration. The deferred half is the
c_local/globalmacro-creating-option detection path, which still uses verbatim casing.Where
src/analyzer/index.ts:extract_syntax_option_namesreturns verbatim option names.extract_macro_creating_option_patternscompares the literal text inside`name'against that set with case-sensitiveSet.has.local_option_names.has(option.name)compares the call-site option name (which may be any valid abbreviation/casing) against the verbatim set populated above.Repro
program define myprog syntax, Cache(string) c_local \`cache' "value" // lowercase to mirror Stata's implicit-local casing end myprog, cache(result) // call-site uses any valid abbreviation display \`result' // should be defined; flagged as undefinedextract_syntax_option_namesyields{\"Cache\"}; the c_local matcher looks up\"cache\"and misses, somacro_creating_local_optionsis empty and the caller-side definition is never registered.Suggested fix
Mirror PR #166: normalize both sides of these matches to lowercase (the runtime form Stata actually creates). That means:
extract_syntax_option_namesstores.inner_namebeforesyntax_option_names.has(...).option.namebeforelocal_option_names.has(...)/global_option_names.has(...).Update the comment block at lines 739–744 once the asymmetry is gone.
Tests should cover: capitalised option declared with
syntax,c_localusing lowercase backticked name, and a caller using the option with a different abbreviation/casing — withdisplayof the resulting local not flagged as undefined.