[diffoscope] 01/02: comparators: java: adds support for procyon-decompiler

Mattia Rizzolo mattia at debian.org
Mon Feb 5 19:50:19 CET 2018


This is an automated email from the git hooks/post-receive script.

mattia pushed a commit to branch master
in repository diffoscope.

commit f23787d60864bd61988f4f56194844f60a73a0dd
Author: Juliana Oliveira <juliana.orod at gmail.com>
Date:   Wed Jan 31 22:38:28 2018 -0200

    comparators: java: adds support for procyon-decompiler
    
    Uses procyon-decompiler as main option for ClassFiles and javap
    as a fallback. (Closes: #849386)
    
    Signed-off-by: Juliana Oliveira <juliana.orod at gmail.com>
    Signed-off-by: Mattia Rizzolo <mattia at debian.org>
---
 diffoscope/comparators/java.py                     | 40 +++++++++++++++++++++-
 diffoscope/external_tools.py                       |  3 ++
 tests/comparators/test_java.py                     | 40 ++++++++++++++++++----
 ...ass_expected_diff => javap_class_expected_diff} |  0
 tests/data/procyon_class_expected_diff             |  9 +++++
 5 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/diffoscope/comparators/java.py b/diffoscope/comparators/java.py
index 537d95f..23cd996 100644
--- a/diffoscope/comparators/java.py
+++ b/diffoscope/comparators/java.py
@@ -20,13 +20,32 @@
 
 import re
 import os.path
+import logging
 
 from diffoscope.tools import tool_required
 from diffoscope.difference import Difference
+from diffoscope.exc import RequiredToolNotFound
 
 from .utils.file import File
 from .utils.command import Command
 
+logger = logging.getLogger(__name__)
+
+
+class ProcyonDecompiler(Command):
+    def __init__(self, path, *args, **kwargs):
+        super().__init__(path, *args, **kwargs)
+        self.real_path = os.path.realpath(path)
+
+    @tool_required('procyon-decompiler')
+    def cmdline(self):
+        return ['procyon-decompiler', '-ec', self.path]
+
+    def filter(self, line):
+        if re.match(r'^(//)', line.decode('utf-8')):
+            return b''
+        return line
+
 
 class Javap(Command):
     def __init__(self, path, *args, **kwargs):
@@ -46,5 +65,24 @@ class Javap(Command):
 class ClassFile(File):
     FILE_TYPE_RE = re.compile(r'^compiled Java class data\b')
 
+    decompilers = [ProcyonDecompiler, Javap]
+
     def compare_details(self, other, source=None):
-        return [Difference.from_command(Javap, self.path, other.path)]
+        diff = None
+
+        for decompiler in self.decompilers:
+            try:
+                diff = [Difference.from_command(decompiler,
+                                                self.path,
+                                                other.path)]
+                if diff:
+                    break
+            except RequiredToolNotFound:
+                logger.debug("Unable to find %s. Falling back...",
+                             decompiler.__name__)
+
+        if not diff:
+            raise RequiredToolNotFound(self.decompilers[-1])
+
+        return diff
+
diff --git a/diffoscope/external_tools.py b/diffoscope/external_tools.py
index cdb097b..1e2f052 100644
--- a/diffoscope/external_tools.py
+++ b/diffoscope/external_tools.py
@@ -257,6 +257,9 @@ EXTERNAL_TOOLS = {
         'arch': 'unzip',
         'FreeBSD': 'unzip',
     },
+    'procyon-decompiler': {
+        'debian': 'procyon-decompiler',
+    },
 }
 
 # May be populated at runtime by remapped names like
diff --git a/tests/comparators/test_java.py b/tests/comparators/test_java.py
index 2be6af3..a001417 100644
--- a/tests/comparators/test_java.py
+++ b/tests/comparators/test_java.py
@@ -21,7 +21,7 @@ import pytest
 import subprocess
 
 from diffoscope.config import Config
-from diffoscope.comparators.java import ClassFile
+from diffoscope.comparators.java import ClassFile, ProcyonDecompiler, Javap
 from diffoscope.comparators.missing_file import MissingFile
 
 from ..utils.data import load_fixture, get_data
@@ -50,19 +50,45 @@ def test_no_differences(class1):
 
 
 @pytest.fixture
-def differences(class1, class2):
+def differences_procyon(monkeypatch, class1, class2):
+    monkeypatch.setattr(class1, 'decompilers', [ProcyonDecompiler])
     return class1.compare(class2).details
 
 
- at skip_unless_tool_is_at_least('javap', javap_version, '1.8')
-def test_diff(differences):
-    expected_diff = get_data('class_expected_diff')
+ at pytest.fixture
+def differences_javap(monkeypatch, class1, class2):
+    monkeypatch.setattr(class1, 'decompilers', [Javap])
+    return class1.compare(class2).details
+
+
+def diff(differences, expected_diff_file):
+    expected_diff = get_data(expected_diff_file)
     assert differences[0].unified_diff == expected_diff
 
 
- at skip_unless_tools_exist('javap')
-def test_compare_non_existing(monkeypatch, class1):
+def compare_non_existing(monkeypatch, class1, decompiler):
     monkeypatch.setattr(Config(), 'new_file', True)
+    monkeypatch.setattr(class1, 'decompilers', [decompiler])
     difference = class1.compare(MissingFile('/nonexisting', class1))
     assert difference.source2 == '/nonexisting'
     assert len(difference.details) > 0
+
+
+ at skip_unless_tools_exist('procyon-decompiler')
+def test_diff_procyon(differences_procyon):
+    diff(differences_procyon, 'procyon_class_expected_diff')
+
+
+ at skip_unless_tool_is_at_least('javap', javap_version, '1.8')
+def test_diff_javap(differences_javap):
+    diff(differences_javap, 'javap_class_expected_diff')
+
+
+ at skip_unless_tools_exist('procyon-decompiler')
+def test_compare_non_existing_procyon(monkeypatch, class1):
+    compare_non_existing(monkeypatch, class1, ProcyonDecompiler)
+
+
+ at skip_unless_tools_exist('javap')
+def test_compare_non_existing_javap(monkeypatch, class1):
+    compare_non_existing(monkeypatch, class1, Javap)
diff --git a/tests/data/class_expected_diff b/tests/data/javap_class_expected_diff
similarity index 100%
rename from tests/data/class_expected_diff
rename to tests/data/javap_class_expected_diff
diff --git a/tests/data/procyon_class_expected_diff b/tests/data/procyon_class_expected_diff
new file mode 100644
index 0000000..d710dc8
--- /dev/null
+++ b/tests/data/procyon_class_expected_diff
@@ -0,0 +1,9 @@
+@@ -1,7 +1,7 @@
+ 
+ class Test
+ {
+     public static int main(final String[] array) {
+-        return 42;
++        return -1;
+     }
+ }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list