@scriptc/compiler 0.1.4 → 0.1.5
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 +75 -11
- package/dist/backend/c/c-emitter.d.ts +5 -1
- package/dist/backend/c/c-emitter.js +22 -9
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.d.ts +2 -2
- package/dist/backend/c/exprs.js +264 -21
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/stmts.js +5 -3
- package/dist/backend/c/stmts.js.map +1 -1
- package/dist/backend/c/types.d.ts +2 -3
- package/dist/backend/c/types.js +8 -1
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/c/walkers.js +1 -1
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/link-plan.d.ts +1 -0
- package/dist/backend/link-plan.js +2 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/dyn.js +1 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +25 -9
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -2
- package/dist/backend/llvm/expr-bytes.js +22 -17
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -0
- package/dist/backend/llvm/expr-containers.js +32 -4
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +6 -2
- package/dist/backend/llvm/expr-primitives.js +22 -7
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +12 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +53 -10
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +64 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +2 -0
- package/dist/backend/native-toolchain.js +2 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/targets.d.ts +3 -0
- package/dist/backend/targets.js +13 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/coverage/surface-manifest.js +6 -4
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
- package/dist/frontend/lowering/containers/bytes.js +6 -5
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +7 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +237 -28
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +8 -0
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +4 -5
- package/dist/frontend/lowering/lower-builtins.js +18 -10
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +3 -2
- package/dist/frontend/lowering/lower-calls.js +265 -88
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +2 -2
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +7 -9
- package/dist/frontend/lowering/lower-containers.js +143 -51
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +12 -0
- package/dist/frontend/lowering/lower-exprs.js +128 -10
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +17 -6
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +2 -4
- package/dist/frontend/lowering/lower-server.js +288 -32
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +4 -4
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.js +37 -2
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +9 -1
- package/dist/frontend/lowering/optional-arguments.js +67 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +3 -1
- package/dist/frontend/lowering/pairs-snapshot.js +12 -4
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +8 -14
- package/dist/frontend/lowering/surfaces.js +37 -27
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +6 -0
- package/dist/frontend/npm-static-prune.js +203 -0
- package/dist/frontend/npm-static-prune.js.map +1 -0
- package/dist/frontend/npm-static-prune.test.d.ts +1 -0
- package/dist/frontend/npm-static-prune.test.js +48 -0
- package/dist/frontend/npm-static-prune.test.js.map +1 -0
- package/dist/frontend/npm.js +7 -6
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.js +15 -4
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance.js +8 -3
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/type-mapper.js +16 -5
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +13 -41
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +5 -3
- package/dist/ir/analysis.js +25 -11
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +50 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.d.ts +17 -0
- package/dist/ir/constant-tables.js +99 -0
- package/dist/ir/constant-tables.js.map +1 -0
- package/dist/ir/constant-tables.test.d.ts +1 -0
- package/dist/ir/constant-tables.test.js +78 -0
- package/dist/ir/constant-tables.test.js.map +1 -0
- package/dist/ir/integer-ranges.d.ts +13 -0
- package/dist/ir/integer-ranges.js +122 -0
- package/dist/ir/integer-ranges.js.map +1 -0
- package/dist/ir/integer-ranges.test.d.ts +1 -0
- package/dist/ir/integer-ranges.test.js +63 -0
- package/dist/ir/integer-ranges.test.js.map +1 -0
- package/dist/ir/ir.d.ts +42 -34
- package/dist/ir/ir.js +7 -1
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +6 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.d.ts +8 -0
- package/dist/ir/scalar-records.js +216 -0
- package/dist/ir/scalar-records.js.map +1 -0
- package/dist/ir/scalar-records.test.d.ts +1 -0
- package/dist/ir/scalar-records.test.js +142 -0
- package/dist/ir/scalar-records.test.js.map +1 -0
- package/dist/ir/validate.js +92 -8
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.d.ts +1 -0
- package/dist/ir/validate.test.js +31 -0
- package/dist/ir/validate.test.js.map +1 -0
- package/dist/library/cache-primitives.d.ts +1 -1
- package/dist/library/cache-primitives.js +3 -3
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/fence-eval.js +11 -4
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/library-cache.js +0 -1
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +3 -3
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +55 -42
|
@@ -865,25 +865,26 @@ export function lowerServerCloseOverrideAssignment(lowerer, left, right, loc) {
|
|
|
865
865
|
loc,
|
|
866
866
|
};
|
|
867
867
|
}
|
|
868
|
-
/**
|
|
869
|
-
*
|
|
870
|
-
* routed from lower-stmts' property-assignment path beside the
|
|
871
|
-
* close-override hook. Null when the target isn't one of the two. */
|
|
868
|
+
/** Writable ServerResponse properties consulted by the implicit head and
|
|
869
|
+
* the strict body-length check. Null when the target isn't one of them. */
|
|
872
870
|
export function lowerHttpResPropertyAssignment(lowerer, left, right, loc) {
|
|
873
871
|
if (!ts.isPropertyAccessExpression(left) || left.questionDotToken)
|
|
874
872
|
return null;
|
|
875
873
|
const name = left.name.text;
|
|
876
|
-
if (name !== "statusCode" && name !== "statusMessage"
|
|
874
|
+
if (name !== "statusCode" && name !== "statusMessage" &&
|
|
875
|
+
name !== "sendDate" && name !== "strictContentLength")
|
|
877
876
|
return null;
|
|
878
877
|
if (lowerer.mapTypeOf(lowerer.typeOf(left.expression))?.kind !== "httpRes")
|
|
879
878
|
return null;
|
|
880
879
|
if (!lowerer.isStdlibMember(left))
|
|
881
880
|
return null;
|
|
882
|
-
const receiver = lowerer
|
|
881
|
+
const receiver = coerceToHandle(lowerer, left.expression, HTTPRES_T);
|
|
883
882
|
const value = name === "statusCode"
|
|
884
883
|
? lowerer.lowerExprExpecting(right, F64)
|
|
885
|
-
: lowerer.lowerExprExpecting(right, STRING);
|
|
886
|
-
const fn = name === "statusCode" ? "http.resStatusSet"
|
|
884
|
+
: lowerer.lowerExprExpecting(right, name === "statusMessage" ? STRING : BOOL);
|
|
885
|
+
const fn = name === "statusCode" ? "http.resStatusSet"
|
|
886
|
+
: name === "statusMessage" ? "http.resStatusMsgSet"
|
|
887
|
+
: name === "sendDate" ? "http.resSendDateSet" : "http.resStrictContentLengthSet";
|
|
887
888
|
return {
|
|
888
889
|
kind: "exprStmt",
|
|
889
890
|
expr: { kind: "libCall", fn, args: [receiver, value], type: VOID, loc },
|
|
@@ -924,6 +925,28 @@ function lowerNetServerMethodCall(lowerer, call, access) {
|
|
|
924
925
|
const name = access.name.text;
|
|
925
926
|
const loc = locOf(call);
|
|
926
927
|
const args = call.arguments;
|
|
928
|
+
if (name === "setTimeout") {
|
|
929
|
+
if (args.length < 1 || args.length > 2)
|
|
930
|
+
lowerer.noLowering("server.setTimeout arguments", call, "pass milliseconds and an optional socket callback");
|
|
931
|
+
const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
|
|
932
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
933
|
+
const cb = args.length === 2
|
|
934
|
+
? lowerCallbackArg(lowerer, args[1], "server timeout callbacks", 1, (p) => p.kind === "netSocket", "use (socket) or ()", [NETSOCKET_T]).cb
|
|
935
|
+
: null;
|
|
936
|
+
const fn = cb === null ? "http.serverSetTimeout" : "http.serverSetTimeoutCb";
|
|
937
|
+
const callArgs = cb === null ? [receiver, ms] : [receiver, ms, cb];
|
|
938
|
+
if (resultIsDiscarded(call))
|
|
939
|
+
return { kind: "libCall", fn, args: callArgs, type: VOID, loc };
|
|
940
|
+
return receiverReturningCall(lowerer, fn, callArgs, NETSERVER_T, loc);
|
|
941
|
+
}
|
|
942
|
+
if (name === "closeAllConnections" || name === "closeIdleConnections") {
|
|
943
|
+
requireStatementPosition(lowerer, call, `server.${name}()`);
|
|
944
|
+
if (args.length !== 0)
|
|
945
|
+
lowerer.noLowering(`server.${name} arguments`, call, `${name}() takes no arguments`);
|
|
946
|
+
const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
|
|
947
|
+
const fn = name === "closeAllConnections" ? "http.serverCloseAllConnections" : "http.serverCloseIdleConnections";
|
|
948
|
+
return { kind: "libCall", fn, args: [receiver], type: VOID, loc };
|
|
949
|
+
}
|
|
927
950
|
if (name === "listen") {
|
|
928
951
|
if (args.length < 1 || args.length > 3) {
|
|
929
952
|
lowerer.noLowering(`listen with ${args.length} arguments`, call, "the supported form is listen(port[, host][, callback]) — port 0 binds an ephemeral port");
|
|
@@ -1140,6 +1163,10 @@ function lowerNetServerMethodCall(lowerer, call, access) {
|
|
|
1140
1163
|
const { cb } = lowerCallbackArg(lowerer, args[1], "close listeners", 0, () => false, "use ()", []);
|
|
1141
1164
|
return { kind: "libCall", fn: "net.serverOnClose", args: [receiver, cb, once], type: VOID, loc };
|
|
1142
1165
|
}
|
|
1166
|
+
if (event === "timeout") {
|
|
1167
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "timeout listeners", 1, (p) => p.kind === "netSocket", "use (socket) or ()", [NETSOCKET_T]);
|
|
1168
|
+
return { kind: "libCall", fn: "http.serverOnTimeout", args: [receiver, cb, once], type: VOID, loc };
|
|
1169
|
+
}
|
|
1143
1170
|
if (event === "listening") {
|
|
1144
1171
|
// The deferred bind emit — listen(port, cb)'s event twin: fires
|
|
1145
1172
|
// once after a successful listen; late registrations on an
|
|
@@ -1525,6 +1552,15 @@ function trailersSnapshotHelper(lowerer, shapeId, loc) {
|
|
|
1525
1552
|
callArgs: [varRef("r.0", HTTPREQ_T, loc)],
|
|
1526
1553
|
});
|
|
1527
1554
|
}
|
|
1555
|
+
function distinctSnapshotHelper(lowerer, shapeId, loc, collection) {
|
|
1556
|
+
return pairsSnapshotHelper(lowerer, shapeId, loc, {
|
|
1557
|
+
keyPrefix: collection,
|
|
1558
|
+
libCall: collection === "headersDistinct" ? "http.reqHeaderPairs" : "http.reqTrailerPairs",
|
|
1559
|
+
lookupValue: collection === "headersDistinct" ? "http.reqHeaderValues" : "http.reqTrailerValues",
|
|
1560
|
+
params: [{ localId: "r.0", name: "r", type: HTTPREQ_T }],
|
|
1561
|
+
callArgs: [varRef("r.0", HTTPREQ_T, loc)],
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1528
1564
|
/** The `endStream` boolean of an h2 options object literal, as a literal
|
|
1529
1565
|
* bool. Returns undefined when absent (or the arg is absent). Fences on
|
|
1530
1566
|
* a non-literal endStream value or unknown keys that would matter. */
|
|
@@ -1797,6 +1833,10 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1797
1833
|
// req.headers.NAME — the `string | undefined` union (envGet's type).
|
|
1798
1834
|
const recvKind = lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind;
|
|
1799
1835
|
if (recvKind === "netServer" && lowerer.isStdlibMember(expr)) {
|
|
1836
|
+
if (expr.name.text === "listening") {
|
|
1837
|
+
const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
|
|
1838
|
+
return { kind: "libCall", fn: "net.serverListening", args: [receiver], type: BOOL, loc };
|
|
1839
|
+
}
|
|
1800
1840
|
const field = httpServerTimeoutField(expr.name.text);
|
|
1801
1841
|
if (field !== null) {
|
|
1802
1842
|
const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
|
|
@@ -1817,7 +1857,7 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1817
1857
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1818
1858
|
return { kind: "libCall", fn: "http.reqStatusCode", args: [receiver], type: lowerer.withUndefinedArm(F64), loc };
|
|
1819
1859
|
}
|
|
1820
|
-
if (name === "socket") {
|
|
1860
|
+
if (name === "socket" || name === "connection") {
|
|
1821
1861
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1822
1862
|
return { kind: "libCall", fn: "http.reqSocket", args: [receiver], type: NETSOCKET_T, loc };
|
|
1823
1863
|
}
|
|
@@ -1879,15 +1919,15 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1879
1919
|
// guarded-no-op / unguarded-TypeError stance; other reads fence.
|
|
1880
1920
|
lowerer.noLowering(`reading '${name}' (an HTTP/2-only member) from a request`, expr, "compatibility requests do not expose their backing h2 stream/session yet; guarded method calls no-op and other reads have no lowering");
|
|
1881
1921
|
}
|
|
1882
|
-
if (name === "headers" || name === "trailers") {
|
|
1883
|
-
//
|
|
1884
|
-
//
|
|
1885
|
-
// copies too; the per-name READS keep their direct lowerings).
|
|
1922
|
+
if (name === "headers" || name === "trailers" || name === "headersDistinct" || name === "trailersDistinct") {
|
|
1923
|
+
// Whole-object reads materialize a typed snapshot record. Per-name
|
|
1924
|
+
// reads retain their direct lowerings.
|
|
1886
1925
|
const mapped = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
1887
1926
|
if (mapped?.kind === "record") {
|
|
1888
1927
|
const helper = name === "headers"
|
|
1889
1928
|
? headersSnapshotHelper(lowerer, mapped.shapeId, loc)
|
|
1890
|
-
: trailersSnapshotHelper(lowerer, mapped.shapeId, loc)
|
|
1929
|
+
: name === "trailers" ? trailersSnapshotHelper(lowerer, mapped.shapeId, loc)
|
|
1930
|
+
: distinctSnapshotHelper(lowerer, mapped.shapeId, loc, name);
|
|
1891
1931
|
if (helper !== null) {
|
|
1892
1932
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1893
1933
|
return { kind: "call", callee: helper, args: [receiver], type: mapped, loc };
|
|
@@ -1895,9 +1935,6 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1895
1935
|
}
|
|
1896
1936
|
lowerer.unsupported("SC1090", expr, `req.${name} as a value of this type (read one field: req.${name}.name or req.${name}[name])`);
|
|
1897
1937
|
}
|
|
1898
|
-
if (name === "headersDistinct" || name === "trailersDistinct") {
|
|
1899
|
-
lowerer.unsupported("SC1090", expr, `req.${name} as a value (read one name with req.${name}[name])`);
|
|
1900
|
-
}
|
|
1901
1938
|
}
|
|
1902
1939
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "stream") {
|
|
1903
1940
|
lowerer.noLowering("reading 'stream' (an HTTP/2-only member) from a response", expr, "compatibility responses do not expose their backing h2 stream yet — guard method calls with '?.' or drop the use");
|
|
@@ -1965,10 +2002,35 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1965
2002
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
1966
2003
|
return { kind: "libCall", fn: "http.clientDestroyed", args: [receiver], type: BOOL, loc };
|
|
1967
2004
|
}
|
|
2005
|
+
if (recvKind === "httpClientReq" && lowerer.isStdlibMember(expr) &&
|
|
2006
|
+
(expr.name.text === "socket" || expr.name.text === "connection")) {
|
|
2007
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2008
|
+
return { kind: "libCall", fn: "http.clientSocket", args: [receiver], type: NETSOCKET_T, loc };
|
|
2009
|
+
}
|
|
1968
2010
|
if (recvKind === "httpClientReq" && lowerer.isStdlibMember(expr) && expr.name.text === "writableCorked") {
|
|
1969
2011
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
1970
2012
|
return { kind: "libCall", fn: "http.clientWritableCorked", args: [receiver], type: F64, loc };
|
|
1971
2013
|
}
|
|
2014
|
+
if (recvKind === "httpClientReq" && lowerer.isStdlibMember(expr)) {
|
|
2015
|
+
const name = expr.name.text;
|
|
2016
|
+
const strFn = name === "method" ? "http.clientMethod"
|
|
2017
|
+
: name === "path" ? "http.clientPath"
|
|
2018
|
+
: name === "host" ? "http.clientHost"
|
|
2019
|
+
: name === "protocol" ? "http.clientProtocol" : null;
|
|
2020
|
+
if (strFn !== null) {
|
|
2021
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2022
|
+
return { kind: "libCall", fn: strFn, args: [receiver], type: STRING, loc };
|
|
2023
|
+
}
|
|
2024
|
+
const boolFn = name === "aborted" ? "http.clientAborted"
|
|
2025
|
+
: name === "headersSent" ? "http.clientHeadersSent"
|
|
2026
|
+
: name === "writableEnded" || name === "finished" ? "http.clientWritableEnded"
|
|
2027
|
+
: name === "writableFinished" ? "http.clientWritableFinished"
|
|
2028
|
+
: name === "reusedSocket" ? "http.clientReusedSocket" : null;
|
|
2029
|
+
if (boolFn !== null) {
|
|
2030
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2031
|
+
return { kind: "libCall", fn: boolFn, args: [receiver], type: BOOL, loc };
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
1972
2034
|
if (httpReqFieldCollection(lowerer, expr.expression) !== null) {
|
|
1973
2035
|
const collection = httpReqFieldCollection(lowerer, expr.expression);
|
|
1974
2036
|
const receiver = coerceToHandle(lowerer, expr.expression.expression, HTTPREQ_T);
|
|
@@ -1983,6 +2045,14 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1983
2045
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
1984
2046
|
return { kind: "libCall", fn: "http.resHeadersSent", args: [receiver], type: BOOL, loc };
|
|
1985
2047
|
}
|
|
2048
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "writableEnded") {
|
|
2049
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2050
|
+
return { kind: "libCall", fn: "http.resWritableEnded", args: [receiver], type: BOOL, loc };
|
|
2051
|
+
}
|
|
2052
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "finished") {
|
|
2053
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2054
|
+
return { kind: "libCall", fn: "http.resWritableEnded", args: [receiver], type: BOOL, loc };
|
|
2055
|
+
}
|
|
1986
2056
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "writableCorked") {
|
|
1987
2057
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
1988
2058
|
return { kind: "libCall", fn: "http.resWritableCorked", args: [receiver], type: F64, loc };
|
|
@@ -1994,11 +2064,30 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1994
2064
|
return { kind: "libCall", fn: "http.resStatusGet", args: [receiver], type: F64, loc };
|
|
1995
2065
|
}
|
|
1996
2066
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "statusMessage") {
|
|
1997
|
-
//
|
|
1998
|
-
// when none was set (Node answers undefined until the head goes out
|
|
1999
|
-
// — divergence: this surface is string-typed, the checker's shape).
|
|
2067
|
+
// Unset until the head is sent; then the assigned or default reason.
|
|
2000
2068
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2001
|
-
return { kind: "libCall", fn: "http.resStatusMsgGet", args: [receiver], type: STRING, loc };
|
|
2069
|
+
return { kind: "libCall", fn: "http.resStatusMsgGet", args: [receiver], type: lowerer.withUndefinedArm(STRING), loc };
|
|
2070
|
+
}
|
|
2071
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr)) {
|
|
2072
|
+
const name = expr.name.text;
|
|
2073
|
+
if (name === "req") {
|
|
2074
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2075
|
+
return { kind: "libCall", fn: "http.resRequest", args: [receiver], type: HTTPREQ_T, loc };
|
|
2076
|
+
}
|
|
2077
|
+
if (name === "socket" || name === "connection") {
|
|
2078
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2079
|
+
const type = { kind: "union", unionId: lowerer.unions.intern([NETSOCKET_T, NULL_T]) };
|
|
2080
|
+
return { kind: "libCall", fn: "http.resSocket", args: [receiver], type, loc };
|
|
2081
|
+
}
|
|
2082
|
+
if (name === "writableFinished") {
|
|
2083
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2084
|
+
return { kind: "libCall", fn: "http.resWritableFinished", args: [receiver], type: BOOL, loc };
|
|
2085
|
+
}
|
|
2086
|
+
if (name === "sendDate" || name === "strictContentLength") {
|
|
2087
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2088
|
+
const fn = name === "sendDate" ? "http.resSendDateGet" : "http.resStrictContentLengthGet";
|
|
2089
|
+
return { kind: "libCall", fn, args: [receiver], type: BOOL, loc };
|
|
2090
|
+
}
|
|
2002
2091
|
}
|
|
2003
2092
|
if (recvKind === "http2Session" && lowerer.isStdlibMember(expr)) {
|
|
2004
2093
|
const m = expr.name.text;
|
|
@@ -2389,13 +2478,33 @@ export function lowerHttpServerNew(lowerer, expr) {
|
|
|
2389
2478
|
* (req, res), (req), or () — runtime adapters bridge each shape.
|
|
2390
2479
|
* Everything else the module declares fences qualified. */
|
|
2391
2480
|
function lowerHttpModuleCall(lowerer, expr, bi, loc) {
|
|
2481
|
+
if (bi.member === "validateHeaderName") {
|
|
2482
|
+
requireStatementPosition(lowerer, expr, "http.validateHeaderName(...)");
|
|
2483
|
+
if (expr.arguments.length < 1 || expr.arguments.length > 2 || expr.arguments.some(ts.isSpreadElement)) {
|
|
2484
|
+
lowerer.noLowering("http.validateHeaderName arguments", expr, "pass a header name and an optional label");
|
|
2485
|
+
}
|
|
2486
|
+
const name = lowerer.lowerExprExpecting(expr.arguments[0], STRING);
|
|
2487
|
+
const label = expr.arguments.length === 2
|
|
2488
|
+
? lowerer.lowerExprExpecting(expr.arguments[1], STRING)
|
|
2489
|
+
: strLit("Header name", loc);
|
|
2490
|
+
return { kind: "libCall", fn: "http.validateHeaderName", args: [name, label], type: VOID, loc };
|
|
2491
|
+
}
|
|
2492
|
+
if (bi.member === "validateHeaderValue") {
|
|
2493
|
+
requireStatementPosition(lowerer, expr, "http.validateHeaderValue(...)");
|
|
2494
|
+
if (expr.arguments.length !== 2 || expr.arguments.some(ts.isSpreadElement)) {
|
|
2495
|
+
lowerer.noLowering("http.validateHeaderValue arguments", expr, "pass a header name and a value");
|
|
2496
|
+
}
|
|
2497
|
+
const name = lowerer.lowerExprExpecting(expr.arguments[0], STRING);
|
|
2498
|
+
const value = lowerer.lowerExprExpecting(expr.arguments[1], DYN);
|
|
2499
|
+
return { kind: "libCall", fn: "http.validateHeaderValue", args: [name, value], type: VOID, loc };
|
|
2500
|
+
}
|
|
2392
2501
|
if (bi.member === "createServer" || bi.member === "Server") {
|
|
2393
2502
|
return lowerHttpCreateServerForms(lowerer, expr, `http.${bi.member}`, loc);
|
|
2394
2503
|
}
|
|
2395
2504
|
if (bi.member === "request" || bi.member === "get") {
|
|
2396
2505
|
return lowerHttpClientCall(lowerer, expr, bi.member, loc);
|
|
2397
2506
|
}
|
|
2398
|
-
lowerer.noLowering(`http.${bi.member}`, expr, "createServer, Server, request, and
|
|
2507
|
+
lowerer.noLowering(`http.${bi.member}`, expr, "createServer, Server, request, get, validateHeaderName, and validateHeaderValue are the lowered http module functions", lowerer.resolveValueSymbol(expr.expression));
|
|
2399
2508
|
}
|
|
2400
2509
|
/** The cert/key PEM option of tls.createServer / https.createServer: an
|
|
2401
2510
|
* OBJECT LITERAL whose lowered `cert` and `key` entries are strings or
|
|
@@ -3664,6 +3773,35 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3664
3773
|
const name = access.name.text;
|
|
3665
3774
|
const loc = locOf(call);
|
|
3666
3775
|
const args = call.arguments;
|
|
3776
|
+
if (name === "setHeader") {
|
|
3777
|
+
requireStatementPosition(lowerer, call, "request.setHeader(...)");
|
|
3778
|
+
if (args.length !== 2)
|
|
3779
|
+
lowerer.noLowering("request.setHeader arguments", call, "pass a name and string value");
|
|
3780
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3781
|
+
const header = lowerer.lowerExprExpecting(args[0], STRING);
|
|
3782
|
+
const value = lowerer.lowerExprExpecting(args[1], STRING);
|
|
3783
|
+
return { kind: "libCall", fn: "http.clientSetHeader", args: [receiver, header, value], type: VOID, loc };
|
|
3784
|
+
}
|
|
3785
|
+
if (name === "getHeader" || name === "hasHeader" || name === "removeHeader") {
|
|
3786
|
+
if (name === "removeHeader")
|
|
3787
|
+
requireStatementPosition(lowerer, call, "request.removeHeader(...)");
|
|
3788
|
+
if (args.length !== 1)
|
|
3789
|
+
lowerer.noLowering(`request.${name} arguments`, call, `pass one header name`);
|
|
3790
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3791
|
+
const header = lowerer.lowerExprExpecting(args[0], STRING);
|
|
3792
|
+
const fn = name === "getHeader" ? "http.clientGetHeader"
|
|
3793
|
+
: name === "hasHeader" ? "http.clientHasHeader" : "http.clientRemoveHeader";
|
|
3794
|
+
const type = name === "getHeader" ? lowerer.envValueType() : name === "hasHeader" ? BOOL : VOID;
|
|
3795
|
+
return { kind: "libCall", fn, args: [receiver, header], type, loc };
|
|
3796
|
+
}
|
|
3797
|
+
if (name === "getHeaderNames" || name === "getRawHeaderNames" || name === "getHeaders") {
|
|
3798
|
+
if (args.length !== 0)
|
|
3799
|
+
lowerer.noLowering(`request.${name} arguments`, call, `${name}() takes no arguments`);
|
|
3800
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3801
|
+
const fn = name === "getHeaderNames" ? "http.clientGetHeaderNames"
|
|
3802
|
+
: name === "getRawHeaderNames" ? "http.clientGetRawHeaderNames" : "http.clientGetHeaders";
|
|
3803
|
+
return { kind: "libCall", fn, args: [receiver], type: name === "getHeaders" ? DYN : arrayOf(STRING), loc };
|
|
3804
|
+
}
|
|
3667
3805
|
if (name === "flushHeaders" || name === "cork" || name === "uncork") {
|
|
3668
3806
|
requireStatementPosition(lowerer, call, `request.${name}()`);
|
|
3669
3807
|
if (args.length !== 0)
|
|
@@ -3673,6 +3811,37 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3673
3811
|
: name === "cork" ? "http.clientCork" : "http.clientUncork";
|
|
3674
3812
|
return { kind: "libCall", fn, args: [receiver], type: VOID, loc };
|
|
3675
3813
|
}
|
|
3814
|
+
if (name === "setNoDelay") {
|
|
3815
|
+
requireStatementPosition(lowerer, call, "request.setNoDelay(...)");
|
|
3816
|
+
if (args.length > 1)
|
|
3817
|
+
lowerer.noLowering("request.setNoDelay arguments", call, "pass an optional boolean");
|
|
3818
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3819
|
+
const enable = args.length === 0 ? boolLit(true, loc) : lowerer.lowerExprExpecting(args[0], BOOL);
|
|
3820
|
+
return { kind: "libCall", fn: "http.clientSetNoDelay", args: [receiver, enable], type: VOID, loc };
|
|
3821
|
+
}
|
|
3822
|
+
if (name === "setSocketKeepAlive") {
|
|
3823
|
+
requireStatementPosition(lowerer, call, "request.setSocketKeepAlive(...)");
|
|
3824
|
+
if (args.length > 2)
|
|
3825
|
+
lowerer.noLowering("request.setSocketKeepAlive arguments", call, "pass an optional boolean and initial delay in milliseconds");
|
|
3826
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3827
|
+
const enable = args.length === 0 ? boolLit(true, loc) : lowerer.lowerExprExpecting(args[0], BOOL);
|
|
3828
|
+
const delay = args.length < 2 ? numLit(0, loc) : lowerer.lowerExprExpecting(args[1], F64);
|
|
3829
|
+
return { kind: "libCall", fn: "http.clientSetSocketKeepAlive", args: [receiver, enable, delay], type: VOID, loc };
|
|
3830
|
+
}
|
|
3831
|
+
if (name === "setTimeout") {
|
|
3832
|
+
if (args.length < 1 || args.length > 2)
|
|
3833
|
+
lowerer.noLowering("request.setTimeout arguments", call, "pass milliseconds and an optional callback");
|
|
3834
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3835
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
3836
|
+
const cb = args.length === 2
|
|
3837
|
+
? lowerCallbackArg(lowerer, args[1], "request timeout callbacks", 0, () => false, "use ()", []).cb
|
|
3838
|
+
: null;
|
|
3839
|
+
const fn = cb === null ? "http.clientSetTimeout" : "http.clientSetTimeoutCb";
|
|
3840
|
+
const callArgs = cb === null ? [receiver, ms] : [receiver, ms, cb];
|
|
3841
|
+
if (resultIsDiscarded(call))
|
|
3842
|
+
return { kind: "libCall", fn, args: callArgs, type: VOID, loc };
|
|
3843
|
+
return receiverReturningCall(lowerer, fn, callArgs, HTTPCLIENTREQ_T, loc);
|
|
3844
|
+
}
|
|
3676
3845
|
if (name === "addTrailers") {
|
|
3677
3846
|
requireStatementPosition(lowerer, call, "request.addTrailers(...)");
|
|
3678
3847
|
if (args.length !== 1)
|
|
@@ -3707,13 +3876,13 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3707
3876
|
}
|
|
3708
3877
|
lowerer.noLowering(`${name} of '${lowerer.fmt(data.type)}' data`, args[0] ?? call, NARROW_DATA_HINT);
|
|
3709
3878
|
}
|
|
3710
|
-
if (name === "destroy") {
|
|
3711
|
-
requireStatementPosition(lowerer, call,
|
|
3879
|
+
if (name === "destroy" || name === "abort") {
|
|
3880
|
+
requireStatementPosition(lowerer, call, `request.${name}()`);
|
|
3712
3881
|
if (args.length !== 0) {
|
|
3713
|
-
lowerer.noLowering(
|
|
3882
|
+
lowerer.noLowering(`${name} with ${args.length} arguments`, call, `${name}() takes no arguments here`);
|
|
3714
3883
|
}
|
|
3715
3884
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
3716
|
-
return { kind: "libCall", fn: "http.clientDestroy", args: [receiver], type: VOID, loc };
|
|
3885
|
+
return { kind: "libCall", fn: name === "destroy" ? "http.clientDestroy" : "http.clientAbort", args: [receiver], type: VOID, loc };
|
|
3717
3886
|
}
|
|
3718
3887
|
if ((name === "on" || name === "once" || name === "addListener") && args.length === 2) {
|
|
3719
3888
|
requireStatementPosition(lowerer, call, `request.${name}(...)`);
|
|
@@ -3725,13 +3894,19 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3725
3894
|
const { cb } = lowerCallbackArg(lowerer, args[1], "response listeners", 1, (p) => p.kind === "httpReq", "use (res) or ()", [HTTPREQ_T]);
|
|
3726
3895
|
return { kind: "libCall", fn: "http.clientOnResponse", args: [receiver, cb, once], type: VOID, loc };
|
|
3727
3896
|
}
|
|
3897
|
+
if (event === "socket") {
|
|
3898
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "socket listeners", 1, (p) => p.kind === "netSocket", "use (socket) or ()", [NETSOCKET_T]);
|
|
3899
|
+
return { kind: "libCall", fn: "http.clientOnSocket", args: [receiver, cb, once], type: VOID, loc };
|
|
3900
|
+
}
|
|
3728
3901
|
if (event === "error") {
|
|
3729
3902
|
const { cb } = lowerCallbackArg(lowerer, args[1], "error listeners", 1, (p) => p.kind === "object" && p.className === "%Error", "use (err) or ()", [ERROR_T]);
|
|
3730
3903
|
return { kind: "libCall", fn: "http.clientOnError", args: [receiver, cb, once], type: VOID, loc };
|
|
3731
3904
|
}
|
|
3732
|
-
if (event === "timeout" || event === "close") {
|
|
3905
|
+
if (event === "timeout" || event === "close" || event === "finish" || event === "abort") {
|
|
3733
3906
|
const { cb } = lowerCallbackArg(lowerer, args[1], `${event} listeners`, 0, () => false, "use ()", []);
|
|
3734
|
-
const fn = event === "timeout" ? "http.clientOnTimeout"
|
|
3907
|
+
const fn = event === "timeout" ? "http.clientOnTimeout"
|
|
3908
|
+
: event === "close" ? "http.clientOnClose"
|
|
3909
|
+
: event === "abort" ? "http.clientOnAbort" : "http.clientOnFinish";
|
|
3735
3910
|
return { kind: "libCall", fn, args: [receiver, cb, once], type: VOID, loc };
|
|
3736
3911
|
}
|
|
3737
3912
|
if (event === "upgrade") {
|
|
@@ -3753,9 +3928,9 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3753
3928
|
}
|
|
3754
3929
|
return { kind: "libCall", fn: "http.clientOnUpgrade", args: [receiver, cb, once], type: VOID, loc };
|
|
3755
3930
|
}
|
|
3756
|
-
lowerer.noLowering(`request.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"response", "upgrade", "error", "timeout", and "close" are the supported request events (as literals)');
|
|
3931
|
+
lowerer.noLowering(`request.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"response", "socket", "upgrade", "error", "timeout", "finish", "abort", and "close" are the supported request events (as literals)');
|
|
3757
3932
|
}
|
|
3758
|
-
lowerer.noLowering(`ClientRequest.${name}`, call, "write, end, destroy,
|
|
3933
|
+
lowerer.noLowering(`ClientRequest.${name}`, call, "header reads/mutations, write, end, destroy, and on/once of response/error/timeout/close are the supported ClientRequest members", lowerer.checker.getSymbolAtLocation(access.name));
|
|
3759
3934
|
}
|
|
3760
3935
|
/** True when `node` is the h2-only stream/session CALL shape —
|
|
3761
3936
|
* `req.stream.destroy()` / `req.session.m(...)` on an identifier
|
|
@@ -3849,6 +4024,17 @@ function lowerHttpReqMethodCall(lowerer, call, access) {
|
|
|
3849
4024
|
const name = access.name.text;
|
|
3850
4025
|
const loc = locOf(call);
|
|
3851
4026
|
const args = call.arguments;
|
|
4027
|
+
if (name === "setTimeout") {
|
|
4028
|
+
requireStatementPosition(lowerer, call, "message.setTimeout(...)");
|
|
4029
|
+
if (args.length < 1 || args.length > 2)
|
|
4030
|
+
lowerer.noLowering("message.setTimeout arguments", call, "pass milliseconds and an optional callback");
|
|
4031
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPREQ_T);
|
|
4032
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
4033
|
+
if (args.length === 1)
|
|
4034
|
+
return { kind: "libCall", fn: "http.reqSetTimeout", args: [receiver, ms], type: VOID, loc };
|
|
4035
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "message timeout callbacks", 0, () => false, "use ()", []);
|
|
4036
|
+
return { kind: "libCall", fn: "http.reqSetTimeoutCb", args: [receiver, ms, cb], type: VOID, loc };
|
|
4037
|
+
}
|
|
3852
4038
|
if (name === "resume" || name === "destroy") {
|
|
3853
4039
|
requireStatementPosition(lowerer, call, `req.${name}()`);
|
|
3854
4040
|
if (args.length !== 0) {
|
|
@@ -3931,6 +4117,72 @@ function lowerHttpResMethodCall(lowerer, call, access) {
|
|
|
3931
4117
|
const name = access.name.text;
|
|
3932
4118
|
const loc = locOf(call);
|
|
3933
4119
|
const args = call.arguments;
|
|
4120
|
+
if (name === "setTimeout") {
|
|
4121
|
+
if (args.length < 1 || args.length > 2) {
|
|
4122
|
+
lowerer.noLowering(`res.setTimeout with ${args.length} arguments`, call, "use setTimeout(milliseconds[, callback])");
|
|
4123
|
+
}
|
|
4124
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4125
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
4126
|
+
const cb = args.length === 2
|
|
4127
|
+
? lowerCallbackArg(lowerer, args[1], "response timeout callbacks", 0, () => false, "use ()", []).cb
|
|
4128
|
+
: null;
|
|
4129
|
+
const fn = cb === null ? "http.resSetTimeout" : "http.resSetTimeoutCb";
|
|
4130
|
+
const callArgs = cb === null ? [receiver, ms] : [receiver, ms, cb];
|
|
4131
|
+
if (resultIsDiscarded(call))
|
|
4132
|
+
return { kind: "libCall", fn, args: callArgs, type: VOID, loc };
|
|
4133
|
+
return receiverReturningCall(lowerer, fn, callArgs, HTTPRES_T, loc);
|
|
4134
|
+
}
|
|
4135
|
+
if (name === "writeContinue" || name === "writeProcessing" || name === "writeEarlyHints") {
|
|
4136
|
+
requireStatementPosition(lowerer, call, `res.${name}(...)`);
|
|
4137
|
+
if (lowerer.typeOf(access.expression).getSymbol()?.name === "Http2ServerResponse") {
|
|
4138
|
+
lowerer.noLowering(`Http2ServerResponse.${name}`, call, "HTTP/2 informational responses are not supported by the static runtime yet");
|
|
4139
|
+
}
|
|
4140
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4141
|
+
if (name !== "writeEarlyHints") {
|
|
4142
|
+
if (args.length !== 0)
|
|
4143
|
+
lowerer.noLowering(`res.${name} callback`, call, `${name}() supports no callback here`);
|
|
4144
|
+
return { kind: "libCall", fn: name === "writeContinue" ? "http.resWriteContinue" : "http.resWriteProcessing", args: [receiver], type: VOID, loc };
|
|
4145
|
+
}
|
|
4146
|
+
if (args.length !== 1)
|
|
4147
|
+
lowerer.noLowering("res.writeEarlyHints arguments", call, "pass one header object or Record<string, string> without a callback");
|
|
4148
|
+
const node = args[0];
|
|
4149
|
+
let pairs;
|
|
4150
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
4151
|
+
const elems = [];
|
|
4152
|
+
for (const prop of node.properties) {
|
|
4153
|
+
const key = ts.isPropertyAssignment(prop) ? staticHeaderKeyOf(lowerer, prop) : null;
|
|
4154
|
+
if (!ts.isPropertyAssignment(prop) || key === null) {
|
|
4155
|
+
lowerer.noLowering("writeEarlyHints headers with dynamic keys, spreads, or shorthand entries", prop, "use literal header keys and string values");
|
|
4156
|
+
}
|
|
4157
|
+
const value = lowerer.lowerExpr(prop.initializer);
|
|
4158
|
+
if (value.type.kind !== "string") {
|
|
4159
|
+
lowerer.noLowering(`writeEarlyHints value of type '${lowerer.fmt(value.type)}'`, prop.initializer, "header values must be strings here");
|
|
4160
|
+
}
|
|
4161
|
+
elems.push({ kind: "strLit", value: key, type: STRING, loc }, value);
|
|
4162
|
+
}
|
|
4163
|
+
pairs = { kind: "arrayLit", elems, type: arrayOf(STRING), loc };
|
|
4164
|
+
}
|
|
4165
|
+
else {
|
|
4166
|
+
const value = lowerer.lowerExpr(node);
|
|
4167
|
+
if (value.type.kind !== "record") {
|
|
4168
|
+
lowerer.noLowering(`writeEarlyHints headers of '${lowerer.fmt(value.type)}'`, node, "pass an object literal or a Record<string, string>");
|
|
4169
|
+
}
|
|
4170
|
+
const helper = lowerer.envToPairsHelper(value.type.shapeId, loc);
|
|
4171
|
+
if (helper === null) {
|
|
4172
|
+
lowerer.noLowering("writeEarlyHints header values", node, "use a Record<string, string> with string values");
|
|
4173
|
+
}
|
|
4174
|
+
pairs = { kind: "call", callee: helper, args: [value], type: arrayOf(STRING), loc };
|
|
4175
|
+
}
|
|
4176
|
+
return { kind: "libCall", fn: "http.resWriteEarlyHints", args: [receiver, pairs], type: VOID, loc };
|
|
4177
|
+
}
|
|
4178
|
+
if (name === "getHeaderNames" || name === "getRawHeaderNames" || name === "getHeaders") {
|
|
4179
|
+
if (args.length !== 0)
|
|
4180
|
+
lowerer.noLowering(`res.${name} arguments`, call, `${name}() takes no arguments`);
|
|
4181
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4182
|
+
const fn = name === "getHeaderNames" ? "http.resGetHeaderNames"
|
|
4183
|
+
: name === "getRawHeaderNames" ? "http.resGetRawHeaderNames" : "http.resGetHeaders";
|
|
4184
|
+
return { kind: "libCall", fn, args: [receiver], type: name === "getHeaders" ? DYN : arrayOf(STRING), loc };
|
|
4185
|
+
}
|
|
3934
4186
|
if (name === "flushHeaders" || name === "cork" || name === "uncork") {
|
|
3935
4187
|
requireStatementPosition(lowerer, call, `res.${name}()`);
|
|
3936
4188
|
if (args.length !== 0)
|
|
@@ -4197,8 +4449,12 @@ function lowerHttpResMethodCall(lowerer, call, access) {
|
|
|
4197
4449
|
const { cb } = lowerCallbackArg(lowerer, args[1], "close listeners", 0, () => false, "use ()", []);
|
|
4198
4450
|
return { kind: "libCall", fn: "http.resOnClose", args: [receiver, cb, once], type: VOID, loc };
|
|
4199
4451
|
}
|
|
4200
|
-
|
|
4452
|
+
if (event === "finish") {
|
|
4453
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "finish listeners", 0, () => false, "use ()", []);
|
|
4454
|
+
return { kind: "libCall", fn: "http.resOnFinish", args: [receiver, cb], type: VOID, loc };
|
|
4455
|
+
}
|
|
4456
|
+
lowerer.noLowering(`res.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"close" and "finish" are the supported response events (as literals)');
|
|
4201
4457
|
}
|
|
4202
|
-
lowerer.noLowering(`ServerResponse.${name}`, call, "setHeader, getHeader, hasHeader, removeHeader, writeHead, write, end, destroy,
|
|
4458
|
+
lowerer.noLowering(`ServerResponse.${name}`, call, "setHeader, getHeader, hasHeader, removeHeader, writeHead, writeContinue, writeProcessing, writeEarlyHints, setTimeout, write, end, destroy, response state reads, and on/once of close are the supported ServerResponse members", lowerer.checker.getSymbolAtLocation(access.name));
|
|
4203
4459
|
}
|
|
4204
4460
|
//# sourceMappingURL=lower-server.js.map
|