Skip to content

Commit f9dd1eb

Browse files
committed
A few more test fixes
1 parent 9b984ea commit f9dd1eb

File tree

3 files changed

+254
-269
lines changed

3 files changed

+254
-269
lines changed

packages/sury/src/Sury.res

Lines changed: 63 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,6 @@ and has = {
545545
}
546546
and builder = (~input: val, ~selfSchema: internal) => val
547547
and val = {
548-
mutable prev?: val,
549548
// We might have the same value, but different instances of the val object
550549
// Use the bond field, to connect the var call
551550
@as("b")
@@ -556,14 +555,15 @@ and val = {
556555
mutable var: unit => string,
557556
@as("i")
558557
mutable inline: string,
559-
@as("f")
560-
mutable flag: flag,
561558
// The schema of the value that is being parsed
562559
@as("s")
563560
mutable schema: internal,
564561
// The schema of the value that we expect to parse into
565562
@as("e")
566563
mutable expected: internal,
564+
mutable prev?: val,
565+
@as("f")
566+
mutable flag: flag,
567567
@as("k")
568568
mutable skipTo?: bool,
569569
@as("d")
@@ -1306,39 +1306,6 @@ module Builder = {
13061306
)
13071307
}
13081308

1309-
let refineInPlace = (val: val, ~schema, ~validation) => {
1310-
// if val.prev !== None {
1311-
// let inputVar = val.var()
1312-
// if val.varsAllocation !== "" {
1313-
// val.codeAfterValidation = val.codeAfterValidation ++ `let ${val.varsAllocation};`
1314-
// val.varsAllocation = ""
1315-
// val.allocate = initialAllocate
1316-
// }
1317-
// val.codeAfterValidation =
1318-
// val.codeAfterValidation ++
1319-
// `if(${validation(~inputVar, ~negative=true)}){${embedInvalidInput(
1320-
// ~input=val,
1321-
// ~expected=val.expected,
1322-
// )}}`
1323-
// } else {
1324-
1325-
let prevValidation = val.validation
1326-
val.validation = Some(
1327-
(~inputVar, ~negative) => {
1328-
{
1329-
switch prevValidation {
1330-
| Some(prevValidation) => prevValidation(~inputVar, ~negative) ++ and_(~negative)
1331-
| None => ""
1332-
}
1333-
} ++
1334-
validation(~inputVar, ~negative)
1335-
},
1336-
)
1337-
1338-
// }
1339-
val.schema = schema
1340-
}
1341-
13421309
let next = (prev: val, initial: string, ~schema, ~expected=prev.expected): val => {
13431310
{
13441311
// FIXME: vals and other object.val fields should be copied
@@ -2091,7 +2058,7 @@ let rec parse = (input: val, ~withEncoder: bool=false) => {
20912058
switch output.contents.expected {
20922059
| {parser} => output := parser(~input=output.contents, ~selfSchema=output.contents.expected)
20932060
| _ =>
2094-
switch output.contents.expected.encoder {
2061+
switch output.contents.schema.encoder {
20952062
| Some(encoder) if to.tag !== unknownTag =>
20962063
output := encoder(~input=output.contents, ~selfSchema=to)
20972064
| _ => ()
@@ -2421,6 +2388,7 @@ let rec makeObjectVal = (prev: val, ~schema): B.Val.Object.t => {
24212388
},
24222389
expected: prev.expected,
24232390
vals: Js.Dict.empty(),
2391+
hasTransform: true,
24242392
codeFromPrev: "",
24252393
codeAfterValidation: "",
24262394
varsAllocation: "",
@@ -2439,6 +2407,7 @@ and array = item => {
24392407
mut->castToPublic
24402408
}
24412409
and arrayDecoder: builder = (~input as unknownInput, ~selfSchema as _) => {
2410+
let isUnion = unknownInput.isUnion->X.Option.getUnsafe
24422411
let expectedSchema = unknownInput.expected
24432412
let unknownInputTagFlag = unknownInput.schema.tag->TagFlag.get
24442413
let expectedItems = expectedSchema.items->X.Option.getUnsafe
@@ -2477,7 +2446,9 @@ and arrayDecoder: builder = (~input as unknownInput, ~selfSchema as _) => {
24772446
}
24782447
switch validation.contents {
24792448
| Some(validation) => unknownInput->B.refine(~schema, ~validation)
2480-
| None => unknownInput
2449+
// Apply refine also here,
2450+
// so literals for union cases don't mutate input
2451+
| None => unknownInput->B.refine
24812452
}
24822453
} else {
24832454
unknownInput->B.unsupportedConversion(~from=unknownInput.schema, ~target=expectedSchema)
@@ -2523,8 +2494,6 @@ and arrayDecoder: builder = (~input as unknownInput, ~selfSchema as _) => {
25232494
}
25242495
}
25252496
| _ =>
2526-
let isUnion = input.isUnion->X.Option.getUnsafe
2527-
25282497
let objectVal = input->makeObjectVal(~schema=expectedSchema)
25292498
let shouldRecreateInput = ref(
25302499
switch expectedSchema.additionalItems->X.Option.getUnsafe {
@@ -2549,19 +2518,20 @@ and arrayDecoder: builder = (~input as unknownInput, ~selfSchema as _) => {
25492518

25502519
switch itemOutput.validation {
25512520
| Some(validation) if isUnion && schema->isLiteral =>
2552-
let _ = input->B.refineInPlace(~schema=input.schema, ~validation=(~inputVar, ~negative) => {
2553-
validation(
2554-
~inputVar=inputVar ++ input.global->B.inlineLocation(key)->Path.fromInlinedLocation,
2555-
~negative,
2556-
)
2557-
})
2521+
input.validation =
2522+
input.validation->B.appendValidation((~inputVar, ~negative) => {
2523+
validation(
2524+
~inputVar=inputVar ++ input.global->B.inlineLocation(key)->Path.fromInlinedLocation,
2525+
~negative,
2526+
)
2527+
})
25582528
itemOutput.validation = None
25592529
| _ => ()
25602530
}
25612531

25622532
objectVal->B.Val.Object.add(~location=key, itemOutput)
25632533
if !shouldRecreateInput.contents {
2564-
shouldRecreateInput := itemOutput !== itemInput
2534+
shouldRecreateInput := itemOutput.hasTransform->X.Option.getUnsafe
25652535
}
25662536
}
25672537

@@ -2578,6 +2548,7 @@ and arrayDecoder: builder = (~input as unknownInput, ~selfSchema as _) => {
25782548
}
25792549
}
25802550
and objectDecoder: Builder.t = (~input as unknownInput, ~selfSchema as _) => {
2551+
let isUnion = unknownInput.isUnion->X.Option.getUnsafe
25812552
let expectedSchema = unknownInput.expected
25822553
let unknownInputTagFlag = unknownInput.schema.tag->TagFlag.get
25832554

@@ -2613,7 +2584,9 @@ and objectDecoder: Builder.t = (~input as unknownInput, ~selfSchema as _) => {
26132584

26142585
switch validation.contents {
26152586
| Some(validation) => unknownInput->B.refine(~schema, ~validation)
2616-
| None => unknownInput
2587+
// Apply refine also here,
2588+
// so literals for union cases don't mutate input
2589+
| None => unknownInput->B.refine
26172590
}
26182591
} else {
26192592
unknownInput->B.unsupportedConversion(~from=unknownInput.schema, ~target=expectedSchema)
@@ -2661,8 +2634,6 @@ and objectDecoder: Builder.t = (~input as unknownInput, ~selfSchema as _) => {
26612634
}
26622635
}
26632636
| _ => {
2664-
let isUnion = input.isUnion->X.Option.getUnsafe
2665-
26662637
let properties = expectedSchema.properties->X.Option.getUnsafe
26672638
let keys = Js.Dict.keys(properties)
26682639
let keysCount = keys->Js.Array2.length
@@ -2694,22 +2665,20 @@ and objectDecoder: Builder.t = (~input as unknownInput, ~selfSchema as _) => {
26942665

26952666
switch itemOutput.validation {
26962667
| Some(validation) if isUnion && schema->isLiteral =>
2697-
let _ = input->B.refineInPlace(~schema=input.schema, ~validation=(
2698-
~inputVar,
2699-
~negative,
2700-
) => {
2701-
validation(
2702-
~inputVar=inputVar ++ input.global->B.inlineLocation(key)->Path.fromInlinedLocation,
2703-
~negative,
2704-
)
2705-
})
2668+
input.validation =
2669+
input.validation->B.appendValidation((~inputVar, ~negative) => {
2670+
validation(
2671+
~inputVar=inputVar ++ input.global->B.inlineLocation(key)->Path.fromInlinedLocation,
2672+
~negative,
2673+
)
2674+
})
27062675
itemOutput.validation = None
27072676
| _ => ()
27082677
}
27092678

27102679
objectVal->B.Val.Object.add(~location=key, itemOutput)
27112680
if !shouldRecreateInput.contents {
2712-
shouldRecreateInput := itemOutput !== itemInput
2681+
shouldRecreateInput := itemOutput.hasTransform->X.Option.getUnsafe
27132682
}
27142683
}
27152684

@@ -3349,7 +3318,12 @@ module Union = {
33493318

33503319
switch val.validation {
33513320
| Some(validation) =>
3352-
if val.hasTransform !== Some(true) {
3321+
if (
3322+
val.hasTransform === Some(true)
3323+
? (val.prev->X.Option.getUnsafe).hasTransform !== Some(true) &&
3324+
val.codeFromPrev === ""
3325+
: true
3326+
) {
33533327
// Validation must be used only when there's a prev value
33543328
let input = current.contents->X.Option.getUnsafe
33553329
let inputVar = input.var()
@@ -3511,12 +3485,13 @@ module Union = {
35113485
itemStart :=
35123486
itemStart.contents ++ if_ ++ `(!(${itemNoop.contents})){${fail(caught.contents)}}`
35133487
} else {
3514-
let _ = typeValidationOutput->B.refineInPlace(
3515-
~schema=typeValidationOutput.schema,
3516-
~validation=(~inputVar as _, ~negative) => {
3488+
typeValidationOutput.validation =
3489+
typeValidationOutput.validation->B.appendValidation((
3490+
~inputVar as _,
3491+
~negative,
3492+
) => {
35173493
`${B.exp(~negative)}(${itemNoop.contents})`
3518-
},
3519-
)
3494+
})
35203495
}
35213496
} else if withExhaustiveCheck.contents {
35223497
let errorCode = fail(caught.contents)
@@ -3652,16 +3627,23 @@ module Union = {
36523627
],
36533628
)
36543629

3655-
if (
3656-
typeValidationInput.validation !== None || (
3657-
typeValidationOutput.hasTransform === Some(true)
3658-
? typeValidationOutput.codeFromPrev === "" &&
3659-
(typeValidationOutput.prev->X.Option.getUnsafe).hasTransform !== Some(true)
3660-
: typeValidationOutput.validation !== None
3630+
let shouldDeopt = ref(true)
3631+
let valRef = ref(Some(typeValidationOutput))
3632+
while valRef.contents !== None && shouldDeopt.contents {
3633+
let v = valRef.contents->X.Option.getUnsafe
3634+
valRef := v.prev
3635+
shouldDeopt :=
3636+
!(
3637+
v.validation !== None && (
3638+
v.hasTransform === Some(true)
3639+
? (v.prev->X.Option.getUnsafe).hasTransform !== Some(true) &&
3640+
v.codeFromPrev === ""
3641+
: true
3642+
)
36613643
)
3662-
) {
3663-
()
3664-
} else {
3644+
}
3645+
3646+
if shouldDeopt.contents {
36653647
for keyIdx in 0 to keys.contents->Stdlib.Array.length - 1 {
36663648
let key = keys.contents->Stdlib.Array.getUnsafe(keyIdx)
36673649
if !exit.contents {
@@ -3717,7 +3699,12 @@ module Union = {
37173699

37183700
switch val.validation {
37193701
| Some(validation) =>
3720-
if val.hasTransform !== Some(true) {
3702+
if (
3703+
val.hasTransform === Some(true)
3704+
? (val.prev->X.Option.getUnsafe).hasTransform !== Some(true) &&
3705+
val.codeFromPrev === ""
3706+
: true
3707+
) {
37213708
// Validation must be used only when there's a prev value
37223709
let input = current.contents->X.Option.getUnsafe
37233710
let inputVar = input.var()

0 commit comments

Comments
 (0)