Description
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?