Update the make variable header to match the ?= and prefix rules
All checks were successful
check / check (push) Successful in 15s
All checks were successful
check / check (push) Successful in 15s
This commit is contained in:
@@ -149,11 +149,15 @@ const MAKE_CONDITIONAL = /^\s*(?:ifeq|ifneq|ifdef|ifndef|else|endif)\b/;
|
|||||||
// one. `$(MAKE)` was already special-cased below, which is this same rule
|
// one. `$(MAKE)` was already special-cased below, which is this same rule
|
||||||
// half-applied to a single name; this is the general form of it.
|
// half-applied to a single name; this is the general form of it.
|
||||||
//
|
//
|
||||||
// Deliberately only the simple case: a name assigned a literal on one line.
|
// Deliberately only the simple case: a name assigned a literal on one line,
|
||||||
// `:=` and `=` differ in when make expands them and `?=` in whether it assigns
|
// optionally through an `export`/`override` prefix. `:=` and `=` differ in
|
||||||
// at all, but none of that changes the single value a literal can take, so all
|
// when make expands them, which does not change the single value a literal can
|
||||||
// three are read the same way. What is not read is anything needing evaluation
|
// take, so those two are read the same way and the last one wins. `?=` differs
|
||||||
// — a value containing another `$(...)`, a make function, or a `define` body —
|
// in whether it assigns at all — it is skipped when the name already has a
|
||||||
|
// value — so among assignments to one name the first `?=` wins, and reading it
|
||||||
|
// as last-wins would resolve a reference to the string make discards. What is
|
||||||
|
// not read is anything needing evaluation — a value containing another
|
||||||
|
// `$(...)`, a make function, or a `define` body —
|
||||||
// because expanding those means implementing make, and a half-implementation
|
// because expanding those means implementing make, and a half-implementation
|
||||||
// that resolves a variable to the wrong string would count invocations that do
|
// that resolves a variable to the wrong string would count invocations that do
|
||||||
// not happen. An unresolved reference is left standing verbatim instead, which
|
// not happen. An unresolved reference is left standing verbatim instead, which
|
||||||
@@ -182,8 +186,8 @@ const makeVariables = (text: string): Map<string, string> => {
|
|||||||
const assignment = MAKE_ASSIGNMENT.exec(raw.replace(/#.*$/, "").trim());
|
const assignment = MAKE_ASSIGNMENT.exec(raw.replace(/#.*$/, "").trim());
|
||||||
if (assignment === null) continue;
|
if (assignment === null) continue;
|
||||||
const [, name, operator, value] = assignment;
|
const [, name, operator, value] = assignment;
|
||||||
if (name === undefined || operator === undefined) continue;
|
if (name === undefined || operator === undefined || value === undefined)
|
||||||
if (value === undefined) continue;
|
continue;
|
||||||
// `?=` assigns only when the name has no value yet, so the first one
|
// `?=` assigns only when the name has no value yet, so the first one
|
||||||
// wins where `:=` and `=` let the last one win. Overwriting here would
|
// wins where `:=` and `=` let the last one win. Overwriting here would
|
||||||
// resolve the reference to a string make never uses.
|
// resolve the reference to a string make never uses.
|
||||||
@@ -853,9 +857,12 @@ describe("the resolver reads what the shell would run", () => {
|
|||||||
// is not read as an assignment of the empty string.
|
// is not read as an assignment of the empty string.
|
||||||
expect(
|
expect(
|
||||||
parseMakefile(
|
parseMakefile(
|
||||||
["FMT := script/fmt-check", "export FMT", "check:", "\t@$(FMT)"].join(
|
[
|
||||||
"\n",
|
"FMT := script/fmt-check",
|
||||||
),
|
"export FMT",
|
||||||
|
"check:",
|
||||||
|
"\t@$(FMT)",
|
||||||
|
].join("\n"),
|
||||||
).get("check")?.recipe,
|
).get("check")?.recipe,
|
||||||
).toEqual(["script/fmt-check"]);
|
).toEqual(["script/fmt-check"]);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user