* fix(javascript): emit no promise for a literal non-callable executor
Node's `Promise` constructor calls the executor synchronously and throws a
`TypeError` when it is not callable, before any promise object exists. The
analysis reported a `constructor` promise operation with a hardcoded
`sourceResolution: "complete"`, which the graph projects as
`creates-promise` `resolved`.
Measured on Node 24.22.1:
new Promise() -> THREW TypeError
new Promise(1) / (-1) -> THREW TypeError
new Promise("work") / (`work`) -> THREW TypeError
new Promise(true) / (!0) -> THREW TypeError
new Promise(null) / (void 1) -> THREW TypeError
new Promise(1n) / (/re/) -> THREW TypeError
new Promise([]) / ({}) -> THREW TypeError
--- accepted ---
new Promise(() => {}) -> OK Promise
new Promise(async () => {}) -> OK Promise
new Promise(function () {}) -> OK Promise
new Promise(class {}) -> OK Promise
A class passes Node's own `typeof` check, so it keeps its operation. An
identifier, a call result or a spread may still supply a function and also keeps
its operation.
The filter gates the candidate push rather than `promiseCandidateDetails`, which
also decides whether an `await` becomes an `awaited-expression`: gating there
made `await new Promise(1)` emit a spurious task fact, whereas gating at the push
site makes it emit nothing, which is the honest answer.
* chore: retrigger title and readiness checks after the title was corrected
* fix(javascript): reject a non-finite executor, not only a literal
greptile caught that `new Promise(1e309)` still emitted a promise. Babel stores
that literal as `Infinity`, and `readExactJavaScriptLiteral` refuses to price a
non-finite number, so the guard missed it.
Measured on Node 24.22.1 — every one throws before a promise exists:
new Promise(1e309) -> THREW TypeError
new Promise(1e400) -> THREW TypeError
new Promise(Infinity) -> THREW TypeError
new Promise(-Infinity) -> THREW TypeError
new Promise(NaN) -> THREW TypeError
A numeric literal is now read directly rather than through the exact-value
reader. `Infinity` and `NaN` are identifiers rather than literals, so they are
decided through `isUnmodifiedGlobalReference`; a shadowed binding keeps its
promise, which is the same scoping rule the timer fix uses.