@scriptc/compiler 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ambient/scriptc-node-fallback.d.ts +73 -29
- package/dist/backend/llvm/bytes-loop-versions.js +6 -0
- package/dist/backend/llvm/bytes-loop-versions.js.map +1 -1
- package/dist/backend/llvm/bytes-loop-versions.test.js +7 -2
- package/dist/backend/llvm/bytes-loop-versions.test.js.map +1 -1
- package/dist/backend/llvm/debug-info.js +2 -5
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +4 -0
- package/dist/backend/llvm/dyn.js +21 -9
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emit-function.js +2 -8
- package/dist/backend/llvm/emit-function.js.map +1 -1
- package/dist/backend/llvm/emit-module.js +16 -6
- package/dist/backend/llvm/emit-module.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +10 -0
- package/dist/backend/llvm/emitter.js +9 -5
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +11 -2
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +11 -13
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +14 -8
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +14 -0
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +20 -11
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +16 -4
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/integer-values.d.ts +5 -0
- package/dist/backend/llvm/integer-values.js +27 -3
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +133 -3
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +37 -1
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +21 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/publish.js +3 -3
- package/dist/backend/llvm/publish.js.map +1 -1
- package/dist/backend/llvm/reference-effects.js +3 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/shapes.js +2 -7
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/stack-captures.js +1 -5
- package/dist/backend/llvm/stack-captures.js.map +1 -1
- package/dist/backend/llvm/union-repr.d.ts +4 -3
- package/dist/backend/llvm/union-repr.js +6 -5
- package/dist/backend/llvm/union-repr.js.map +1 -1
- package/dist/backend/llvm/walkers.js +13 -0
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +5 -3
- package/dist/backend/native-codegen-core.js +13 -6
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.test.js +6 -4
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/target-cpu.d.ts +26 -0
- package/dist/backend/target-cpu.js +98 -0
- package/dist/backend/target-cpu.js.map +1 -0
- package/dist/backend/target-cpu.test.d.ts +1 -0
- package/dist/backend/target-cpu.test.js +38 -0
- package/dist/backend/target-cpu.test.js.map +1 -0
- package/dist/cli/command.js +20 -1
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/usage.d.ts +4 -1
- package/dist/cli/usage.js +7 -0
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +7 -0
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +3 -0
- package/dist/executable/executable-cache.js +4 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +2 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/decl-projection.js +105 -10
- package/dist/frontend/decl-projection.js.map +1 -1
- package/dist/frontend/lowering/builtins/async-context.d.ts +8 -2
- package/dist/frontend/lowering/builtins/async-context.js +62 -3
- package/dist/frontend/lowering/builtins/async-context.js.map +1 -1
- package/dist/frontend/lowering/builtins/crypto.js +3 -1
- package/dist/frontend/lowering/builtins/crypto.js.map +1 -1
- package/dist/frontend/lowering/builtins/dates.js +4 -1
- package/dist/frontend/lowering/builtins/dates.js.map +1 -1
- package/dist/frontend/lowering/builtins/filesystem-calls.js +3 -3
- package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-glob.js +6 -3
- package/dist/frontend/lowering/builtins/fs-glob.js.map +1 -1
- package/dist/frontend/lowering/builtins/fs-paths.d.ts +43 -5
- package/dist/frontend/lowering/builtins/fs-paths.js +245 -93
- package/dist/frontend/lowering/builtins/fs-paths.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +6 -3
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.d.ts +1 -1
- package/dist/frontend/lowering/builtins/promises.js +149 -138
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/call-signatures.js +0 -1
- package/dist/frontend/lowering/call-signatures.js.map +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js +1 -1
- package/dist/frontend/lowering/cjs-exports-object.js.map +1 -1
- package/dist/frontend/lowering/cjs-inline-require.d.ts +32 -0
- package/dist/frontend/lowering/cjs-inline-require.js +307 -4
- package/dist/frontend/lowering/cjs-inline-require.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +10 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +114 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.js +54 -18
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -1
- package/dist/frontend/lowering/class-protocols.d.ts +25 -0
- package/dist/frontend/lowering/class-protocols.js +183 -1
- package/dist/frontend/lowering/class-protocols.js.map +1 -1
- package/dist/frontend/lowering/completion-callbacks.d.ts +4 -0
- package/dist/frontend/lowering/completion-callbacks.js +146 -0
- package/dist/frontend/lowering/completion-callbacks.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +5 -4
- package/dist/frontend/lowering/containers/array-callbacks.js +7 -6
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +5 -0
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.js +11 -3
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +25 -17
- package/dist/frontend/lowering/containers/bytes.js +453 -45
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/date-values.d.ts +11 -0
- package/dist/frontend/lowering/date-values.js +207 -0
- package/dist/frontend/lowering/date-values.js.map +1 -0
- package/dist/frontend/lowering/expressions/array-literals.js +6 -0
- package/dist/frontend/lowering/expressions/array-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/binary.js +64 -26
- package/dist/frontend/lowering/expressions/binary.js.map +1 -1
- package/dist/frontend/lowering/expressions/element-access.js +79 -0
- package/dist/frontend/lowering/expressions/element-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/identifiers.js +31 -1
- package/dist/frontend/lowering/expressions/identifiers.js.map +1 -1
- package/dist/frontend/lowering/expressions/property-access.js +56 -0
- package/dist/frontend/lowering/expressions/property-access.js.map +1 -1
- package/dist/frontend/lowering/expressions/typeof.js +6 -0
- package/dist/frontend/lowering/expressions/typeof.js.map +1 -1
- package/dist/frontend/lowering/expressions/updates.js +17 -0
- package/dist/frontend/lowering/expressions/updates.js.map +1 -1
- package/dist/frontend/lowering/function-returns.js +15 -0
- package/dist/frontend/lowering/function-returns.js.map +1 -1
- package/dist/frontend/lowering/indexed-unions.d.ts +54 -0
- package/dist/frontend/lowering/indexed-unions.js +401 -0
- package/dist/frontend/lowering/indexed-unions.js.map +1 -0
- package/dist/frontend/lowering/key-order-witness.js +210 -32
- package/dist/frontend/lowering/key-order-witness.js.map +1 -1
- package/dist/frontend/lowering/key-order-witness.test.js +104 -4
- package/dist/frontend/lowering/key-order-witness.test.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +15 -3
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +19 -3
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +22 -47
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +205 -1
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +1 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
- package/dist/frontend/lowering/lower-inspect.js +35 -11
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +21 -5
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +100 -34
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +30 -2
- package/dist/frontend/lowering/lowerer.js +68 -7
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/object-factory-new.d.ts +5 -0
- package/dist/frontend/lowering/object-factory-new.js +20 -6
- package/dist/frontend/lowering/object-factory-new.js.map +1 -1
- package/dist/frontend/lowering/overload-choice.d.ts +33 -0
- package/dist/frontend/lowering/overload-choice.js +190 -0
- package/dist/frontend/lowering/overload-choice.js.map +1 -0
- package/dist/frontend/lowering/surfaces.js +55 -2
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/pipeline.js +1 -1
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +5 -1
- package/dist/frontend/program-analysis.js +5 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +13 -5
- package/dist/frontend/program.js +197 -14
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.d.ts +3 -0
- package/dist/frontend/ts7/semantic-model.js +5 -0
- package/dist/frontend/ts7/semantic-model.js.map +1 -1
- package/dist/frontend/ts7/semantic-model.test.js +6 -1
- package/dist/frontend/ts7/semantic-model.test.js.map +1 -1
- package/dist/frontend/ts7/semantic-types.d.ts +1 -1
- package/dist/frontend/ts7/semantic-types.js +1 -1
- package/dist/frontend/ts7/semantic-types.js.map +1 -1
- package/dist/frontend/type-mapper.js +45 -16
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-effects.js +8 -0
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +56 -0
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/int32-slots.js +7 -0
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +33 -0
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-loops.js +14 -4
- package/dist/ir/integer-loops.js.map +1 -1
- package/dist/ir/ir.d.ts +13 -3
- package/dist/ir/ir.js +19 -5
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +2 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/js-ic.d.ts +2 -15
- package/dist/ir/js-ic.js +11 -79
- package/dist/ir/js-ic.js.map +1 -1
- package/dist/ir/js-ic.test.js +0 -142
- package/dist/ir/js-ic.test.js.map +1 -1
- package/dist/ir/runtime-features.js +25 -1
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/validate.js +46 -5
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/ir-policy.js +1 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/prepare.d.ts +1 -1
- package/dist/native/prepare.js +11 -1
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/prepare.test.js +18 -2
- package/dist/native/prepare.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +2 -4
|
@@ -26,7 +26,7 @@ import { lowerSafeIndexRead, tryLowerIndexTruthiness, tryLowerNumericIndexRead,
|
|
|
26
26
|
import { nsMemberIdentOf } from "./lower-namespaces.js";
|
|
27
27
|
import { bindingNeverReassigned } from "./binding-analysis.js";
|
|
28
28
|
import { implicitMonoFile } from "./generic-functions.js";
|
|
29
|
-
import { lowerTaggedTemplate } from "./lower-calls.js";
|
|
29
|
+
import { lowerPrimitiveUnionNumber, lowerTaggedTemplate } from "./lower-calls.js";
|
|
30
30
|
import { unitOnlyUnion } from "../type-mapper.js";
|
|
31
31
|
import { lowerYield } from "./lower-generators.js";
|
|
32
32
|
import { unionWideningTags } from "../../ir/analysis.js";
|
|
@@ -272,6 +272,14 @@ function lowerExprInner(lowerer, expr) {
|
|
|
272
272
|
const use = runtimeOptionalUseOf(expr);
|
|
273
273
|
if (runtimeOptionalAssertionErases(lowerer, expr, inner, use))
|
|
274
274
|
return inner;
|
|
275
|
+
// A destination that holds null or undefined keeps the value, as `!`
|
|
276
|
+
// does in JavaScript (`return cache.get(key)!` from a function that
|
|
277
|
+
// returns `T | null`); the destination's own coercion re-tags it.
|
|
278
|
+
if (assertionDestinationHoldsNullish(lowerer, expr, inner.type))
|
|
279
|
+
return inner;
|
|
280
|
+
const operand = assertionOperand(lowerer, expr, inner, target ?? null, loc);
|
|
281
|
+
if (operand)
|
|
282
|
+
return operand;
|
|
275
283
|
if (target && target.kind !== "union" && !typeEquals(target, inner.type)) {
|
|
276
284
|
const helper = lowerer.narrowedArmHelper(inner.type.unionId, target, loc);
|
|
277
285
|
if (helper) {
|
|
@@ -723,6 +731,198 @@ export function assertedElementKeepsUndefined(lowerer, node) {
|
|
|
723
731
|
return (admits(contextual) ||
|
|
724
732
|
((contextual.flags & ts.TypeFlags.Union) !== 0 && constituentTypes(contextual).some(admits)));
|
|
725
733
|
}
|
|
734
|
+
/** Whether `node!` is a returned value, an arrow function's body or a call
|
|
735
|
+
* argument whose destination type (the return or parameter type) is `any`
|
|
736
|
+
* or `unknown` (as for `String(x!)` and `Number(x!)`) or holds null or
|
|
737
|
+
* undefined that the union `inner` holds and the assertion would remove.
|
|
738
|
+
* Bindings and assignments are left out: the checker narrows them to the
|
|
739
|
+
* asserted type for later reads. */
|
|
740
|
+
function assertionDestinationHoldsNullish(lowerer, node, inner) {
|
|
741
|
+
const holdsNull = lowerer.armTag(inner.unionId, NULL_T) >= 0;
|
|
742
|
+
const holdsUndefined = lowerer.armTag(inner.unionId, UNDEFINED_T) >= 0;
|
|
743
|
+
if (!holdsNull && !holdsUndefined)
|
|
744
|
+
return false;
|
|
745
|
+
let outer = node;
|
|
746
|
+
while (ts.isParenthesizedExpression(outer.parent))
|
|
747
|
+
outer = outer.parent;
|
|
748
|
+
const parent = outer.parent;
|
|
749
|
+
const destination = (ts.isReturnStatement(parent) && parent.expression === outer) ||
|
|
750
|
+
(ts.isArrowFunction(parent) && parent.body === outer) ||
|
|
751
|
+
((ts.isCallExpression(parent) || ts.isNewExpression(parent)) &&
|
|
752
|
+
parent.arguments?.nodes.includes(outer) === true);
|
|
753
|
+
if (!destination)
|
|
754
|
+
return false;
|
|
755
|
+
const contextual = lowerer.checker.getContextualType(outer);
|
|
756
|
+
if (!contextual)
|
|
757
|
+
return false;
|
|
758
|
+
const nullish = ts.TypeFlags.Any |
|
|
759
|
+
ts.TypeFlags.Unknown |
|
|
760
|
+
(holdsNull ? ts.TypeFlags.Null : 0) |
|
|
761
|
+
(holdsUndefined && !optionalStdlibParameter(lowerer, parent, outer)
|
|
762
|
+
? ts.TypeFlags.Undefined
|
|
763
|
+
: 0);
|
|
764
|
+
if ((contextual.flags & ts.TypeFlags.Union) === 0)
|
|
765
|
+
return (contextual.flags & nullish) !== 0;
|
|
766
|
+
return constituentTypes(contextual).some((type) => (type.flags & nullish) !== 0);
|
|
767
|
+
}
|
|
768
|
+
/** Whether `argument` of `call` binds an optional parameter of a standard
|
|
769
|
+
* library declaration (`decoder.decode(input?)`). The undefined such a
|
|
770
|
+
* parameter's type holds comes from its optionality, and the builtin
|
|
771
|
+
* lowerings read the argument as the declared type, so `x!` keeps the
|
|
772
|
+
* checked narrowing there. */
|
|
773
|
+
function optionalStdlibParameter(lowerer, call, argument) {
|
|
774
|
+
if (!ts.isCallExpression(call) && !ts.isNewExpression(call))
|
|
775
|
+
return false;
|
|
776
|
+
const declaration = lowerer.checker.getResolvedSignature(call)?.declaration;
|
|
777
|
+
if (declaration === undefined || !lowerer.isStdlibFile(ts.getSourceFileOfNode(declaration)))
|
|
778
|
+
return false;
|
|
779
|
+
const index = call.arguments?.nodes.indexOf(argument) ?? -1;
|
|
780
|
+
const parameter = declaration.parameters?.nodes[index];
|
|
781
|
+
return (parameter !== undefined &&
|
|
782
|
+
parameter.dotDotDotToken === undefined &&
|
|
783
|
+
(parameter.questionToken !== undefined || parameter.initializer !== undefined));
|
|
784
|
+
}
|
|
785
|
+
/** `x!` as the operand of an operator that converts its operands: an
|
|
786
|
+
* arithmetic, bitwise, relational or equality operator, `+`, a compound
|
|
787
|
+
* assignment, a unary `-`, `+`, `~` or `!`, a template span, or an argument
|
|
788
|
+
* of a Math function. `!` performs no runtime check,
|
|
789
|
+
* so a value that still holds undefined or null reaches the operator, which
|
|
790
|
+
* converts it as JavaScript does: NaN or 0 in arithmetic, false in a
|
|
791
|
+
* comparison, "undefined" or "null" in a string. Returns the operand to
|
|
792
|
+
* use, or null where the assertion narrows as usual. A numeric use gets the
|
|
793
|
+
* value converted with ToNumber; other uses get the union itself. */
|
|
794
|
+
function assertionOperand(lowerer, expr, inner, target, loc) {
|
|
795
|
+
if (inner.type.kind !== "union" || target === null || target.kind === "union")
|
|
796
|
+
return null;
|
|
797
|
+
const arms = lowerer.unions.get(inner.type.unionId)?.arms;
|
|
798
|
+
if (!arms?.some(isUnitType) ||
|
|
799
|
+
!arms.every((arm) => arm.kind === "f64" || arm.kind === "string" || arm.kind === "bool" || isUnitType(arm)))
|
|
800
|
+
return null;
|
|
801
|
+
// Array and typed-array element reads keep their own handling of a
|
|
802
|
+
// missing element.
|
|
803
|
+
let operand = expr.expression;
|
|
804
|
+
while (ts.isParenthesizedExpression(operand))
|
|
805
|
+
operand = operand.expression;
|
|
806
|
+
if (ts.isElementAccessExpression(operand)) {
|
|
807
|
+
const kind = lowerer.mapTypeOf(lowerer.typeOf(operand.expression))?.kind;
|
|
808
|
+
if (kind === "array" || kind === "bytes")
|
|
809
|
+
return null;
|
|
810
|
+
}
|
|
811
|
+
const use = convertingUseOf(lowerer, expr);
|
|
812
|
+
if (use === null)
|
|
813
|
+
return null;
|
|
814
|
+
if (use === "value")
|
|
815
|
+
return inner;
|
|
816
|
+
return lowerPrimitiveUnionNumber(lowerer, inner, expr, loc);
|
|
817
|
+
}
|
|
818
|
+
/** How the converting use of `x!` (see assertionOperand) reads it:
|
|
819
|
+
* "number" where the use applies ToNumber, "value" where the consumer
|
|
820
|
+
* lowers the union itself (strings, equality, truthiness), null for other
|
|
821
|
+
* uses. */
|
|
822
|
+
function convertingUseOf(lowerer, expr) {
|
|
823
|
+
let outer = expr;
|
|
824
|
+
while (ts.isParenthesizedExpression(outer.parent))
|
|
825
|
+
outer = outer.parent;
|
|
826
|
+
const parent = outer.parent;
|
|
827
|
+
if (ts.isTemplateSpan(parent))
|
|
828
|
+
return parent.expression === outer ? "value" : null;
|
|
829
|
+
if (ts.isPrefixUnaryExpression(parent)) {
|
|
830
|
+
if (parent.operator === ts.SyntaxKind.ExclamationToken)
|
|
831
|
+
return "value";
|
|
832
|
+
return parent.operator === ts.SyntaxKind.MinusToken ||
|
|
833
|
+
parent.operator === ts.SyntaxKind.PlusToken ||
|
|
834
|
+
parent.operator === ts.SyntaxKind.TildeToken
|
|
835
|
+
? "number"
|
|
836
|
+
: null;
|
|
837
|
+
}
|
|
838
|
+
if (ts.isCallExpression(parent) && parent.arguments.nodes.includes(outer)) {
|
|
839
|
+
const callee = parent.expression;
|
|
840
|
+
return ts.isPropertyAccessExpression(callee) &&
|
|
841
|
+
stdlibGlobalNameOf(lowerer, callee.expression) === "Math"
|
|
842
|
+
? "number"
|
|
843
|
+
: null;
|
|
844
|
+
}
|
|
845
|
+
if (!ts.isBinaryExpression(parent))
|
|
846
|
+
return null;
|
|
847
|
+
const op = parent.operatorToken.kind;
|
|
848
|
+
if (EQUALITY_OPERATORS.has(op))
|
|
849
|
+
return "value";
|
|
850
|
+
const other = parent.left === outer ? parent.right : parent.left;
|
|
851
|
+
const isString = (node) => (lowerer.typeOf(node).flags & ts.TypeFlags.StringLike) !== 0;
|
|
852
|
+
// With a string on either side, `+` concatenates and a comparison
|
|
853
|
+
// compares strings. `undefined + 1` and `undefined + undefined` are NaN,
|
|
854
|
+
// which a string-typed result cannot hold, so `+` takes the union only
|
|
855
|
+
// with a string partner that is not itself asserted. A partner that may
|
|
856
|
+
// hold a string or a number at run time (`any`, `unknown`) also gets the
|
|
857
|
+
// union, and `+` decides between concatenation and addition when it runs.
|
|
858
|
+
if (op === ts.SyntaxKind.PlusToken || op === ts.SyntaxKind.PlusEqualsToken) {
|
|
859
|
+
if (op === ts.SyntaxKind.PlusEqualsToken && parent.right !== outer)
|
|
860
|
+
return null;
|
|
861
|
+
let partner = other;
|
|
862
|
+
while (ts.isParenthesizedExpression(partner))
|
|
863
|
+
partner = partner.expression;
|
|
864
|
+
if (isString(other))
|
|
865
|
+
return ts.isNonNullExpression(partner) ? null : "value";
|
|
866
|
+
if (!numericPartner(lowerer.typeOf(other)))
|
|
867
|
+
return "value";
|
|
868
|
+
return isString(expr) ? null : "number";
|
|
869
|
+
}
|
|
870
|
+
if (RELATIONAL_OPERATORS.has(op))
|
|
871
|
+
return isString(other) || isString(expr) ? "value" : "number";
|
|
872
|
+
if (NUMERIC_OPERATORS.has(op))
|
|
873
|
+
return "number";
|
|
874
|
+
return NUMERIC_COMPOUNDS.has(op) && parent.right === outer ? "number" : null;
|
|
875
|
+
}
|
|
876
|
+
/** A `+` partner whose every value is a number, a boolean, null or
|
|
877
|
+
* undefined: `+` adds with it. */
|
|
878
|
+
function numericPartner(type) {
|
|
879
|
+
const numeric = ts.TypeFlags.NumberLike |
|
|
880
|
+
ts.TypeFlags.BooleanLike |
|
|
881
|
+
ts.TypeFlags.Null |
|
|
882
|
+
ts.TypeFlags.Undefined |
|
|
883
|
+
ts.TypeFlags.Void;
|
|
884
|
+
return (type.flags & ts.TypeFlags.Union) !== 0
|
|
885
|
+
? constituentTypes(type).every((part) => (part.flags & numeric) !== 0)
|
|
886
|
+
: (type.flags & numeric) !== 0;
|
|
887
|
+
}
|
|
888
|
+
const EQUALITY_OPERATORS = new Set([
|
|
889
|
+
ts.SyntaxKind.EqualsEqualsEqualsToken,
|
|
890
|
+
ts.SyntaxKind.ExclamationEqualsEqualsToken,
|
|
891
|
+
ts.SyntaxKind.EqualsEqualsToken,
|
|
892
|
+
ts.SyntaxKind.ExclamationEqualsToken,
|
|
893
|
+
]);
|
|
894
|
+
const RELATIONAL_OPERATORS = new Set([
|
|
895
|
+
ts.SyntaxKind.LessThanToken,
|
|
896
|
+
ts.SyntaxKind.GreaterThanToken,
|
|
897
|
+
ts.SyntaxKind.LessThanEqualsToken,
|
|
898
|
+
ts.SyntaxKind.GreaterThanEqualsToken,
|
|
899
|
+
]);
|
|
900
|
+
const NUMERIC_OPERATORS = new Set([
|
|
901
|
+
ts.SyntaxKind.MinusToken,
|
|
902
|
+
ts.SyntaxKind.AsteriskToken,
|
|
903
|
+
ts.SyntaxKind.SlashToken,
|
|
904
|
+
ts.SyntaxKind.PercentToken,
|
|
905
|
+
ts.SyntaxKind.AsteriskAsteriskToken,
|
|
906
|
+
ts.SyntaxKind.AmpersandToken,
|
|
907
|
+
ts.SyntaxKind.BarToken,
|
|
908
|
+
ts.SyntaxKind.CaretToken,
|
|
909
|
+
ts.SyntaxKind.LessThanLessThanToken,
|
|
910
|
+
ts.SyntaxKind.GreaterThanGreaterThanToken,
|
|
911
|
+
ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken,
|
|
912
|
+
]);
|
|
913
|
+
const NUMERIC_COMPOUNDS = new Set([
|
|
914
|
+
ts.SyntaxKind.MinusEqualsToken,
|
|
915
|
+
ts.SyntaxKind.AsteriskEqualsToken,
|
|
916
|
+
ts.SyntaxKind.SlashEqualsToken,
|
|
917
|
+
ts.SyntaxKind.PercentEqualsToken,
|
|
918
|
+
ts.SyntaxKind.AsteriskAsteriskEqualsToken,
|
|
919
|
+
ts.SyntaxKind.AmpersandEqualsToken,
|
|
920
|
+
ts.SyntaxKind.BarEqualsToken,
|
|
921
|
+
ts.SyntaxKind.CaretEqualsToken,
|
|
922
|
+
ts.SyntaxKind.LessThanLessThanEqualsToken,
|
|
923
|
+
ts.SyntaxKind.GreaterThanGreaterThanEqualsToken,
|
|
924
|
+
ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken,
|
|
925
|
+
]);
|
|
726
926
|
export function runtimeOptionalAssertionErases(lowerer, expr, inner, use) {
|
|
727
927
|
if (inner.type.kind !== "union" ||
|
|
728
928
|
!use?.optional ||
|
|
@@ -847,6 +1047,10 @@ export function lowerCondition(lowerer, expr) {
|
|
|
847
1047
|
e.name.text === "setPrototypeOf" &&
|
|
848
1048
|
lowerer.isStdlibGlobal(e.expression, "Object"))
|
|
849
1049
|
return { kind: "boolLit", value: true, type: BOOL, loc: locOf(e) };
|
|
1050
|
+
// `if (runtimeBuffer)` over an alias of the Buffer global (a
|
|
1051
|
+
// capability probe): Node always defines Buffer.
|
|
1052
|
+
if (lowerer.isStdlibGlobal(e, "Buffer"))
|
|
1053
|
+
return { kind: "boolLit", value: true, type: BOOL, loc: locOf(e) };
|
|
850
1054
|
if (ts.isPropertyAccessExpression(e)) {
|
|
851
1055
|
const presence = lowerPromiseThenPresence(lowerer, e, {
|
|
852
1056
|
kind: "boolLit",
|