diff --git a/packages/tests/src/core/Example_test.res b/packages/tests/src/core/Example_test.res index dc409d38..a408ae17 100644 --- a/packages/tests/src/core/Example_test.res +++ b/packages/tests/src/core/Example_test.res @@ -69,7 +69,7 @@ test("Compiled parse code snapshot", t => { t->U.assertCompiledCode( ~schema=filmSchema, ~op=#parse, - `i=>{if(!i||i.constructor!==Object){e[11](i)}let v0,v1,v2,v7,v8=i["Rating"],v9,v14,v15;v0=i["Id"];if(typeof v0!=="number"||Number.isNaN(v0)){e[0](v0)}v1=i["Title"];if(typeof v1!=="string"){e[1](v1)}v2=i["Tags"];if(v2!==void 0&&(!Array.isArray(v2))){e[2](v2)}if(v2!==void 0){let v6=[];for(let v3=0;v32147483647||v14<-2147483648||v14%1!==0)){e[10](v14)}if(v14!==void 0){v15=v14}return {"id":v0,"title":v1,"tags":v7===void 0?e[4]:v7,"rating":v9,"deprecatedAgeRestriction":v15,}}`, + `i=>{if(!i||i.constructor!==Object){e[11](i)}let v0=i["Id"],v1=i["Title"],v2=i["Tags"],v7,v8=i["Rating"],v9,v14=i["Age"],v15;if(typeof v0!=="number"||Number.isNaN(v0)){e[0](v0)}if(typeof v1!=="string"){e[1](v1)}if(v2!==void 0&&(!Array.isArray(v2))){e[2](v2)}if(v2!==void 0){let v6=[];for(let v3=0;v32147483647||v14<-2147483648||v14%1!==0)){e[10](v14)}if(v14!==void 0){v15=v14}return {"id":v0,"title":v1,"tags":v7===void 0?e[4]:v7,"rating":v9,"deprecatedAgeRestriction":v15,}}`, ) }) @@ -77,6 +77,6 @@ test("Compiled serialize code snapshot", t => { t->U.assertCompiledCode( ~schema=filmSchema, ~op=#serialize, - `i=>{let v0=i["tags"],v1,v2=i["rating"],v3,v8=i["deprecatedAgeRestriction"],v9;if(v0!==void 0){v1=e[0](v0)}try{v2==="G"||e[1](v2);v3=v2}catch(v4){if(v4&&v4.s===s){try{v2==="PG"||e[2](v2);v3=v2}catch(v5){if(v5&&v5.s===s){try{v2==="PG13"||e[3](v2);v3=v2}catch(v6){if(v6&&v6.s===s){try{v2==="R"||e[4](v2);v3=v2}catch(v7){if(v7&&v7.s===s){e[5]([v4,v5,v6,v7,])}else{throw v7}}}else{throw v6}}}else{throw v5}}}else{throw v4}}if(v8!==void 0){v9=e[6](v8)}return {"Id":i["id"],"Title":i["title"],"Tags":v1,"Rating":v3,"Age":v9,}}`, + `i=>{let v0=i["tags"],v1,v2,v4=i["rating"],v8=i["deprecatedAgeRestriction"],v9;if(v0!==void 0){v1=e[0](v0)}try{v4==="G"||e[1](v4);v2=v4}catch(v3){if(v3&&v3.s===s){try{v4==="PG"||e[2](v4);v2=v4}catch(v5){if(v5&&v5.s===s){try{v4==="PG13"||e[3](v4);v2=v4}catch(v6){if(v6&&v6.s===s){try{v4==="R"||e[4](v4);v2=v4}catch(v7){if(v7&&v7.s===s){e[5]([v3,v5,v6,v7,])}else{throw v7}}}else{throw v6}}}else{throw v5}}}else{throw v3}}if(v8!==void 0){v9=e[6](v8)}return {"Id":i["id"],"Title":i["title"],"Tags":v1,"Rating":v2,"Age":v9,}}`, ) }) diff --git a/packages/tests/src/core/S_array_test.res b/packages/tests/src/core/S_array_test.res index 1a4c5d11..22767616 100644 --- a/packages/tests/src/core/S_array_test.res +++ b/packages/tests/src/core/S_array_test.res @@ -52,7 +52,7 @@ module CommonWithNested = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!Array.isArray(i)){e[1](i)}let v3=[];for(let v0=0;v0{if(!Array.isArray(i)){e[1](i)}let v3=[];for(let v0=0;v0U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!i||i.constructor!==Object){e[1](i)}let v1;v1={};for(let v0 in i){let v3;try{v3=i[v0];if(typeof v3!=="string"){e[0](v3)}}catch(v2){if(v2&&v2.s===s){v2.path=""+\'["\'+v0+\'"]\'+v2.path}throw v2}v1[v0]=v3}return v1}`, + `i=>{if(!i||i.constructor!==Object){e[1](i)}let v1;v1={};for(let v0 in i){let v3=i[v0];try{if(typeof v3!=="string"){e[0](v3)}}catch(v2){if(v2&&v2.s===s){v2.path=""+\'["\'+v0+\'"]\'+v2.path}throw v2}v1[v0]=v3}return v1}`, ) }) diff --git a/packages/tests/src/core/S_object_test.res b/packages/tests/src/core/S_object_test.res index a02be462..bd369ee0 100644 --- a/packages/tests/src/core/S_object_test.res +++ b/packages/tests/src/core/S_object_test.res @@ -986,7 +986,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!i||i.constructor!==Object){e[2](i)}let v0,v1;v0=i["foo"];if(typeof v0!=="string"){e[0](v0)}v1=i["bar"];if(typeof v1!=="boolean"){e[1](v1)}return {"foo":v0,"bar":v1,}}`, + `i=>{if(!i||i.constructor!==Object){e[2](i)}let v0=i["foo"],v1=i["bar"];if(typeof v0!=="string"){e[0](v0)}if(typeof v1!=="boolean"){e[1](v1)}return {"foo":v0,"bar":v1,}}`, ) }) @@ -1004,7 +1004,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!i||i.constructor!==Object){e[2](i)}let v0,v1,v2=()=>Promise.all([v0()]).then(([v0])=>({"foo":v0,"bar":v1,}));v0=e[0](i["foo"]);v1=i["bar"];if(typeof v1!=="boolean"){e[1](v1)}return v2}`, + `i=>{if(!i||i.constructor!==Object){e[2](i)}let v0,v1=i["bar"],v2=()=>Promise.all([v0()]).then(([v0])=>({"foo":v0,"bar":v1,}));v0=e[0](i["foo"]);if(typeof v1!=="boolean"){e[1](v1)}return v2}`, ) }) @@ -1030,7 +1030,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!i||i.constructor!==Object){e[3](i)}let v0,v1,v2;v1=i["foo"];if(typeof v1!=="string"){e[1](v1)}v2=i["bar"];if(typeof v2!=="boolean"){e[2](v2)}for(v0 in i){if(v0!=="foo"&&v0!=="bar"){e[0](v0)}}return {"foo":v1,"bar":v2,}}`, + `i=>{if(!i||i.constructor!==Object){e[3](i)}let v0,v1=i["foo"],v2=i["bar"];if(typeof v1!=="string"){e[1](v1)}if(typeof v2!=="boolean"){e[2](v2)}for(v0 in i){if(v0!=="foo"&&v0!=="bar"){e[0](v0)}}return {"foo":v1,"bar":v2,}}`, ) }) @@ -1060,7 +1060,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!i||i.constructor!==Object){e[5](i)}let v0,v1,v2,v3=i["tag"];v3===0||e[4](v3);v1=i["FOO"];if(typeof v1!=="string"){e[1](v1)}v2=i["BAR"];if(typeof v2!=="boolean"){e[2](v2)}for(v0 in i){if(v0!=="tag"&&v0!=="FOO"&&v0!=="BAR"){e[0](v0)}}return {"foo":v1,"bar":v2,"zoo":e[3],}}`, + `i=>{if(!i||i.constructor!==Object){e[5](i)}let v0,v1=i["FOO"],v2=i["BAR"],v3=i["tag"];v3===0||e[4](v3);if(typeof v1!=="string"){e[1](v1)}if(typeof v2!=="boolean"){e[2](v2)}for(v0 in i){if(v0!=="tag"&&v0!=="FOO"&&v0!=="BAR"){e[0](v0)}}return {"foo":v1,"bar":v2,"zoo":e[3],}}`, ) }, ) diff --git a/packages/tests/src/core/S_refine_test.res b/packages/tests/src/core/S_refine_test.res index 3bd7f598..37ed12c1 100644 --- a/packages/tests/src/core/S_refine_test.res +++ b/packages/tests/src/core/S_refine_test.res @@ -61,7 +61,7 @@ test("Compiled parse code snapshot for simple object with refine", t => { t->U.assertCompiledCode( ~schema, ~op=#parse, - // FIXME: let v0,v1;v0= looks wrong - `i=>{if(!i||i.constructor!==Object){e[3](i)}let v2;let v0,v1;v0=i["foo"];if(typeof v0!=="string"){e[0](v0)}v1=i["bar"];if(typeof v1!=="boolean"){e[1](v1)}v2={"foo":v0,"bar":v1,};e[2](v2);return v2}`, + // FIXME: Double "let" looks wrong + `i=>{if(!i||i.constructor!==Object){e[3](i)}let v2={"foo":v0,"bar":v1,};let v0=i["foo"],v1=i["bar"];if(typeof v0!=="string"){e[0](v0)}if(typeof v1!=="boolean"){e[1](v1)}e[2](v2);return v2}`, ) }) diff --git a/packages/tests/src/core/S_tuple_test.res b/packages/tests/src/core/S_tuple_test.res index f62e4479..b3ca0c93 100644 --- a/packages/tests/src/core/S_tuple_test.res +++ b/packages/tests/src/core/S_tuple_test.res @@ -234,7 +234,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!Array.isArray(i)){e[3](i)}if(i.length!==2){e[0](i.length)}let v0,v1;v0=i["0"];if(typeof v0!=="string"){e[1](v0)}v1=i["1"];if(typeof v1!=="boolean"){e[2](v1)}return [v0,v1,]}`, + `i=>{if(!Array.isArray(i)){e[3](i)}if(i.length!==2){e[0](i.length)}let v0=i["0"],v1=i["1"];if(typeof v0!=="string"){e[1](v0)}if(typeof v1!=="boolean"){e[2](v1)}return [v0,v1,]}`, ) }) @@ -247,7 +247,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!Array.isArray(i)){e[3](i)}if(i.length!==2){e[0](i.length)}let v0,v1,v2=()=>Promise.all([v0()]).then(([v0])=>([v0,v1,]));v0=e[1](i["0"]);v1=i["1"];if(typeof v1!=="boolean"){e[2](v1)}return v2}`, + `i=>{if(!Array.isArray(i)){e[3](i)}if(i.length!==2){e[0](i.length)}let v0,v1=i["1"],v2=()=>Promise.all([v0()]).then(([v0])=>([v0,v1,]));v0=e[1](i["0"]);if(typeof v1!=="boolean"){e[2](v1)}return v2}`, ) }) @@ -277,7 +277,7 @@ module Compiled = { t->U.assertCompiledCode( ~schema, ~op=#parse, - `i=>{if(!Array.isArray(i)){e[5](i)}if(i.length!==3){e[0](i.length)}let v0,v1,v2=i["0"];v2===0||e[4](v2);v0=i["1"];if(typeof v0!=="string"){e[1](v0)}v1=i["2"];if(typeof v1!=="boolean"){e[2](v1)}return {"foo":v0,"bar":v1,"zoo":e[3],}}`, + `i=>{if(!Array.isArray(i)){e[5](i)}if(i.length!==3){e[0](i.length)}let v0=i["1"],v1=i["2"],v2=i["0"];v2===0||e[4](v2);if(typeof v0!=="string"){e[1](v0)}if(typeof v1!=="boolean"){e[2](v1)}return {"foo":v0,"bar":v1,"zoo":e[3],}}`, ) }, ) diff --git a/packages/tests/src/core/S_union_test.res b/packages/tests/src/core/S_union_test.res index 195296eb..281f2281 100644 --- a/packages/tests/src/core/S_union_test.res +++ b/packages/tests/src/core/S_union_test.res @@ -343,6 +343,14 @@ test("Compiled parse code snapshot", t => { ) }) +test("Compiled parse code snapshot for discriminated union", t => { + t->U.assertCompiledCode( + ~schema=Advanced.shapeSchema, + ~op=#parse, + `i=>{let v7;try{if(!i||i.constructor!==Object){e[0](i)}let v0=i["radius"],v1=i["kind"];v1==="circle"||e[3](v1);if(typeof v0!=="number"||Number.isNaN(v0)){e[2](v0)}v7={"TAG":e[1],"radius":v0,}}catch(v8){if(v8&&v8.s===s){try{if(!i||i.constructor!==Object){e[4](i)}let v2=i["x"],v3=i["kind"];v3==="square"||e[7](v3);if(typeof v2!=="number"||Number.isNaN(v2)){e[6](v2)}v7={"TAG":e[5],"x":v2,}}catch(v9){if(v9&&v9.s===s){try{if(!i||i.constructor!==Object){e[8](i)}let v4=i["x"],v5=i["y"],v6=i["kind"];v6==="triangle"||e[12](v6);if(typeof v4!=="number"||Number.isNaN(v4)){e[10](v4)}if(typeof v5!=="number"||Number.isNaN(v5)){e[11](v5)}v7={"TAG":e[9],"x":v4,"y":v5,}}catch(v10){if(v10&&v10.s===s){e[13]([v8,v9,v10])}else{throw v10}}}else{throw v9}}}else{throw v8}}return v7}`, + ) +}) + test("Compiled async parse code snapshot", t => { let schema = S.union([ S.literal(0)->S.transform(_ => {asyncParser: i => () => Promise.resolve(i)}), @@ -381,6 +389,6 @@ test("Compiled serialize code snapshot for unboxed variant", t => { t->U.assertCompiledCode( ~schema, ~op=#serialize, - `i=>{let v0;try{if(typeof i!=="string"){e[0](i)}v0=i}catch(v1){if(v1&&v1.s===s){try{let v3;v3=e[1](i);if(typeof v3!=="string"){e[2](v3)}v0=v3}catch(v2){if(v2&&v2.s===s){e[3]([v1,v2,])}else{throw v2}}}else{throw v1}}return v0}`, + `i=>{let v0;try{if(typeof i!=="string"){e[0](i)}v0=i}catch(v1){if(v1&&v1.s===s){try{let v3=e[1](i);if(typeof v3!=="string"){e[2](v3)}v0=v3}catch(v2){if(v2&&v2.s===s){e[3]([v1,v2,])}else{throw v2}}}else{throw v1}}return v0}`, ) }) diff --git a/src/S_Core.bs.mjs b/src/S_Core.bs.mjs index 62ce0446..b854347c 100644 --- a/src/S_Core.bs.mjs +++ b/src/S_Core.bs.mjs @@ -133,43 +133,6 @@ function $$var(b) { return v; } -function embed(b, val) { - var $$var$1 = val.v; - if ($$var$1 !== undefined) { - return $$var$1; - } - var initial = val.i; - if (initial !== undefined) { - return initial; - } else { - return $$var(b); - } -} - -function $$var$1(b, val) { - var _var = val.v; - if (_var !== undefined) { - return _var; - } - var $$var$2 = varWithoutAllocation(b); - var i = val.i; - var allocation = i !== undefined ? $$var$2 + "=" + i : $$var$2; - var varsAllocation = val.x.l; - val.x.l = varsAllocation === "" ? allocation : varsAllocation + "," + allocation; - val.v = $$var$2; - return $$var$2; -} - -function push(b, val, code) { - var $$var$2 = $$var$1(b, val); - return $$var$2 + ".push(" + code + ")"; -} - -function set(b, val, code) { - var $$var$2 = $$var$1(b, val); - return $$var$2 + "=" + code; -} - function allocateVal(b) { return { x: b.x, @@ -205,45 +168,73 @@ function asyncVal(b, initial) { }; } -function toVar(b, val) { - if (b.s.has(val)) { - return val; +function inline(b, val) { + var $$var$1 = val.v; + if ($$var$1 !== undefined) { + return $$var$1; + } + var initial = val.i; + if (initial !== undefined) { + return initial; + } else { + return $$var(b); + } +} + +function $$var$1(b, val) { + var _var = val.v; + if (_var !== undefined) { + return _var; } - var $$var$2 = $$var(b); - b.c = b.c + ($$var$2 + "=" + val + ";"); + var $$var$2 = varWithoutAllocation(b); + var i = val.i; + var allocation = i !== undefined ? $$var$2 + "=" + i : $$var$2; + var varsAllocation = val.x.l; + val.x.l = varsAllocation === "" ? allocation : varsAllocation + "," + allocation; + val.v = $$var$2; return $$var$2; } +function push(b, val, code) { + var $$var$2 = $$var$1(b, val); + return $$var$2 + ".push(" + code + ")"; +} + +function set(b, val, code) { + var $$var$2 = $$var$1(b, val); + return $$var$2 + "=" + code; +} + function transform(b, input, isAsync, operation) { if (b.a === true) { var prevCode = b.c; b.c = ""; var inputVar = varWithoutAllocation(b); - var operationOutputVar = operation(b, inputVar); + var operationOutputVal = operation(b, inputVar); var outputVar = $$var(b); - b.c = prevCode + (outputVar + "=()=>" + input + "().then(" + inputVar + "=>{" + b.c + "return " + operationOutputVar + ( + b.c = prevCode + (outputVar + "=()=>" + input + "().then(" + inputVar + "=>{" + b.c + "return " + inline(b, operationOutputVal) + ( isAsync ? "()" : "" ) + "});"); return outputVar; } if (!isAsync) { - return operation(b, input); + return inline(b, operation(b, input)); } b.a = true; var outputVar$1 = $$var(b); - b.c = b.c + (outputVar$1 + "=" + operation(b, input) + ";"); + b.c = b.c + (outputVar$1 + "=" + inline(b, operation(b, input)) + ";"); return outputVar$1; } function embedSyncOperation(b, input, fn) { return transform(b, input, false, (function (b, input) { - return "e[" + (b.e.push(fn) - 1) + "](" + input + ")"; + return val(b, "e[" + (b.e.push(fn) - 1) + "](" + input + ")"); })); } function embedAsyncOperation(b, input, fn) { return transform(b, input, true, (function (b, input) { - return "e[" + (b.e.push(fn) - 1) + "](" + input + ")"; + return val(b, "e[" + (b.e.push(fn) - 1) + "](" + input + ")"); })); } @@ -323,7 +314,8 @@ function withPathPrepend(b, path, maybeDynamicLocationVar, fn) { } } -function typeFilterCode(b, typeFilter, schema, inputVar, path) { +function typeFilterCode(b, typeFilter, schema, input, path) { + var inputVar = $$var$1(b, input); return "if(" + typeFilter(inputVar) + "){" + raiseWithArg(b, path, (function (input) { return { TAG: "InvalidType", @@ -336,12 +328,11 @@ function typeFilterCode(b, typeFilter, schema, inputVar, path) { function use(b, schema, input, path) { var isParentAsync = b.a; var isParsing = b.o === "Parsing"; - b.i = val(b, input); + b.i = input; b.a = false; - var outputVal = ( + var output = ( isParsing ? schema.p : schema.s )(b, schema, path); - var output = embed(b, outputVal); if (isParsing) { schema.i = b.a; b.a = isParentAsync || b.a; @@ -351,14 +342,7 @@ function use(b, schema, input, path) { function useWithTypeFilter(b, schema, input, path) { var typeFilter = schema.f; - var input$1; - if (typeFilter !== undefined) { - var inputVar = toVar(b, input); - b.c = b.c + typeFilterCode(b, typeFilter, schema, inputVar, path); - input$1 = inputVar; - } else { - input$1 = input; - } + var input$1 = typeFilter !== undefined ? (b.c = b.c + typeFilterCode(b, typeFilter, schema, input, path), input) : input; return use(b, schema, input$1, path); } @@ -370,7 +354,7 @@ function withBuildErrorInline(b, fn) { var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); var error = getOrRethrow(exn); b.c = "throw " + ("e[" + (b.e.push(error) - 1) + "]") + ";"; - return embed(b, b.i); + return b.i; } } @@ -386,6 +370,11 @@ function build(builder, schema, operation) { var scope = { l: "" }; + var input = { + v: "i", + x: scope, + a: false + }; var b = { a: false, c: "", @@ -393,22 +382,18 @@ function build(builder, schema, operation) { v: -1, s: new Set(["i"]), x: scope, - i: { - v: "i", - x: scope, - a: false - }, + i: input, e: [] }; var outputVal = builder(b, schema, ""); - var output = embed(b, outputVal); + var output = inline(b, outputVal); if (b.x.l !== "") { b.c = "let " + b.x.l + ";" + b.c; } if (operation === "Parsing") { var typeFilter = schema.f; if (typeFilter !== undefined) { - b.c = typeFilterCode(b, typeFilter, schema, "i", "") + b.c; + b.c = typeFilterCode(b, typeFilter, schema, input, "") + b.c; } schema.i = b.a; } @@ -1047,7 +1032,7 @@ function recursive(fn) { Object.assign(placeholder, schema); var builder = placeholder.p; placeholder.p = (function (b, selfSchema, path) { - var input = embed(b, b.i); + var input = inline(b, b.i); selfSchema.p = noop; var scope = { l: "" @@ -1069,7 +1054,7 @@ function recursive(fn) { builder(ctx, selfSchema, path); var isAsync = ctx.a; selfSchema.p = (function (b, selfSchema, param) { - var input = embed(b, b.i); + var input = inline(b, b.i); return val(b, isAsync ? embedAsyncOperation(b, input, (function (input) { return internalParseAsyncWith(input, selfSchema); })) : embedSyncOperation(b, input, (function (input) { @@ -1093,9 +1078,9 @@ function recursive(fn) { }); var builder$1 = placeholder.s; placeholder.s = (function (b, selfSchema, path) { - var input = embed(b, b.i); + var input = inline(b, b.i); selfSchema.s = (function (b, selfSchema, param) { - var input = embed(b, b.i); + var input = inline(b, b.i); return val(b, embedSyncOperation(b, input, (function (input) { return serializeToUnknownOrRaiseWith(input, selfSchema); }))); @@ -1138,20 +1123,24 @@ function internalRefine(schema, refiner) { t: schema.t, n: schema.n, p: (function (b, selfSchema, path) { - var input = embed(b, b.i); - return val(b, transform(b, use(b, schema, input, path), false, (function (b, input) { - var inputVar = toVar(b, input); - b.c = b.c + refiner(b, inputVar, selfSchema, path); - return inputVar; + var input = b.i; + return val(b, transform(b, (function (__x) { + return inline(b, __x); + })(use(b, schema, input, path)), false, (function (b, input) { + var input$1 = val(b, input); + b.c = b.c + refiner(b, input$1, selfSchema, path); + return input$1; }))); }), s: (function (b, selfSchema, path) { - var input = embed(b, b.i); - return val(b, use(b, schema, transform(b, input, false, (function (b, input) { - var inputVar = toVar(b, input); - b.c = b.c + refiner(b, inputVar, selfSchema, path); - return inputVar; - })), path)); + var input = inline(b, b.i); + return use(b, schema, (function (__x) { + return val(b, __x); + })(transform(b, input, false, (function (b, input) { + var input$1 = val(b, input); + b.c = b.c + refiner(b, input$1, selfSchema, path); + return input$1; + }))), path); }), f: schema.f, i: 0, @@ -1160,9 +1149,9 @@ function internalRefine(schema, refiner) { } function refine(schema, refiner) { - return internalRefine(schema, (function (b, inputVar, selfSchema, path) { + return internalRefine(schema, (function (b, input, selfSchema, path) { var value = refiner(make(selfSchema, path, b.o)); - return "e[" + (b.e.push(value) - 1) + "](" + inputVar + ");"; + return "e[" + (b.e.push(value) - 1) + "](" + $$var$1(b, input) + ");"; })); } @@ -1176,8 +1165,10 @@ function transform$1(schema, transformer) { t: schema.t, n: schema.n, p: (function (b, selfSchema, path) { - var input = embed(b, b.i); - var input$1 = use(b, schema, input, path); + var input = b.i; + var input$1 = (function (__x) { + return inline(b, __x); + })(use(b, schema, input, path)); var match = transformer(make(selfSchema, path, b.o)); var parser = match.p; var tmp; @@ -1192,12 +1183,25 @@ function transform$1(schema, transformer) { return val(b, tmp); }), s: (function (b, selfSchema, path) { - var input = embed(b, b.i); var match = transformer(make(selfSchema, path, b.o)); var serializer = match.s; - return val(b, serializer !== undefined ? use(b, schema, embedSyncOperation(b, input, serializer), path) : ( - match.a !== undefined || match.p !== undefined ? invalidOperation(b, path, "The S.transform serializer is missing") : use(b, schema, input, path) - )); + var tmp; + if (serializer !== undefined) { + var input = inline(b, b.i); + tmp = (function (__x) { + return inline(b, __x); + })(use(b, schema, (function (__x) { + return val(b, __x); + })(embedSyncOperation(b, input, serializer)), path)); + } else if (match.a !== undefined || match.p !== undefined) { + tmp = invalidOperation(b, path, "The S.transform serializer is missing"); + } else { + var input$1 = b.i; + tmp = (function (__x) { + return inline(b, __x); + })(use(b, schema, input$1, path)); + } + return val(b, tmp); }), f: schema.f, i: 0, @@ -1227,7 +1231,7 @@ function preprocess(schema, transformer) { t: schema.t, n: schema.n, p: (function (b, selfSchema, path) { - var input = embed(b, b.i); + var input = inline(b, b.i); var match = transformer(make(selfSchema, path, b.o)); var parser = match.p; var tmp; @@ -1237,7 +1241,11 @@ function preprocess(schema, transformer) { } else { var operationResultVar = $$var(b); b.c = b.c + (operationResultVar + "=" + embedSyncOperation(b, input, parser) + ";"); - tmp = useWithTypeFilter(b, schema, operationResultVar, path); + tmp = (function (__x) { + return inline(b, __x); + })(useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(operationResultVar), path)); } } else { var asyncParser = match.a; @@ -1246,7 +1254,11 @@ function preprocess(schema, transformer) { var outputVar = $$var(b); var asyncResultVar = varWithoutAllocation(b); b.c = b.c + (outputVar + "=()=>" + parseResultVar + "().then(" + asyncResultVar + "=>{" + scope(b, (function (b) { - var schemaOutputVar = useWithTypeFilter(b, schema, asyncResultVar, path); + var schemaOutputVar = (function (__x) { + return inline(b, __x); + })(useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(asyncResultVar), path)); var isAsync = schema.i; return "return " + ( isAsync ? schemaOutputVar + "()" : schemaOutputVar @@ -1254,14 +1266,20 @@ function preprocess(schema, transformer) { })) + "});"); tmp = outputVar; } else { - tmp = useWithTypeFilter(b, schema, input, path); + tmp = (function (__x) { + return inline(b, __x); + })(useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(input), path)); } } return val(b, tmp); }), s: (function (b, selfSchema, path) { - var input = embed(b, b.i); - var input$1 = use(b, schema, input, path); + var input = b.i; + var input$1 = (function (__x) { + return inline(b, __x); + })(use(b, schema, input, path)); var match = transformer(make(selfSchema, path, b.o)); var serializer = match.s; return val(b, serializer !== undefined ? embedSyncOperation(b, input$1, serializer) : input$1); @@ -1279,7 +1297,7 @@ function custom(name, definer) { return name; }), p: (function (b, selfSchema, path) { - var input = embed(b, b.i); + var input = inline(b, b.i); var match = definer(make(selfSchema, path, b.o)); var parser = match.p; var tmp; @@ -1294,7 +1312,7 @@ function custom(name, definer) { return val(b, tmp); }), s: (function (b, selfSchema, path) { - var input = embed(b, b.i); + var input = inline(b, b.i); var match = definer(make(selfSchema, path, b.o)); var serializer = match.s; return val(b, serializer !== undefined ? embedSyncOperation(b, input, serializer) : ( @@ -1353,8 +1371,10 @@ function factory(schema, definer) { t: schema.t, n: schema.n, p: (function (b, param, path) { - var input = embed(b, b.i); - return val(b, embedSyncOperation(b, use(b, schema, input, path), definer)); + var input = b.i; + return val(b, embedSyncOperation(b, (function (__x) { + return inline(b, __x); + })(use(b, schema, input, path)), definer)); }), s: (function (b, selfSchema, path) { var inputVar = $$var$1(b, b.i); @@ -1399,18 +1419,22 @@ function factory(schema, definer) { } }; var output = definitionToOutput(definition, ""); - var tmp; - if (typeof output !== "string") { - if (output === 0) { - var literal = toInternalLiteral(selfSchema); - tmp = literal !== undefined ? use(b, schema, "e[" + (b.e.push(literal.value) - 1) + "]", path) : invalidOperation(b, path, "Can't create serializer. The S.variant's value is not registered and not a literal. Use S.transform instead"); - } else { - tmp = invalidOperation(b, path, "Can't create serializer. The S.variant's value is registered multiple times. Use S.transform instead"); - } + if (typeof output === "string") { + return use(b, schema, (function (__x) { + return val(b, __x); + })(output), path); + } + if (output !== 0) { + return invalidOperation(b, path, "Can't create serializer. The S.variant's value is registered multiple times. Use S.transform instead"); + } + var literal = toInternalLiteral(selfSchema); + if (literal !== undefined) { + return use(b, schema, (function (__x) { + return val(b, __x); + })("e[" + (b.e.push(literal.value) - 1) + "]"), path); } else { - tmp = use(b, schema, output, path); + return invalidOperation(b, path, "Can't create serializer. The S.variant's value is not registered and not a literal. Use S.transform instead"); } - return val(b, tmp); }), f: schema.f, i: 0, @@ -1425,12 +1449,14 @@ function $$default(schema) { } function parseOperationBuilder(b, selfSchema, path) { - var inputVar = $$var$1(b, b.i); + var input = b.i; var outputVal = allocateVal(b); var isNull = (selfSchema.t.TAG === "Null"); var childSchema = selfSchema.t._0; var ifCode = scope(b, (function (b) { - return set(b, outputVal, use(b, childSchema, inputVar, path)); + return set(b, outputVal, (function (__x) { + return inline(b, __x); + })(use(b, childSchema, input, path))); })); var isAsync = childSchema.i; var tmp; @@ -1443,20 +1469,24 @@ function parseOperationBuilder(b, selfSchema, path) { if (exit === 1) { tmp = "else{" + set(b, outputVal, isAsync ? "()=>Promise.resolve(void 0)" : "void 0") + "}"; } - b.c = b.c + ("if(" + inputVar + "!==" + ( + b.c = b.c + ("if(" + $$var$1(b, input) + "!==" + ( isNull ? "null" : "void 0" ) + "){" + ifCode + "}" + tmp); return outputVal; } function serializeOperationBuilder(b, selfSchema, path) { - var inputVar = $$var$1(b, b.i); + var input = b.i; var outputVal = allocateVal(b); var isNull = (selfSchema.t.TAG === "Null"); var childSchema = selfSchema.t._0; - b.c = b.c + ("if(" + inputVar + "!==void 0){" + scope(b, (function (b) { + b.c = b.c + ("if(" + $$var$1(b, input) + "!==void 0){" + scope(b, (function (b) { var value = Caml_option.valFromOption; - return set(b, outputVal, use(b, childSchema, "e[" + (b.e.push(value) - 1) + "](" + inputVar + ")", path)); + return set(b, outputVal, (function (__x) { + return inline(b, __x); + })(use(b, childSchema, (function (__x) { + return val(b, __x); + })("e[" + (b.e.push(value) - 1) + "](" + $$var$1(b, input) + ")"), path))); })) + "}" + ( isNull ? "else{" + set(b, outputVal, "null") + "}" : "" )); @@ -1493,11 +1523,13 @@ function getWithDefault(schema, $$default) { t: schema.t, n: schema.n, p: (function (b, param, path) { - var input = embed(b, b.i); - return val(b, transform(b, use(b, schema, input, path), false, (function (b, input) { + var input = b.i; + return val(b, transform(b, (function (__x) { + return inline(b, __x); + })(use(b, schema, input, path)), false, (function (b, input) { var tmp; tmp = $$default.TAG === "Value" ? "e[" + (b.e.push($$default._0) - 1) + "]" : "e[" + (b.e.push($$default._0) - 1) + "]()"; - return input + "===void 0?" + tmp + ":" + input; + return val(b, input + "===void 0?" + tmp + ":" + input); }))); }), s: schema.s, @@ -1550,11 +1582,13 @@ function noopRefinement(_b, param, param$1, param$2) { function makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet, definition, inputRefinement, unknownKeysRefinement) { return function (b, selfSchema, path) { - var inputVar = $$var$1(b, b.i); - var registeredDefinitions = new Set(); - var asyncOutputVars = []; - inputRefinement(b, selfSchema, inputVar, path); + if (inputRefinement !== undefined) { + inputRefinement(b, selfSchema, path); + } var fn = function (b) { + var inputVar = $$var$1(b, b.i); + var registeredDefinitions = new Set(); + var asyncOutputVars = []; var prevCode = b.c; b.c = ""; unknownKeysRefinement(b, selfSchema, inputVar, path); @@ -1584,7 +1618,11 @@ function makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet, definiti registeredDefinitions.add(definition); var inputPath = definition.p; var schema = definition.s; - var fieldOuputVar = useWithTypeFilter(b, schema, inputVar + inputPath, path + inputPath); + var fieldOuputVar = (function (__x) { + return inline(b, __x); + })(useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(inputVar + inputPath), path + inputPath)); var isAsyncField = schema.i; if (isAsyncField) { asyncOutputVars.push(fieldOuputVar); @@ -1601,7 +1639,11 @@ function makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet, definiti if (!registeredDefinitions.has(itemDefinition)) { var inputPath = itemDefinition.p; var schema = itemDefinition.s; - var fieldOuputVar = useWithTypeFilter(b, schema, inputVar + inputPath, path + inputPath); + var fieldOuputVar = (function (__x) { + return inline(b, __x); + })(useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(inputVar + inputPath), path + inputPath)); var isAsyncField = schema.i; if (isAsyncField) { asyncOutputVars.push(fieldOuputVar); @@ -1690,7 +1732,7 @@ function factory$3(definer) { return JSON.stringify(fieldName) + ": " + fieldSchema.n(); }).join(", ") + "})"; }), - p: makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet$1, definition, noopRefinement, (function (b, selfSchema, inputVar, path) { + p: makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet$1, definition, undefined, (function (b, selfSchema, inputVar, path) { var withUnknownKeysRefinement = selfSchema.t.unknownKeys === "Strict"; if (!withUnknownKeysRefinement) { return ; @@ -1754,7 +1796,11 @@ function factory$3(definer) { return invalidOperation(b, path, "The field " + definition.l + " is registered multiple times. If you want to duplicate the field, use S.transform instead"); } else { registeredDefinitions.add(definition); - fieldsCodeRef.contents = fieldsCodeRef.contents + (definition.l + ":" + use(b, definition.s, inputVar + outputPath, path + outputPath) + ","); + fieldsCodeRef.contents = fieldsCodeRef.contents + (definition.l + ":" + (function (__x) { + return inline(b, __x); + })(use(b, definition.s, (function (__x) { + return val(b, __x); + })(inputVar + outputPath), path + outputPath)) + ","); return ; } @@ -1828,15 +1874,15 @@ function strict(schema) { } function builder(b, selfSchema, path) { - var input = embed(b, b.i); + var input = b.i; b.c = b.c + raiseWithArg(b, path, (function (input) { return { TAG: "InvalidType", expected: selfSchema, received: input }; - }), input) + ";"; - return val(b, input); + }), inline(b, input)) + ";"; + return input; } var schema = { @@ -1900,8 +1946,8 @@ function min(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ".length<" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ".length<" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -1913,8 +1959,8 @@ function max(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ".length>" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ".length>" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -1926,8 +1972,8 @@ function length(schema, length$1, maybeMessage) { length: length$1 }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ".length!==" + ("e[" + (b.e.push(length$1) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ".length!==" + ("e[" + (b.e.push(length$1) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -1936,8 +1982,8 @@ function email(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Email", message: message - }, (function (b, inputVar, param, path) { - return "if(!" + ("e[" + (b.e.push(emailRegex) - 1) + "]") + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(!" + ("e[" + (b.e.push(emailRegex) - 1) + "]") + ".test(" + $$var$1(b, input) + ")){" + fail(b, message, path) + "}"; })); } @@ -1946,8 +1992,8 @@ function uuid(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Uuid", message: message - }, (function (b, inputVar, param, path) { - return "if(!" + ("e[" + (b.e.push(uuidRegex) - 1) + "]") + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(!" + ("e[" + (b.e.push(uuidRegex) - 1) + "]") + ".test(" + $$var$1(b, input) + ")){" + fail(b, message, path) + "}"; })); } @@ -1956,8 +2002,8 @@ function cuid(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Cuid", message: message - }, (function (b, inputVar, param, path) { - return "if(!" + ("e[" + (b.e.push(cuidRegex) - 1) + "]") + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(!" + ("e[" + (b.e.push(cuidRegex) - 1) + "]") + ".test(" + $$var$1(b, input) + ")){" + fail(b, message, path) + "}"; })); } @@ -1966,8 +2012,8 @@ function url(schema, messageOpt) { return addRefinement(schema, metadataId, { kind: "Url", message: message - }, (function (b, inputVar, param, path) { - return "try{new URL(" + inputVar + ")}catch(_){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "try{new URL(" + $$var$1(b, input) + ")}catch(_){" + fail(b, message, path) + "}"; })); } @@ -1979,9 +2025,9 @@ function pattern(schema, re, messageOpt) { re: re }, message: message - }, (function (b, inputVar, param, path) { + }, (function (b, input, param, path) { var reVar = $$var(b); - return reVar + "=" + ("e[" + (b.e.push(re) - 1) + "]") + ";" + reVar + ".lastIndex=0;if(!" + reVar + ".test(" + inputVar + ")){" + fail(b, message, path) + "}"; + return reVar + "=" + ("e[" + (b.e.push(re) - 1) + "]") + ";" + reVar + ".lastIndex=0;if(!" + reVar + ".test(" + $$var$1(b, input) + ")){" + fail(b, message, path) + "}"; })); } @@ -2034,7 +2080,7 @@ function factory$4(schema, spaceOpt) { t: "String", n: primitiveName, p: (function (b, param, path) { - var input = embed(b, b.i); + var input = inline(b, b.i); var jsonVar = $$var(b); b.c = b.c + ("try{" + jsonVar + "=JSON.parse(" + input + ")}catch(t){" + raiseWithArg(b, path, (function (message) { return { @@ -2042,11 +2088,13 @@ function factory$4(schema, spaceOpt) { _0: message }; }), "t.message") + "}"); - return val(b, useWithTypeFilter(b, schema, jsonVar, path)); + return useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(jsonVar), path); }), s: (function (b, param, path) { - var input = embed(b, b.i); - return val(b, "JSON.stringify(" + use(b, schema, input, path) + ( + var input = b.i; + return val(b, "JSON.stringify(" + inline(b, use(b, schema, input, path)) + ( space > 0 ? ",null," + space : "" ) + ")"); }), @@ -2103,8 +2151,8 @@ function min$1(schema, minValue, maybeMessage) { value: minValue }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + "<" + ("e[" + (b.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + "<" + ("e[" + (b.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2116,8 +2164,8 @@ function max$1(schema, maxValue, maybeMessage) { value: maxValue }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ">" + ("e[" + (b.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ">" + ("e[" + (b.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2126,8 +2174,8 @@ function port(schema, messageOpt) { return addRefinement(schema, metadataId$1, { kind: "Port", message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + "<1||" + inputVar + ">65535){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + "<1||" + $$var$1(b, input) + ">65535){" + fail(b, message, path) + "}"; })); } @@ -2164,8 +2212,8 @@ function min$2(schema, minValue, maybeMessage) { value: minValue }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + "<" + ("e[" + (b.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + "<" + ("e[" + (b.e.push(minValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2177,8 +2225,8 @@ function max$2(schema, maxValue, maybeMessage) { value: maxValue }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ">" + ("e[" + (b.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ">" + ("e[" + (b.e.push(maxValue) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2210,7 +2258,10 @@ function factory$5(schema) { var outputVal = val(b, "[]"); b.c = b.c + ("for(let " + iteratorVar + "=0;" + iteratorVar + "<" + inputVar + ".length;++" + iteratorVar + "){" + scope(b, (function (b) { var itemOutputVar = withPathPrepend(b, path, iteratorVar, (function (b, path) { - return useWithTypeFilter(b, schema, inputVar + "[" + iteratorVar + "]", path); + var __x = useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(inputVar + "[" + iteratorVar + "]"), path); + return inline(b, __x); })); return push(b, outputVal, itemOutputVar); })) + "}"); @@ -2230,7 +2281,10 @@ function factory$5(schema) { var outputVal = val(b, "[]"); b.c = b.c + ("for(let " + iteratorVar + "=0;" + iteratorVar + "<" + inputVar + ".length;++" + iteratorVar + "){" + scope(b, (function (b) { var itemOutputVar = withPathPrepend(b, path, iteratorVar, (function (b, path) { - return use(b, schema, inputVar + "[" + iteratorVar + "]", path); + var __x = use(b, schema, (function (__x) { + return val(b, __x); + })(inputVar + "[" + iteratorVar + "]"), path); + return inline(b, __x); })); return push(b, outputVal, itemOutputVar); })) + "}"); @@ -2250,8 +2304,8 @@ function min$3(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ".length<" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ".length<" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2263,8 +2317,8 @@ function max$3(schema, length, maybeMessage) { length: length }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ".length>" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ".length>" + ("e[" + (b.e.push(length) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2276,8 +2330,8 @@ function length$1(schema, length$2, maybeMessage) { length: length$2 }, message: message - }, (function (b, inputVar, param, path) { - return "if(" + inputVar + ".length!==" + ("e[" + (b.e.push(length$2) - 1) + "]") + "){" + fail(b, message, path) + "}"; + }, (function (b, input, param, path) { + return "if(" + $$var$1(b, input) + ".length!==" + ("e[" + (b.e.push(length$2) - 1) + "]") + "){" + fail(b, message, path) + "}"; })); } @@ -2294,7 +2348,10 @@ function factory$6(schema) { var outputVar = $$var(b); b.c = b.c + (outputVar + "={};for(let " + keyVar + " in " + inputVar + "){" + scope(b, (function (b) { var itemOutputVar = withPathPrepend(b, path, keyVar, (function (b, path) { - return useWithTypeFilter(b, schema, inputVar + "[" + keyVar + "]", path); + var __x = useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(inputVar + "[" + keyVar + "]"), path); + return inline(b, __x); })); return outputVar + "[" + keyVar + "]=" + itemOutputVar; })) + "}"); @@ -2316,14 +2373,17 @@ function factory$6(schema) { s: (function (b, param, path) { var tmp; if (schema.s === noop) { - tmp = embed(b, b.i); + tmp = inline(b, b.i); } else { var inputVar = $$var$1(b, b.i); var keyVar = varWithoutAllocation(b); var outputVar = $$var(b); b.c = b.c + (outputVar + "={};for(let " + keyVar + " in " + inputVar + "){" + scope(b, (function (b) { var itemOutputVar = withPathPrepend(b, path, keyVar, (function (b, path) { - return use(b, schema, inputVar + "[" + keyVar + "]", path); + var __x = use(b, schema, (function (__x) { + return val(b, __x); + })(inputVar + "[" + keyVar + "]"), path); + return inline(b, __x); })); return outputVar + "[" + keyVar + "]=" + itemOutputVar; })) + "}"); @@ -2395,7 +2455,8 @@ function factory$7(definer) { return s.n(); }).join(", ") + ")"; }), - p: makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet$1, definition, (function (b, param, inputVar, path) { + p: makeParseOperationBuilder(itemDefinitions, itemDefinitionsSet$1, definition, (function (b, param, path) { + var inputVar = $$var$1(b, b.i); b.c = b.c + ("if(" + inputVar + ".length!==" + length + "){" + raiseWithArg(b, path, (function (numberOfInputItems) { return { TAG: "InvalidTupleSize", @@ -2436,7 +2497,11 @@ function factory$7(definer) { return invalidOperation(b, path, "The item " + definition.l + " is registered multiple times. If you want to duplicate the item, use S.transform instead"); } registeredDefinitions.add(definition); - var fieldOuputVar = use(b, definition.s, inputVar + outputPath, path + outputPath); + var fieldOuputVar = (function (__x) { + return inline(b, __x); + })(use(b, definition.s, (function (__x) { + return val(b, __x); + })(inputVar + outputPath), path + outputPath)); b.c = b.c + (outputVar + definition.p + "=" + fieldOuputVar + ";"); return ; @@ -2481,23 +2546,25 @@ function factory$8(schemas) { }).join(", ") + ")"; }), p: (function (b, selfSchema, path) { - var inputVar = $$var$1(b, b.i); + var input = b.i; var schemas = selfSchema.t._0; var isAsyncRef = false; var itemsCode = []; - var itemsOutputVar = []; + var itemOutputVars = []; var prevCode = b.c; for(var idx = 0 ,idx_finish = schemas.length; idx < idx_finish; ++idx){ var schema = schemas[idx]; b.c = ""; - var itemOutputVar = withBuildErrorInline(b, (function () { - return useWithTypeFilter(b, schema, inputVar, ""); + var itemOutputVal = withBuildErrorInline(b, (function () { + return useWithTypeFilter(b, schema, input, ""); })); var isAsyncItem = schema.i; if (isAsyncItem) { isAsyncRef = true; } - itemsOutputVar.push(itemOutputVar); + itemOutputVars.push((function (__x) { + return inline(b, __x); + })(itemOutputVal)); itemsCode.push(b.c); } b.c = prevCode; @@ -2508,19 +2575,19 @@ function factory$8(schemas) { for(var idx$1 = 0 ,idx_finish$1 = schemas.length; idx$1 < idx_finish$1; ++idx$1){ var schema$1 = schemas[idx$1]; var code = itemsCode[idx$1]; - var itemOutputVar$1 = itemsOutputVar[idx$1]; + var itemOutputVar = itemOutputVars[idx$1]; var isAsyncItem$1 = schema$1.i; var errorVar = varWithoutAllocation(b); var errorCode = isAsync ? ( - isAsyncItem$1 ? errorVar + "===" + itemOutputVar$1 + "?" + errorVar + "():" : "" + isAsyncItem$1 ? errorVar + "===" + itemOutputVar + "?" + errorVar + "():" : "" ) + ("Promise.reject(" + errorVar + ")") : errorVar; errorCodeRef = idx$1 === 0 ? errorCode : errorCodeRef + "," + errorCode; b.c = b.c + ("try{" + code + ( - isAsyncItem$1 ? "throw " + itemOutputVar$1 : ( - isAsync ? outputVar + "=()=>Promise.resolve(" + itemOutputVar$1 + ")" : outputVar + "=" + itemOutputVar$1 + isAsyncItem$1 ? "throw " + itemOutputVar : ( + isAsync ? outputVar + "=()=>Promise.resolve(" + itemOutputVar + ")" : outputVar + "=" + itemOutputVar ) ) + "}catch(" + errorVar + "){if(" + (errorVar + "&&" + errorVar + ".s===s") + ( - isAsyncItem$1 ? "||" + errorVar + "===" + itemOutputVar$1 : "" + isAsyncItem$1 ? "||" + errorVar + "===" + itemOutputVar : "" ) + "){"); codeEndRef = "}else{throw " + errorVar + "}}" + codeEndRef; } @@ -2543,7 +2610,7 @@ function factory$8(schemas) { } }), s: (function (b, selfSchema, path) { - var inputVar = $$var$1(b, b.i); + var input = b.i; var schemas = selfSchema.t._0; var outputVar = $$var(b); var codeEndRef = ""; @@ -2555,18 +2622,15 @@ function factory$8(schemas) { b.c = b.c + ("try{" + scope(b, (function(itemSchema){ return function (b) { var itemOutput = withBuildErrorInline(b, (function () { - return use(b, itemSchema, inputVar, ""); + return use(b, itemSchema, input, ""); })); var typeFilter = itemSchema.f; - var itemOutput$1; if (typeFilter !== undefined) { - var itemOutputVar = toVar(b, itemOutput); - b.c = b.c + typeFilterCode(b, typeFilter, itemSchema, itemOutputVar, ""); - itemOutput$1 = itemOutputVar; - } else { - itemOutput$1 = itemOutput; + b.c = b.c + typeFilterCode(b, typeFilter, itemSchema, itemOutput, ""); } - return outputVar + "=" + itemOutput$1; + return outputVar + "=" + (function (__x) { + return inline(b, __x); + })(itemOutput); } }(itemSchema))) + "}catch(" + errorVar + "){if(" + (errorVar + "&&" + errorVar + ".s===s") + "){"); codeEndRef = "}else{throw " + errorVar + "}}" + codeEndRef; @@ -2648,8 +2712,8 @@ function json(validate) { received: input }, "Parsing", path$1); }; - var input = embed(b, b.i); - return val(b, "e[" + (b.e.push(parse) - 1) + "](" + input + ")"); + var input = b.i; + return val(b, "e[" + (b.e.push(parse) - 1) + "](" + inline(b, input) + ")"); }) : noop, s: noop, f: undefined, @@ -2682,7 +2746,10 @@ function $$catch(schema, getFallbackValue) { }); }) - 1) + "](" + inputVar + "," + errorVar + ")"; }), (function (b) { - return useWithTypeFilter(b, schema, inputVar, path); + var __x = useWithTypeFilter(b, schema, (function (__x) { + return val(b, __x); + })(inputVar), path); + return inline(b, __x); }))); }), s: schema.s, @@ -3069,7 +3136,7 @@ function internalInline(schema, maybeVariant, param) { } } -function inline(schema) { +function inline$1(schema) { if (false) { var v = (void 0); if (v !== undefined) { @@ -3294,10 +3361,10 @@ function js_merge(s1, s2) { return s1.n() + " & " + s2.n(); }), p: (function (b, param, path) { - var inputVar = $$var$1(b, b.i); - var s1Result = use(b, s1, inputVar, path); - var s2Result = use(b, s2, inputVar, path); - return val(b, "Object.assign(" + s1Result + ", " + s2Result + ")"); + var input = b.i; + var s1Result = use(b, s1, input, path); + var s2Result = use(b, s2, input, path); + return val(b, "Object.assign(" + inline(b, s1Result) + ", " + inline(b, s2Result) + ")"); }), s: (function (b, param, path) { return invalidOperation(b, path, "The S.merge serializing is not supported yet"); @@ -3515,7 +3582,7 @@ export { Float , $$Array , Metadata , - inline , + inline$1 as inline, js_optional , js_tuple , js_custom , diff --git a/src/S_Core.res b/src/S_Core.res index 9d14c2d3..932b8550 100644 --- a/src/S_Core.res +++ b/src/S_Core.res @@ -453,8 +453,33 @@ module Builder = { v } + let allocateVal = (b: b): val => { + {_varScope: b._scope, _isAsync: false} + } + + let val = (b: b, initial: string): val => { + // TODO: Get rid of _vars + if b._vars->Stdlib.Set.has(initial) { + {_var: initial, _varScope: b._scope, _isAsync: false} + } else { + {_initial: initial, _varScope: b._scope, _isAsync: false} + } + } + + let asyncVal = (b: b, initial: string): val => { + let var = b->varWithoutAllocation + let allocation = `${var}=()=>${initial}` + let varsAllocation = b._scope._varsAllocation + b._scope._varsAllocation = varsAllocation === "" + ? allocation + : varsAllocation ++ "," ++ allocation + // TODO: Don't require for it to be a var. + // FIXME: isAsync is currently not used + {_var: var, _varScope: b._scope, _isAsync: true} + } + module Val = { - let embed = (b: b, val: val) => { + let inline = (b: b, val: val) => { switch val { | {_var: ?Some(var)} => var | {_initial: ?Some(initial)} => initial @@ -492,31 +517,6 @@ module Builder = { } } - let allocateVal = (b: b): val => { - {_varScope: b._scope, _isAsync: false} - } - - let val = (b: b, initial: string): val => { - // TODO: Get rid of _vars - if b._vars->Stdlib.Set.has(initial) { - {_var: initial, _varScope: b._scope, _isAsync: false} - } else { - {_initial: initial, _varScope: b._scope, _isAsync: false} - } - } - - let asyncVal = (b: b, initial: string): val => { - let var = b->varWithoutAllocation - let allocation = `${var}=()=>${initial}` - let varsAllocation = b._scope._varsAllocation - b._scope._varsAllocation = varsAllocation === "" - ? allocation - : varsAllocation ++ "," ++ allocation - // TODO: Don't require for it to be a var. - // FIXME: isAsync is currently not used - {_var: var, _varScope: b._scope, _isAsync: true} - } - @inline let useInputVal = (b: b): val => { b._input @@ -524,18 +524,9 @@ module Builder = { @inline let useInput = b => { - b->Val.embed(b._input) + b->Val.inline(b._input) } - let toVar = (b, val) => - if b._vars->Stdlib.Set.has(val) { - val - } else { - let var = b->var - b.code = b.code ++ `${var}=${val};` - var - } - @inline let useInputVar = b => { b->Val.var(b._input) @@ -551,34 +542,34 @@ module Builder = { let prevCode = b.code b.code = "" let inputVar = b->varWithoutAllocation - let operationOutputVar = operation(b, ~input=inputVar) + let operationOutputVal = operation(b, ~input=inputVar) let outputVar = b->var b.code = prevCode ++ - `${outputVar}=()=>${input}().then(${inputVar}=>{${b.code}return ${operationOutputVar}${isAsync - ? "()" - : ""}});` + `${outputVar}=()=>${input}().then(${inputVar}=>{${b.code}return ${b->Val.inline( + operationOutputVal, + )}${isAsync ? "()" : ""}});` outputVar } else if isAsync { b.isAsyncBranch = true // TODO: Would be nice to remove. Needed to enforce that async ops are always vars let outputVar = b->var - b.code = b.code ++ `${outputVar}=${operation(b, ~input)};` + b.code = b.code ++ `${outputVar}=${b->Val.inline(operation(b, ~input))};` outputVar } else { - operation(b, ~input) + b->Val.inline(operation(b, ~input)) } } let embedSyncOperation = (b: b, ~input, ~fn: 'input => 'output) => { b->transform(~input, ~isAsync=false, (b, ~input) => { - `${b->embed(fn)}(${input})` + b->val(`${b->embed(fn)}(${input})`) }) } let embedAsyncOperation = (b: b, ~input, ~fn: 'input => unit => promise<'output>) => { b->transform(~input, ~isAsync=true, (b, ~input) => { - `${b->embed(fn)}(${input})` + b->val(`${b->embed(fn)}(${input})`) }) } @@ -671,7 +662,8 @@ module Builder = { } } - let typeFilterCode = (b: b, ~typeFilter, ~schema, ~inputVar, ~path) => { + let typeFilterCode = (b: b, ~typeFilter, ~schema, ~input, ~path) => { + let inputVar = b->Val.var(input) `if(${typeFilter(~inputVar)}){${b->raiseWithArg( ~path, input => InvalidType({ @@ -685,14 +677,13 @@ module Builder = { let use = (b: b, ~schema, ~input, ~path) => { let isParentAsync = b.isAsyncBranch let isParsing = b.operation === Parsing - b._input = b->val(input) + b._input = input b.isAsyncBranch = false - let outputVal = ( + let output = ( (isParsing ? schema.parseOperationBuilder : schema.serializeOperationBuilder)->( Obj.magic: builder => implementation ) )(b, ~selfSchema=schema, ~path) - let output = b->Val.embed(outputVal) if isParsing { schema.isAsyncParse = Value(b.isAsyncBranch) b.isAsyncBranch = isParentAsync || b.isAsyncBranch @@ -703,9 +694,8 @@ module Builder = { let useWithTypeFilter = (b: b, ~schema, ~input, ~path) => { let input = switch schema.maybeTypeFilter { | Some(typeFilter) => { - let inputVar = b->toVar(input) - b.code = b.code ++ b->typeFilterCode(~schema, ~typeFilter, ~inputVar, ~path) - inputVar + b.code = b.code ++ b->typeFilterCode(~schema, ~typeFilter, ~input, ~path) + input } | None => input } @@ -719,7 +709,7 @@ module Builder = { | exn => { let error = exn->InternalError.getOrRethrow b.code = `throw ${b->embed(error)};` - b->Val.embed(b._input) + b._input } } } @@ -738,11 +728,12 @@ module Builder = { let scope = { _varsAllocation: "", } + let input = {_var: intitialInputVar, _varScope: scope, _isAsync: false} let b = { _embeded: [], _varCounter: -1, _vars: Stdlib.Set.fromArray([intitialInputVar]), - _input: {_var: intitialInputVar, _varScope: scope, _isAsync: false}, + _input: input, _scope: scope, code: "", isAsyncBranch: false, @@ -754,7 +745,7 @@ module Builder = { ~selfSchema=schema, ~path=Path.empty, ) - let output = b->B.Val.embed(outputVal) + let output = b->B.Val.inline(outputVal) if b._scope._varsAllocation !== "" { b.code = `let ${b._scope._varsAllocation};${b.code}` @@ -763,9 +754,7 @@ module Builder = { if operation === Parsing { switch schema.maybeTypeFilter { | Some(typeFilter) => - b.code = - b->B.typeFilterCode(~schema, ~typeFilter, ~inputVar=intitialInputVar, ~path=Path.empty) ++ - b.code + b.code = b->B.typeFilterCode(~schema, ~typeFilter, ~input, ~path=Path.empty) ++ b.code | None => () } schema.isAsyncParse = Value(b.isAsyncBranch) @@ -1501,27 +1490,33 @@ let internalRefine = (schema, refiner) => { ~name=schema.name, ~tagged=schema.tagged, ~parseOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { - let input = b->B.useInput + let input = b->B.useInputVal b->B.val( - b->B.transform(~input=b->B.use(~schema, ~input, ~path), ~isAsync=false, (b, ~input) => { - let inputVar = b->B.toVar(input) - b.code = b.code ++ refiner(b, ~inputVar, ~selfSchema, ~path) - inputVar - }), + b->B.transform( + ~input=b->B.use(~schema, ~input, ~path)->(B.Val.inline(b, _)), + ~isAsync=false, + (b, ~input) => { + let input = b->B.val(input) + b.code = b.code ++ refiner(b, ~input, ~selfSchema, ~path) + input + }, + ), ) }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { let input = b->B.useInput - b->B.val( - b->B.use( - ~schema, - ~input=b->B.transform(~input, ~isAsync=false, (b, ~input) => { - let inputVar = b->B.toVar(input) - b.code = b.code ++ refiner(b, ~inputVar, ~selfSchema, ~path) - inputVar - }), - ~path, - ), + + b->B.use( + ~schema, + ~input=b + ->B.transform(~input, ~isAsync=false, (b, ~input) => { + let input = b->B.val(input) + b.code = b.code ++ refiner(b, ~input, ~selfSchema, ~path) + input + }) + // TODO: Remove all ->(B.val(b, _)) and clean up many B.val/B.var/B.inline in other places + ->(B.val(b, _)), + ~path, ) }), ~maybeTypeFilter=schema.maybeTypeFilter, @@ -1530,10 +1525,10 @@ let internalRefine = (schema, refiner) => { } let refine: (t<'value>, s<'value> => 'value => unit) => t<'value> = (schema, refiner) => { - schema->internalRefine((b, ~inputVar, ~selfSchema, ~path) => { + schema->internalRefine((b, ~input, ~selfSchema, ~path) => { `${b->B.embed( refiner(EffectCtx.make(~selfSchema, ~path, ~operation=b.operation)), - )}(${inputVar});` + )}(${b->B.Val.var(input)});` }) } @@ -1566,8 +1561,8 @@ let transform: (t<'input>, s<'output> => transformDefinition<'input, 'output>) = ~name=schema.name, ~tagged=schema.tagged, ~parseOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { - let input = b->B.useInput - let input = b->B.use(~schema, ~input, ~path) + let input = b->B.useInputVal + let input = b->B.use(~schema, ~input, ~path)->(B.Val.inline(b, _)) b->B.val( switch transformer(EffectCtx.make(~selfSchema, ~path, ~operation=b.operation)) { | {parser, asyncParser: ?None} => b->B.embedSyncOperation(~input, ~fn=parser) @@ -1584,12 +1579,20 @@ let transform: (t<'input>, s<'output> => transformDefinition<'input, 'output>) = ) }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { - let input = b->B.useInput b->B.val( switch transformer(EffectCtx.make(~selfSchema, ~path, ~operation=b.operation)) { | {serializer} => - b->B.use(~schema, ~input=b->B.embedSyncOperation(~input, ~fn=serializer), ~path) - | {parser: ?None, asyncParser: ?None, serializer: ?None} => b->B.use(~schema, ~input, ~path) + let input = b->B.useInput + b + ->B.use( + ~schema, + ~input=b->B.embedSyncOperation(~input, ~fn=serializer)->(B.val(b, _)), + ~path, + ) + ->(B.Val.inline(b, _)) + | {parser: ?None, asyncParser: ?None, serializer: ?None} => + let input = b->B.useInputVal + b->B.use(~schema, ~input, ~path)->(B.Val.inline(b, _)) | {serializer: ?None, asyncParser: ?Some(_)} | {serializer: ?None, parser: ?Some(_)} => b->B.invalidOperation(~path, ~description=`The S.transform serializer is missing`) @@ -1638,7 +1641,9 @@ let rec preprocess = (schema, transformer) => { let operationResultVar = b->B.var b.code = b.code ++ `${operationResultVar}=${b->B.embedSyncOperation(~input, ~fn=parser)};` - b->B.useWithTypeFilter(~schema, ~input=operationResultVar, ~path) + b + ->B.useWithTypeFilter(~schema, ~input=operationResultVar->(B.val(b, _)), ~path) + ->(B.Val.inline(b, _)) | {parser: ?None, asyncParser} => { let parseResultVar = b->B.embedAsyncOperation(~input, ~fn=asyncParser) let outputVar = b->B.var @@ -1649,13 +1654,18 @@ let rec preprocess = (schema, transformer) => { b.code ++ `${outputVar}=()=>${parseResultVar}().then(${asyncResultVar}=>{${b->B.scope(b => { let schemaOutputVar = - b->B.useWithTypeFilter(~schema, ~input=asyncResultVar, ~path) + b + ->B.useWithTypeFilter(~schema, ~input=asyncResultVar->(B.val(b, _)), ~path) + ->(B.Val.inline(b, _)) let isAsync = schema.isAsyncParse->(Obj.magic: isAsyncParse => bool) `return ${isAsync ? `${schemaOutputVar}()` : schemaOutputVar}` })}});` outputVar } - | {parser: ?None, asyncParser: ?None} => b->B.useWithTypeFilter(~schema, ~input, ~path) + | {parser: ?None, asyncParser: ?None} => + b + ->B.useWithTypeFilter(~schema, ~input=input->(B.val(b, _)), ~path) + ->(B.Val.inline(b, _)) | {parser: _, asyncParser: _} => b->B.invalidOperation( ~path, @@ -1665,8 +1675,8 @@ let rec preprocess = (schema, transformer) => { ) }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { - let input = b->B.useInput - let input = b->B.use(~schema, ~input, ~path) + let input = b->B.useInputVal + let input = b->B.use(~schema, ~input, ~path)->(B.Val.inline(b, _)) b->B.val( switch transformer(EffectCtx.make(~selfSchema, ~path, ~operation=b.operation)) { @@ -1800,8 +1810,13 @@ module Variant = { ~name=schema.name, ~tagged=schema.tagged, ~parseOperationBuilder=Builder.make((b, ~selfSchema as _, ~path) => { - let input = b->B.useInput - b->B.val(b->B.embedSyncOperation(~input=b->B.use(~schema, ~input, ~path), ~fn=definer)) + let input = b->B.useInputVal + b->B.val( + b->B.embedSyncOperation( + ~input=b->B.use(~schema, ~input, ~path)->(B.Val.inline(b, _)), + ~fn=definer, + ), + ) }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { let inputVar = b->B.useInputVar @@ -1864,25 +1879,24 @@ module Variant = { definitionToOutput(definition, ~outputPath=Path.empty) } - b->B.val( - switch output { - | RegisteredMultipleTimes => + switch output { + | RegisteredMultipleTimes => + b->B.invalidOperation( + ~path, + ~description=`Can't create serializer. The S.variant's value is registered multiple times. Use S.transform instead`, + ) + | Registered(var) => b->B.use(~schema, ~input=var->(B.val(b, _)), ~path) + | Unregistered => + switch selfSchema->toInternalLiteral { + | Some(literal) => + b->B.use(~schema, ~input=b->B.embed(literal.value)->(B.val(b, _)), ~path) + | None => b->B.invalidOperation( ~path, - ~description=`Can't create serializer. The S.variant's value is registered multiple times. Use S.transform instead`, + ~description=`Can't create serializer. The S.variant's value is not registered and not a literal. Use S.transform instead`, ) - | Registered(var) => b->B.use(~schema, ~input=var, ~path) - | Unregistered => - switch selfSchema->toInternalLiteral { - | Some(literal) => b->B.use(~schema, ~input=b->B.embed(literal.value), ~path) - | None => - b->B.invalidOperation( - ~path, - ~description=`Can't create serializer. The S.variant's value is not registered and not a literal. Use S.transform instead`, - ) - } - }, - ) + } + } }), ~maybeTypeFilter=schema.maybeTypeFilter, ~metadataMap=schema.metadataMap, @@ -1902,20 +1916,23 @@ module Option = { let default = schema => schema->Metadata.get(~id=defaultMetadataId) let parseOperationBuilder = Builder.make((b, ~selfSchema, ~path) => { - let inputVar = b->B.useInputVar + let input = b->B.useInputVal let outputVal = b->B.allocateVal let isNull = %raw(`selfSchema.t.TAG === "Null"`) let childSchema = selfSchema.tagged->unsafeGetVariantPayload let ifCode = b->B.scope(b => { - b->B.Val.set(outputVal, b->B.use(~schema=childSchema, ~input=inputVar, ~path)) + b->B.Val.set(outputVal, b->B.use(~schema=childSchema, ~input, ~path)->(B.Val.inline(b, _))) }) let isAsync = childSchema.isAsyncParse->(Obj.magic: isAsyncParse => bool) b.code = b.code ++ - `if(${inputVar}!==${isNull ? "null" : "void 0"}){${ifCode}}${switch (isNull, isAsync) { + `if(${b->B.Val.var(input)}!==${isNull ? "null" : "void 0"}){${ifCode}}${switch ( + isNull, + isAsync, + ) { | (false, false) => "" | _ => `else{${b->B.Val.set( @@ -1931,7 +1948,7 @@ module Option = { }) let serializeOperationBuilder = Builder.make((b, ~selfSchema, ~path) => { - let inputVar = b->B.useInputVar + let input = b->B.useInputVal let outputVal = b->B.allocateVal let isNull = %raw(`selfSchema.t.TAG === "Null"`) @@ -1939,14 +1956,18 @@ module Option = { b.code = b.code ++ - `if(${inputVar}!==void 0){${b->B.scope(b => { + `if(${b->B.Val.var(input)}!==void 0){${b->B.scope(b => { b->B.Val.set( outputVal, - b->B.use( + b + ->B.use( ~schema=childSchema, - ~input=`${b->B.embed(%raw("Caml_option.valFromOption"))}(${inputVar})`, + ~input=`${b->B.embed(%raw("Caml_option.valFromOption"))}(${b->B.Val.var(input)})`->( + B.val(b, _) + ), ~path, - ), + ) + ->(B.Val.inline(b, _)), ) })}}${isNull ? `else{${b->B.Val.set(outputVal, `null`)}}` : ""}` @@ -1984,15 +2005,21 @@ module Option = { ~metadataMap=schema.metadataMap->Metadata.Map.set(~id=defaultMetadataId, default), ~tagged=schema.tagged, ~parseOperationBuilder=Builder.make((b, ~selfSchema as _, ~path) => { - let input = b->B.useInput + let input = b->B.useInputVal b->B.val( - b->B.transform(~input=b->B.use(~schema, ~input, ~path), ~isAsync=false, (b, ~input) => { - // TODO: Reassign input if it's not a var - `${input}===void 0?${switch default { - | Value(v) => b->B.embed(v) - | Callback(cb) => `${b->B.embed(cb)}()` - }}:${input}` - }), + b->B.transform( + ~input=b->B.use(~schema, ~input, ~path)->(B.Val.inline(b, _)), + ~isAsync=false, + (b, ~input) => { + // TODO: Reassign input if it's not a var + b->B.val( + `${input}===void 0?${switch default { + | Value(v) => b->B.embed(v) + | Callback(cb) => `${b->B.embed(cb)}()` + }}:${input}`, + ) + }, + ), ) }), ~serializeOperationBuilder=schema.serializeOperationBuilder, @@ -2075,11 +2102,13 @@ module Object = { registeredDefinitions->Stdlib.Set.add(itemDefinition)->ignore let {schema, inputPath} = itemDefinition let fieldOuputVar = - b->B.useWithTypeFilter( + b + ->B.useWithTypeFilter( ~schema, - ~input=`${inputVar}${inputPath}`, + ~input=`${inputVar}${inputPath}`->(B.val(b, _)), ~path=path->Path.concat(inputPath), ) + ->(B.Val.inline(b, _)) let isAsyncField = schema.isAsyncParse->(Obj.magic: isAsyncParse => bool) if isAsyncField { // TODO: Ensure that it's not a var, but inlined @@ -2122,11 +2151,13 @@ module Object = { if registeredDefinitions->Stdlib.Set.has(itemDefinition)->not { let {schema, inputPath} = itemDefinition let fieldOuputVar = - b->B.useWithTypeFilter( + b + ->B.useWithTypeFilter( ~schema, - ~input=`${inputVar}${inputPath}`, + ~input=`${inputVar}${inputPath}`->(B.val(b, _)), ~path=path->Path.concat(inputPath), ) + ->(B.Val.inline(b, _)) let isAsyncField = schema.isAsyncParse->(Obj.magic: isAsyncParse => bool) if isAsyncField { // TODO: Ensure that it's not a var, but inlined @@ -2249,7 +2280,7 @@ module Object = { ~itemDefinitions, ~itemDefinitionsSet, ~definition, - ~inputRefinement=noopRefinement, + ~inputRefinement=None, ~unknownKeysRefinement=(b, ~selfSchema, ~inputVar, ~path) => { let withUnknownKeysRefinement = (selfSchema->classify->Obj.magic)["unknownKeys"] === Strict @@ -2310,11 +2341,13 @@ module Object = { let {inlinedInputLocation, schema} = itemDefinition fieldsCodeRef.contents = fieldsCodeRef.contents ++ - `${inlinedInputLocation}:${b->B.use( + `${inlinedInputLocation}:${b + ->B.use( ~schema, - ~input=`${inputVar}${outputPath}`, + ~input=`${inputVar}${outputPath}`->(B.val(b, _)), ~path=path->Path.concat(outputPath), - )},` + ) + ->(B.Val.inline(b, _))},` } | Constant => { let value = definition->Definition.toConstant @@ -2404,7 +2437,7 @@ module Object = { module Never = { let builder = Builder.make((b, ~selfSchema, ~path) => { - let input = b->B.useInput + let input = b->B.useInputVal b.code = b.code ++ b->B.raiseWithArg( @@ -2413,9 +2446,9 @@ module Never = { expected: selfSchema, received: input, }), - input, + b->B.Val.inline(input), ) ++ ";" - b->B.val(input) + input }) let schema = make( @@ -2494,8 +2527,8 @@ module String = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({length: length}), @@ -2511,8 +2544,8 @@ module String = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({length: length}), @@ -2528,8 +2561,8 @@ module String = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Length({length: length}), @@ -2541,8 +2574,8 @@ module String = { let email = (schema, ~message=`Invalid email address`) => { schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(!${b->B.embed(emailRegex)}.test(${inputVar})){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(!${b->B.embed(emailRegex)}.test(${b->B.Val.var(input)})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Email, @@ -2554,8 +2587,8 @@ module String = { let uuid = (schema, ~message=`Invalid UUID`) => { schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(!${b->B.embed(uuidRegex)}.test(${inputVar})){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(!${b->B.embed(uuidRegex)}.test(${b->B.Val.var(input)})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Uuid, @@ -2567,8 +2600,8 @@ module String = { let cuid = (schema, ~message=`Invalid CUID`) => { schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(!${b->B.embed(cuidRegex)}.test(${inputVar})){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(!${b->B.embed(cuidRegex)}.test(${b->B.Val.var(input)})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Cuid, @@ -2580,8 +2613,8 @@ module String = { let url = (schema, ~message=`Invalid url`) => { schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `try{new URL(${inputVar})}catch(_){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `try{new URL(${b->B.Val.var(input)})}catch(_){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Url, @@ -2593,11 +2626,11 @@ module String = { let pattern = (schema, re, ~message=`Invalid`) => { schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { let reVar = b->B.var - `${reVar}=${b->B.embed( - re, - )};${reVar}.lastIndex=0;if(!${reVar}.test(${inputVar})){${b->B.fail(~message, ~path)}}` + `${reVar}=${b->B.embed(re)};${reVar}.lastIndex=0;if(!${reVar}.test(${b->B.Val.var( + input, + )})){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Pattern({re: re}), @@ -2666,12 +2699,12 @@ module JsonString = { "t.message", )}}` - b->B.val(b->B.useWithTypeFilter(~schema, ~input=jsonVar, ~path)) + b->B.useWithTypeFilter(~schema, ~input=jsonVar->(B.val(b, _)), ~path) }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema as _, ~path) => { - let input = b->B.useInput + let input = b->B.useInputVal b->B.val( - `JSON.stringify(${b->B.use(~schema, ~input, ~path)}${space > 0 + `JSON.stringify(${b->B.Val.inline(b->B.use(~schema, ~input, ~path))}${space > 0 ? `,null,${space->Stdlib.Int.unsafeToString}` : ""})`, ) @@ -2735,8 +2768,8 @@ module Int = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({value: minValue}), @@ -2752,8 +2785,8 @@ module Int = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({value: maxValue}), @@ -2765,8 +2798,8 @@ module Int = { let port = (schema, ~message="Invalid port") => { schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}<1||${inputVar}>65535){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}<1||${b->B.Val.var(input)}>65535){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Port, @@ -2816,8 +2849,8 @@ module Float = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}<${b->B.embed(minValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({value: minValue}), @@ -2833,8 +2866,8 @@ module Float = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}>${b->B.embed(maxValue)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({value: maxValue}), @@ -2885,13 +2918,18 @@ module Array = { b.code ++ `for(let ${iteratorVar}=0;${iteratorVar}<${inputVar}.length;++${iteratorVar}){${b->B.scope( b => { - let itemOutputVar = - b->B.withPathPrepend( - ~path, - ~dynamicLocationVar=iteratorVar, - (b, ~path) => - b->B.useWithTypeFilter(~schema, ~input=`${inputVar}[${iteratorVar}]`, ~path), - ) + let itemOutputVar = b->B.withPathPrepend( + ~path, + ~dynamicLocationVar=iteratorVar, + (b, ~path) => + b + ->B.useWithTypeFilter( + ~schema, + ~input=`${inputVar}[${iteratorVar}]`->(B.val(b, _)), + ~path, + ) + ->(B.Val.inline(b, _)), + ) b->B.Val.push(outputVal, itemOutputVar) }, )}}` @@ -2915,12 +2953,14 @@ module Array = { b.code ++ `for(let ${iteratorVar}=0;${iteratorVar}<${inputVar}.length;++${iteratorVar}){${b->B.scope( b => { - let itemOutputVar = - b->B.withPathPrepend( - ~path, - ~dynamicLocationVar=iteratorVar, - (b, ~path) => b->B.use(~schema, ~input=`${inputVar}[${iteratorVar}]`, ~path), - ) + let itemOutputVar = b->B.withPathPrepend( + ~path, + ~dynamicLocationVar=iteratorVar, + (b, ~path) => + b + ->B.use(~schema, ~input=`${inputVar}[${iteratorVar}]`->(B.val(b, _)), ~path) + ->(B.Val.inline(b, _)), + ) b->B.Val.push(outputVal, itemOutputVar) }, )}}` @@ -2939,8 +2979,8 @@ module Array = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}.length<${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Min({length: length}), @@ -2956,8 +2996,8 @@ module Array = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}.length>${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Max({length: length}), @@ -2973,8 +3013,8 @@ module Array = { } schema->addRefinement( ~metadataId=Refinement.metadataId, - ~refiner=(b, ~inputVar, ~selfSchema as _, ~path) => { - `if(${inputVar}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` + ~refiner=(b, ~input, ~selfSchema as _, ~path) => { + `if(${b->B.Val.var(input)}.length!==${b->B.embed(length)}){${b->B.fail(~message, ~path)}}` }, ~refinement={ kind: Length({length: length}), @@ -2999,13 +3039,18 @@ module Dict = { b.code = b.code ++ `${outputVar}={};for(let ${keyVar} in ${inputVar}){${b->B.scope(b => { - let itemOutputVar = - b->B.withPathPrepend( - ~path, - ~dynamicLocationVar=keyVar, - (b, ~path) => - b->B.useWithTypeFilter(~schema, ~input=`${inputVar}[${keyVar}]`, ~path), - ) + let itemOutputVar = b->B.withPathPrepend( + ~path, + ~dynamicLocationVar=keyVar, + (b, ~path) => + b + ->B.useWithTypeFilter( + ~schema, + ~input=`${inputVar}[${keyVar}]`->(B.val(b, _)), + ~path, + ) + ->(B.Val.inline(b, _)), + ) `${outputVar}[${keyVar}]=${itemOutputVar}` })}}` @@ -3038,12 +3083,14 @@ module Dict = { b.code = b.code ++ `${outputVar}={};for(let ${keyVar} in ${inputVar}){${b->B.scope(b => { - let itemOutputVar = - b->B.withPathPrepend( - ~path, - ~dynamicLocationVar=keyVar, - (b, ~path) => b->B.use(~schema, ~input=`${inputVar}[${keyVar}]`, ~path), - ) + let itemOutputVar = b->B.withPathPrepend( + ~path, + ~dynamicLocationVar=keyVar, + (b, ~path) => + b + ->B.use(~schema, ~input=`${inputVar}[${keyVar}]`->(B.val(b, _)), ~path) + ->(B.Val.inline(b, _)), + ) `${outputVar}[${keyVar}]=${itemOutputVar}` })}}` @@ -3145,7 +3192,7 @@ module Tuple = { ~itemDefinitionsSet, ~definition, ~inputRefinement=Some( - (b, ~selfSchema as _, ~inputVar, ~path) => { + (b, ~selfSchema as _, ~path) => { let inputVar = b->B.useInputVar b.code = @@ -3188,11 +3235,13 @@ module Tuple = { registeredDefinitions->Stdlib.Set.add(itemDefinition)->ignore let {schema, inputPath} = itemDefinition let fieldOuputVar = - b->B.use( + b + ->B.use( ~schema, - ~input=`${inputVar}${outputPath}`, + ~input=`${inputVar}${outputPath}`->(B.val(b, _)), ~path=path->Path.concat(outputPath), ) + ->(B.Val.inline(b, _)) b.code = b.code ++ `${outputVar}${inputPath}=${fieldOuputVar};` } | Constant => { @@ -3263,23 +3312,23 @@ module Union = { ~metadataMap=Metadata.Map.empty, ~tagged=Union(schemas), ~parseOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { - let inputVar = b->B.useInputVar + let input = b->B.useInputVal let schemas = selfSchema->classify->unsafeGetVariantPayload let isAsyncRef = ref(false) let itemsCode = [] - let itemsOutputVar = [] + let itemOutputVars = [] let prevCode = b.code for idx in 0 to schemas->Js.Array2.length - 1 { let schema = schemas->Js.Array2.unsafe_get(idx) b.code = "" - let itemOutputVar = b->B.withBuildErrorInline( + let itemOutputVal = b->B.withBuildErrorInline( () => { b->B.useWithTypeFilter( // A hack to bypass an additional function wrapping for var context optimisation ~schema=%raw(`schema`), - ~input=inputVar, + ~input, ~path=Path.empty, ) }, @@ -3288,7 +3337,7 @@ module Union = { if isAsyncItem { isAsyncRef.contents = true } - itemsOutputVar->Js.Array2.push(itemOutputVar)->ignore + itemOutputVars->Js.Array2.push(itemOutputVal->(B.Val.inline(b, _)))->ignore itemsCode->Js.Array2.push(b.code)->ignore } b.code = prevCode @@ -3303,7 +3352,7 @@ module Union = { for idx in 0 to schemas->Js.Array2.length - 1 { let schema = schemas->Js.Array2.unsafe_get(idx) let code = itemsCode->Js.Array2.unsafe_get(idx) - let itemOutputVar = itemsOutputVar->Js.Array2.unsafe_get(idx) + let itemOutputVar = itemOutputVars->Js.Array2.unsafe_get(idx) let isAsyncItem = schema.isAsyncParse->(Obj.magic: isAsyncParse => bool) let errorVar = b->B.varWithoutAllocation @@ -3357,7 +3406,7 @@ module Union = { } }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema, ~path) => { - let inputVar = b->B.useInputVar + let input = b->B.useInputVal let schemas = selfSchema->classify->unsafeGetVariantPayload let outputVar = b->B.var @@ -3376,23 +3425,21 @@ module Union = { b => { let itemOutput = b->B.withBuildErrorInline( - () => b->B.use(~schema=itemSchema, ~input=inputVar, ~path=Path.empty), + () => b->B.use(~schema=itemSchema, ~input, ~path=Path.empty), ) - let itemOutput = switch itemSchema.maybeTypeFilter { + switch itemSchema.maybeTypeFilter { | Some(typeFilter) => - let itemOutputVar = b->B.toVar(itemOutput) b.code = b.code ++ b->B.typeFilterCode( ~schema=itemSchema, ~typeFilter, - ~inputVar=itemOutputVar, + ~input=itemOutput, ~path=Path.empty, ) - itemOutputVar - | None => itemOutput + | None => () } - `${outputVar}=${itemOutput}` + `${outputVar}=${itemOutput->(B.Val.inline(b, _))}` }, )}}catch(${errorVar}){if(${b->B.isInternalError(errorVar)}){` @@ -3484,9 +3531,9 @@ let json = (~validate) => ) } } - let input = b->B.useInput + let input = b->B.useInputVal - b->B.val(`${b->B.embed(parse)}(${input})`) + b->B.val(`${b->B.embed(parse)}(${b->B.Val.inline(input)})`) }) : Builder.noop, ) @@ -3524,7 +3571,9 @@ let catch = (schema, getFallbackValue) => { )}(${inputVar},${errorVar})`, ), b => { - b->B.useWithTypeFilter(~schema, ~input=inputVar, ~path) + b + ->B.useWithTypeFilter(~schema, ~input=inputVar->(B.val(b, _)), ~path) + ->(B.Val.inline(b, _)) }, ), ) @@ -4102,12 +4151,12 @@ let js_merge = (s1, s2) => { fields, }), ~parseOperationBuilder=Builder.make((b, ~selfSchema as _, ~path) => { - let inputVar = b->B.useInputVar - let s1Result = b->B.use(~schema=s1, ~input=inputVar, ~path) - let s2Result = b->B.use(~schema=s2, ~input=inputVar, ~path) + let input = b->B.useInputVal + let s1Result = b->B.use(~schema=s1, ~input, ~path) + let s2Result = b->B.use(~schema=s2, ~input, ~path) // TODO: Check that these are objects // TODO: Check that s1Result is not mutating input - b->B.val(`Object.assign(${s1Result}, ${s2Result})`) + b->B.val(`Object.assign(${b->B.Val.inline(s1Result)}, ${b->B.Val.inline(s2Result)})`) }), ~serializeOperationBuilder=Builder.make((b, ~selfSchema as _, ~path) => { b->B.invalidOperation(~path, ~description=`The S.merge serializing is not supported yet`)