Skip to content

Commit

Permalink
fix(compiler): string interpolation of Json is inconsistent (#4044)
Browse files Browse the repository at this point in the history
Fixes #3088
Fixes #3987
Fixes #3988

## Checklist

- [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted)
- [x] Description explains motivation and solution
- [x] Tests added (always)
- [ ] Docs updated (only required for features)
- [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing

*By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
  • Loading branch information
Chriscbr authored Sep 1, 2023
1 parent 0858dd8 commit 7f28718
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 5 deletions.
9 changes: 8 additions & 1 deletion examples/tests/valid/json_string_interpolation.w
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ let obj = Json {
};

let notStringifyStrValue = "string: ${obj.get("strValue")}";
assert(notStringifyStrValue == "string: test");
assert(notStringifyStrValue == "string: \"test\"");
let stringifyNumValue = "number: ${obj.get("numValue")}";
assert(stringifyNumValue == "number: 1");

// string interpolation of Json is equivalent to calling Json.stringify
assert("${obj}" == Json.stringify(obj));
assert("${obj.get("strValue")}" == Json.stringify(obj.get("strValue")));

assert(obj.get("strValue") == Json.parse(Json.stringify(obj.get("strValue"))));
assert(obj.get("strValue") == Json.parse("${obj.get("strValue")}"));
2 changes: 1 addition & 1 deletion libs/wingc/src/jsify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ impl<'a> JSifier<'a> {
InterpolatedStringPart::Static(_) => None,
InterpolatedStringPart::Expr(e) => Some(match *self.types.get_expr_type(e) {
Type::Json(_) | Type::MutJson => {
format!("((e) => typeof e === 'string' ? e : JSON.stringify(e, null, 2))({})", self.jsify_expression(e, ctx))
format!("JSON.stringify({})", self.jsify_expression(e, ctx))
}
_ => self.jsify_expression(e, ctx),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,14 @@ class $Root extends $stdlib.std.Resource {
constructor(scope, id) {
super(scope, id);
const obj = ({"strValue": "test","numValue": 1});
const notStringifyStrValue = String.raw({ raw: ["string: ", ""] }, ((e) => typeof e === 'string' ? e : JSON.stringify(e, null, 2))((obj)["strValue"]));
{((cond) => {if (!cond) throw new Error("assertion failed: notStringifyStrValue == \"string: test\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(notStringifyStrValue,"string: test")))};
const stringifyNumValue = String.raw({ raw: ["number: ", ""] }, ((e) => typeof e === 'string' ? e : JSON.stringify(e, null, 2))((obj)["numValue"]));
const notStringifyStrValue = String.raw({ raw: ["string: ", ""] }, JSON.stringify((obj)["strValue"]));
{((cond) => {if (!cond) throw new Error("assertion failed: notStringifyStrValue == \"string: \\\"test\\\"\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(notStringifyStrValue,"string: \"test\"")))};
const stringifyNumValue = String.raw({ raw: ["number: ", ""] }, JSON.stringify((obj)["numValue"]));
{((cond) => {if (!cond) throw new Error("assertion failed: stringifyNumValue == \"number: 1\"")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(stringifyNumValue,"number: 1")))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"${obj}\" == Json.stringify(obj)")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(String.raw({ raw: ["", ""] }, JSON.stringify(obj)),((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([obj]))))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"${obj.get(\"strValue\")}\" == Json.stringify(obj.get(\"strValue\"))")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(String.raw({ raw: ["", ""] }, JSON.stringify((obj)["strValue"])),((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([(obj)["strValue"]]))))};
{((cond) => {if (!cond) throw new Error("assertion failed: obj.get(\"strValue\") == Json.parse(Json.stringify(obj.get(\"strValue\")))")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((obj)["strValue"],(JSON.parse(((args) => { return JSON.stringify(args[0], null, args[1]?.indent) })([(obj)["strValue"]]))))))};
{((cond) => {if (!cond) throw new Error("assertion failed: obj.get(\"strValue\") == Json.parse(\"${obj.get(\"strValue\")}\")")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })((obj)["strValue"],(JSON.parse(String.raw({ raw: ["", ""] }, JSON.stringify((obj)["strValue"])))))))};
}
}
const $App = $stdlib.core.App.for(process.env.WING_TARGET);
Expand Down

0 comments on commit 7f28718

Please sign in to comment.