Skip to content

Identifying move operations when computing JSON patches #76

Open
@szabta89

Description

@szabta89

This is more of an inquiry and not necessary a bug report. I was experimenting with the tool, and I saw that the resulting patch for certain inputs is not optimal in the sense that the patch uses insertion and deletion operations instead of moves. Consider these two JSON documents describing the syntax tree of some function. The second tree has an extra statement inserted in the beginning:

public static String SRC = "{\n" +
            "  \"name\": \"foo\",\n" +
            "  \"stmts\": [\n" +
            "    {\n" +
            "      \"kind\": \"VarDecl\",\n" +
            "      \"name\": \"a\",\n" +
            "      \"value\": {\n" +
            "        \"kind\": \"PlusExpr\",\n" +
            "        \"lhs\": \"1\",\n" +
            "        \"rhs\": \"2\"\n" +
            "      }\n" +
            "    },\n" +
            "    {\n" +
            "      \"kind\": \"Print\",\n" +
            "      \"exp\": {\n" +
            "        \"kind\": \"VarRef\",\n" +
            "        \"name\": \"a\"\n" +
            "      }\n" +
            "    }\n" +
            "  ]\n" +
            "}";

    public static String TRG = "{\n" +
            "  \"name\": \"foo\",\n" +
            "  \"stmts\": [\n" +
            "    {\n" +
            "      \"kind\": \"VarDecl\",\n" +
            "      \"name\": \"b\",\n" +
            "      \"value\": {\n" +
            "        \"kind\": \"NumLit\",\n" +
            "        \"value\": \"3\"\n" +
            "      }\n" +
            "    },\n" +
            "    {\n" +
            "      \"kind\": \"VarDecl\",\n" +
            "      \"name\": \"a\",\n" +
            "      \"value\": {\n" +
            "        \"kind\": \"PlusExpr\",\n" +
            "        \"lhs\": \"1\",\n" +
            "        \"rhs\": \"2\"\n" +
            "      }\n" +
            "    },\n" +
            "    {\n" +
            "      \"kind\": \"Print\",\n" +
            "      \"exp\": {\n" +
            "        \"kind\": \"VarRef\",\n" +
            "        \"name\": \"a\"\n" +
            "      }\n" +
            "    }\n" +
            "  ]\n" +
            "}";

I use the following code snippet to compute the patch between them:

        final ObjectMapper mapper = new ObjectMapper();
        final JsonNode n1 = mapper.readTree(SRC);
        final JsonNode n2 = mapper.readTree(TRG);
        final JsonPatch diff = JsonDiff.asJsonPatch(n1, n2);

The resulting patch is as follows:

op: replace; path: "/stmts/0/name"; value: "b", 
op: remove; path: "/stmts/0/value/lhs", 
op: remove; path: "/stmts/0/value/rhs", 
op: add; path: "/stmts/0/value/value"; value: "3", 
op: replace; path: "/stmts/0/value/kind"; value: "NumLit", 
op: remove; path: "/stmts/1/exp", 
op: add; path: "/stmts/1/name"; value: "a", 
op: add; path: "/stmts/1/value"; value: {"kind":"PlusExpr","lhs":"1","rhs":"2"}, 
op: replace; path: "/stmts/1/kind"; value: "VarDecl", 
op: add; path: "/stmts/-"; value: {"kind":"Print","exp":{"kind":"VarRef","name":"a"}}

Ideally, the shifting of the original two statements should be described with two moves and no change at all to the nodes in their subtrees. Can you please provide some insights on this scenario? Am I missing something or is the above patch the expected output?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions