WIP: fix export/override prefix and ?= first-wins in make variable parser
All checks were successful
check / check (push) Successful in 14s
All checks were successful
check / check (push) Successful in 14s
Two defects in the lint-once resolver's make variable handling: - The assignment pattern anchored at the start of the name, so `export FMT := script/fmt-check` was never collected and `@$(FMT)` went unresolved. An optional `export `/`override ` prefix is now allowed. - `?=` assigns only when the name is unset, so the first assignment wins. The parser called .set() unconditionally, letting a later `FMT ?= script/build` overwrite an earlier `FMT := script/fmt-check` and resolve to a command make never runs. Tests pinning both to follow.
This commit is contained in:
@@ -159,7 +159,7 @@ const MAKE_CONDITIONAL = /^\s*(?:ifeq|ifneq|ifdef|ifndef|else|endif)\b/;
|
||||
// not happen. An unresolved reference is left standing verbatim instead, which
|
||||
// is the same dead end as any other unfollowed edge rather than a wrong answer.
|
||||
const MAKE_ASSIGNMENT = new RegExp(
|
||||
`^([A-Za-z_][A-Za-z0-9_]*)\\s*(?::=|\\?=|=)\\s*(.*)$`,
|
||||
`^(?:(?:export|override)\\s+)*([A-Za-z_][A-Za-z0-9_]*)\\s*(:=|\\?=|=)\\s*(.*)$`,
|
||||
);
|
||||
const MAKE_VARIABLE_REFERENCE = /\$[({]([A-Za-z_][A-Za-z0-9_]*)[)}]/g;
|
||||
|
||||
@@ -181,8 +181,13 @@ const makeVariables = (text: string): Map<string, string> => {
|
||||
if (inDefine || raw.startsWith("\t")) continue;
|
||||
const assignment = MAKE_ASSIGNMENT.exec(raw.replace(/#.*$/, "").trim());
|
||||
if (assignment === null) continue;
|
||||
const [, name, value] = assignment;
|
||||
if (name === undefined || value === undefined) continue;
|
||||
const [, name, operator, value] = assignment;
|
||||
if (name === undefined || operator === undefined) continue;
|
||||
if (value === undefined) continue;
|
||||
// `?=` assigns only when the name has no value yet, so the first one
|
||||
// wins where `:=` and `=` let the last one win. Overwriting here would
|
||||
// resolve the reference to a string make never uses.
|
||||
if (operator === "?=" && variables.has(name)) continue;
|
||||
// A value that is itself a reference is the recursive case, and is not
|
||||
// resolved. Recording it would hand the substitution below a string it
|
||||
// cannot finish expanding.
|
||||
|
||||
Reference in New Issue
Block a user