GumTreeDiff / gumtree

An awesome code differencing tool
https://github.com/GumTreeDiff/gumtree/wiki
GNU Lesser General Public License v3.0
933 stars 174 forks source link

Empty EditScript from non-empty diff #310

Closed andre15silva closed 12 months ago

andre15silva commented 1 year ago

Hi (CC @algomaster99, @Nfsaavedra),

I am trying to generate an EditScript, following the documentation provided in the Wiki. This is the unified diff of the change I am trying to capture:

--- before.java 2023-06-08 13:31:56.360236099 +0200
+++ after.java  2023-06-08 13:32:10.127134708 +0200
@@ -2,13 +2,13 @@

 public class ResultScanner implements IResultScanner {
     public void parseResultFile(File file) throws MojoExecutionException {
-            successCount = csvScanResult.getSuccessCount();
-            failureCount = csvScanResult.getFailureCount();
+            successCount += csvScanResult.getSuccessCount();
+            failureCount += csvScanResult.getFailureCount();
             if (countSuccesses) {
-                successCount = scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_SUCCESS_PATTERN, Pattern.CASE_INSENSITIVE));
+                successCount += scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_SUCCESS_PATTERN, Pattern.CASE_INSENSITIVE));
             }
             if (countFailures) {
-                failureCount = scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_FAILURE_PATTERN, Pattern.CASE_INSENSITIVE));
+                failureCount += scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_FAILURE_PATTERN, Pattern.CASE_INSENSITIVE));
             }
     }
 }

This is the code that I am running (from the wiki example)

        Run.initGenerators(); // registers the available parsers
        String srcFile = "before.java";
        String dstFile = "after.java";
        Tree src = TreeGenerators.getInstance().getTree(srcFile).getRoot(); // retrieves and applies the default parser for the file 
        Tree dst = TreeGenerators.getInstance().getTree(dstFile).getRoot(); // retrieves and applies the default parser for the file 
        Matcher defaultMatcher = Matchers.getInstance().getMatcher(); // retrieves the default matcher
        MappingStore mappings = defaultMatcher.match(src, dst); // computes the mappings between the trees
        EditScriptGenerator editScriptGenerator = new SimplifiedChawatheScriptGenerator(); // instantiates the simplified Chawathe script generator
        EditScript actions = editScriptGenerator.computeActions(mappings); // computes the edit script

The EditScript actions is empty, containing no Action inside.

However, when I run gumtree's webdiff on the same files, I obtain the correct diff: 2023-06-08_15-16

Do you have any idea why this is happening? Is there any error in the EditScript computation code?

Thanks a lot!

Files for reproduction: before.java

package com.lazerycode.jmeter.results;

public class ResultScanner implements IResultScanner {
    public void parseResultFile(File file) throws MojoExecutionException {
            successCount = csvScanResult.getSuccessCount();
            failureCount = csvScanResult.getFailureCount();
            if (countSuccesses) {
                successCount = scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_SUCCESS_PATTERN, Pattern.CASE_INSENSITIVE));
            }
            if (countFailures) {
                failureCount = scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_FAILURE_PATTERN, Pattern.CASE_INSENSITIVE));
            }
    }
}

after.java

package com.lazerycode.jmeter.results;

public class ResultScanner implements IResultScanner {
    public void parseResultFile(File file) throws MojoExecutionException {
            successCount += csvScanResult.getSuccessCount();
            failureCount += csvScanResult.getFailureCount();
            if (countSuccesses) {
                successCount += scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_SUCCESS_PATTERN, Pattern.CASE_INSENSITIVE));
            }
            if (countFailures) {
                failureCount += scanXmlFileForPattern(file, Pattern.compile(XML_REQUEST_FAILURE_PATTERN, Pattern.CASE_INSENSITIVE));
            }
    }
}
jrfaller commented 1 year ago

Strange...

Could you paste what you obtain when you replace monaco-diff by raw-diff inside the URL when using webdiff??

Cheers!

andre15silva commented 1 year ago

Here is the raw-diff output:

===
match
---
SimpleName: countFailures [486,499]
SimpleName: countFailures [489,502]
===
match
---
TYPE_DECLARATION_KIND: class [47,52]
TYPE_DECLARATION_KIND: class [47,52]
===
match
---
SimpleName: parseResultFile [111,126]
SimpleName: parseResultFile [111,126]
===
match
---
Assignment [182,228]
Assignment [182,229]
===
match
---
TypeDeclaration [40,656]
TypeDeclaration [40,660]
===
match
---
QualifiedName: Pattern.CASE_INSENSITIVE [607,631]
QualifiedName: Pattern.CASE_INSENSITIVE [611,635]
===
match
---
SimpleName: scanXmlFileForPattern [534,555]
SimpleName: scanXmlFileForPattern [538,559]
===
match
---
MethodInvocation [355,454]
MethodInvocation [358,457]
===
match
---
IfStatement [482,648]
IfStatement [485,652]
===
match
---
Block [168,654]
Block [168,658]
===
match
---
MethodInvocation [383,453]
MethodInvocation [386,456]
===
match
---
SimpleName: Pattern [383,390]
SimpleName: Pattern [386,393]
===
match
---
MethodInvocation [534,633]
MethodInvocation [538,637]
===
match
---
METHOD_INVOCATION_ARGUMENTS [399,452]
METHOD_INVOCATION_ARGUMENTS [402,455]
===
match
---
QualifiedName: Pattern.CASE_INSENSITIVE [428,452]
QualifiedName: Pattern.CASE_INSENSITIVE [431,455]
===
match
---
SimpleType [78,92]
SimpleType [78,92]
===
match
---
MethodInvocation [562,632]
MethodInvocation [566,636]
===
match
---
SingleVariableDeclaration [127,136]
SingleVariableDeclaration [127,136]
===
match
---
SimpleName: IResultScanner [78,92]
SimpleName: IResultScanner [78,92]
===
match
---
Assignment [340,454]
Assignment [342,457]
===
match
---
PrimitiveType: void [106,110]
PrimitiveType: void [106,110]
===
match
---
Modifier: public [40,46]
Modifier: public [40,46]
===
match
---
SimpleName: file [132,136]
SimpleName: file [132,136]
===
match
---
ASSIGNMENT_OPERATOR: = [532,533]
ASSIGNMENT_OPERATOR: += [535,537]
===
match
---
SimpleName: successCount [340,352]
SimpleName: successCount [342,354]
===
match
---
SimpleName: compile [570,577]
SimpleName: compile [574,581]
===
match
---
MethodDeclaration [99,654]
MethodDeclaration [99,658]
===
match
---
ExpressionStatement [519,634]
ExpressionStatement [522,638]
===
match
---
Block [501,648]
Block [504,652]
===
match
---
METHOD_INVOCATION_RECEIVER [197,210]
METHOD_INVOCATION_RECEIVER [198,211]
===
match
---
SimpleName: scanXmlFileForPattern [355,376]
SimpleName: scanXmlFileForPattern [358,379]
===
match
---
METHOD_INVOCATION_ARGUMENTS [578,631]
METHOD_INVOCATION_ARGUMENTS [582,635]
===
match
---
SimpleName: file [377,381]
SimpleName: file [380,384]
===
match
---
METHOD_INVOCATION_RECEIVER [383,390]
METHOD_INVOCATION_RECEIVER [386,393]
===
match
---
ExpressionStatement [242,289]
ExpressionStatement [243,291]
===
match
---
METHOD_INVOCATION_ARGUMENTS [556,632]
METHOD_INVOCATION_ARGUMENTS [560,636]
===
match
---
SimpleName: compile [391,398]
SimpleName: compile [394,401]
===
match
---
PackageDeclaration [0,38]
PackageDeclaration [0,38]
===
match
---
SimpleType [127,131]
SimpleType [127,131]
===
match
---
QualifiedName: com.lazerycode.jmeter.results [8,37]
QualifiedName: com.lazerycode.jmeter.results [8,37]
===
match
---
SimpleName: File [127,131]
SimpleName: File [127,131]
===
match
---
ExpressionStatement [340,455]
ExpressionStatement [342,458]
===
match
---
SimpleName: ResultScanner [53,66]
SimpleName: ResultScanner [53,66]
===
match
---
SimpleName: failureCount [519,531]
SimpleName: failureCount [522,534]
===
match
---
SimpleName: XML_REQUEST_FAILURE_PATTERN [578,605]
SimpleName: XML_REQUEST_FAILURE_PATTERN [582,609]
===
match
---
SimpleName: getSuccessCount [211,226]
SimpleName: getSuccessCount [212,227]
===
match
---
SimpleName: XML_REQUEST_SUCCESS_PATTERN [399,426]
SimpleName: XML_REQUEST_SUCCESS_PATTERN [402,429]
===
match
---
SimpleName: Pattern [562,569]
SimpleName: Pattern [566,573]
===
match
---
Assignment [519,633]
Assignment [522,637]
===
match
---
SimpleName: csvScanResult [197,210]
SimpleName: csvScanResult [198,211]
===
match
---
MethodInvocation [197,228]
MethodInvocation [198,229]
===
match
---
SimpleType [145,167]
SimpleType [145,167]
===
match
---
METHOD_INVOCATION_RECEIVER [562,569]
METHOD_INVOCATION_RECEIVER [566,573]
===
match
---
MethodInvocation [257,288]
MethodInvocation [259,290]
===
match
---
METHOD_INVOCATION_ARGUMENTS [377,453]
METHOD_INVOCATION_ARGUMENTS [380,456]
===
match
---
ASSIGNMENT_OPERATOR: = [353,354]
ASSIGNMENT_OPERATOR: += [355,357]
===
match
---
Modifier: public [99,105]
Modifier: public [99,105]
===
match
---
CompilationUnit [0,657]
CompilationUnit [0,661]
===
match
---
ExpressionStatement [182,229]
ExpressionStatement [182,230]
===
match
---
SimpleName: successCount [182,194]
SimpleName: successCount [182,194]
===
match
---
SimpleName: MojoExecutionException [145,167]
SimpleName: MojoExecutionException [145,167]
===
match
---
METHOD_INVOCATION_RECEIVER [257,270]
METHOD_INVOCATION_RECEIVER [259,272]
===
match
---
SimpleName: file [556,560]
SimpleName: file [560,564]
===
match
---
SimpleName: countSuccesses [306,320]
SimpleName: countSuccesses [308,322]
===
match
---
IfStatement [302,469]
IfStatement [304,472]
===
match
---
Assignment [242,288]
Assignment [243,290]
===
match
---
Block [322,469]
Block [324,472]
===
match
---
SimpleName: csvScanResult [257,270]
SimpleName: csvScanResult [259,272]
===
match
---
ASSIGNMENT_OPERATOR: = [195,196]
ASSIGNMENT_OPERATOR: += [195,197]
===
match
---
SimpleName: failureCount [242,254]
SimpleName: failureCount [243,255]
===
match
---
SimpleName: getFailureCount [271,286]
SimpleName: getFailureCount [273,288]
===
match
---
ASSIGNMENT_OPERATOR: = [255,256]
ASSIGNMENT_OPERATOR: += [256,258]
===
update-node
---
ASSIGNMENT_OPERATOR: = [195,196]
replace = by +=
===
update-node
---
ASSIGNMENT_OPERATOR: = [255,256]
replace = by +=
===
update-node
---
ASSIGNMENT_OPERATOR: = [353,354]
replace = by +=
===
update-node
---
ASSIGNMENT_OPERATOR: = [532,533]
replace = by +=

Thanks a lot!

jrfaller commented 1 year ago

OK the actions seem to be there :

update-node
---
ASSIGNMENT_OPERATOR: = [195,196]
replace = by +=
===
update-node
---
ASSIGNMENT_OPERATOR: = [255,256]
replace = by +=
===
update-node
---
ASSIGNMENT_OPERATOR: = [353,354]
replace = by +=
===
update-node
---
ASSIGNMENT_OPERATOR: = [532,533]
replace = by +=

I suspect the problem comes from the Java code then.

andre15silva commented 1 year ago

Do you have any idea why the Java code does not generate the same actions? Maybe it is different from the one used in webdiff?

jrfaller commented 1 year ago

Maybe you could inspect the mappings variable to see if it is filled?