From e4e72404dcca533c0cbaece10624414ea3586bf1 Mon Sep 17 00:00:00 2001 From: Sebastian Zarnekow Date: Tue, 9 Jun 2015 15:34:08 +0300 Subject: [PATCH 001/252] Fixed Fernflower decompiler output for generic nested types (IDEA-141230) https://github.com/JetBrains/intellij-community/pull/273 --- .../struct/gen/generics/GenericMain.java | 96 ++++++++++-------- .../java/decompiler/SingleClassesTest.java | 1 + .../pkg/TestParameterizedTypes$Inner.class | Bin 0 -> 642 bytes .../classes/pkg/TestParameterizedTypes.class | Bin 0 -> 776 bytes testData/results/TestParameterizedTypes.dec | 11 ++ testData/src/pkg/TestParameterizedTypes.java | 26 +++++ 6 files changed, 91 insertions(+), 43 deletions(-) create mode 100644 testData/classes/pkg/TestParameterizedTypes$Inner.class create mode 100644 testData/classes/pkg/TestParameterizedTypes.class create mode 100644 testData/results/TestParameterizedTypes.dec create mode 100644 testData/src/pkg/TestParameterizedTypes.java diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java index 2992078..0a3f9d3 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,6 @@ package org.jetbrains.java.decompiler.struct.gen.generics; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; -import org.jetbrains.java.decompiler.struct.StructClass; import java.util.ArrayList; import java.util.List; @@ -193,57 +192,68 @@ public class GenericMain { } else if (tp == CodeConstants.TYPE_OBJECT) { StringBuilder buffer = new StringBuilder(); - buffer.append(DecompilerContext.getImportCollector().getShortName(buildJavaClassName(type))); - - if (!type.getArguments().isEmpty()) { - buffer.append("<"); - for (int i = 0; i < type.getArguments().size(); i++) { - if (i > 0) { - buffer.append(", "); - } - int wildcard = type.getWildcards().get(i); - if (wildcard != GenericType.WILDCARD_NO) { - buffer.append("?"); - - switch (wildcard) { - case GenericType.WILDCARD_EXTENDS: - buffer.append(" extends "); - break; - case GenericType.WILDCARD_SUPER: - buffer.append(" super "); - } - } - - GenericType genPar = type.getArguments().get(i); - if (genPar != null) { - buffer.append(getGenericCastTypeName(genPar)); - } - } - buffer.append(">"); - } - + appendClassName(type, buffer); return buffer.toString(); } throw new RuntimeException("Invalid type: " + type); } - private static String buildJavaClassName(GenericType type) { - String name = ""; - for (GenericType tp : type.getEnclosingClasses()) { - name += tp.value + "$"; + private static void appendClassName(GenericType type, StringBuilder buffer) { + List enclosingClasses = type.getEnclosingClasses(); + + if (enclosingClasses.isEmpty()) { + String name = type.value.replace('/', '.'); + buffer.append(DecompilerContext.getImportCollector().getShortName(name)); } - name += type.value; + else { + for (GenericType tp : enclosingClasses) { + if (buffer.length() == 0) { + buffer.append(DecompilerContext.getImportCollector().getShortName(tp.value)); + } + else { + buffer.append(tp.value); + } - String res = name.replace('/', '.'); - - if (res.contains("$")) { - StructClass cl = DecompilerContext.getStructContext().getClass(name); - if (cl == null || !cl.isOwn()) { - res = res.replace('$', '.'); + appendTypeArguments(tp, buffer); + buffer.append('.'); } + + buffer.append(type.value); } - return res; + appendTypeArguments(type, buffer); + } + + private static void appendTypeArguments(GenericType type, StringBuilder buffer) { + if (!type.getArguments().isEmpty()) { + buffer.append('<'); + + for (int i = 0; i < type.getArguments().size(); i++) { + if (i > 0) { + buffer.append(", "); + } + + int wildcard = type.getWildcards().get(i); + switch (wildcard) { + case GenericType.WILDCARD_UNBOUND: + buffer.append('?'); + break; + case GenericType.WILDCARD_EXTENDS: + buffer.append("? extends "); + break; + case GenericType.WILDCARD_SUPER: + buffer.append("? super "); + break; + } + + GenericType genPar = type.getArguments().get(i); + if (genPar != null) { + buffer.append(getGenericCastTypeName(genPar)); + } + } + + buffer.append(">"); + } } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index d8f6bee..e85cd67 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -60,4 +60,5 @@ public class SingleClassesTest extends SingleClassesTestBase { @Test public void testInnerLocal() { doTest("pkg/TestInnerLocal"); } @Test public void testInnerLocalPkg() { doTest("pkg/TestInnerLocalPkg"); } @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } + @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } } diff --git a/testData/classes/pkg/TestParameterizedTypes$Inner.class b/testData/classes/pkg/TestParameterizedTypes$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..55f1d4cd6538a1400040bba8710b1dc2aa630390 GIT binary patch literal 642 zcmaJ;O;5r=5PeGvm0AT+Q32yeI3ODE;K??#|?`2TFWGFe)he6#HLD=Fx zAB#}<@>%rVr>O``;#ty@q0MkqSw%eSFsO}5Uod1G>51FfxGQ{@cSqF8Ig=hAb+|7h zylASC0fuDL^Mub}#JMrzK_IAoy5h2OOeJsmpSt9Dp?$Gp+HzZ_U5h0ww`tm>lWxm_ z$HSRVUMp7f+8OdkULSF9P`~RAMK3h%zbyv6J(>AEaU-KQ7XRO1Es`>jM9P4MqJ|Q~ z@$!YwpT>~=?SMh4L_01lpH)xjlU4d}md!>NMim_mYZTLjT1e0V^y>L5SoIBw7eWej xiYej%J6NZfpR-^fLx}jX8kwTnhDt&63QwwUN&c{1_f2l!FO zX-gtRX%9P{nfK<+%38%>1a zwYz^q45~g`IEJ{E{>_yCUwqRaBZCyS7)qP(havYnZ>Y&|x)~oXSE(XK@5}$^Q zY4WbfGO~%Ycd)l0t { + abstract TestParameterizedTypes

.Inner getUnspecificInner(); + + abstract TestParameterizedTypes.Inner getSpecificInner(); + + public abstract class Inner { + } +} + diff --git a/testData/src/pkg/TestParameterizedTypes.java b/testData/src/pkg/TestParameterizedTypes.java new file mode 100644 index 0000000..490869e --- /dev/null +++ b/testData/src/pkg/TestParameterizedTypes.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2015 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +public abstract class TestParameterizedTypes

{ + + public abstract class Inner { } + + abstract Inner getUnspecificInner(); + + abstract TestParameterizedTypes.Inner getSpecificInner(); + +} \ No newline at end of file From debe6cc338fd8075df412fbdb15e82ab2ce17b7e Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 29 Jun 2015 13:27:31 +0300 Subject: [PATCH 002/252] safe delete unused environment + deprecations, part 2 (follow-up to 63cae114) --- .../java/decompiler/main/ClassesProcessor.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index b27e343..2403836 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -148,7 +148,7 @@ public class ClassesProcessor { // root class? if (!mapInnerClasses.containsKey(ent.getKey())) { - HashSet setVisited = new HashSet(); + Set setVisited = new HashSet(); LinkedList stack = new LinkedList(); stack.add(ent.getKey()); @@ -157,12 +157,12 @@ public class ClassesProcessor { while (!stack.isEmpty()) { String superClass = stack.removeFirst(); - ClassNode supernode = mapRootClasses.get(superClass); + ClassNode superNode = mapRootClasses.get(superClass); - HashSet setNestedClasses = mapNestedClassReferences.get(superClass); + Set setNestedClasses = mapNestedClassReferences.get(superClass); if (setNestedClasses != null) { - StructClass scl = supernode.classStruct; + StructClass scl = superNode.classStruct; StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttributes().getWithKey("InnerClasses"); for (int i = 0; i < inner.getStringEntries().size(); i++) { String nestedClass = inner.getStringEntries().get(i)[0]; @@ -216,8 +216,8 @@ public class ClassesProcessor { nestednode.access &= (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_FINAL); } - supernode.nested.add(nestednode); - nestednode.parent = supernode; + superNode.nested.add(nestednode); + nestednode.parent = superNode; nestednode.enclosingClasses.addAll(mapEnclosingClassReferences.get(nestedClass)); From aa480480e9c90f7283fbd03c90eaec00fccacac9 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 29 Jun 2015 14:59:18 +0300 Subject: [PATCH 003/252] Cleanup (formatting; typos) --- .../decompiler/main/ClassesProcessor.java | 84 +++++++++---------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 2403836..acdf656 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -47,10 +47,10 @@ public class ClassesProcessor { public ClassesProcessor(StructContext context) { - HashMap mapInnerClasses = new HashMap(); - HashMap> mapNestedClassReferences = new HashMap>(); - HashMap> mapEnclosingClassReferences = new HashMap>(); - HashMap mapNewSimpleNames = new HashMap(); + Map mapInnerClasses = new HashMap(); + Map> mapNestedClassReferences = new HashMap>(); + Map> mapEnclosingClassReferences = new HashMap>(); + Map mapNewSimpleNames = new HashMap(); boolean bDecompileInner = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_INNER); @@ -65,18 +65,16 @@ public class ClassesProcessor { for (int i = 0; i < inner.getClassEntries().size(); i++) { int[] entry = inner.getClassEntries().get(i); - String[] strentry = inner.getStringEntries().get(i); - + String[] strEntry = inner.getStringEntries().get(i); Object[] arr = new Object[4]; // arr[0] not used - - String innername = strentry[0]; + String innerName = strEntry[0]; // nested class type arr[2] = entry[1] == 0 ? (entry[2] == 0 ? ClassNode.CLASS_ANONYMOUS : ClassNode.CLASS_LOCAL) : ClassNode.CLASS_MEMBER; // original simple name - String simpleName = strentry[2]; - String savedName = mapNewSimpleNames.get(innername); + String simpleName = strEntry[2]; + String savedName = mapNewSimpleNames.get(innerName); if (savedName != null) { simpleName = savedName; @@ -84,8 +82,8 @@ public class ClassesProcessor { else if (simpleName != null && DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) { IIdentifierRenamer renamer = DecompilerContext.getPoolInterceptor().getHelper(); if (renamer.toBeRenamed(IIdentifierRenamer.Type.ELEMENT_CLASS, simpleName, null, null)) { - simpleName = renamer.getNextClassName(innername, simpleName); - mapNewSimpleNames.put(innername, simpleName); + simpleName = renamer.getNextClassName(innerName, simpleName); + mapNewSimpleNames.put(innerName, simpleName); } } @@ -97,36 +95,36 @@ public class ClassesProcessor { // enclosing class String enclClassName; if (entry[1] != 0) { - enclClassName = strentry[1]; + enclClassName = strEntry[1]; } else { enclClassName = cl.qualifiedName; } - if (!innername.equals(enclClassName)) { // self reference + if (!innerName.equals(enclClassName)) { // self reference StructClass enclosing_class = context.getClasses().get(enclClassName); if (enclosing_class != null && enclosing_class.isOwn()) { // own classes only - Object[] arrold = mapInnerClasses.get(innername); - if (arrold == null) { - mapInnerClasses.put(innername, arr); + Object[] arrOld = mapInnerClasses.get(innerName); + if (arrOld == null) { + mapInnerClasses.put(innerName, arr); } - else if (!InterpreterUtil.equalObjectArrays(arrold, arr)) { - String message = "Inconsistent inner class entries for " + innername + "!"; + else if (!InterpreterUtil.equalObjectArrays(arrOld, arr)) { + String message = "Inconsistent inner class entries for " + innerName + "!"; DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } // reference to the nested class - HashSet set = mapNestedClassReferences.get(enclClassName); + Set set = mapNestedClassReferences.get(enclClassName); if (set == null) { mapNestedClassReferences.put(enclClassName, set = new HashSet()); } - set.add(innername); + set.add(innerName); // reference to the enclosing class - set = mapEnclosingClassReferences.get(innername); + set = mapEnclosingClassReferences.get(innerName); if (set == null) { - mapEnclosingClassReferences.put(innername, set = new HashSet()); + mapEnclosingClassReferences.put(innerName, set = new HashSet()); } set.add(enclClassName); } @@ -174,8 +172,8 @@ public class ClassesProcessor { continue; } - ClassNode nestednode = mapRootClasses.get(nestedClass); - if (nestednode == null) { + ClassNode nestedNode = mapRootClasses.get(nestedClass); + if (nestedNode == null) { DecompilerContext.getLogger().writeMessage("Nested class " + nestedClass + " missing!", IFernflowerLogger.Severity.WARN); continue; } @@ -186,16 +184,16 @@ public class ClassesProcessor { // FIXME: check for consistent naming //} - nestednode.type = (Integer)arr[2]; - nestednode.simpleName = (String)arr[1]; - nestednode.access = (Integer)arr[3]; + nestedNode.type = (Integer)arr[2]; + nestedNode.simpleName = (String)arr[1]; + nestedNode.access = (Integer)arr[3]; - if (nestednode.type == ClassNode.CLASS_ANONYMOUS) { - StructClass cl = nestednode.classStruct; + if (nestedNode.type == ClassNode.CLASS_ANONYMOUS) { + StructClass cl = nestedNode.classStruct; // remove static if anonymous class // a common compiler bug - nestednode.access &= ~CodeConstants.ACC_STATIC; + nestedNode.access &= ~CodeConstants.ACC_STATIC; int[] interfaces = cl.getInterfaces(); @@ -204,22 +202,22 @@ public class ClassesProcessor { String message = "Inconsistent anonymous class definition: " + cl.qualifiedName; DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } - nestednode.anonymousClassType = new VarType(cl.getInterface(0), true); + nestedNode.anonymousClassType = new VarType(cl.getInterface(0), true); } else { - nestednode.anonymousClassType = new VarType(cl.superClass.getString(), true); + nestedNode.anonymousClassType = new VarType(cl.superClass.getString(), true); } } - else if (nestednode.type == ClassNode.CLASS_LOCAL) { + else if (nestedNode.type == ClassNode.CLASS_LOCAL) { // only abstract and final are permitted // a common compiler bug - nestednode.access &= (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_FINAL); + nestedNode.access &= (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_FINAL); } - superNode.nested.add(nestednode); - nestednode.parent = superNode; + superNode.nested.add(nestedNode); + nestedNode.parent = superNode; - nestednode.enclosingClasses.addAll(mapEnclosingClassReferences.get(nestedClass)); + nestedNode.enclosingClasses.addAll(mapEnclosingClassReferences.get(nestedClass)); stack.add(nestedClass); } @@ -258,11 +256,8 @@ public class ClassesProcessor { TextBuffer classBuffer = new TextBuffer(AVERAGE_CLASS_SIZE); new ClassWriter().classToJava(root, classBuffer, 0, null); - int total_offset_lines = 0; - int index = cl.qualifiedName.lastIndexOf("/"); if (index >= 0) { - total_offset_lines+=2; String packageName = cl.qualifiedName.substring(0, index).replace('/', '.'); buffer.append("package "); @@ -275,16 +270,15 @@ public class ClassesProcessor { int import_lines_written = importCollector.writeImports(buffer); if (import_lines_written > 0) { buffer.appendLineSeparator(); - total_offset_lines += import_lines_written + 1; } - //buffer.append(lineSeparator); - total_offset_lines = buffer.countLines(); + int offsetLines = buffer.countLines(); + buffer.append(classBuffer); if (DecompilerContext.getOption(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING)) { BytecodeSourceMapper mapper = DecompilerContext.getBytecodeSourceMapper(); - mapper.addTotalOffset(total_offset_lines); + mapper.addTotalOffset(offsetLines); if (DecompilerContext.getOption(IFernflowerPreferences.DUMP_ORIGINAL_LINES)) { buffer.dumpOriginalLineNumbers(mapper.getOriginalLinesMapping()); } From 6a802a6fc971f37b1cde2db35c97d9984c877626 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 29 Jun 2015 15:13:05 +0300 Subject: [PATCH 004/252] java-decompiler: NPE fixed https://github.com/JetBrains/intellij-community/pull/268 --- .../jetbrains/java/decompiler/main/ClassesProcessor.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index acdf656..5a56641 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -162,6 +162,12 @@ public class ClassesProcessor { StructClass scl = superNode.classStruct; StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttributes().getWithKey("InnerClasses"); + + if (inner == null || inner.getStringEntries().isEmpty()) { + DecompilerContext.getLogger().writeMessage(superClass + " does not contain inner classes!", IFernflowerLogger.Severity.WARN); + continue; + } + for (int i = 0; i < inner.getStringEntries().size(); i++) { String nestedClass = inner.getStringEntries().get(i)[0]; if (!setNestedClasses.contains(nestedClass)) { From 9a06c52a8f8a3b2c361e8a006d53cd5f7ae86766 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 24 Aug 2015 17:51:52 +0200 Subject: [PATCH 005/252] move hamcrest-library to hamcrest lib --- java-decompiler-engine.iml | 1 + 1 file changed, 1 insertion(+) diff --git a/java-decompiler-engine.iml b/java-decompiler-engine.iml index d56249d..5880ebf 100644 --- a/java-decompiler-engine.iml +++ b/java-decompiler-engine.iml @@ -9,5 +9,6 @@ + \ No newline at end of file From aab87019efe1249352e0c45f58a8d28aa8732164 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 7 Sep 2015 19:23:12 +0300 Subject: [PATCH 006/252] [java-decompiler] common file comparison method extracted; test data updated --- .../decompiler/BulkDecompilationTest.java | 21 ++------- .../decompiler/DecompilerTestFixture.java | 27 +++++++++++- .../decompiler/SingleClassesTestBase.java | 43 ++++++------------- testData/bulk/META-INF/MANIFEST.MF | 3 ++ testData/bulk/pkg/Main.java | 11 +++++ testData/bulk/pkg/res/Loader.java | 25 +++++++++++ 6 files changed, 82 insertions(+), 48 deletions(-) diff --git a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java index 1b5353b..0211a57 100644 --- a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java +++ b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package org.jetbrains.java.decompiler; -import org.hamcrest.Matchers; import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.junit.After; @@ -27,7 +26,7 @@ import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import static org.junit.Assert.assertThat; +import static org.jetbrains.java.decompiler.DecompilerTestFixture.assertFilesEqual; import static org.junit.Assert.assertTrue; public class BulkDecompilationTest { @@ -54,7 +53,7 @@ public class BulkDecompilationTest { decompiler.addSpace(classes, true); decompiler.decompileContext(); - compareDirectories(new File(fixture.getTestDataDir(), "bulk"), fixture.getTargetDir()); + assertFilesEqual(new File(fixture.getTestDataDir(), "bulk"), fixture.getTargetDir()); } @Test @@ -66,7 +65,7 @@ public class BulkDecompilationTest { File unpacked = new File(fixture.getTempDir(), "unpacked"); unpack(new File(fixture.getTargetDir(), "bulk.jar"), unpacked); - compareDirectories(new File(fixture.getTestDataDir(), "bulk"), unpacked); + assertFilesEqual(new File(fixture.getTestDataDir(), "bulk"), unpacked); } private static void unpack(File archive, File targetDir) { @@ -95,16 +94,4 @@ public class BulkDecompilationTest { throw new RuntimeException(e); } } - - private static void compareDirectories(File expected, File actual) { - String[] expectedList = expected.list(); - String[] actualList = actual.list(); - assertThat(actualList, Matchers.arrayContainingInAnyOrder(expectedList)); - for (String name : expectedList) { - File child = new File(expected, name); - if (child.isDirectory()) { - compareDirectories(child, new File(actual, name)); - } - } - } } diff --git a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java index d0d869c..ad36548 100644 --- a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java +++ b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,8 +15,10 @@ */ package org.jetbrains.java.decompiler; +import org.hamcrest.Matchers; import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.io.File; import java.io.IOException; @@ -24,6 +26,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; public class DecompilerTestFixture { @@ -43,6 +46,7 @@ public class DecompilerTestFixture { if (!isTestDataDir(testDataDir)) testDataDir = new File("../community/plugins/java-decompiler/engine/testData"); if (!isTestDataDir(testDataDir)) testDataDir = new File("../plugins/java-decompiler/engine/testData"); assertTrue("current dir: " + new File("").getAbsolutePath(), isTestDataDir(testDataDir)); + testDataDir = testDataDir.getAbsoluteFile(); //noinspection SSBasedInspection tempDir = File.createTempFile("decompiler_test_", "_dir"); @@ -96,4 +100,25 @@ public class DecompilerTestFixture { } assertTrue(file.delete()); } + + public static void assertFilesEqual(File expected, File actual) { + if (expected.isDirectory()) { + assertThat(actual.list(), Matchers.arrayContainingInAnyOrder(expected.list())); + for (String name : expected.list()) { + assertFilesEqual(new File(expected, name), new File(actual, name)); + } + } + else { + assertThat(getContent(actual), Matchers.equalTo(getContent(expected))); + } + } + + private static String getContent(File expected) { + try { + return new String(InterpreterUtil.getBytes(expected), "UTF-8").replace("\r\n", "\n"); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java b/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java index 165f695..97e98b2 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.jetbrains.java.decompiler; import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; -import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.junit.After; import org.junit.Before; @@ -28,7 +27,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import static org.junit.Assert.assertEquals; +import static org.jetbrains.java.decompiler.DecompilerTestFixture.assertFilesEqual; import static org.junit.Assert.assertTrue; public abstract class SingleClassesTestBase { @@ -51,25 +50,20 @@ public abstract class SingleClassesTestBase { } protected void doTest(String testFile) { - try { - File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); - assertTrue(classFile.isFile()); - String testName = classFile.getName().substring(0, classFile.getName().length() - 6); + File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); + assertTrue(classFile.isFile()); + String testName = classFile.getName().substring(0, classFile.getName().length() - 6); - ConsoleDecompiler decompiler = fixture.getDecompiler(); + ConsoleDecompiler decompiler = fixture.getDecompiler(); - for (File file : collectClasses(classFile)) decompiler.addSpace(file, true); - decompiler.decompileContext(); + for (File file : collectClasses(classFile)) decompiler.addSpace(file, true); + decompiler.decompileContext(); - File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); - assertTrue(decompiledFile.isFile()); - File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); - assertTrue(referenceFile.isFile()); - compareContent(decompiledFile, referenceFile); - } - catch (Exception e) { - throw new RuntimeException(e); - } + File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); + assertTrue(decompiledFile.isFile()); + File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); + assertTrue(referenceFile.isFile()); + assertFilesEqual(referenceFile, decompiledFile); } private static List collectClasses(File classFile) { @@ -90,15 +84,4 @@ public abstract class SingleClassesTestBase { return files; } - - private static void compareContent(File decompiledFile, File referenceFile) throws IOException { - String decompiledContent = new String(InterpreterUtil.getBytes(decompiledFile), "UTF-8"); - - String referenceContent = new String(InterpreterUtil.getBytes(referenceFile), "UTF-8"); - if (InterpreterUtil.IS_WINDOWS && !referenceContent.contains("\r\n")) { - referenceContent = referenceContent.replace("\n", "\r\n"); // fix for broken Git checkout on Windows - } - - assertEquals(referenceContent, decompiledContent); - } } diff --git a/testData/bulk/META-INF/MANIFEST.MF b/testData/bulk/META-INF/MANIFEST.MF index e69de29..22f53c8 100644 --- a/testData/bulk/META-INF/MANIFEST.MF +++ b/testData/bulk/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: 1.8.0_20 (Oracle Corporation) + diff --git a/testData/bulk/pkg/Main.java b/testData/bulk/pkg/Main.java index e69de29..f22c5d2 100644 --- a/testData/bulk/pkg/Main.java +++ b/testData/bulk/pkg/Main.java @@ -0,0 +1,11 @@ +package pkg; + +import pkg.res.Loader; + +public class Main { + public static void main(String[] args) { + Loader loader = new Loader(); + String resource = loader.getResource(); + System.out.println(resource); + } +} diff --git a/testData/bulk/pkg/res/Loader.java b/testData/bulk/pkg/res/Loader.java index e69de29..b0326dd 100644 --- a/testData/bulk/pkg/res/Loader.java +++ b/testData/bulk/pkg/res/Loader.java @@ -0,0 +1,25 @@ +package pkg.res; + +import java.io.File; +import java.io.FileInputStream; +import java.net.URL; + +public class Loader { + public String getResource() { + URL resource = this.getClass().getClassLoader().getResource("pkg/res/resource.txt"); + if(resource == null) { + throw new RuntimeException("Resource missing"); + } else { + try { + File e = new File(resource.toURI()); + byte[] bytes = new byte[(int)e.length()]; + FileInputStream stream = new FileInputStream(e); + stream.read(bytes); + stream.close(); + return new String(bytes, "UTF-8"); + } catch (Exception var5) { + throw new RuntimeException("Resource load failed", var5); + } + } + } +} From ee740aa05628856906e4b1b25f84d6cbb8cd3d9c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 7 Sep 2015 20:34:28 +0300 Subject: [PATCH 007/252] [java-decompiler] main test method extended to accept companion files --- .../decompiler/SingleClassesTestBase.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java b/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java index 97e98b2..0601f0e 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java @@ -49,16 +49,26 @@ public abstract class SingleClassesTestBase { return Collections.emptyMap(); } - protected void doTest(String testFile) { - File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); - assertTrue(classFile.isFile()); - String testName = classFile.getName().substring(0, classFile.getName().length() - 6); - + protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); - for (File file : collectClasses(classFile)) decompiler.addSpace(file, true); + File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); + assertTrue(classFile.isFile()); + for (File file : collectClasses(classFile)) { + decompiler.addSpace(file, true); + } + + for (String companionFile : companionFiles) { + File companionClassFile = new File(fixture.getTestDataDir(), "/classes/" + companionFile + ".class"); + assertTrue(companionClassFile.isFile()); + for (File file : collectClasses(companionClassFile)) { + decompiler.addSpace(file, true); + } + } + decompiler.decompileContext(); + String testName = classFile.getName().substring(0, classFile.getName().length() - 6); File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); assertTrue(decompiledFile.isFile()); File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); From 766fc1390d833f1694f67dccc40c99033b88e452 Mon Sep 17 00:00:00 2001 From: Alexandru-Constantin Bledea Date: Mon, 7 Sep 2015 20:44:51 +0300 Subject: [PATCH 008/252] Decompiler name shadowing resolution https://github.com/JetBrains/intellij-community/pull/295 --- .../main/collectors/ImportCollector.java | 3 ++- .../java/decompiler/SingleClassesTest.java | 1 + testData/classes/ext/Shadow$B.class | Bin 0 -> 243 bytes testData/classes/ext/Shadow.class | Bin 0 -> 243 bytes testData/classes/pkg/Shadow.class | Bin 0 -> 190 bytes testData/classes/pkg/TestShadowing.class | Bin 0 -> 342 bytes testData/results/TestShadowing.dec | 6 ++++++ testData/src/ext/Shadow.java | 6 ++++++ testData/src/pkg/Shadow.java | 4 ++++ testData/src/pkg/TestShadowing.java | 5 +++++ 10 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 testData/classes/ext/Shadow$B.class create mode 100644 testData/classes/ext/Shadow.class create mode 100644 testData/classes/pkg/Shadow.class create mode 100644 testData/classes/pkg/TestShadowing.class create mode 100644 testData/results/TestShadowing.dec create mode 100644 testData/src/ext/Shadow.java create mode 100644 testData/src/pkg/Shadow.java create mode 100644 testData/src/pkg/TestShadowing.java diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index 05dc835..ada6abc 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -99,7 +99,8 @@ public class ImportCollector { if (existsDefaultClass || (mapSimpleNames.containsKey(nshort) && !npackage.equals(mapSimpleNames.get(nshort)))) { - return fullname; + // don't return full name because if the class is a inner class, full name refers to the parent full name, not the child full name + return retname == null ? fullname : (npackage + "." + retname); } else if (!mapSimpleNames.containsKey(nshort)) { mapSimpleNames.put(nshort, npackage); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index e85cd67..0da0d3b 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -61,4 +61,5 @@ public class SingleClassesTest extends SingleClassesTestBase { @Test public void testInnerLocalPkg() { doTest("pkg/TestInnerLocalPkg"); } @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } + @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } } diff --git a/testData/classes/ext/Shadow$B.class b/testData/classes/ext/Shadow$B.class new file mode 100644 index 0000000000000000000000000000000000000000..eeb9d384874454df5be278d03747e9da23ae6fa6 GIT binary patch literal 243 zcmYLD%?`m}5S%S-siGdhLE?aeUL3`NL?RIm75A@vp;BLy{@}HoBn}?HLy2u2Y_dC< znapJ0pXUp}2rUaGSSD-}O@c8FRFF;xrCxtaD9@t3Bs7i(SWlt8@pLMa)~LXjjgAvk%!4TU#ZKQ9~6CMvGMqHPli40_$KbJOBUy literal 0 HcmV?d00001 diff --git a/testData/classes/ext/Shadow.class b/testData/classes/ext/Shadow.class new file mode 100644 index 0000000000000000000000000000000000000000..e576dfd9b0fdfd1b1feffd31f52d1a42bb23e849 GIT binary patch literal 243 zcmYL@%?`m(5QWcZDOGiHVuu$e)UUT<{2~8ciu~0jA6&z%k^Vxsi s_0U0qU(>};=>@D6cI~eRii11o_Kj`U5@W#Rp(^(R943IxRI?%~AJWb&K>z>% literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/Shadow.class b/testData/classes/pkg/Shadow.class new file mode 100644 index 0000000000000000000000000000000000000000..61ed27b36a1d424dc1237961c416e6f9a4490b12 GIT binary patch literal 190 zcmX^0Z`VEs1_l!bUM>b^1}=66ZgvJ9Mg}&U%)HDJJ4Oa(4b3n{1{UZ1lvG9rexJ;| zRKL>Pq|~C2#H1Xc2v=}^X;E^jTPBFZ9h{Mvl3%Wul~|U@!@$D83Y0I%PS=MBGcpK( zB=mC<^V0SGld@8iOBfUxn1Hr|03#3rbpS~=AWs&|XJBB}+RnhZ5iHFPB-wz%3_xX! L3>-k3iGdRUsiz`b literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestShadowing.class b/testData/classes/pkg/TestShadowing.class new file mode 100644 index 0000000000000000000000000000000000000000..228fd8f7571f13eb43fd7fd3d86211b334142ec8 GIT binary patch literal 342 zcmY*V%Syvg5IvK`#H6uJ>T~JBg%&XzcZ!P^1fkePi{SDmy~bPPO-WMqw_Hd;!4L4G z#7Pv?#SCX2=Nx7}K40Gf9An3WjnKim2Lqvt6>K=zbg)HeDP2}VCvtStClH5!p|vaq znJ7zH652!gR7K-kG0h+M`X>bYRB2V65zPIAD}pu1r;^YaDlIP;_pvM{BF?zujq^p3 z$a7T}-H9x#ZxN-_qnUURK3eb{Y_sEE2OkbRLO8!mqkkkqP}8DJ=rkI|GnrIu@=L`o z-(~Z?#K9Urh)uY&#?>LrW)}38pxzsd>m|$=SkKL7n{)jh@Rr3&20Dxl1aO-PG45g& F?iW35LgoMf literal 0 HcmV?d00001 diff --git a/testData/results/TestShadowing.dec b/testData/results/TestShadowing.dec new file mode 100644 index 0000000..45adbea --- /dev/null +++ b/testData/results/TestShadowing.dec @@ -0,0 +1,6 @@ +package pkg; + +class TestShadowing { + ext.Shadow.B instanceOfB = new ext.Shadow.B(); +} + diff --git a/testData/src/ext/Shadow.java b/testData/src/ext/Shadow.java new file mode 100644 index 0000000..02869ca --- /dev/null +++ b/testData/src/ext/Shadow.java @@ -0,0 +1,6 @@ +package ext; + +// companion class for pkg/TestShadowing.java +public class Shadow { + public static class B { } +} \ No newline at end of file diff --git a/testData/src/pkg/Shadow.java b/testData/src/pkg/Shadow.java new file mode 100644 index 0000000..d76fb78 --- /dev/null +++ b/testData/src/pkg/Shadow.java @@ -0,0 +1,4 @@ +package pkg; + +// companion class for pkg/TestShadowing.java +public class Shadow { } \ No newline at end of file diff --git a/testData/src/pkg/TestShadowing.java b/testData/src/pkg/TestShadowing.java new file mode 100644 index 0000000..c8792b2 --- /dev/null +++ b/testData/src/pkg/TestShadowing.java @@ -0,0 +1,5 @@ +package pkg; + +class TestShadowing { + ext.Shadow.B instanceOfB = new ext.Shadow.B(); +} \ No newline at end of file From 810818e2c328070ba0968b70277c05f244ab749a Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 7 Sep 2015 23:04:43 +0300 Subject: [PATCH 009/252] [java-decompiler] Ant tests in forked VM --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 9f4c208..7986eb4 100644 --- a/build.xml +++ b/build.xml @@ -46,7 +46,7 @@ - + From 26ab681d56eb73ed71264463e2052d3642682431 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 9 Nov 2015 20:46:35 +0100 Subject: [PATCH 010/252] [java-decompiler] cleanup (text rearranging mode dropped) --- .../java/decompiler/main/ClassWriter.java | 39 ------------------ .../decompiler/main/DecompilerContext.java | 2 +- .../java/decompiler/main/TextBuffer.java | 18 +------- .../main/extern/IFernflowerPreferences.java | 6 +-- .../java/decompiler/LineNumbersMatchTest.java | 33 --------------- .../classes/pkg/TestLineNumbersMatch.class | Bin 783 -> 0 bytes testData/results/TestLineNumbersMatch.dec | 22 ---------- testData/src/pkg/TestLineNumbersMatch.java | 22 ---------- 8 files changed, 5 insertions(+), 137 deletions(-) delete mode 100644 test/org/jetbrains/java/decompiler/LineNumbersMatchTest.java delete mode 100644 testData/classes/pkg/TestLineNumbersMatch.class delete mode 100644 testData/results/TestLineNumbersMatch.dec delete mode 100644 testData/src/pkg/TestLineNumbersMatch.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index afa2473..f84e05c 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -835,9 +835,6 @@ public class ClassWriter { // We do not have line information for method start, lets have it here for now StructLineNumberTableAttribute lineNumberTable = (StructLineNumberTableAttribute)mt.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); - if (lineNumberTable != null && DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_LINE_NUMBERS)) { - buffer.setCurrentLine(lineNumberTable.getFirstLine() - 1); - } buffer.append('{').appendLineSeparator(); tracer.incrementCurrentSourceLine(); @@ -851,10 +848,6 @@ public class ClassWriter { hideMethod = (clinit || dinit || hideConstructor(wrapper, init, throwsExceptions, paramCount)) && code.length() == 0; - if (!hideMethod && lineNumberTable != null && DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_LINE_NUMBERS)) { - mapLines(code, lineNumberTable, tracer, startLine); - } - buffer.append(code); } catch (Throwable ex) { @@ -888,38 +881,6 @@ public class ClassWriter { return !hideMethod; } - private static void mapLines(TextBuffer code, StructLineNumberTableAttribute table, BytecodeMappingTracer tracer, int startLine) { - // build line start offsets map - HashMap> lineStartOffsets = new HashMap>(); - for (Map.Entry entry : tracer.getMapping().entrySet()) { - Integer lineNumber = entry.getValue() - startLine; - Set curr = lineStartOffsets.get(lineNumber); - if (curr == null) { - curr = new TreeSet(); // requires natural sorting! - } - curr.add(entry.getKey()); - lineStartOffsets.put(lineNumber, curr); - } - String lineSeparator = DecompilerContext.getNewLineSeparator(); - StringBuilder text = code.getOriginalText(); - int pos = text.indexOf(lineSeparator); - int lineNumber = 0; - while (pos != -1) { - Set startOffsets = lineStartOffsets.get(lineNumber); - if (startOffsets != null) { - for (Integer offset : startOffsets) { - int number = table.findLineNumber(offset); - if (number >= 0) { - code.setLineMapping(number, pos); - break; - } - } - } - pos = text.indexOf(lineSeparator, pos+1); - lineNumber++; - } - } - private static boolean hideConstructor(ClassWrapper wrapper, boolean init, boolean throwsExceptions, int paramCount) { if (!init || throwsExceptions || paramCount > 0 || !DecompilerContext.getOption(IFernflowerPreferences.HIDE_DEFAULT_CONSTRUCTOR)) { return false; diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java index 15c6e40..d105959 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -156,6 +156,6 @@ public class DecompilerContext { public static String getNewLineSeparator() { return getOption(IFernflowerPreferences.NEW_LINE_SEPARATOR) ? - IFernflowerPreferences.LINE_SEPARATOR_LIN : IFernflowerPreferences.LINE_SEPARATOR_WIN; + IFernflowerPreferences.LINE_SEPARATOR_UNX : IFernflowerPreferences.LINE_SEPARATOR_WIN; } } diff --git a/src/org/jetbrains/java/decompiler/main/TextBuffer.java b/src/org/jetbrains/java/decompiler/main/TextBuffer.java index 95afc50..952b26f 100644 --- a/src/org/jetbrains/java/decompiler/main/TextBuffer.java +++ b/src/org/jetbrains/java/decompiler/main/TextBuffer.java @@ -42,17 +42,6 @@ public class TextBuffer { myStringBuilder = new StringBuilder(text); } - public void setCurrentLine(int line) { - setLineMapping(line, myStringBuilder.length()+1); - } - - public void setLineMapping(int line, int offset) { - if (line >= 0) { - checkMapCreated(); - myLineToOffsetMapping.put(line, offset); - } - } - public TextBuffer append(String str) { myStringBuilder.append(str); return this; @@ -301,15 +290,12 @@ public class TextBuffer { return res; } - public StringBuilder getOriginalText() { - return myStringBuilder; - } - private Map> myLineMapping = null; // new to original + public void dumpOriginalLineNumbers(int[] lineMapping) { if (lineMapping.length > 0) { myLineMapping = new HashMap>(); - for (int i = 0; i < lineMapping.length; i+=2) { + for (int i = 0; i < lineMapping.length; i += 2) { int key = lineMapping[i + 1]; Set existing = myLineMapping.get(key); if (existing == null) { diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java index 31871c5..cd6333b 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,6 @@ public interface IFernflowerPreferences { String IDEA_NOT_NULL_ANNOTATION = "inn"; String LAMBDA_TO_ANONYMOUS_CLASS = "lac"; String BYTECODE_SOURCE_MAPPING = "bsm"; - String USE_DEBUG_LINE_NUMBERS = "udl"; String LOG_LEVEL = "log"; String MAX_PROCESSING_METHOD = "mpm"; @@ -58,7 +57,7 @@ public interface IFernflowerPreferences { String UNIT_TEST_MODE = "__unit_test_mode__"; String LINE_SEPARATOR_WIN = "\r\n"; - String LINE_SEPARATOR_LIN = "\n"; + String LINE_SEPARATOR_UNX = "\n"; Map DEFAULTS = Collections.unmodifiableMap(new HashMap() {{ put(REMOVE_BRIDGE, "1"); @@ -83,7 +82,6 @@ public interface IFernflowerPreferences { put(IDEA_NOT_NULL_ANNOTATION, "1"); put(LAMBDA_TO_ANONYMOUS_CLASS, "0"); put(BYTECODE_SOURCE_MAPPING, "0"); - put(USE_DEBUG_LINE_NUMBERS, "0"); put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); put(MAX_PROCESSING_METHOD, "0"); diff --git a/test/org/jetbrains/java/decompiler/LineNumbersMatchTest.java b/test/org/jetbrains/java/decompiler/LineNumbersMatchTest.java deleted file mode 100644 index 758aa5f..0000000 --- a/test/org/jetbrains/java/decompiler/LineNumbersMatchTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.java.decompiler; - -import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -public class LineNumbersMatchTest extends SingleClassesTestBase { - @Override - protected Map getDecompilerOptions() { - return new HashMap() {{ - put(IFernflowerPreferences.USE_DEBUG_LINE_NUMBERS, "1"); - }}; - } - - @Test public void testMatch1() { doTest("pkg/TestLineNumbersMatch"); } -} diff --git a/testData/classes/pkg/TestLineNumbersMatch.class b/testData/classes/pkg/TestLineNumbersMatch.class deleted file mode 100644 index 0a96fbb25cd9a20f3938d8843fb61aa153bed8e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 783 zcmZ{i-%iv(6vn@4OS@ajE-o%CApS)ys5I!E7;i{SOcpg+LLzt5I#~++vuV2~K8jD^ zwO(MNi4WjI8NcanKofS7nRDjM`F?YHroaFE_yyn@0v9fBG_ir34cu~Z8+RI5c5v5) zjeC08ba3Cn0|5wlud_@Q`-v<|RSMWI;w-LS3Yh-Zk$|Ley(tv@;&28XJwE@kC`tfG@W0VCZd)<4#C5po_2EDS0cogK*0 zlw+h%1>8YCE+X|R*4M3GMcX-*AEk!{v>ZJ2;A4w8>0sN#BRpmuv&z`q)v6~RcF+>& z%}Ntk)Hei)%!a|+@Kik|{rU>58y`Gtx;( zMx8$q*0)dQI{WDtMV06rLSYI%&-8s6NXV$z9Ecy+uO)BTHLaJsj zPxKe;9wRHH_jqQ(Xgjp47sWm&O&9C^g#DfcJLhOz*6h|SP4E6ww>M=QSfkRwI&TJB J!9SRm<1ah8l>`6) diff --git a/testData/results/TestLineNumbersMatch.dec b/testData/results/TestLineNumbersMatch.dec deleted file mode 100644 index 9ab7626..0000000 --- a/testData/results/TestLineNumbersMatch.dec +++ /dev/null @@ -1,22 +0,0 @@ -package pkg; - -class TestLineNumbersMatch { - - - - void m1(boolean b) { - if(b) { - System.out.println("a"); - } else { - System.out.println("b"); - } } - - void m2() { - (new Runnable() { - - public void run() { - System.out.println("run with me"); - } - }).run(); - } -} diff --git a/testData/src/pkg/TestLineNumbersMatch.java b/testData/src/pkg/TestLineNumbersMatch.java deleted file mode 100644 index d9d486a..0000000 --- a/testData/src/pkg/TestLineNumbersMatch.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Weird comment here. - */ -package pkg; - -class TestLineNumbersMatch { - void m1(boolean b) { - if (b) - System.out.println("a"); - else - System.out.println("b"); - } - - void m2() { - new Runnable() { - @Override - public void run() { - System.out.println("run with me"); - } - }.run(); - } -} \ No newline at end of file From 45a41684e6dc257808615b35841f617cea926f72 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 10 Nov 2015 19:48:44 +0100 Subject: [PATCH 011/252] [java-decompiler] cleanup (arrays to data classes; formatting; typos; dead code) --- .../java/decompiler/main/ClassWriter.java | 29 +- .../decompiler/main/ClassesProcessor.java | 78 +- .../collectors/BytecodeMappingTracer.java | 12 +- .../main/rels/NestedClassProcessor.java | 720 ++++++++---------- .../modules/decompiler/exps/NewExprent.java | 223 +++--- .../attr/StructInnerClassesAttribute.java | 62 +- .../java/decompiler/util/InterpreterUtil.java | 25 +- 7 files changed, 500 insertions(+), 649 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index f84e05c..b55f29d 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -46,7 +46,6 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.*; public class ClassWriter { - private final ClassReference14Processor ref14processor; private final PoolInterceptor interceptor; @@ -154,15 +153,6 @@ public class ClassWriter { DecompilerContext.getLogger().endWriteClass(); } - private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) { - StructLineNumberTableAttribute lineNumberTable = - (StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); - tracer.setLineNumberTable(lineNumberTable); - DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName, - InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor()), - tracer); - } - public void classToJava(ClassNode node, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { ClassNode outerNode = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, node); @@ -183,12 +173,7 @@ public class ClassWriter { int start_class_def = buffer.length(); writeClassDefinition(node, buffer, indent); -// // count lines in class definition the easiest way -// startLine = buffer.substring(start_class_def).toString().split(lineSeparator, -1).length - 1; - boolean hasContent = false; - - // fields boolean enumFields = false; dummy_tracer.incrementCurrentSourceLine(buffer.countLines(start_class_def)); @@ -287,6 +272,13 @@ public class ClassWriter { DecompilerContext.getLogger().endWriteClass(); } + private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) { + StructLineNumberTableAttribute table = (StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); + tracer.setLineNumberTable(table); + String key = InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor()); + DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName, key, tracer); + } + private void writeClassDefinition(ClassNode node, TextBuffer buffer, int indent) { if (node.type == ClassNode.CLASS_ANONYMOUS) { buffer.append(" {").appendLineSeparator(); @@ -567,7 +559,7 @@ public class ClassWriter { } } - public static String toValidJavaIdentifier(String name) { + private static String toValidJavaIdentifier(String name) { if (name == null || name.isEmpty()) return name; boolean changed = false; @@ -833,8 +825,6 @@ public class ClassWriter { } // We do not have line information for method start, lets have it here for now - StructLineNumberTableAttribute lineNumberTable = - (StructLineNumberTableAttribute)mt.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); buffer.append('{').appendLineSeparator(); tracer.incrementCurrentSourceLine(); @@ -842,8 +832,6 @@ public class ClassWriter { if (root != null && !methodWrapper.decompiledWithErrors) { // check for existence try { - int startLine = tracer.getCurrentSourceLine(); - TextBuffer code = root.toJava(indent + 1, tracer); hideMethod = (clinit || dinit || hideConstructor(wrapper, init, throwsExceptions, paramCount)) && code.length() == 0; @@ -960,7 +948,6 @@ public class ClassWriter { StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS}; private static void appendAnnotations(TextBuffer buffer, StructMember mb, int indent) { - BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one for (String name : ANNOTATION_ATTRIBUTES) { diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 5a56641..17331e9 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -40,14 +40,22 @@ import java.util.*; import java.util.Map.Entry; public class ClassesProcessor { - public static final int AVERAGE_CLASS_SIZE = 16 * 1024; private final Map mapRootClasses = new HashMap(); - public ClassesProcessor(StructContext context) { + private static class Inner { + private String simpleName; + private int type; + private int accessFlags; - Map mapInnerClasses = new HashMap(); + private static boolean equal(Inner o1, Inner o2) { + return o1.type == o2.type && o1.accessFlags == o2.accessFlags && InterpreterUtil.equalObjects(o1.simpleName, o2.simpleName); + } + } + + public ClassesProcessor(StructContext context) { + Map mapInnerClasses = new HashMap(); Map> mapNestedClassReferences = new HashMap>(); Map> mapEnclosingClassReferences = new HashMap>(); Map mapNewSimpleNames = new HashMap(); @@ -57,25 +65,16 @@ public class ClassesProcessor { // create class nodes for (StructClass cl : context.getClasses().values()) { if (cl.isOwn() && !mapRootClasses.containsKey(cl.qualifiedName)) { - if (bDecompileInner) { StructInnerClassesAttribute inner = (StructInnerClassesAttribute)cl.getAttributes().getWithKey("InnerClasses"); + if (inner != null) { - - for (int i = 0; i < inner.getClassEntries().size(); i++) { - - int[] entry = inner.getClassEntries().get(i); - String[] strEntry = inner.getStringEntries().get(i); - Object[] arr = new Object[4]; // arr[0] not used - String innerName = strEntry[0]; - - // nested class type - arr[2] = entry[1] == 0 ? (entry[2] == 0 ? ClassNode.CLASS_ANONYMOUS : ClassNode.CLASS_LOCAL) : ClassNode.CLASS_MEMBER; + for (StructInnerClassesAttribute.Entry entry : inner.getEntries()) { + String innerName = entry.innerName; // original simple name - String simpleName = strEntry[2]; + String simpleName = entry.simpleName; String savedName = mapNewSimpleNames.get(innerName); - if (savedName != null) { simpleName = savedName; } @@ -87,15 +86,15 @@ public class ClassesProcessor { } } - arr[1] = simpleName; - - // original access flags - arr[3] = entry[3]; + Inner rec = new Inner(); + rec.simpleName = simpleName; + rec.type = entry.outerNameIdx != 0 ? ClassNode.CLASS_MEMBER : entry.simpleNameIdx != 0 ? ClassNode.CLASS_LOCAL : ClassNode.CLASS_ANONYMOUS; + rec.accessFlags = entry.accessFlags; // enclosing class String enclClassName; - if (entry[1] != 0) { - enclClassName = strEntry[1]; + if (entry.outerNameIdx != 0) { + enclClassName = entry.enclosingName; } else { enclClassName = cl.qualifiedName; @@ -105,11 +104,11 @@ public class ClassesProcessor { StructClass enclosing_class = context.getClasses().get(enclClassName); if (enclosing_class != null && enclosing_class.isOwn()) { // own classes only - Object[] arrOld = mapInnerClasses.get(innerName); - if (arrOld == null) { - mapInnerClasses.put(innerName, arr); + Inner existingRec = mapInnerClasses.get(innerName); + if (existingRec == null) { + mapInnerClasses.put(innerName, rec); } - else if (!InterpreterUtil.equalObjectArrays(arrOld, arr)) { + else if (!Inner.equal(existingRec, rec)) { String message = "Inconsistent inner class entries for " + innerName + "!"; DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } @@ -140,12 +139,10 @@ public class ClassesProcessor { } if (bDecompileInner) { - // connect nested classes for (Entry ent : mapRootClasses.entrySet()) { // root class? if (!mapInnerClasses.containsKey(ent.getKey())) { - Set setVisited = new HashSet(); LinkedList stack = new LinkedList(); @@ -153,7 +150,6 @@ public class ClassesProcessor { setVisited.add(ent.getKey()); while (!stack.isEmpty()) { - String superClass = stack.removeFirst(); ClassNode superNode = mapRootClasses.get(superClass); @@ -163,13 +159,13 @@ public class ClassesProcessor { StructClass scl = superNode.classStruct; StructInnerClassesAttribute inner = (StructInnerClassesAttribute)scl.getAttributes().getWithKey("InnerClasses"); - if (inner == null || inner.getStringEntries().isEmpty()) { + if (inner == null || inner.getEntries().isEmpty()) { DecompilerContext.getLogger().writeMessage(superClass + " does not contain inner classes!", IFernflowerLogger.Severity.WARN); continue; } - for (int i = 0; i < inner.getStringEntries().size(); i++) { - String nestedClass = inner.getStringEntries().get(i)[0]; + for (StructInnerClassesAttribute.Entry entry : inner.getEntries()) { + String nestedClass = entry.innerName; if (!setNestedClasses.contains(nestedClass)) { continue; } @@ -184,21 +180,20 @@ public class ClassesProcessor { continue; } - Object[] arr = mapInnerClasses.get(nestedClass); + Inner rec = mapInnerClasses.get(nestedClass); //if ((Integer)arr[2] == ClassNode.CLASS_MEMBER) { // FIXME: check for consistent naming //} - nestedNode.type = (Integer)arr[2]; - nestedNode.simpleName = (String)arr[1]; - nestedNode.access = (Integer)arr[3]; + nestedNode.simpleName = rec.simpleName; + nestedNode.type = rec.type; + nestedNode.access = rec.accessFlags; if (nestedNode.type == ClassNode.CLASS_ANONYMOUS) { StructClass cl = nestedNode.classStruct; - // remove static if anonymous class - // a common compiler bug + // remove static if anonymous class (a common compiler bug) nestedNode.access &= ~CodeConstants.ACC_STATIC; int[] interfaces = cl.getInterfaces(); @@ -215,8 +210,7 @@ public class ClassesProcessor { } } else if (nestedNode.type == ClassNode.CLASS_LOCAL) { - // only abstract and final are permitted - // a common compiler bug + // only abstract and final are permitted (a common compiler bug) nestedNode.access &= (CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_FINAL); } @@ -301,7 +295,6 @@ public class ClassesProcessor { } private static void initWrappers(ClassNode node) throws IOException { - if (node.type == ClassNode.CLASS_LAMBDA) { return; } @@ -317,7 +310,6 @@ public class ClassesProcessor { } private static void addClassnameToImport(ClassNode node, ImportCollector imp) { - if (node.simpleName != null && node.simpleName.length() > 0) { imp.getShortName(node.type == ClassNode.CLASS_ROOT ? node.classStruct.qualifiedName : node.simpleName, false); } @@ -328,7 +320,6 @@ public class ClassesProcessor { } private static void destroyWrappers(ClassNode node) { - node.wrapper = null; node.classStruct.releaseResources(); @@ -343,7 +334,6 @@ public class ClassesProcessor { public static class ClassNode { - public static final int CLASS_ROOT = 0; public static final int CLASS_MEMBER = 1; public static final int CLASS_ANONYMOUS = 2; diff --git a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java index e25cca2..94c2993 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java @@ -21,13 +21,9 @@ import java.util.*; import java.util.Map.Entry; public class BytecodeMappingTracer { - private int currentSourceLine; - private StructLineNumberTableAttribute lineNumberTable = null; - - // bytecode offset, source line - private final Map mapping = new HashMap(); + private final Map mapping = new HashMap(); // bytecode offset, source line public BytecodeMappingTracer() { } @@ -43,12 +39,6 @@ public class BytecodeMappingTracer { currentSourceLine += number_lines; } - public void shiftSourceLines(int shift) { - for (Entry entry : mapping.entrySet()) { - entry.setValue(entry.getValue() + shift); - } - } - public void addMapping(int bytecode_offset) { if (!mapping.containsKey(bytecode_offset)) { mapping.put(bytecode_offset, currentSourceLine); diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 798010e..6963f1d 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -43,9 +43,7 @@ import java.util.Map.Entry; public class NestedClassProcessor { - public void processClass(ClassNode root, ClassNode node) { - // hide synthetic lambda content methods if (node.type == ClassNode.CLASS_LAMBDA && !node.lambdaInformation.is_method_reference) { ClassNode node_content = DecompilerContext.getClassProcessor().getMapRootClasses().get(node.classStruct.qualifiedName); @@ -59,7 +57,6 @@ public class NestedClassProcessor { } if (node.type != ClassNode.CLASS_LAMBDA) { - computeLocalVarsAndDefinitions(node); // for each local or anonymous class ensure not empty enclosing method @@ -102,13 +99,12 @@ public class NestedClassProcessor { } private static void setLambdaVars(ClassNode parent, ClassNode child) { - if (child.lambdaInformation.is_method_reference) { // method reference, no code and no parameters return; } - final MethodWrapper meth = parent.getWrapper().getMethods().getWithKey(child.lambdaInformation.content_method_key); - final MethodWrapper encmeth = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); + MethodWrapper method = parent.getWrapper().getMethods().getWithKey(child.lambdaInformation.content_method_key); + final MethodWrapper enclosingMethod = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); MethodDescriptor md_lambda = MethodDescriptor.parseDescriptor(child.lambdaInformation.method_descriptor); final MethodDescriptor md_content = MethodDescriptor.parseDescriptor(child.lambdaInformation.content_method_descriptor); @@ -120,52 +116,45 @@ public class NestedClassProcessor { final boolean is_static_lambda_content = child.lambdaInformation.is_content_method_static; - final String parent_class_name = parent.getWrapper().getClassStruct().qualifiedName; - final String lambda_class_name = child.simpleName; + String parent_class_name = parent.getWrapper().getClassStruct().qualifiedName; + String lambda_class_name = child.simpleName; final VarType lambda_class_type = new VarType(lambda_class_name, true); // this pointer if (!is_static_lambda_content && DecompilerContext.getOption(IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS)) { - meth.varproc.getThisVars().put(new VarVersionPair(0, 0), parent_class_name); - meth.varproc.setVarName(new VarVersionPair(0, 0), parent.simpleName + ".this"); + method.varproc.getThisVars().put(new VarVersionPair(0, 0), parent_class_name); + method.varproc.setVarName(new VarVersionPair(0, 0), parent.simpleName + ".this"); } - // local variables - DirectGraph graph = encmeth.getOrBuildGraph(); + final Map mapNewNames = new HashMap(); - final HashMap mapNewNames = new HashMap(); - - graph.iterateExprents(new DirectGraph.ExprentIterator() { + enclosingMethod.getOrBuildGraph().iterateExprents(new DirectGraph.ExprentIterator() { + @Override public int processExprent(Exprent exprent) { - List lst = exprent.getAllExprents(true); lst.add(exprent); for (Exprent expr : lst) { - if (expr.type == Exprent.EXPRENT_NEW) { NewExprent new_expr = (NewExprent)expr; - if (new_expr.isLambda() && lambda_class_type.equals(new_expr.getNewType())) { + if (new_expr.isLambda() && lambda_class_type.equals(new_expr.getNewType())) { InvocationExprent inv_dynamic = new_expr.getConstructor(); int param_index = is_static_lambda_content ? 0 : 1; - int varindex = is_static_lambda_content ? 0 : 1; + int varIndex = is_static_lambda_content ? 0 : 1; for (int i = 0; i < vars_count; ++i) { - Exprent param = inv_dynamic.getLstParameters().get(param_index + i); if (param.type == Exprent.EXPRENT_VAR) { - VarVersionPair enc_varpaar = new VarVersionPair((VarExprent)param); - String enc_varname = encmeth.varproc.getVarName(enc_varpaar); - - //meth.varproc.setVarName(new VarVersionPair(varindex, 0), enc_varname); - mapNewNames.put(new VarVersionPair(varindex, 0), enc_varname); + VarVersionPair pair = new VarVersionPair((VarExprent)param); + String name = enclosingMethod.varproc.getVarName(pair); + mapNewNames.put(new VarVersionPair(varIndex, 0), name); } - varindex += md_content.params[i].stackSize; + varIndex += md_content.params[i].stackSize; } } } @@ -176,36 +165,33 @@ public class NestedClassProcessor { }); // update names of local variables - HashSet setNewOuterNames = new HashSet(mapNewNames.values()); - setNewOuterNames.removeAll(meth.setOuterVarNames); + Set setNewOuterNames = new HashSet(mapNewNames.values()); + setNewOuterNames.removeAll(method.setOuterVarNames); - meth.varproc.refreshVarNames(new VarNamesCollector(setNewOuterNames)); - meth.setOuterVarNames.addAll(setNewOuterNames); + method.varproc.refreshVarNames(new VarNamesCollector(setNewOuterNames)); + method.setOuterVarNames.addAll(setNewOuterNames); - for (Entry entr : mapNewNames.entrySet()) { - meth.varproc.setVarName(entr.getKey(), entr.getValue()); + for (Entry entry : mapNewNames.entrySet()) { + method.varproc.setVarName(entry.getKey(), entry.getValue()); } } private static void checkNotFoundClasses(ClassNode root, ClassNode node) { + List copy = new ArrayList(node.nested); - List lstChildren = new ArrayList(node.nested); - - for (ClassNode child : lstChildren) { - + for (ClassNode child : copy) { if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_ANONYMOUS) && child.enclosingMethod == null) { - Set setEnclosing = child.enclosingClasses; if (setEnclosing.size() == 1) { StructEnclosingMethodAttribute attr = (StructEnclosingMethodAttribute)child.classStruct.getAttributes().getWithKey("EnclosingMethod"); - if (attr != null && attr.getMethodName() != null) { - if (node.classStruct.qualifiedName.equals(attr.getClassName()) && - node.classStruct.getMethod(attr.getMethodName(), attr.getMethodDescriptor()) != null) { - child.enclosingMethod = InterpreterUtil.makeUniqueKey(attr.getMethodName(), attr.getMethodDescriptor()); - continue; - } + if (attr != null && + attr.getMethodName() != null && + node.classStruct.qualifiedName.equals(attr.getClassName()) && + node.classStruct.getMethod(attr.getMethodName(), attr.getMethodDescriptor()) != null) { + child.enclosingMethod = InterpreterUtil.makeUniqueKey(attr.getMethodName(), attr.getMethodDescriptor()); + continue; } } @@ -235,14 +221,12 @@ public class NestedClassProcessor { } private static boolean insertNestedClass(ClassNode root, ClassNode child) { - Set setEnclosing = child.enclosingClasses; LinkedList stack = new LinkedList(); stack.add(root); while (!stack.isEmpty()) { - ClassNode node = stack.removeFirst(); if (setEnclosing.contains(node.classStruct.qualifiedName)) { @@ -259,109 +243,98 @@ public class NestedClassProcessor { return false; } - private static void computeLocalVarsAndDefinitions(final ClassNode node) { - // local var masks // class name, constructor descriptor, field mask - final HashMap>> mapVarMasks = new HashMap>>(); + final Map>> mapVarMasks = new HashMap>>(); - int cltypes = 0; + int clTypes = 0; for (ClassNode nd : node.nested) { - if (nd.type != ClassNode.CLASS_LAMBDA) { - if ((nd.access & CodeConstants.ACC_STATIC) == 0 && (nd.access & CodeConstants.ACC_INTERFACE) == 0) { + if (nd.type != ClassNode.CLASS_LAMBDA && + (nd.access & CodeConstants.ACC_STATIC) == 0 && + (nd.access & CodeConstants.ACC_INTERFACE) == 0) { + clTypes |= nd.type; - cltypes |= nd.type; - - HashMap> mask = getMaskLocalVars(nd.getWrapper()); - if (mask.isEmpty()) { - if (!nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { - String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!"; - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); - } - } - else { - mapVarMasks.put(nd.classStruct.qualifiedName, mask); + Map> mask = getMaskLocalVars(nd.getWrapper()); + if (mask.isEmpty()) { + if (!nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { + String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!"; + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } } + else { + mapVarMasks.put(nd.classStruct.qualifiedName, mask); + } } } // local var masks - final HashMap>> mapVarFieldPairs = - new HashMap>>(); - - if (cltypes != ClassNode.CLASS_MEMBER) { + final Map>> mapVarFieldPairs = new HashMap>>(); + if (clTypes != ClassNode.CLASS_MEMBER) { // iterate enclosing class - for (final MethodWrapper meth : node.getWrapper().getMethods()) { - - if (meth.root != null) { // neither abstract, nor native - DirectGraph graph = meth.getOrBuildGraph(); - - graph.iterateExprents(new DirectGraph.ExprentIterator() { + for (final MethodWrapper method : node.getWrapper().getMethods()) { + if (method.root != null) { // neither abstract, nor native + method.getOrBuildGraph().iterateExprents(new DirectGraph.ExprentIterator() { + @Override public int processExprent(Exprent exprent) { List lst = exprent.getAllExprents(true); lst.add(exprent); for (Exprent expr : lst) { - if (expr.type == Exprent.EXPRENT_NEW) { - InvocationExprent constr = ((NewExprent)expr).getConstructor(); + InvocationExprent constructor = ((NewExprent)expr).getConstructor(); - if (constr != null && mapVarMasks.containsKey(constr.getClassname())) { // non-static inner class constructor - - String refclname = constr.getClassname(); - - ClassNode nestedClassNode = node.getClassNode(refclname); + if (constructor != null && mapVarMasks.containsKey(constructor.getClassname())) { // non-static inner class constructor + String refClassName = constructor.getClassname(); + ClassNode nestedClassNode = node.getClassNode(refClassName); if (nestedClassNode.type != ClassNode.CLASS_MEMBER) { + List mask = mapVarMasks.get(refClassName).get(constructor.getStringDescriptor()); - List mask = mapVarMasks.get(refclname).get(constr.getStringDescriptor()); - - if (!mapVarFieldPairs.containsKey(refclname)) { - mapVarFieldPairs.put(refclname, new HashMap>()); + if (!mapVarFieldPairs.containsKey(refClassName)) { + mapVarFieldPairs.put(refClassName, new HashMap>()); } List lstTemp = new ArrayList(); for (int i = 0; i < mask.size(); i++) { - Exprent param = constr.getLstParameters().get(i); + Exprent param = constructor.getLstParameters().get(i); VarFieldPair pair = null; if (param.type == Exprent.EXPRENT_VAR && mask.get(i) != null) { - VarVersionPair varpaar = new VarVersionPair((VarExprent)param); + VarVersionPair varPair = new VarVersionPair((VarExprent)param); - // FIXME: final flags of variables are wrong! Correct the entire final functionality. - // if(meth.varproc.getVarFinal(varpaar) != VarTypeProcessor.VAR_NON_FINAL) { - pair = new VarFieldPair(mask.get(i).keyfield, varpaar); - // } + // FIXME: flags of variables are wrong! Correct the entire functionality. + // if(method.varproc.getVarFinal(varPair) != VarTypeProcessor.VAR_NON_FINAL) { + pair = new VarFieldPair(mask.get(i).fieldKey, varPair); + // } } lstTemp.add(pair); } - List pairmask = mapVarFieldPairs.get(refclname).get(constr.getStringDescriptor()); - - if (pairmask == null) { - pairmask = lstTemp; + List pairMask = mapVarFieldPairs.get(refClassName).get(constructor.getStringDescriptor()); + if (pairMask == null) { + pairMask = lstTemp; } else { - for (int i = 0; i < pairmask.size(); i++) { - if (!InterpreterUtil.equalObjects(pairmask.get(i), lstTemp.get(i))) { - pairmask.set(i, null); + for (int i = 0; i < pairMask.size(); i++) { + if (!InterpreterUtil.equalObjects(pairMask.get(i), lstTemp.get(i))) { + pairMask.set(i, null); } } } - mapVarFieldPairs.get(refclname).put(constr.getStringDescriptor(), pairmask); + mapVarFieldPairs.get(refClassName).put(constructor.getStringDescriptor(), pairMask); nestedClassNode.enclosingMethod = - InterpreterUtil.makeUniqueKey(meth.methodStruct.getName(), meth.methodStruct.getDescriptor()); + InterpreterUtil.makeUniqueKey(method.methodStruct.getName(), method.methodStruct.getDescriptor()); } } } } + return 0; } }); @@ -370,219 +343,200 @@ public class NestedClassProcessor { } // merge var masks - for (Entry>> entcl : mapVarMasks.entrySet()) { - - ClassNode nestedNode = node.getClassNode(entcl.getKey()); + for (Entry>> enclosing : mapVarMasks.entrySet()) { + ClassNode nestedNode = node.getClassNode(enclosing.getKey()); // intersection - List intrPairMask = null; + List interPairMask = null; // merge referenced constructors - if (mapVarFieldPairs.containsKey(entcl.getKey())) { - for (List mask : mapVarFieldPairs.get(entcl.getKey()).values()) { - if (intrPairMask == null) { - intrPairMask = new ArrayList(mask); + if (mapVarFieldPairs.containsKey(enclosing.getKey())) { + for (List mask : mapVarFieldPairs.get(enclosing.getKey()).values()) { + if (interPairMask == null) { + interPairMask = new ArrayList(mask); } else { - mergeListSignatures(intrPairMask, mask, false); + mergeListSignatures(interPairMask, mask, false); } } } - List intrMask = null; + List interMask = null; // merge all constructors - for (List mask : entcl.getValue().values()) { - if (intrMask == null) { - intrMask = new ArrayList(mask); + for (List mask : enclosing.getValue().values()) { + if (interMask == null) { + interMask = new ArrayList(mask); } else { - mergeListSignatures(intrMask, mask, false); + mergeListSignatures(interMask, mask, false); } } - if (intrPairMask == null) { // member or local and never instantiated - intrPairMask = new ArrayList(intrMask); + if (interPairMask == null) { // member or local and never instantiated + interPairMask = interMask != null ? new ArrayList(interMask) : new ArrayList(); boolean found = false; - for (int i = 0; i < intrPairMask.size(); i++) { - if (intrPairMask.get(i) != null) { + for (int i = 0; i < interPairMask.size(); i++) { + if (interPairMask.get(i) != null) { if (found) { - intrPairMask.set(i, null); + interPairMask.set(i, null); } found = true; } } } - mergeListSignatures(intrPairMask, intrMask, true); + mergeListSignatures(interPairMask, interMask, true); - for (int i = 0; i < intrPairMask.size(); i++) { - VarFieldPair pair = intrPairMask.get(i); - if (pair != null && pair.keyfield.length() > 0) { - nestedNode.mapFieldsToVars.put(pair.keyfield, pair.varpaar); + for (VarFieldPair pair : interPairMask) { + if (pair != null && pair.fieldKey.length() > 0) { + nestedNode.mapFieldsToVars.put(pair.fieldKey, pair.varPair); } } // set resulting constructor signatures - for (Entry> entmt : entcl.getValue().entrySet()) { - mergeListSignatures(entmt.getValue(), intrPairMask, false); + for (Entry> entry : enclosing.getValue().entrySet()) { + mergeListSignatures(entry.getValue(), interPairMask, false); - MethodWrapper meth = nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entmt.getKey()); - meth.signatureFields = new ArrayList(); + MethodWrapper method = nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entry.getKey()); + method.signatureFields = new ArrayList(); - for (VarFieldPair pair : entmt.getValue()) { - meth.signatureFields.add(pair == null ? null : pair.varpaar); + for (VarFieldPair pair : entry.getValue()) { + method.signatureFields.add(pair == null ? null : pair.varPair); } } } } - private static void insertLocalVars(final ClassNode parent, final ClassNode child) { - + private static void insertLocalVars(ClassNode parent, final ClassNode child) { // enclosing method, is null iff member class - MethodWrapper encmeth = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); + MethodWrapper enclosingMethod = parent.getWrapper().getMethods().getWithKey(child.enclosingMethod); // iterate all child methods - for (final MethodWrapper meth : child.getWrapper().getMethods()) { + for (final MethodWrapper method : child.getWrapper().getMethods()) { + if (method.root != null) { // neither abstract nor native + Map mapNewNames = new HashMap(); // local var names + Map mapNewTypes = new HashMap(); // local var types - if (meth.root != null) { // neither abstract nor native + final Map mapParamsToNewVars = new HashMap(); + if (method.signatureFields != null) { + int index = 0, varIndex = 1; + MethodDescriptor md = MethodDescriptor.parseDescriptor(method.methodStruct.getDescriptor()); - // local var names - HashMap mapNewNames = new HashMap(); - // local var types - HashMap mapNewTypes = new HashMap(); + for (VarVersionPair pair : method.signatureFields) { + if (pair != null) { + VarVersionPair newVar = new VarVersionPair(method.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); - final HashMap mapParamsToNewVars = new HashMap(); - if (meth.signatureFields != null) { - int index = 0; - int varindex = 1; - MethodDescriptor md = MethodDescriptor.parseDescriptor(meth.methodStruct.getDescriptor()); + mapParamsToNewVars.put(varIndex, newVar); - for (VarVersionPair paar : meth.signatureFields) { - if (paar != null) { - VarVersionPair newvar = new VarVersionPair(meth.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); - - mapParamsToNewVars.put(varindex, newvar); - - String varname = null; - VarType vartype = null; + String varName = null; + VarType varType = null; if (child.type != ClassNode.CLASS_MEMBER) { - varname = encmeth.varproc.getVarName(paar); - vartype = encmeth.varproc.getVarType(paar); + varName = enclosingMethod.varproc.getVarName(pair); + varType = enclosingMethod.varproc.getVarType(pair); - encmeth.varproc.setVarFinal(paar, VarTypeProcessor.VAR_EXPLICIT_FINAL); + enclosingMethod.varproc.setVarFinal(pair, VarTypeProcessor.VAR_EXPLICIT_FINAL); } - if (paar.var == -1 || "this".equals(varname)) { + if (pair.var == -1 || "this".equals(varName)) { if (parent.simpleName == null) { // anonymous enclosing class, no access to this - varname = VarExprent.VAR_NAMELESS_ENCLOSURE; + varName = VarExprent.VAR_NAMELESS_ENCLOSURE; } else { - varname = parent.simpleName + ".this"; + varName = parent.simpleName + ".this"; } - meth.varproc.getThisVars().put(newvar, parent.classStruct.qualifiedName); + method.varproc.getThisVars().put(newVar, parent.classStruct.qualifiedName); } - mapNewNames.put(newvar, varname); - mapNewTypes.put(newvar, vartype); + mapNewNames.put(newVar, varName); + mapNewTypes.put(newVar, varType); } - varindex += md.params[index++].stackSize; + + varIndex += md.params[index++].stackSize; } } - // new vars - final HashMap mapFieldsToNewVars = new HashMap(); + final Map mapFieldsToNewVars = new HashMap(); + for (ClassNode classNode = child; classNode != null; classNode = classNode.parent) { + for (Entry entry : classNode.mapFieldsToVars.entrySet()) { + VarVersionPair newVar = new VarVersionPair(method.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); - for (ClassNode clnode = child; clnode != null; clnode = clnode.parent) { + mapFieldsToNewVars.put(InterpreterUtil.makeUniqueKey(classNode.classStruct.qualifiedName, entry.getKey()), newVar); - for (Entry entr : clnode.mapFieldsToVars.entrySet()) { - VarVersionPair newvar = new VarVersionPair(meth.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); + String varName = null; + VarType varType = null; - mapFieldsToNewVars.put(InterpreterUtil.makeUniqueKey(clnode.classStruct.qualifiedName, entr.getKey()), newvar); + if (classNode.type != ClassNode.CLASS_MEMBER) { + MethodWrapper enclosing_method = classNode.parent.getWrapper().getMethods().getWithKey(classNode.enclosingMethod); - String varname = null; - VarType vartype = null; + varName = enclosing_method.varproc.getVarName(entry.getValue()); + varType = enclosing_method.varproc.getVarType(entry.getValue()); - if (clnode.type != ClassNode.CLASS_MEMBER) { - - MethodWrapper enclosing_method = clnode.parent.getWrapper().getMethods().getWithKey(clnode.enclosingMethod); - - varname = enclosing_method.varproc.getVarName(entr.getValue()); - vartype = enclosing_method.varproc.getVarType(entr.getValue()); - - enclosing_method.varproc.setVarFinal(entr.getValue(), VarTypeProcessor.VAR_EXPLICIT_FINAL); + enclosing_method.varproc.setVarFinal(entry.getValue(), VarTypeProcessor.VAR_EXPLICIT_FINAL); } - if (entr.getValue().var == -1 || "this".equals(varname)) { - if (clnode.parent.simpleName == null) { + if (entry.getValue().var == -1 || "this".equals(varName)) { + if (classNode.parent.simpleName == null) { // anonymous enclosing class, no access to this - varname = VarExprent.VAR_NAMELESS_ENCLOSURE; + varName = VarExprent.VAR_NAMELESS_ENCLOSURE; } else { - varname = clnode.parent.simpleName + ".this"; + varName = classNode.parent.simpleName + ".this"; } - meth.varproc.getThisVars().put(newvar, clnode.parent.classStruct.qualifiedName); + method.varproc.getThisVars().put(newVar, classNode.parent.classStruct.qualifiedName); } - mapNewNames.put(newvar, varname); - mapNewTypes.put(newvar, vartype); + mapNewNames.put(newVar, varName); + mapNewTypes.put(newVar, varType); // hide synthetic field - if (clnode == child) { // fields higher up the chain were already handled with their classes - StructField fd = child.classStruct.getFields().getWithKey(entr.getKey()); + if (classNode == child) { // fields higher up the chain were already handled with their classes + StructField fd = child.classStruct.getFields().getWithKey(entry.getKey()); child.getWrapper().getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); } } } - HashSet setNewOuterNames = new HashSet(mapNewNames.values()); - setNewOuterNames.removeAll(meth.setOuterVarNames); + Set setNewOuterNames = new HashSet(mapNewNames.values()); + setNewOuterNames.removeAll(method.setOuterVarNames); - meth.varproc.refreshVarNames(new VarNamesCollector(setNewOuterNames)); - meth.setOuterVarNames.addAll(setNewOuterNames); + method.varproc.refreshVarNames(new VarNamesCollector(setNewOuterNames)); + method.setOuterVarNames.addAll(setNewOuterNames); - for (Entry entr : mapNewNames.entrySet()) { - VarVersionPair varpaar = entr.getKey(); - VarType vartype = mapNewTypes.get(varpaar); + for (Entry entry : mapNewNames.entrySet()) { + VarVersionPair pair = entry.getKey(); + VarType type = mapNewTypes.get(pair); - meth.varproc.setVarName(varpaar, entr.getValue()); - if (vartype != null) { - meth.varproc.setVarType(varpaar, vartype); + method.varproc.setVarName(pair, entry.getValue()); + if (type != null) { + method.varproc.setVarType(pair, type); } } - DirectGraph graph = meth.getOrBuildGraph(); - - graph.iterateExprents(new DirectGraph.ExprentIterator() { + method.getOrBuildGraph().iterateExprents(new DirectGraph.ExprentIterator() { + @Override public int processExprent(Exprent exprent) { - if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { - AssignmentExprent asexpr = (AssignmentExprent)exprent; - if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD) { - FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); - - if (fexpr.getClassname().equals(child.classStruct.qualifiedName) && // process this class only - mapFieldsToNewVars.containsKey(InterpreterUtil.makeUniqueKey(child.classStruct.qualifiedName, - InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr - .getDescriptor().descriptorString)))) { + AssignmentExprent assignExpr = (AssignmentExprent)exprent; + if (assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) { + FieldExprent fExpr = (FieldExprent)assignExpr.getLeft(); + String qName = child.classStruct.qualifiedName; + if (fExpr.getClassname().equals(qName) && // process this class only + mapFieldsToNewVars.containsKey(InterpreterUtil.makeUniqueKey(qName, fExpr.getName(), fExpr.getDescriptor().descriptorString))) { return 2; } - - //if(fexpr.getClassname().equals(child.classStruct.qualifiedName) && - // mapFieldsToNewVars.containsKey(InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString))) { - // return 2; - //} } } - if (child.type == ClassNode.CLASS_ANONYMOUS && CodeConstants.INIT_NAME.equals(meth.methodStruct.getName()) - && exprent.type == Exprent.EXPRENT_INVOCATION) { - InvocationExprent invexpr = (InvocationExprent)exprent; - if (invexpr.getFunctype() == InvocationExprent.TYP_INIT) { + if (child.type == ClassNode.CLASS_ANONYMOUS && + CodeConstants.INIT_NAME.equals(method.methodStruct.getName()) && + exprent.type == Exprent.EXPRENT_INVOCATION) { + InvocationExprent invokeExpr = (InvocationExprent)exprent; + if (invokeExpr.getFunctype() == InvocationExprent.TYP_INIT) { // invocation of the super constructor in an anonymous class - child.superInvocation = invexpr; // FIXME: save original names of parameters + child.superInvocation = invokeExpr; // FIXME: save original names of parameters return 2; } } @@ -593,27 +547,23 @@ public class NestedClassProcessor { } private Exprent replaceExprent(Exprent exprent) { - if (exprent.type == Exprent.EXPRENT_VAR) { - int varindex = ((VarExprent)exprent).getIndex(); - if (mapParamsToNewVars.containsKey(varindex)) { - VarVersionPair newvar = mapParamsToNewVars.get(varindex); - meth.varproc.getExternalVars().add(newvar); - return new VarExprent(newvar.var, meth.varproc.getVarType(newvar), meth.varproc); + int varIndex = ((VarExprent)exprent).getIndex(); + if (mapParamsToNewVars.containsKey(varIndex)) { + VarVersionPair newVar = mapParamsToNewVars.get(varIndex); + method.varproc.getExternalVars().add(newVar); + return new VarExprent(newVar.var, method.varproc.getVarType(newVar), method.varproc); } } else if (exprent.type == Exprent.EXPRENT_FIELD) { - FieldExprent fexpr = (FieldExprent)exprent; - - String keyField = InterpreterUtil.makeUniqueKey(fexpr.getClassname(), InterpreterUtil - .makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString)); - - if (mapFieldsToNewVars.containsKey(keyField)) { - //if(fexpr.getClassname().equals(child.classStruct.qualifiedName) && - // mapFieldsToNewVars.containsKey(keyField)) { - VarVersionPair newvar = mapFieldsToNewVars.get(keyField); - meth.varproc.getExternalVars().add(newvar); - return new VarExprent(newvar.var, meth.varproc.getVarType(newvar), meth.varproc); + FieldExprent fExpr = (FieldExprent)exprent; + String key = InterpreterUtil.makeUniqueKey(fExpr.getClassname(), fExpr.getName(), fExpr.getDescriptor().descriptorString); + if (mapFieldsToNewVars.containsKey(key)) { + //if(fExpr.getClassname().equals(child.classStruct.qualifiedName) && + // mapFieldsToNewVars.containsKey(key)) { + VarVersionPair newVar = mapFieldsToNewVars.get(key); + method.varproc.getExternalVars().add(newVar); + return new VarExprent(newVar.var, method.varproc.getVarType(newVar), method.varproc); } } @@ -622,9 +572,9 @@ public class NestedClassProcessor { replaced = false; for (Exprent expr : exprent.getAllExprents()) { - Exprent retexpr = replaceExprent(expr); - if (retexpr != null) { - exprent.replaceExprent(expr, retexpr); + Exprent retExpr = replaceExprent(expr); + if (retExpr != null) { + exprent.replaceExprent(expr, retExpr); replaced = true; break; } @@ -638,30 +588,28 @@ public class NestedClassProcessor { } } - private static HashMap> getMaskLocalVars(ClassWrapper wrapper) { - - HashMap> mapMasks = new HashMap>(); + private static Map> getMaskLocalVars(ClassWrapper wrapper) { + Map> mapMasks = new HashMap>(); StructClass cl = wrapper.getClassStruct(); // iterate over constructors for (StructMethod mt : cl.getMethods()) { if (CodeConstants.INIT_NAME.equals(mt.getName())) { - MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); - - MethodWrapper meth = wrapper.getMethodWrapper(CodeConstants.INIT_NAME, mt.getDescriptor()); - DirectGraph graph = meth.getOrBuildGraph(); + MethodWrapper method = wrapper.getMethodWrapper(CodeConstants.INIT_NAME, mt.getDescriptor()); + DirectGraph graph = method.getOrBuildGraph(); if (graph != null) { // something gone wrong, should not be null List fields = new ArrayList(); - int varindex = 1; + int varIndex = 1; for (int i = 0; i < md.params.length; i++) { // no static methods allowed - String keyField = getEnclosingVarField(cl, meth, graph, varindex); + String keyField = getEnclosingVarField(cl, method, graph, varIndex); fields.add(keyField == null ? null : new VarFieldPair(keyField, new VarVersionPair(-1, 0))); // TODO: null? - varindex += md.params[i].stackSize; + varIndex += md.params[i].stackSize; } + mapMasks.put(mt.getDescriptor(), fields); } } @@ -670,38 +618,35 @@ public class NestedClassProcessor { return mapMasks; } - private static String getEnclosingVarField(StructClass cl, MethodWrapper meth, DirectGraph graph, final int index) { - + private static String getEnclosingVarField(StructClass cl, MethodWrapper method, DirectGraph graph, int index) { String field = ""; // parameter variable final - if (meth.varproc.getVarFinal(new VarVersionPair(index, 0)) == VarTypeProcessor.VAR_NON_FINAL) { + if (method.varproc.getVarFinal(new VarVersionPair(index, 0)) == VarTypeProcessor.VAR_NON_FINAL) { return null; } boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET); // no loop at the begin - DirectNode firstnode = graph.first; - if (firstnode.preds.isEmpty()) { - // assignment to a final synthetic field? - for (Exprent exprent : firstnode.exprents) { + DirectNode firstNode = graph.first; + if (firstNode.preds.isEmpty()) { + // assignment to a synthetic field? + for (Exprent exprent : firstNode.exprents) { if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { - AssignmentExprent asexpr = (AssignmentExprent)exprent; - if (asexpr.getRight().type == Exprent.EXPRENT_VAR && ((VarExprent)asexpr.getRight()).getIndex() == index) { - if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD) { + AssignmentExprent assignExpr = (AssignmentExprent)exprent; + if (assignExpr.getRight().type == Exprent.EXPRENT_VAR && + ((VarExprent)assignExpr.getRight()).getIndex() == index && + assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) { + FieldExprent left = (FieldExprent)assignExpr.getLeft(); + StructField fd = cl.getField(left.getName(), left.getDescriptor().descriptorString); - FieldExprent left = (FieldExprent)asexpr.getLeft(); - StructField fd = cl.getField(left.getName(), left.getDescriptor().descriptorString); - - if (fd != null) { // local (== not inherited) field - if (cl.qualifiedName.equals(left.getClassname()) && - fd.hasModifier(CodeConstants.ACC_FINAL) && - (fd.isSynthetic() || (noSynthFlag && fd.hasModifier(CodeConstants.ACC_PRIVATE)))) { - field = InterpreterUtil.makeUniqueKey(left.getName(), left.getDescriptor().descriptorString); - break; - } - } + if (fd != null && cl.qualifiedName.equals(left.getClassname()) && + fd.hasModifier(CodeConstants.ACC_FINAL) && + (fd.isSynthetic() || (noSynthFlag && fd.hasModifier(CodeConstants.ACC_PRIVATE)))) { + // local (== not inherited) field + field = InterpreterUtil.makeUniqueKey(left.getName(), left.getDescriptor().descriptorString); + break; } } } @@ -712,51 +657,31 @@ public class NestedClassProcessor { } private static void mergeListSignatures(List first, List second, boolean both) { - int i = 1; + while (true) { if (first.size() <= i || second.size() <= i) { break; } - VarFieldPair fobj = first.get(first.size() - i); - VarFieldPair sobj = second.get(second.size() - i); + VarFieldPair fObj = first.get(first.size() - i); + VarFieldPair sObj = second.get(second.size() - i); - boolean eq = false; - if (fobj == null || sobj == null) { - eq = (fobj == sobj); - } - else { - eq = true; - if (fobj.keyfield.length() == 0) { - fobj.keyfield = sobj.keyfield; - } - else if (sobj.keyfield.length() == 0) { - if (both) { - sobj.keyfield = fobj.keyfield; - } - } - else { - eq = fobj.keyfield.equals(sobj.keyfield); - } - } - - if (!eq) { + if (!isEqual(both, fObj, sObj)) { first.set(first.size() - i, null); if (both) { second.set(second.size() - i, null); } } - else { - if (fobj != null) { - if (fobj.varpaar.var == -1) { - fobj.varpaar = sobj.varpaar; - } - else { - sobj.varpaar = fobj.varpaar; - } + else if (fObj != null) { + if (fObj.varPair.var == -1) { + fObj.varPair = sObj.varPair; + } + else { + sObj.varPair = fObj.varPair; } } + i++; } @@ -780,64 +705,66 @@ public class NestedClassProcessor { first.set(0, null); } else { - VarFieldPair fobj = first.get(0); - VarFieldPair sobj = second.get(0); + VarFieldPair fObj = first.get(0); + VarFieldPair sObj = second.get(0); - boolean eq = false; - if (fobj == null || sobj == null) { - eq = (fobj == sobj); - } - else { - eq = true; - if (fobj.keyfield.length() == 0) { - fobj.keyfield = sobj.keyfield; - } - else if (sobj.keyfield.length() == 0) { - if (both) { - sobj.keyfield = fobj.keyfield; - } - } - else { - eq = fobj.keyfield.equals(sobj.keyfield); - } - } - - if (!eq) { + if (!isEqual(both, fObj, sObj)) { first.set(0, null); if (both) { second.set(0, null); } } - else if (fobj != null) { - if (fobj.varpaar.var == -1) { - fobj.varpaar = sobj.varpaar; + else if (fObj != null) { + if (fObj.varPair.var == -1) { + fObj.varPair = sObj.varPair; } else { - sobj.varpaar = fobj.varpaar; + sObj.varPair = fObj.varPair; } } } } + private static boolean isEqual(boolean both, VarFieldPair fObj, VarFieldPair sObj) { + boolean eq; + if (fObj == null || sObj == null) { + eq = (fObj == sObj); + } + else { + eq = true; + if (fObj.fieldKey.length() == 0) { + fObj.fieldKey = sObj.fieldKey; + } + else if (sObj.fieldKey.length() == 0) { + if (both) { + sObj.fieldKey = fObj.fieldKey; + } + } + else { + eq = fObj.fieldKey.equals(sObj.fieldKey); + } + } + return eq; + } - private static void setLocalClassDefinition(MethodWrapper meth, ClassNode node) { + private static void setLocalClassDefinition(MethodWrapper method, ClassNode node) { + RootStatement root = method.root; - RootStatement root = meth.root; + Set setStats = new HashSet(); + VarType classType = new VarType(node.classStruct.qualifiedName, true); - HashSet setStats = new HashSet(); - VarType classtype = new VarType(node.classStruct.qualifiedName, true); - - Statement stdef = getDefStatement(root, classtype, setStats); - if (stdef == null) { + Statement statement = getDefStatement(root, classType, setStats); + if (statement == null) { // unreferenced local class - stdef = root.getFirst(); + statement = root.getFirst(); } - Statement first = findFirstBlock(stdef, setStats); + Statement first = findFirstBlock(statement, setStats); List lst; + //noinspection Duplicates if (first == null) { - lst = stdef.getVarDefinitions(); + lst = statement.getVarDefinitions(); } else if (first.getExprents() == null) { lst = first.getVarDefinitions(); @@ -846,26 +773,22 @@ public class NestedClassProcessor { lst = first.getExprents(); } - - int addindex = 0; + int addIndex = 0; for (Exprent expr : lst) { - if (searchForClass(expr, classtype)) { + if (searchForClass(expr, classType)) { break; } - addindex++; + addIndex++; } - VarExprent var = new VarExprent(meth.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), - classtype, meth.varproc); + VarExprent var = new VarExprent(method.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), classType, method.varproc); var.setDefinition(true); var.setClassDef(true); - lst.add(addindex, var); + lst.add(addIndex, var); } - - private static Statement findFirstBlock(Statement stat, HashSet setStats) { - + private static Statement findFirstBlock(Statement stat, Set setStats) { LinkedList stack = new LinkedList(); stack.add(stat); @@ -873,30 +796,25 @@ public class NestedClassProcessor { Statement st = stack.remove(0); if (stack.isEmpty() || setStats.contains(st)) { - - if (st.isLabeled() && !stack.isEmpty()) { + if (st.isLabeled() && !stack.isEmpty() || st.getExprents() != null) { return st; } - if (st.getExprents() != null) { - return st; - } - else { - stack.clear(); + stack.clear(); - switch (st.type) { - case Statement.TYPE_SEQUENCE: - stack.addAll(0, st.getStats()); - break; - case Statement.TYPE_IF: - case Statement.TYPE_ROOT: - case Statement.TYPE_SWITCH: - case Statement.TYPE_SYNCRONIZED: - stack.add(st.getFirst()); - break; - default: - return st; - } + //noinspection Duplicates + switch (st.type) { + case Statement.TYPE_SEQUENCE: + stack.addAll(0, st.getStats()); + break; + case Statement.TYPE_IF: + case Statement.TYPE_ROOT: + case Statement.TYPE_SWITCH: + case Statement.TYPE_SYNCRONIZED: + stack.add(st.getFirst()); + break; + default: + return st; } } } @@ -904,11 +822,9 @@ public class NestedClassProcessor { return null; } - - private static Statement getDefStatement(Statement stat, VarType classtype, HashSet setStats) { - - List condlst = new ArrayList(); - Statement retstat = null; + private static Statement getDefStatement(Statement stat, VarType classType, Set setStats) { + List lst = new ArrayList(); + Statement retStat = null; if (stat.getExprents() == null) { int counter = 0; @@ -917,65 +833,63 @@ public class NestedClassProcessor { if (obj instanceof Statement) { Statement st = (Statement)obj; - Statement stTemp = getDefStatement(st, classtype, setStats); + Statement stTemp = getDefStatement(st, classType, setStats); if (stTemp != null) { if (counter == 1) { - retstat = stat; + retStat = stat; break; } - retstat = stTemp; + retStat = stTemp; counter++; } - if (st.type == DoStatement.TYPE_DO) { + if (st.type == Statement.TYPE_DO) { DoStatement dost = (DoStatement)st; - condlst.addAll(dost.getInitExprentList()); - condlst.addAll(dost.getConditionExprentList()); + lst.addAll(dost.getInitExprentList()); + lst.addAll(dost.getConditionExprentList()); } } else if (obj instanceof Exprent) { - condlst.add((Exprent)obj); + lst.add((Exprent)obj); } } } else { - condlst = stat.getExprents(); + lst = stat.getExprents(); } - if (retstat != stat) { - for (Exprent exprent : condlst) { - if (exprent != null && searchForClass(exprent, classtype)) { - retstat = stat; + if (retStat != stat) { + for (Exprent exprent : lst) { + if (exprent != null && searchForClass(exprent, classType)) { + retStat = stat; break; } } } - if (retstat != null) { + if (retStat != null) { setStats.add(stat); } - return retstat; + return retStat; } - private static boolean searchForClass(Exprent exprent, VarType classtype) { - + private static boolean searchForClass(Exprent exprent, VarType classType) { List lst = exprent.getAllExprents(true); lst.add(exprent); - String classname = classtype.value; + String classname = classType.value; for (Exprent expr : lst) { - boolean res = false; switch (expr.type) { case Exprent.EXPRENT_CONST: - ConstExprent cexpr = (ConstExprent)expr; - res = (VarType.VARTYPE_CLASS.equals(cexpr.getConstType()) && classname.equals(cexpr.getValue()) || - classtype.equals(cexpr.getConstType())); + ConstExprent constExpr = (ConstExprent)expr; + res = (VarType.VARTYPE_CLASS.equals(constExpr.getConstType()) && classname.equals(constExpr.getValue()) || + classType.equals(constExpr.getConstType())); break; case Exprent.EXPRENT_FIELD: res = classname.equals(((FieldExprent)expr).getClassname()); @@ -988,10 +902,10 @@ public class NestedClassProcessor { res = newType.type == CodeConstants.TYPE_OBJECT && classname.equals(newType.value); break; case Exprent.EXPRENT_VAR: - VarExprent vexpr = (VarExprent)expr; - if (vexpr.isDefinition()) { - VarType vtype = vexpr.getVarType(); - if (classtype.equals(vtype) || (vtype.arrayDim > 0 && classtype.value.equals(vtype.value))) { + VarExprent varExpr = (VarExprent)expr; + if (varExpr.isDefinition()) { + VarType varType = varExpr.getVarType(); + if (classType.equals(varType) || (varType.arrayDim > 0 && classType.value.equals(varType.value))) { res = true; } } @@ -1005,15 +919,13 @@ public class NestedClassProcessor { return false; } - private static class VarFieldPair { + public String fieldKey = ""; + public VarVersionPair varPair; - public String keyfield = ""; - public VarVersionPair varpaar; - - public VarFieldPair(String field, VarVersionPair varpaar) { - this.keyfield = field; - this.varpaar = varpaar; + public VarFieldPair(String field, VarVersionPair varPair) { + this.fieldKey = field; + this.varPair = varPair; } @Override @@ -1022,12 +934,12 @@ public class NestedClassProcessor { if (o == null || !(o instanceof VarFieldPair)) return false; VarFieldPair pair = (VarFieldPair)o; - return keyfield.equals(pair.keyfield) && varpaar.equals(pair.varpaar); + return fieldKey.equals(pair.fieldKey) && varPair.equals(pair.varPair); } @Override public int hashCode() { - return keyfield.hashCode() + varpaar.hashCode(); + return fieldKey.hashCode() + varPair.hashCode(); } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index b5ecd9e..fb0adb7 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -36,7 +36,6 @@ import java.util.List; import java.util.Set; public class NewExprent extends Exprent { - private InvocationExprent constructor; private final VarType newType; private List lstDims = new ArrayList(); @@ -80,12 +79,7 @@ public class NewExprent extends Exprent { @Override public VarType getExprType() { - if (anonymous) { - return DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value).anonymousClassType; - } - else { - return newType; - } + return anonymous ? DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value).anonymousClassType : newType; } @Override @@ -163,24 +157,22 @@ public class NewExprent extends Exprent { TextBuffer buf = new TextBuffer(); if (anonymous) { - ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); buf.append("("); if (!lambda && constructor != null) { + InvocationExprent invSuper = child.superInvocation; - InvocationExprent invsuper = child.superInvocation; - - ClassNode newnode = DecompilerContext.getClassProcessor().getMapRootClasses().get(invsuper.getClassname()); + ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(invSuper.getClassname()); List sigFields = null; - if (newnode != null) { // own class - if (newnode.getWrapper() != null) { - sigFields = newnode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, invsuper.getStringDescriptor()).signatureFields; + if (newNode != null) { // own class + if (newNode.getWrapper() != null) { + sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, invSuper.getStringDescriptor()).signatureFields; } else { - if (newnode.type == ClassNode.CLASS_MEMBER && (newnode.access & CodeConstants.ACC_STATIC) == 0 && + if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && !constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance sigFields = new ArrayList(Collections.nCopies(constructor.getLstParameters().size(), (VarVersionPair)null)); sigFields.set(0, new VarVersionPair(-1, 0)); @@ -188,31 +180,29 @@ public class NewExprent extends Exprent { } } - boolean firstpar = true; - int start = 0, end = invsuper.getLstParameters().size(); + boolean firstParam = true; + int start = 0, end = invSuper.getLstParameters().size(); if (enumConst) { start += 2; end -= 1; } for (int i = start; i < end; i++) { if (sigFields == null || sigFields.get(i) == null) { - if (!firstpar) { + if (!firstParam) { buf.append(", "); } - Exprent param = invsuper.getLstParameters().get(i); + Exprent param = invSuper.getLstParameters().get(i); if (param.type == Exprent.EXPRENT_VAR) { - int varindex = ((VarExprent)param).getIndex(); - if (varindex > 0 && varindex <= constructor.getLstParameters().size()) { - param = constructor.getLstParameters().get(varindex - 1); + int varIndex = ((VarExprent)param).getIndex(); + if (varIndex > 0 && varIndex <= constructor.getLstParameters().size()) { + param = constructor.getLstParameters().get(varIndex - 1); } } - TextBuffer buff = new TextBuffer(); - ExprProcessor.getCastedExprent(param, invsuper.getDescriptor().params[i], buff, indent, true, tracer); + ExprProcessor.getCastedExprent(param, invSuper.getDescriptor().params[i], buf, indent, true, tracer); - buf.append(buff); - firstpar = false; + firstParam = false; } } } @@ -226,14 +216,15 @@ public class NewExprent extends Exprent { String typename = ExprProcessor.getCastTypeName(child.anonymousClassType); if (enclosing != null) { - ClassNode anonimousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value); - if (anonimousNode != null) { - typename = anonimousNode.simpleName; + ClassNode anonymousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value); + if (anonymousNode != null) { + typename = anonymousNode.simpleName; } else { typename = typename.substring(typename.lastIndexOf('.') + 1); } } + buf.prepend("new " + typename); if (enclosing != null) { @@ -275,118 +266,108 @@ public class NewExprent extends Exprent { } buf.append("}"); } - else { - if (newType.arrayDim == 0) { + else if (newType.arrayDim == 0) { + if (constructor != null) { + List lstParameters = constructor.getLstParameters(); - if (constructor != null) { + ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(constructor.getClassname()); - List lstParameters = constructor.getLstParameters(); - - ClassNode newnode = DecompilerContext.getClassProcessor().getMapRootClasses().get(constructor.getClassname()); - - List sigFields = null; - if (newnode != null) { // own class - if (newnode.getWrapper() != null) { - sigFields = newnode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields; - } - else { - if (newnode.type == ClassNode.CLASS_MEMBER && (newnode.access & CodeConstants.ACC_STATIC) == 0 && - !constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance - sigFields = new ArrayList(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); - sigFields.set(0, new VarVersionPair(-1, 0)); - } - } + List sigFields = null; + if (newNode != null) { // own class + if (newNode.getWrapper() != null) { + sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields; } - - int start = enumConst ? 2 : 0; - if (!enumConst || start < lstParameters.size()) { - buf.append("("); - - boolean firstParam = true; - for (int i = start; i < lstParameters.size(); i++) { - if (sigFields == null || sigFields.get(i) == null) { - Exprent expr = lstParameters.get(i); - VarType leftType = constructor.getDescriptor().params[i]; - - if (i == lstParameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL) { - ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(leftType.value); - if (node != null && node.namelessConstructorStub) { - break; // skip last parameter of synthetic constructor call - } - } - - if (!firstParam) { - buf.append(", "); - } - - TextBuffer buff = new TextBuffer(); - ExprProcessor.getCastedExprent(expr, leftType, buff, indent, true, tracer); - buf.append(buff); - - firstParam = false; - } - } - - buf.append(")"); + else if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && !constructor.getLstParameters().isEmpty()) { + // member non-static class invoked with enclosing class instance + sigFields = new ArrayList(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); + sigFields.set(0, new VarVersionPair(-1, 0)); } } - if (!enumConst) { - String enclosing = null; - if (constructor != null) { - enclosing = getQualifiedNewInstance(newType.value, constructor.getLstParameters(), indent, tracer); - } + int start = enumConst ? 2 : 0; + if (!enumConst || start < lstParameters.size()) { + buf.append("("); - String typename = ExprProcessor.getTypeName(newType); + boolean firstParam = true; + for (int i = start; i < lstParameters.size(); i++) { + if (sigFields == null || sigFields.get(i) == null) { + Exprent expr = lstParameters.get(i); + VarType leftType = constructor.getDescriptor().params[i]; - if (enclosing != null) { - ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); - if (newNode != null) { - typename = newNode.simpleName; - } - else { - typename = typename.substring(typename.lastIndexOf('.') + 1); + if (i == lstParameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL) { + ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(leftType.value); + if (node != null && node.namelessConstructorStub) { + break; // skip last parameter of synthetic constructor call + } + } + + if (!firstParam) { + buf.append(", "); + } + + ExprProcessor.getCastedExprent(expr, leftType, buf, indent, true, tracer); + + firstParam = false; } } - buf.prepend("new " + typename); - if (enclosing != null) { - buf.prepend(enclosing + "."); - } + buf.append(")"); } } - else { - buf.append("new ").append(ExprProcessor.getTypeName(newType)); - if (lstArrayElements.isEmpty()) { - for (int i = 0; i < newType.arrayDim; i++) { - buf.append("["); - if (i < lstDims.size()) { - buf.append(lstDims.get(i).toJava(indent, tracer)); - } - buf.append("]"); + if (!enumConst) { + String enclosing = null; + if (constructor != null) { + enclosing = getQualifiedNewInstance(newType.value, constructor.getLstParameters(), indent, tracer); + } + + String typename = ExprProcessor.getTypeName(newType); + + if (enclosing != null) { + ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); + if (newNode != null) { + typename = newNode.simpleName; + } + else { + typename = typename.substring(typename.lastIndexOf('.') + 1); } } - else { - for (int i = 0; i < newType.arrayDim; i++) { - buf.append("[]"); - } + buf.prepend("new " + typename); - VarType leftType = newType.decreaseArrayDim(); - buf.append("{"); - for (int i = 0; i < lstArrayElements.size(); i++) { - if (i > 0) { - buf.append(", "); - } - TextBuffer buff = new TextBuffer(); - ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buff, indent, false, tracer); - - buf.append(buff); - } - buf.append("}"); + if (enclosing != null) { + buf.prepend(enclosing + "."); } } } + else { + buf.append("new ").append(ExprProcessor.getTypeName(newType)); + + if (lstArrayElements.isEmpty()) { + for (int i = 0; i < newType.arrayDim; i++) { + buf.append("["); + if (i < lstDims.size()) { + buf.append(lstDims.get(i).toJava(indent, tracer)); + } + buf.append("]"); + } + } + else { + for (int i = 0; i < newType.arrayDim; i++) { + buf.append("[]"); + } + + VarType leftType = newType.decreaseArrayDim(); + buf.append("{"); + for (int i = 0; i < lstArrayElements.size(); i++) { + if (i > 0) { + buf.append(", "); + } + ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buf, indent, false, tracer); + } + buf.append("}"); + } + } + return buf; } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java index 5969487..3c9f760 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,9 +24,27 @@ import java.util.Collections; import java.util.List; public class StructInnerClassesAttribute extends StructGeneralAttribute { + public static class Entry { + public final int innerNameIdx; + public final int outerNameIdx; + public final int simpleNameIdx; + public final int accessFlags; + public final String innerName; + public final String enclosingName; + public final String simpleName; - private List classEntries; - private List stringEntries; + private Entry(int innerNameIdx, int outerNameIdx, int simpleNameIdx, int accessFlags, String innerName, String enclosingName, String simpleName) { + this.innerNameIdx = innerNameIdx; + this.outerNameIdx = outerNameIdx; + this.simpleNameIdx = simpleNameIdx; + this.accessFlags = accessFlags; + this.innerName = innerName; + this.enclosingName = enclosingName; + this.simpleName = simpleName; + } + } + + private List entries; @Override public void initContent(ConstantPool pool) throws IOException { @@ -34,39 +52,27 @@ public class StructInnerClassesAttribute extends StructGeneralAttribute { int len = data.readUnsignedShort(); if (len > 0) { - classEntries = new ArrayList(len); - stringEntries = new ArrayList(len); + entries = new ArrayList(len); for (int i = 0; i < len; i++) { - int[] classEntry = new int[4]; - for (int j = 0; j < 4; j++) { - classEntry[j] = data.readUnsignedShort(); - } - classEntries.add(classEntry); + int innerNameIdx = data.readUnsignedShort(); + int outerNameIdx = data.readUnsignedShort(); + int simpleNameIdx = data.readUnsignedShort(); + int accessFlags = data.readUnsignedShort(); - // inner name, enclosing class, original simple name - String[] stringEntry = new String[3]; - stringEntry[0] = pool.getPrimitiveConstant(classEntry[0]).getString(); - if (classEntry[1] != 0) { - stringEntry[1] = pool.getPrimitiveConstant(classEntry[1]).getString(); - } - if (classEntry[2] != 0) { - stringEntry[2] = pool.getPrimitiveConstant(classEntry[2]).getString(); - } - stringEntries.add(stringEntry); + String innerName = pool.getPrimitiveConstant(innerNameIdx).getString(); + String outerName = outerNameIdx != 0 ? pool.getPrimitiveConstant(outerNameIdx).getString() : null; + String simpleName = simpleNameIdx != 0 ? pool.getPrimitiveConstant(simpleNameIdx).getString() : null; + + entries.add(new Entry(innerNameIdx, outerNameIdx, simpleNameIdx, accessFlags, innerName, outerName, simpleName)); } } else { - classEntries = Collections.emptyList(); - stringEntries = Collections.emptyList(); + entries = Collections.emptyList(); } } - public List getClassEntries() { - return classEntries; - } - - public List getStringEntries() { - return stringEntries; + public List getEntries() { + return entries; } } diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java index b965009..8ec1aaa 100644 --- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -120,25 +120,6 @@ public class InterpreterUtil { return first == null ? second == null : first.equals(second); } - public static boolean equalObjectArrays(Object[] first, Object[] second) { - if (first == null || second == null) { - return equalObjects(first, second); - } - else { - if (first.length != second.length) { - return false; - } - - for (int i = 0; i < first.length; i++) { - if (!equalObjects(first[i], second[i])) { - return false; - } - } - } - - return true; - } - public static boolean equalLists(List first, List second) { if (first == null) { return second == null; @@ -172,6 +153,10 @@ public class InterpreterUtil { } public static String makeUniqueKey(String name, String descriptor) { - return name + " " + descriptor; + return name + ' ' + descriptor; + } + + public static String makeUniqueKey(String name, String descriptor1, String descriptor2) { + return name + ' ' + descriptor1 + ' ' + descriptor2; } } From 1794156473bf72a83dc5644333234d922f0d0a4f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 11 Nov 2015 16:25:11 +0100 Subject: [PATCH 012/252] [java-decompiler] synthetic inner class constructor parameter filtering (IDEA-147606) --- .../main/rels/NestedClassProcessor.java | 32 ++++++---- .../pkg/TestInnerClassConstructor$1.class | Bin 234 -> 231 bytes .../TestInnerClassConstructor$Another.class | Bin 0 -> 856 bytes .../pkg/TestInnerClassConstructor$Inner.class | Bin 671 -> 668 bytes .../pkg/TestInnerClassConstructor.class | Bin 886 -> 1081 bytes .../v11/TestInnerClassConstructor$1.class | Bin 206 -> 224 bytes .../TestInnerClassConstructor$Another.class | Bin 0 -> 880 bytes .../v11/TestInnerClassConstructor$Inner.class | Bin 695 -> 695 bytes .../v11/TestInnerClassConstructor.class | Bin 880 -> 1086 bytes .../results/TestInnerClassConstructor.dec | 60 +++++++++++++----- .../src/pkg/TestInnerClassConstructor.java | 12 +++- 11 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 testData/classes/pkg/TestInnerClassConstructor$Another.class create mode 100644 testData/classes/v11/TestInnerClassConstructor$Another.class diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 6963f1d..c529a44 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -65,9 +65,9 @@ public class NestedClassProcessor { int nameless = 0, synthetics = 0; for (ClassNode child : node.nested) { + StructClass cl = child.classStruct; // ensure not-empty class name if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_MEMBER) && child.simpleName == null) { - StructClass cl = child.classStruct; if ((child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) { child.simpleName = "SyntheticClass_" + (++synthetics); } @@ -78,6 +78,9 @@ public class NestedClassProcessor { } child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0; } + else if (child.type == ClassNode.CLASS_ANONYMOUS && (child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) { + child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0; + } } for (ClassNode child : node.nested) { @@ -180,10 +183,14 @@ public class NestedClassProcessor { List copy = new ArrayList(node.nested); for (ClassNode child : copy) { + if (child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { + continue; + } + if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_ANONYMOUS) && child.enclosingMethod == null) { Set setEnclosing = child.enclosingClasses; - if (setEnclosing.size() == 1) { + if (!setEnclosing.isEmpty()) { StructEnclosingMethodAttribute attr = (StructEnclosingMethodAttribute)child.classStruct.getAttributes().getWithKey("EnclosingMethod"); if (attr != null && @@ -199,17 +206,12 @@ public class NestedClassProcessor { child.parent = null; setEnclosing.remove(node.classStruct.qualifiedName); - boolean hasEnclosing = !setEnclosing.isEmpty(); - if (hasEnclosing) { - hasEnclosing = insertNestedClass(root, child); - } + boolean hasEnclosing = !setEnclosing.isEmpty() && insertNestedClass(root, child); if (!hasEnclosing) { if (child.type == ClassNode.CLASS_ANONYMOUS) { - if (!child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { - String message = "Unreferenced anonymous class " + child.classStruct.qualifiedName + "!"; - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); - } + String message = "Unreferenced anonymous class " + child.classStruct.qualifiedName + "!"; + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } else if (child.type == ClassNode.CLASS_LOCAL) { String message = "Unreferenced local class " + child.classStruct.qualifiedName + "!"; @@ -251,6 +253,10 @@ public class NestedClassProcessor { int clTypes = 0; for (ClassNode nd : node.nested) { + if (nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { + continue; + } + if (nd.type != ClassNode.CLASS_LAMBDA && (nd.access & CodeConstants.ACC_STATIC) == 0 && (nd.access & CodeConstants.ACC_INTERFACE) == 0) { @@ -258,10 +264,8 @@ public class NestedClassProcessor { Map> mask = getMaskLocalVars(nd.getWrapper()); if (mask.isEmpty()) { - if (!nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { - String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!"; - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); - } + String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!"; + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } else { mapVarMasks.put(nd.classStruct.qualifiedName, mask); diff --git a/testData/classes/pkg/TestInnerClassConstructor$1.class b/testData/classes/pkg/TestInnerClassConstructor$1.class index 384ce5d4577bd4552a2b6956d2ae76ecf26ffa18..07172b9a8804ea82bb1ac365a26af77275b5879d 100644 GIT binary patch delta 54 zcmaFG_?%JT)W2Q(7#J8#7`WLP*x4C4Cki;Ra4|B-Pn;{uq+&R+BAK59D9y#d2!uc& GzySbo`U%?r delta 61 zcmaFP_=-{B)W2Q(7#J9g8F<(k*x4DlCJH!la5FN<7i6dFPgIa(RWW2_V3=5%%+Co_ O#l^q~glr590vrIt(hAuC diff --git a/testData/classes/pkg/TestInnerClassConstructor$Another.class b/testData/classes/pkg/TestInnerClassConstructor$Another.class new file mode 100644 index 0000000000000000000000000000000000000000..5178a8fb69c55046581f2e931144727cedd2c4f3 GIT binary patch literal 856 zcmah{?@QZI6g{`CO&X)d&fm7$&2&qfX(#MkhoD8FQ1pW$_%UrCH7<`!M$_Iu;^qt=Z`RaZ)pbfO?lJF!evG8w2iX*2a*C_{BZaJ?tE z-EQNSQ0T-%L0IX9Qd~|x^hI(L^dn)QPO#@DA|;$Zt(a};9=ElnbsbNVfw%}GHs1U1 zWsV+#kAaO9I5w8BtkFxtrvBQB0y%13t0a`8vq=~YMPlO>JOcR|G;B2C8+dKw5J!Z1 z=G5F%8LNAd5R5;_ncH0TAH+cM?6XCV33*RnuNaKSLJkQPuiNO&b^dCX|J0%P=&+r| zH&y&gg0SX2CbD8RvqK(^B&`3-^_G`yk@pcG$I-)Pl;ekI55g+Hog>d%3DleZXXKhQ zTaWrg7kd&t)=no*elv}YWl1ChMbJ4Bt(Q_f6>R* VqbWqJDG9QrP%cX1L@sJp#6RY#4+a1L diff --git a/testData/classes/pkg/TestInnerClassConstructor.class b/testData/classes/pkg/TestInnerClassConstructor.class index fb0d8989730ab54ff28ba8910d7d1e9ab98c7c4f..6a4810977c54f3006d49d15e74ff4e65928b43d7 100644 GIT binary patch delta 508 zcmZXQ%St0r5Qe|%PWp7(PK+_$O}uLo$IEyhXAneOWamoB(nUZ)q9oa8<6c6ZL>CF8 z-~+f(d>C;xSlx&tdf?Pw=kon^PQ5sP-NwVe+k0S*ZI5oUhB23M4~q%Iq(_vg7}Lxc zW<6Z8E^~qAf{^zpFmL!_STHOKez8(1SNG12YqfGsFuRrW`boJeM8gBY`Ey!1t?vkS zE`KOQ_RgCZ19H~9JaE$V2~({n$u?gTx>^!uf>rw6#3#+N;iu0EtF0cH?p&1^_L!XwQy$GoNy5l{frJ$%X-=1ygRr%3KB|+rj5PS7F4m2(AIPeYpmO2)hcbU zY1m?0vtuN`tfqe`cL&m3q+lv{CjLq9L`sL!ha<=9ifwONWLRIBpOoqpOB~WomCN+N0nGG5mt1$ KaVX3%LHq^e%q9>3 diff --git a/testData/classes/v11/TestInnerClassConstructor$1.class b/testData/classes/v11/TestInnerClassConstructor$1.class index b11a30e153220b083b2262397ec5df205ba94cff..fad6e4e7f4f46628e12b2c2e25d7ddcd25c00e1b 100644 GIT binary patch delta 75 zcmX@d_<&L1)W2Q(7?>G!8F<(k*x4DlCJN~BGcs@nSLT&uq?TkRvoml{bS#l)2C89T YU}9ilUG!8MxUQ*w`63Ckp5>voml_^evHO0*W&*Ffp(&Z~$p821X!c H1+o|bUF`?U diff --git a/testData/classes/v11/TestInnerClassConstructor$Another.class b/testData/classes/v11/TestInnerClassConstructor$Another.class new file mode 100644 index 0000000000000000000000000000000000000000..61d71db360eb86036f2920a316203a8f7e279245 GIT binary patch literal 880 zcmah|T~8WO5IwW3EUa6l)S@k*)-LS=D)LOz#1fm3koEy%(#Hj_xQchl?xl%8%ZEbJ zCjJ0_RMWYdh>3O0CiAs(=FFYB_vY{KYoxG)rj13swc((cWvgVNY{NuRi}egPwBFR> zosBKLx8Pd%KuD|8Aa?f%8{P5wuyH72)sa#}?U5hH?NG)lnhaDJwFueXrBtUv1p|hC z3S^)@6I|~ZT&Gh#BAD&)SP+)GffU~+7kv>O`u&lx@R0z5Gv^dB;o$kA$*gX(rCIG> zIEe=0YcOK&^(W7^d*=W29pvy*3(vs|ED;Ji+8FtA*yyP!ki##NlM@j+sG>%ox;9vB zW5>d-g9dnrmBbmk`!eJKMg;5L%FS86_s_&Y@g|asGzlqBpDyi>$3h+xie9JMo!5ET zEw63cd-SiBke*TDT>-+1_c)IWmJ|Eq(MZDU|B)VHlW(R2z45#rGV5jb0E0gs|7{#N z;0tYXv{IYFsMUWVRsRF?#|#UlDbjgsicFb}DY8@8SDZ+A#d3*Zz$&s>gNrw8=h!ot q3QTNbfpw-|3{ngN0Enywr~m)} delta 37 rcmdnax}9}HBoiku11AF?5b{q>V$xycncUAL&&j~R${@}l#UKCxhWrJP diff --git a/testData/classes/v11/TestInnerClassConstructor.class b/testData/classes/v11/TestInnerClassConstructor.class index 9cbad7f8e6e0ca2762bab8a9b4aae003965c3e4e..b203edf2f2b92bcc8d835a7af96e2be831d14eee 100644 GIT binary patch delta 486 zcmZ9J%T60X5JgXoJ=5dK*t|n9*gVX`HkfDZ@Q5OXC=2gcfmlY0C6K^Km^~Zz$eJ&K zg)L!;56A+<2k;LpSs|)p6r{A&eY?8q-n!lWs$maf@x_N;kqM zUG3%3Cy8qzjC9MRM<;v!o^=WFG@Je>R?ygrB|EtLMbAhZZ|{H6gwg^n8f8q2t%r&> zvhC8>m=6Aan?!%m;={bo7GaCzyGFU|EUBJSO3EnBAxpodt4yz+qTk{w4rs&cDtRB+`>*X|%XPIM52vK&;OBIXCVhZgs>QxHGf@CMZ zG}dTpO$T=K-gL~D#7-a{SfnaW13D3~>D1pSeBfM-(V?5+btE$UjG2G>l;Kg!X*HR$ Rs8bdVr78*A97}YL@*lWTDI5R* diff --git a/testData/results/TestInnerClassConstructor.dec b/testData/results/TestInnerClassConstructor.dec index 235d50f..f15701a 100644 --- a/testData/results/TestInnerClassConstructor.dec +++ b/testData/results/TestInnerClassConstructor.dec @@ -1,40 +1,65 @@ package pkg; class TestInnerClassConstructor { - void m() { + void l() { new TestInnerClassConstructor.Inner("text");// 5 }// 6 - void n(String var1) { - System.out.println("n(): " + var1);// 9 + void m() { + new TestInnerClassConstructor.Another(3, 4);// 9 }// 10 + void n(String var1) { + System.out.println("n(): " + var1);// 13 + }// 14 + + private class Another { + private Another(int var2, int var3) { + TestInnerClassConstructor.this.n(var2 + "+" + var3);// 24 + }// 25 + } + final class Inner { private Inner(String var2) { - TestInnerClassConstructor.this.n(var2);// 14 - }// 15 + TestInnerClassConstructor.this.n(var2);// 18 + }// 19 } } class 'pkg/TestInnerClassConstructor' { - method 'm ()V' { + method 'l ()V' { 5 4 c 5 } + method 'm ()V' { + 5 8 + 6 8 + c 9 + } + method 'n (Ljava/lang/String;)V' { - 0 8 - a 8 - 13 8 - 16 8 - 19 9 + 0 12 + a 12 + 13 12 + 16 12 + 19 13 + } +} + +class 'pkg/TestInnerClassConstructor$Another' { + method ' (Lpkg/TestInnerClassConstructor;II)V' { + 15 17 + 1e 17 + 21 17 + 24 18 } } class 'pkg/TestInnerClassConstructor$Inner' { method ' (Lpkg/TestInnerClassConstructor;Ljava/lang/String;)V' { - b 13 - e 14 + b 23 + e 24 } } @@ -43,7 +68,12 @@ Lines mapping: 6 <-> 6 9 <-> 9 10 <-> 10 +13 <-> 13 14 <-> 14 -15 <-> 15 +18 <-> 24 +19 <-> 25 +24 <-> 18 +25 <-> 19 Not mapped: -13 +17 +23 diff --git a/testData/src/pkg/TestInnerClassConstructor.java b/testData/src/pkg/TestInnerClassConstructor.java index e42c319..ccc33ff 100644 --- a/testData/src/pkg/TestInnerClassConstructor.java +++ b/testData/src/pkg/TestInnerClassConstructor.java @@ -1,10 +1,14 @@ package pkg; class TestInnerClassConstructor { - void m() { + void l() { new Inner("text"); } + void m() { + new Another(3, 4); + } + void n(String s) { System.out.println("n(): " + s); } @@ -14,4 +18,10 @@ class TestInnerClassConstructor { n(s); } } + + private class Another { + private Another(int a, int b) { + n(a + "+" + b); + } + } } From a725e5b7b6fa328083ae783b8838309f9c4f48e9 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 28 Dec 2015 15:23:16 +0100 Subject: [PATCH 013/252] Cleanup (java decompiler test optimization) --- .../decompiler/BulkDecompilationTest.java | 2 +- .../decompiler/DecompilerTestFixture.java | 31 +++--- .../java/decompiler/SingleClassesTest.java | 81 ++++++++++++++-- .../decompiler/SingleClassesTestBase.java | 97 ------------------- 4 files changed, 88 insertions(+), 123 deletions(-) delete mode 100644 test/org/jetbrains/java/decompiler/SingleClassesTestBase.java diff --git a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java index 0211a57..31778cb 100644 --- a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java +++ b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java @@ -94,4 +94,4 @@ public class BulkDecompilationTest { throw new RuntimeException(e); } } -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java index ad36548..b3385e2 100644 --- a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java +++ b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java @@ -22,10 +22,10 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.io.File; import java.io.IOException; -import java.util.Collections; import java.util.HashMap; import java.util.Map; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; @@ -35,11 +35,9 @@ public class DecompilerTestFixture { private File targetDir; private ConsoleDecompiler decompiler; - public void setUp() throws IOException { - setUp(Collections.emptyMap()); - } + public void setUp(String... optionPairs) throws IOException { + assertEquals(0, optionPairs.length % 2); - public void setUp(final Map options) throws IOException { testDataDir = new File("testData"); if (!isTestDataDir(testDataDir)) testDataDir = new File("community/plugins/java-decompiler/engine/testData"); if (!isTestDataDir(testDataDir)) testDataDir = new File("plugins/java-decompiler/engine/testData"); @@ -54,15 +52,18 @@ public class DecompilerTestFixture { targetDir = new File(tempDir, "decompiled"); assertTrue(targetDir.mkdirs()); - decompiler = new ConsoleDecompiler(this.targetDir, new HashMap() {{ - put(IFernflowerPreferences.LOG_LEVEL, "warn"); - put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1"); - put(IFernflowerPreferences.REMOVE_SYNTHETIC, "1"); - put(IFernflowerPreferences.REMOVE_BRIDGE, "1"); - put(IFernflowerPreferences.LITERALS_AS_IS, "1"); - put(IFernflowerPreferences.UNIT_TEST_MODE, "1"); - putAll(options); - }}); + + Map options = new HashMap(); + options.put(IFernflowerPreferences.LOG_LEVEL, "warn"); + options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1"); + options.put(IFernflowerPreferences.REMOVE_SYNTHETIC, "1"); + options.put(IFernflowerPreferences.REMOVE_BRIDGE, "1"); + options.put(IFernflowerPreferences.LITERALS_AS_IS, "1"); + options.put(IFernflowerPreferences.UNIT_TEST_MODE, "1"); + for (int i = 0; i < optionPairs.length; i += 2) { + options.put(optionPairs[i], optionPairs[i + 1]); + } + decompiler = new ConsoleDecompiler(targetDir, options); } public void tearDown() { @@ -121,4 +122,4 @@ public class DecompilerTestFixture { throw new RuntimeException(e); } } -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 0da0d3b..1ab4ea2 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -15,19 +15,34 @@ */ package org.jetbrains.java.decompiler; +import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.junit.After; +import org.junit.Before; import org.junit.Test; -import java.util.HashMap; -import java.util.Map; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.*; -public class SingleClassesTest extends SingleClassesTestBase { - @Override - protected Map getDecompilerOptions() { - return new HashMap() {{ - put(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1"); - put(IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1"); - }}; +import static org.jetbrains.java.decompiler.DecompilerTestFixture.assertFilesEqual; +import static org.junit.Assert.assertTrue; + +public class SingleClassesTest { + private DecompilerTestFixture fixture; + + @Before + public void setUp() throws IOException { + fixture = new DecompilerTestFixture(); + fixture.setUp(IFernflowerPreferences.BYTECODE_SOURCE_MAPPING, "1", + IFernflowerPreferences.DUMP_ORIGINAL_LINES, "1"); + } + + @After + public void tearDown() { + fixture.tearDown(); + fixture = null; } @Test public void testClassFields() { doTest("pkg/TestClassFields"); } @@ -62,4 +77,50 @@ public class SingleClassesTest extends SingleClassesTestBase { @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } -} + + protected void doTest(String testFile, String... companionFiles) { + ConsoleDecompiler decompiler = fixture.getDecompiler(); + + File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); + assertTrue(classFile.isFile()); + for (File file : collectClasses(classFile)) { + decompiler.addSpace(file, true); + } + + for (String companionFile : companionFiles) { + File companionClassFile = new File(fixture.getTestDataDir(), "/classes/" + companionFile + ".class"); + assertTrue(companionClassFile.isFile()); + for (File file : collectClasses(companionClassFile)) { + decompiler.addSpace(file, true); + } + } + + decompiler.decompileContext(); + + String testName = classFile.getName().substring(0, classFile.getName().length() - 6); + File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); + assertTrue(decompiledFile.isFile()); + File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); + assertTrue(referenceFile.isFile()); + assertFilesEqual(referenceFile, decompiledFile); + } + + private static List collectClasses(File classFile) { + List files = new ArrayList(); + files.add(classFile); + + File parent = classFile.getParentFile(); + if (parent != null) { + final String pattern = classFile.getName().replace(".class", "") + "\\$.+\\.class"; + File[] inner = parent.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.matches(pattern); + } + }); + if (inner != null) Collections.addAll(files, inner); + } + + return files; + } +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java b/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java deleted file mode 100644 index 0601f0e..0000000 --- a/test/org/jetbrains/java/decompiler/SingleClassesTestBase.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2000-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.java.decompiler; - -import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; -import org.junit.After; -import org.junit.Before; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import static org.jetbrains.java.decompiler.DecompilerTestFixture.assertFilesEqual; -import static org.junit.Assert.assertTrue; - -public abstract class SingleClassesTestBase { - private DecompilerTestFixture fixture; - - @Before - public void setUp() throws IOException { - fixture = new DecompilerTestFixture(); - fixture.setUp(getDecompilerOptions()); - } - - @After - public void tearDown() { - fixture.tearDown(); - fixture = null; - } - - protected Map getDecompilerOptions() { - return Collections.emptyMap(); - } - - protected void doTest(String testFile, String... companionFiles) { - ConsoleDecompiler decompiler = fixture.getDecompiler(); - - File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); - assertTrue(classFile.isFile()); - for (File file : collectClasses(classFile)) { - decompiler.addSpace(file, true); - } - - for (String companionFile : companionFiles) { - File companionClassFile = new File(fixture.getTestDataDir(), "/classes/" + companionFile + ".class"); - assertTrue(companionClassFile.isFile()); - for (File file : collectClasses(companionClassFile)) { - decompiler.addSpace(file, true); - } - } - - decompiler.decompileContext(); - - String testName = classFile.getName().substring(0, classFile.getName().length() - 6); - File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); - assertTrue(decompiledFile.isFile()); - File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); - assertTrue(referenceFile.isFile()); - assertFilesEqual(referenceFile, decompiledFile); - } - - private static List collectClasses(File classFile) { - List files = new ArrayList(); - files.add(classFile); - - File parent = classFile.getParentFile(); - if (parent != null) { - final String pattern = classFile.getName().replace(".class", "") + "\\$.+\\.class"; - File[] inner = parent.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.matches(pattern); - } - }); - if (inner != null) Collections.addAll(files, inner); - } - - return files; - } -} From 811494ccb28c0cd4b40834c58bd6512dfad3f1ca Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 28 Dec 2015 16:36:40 +0100 Subject: [PATCH 014/252] [java decompiler] "new" expression writer optimization --- .../modules/decompiler/exps/NewExprent.java | 119 +++++++++--------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index fb0adb7..1edd0e4 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -159,7 +159,32 @@ public class NewExprent extends Exprent { if (anonymous) { ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); - buf.append("("); + if (!enumConst) { + String enclosing = null; + + if (!lambda && constructor != null) { + enclosing = getQualifiedNewInstance(child.anonymousClassType.value, constructor.getLstParameters(), indent, tracer); + if (enclosing != null) { + buf.append(enclosing).append('.'); + } + } + + buf.append("new "); + + String typename = ExprProcessor.getCastTypeName(child.anonymousClassType); + if (enclosing != null) { + ClassNode anonymousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value); + if (anonymousNode != null) { + typename = anonymousNode.simpleName; + } + else { + typename = typename.substring(typename.lastIndexOf('.') + 1); + } + } + buf.append(typename); + } + + buf.append('('); if (!lambda && constructor != null) { InvocationExprent invSuper = child.superInvocation; @@ -207,32 +232,7 @@ public class NewExprent extends Exprent { } } - if (!enumConst) { - String enclosing = null; - if (!lambda && constructor != null) { - enclosing = getQualifiedNewInstance(child.anonymousClassType.value, constructor.getLstParameters(), indent, tracer); - } - - String typename = ExprProcessor.getCastTypeName(child.anonymousClassType); - - if (enclosing != null) { - ClassNode anonymousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value); - if (anonymousNode != null) { - typename = anonymousNode.simpleName; - } - else { - typename = typename.substring(typename.lastIndexOf('.') + 1); - } - } - - buf.prepend("new " + typename); - - if (enclosing != null) { - buf.prepend(enclosing + "."); - } - } - - buf.append(")"); + buf.append(')'); if (enumConst && buf.length() == 2) { buf.setLength(0); @@ -257,16 +257,41 @@ public class NewExprent extends Exprent { } else if (directArrayInit) { VarType leftType = newType.decreaseArrayDim(); - buf.append("{"); + buf.append('{'); for (int i = 0; i < lstArrayElements.size(); i++) { if (i > 0) { buf.append(", "); } ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buf, indent, false, tracer); } - buf.append("}"); + buf.append('}'); } else if (newType.arrayDim == 0) { + if (!enumConst) { + String enclosing = null; + + if (constructor != null) { + enclosing = getQualifiedNewInstance(newType.value, constructor.getLstParameters(), indent, tracer); + if (enclosing != null) { + buf.append(enclosing).append('.'); + } + } + + buf.append("new "); + + String typename = ExprProcessor.getTypeName(newType); + if (enclosing != null) { + ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); + if (newNode != null) { + typename = newNode.simpleName; + } + else { + typename = typename.substring(typename.lastIndexOf('.') + 1); + } + } + buf.append(typename); + } + if (constructor != null) { List lstParameters = constructor.getLstParameters(); @@ -286,7 +311,7 @@ public class NewExprent extends Exprent { int start = enumConst ? 2 : 0; if (!enumConst || start < lstParameters.size()) { - buf.append("("); + buf.append('('); boolean firstParam = true; for (int i = start; i < lstParameters.size(); i++) { @@ -311,31 +336,7 @@ public class NewExprent extends Exprent { } } - buf.append(")"); - } - } - - if (!enumConst) { - String enclosing = null; - if (constructor != null) { - enclosing = getQualifiedNewInstance(newType.value, constructor.getLstParameters(), indent, tracer); - } - - String typename = ExprProcessor.getTypeName(newType); - - if (enclosing != null) { - ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); - if (newNode != null) { - typename = newNode.simpleName; - } - else { - typename = typename.substring(typename.lastIndexOf('.') + 1); - } - } - buf.prepend("new " + typename); - - if (enclosing != null) { - buf.prepend(enclosing + "."); + buf.append(')'); } } } @@ -344,11 +345,11 @@ public class NewExprent extends Exprent { if (lstArrayElements.isEmpty()) { for (int i = 0; i < newType.arrayDim; i++) { - buf.append("["); + buf.append('['); if (i < lstDims.size()) { buf.append(lstDims.get(i).toJava(indent, tracer)); } - buf.append("]"); + buf.append(']'); } } else { @@ -357,14 +358,14 @@ public class NewExprent extends Exprent { } VarType leftType = newType.decreaseArrayDim(); - buf.append("{"); + buf.append('{'); for (int i = 0; i < lstArrayElements.size(); i++) { if (i > 0) { buf.append(", "); } ExprProcessor.getCastedExprent(lstArrayElements.get(i), leftType, buf, indent, false, tracer); } - buf.append("}"); + buf.append('}'); } } From bfddced4e257b1259865151c54669f3eab095eb9 Mon Sep 17 00:00:00 2001 From: Christopher Carpenter Date: Thu, 21 Jan 2016 01:06:45 -0500 Subject: [PATCH 015/252] Fixed renaming class elements when using the decompilers -ren=1 option. Fixes issue IDEA-137253 --- .../java/decompiler/struct/consts/ConstantPool.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java index aa9ed9c..097440b 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java @@ -150,6 +150,11 @@ public class ConstantPool implements NewClassNameBuilder { String descriptor = ((PrimitiveConstant)getConstant(descriptorIndex)).getString(); if (interceptor != null) { + String oldClassName = interceptor.getOldName(className); + if (oldClassName != null) { + className = oldClassName; + } + String newElement = interceptor.getName(className + " " + elementName + " " + descriptor); if (newElement != null) { elementName = newElement.split(" ")[1]; From c825dd68ecd7ad0880f1187c4de97787577ff43b Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 27 Jan 2016 19:06:07 +0300 Subject: [PATCH 016/252] Cleanup (formatting; minor optimization) --- .../struct/consts/ConstantPool.java | 58 +++++++++++-------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java index 097440b..5d9b881 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,20 +27,21 @@ import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.BitSet; import java.util.List; +@SuppressWarnings("AssignmentToForLoopParameter") public class ConstantPool implements NewClassNameBuilder { - public static final int FIELD = 1; public static final int METHOD = 2; - private final List pool = new ArrayList(); + private final List pool; private final PoolInterceptor interceptor; - public ConstantPool(DataInputStream in) throws IOException { int size = in.readUnsignedShort(); - int[] pass = new int[size]; + pool = new ArrayList(size); + BitSet[] nextPass = {new BitSet(size), new BitSet(size), new BitSet(size)}; // first dummy constant pool.add(null); @@ -53,54 +54,59 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_Utf8: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Utf8, in.readUTF())); break; + case CodeConstants.CONSTANT_Integer: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Integer, new Integer(in.readInt()))); break; + case CodeConstants.CONSTANT_Float: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Float, new Float(in.readFloat()))); break; + case CodeConstants.CONSTANT_Long: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Long, new Long(in.readLong()))); pool.add(null); i++; break; + case CodeConstants.CONSTANT_Double: pool.add(new PrimitiveConstant(CodeConstants.CONSTANT_Double, new Double(in.readDouble()))); pool.add(null); i++; break; + case CodeConstants.CONSTANT_Class: case CodeConstants.CONSTANT_String: case CodeConstants.CONSTANT_MethodType: pool.add(new PrimitiveConstant(tag, in.readUnsignedShort())); - pass[i] = 1; + nextPass[0].set(i); break; + + case CodeConstants.CONSTANT_NameAndType: + pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort())); + nextPass[0].set(i); + break; + case CodeConstants.CONSTANT_Fieldref: case CodeConstants.CONSTANT_Methodref: case CodeConstants.CONSTANT_InterfaceMethodref: - case CodeConstants.CONSTANT_NameAndType: case CodeConstants.CONSTANT_InvokeDynamic: pool.add(new LinkConstant(tag, in.readUnsignedShort(), in.readUnsignedShort())); - if (tag == CodeConstants.CONSTANT_NameAndType) { - pass[i] = 1; - } - else { - pass[i] = 2; - } + nextPass[1].set(i); break; + case CodeConstants.CONSTANT_MethodHandle: pool.add(new LinkConstant(tag, in.readUnsignedByte(), in.readUnsignedShort())); - pass[i] = 3; + nextPass[2].set(i); break; } } // resolving complex pool elements - for (int passIndex = 1; passIndex <= 3; passIndex++) { - for (int i = 1; i < size; i++) { - if (pass[i] == passIndex) { - pool.get(i).resolveConstant(this); - } + for (BitSet pass : nextPass) { + int idx = 0; + while ((idx = pass.nextSetBit(idx + 1)) > 0) { + pool.get(idx).resolveConstant(this); } } @@ -116,6 +122,7 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_Utf8: in.readUTF(); break; + case CodeConstants.CONSTANT_Integer: case CodeConstants.CONSTANT_Float: case CodeConstants.CONSTANT_Fieldref: @@ -125,16 +132,19 @@ public class ConstantPool implements NewClassNameBuilder { case CodeConstants.CONSTANT_InvokeDynamic: in.discard(4); break; + case CodeConstants.CONSTANT_Long: case CodeConstants.CONSTANT_Double: in.discard(8); i++; break; + case CodeConstants.CONSTANT_Class: case CodeConstants.CONSTANT_String: case CodeConstants.CONSTANT_MethodType: in.discard(2); break; + case CodeConstants.CONSTANT_MethodHandle: in.discard(3); } @@ -155,7 +165,7 @@ public class ConstantPool implements NewClassNameBuilder { className = oldClassName; } - String newElement = interceptor.getName(className + " " + elementName + " " + descriptor); + String newElement = interceptor.getName(className + ' ' + elementName + ' ' + descriptor); if (newElement != null) { elementName = newElement.split(" ")[1]; } @@ -196,7 +206,7 @@ public class ConstantPool implements NewClassNameBuilder { ln.type == CodeConstants.CONSTANT_Methodref || ln.type == CodeConstants.CONSTANT_InterfaceMethodref)) { String newClassName = buildNewClassname(ln.classname); - String newElement = interceptor.getName(ln.classname + " " + ln.elementname + " " + ln.descriptor); + String newElement = interceptor.getName(ln.classname + ' ' + ln.elementname + ' ' + ln.descriptor); String newDescriptor = buildNewDescriptor(ln.type == CodeConstants.CONSTANT_Fieldref, ln.descriptor); if (newClassName != null || newElement != null || newDescriptor != null) { @@ -220,10 +230,10 @@ public class ConstantPool implements NewClassNameBuilder { if (vt.arrayDim > 0) { for (int i = 0; i < vt.arrayDim; i++) { - buffer.append("["); + buffer.append('['); } - buffer.append("L").append(newName).append(";"); + buffer.append('L').append(newName).append(';'); } else { buffer.append(newName); @@ -243,4 +253,4 @@ public class ConstantPool implements NewClassNameBuilder { return MethodDescriptor.parseDescriptor(descriptor).buildNewDescriptor(this); } } -} +} \ No newline at end of file From 233a1547a053cdb8507a2d8d6f8f6847f8326fef Mon Sep 17 00:00:00 2001 From: Christopher Carpenter Date: Tue, 2 Feb 2016 22:40:00 -0500 Subject: [PATCH 017/252] [Fernflower] When using -ren=1, make the default renamer rename classes that have names that are reserved by the windows namespace. --- .../java/decompiler/modules/renamer/ConverterHelper.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java b/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java index 5912e6e..8a431df 100644 --- a/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java @@ -28,6 +28,10 @@ public class ConverterHelper implements IIdentifierRenamer { "protected", "throw", "byte", "extends", "instanceof", "public", "throws", "case", "false", "int", "return", "transient", "catch", "final", "interface", "short", "true", "char", "finally", "long", "static", "try", "class", "float", "native", "strictfp", "void", "const", "for", "new", "super", "volatile", "continue", "goto", "null", "switch", "while", "default", "assert", "enum")); + private static final Set RESERVED_WINDOWS_NAMESPACE = new HashSet(Arrays.asList( + "aux", "prn", "aux", "nul", + "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", + "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9")); private int classCounter = 0; private int fieldCounter = 0; @@ -37,7 +41,8 @@ public class ConverterHelper implements IIdentifierRenamer { @Override public boolean toBeRenamed(Type elementType, String className, String element, String descriptor) { String value = elementType == Type.ELEMENT_CLASS ? className : element; - return value == null || value.length() == 0 || value.length() <= 2 || KEYWORDS.contains(value) || Character.isDigit(value.charAt(0)); + return value == null || value.length() == 0 || value.length() <= 2 || KEYWORDS.contains(value) || Character.isDigit(value.charAt(0)) + || elementType == Type.ELEMENT_CLASS && RESERVED_WINDOWS_NAMESPACE.contains(value.toLowerCase()); } // TODO: consider possible conflicts with not renamed classes, fields and methods! From 94851b6cbbbb81b36073990a83d61eb3646cb9c4 Mon Sep 17 00:00:00 2001 From: Christopher Carpenter Date: Wed, 3 Feb 2016 16:30:06 -0500 Subject: [PATCH 018/252] Added a TODO regarding IDEA-137253. --- .../jetbrains/java/decompiler/struct/consts/ConstantPool.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java index 5d9b881..a204910 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java @@ -208,7 +208,8 @@ public class ConstantPool implements NewClassNameBuilder { String newClassName = buildNewClassname(ln.classname); String newElement = interceptor.getName(ln.classname + ' ' + ln.elementname + ' ' + ln.descriptor); String newDescriptor = buildNewDescriptor(ln.type == CodeConstants.CONSTANT_Fieldref, ln.descriptor); - + //TODO: Fix newElement being null caused by ln.classname being a leaf class instead of the class that declared the field/method. + //See the comments of IDEA-137253 for more information. if (newClassName != null || newElement != null || newDescriptor != null) { String className = newClassName == null ? ln.classname : newClassName; String elementName = newElement == null ? ln.elementname : newElement.split(" ")[1]; From ec51c10d08f92a708de26bf68509d20a9e456298 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 29 Feb 2016 15:31:12 +0300 Subject: [PATCH 019/252] decompiler: support java 9 bytecode version --- src/org/jetbrains/java/decompiler/code/CodeConstants.java | 3 ++- src/org/jetbrains/java/decompiler/struct/StructClass.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/code/CodeConstants.java b/src/org/jetbrains/java/decompiler/code/CodeConstants.java index 18d1ddb..7718ac3 100644 --- a/src/org/jetbrains/java/decompiler/code/CodeConstants.java +++ b/src/org/jetbrains/java/decompiler/code/CodeConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ public interface CodeConstants { int BYTECODE_JAVA_6 = 3; int BYTECODE_JAVA_7 = 4; int BYTECODE_JAVA_8 = 5; + int BYTECODE_JAVA_9 = 6; // ---------------------------------------------------------------------- // VARIABLE TYPES diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java index cb24ff6..895e4c1 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -180,6 +180,8 @@ public class StructClass extends StructMember { public int getBytecodeVersion() { switch (majorVersion) { + case 53: + return CodeConstants.BYTECODE_JAVA_9; case 52: return CodeConstants.BYTECODE_JAVA_8; case 51: From f12851532512439e2c951494230511e3d0c4a5bf Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 29 Feb 2016 16:21:54 +0300 Subject: [PATCH 020/252] IDEA-151950 Decompiler doesn't work for classes from JDK 9 --- .../decompiler/modules/decompiler/ExprProcessor.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 9296bb3..cbc66c7 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -573,9 +573,12 @@ public class ExprProcessor implements CodeConstants { if (instr.opcode == opc_invokedynamic && bootstrap != null) { List bootstrap_arguments = bootstrap.getMethodArguments(invoke_constant.index1); - LinkConstant content_method_handle = (LinkConstant)bootstrap_arguments.get(1); - - dynamic_invokation_type = content_method_handle.index1; + if (bootstrap_arguments.size() > 1) { // INVOKEDYNAMIC is used not only for lambdas + PooledConstant link = bootstrap_arguments.get(1); + if (link instanceof LinkConstant) { + dynamic_invokation_type = ((LinkConstant)link).index1; + } + } } InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, stack, dynamic_invokation_type, bytecode_offsets); From 4724fd78a6e296c27aae91182afeebc84c0c2161 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 1 Mar 2016 18:04:29 +0300 Subject: [PATCH 021/252] IDEA-151950 Decompiler doesn't work for classes from JDK 9 - support java 9 string concatenation --- .../decompiler/ConcatenationHelper.java | 69 ++++++++++++++++-- .../modules/decompiler/ExprProcessor.java | 13 +--- .../decompiler/exps/InvocationExprent.java | 35 ++++++--- .../java/decompiler/SingleClassesTest.java | 4 +- .../classes/java9/TestJava9StringConcat.class | Bin 0 -> 871 bytes testData/classes/pkg/TestStringConcat.class | Bin 0 -> 740 bytes testData/results/TestJava9StringConcat.dec | 27 +++++++ testData/results/TestStringConcat.dec | 31 ++++++++ testData/src/java9/TestJava9StringConcat.java | 26 +++++++ testData/src/pkg/TestStringConcat.class | Bin 0 -> 740 bytes testData/src/pkg/TestStringConcat.java | 26 +++++++ 11 files changed, 206 insertions(+), 25 deletions(-) create mode 100644 testData/classes/java9/TestJava9StringConcat.class create mode 100644 testData/classes/pkg/TestStringConcat.class create mode 100644 testData/results/TestJava9StringConcat.dec create mode 100644 testData/results/TestStringConcat.dec create mode 100644 testData/src/java9/TestJava9StringConcat.java create mode 100644 testData/src/pkg/TestStringConcat.class create mode 100644 testData/src/pkg/TestStringConcat.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java index 74ef0a2..7d7b33d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,15 @@ package org.jetbrains.java.decompiler.modules.decompiler; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.modules.decompiler.exps.*; +import org.jetbrains.java.decompiler.struct.consts.PooledConstant; +import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Set; public class ConcatenationHelper { @@ -52,6 +56,12 @@ public class ConcatenationHelper { exprTmp = iex.getInstance(); } } + else if ("makeConcatWithConstants".equals(iex.getName())) { // java 9 style + List parameters = extractParameters(iex.getBootstrapArguments(), iex); + if (parameters.size() >= 2) { + return createConcatExprent(parameters, expr.bytecode); + } + } } if (exprTmp == null) { @@ -125,20 +135,69 @@ public class ConcatenationHelper { lstOperands.set(i, rep); } } + return createConcatExprent(lstOperands, expr.bytecode); + } + private static Exprent createConcatExprent(List lstOperands, Set bytecode) { // build exprent to return Exprent func = lstOperands.get(0); for (int i = 1; i < lstOperands.size(); i++) { - List lstTmp = new ArrayList(); - lstTmp.add(func); - lstTmp.add(lstOperands.get(i)); - func = new FunctionExprent(FunctionExprent.FUNCTION_STR_CONCAT, lstTmp, expr.bytecode); + func = new FunctionExprent(FunctionExprent.FUNCTION_STR_CONCAT, Arrays.asList(func, lstOperands.get(i)), bytecode); } return func; } + // See StringConcatFactory in jdk sources + private static final char TAG_ARG = '\u0001'; + private static final char TAG_CONST = '\u0002'; + + private static List extractParameters(List bootstrapArguments, InvocationExprent expr) { + List parameters = expr.getLstParameters(); + if (bootstrapArguments != null) { + PooledConstant constant = bootstrapArguments.get(0); + if (constant.type == CodeConstants.CONSTANT_String) { + String recipe = ((PrimitiveConstant)constant).getString(); + + List res = new ArrayList<>(); + StringBuilder acc = new StringBuilder(); + int parameterId = 0; + for (int i = 0; i < recipe.length(); i++) { + char c = recipe.charAt(i); + + if (c == TAG_CONST || c == TAG_ARG) { + // Detected a special tag, flush all accumulated characters + // as a constant first: + if (acc.length() > 0) { + res.add(new ConstExprent(VarType.VARTYPE_STRING, acc.toString(), expr.bytecode)); + acc.setLength(0); + } + if (c == TAG_CONST) { + // skip for now + } + if (c == TAG_ARG) { + res.add(parameters.get(parameterId++)); + } + } + else { + // Not a special characters, this is a constant embedded into + // the recipe itself. + acc.append(c); + } + } + + // Flush the remaining characters as constant: + if (acc.length() > 0) { + res.add(new ConstExprent(VarType.VARTYPE_STRING, acc.toString(), expr.bytecode)); + } + + return res; + } + } + return new ArrayList<>(parameters); + } + private static boolean isAppendConcat(InvocationExprent expr, VarType cltype) { if ("append".equals(expr.getName())) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index cbc66c7..008d0bb 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -567,21 +567,14 @@ public class ExprProcessor implements CodeConstants { case opc_invokeinterface: case opc_invokedynamic: if (instr.opcode != opc_invokedynamic || instr.bytecode_version >= CodeConstants.BYTECODE_JAVA_7) { - LinkConstant invoke_constant = pool.getLinkConstant(instr.getOperand(0)); - int dynamic_invokation_type = -1; + List bootstrap_arguments = null; if (instr.opcode == opc_invokedynamic && bootstrap != null) { - List bootstrap_arguments = bootstrap.getMethodArguments(invoke_constant.index1); - if (bootstrap_arguments.size() > 1) { // INVOKEDYNAMIC is used not only for lambdas - PooledConstant link = bootstrap_arguments.get(1); - if (link instanceof LinkConstant) { - dynamic_invokation_type = ((LinkConstant)link).index1; - } - } + bootstrap_arguments = bootstrap.getMethodArguments(invoke_constant.index1); } - InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, stack, dynamic_invokation_type, bytecode_offsets); + InvocationExprent exprinv = new InvocationExprent(instr.opcode, invoke_constant, bootstrap_arguments, stack, bytecode_offsets); if (exprinv.getDescriptor().ret.type == CodeConstants.TYPE_VOID) { exprlist.add(exprinv); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 294a115..3ceb99c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,13 +15,6 @@ */ package org.jetbrains.java.decompiler.modules.decompiler.exps; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; @@ -36,6 +29,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; +import org.jetbrains.java.decompiler.struct.consts.PooledConstant; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.match.MatchEngine; @@ -45,6 +39,9 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.ListStack; import org.jetbrains.java.decompiler.util.TextUtil; +import java.util.*; +import java.util.Map.Entry; + public class InvocationExprent extends Exprent { public static final int INVOKE_SPECIAL = 1; @@ -69,16 +66,22 @@ public class InvocationExprent extends Exprent { private String invokeDynamicClassSuffix; private int invocationTyp = INVOKE_VIRTUAL; private List lstParameters = new ArrayList(); + private List bootstrapArguments; public InvocationExprent() { super(EXPRENT_INVOCATION); } - public InvocationExprent(int opcode, LinkConstant cn, ListStack stack, int dynamicInvocationType, Set bytecodeOffsets) { + public InvocationExprent(int opcode, + LinkConstant cn, + List bootstrapArguments, + ListStack stack, + Set bytecodeOffsets) { this(); name = cn.elementname; classname = cn.classname; + this.bootstrapArguments = bootstrapArguments; switch (opcode) { case CodeConstants.opc_invokestatic: @@ -115,6 +118,15 @@ public class InvocationExprent extends Exprent { } if (opcode == CodeConstants.opc_invokedynamic) { + int dynamicInvocationType = -1; + if (bootstrapArguments != null) { + if (bootstrapArguments.size() > 1) { // INVOKEDYNAMIC is used not only for lambdas + PooledConstant link = bootstrapArguments.get(1); + if (link instanceof LinkConstant) { + dynamicInvocationType = ((LinkConstant)link).index1; + } + } + } if (dynamicInvocationType == CodeConstants.CONSTANT_MethodHandle_REF_invokeStatic) { isStatic = true; } @@ -154,6 +166,7 @@ public class InvocationExprent extends Exprent { ExprProcessor.copyEntries(lstParameters); addBytecodeOffsets(expr.bytecode); + bootstrapArguments = expr.getBootstrapArguments(); } @Override @@ -492,6 +505,10 @@ public class InvocationExprent extends Exprent { return invokeDynamicClassSuffix; } + public List getBootstrapArguments() { + return bootstrapArguments; + } + // ***************************************************************************** // IMatchable implementation // ***************************************************************************** diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 1ab4ea2..b8869b0 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,6 +77,8 @@ public class SingleClassesTest { @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } + @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } + @Test public void testJava9StringConcat() { doTest("java9/TestJava9StringConcat"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/java9/TestJava9StringConcat.class b/testData/classes/java9/TestJava9StringConcat.class new file mode 100644 index 0000000000000000000000000000000000000000..721a0ed9499e46d3ea2ea1853198faba1186a168 GIT binary patch literal 871 zcmaJfgc5Pg#-aq6Z`TMGS3OG{IlP?-qCB?{s|q>7>dheUATv`JR28+SLdHuo{bq5=S;%i^| z<_%%4-uO(&cl1aSDqUa6kJHP64EtgbaHe2nWL^-C>fH-*C7OXyXU(1oeRbA8ZQRc# zjF*H~79&OYG`NsM)6UdzdwLoU<%w@w*y?i&@40v@uG`USD9m%)P8mfwgypwdo5+M> z@PnAgGO<|TL=24%uN@rn8oFAKrxQZ?R4EyD0ue=$ zRllW&muSRydneQ=kWnorwo?O5wvx*HL+oEqWCr|e3ZJo(M4}^tpywOecJP#Nc<+8$ zy%Bc*kHbFl{5tJ7$8VEY$+pC&9rnb&@a!k(2M0W6w#A#Iea0>p*jnfwa!dwF$JH5! z_t@r!WN?i(Gq7N{XN?UB 5 +24 <-> 9 diff --git a/testData/results/TestStringConcat.dec b/testData/results/TestStringConcat.dec new file mode 100644 index 0000000..b3fc995 --- /dev/null +++ b/testData/results/TestStringConcat.dec @@ -0,0 +1,31 @@ +package pkg; + +public class TestStringConcat { + public String test1(String var1, int var2) { + return var1 + var2;// 20 + } + + public String test2(String var1, int var2, Object var3) { + return "(" + var1 + "-" + var2 + "---" + var3 + ")";// 24 + } +} + +class 'pkg/TestStringConcat' { + method 'test1 (Ljava/lang/String;I)Ljava/lang/String;' { + f 4 + 12 4 + } + + method 'test2 (Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/String;' { + 7 8 + 10 8 + 19 8 + 22 8 + 27 8 + 2a 8 + } +} + +Lines mapping: +20 <-> 5 +24 <-> 9 diff --git a/testData/src/java9/TestJava9StringConcat.java b/testData/src/java9/TestJava9StringConcat.java new file mode 100644 index 0000000..9e19596 --- /dev/null +++ b/testData/src/java9/TestJava9StringConcat.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package java9; + +public class TestJava9StringConcat { + public String test1(String prefix, int a) { + return prefix + a; + } + + public String test2(String var, int b, Object c) { + return "(" + var + "-" + b + "---" + c + ")"; + } +} \ No newline at end of file diff --git a/testData/src/pkg/TestStringConcat.class b/testData/src/pkg/TestStringConcat.class new file mode 100644 index 0000000000000000000000000000000000000000..029207376cef59555729fc47605dda16cd3b41b5 GIT binary patch literal 740 zcmZ`%O;5r=5PeI5){24!1Qk^LqChIqcrh3cl9-qfJwQx67HCKjTT+X^OD`qS#2?^~ zGR{g33bo0;-I?us^JcOipRex#PEeMygsg})86jjjtaI4lkdu&?uqk1SN81t#B6dXV zGDOcz%XH5f1hsU_5U$%@gCX89E#rFh&^DZw-X2gU;u??c5kpaJ^z|pbI?%0Nwdp#h z)vH~V=5s#dnBg>t@r!WN?i(Gq7N{XN?UB Date: Tue, 1 Mar 2016 17:44:22 +0100 Subject: [PATCH 022/252] [java decompiler] engine target level set back to Java 6 --- java-decompiler-engine.iml | 2 +- .../decompiler/modules/decompiler/ConcatenationHelper.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java-decompiler-engine.iml b/java-decompiler-engine.iml index 5880ebf..f5977f4 100644 --- a/java-decompiler-engine.iml +++ b/java-decompiler-engine.iml @@ -1,6 +1,6 @@ - + diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java index 7d7b33d..90d2732 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java @@ -160,7 +160,7 @@ public class ConcatenationHelper { if (constant.type == CodeConstants.CONSTANT_String) { String recipe = ((PrimitiveConstant)constant).getString(); - List res = new ArrayList<>(); + List res = new ArrayList(); StringBuilder acc = new StringBuilder(); int parameterId = 0; for (int i = 0; i < recipe.length(); i++) { @@ -195,7 +195,7 @@ public class ConcatenationHelper { return res; } } - return new ArrayList<>(parameters); + return new ArrayList(parameters); } private static boolean isAppendConcat(InvocationExprent expr, VarType cltype) { From cb72744cdb13a69849d8a96f55e024c2b0951473 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 2 Mar 2016 15:41:33 +0300 Subject: [PATCH 023/252] removed misplaced test file --- testData/src/pkg/TestStringConcat.class | Bin 740 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 testData/src/pkg/TestStringConcat.class diff --git a/testData/src/pkg/TestStringConcat.class b/testData/src/pkg/TestStringConcat.class deleted file mode 100644 index 029207376cef59555729fc47605dda16cd3b41b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 740 zcmZ`%O;5r=5PeI5){24!1Qk^LqChIqcrh3cl9-qfJwQx67HCKjTT+X^OD`qS#2?^~ zGR{g33bo0;-I?us^JcOipRex#PEeMygsg})86jjjtaI4lkdu&?uqk1SN81t#B6dXV zGDOcz%XH5f1hsU_5U$%@gCX89E#rFh&^DZw-X2gU;u??c5kpaJ^z|pbI?%0Nwdp#h z)vH~V=5s#dnBg>t@r!WN?i(Gq7N{XN?UB Date: Wed, 2 Mar 2016 17:53:25 +0300 Subject: [PATCH 024/252] decompiler: fixed SOE if referenced method name is the same as current --- .../decompiler/main/rels/LambdaProcessor.java | 6 ++-- .../java/decompiler/SingleClassesTest.java | 1 + .../pkg/TestMethodReferenceSameName$R1.class | Bin 0 -> 444 bytes .../pkg/TestMethodReferenceSameName.class | Bin 0 -> 1000 bytes .../results/TestMethodReferenceSameName.dec | 34 ++++++++++++++++++ .../src/pkg/TestMethodReferenceSameName.java | 26 ++++++++++++++ 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 testData/classes/pkg/TestMethodReferenceSameName$R1.class create mode 100644 testData/classes/pkg/TestMethodReferenceSameName.class create mode 100644 testData/results/TestMethodReferenceSameName.dec create mode 100644 testData/src/pkg/TestMethodReferenceSameName.java diff --git a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java index 0704efd..b5ac0fb 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,7 +115,9 @@ public class LambdaProcessor { node_lambda.parent = node; clProcessor.getMapRootClasses().put(node_lambda.simpleName, node_lambda); - mapMethodsLambda.put(node_lambda.lambdaInformation.content_method_key, node_lambda.simpleName); + if (!node_lambda.lambdaInformation.is_method_reference) { + mapMethodsLambda.put(node_lambda.lambdaInformation.content_method_key, node_lambda.simpleName); + } } } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index b8869b0..6ef71c0 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -79,6 +79,7 @@ public class SingleClassesTest { @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } @Test public void testJava9StringConcat() { doTest("java9/TestJava9StringConcat"); } + @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestMethodReferenceSameName$R1.class b/testData/classes/pkg/TestMethodReferenceSameName$R1.class new file mode 100644 index 0000000000000000000000000000000000000000..895110b36fa6faecdbecbedb8b0db49a57213437 GIT binary patch literal 444 zcmaKo%Syvg5QhIrVq#;o@s5ZRq>Ea?D!5bJ6a=AGXp8%kbZS%56G&3u%Y_Iod;lLx zoFlGWWHJBTzB9v_ukVjf09V*=z(&)DgV4j4hh2hO&C;@UK{)D7 z@JKCqAa*U_O{&xCmJqdT$3T)n6OD{upN2t4c&j%)bV@RDE|3GTJ#qL-<%Z1#Yz=Wi&f(b#s^7^Cfk|-(fByPfZHxJWIvkpXPFp{ zeeeeuf0OYp)UZagCO*u}nKSpEnR{mD+mExa03PF!1rr;qFmNeGm&?p<7H}O~Cbmu7 zFi|CBy88tCl~U60cp?a7Kp>w`b^0<04`ldWkGgU!eW`}BC#Ld{Tdlj_CKyj$<%Z7) z*?Qv*VWp!-l2CG7B@d(NK>B?#@R-StwI*0S9r;7~!i}kFium4k8_rT;PPQ%7(Xfz5lZ*8uMR-#GmwicUNe9t~$}jvgL^BU?kWUF&4v6`=^A$bU8D@6&Q}z$I*=Ny`DJ!xxm8FmqLv^8Ppb$ z?L=5F^j$ScGQTDEPiOM~78hHl=O&Fh-?k$>ujhucZQ>ze_YXt$Kq_;+R)TRfH-<(XY&e4o|!P{9?(HtS#I*b1(p@)O!a0^a}t literal 0 HcmV?d00001 diff --git a/testData/results/TestMethodReferenceSameName.dec b/testData/results/TestMethodReferenceSameName.dec new file mode 100644 index 0000000..3449a8c --- /dev/null +++ b/testData/results/TestMethodReferenceSameName.dec @@ -0,0 +1,34 @@ +public class TestMethodReferenceSameName { + TestMethodReferenceSameName.R1 r; + + private void foo() { + TestMethodReferenceSameName.R1 var10000 = this.r;// 5 + this.r.getClass(); + (var10000::foo).run(); + }// 6 + + class R1 { + void foo() { + }// 9 + } +} + +class 'TestMethodReferenceSameName' { + method 'foo ()V' { + 1 4 + 5 5 + e 6 + 13 7 + } +} + +class 'TestMethodReferenceSameName$R1' { + method 'foo ()V' { + 0 11 + } +} + +Lines mapping: +5 <-> 5 +6 <-> 8 +9 <-> 12 diff --git a/testData/src/pkg/TestMethodReferenceSameName.java b/testData/src/pkg/TestMethodReferenceSameName.java new file mode 100644 index 0000000..58d18d3 --- /dev/null +++ b/testData/src/pkg/TestMethodReferenceSameName.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +public class TestMethodReferenceSameName { + R1 r; + + private void foo() { + ((Runnable)r::foo).run(); + } + + class R1 { + void foo() {} + } +} From 876740dd0e9804ec2db08b13f06a5481efa959f6 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 2 Mar 2016 20:44:56 +0300 Subject: [PATCH 025/252] decompiler: fixed incorrect method references from single letter classes --- .../java/decompiler/main/ClassWriter.java | 4 +-- .../java/decompiler/SingleClassesTest.java | 1 + testData/classes/pkg/R.class | Bin 0 -> 250 bytes .../pkg/TestMethodReferenceLetterClass.class | Bin 0 -> 839 bytes .../TestMethodReferenceLetterClass.dec | 18 ++++++++++++ .../pkg/TestMethodReferenceLetterClass.java | 27 ++++++++++++++++++ 6 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 testData/classes/pkg/R.class create mode 100644 testData/classes/pkg/TestMethodReferenceLetterClass.class create mode 100644 testData/results/TestMethodReferenceLetterClass.dec create mode 100644 testData/src/pkg/TestMethodReferenceLetterClass.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index b55f29d..dc0f3fc 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -98,7 +98,7 @@ public class ClassWriter { } else { // reference to a static method - buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambdaInformation.content_class_name, false))); + buffer.append(ExprProcessor.getCastTypeName(new VarType(node.lambdaInformation.content_class_name, true))); } buffer.append("::"); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 6ef71c0..e3a6f56 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -80,6 +80,7 @@ public class SingleClassesTest { @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } @Test public void testJava9StringConcat() { doTest("java9/TestJava9StringConcat"); } @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } + @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/R.class b/testData/classes/pkg/R.class new file mode 100644 index 0000000000000000000000000000000000000000..7c9c9e22c83c2a30917e4935a229eedcab9d1397 GIT binary patch literal 250 zcmZWjyGq1R5IvKp#$DZ3K@e=z!ZenPO<=3ILJamd$wU)kF5KMsUsl2vet;h(&b8Ra zftmA|Q=IRg-4}p694GK`6k`!%Nr=|n*x7r6e|7y#2r}I;;Uw=y-p+3on^IMSIDV@& zA$iiXsd>{m>$2p@KCpe&O~EZ29&66oS~l6Brs=j_L&JXr}s`UpE0B*F0J6Z9d35X+7J%u`_p`>0bc`Y(1S_MtpHB)>#BD&YVC literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestMethodReferenceLetterClass.class b/testData/classes/pkg/TestMethodReferenceLetterClass.class new file mode 100644 index 0000000000000000000000000000000000000000..74bb32df8d438abca6a2b7ee6fc4e0a96342aef2 GIT binary patch literal 839 zcmbVKO>fgc5Pg$0ad8a^Eh(REY12}t2Ylfc#DPc%Bm+_s^}cZ?#jUd&+3QOES)7o1 z;0GXn6JlIPBz!0bEO}?<&6}B>+4=V4`YV7JIB~HCZ&UP52U`yA5$Z2v9otugs^2*! zto6*835_t;{2`x?I321{B1m;)48a|kJdOBGTtMw1XZAhYPiEZb38$`I4z*cVF_6-7L=ggw7g@^c#}!6es_jg1a^MrZky)2@R(4^MIE z;K;+X;{FGV^s&A)7aW9YIvOkKMom;?O?pMxm@X^_z7!0NxyWY(@1553sc=U4zI@$z zzH%;al^!RY9hQOJrLG1xjrG|w@>}5WYR3QPEK9DAosa8g@bj`gl_Z1Ma+g4TS&xY^ z4myORzb5ss&g89E^RSPq>}v54>!>l0?={zJNZ9LRgoxa06TN-}*&u3sw=t qxh_PwAiFnkONiT2#T7~g8)%DkC1fARIFN 5 +22 <-> 6 diff --git a/testData/src/pkg/TestMethodReferenceLetterClass.java b/testData/src/pkg/TestMethodReferenceLetterClass.java new file mode 100644 index 0000000..5f290d8 --- /dev/null +++ b/testData/src/pkg/TestMethodReferenceLetterClass.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.function.Consumer; + +public class TestMethodReferenceLetterClass { + void boo() { + Consumer foo = R::foo; + } +} + +class R { + void foo() {} +} \ No newline at end of file From df863df9c1efc9e8d7850066a6820962e0ffefef Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 3 Mar 2016 12:16:46 +0100 Subject: [PATCH 026/252] [java decompiler] engine source/target level set to Java 8 --- build.xml | 2 +- java-decompiler-engine.iml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.xml b/build.xml index 7986eb4..3088f83 100644 --- a/build.xml +++ b/build.xml @@ -26,7 +26,7 @@ - + diff --git a/java-decompiler-engine.iml b/java-decompiler-engine.iml index f5977f4..5880ebf 100644 --- a/java-decompiler-engine.iml +++ b/java-decompiler-engine.iml @@ -1,6 +1,6 @@ - + From cfe1448b2b0f00bdda2434726ab15b1030519f89 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 3 Mar 2016 13:45:52 +0100 Subject: [PATCH 027/252] Cleanup (unneeded anonymous classes) --- .../java/decompiler/main/ClassWriter.java | 28 +++---- .../main/extern/IFernflowerPreferences.java | 74 ++++++++++--------- .../modules/decompiler/exps/ConstExprent.java | 28 +++---- 3 files changed, 69 insertions(+), 61 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index dc0f3fc..b438695 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -980,19 +980,21 @@ public class ClassWriter { } } - private static final Map MODIFIERS = new LinkedHashMap() {{ - put(CodeConstants.ACC_PUBLIC, "public"); - put(CodeConstants.ACC_PROTECTED, "protected"); - put(CodeConstants.ACC_PRIVATE, "private"); - put(CodeConstants.ACC_ABSTRACT, "abstract"); - put(CodeConstants.ACC_STATIC, "static"); - put(CodeConstants.ACC_FINAL, "final"); - put(CodeConstants.ACC_STRICT, "strictfp"); - put(CodeConstants.ACC_TRANSIENT, "transient"); - put(CodeConstants.ACC_VOLATILE, "volatile"); - put(CodeConstants.ACC_SYNCHRONIZED, "synchronized"); - put(CodeConstants.ACC_NATIVE, "native"); - }}; + private static final Map MODIFIERS; + static { + MODIFIERS = new LinkedHashMap<>(); + MODIFIERS.put(CodeConstants.ACC_PUBLIC, "public"); + MODIFIERS.put(CodeConstants.ACC_PROTECTED, "protected"); + MODIFIERS.put(CodeConstants.ACC_PRIVATE, "private"); + MODIFIERS.put(CodeConstants.ACC_ABSTRACT, "abstract"); + MODIFIERS.put(CodeConstants.ACC_STATIC, "static"); + MODIFIERS.put(CodeConstants.ACC_FINAL, "final"); + MODIFIERS.put(CodeConstants.ACC_STRICT, "strictfp"); + MODIFIERS.put(CodeConstants.ACC_TRANSIENT, "transient"); + MODIFIERS.put(CodeConstants.ACC_VOLATILE, "volatile"); + MODIFIERS.put(CodeConstants.ACC_SYNCHRONIZED, "synchronized"); + MODIFIERS.put(CodeConstants.ACC_NATIVE, "native"); + } private static final int CLASS_ALLOWED = CodeConstants.ACC_PUBLIC | CodeConstants.ACC_PROTECTED | CodeConstants.ACC_PRIVATE | CodeConstants.ACC_ABSTRACT | diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java index cd6333b..c1ceecd 100644 --- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java +++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -59,37 +59,43 @@ public interface IFernflowerPreferences { String LINE_SEPARATOR_WIN = "\r\n"; String LINE_SEPARATOR_UNX = "\n"; - Map DEFAULTS = Collections.unmodifiableMap(new HashMap() {{ - put(REMOVE_BRIDGE, "1"); - put(REMOVE_SYNTHETIC, "0"); - put(DECOMPILE_INNER, "1"); - put(DECOMPILE_CLASS_1_4, "1"); - put(DECOMPILE_ASSERTIONS, "1"); - put(HIDE_EMPTY_SUPER, "1"); - put(HIDE_DEFAULT_CONSTRUCTOR, "1"); - put(DECOMPILE_GENERIC_SIGNATURES, "0"); - put(NO_EXCEPTIONS_RETURN, "1"); - put(DECOMPILE_ENUM, "1"); - put(REMOVE_GET_CLASS_NEW, "1"); - put(LITERALS_AS_IS, "0"); - put(BOOLEAN_TRUE_ONE, "1"); - put(ASCII_STRING_CHARACTERS, "0"); - put(SYNTHETIC_NOT_SET, "1"); - put(UNDEFINED_PARAM_TYPE_OBJECT, "1"); - put(USE_DEBUG_VAR_NAMES, "1"); - put(REMOVE_EMPTY_RANGES, "1"); - put(FINALLY_DEINLINE, "1"); - put(IDEA_NOT_NULL_ANNOTATION, "1"); - put(LAMBDA_TO_ANONYMOUS_CLASS, "0"); - put(BYTECODE_SOURCE_MAPPING, "0"); + Map DEFAULTS = getDefaults(); - put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); - put(MAX_PROCESSING_METHOD, "0"); - put(RENAME_ENTITIES, "0"); - put(NEW_LINE_SEPARATOR, (InterpreterUtil.IS_WINDOWS ? "0" : "1")); - put(INDENT_STRING, " "); - put(BANNER, ""); - put(UNIT_TEST_MODE, "0"); - put(DUMP_ORIGINAL_LINES, "0"); - }}); -} + static Map getDefaults() { + Map defaults = new HashMap<>(); + + defaults.put(REMOVE_BRIDGE, "1"); + defaults.put(REMOVE_SYNTHETIC, "0"); + defaults.put(DECOMPILE_INNER, "1"); + defaults.put(DECOMPILE_CLASS_1_4, "1"); + defaults.put(DECOMPILE_ASSERTIONS, "1"); + defaults.put(HIDE_EMPTY_SUPER, "1"); + defaults.put(HIDE_DEFAULT_CONSTRUCTOR, "1"); + defaults.put(DECOMPILE_GENERIC_SIGNATURES, "0"); + defaults.put(NO_EXCEPTIONS_RETURN, "1"); + defaults.put(DECOMPILE_ENUM, "1"); + defaults.put(REMOVE_GET_CLASS_NEW, "1"); + defaults.put(LITERALS_AS_IS, "0"); + defaults.put(BOOLEAN_TRUE_ONE, "1"); + defaults.put(ASCII_STRING_CHARACTERS, "0"); + defaults.put(SYNTHETIC_NOT_SET, "1"); + defaults.put(UNDEFINED_PARAM_TYPE_OBJECT, "1"); + defaults.put(USE_DEBUG_VAR_NAMES, "1"); + defaults.put(REMOVE_EMPTY_RANGES, "1"); + defaults.put(FINALLY_DEINLINE, "1"); + defaults.put(IDEA_NOT_NULL_ANNOTATION, "1"); + defaults.put(LAMBDA_TO_ANONYMOUS_CLASS, "0"); + defaults.put(BYTECODE_SOURCE_MAPPING, "0"); + + defaults.put(LOG_LEVEL, IFernflowerLogger.Severity.INFO.name()); + defaults.put(MAX_PROCESSING_METHOD, "0"); + defaults.put(RENAME_ENTITIES, "0"); + defaults.put(NEW_LINE_SEPARATOR, (InterpreterUtil.IS_WINDOWS ? "0" : "1")); + defaults.put(INDENT_STRING, " "); + defaults.put(BANNER, ""); + defaults.put(UNIT_TEST_MODE, "0"); + defaults.put(DUMP_ORIGINAL_LINES, "0"); + + return Collections.unmodifiableMap(defaults); + } +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index 4b9b687..8fcf176 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,7 +25,6 @@ import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; -import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import org.jetbrains.java.decompiler.util.InterpreterUtil; @@ -33,16 +32,18 @@ import java.util.*; import java.util.Map.Entry; public class ConstExprent extends Exprent { - private static final Map ESCAPES = new HashMap() {{ - put(new Integer(0x8), "\\b"); /* \u0008: backspace BS */ - put(new Integer(0x9), "\\t"); /* \u0009: horizontal tab HT */ - put(new Integer(0xA), "\\n"); /* \u000a: linefeed LF */ - put(new Integer(0xC), "\\f"); /* \u000c: form feed FF */ - put(new Integer(0xD), "\\r"); /* \u000d: carriage return CR */ - put(new Integer(0x22), "\\\""); /* \u0022: double quote " */ - put(new Integer(0x27), "\\\'"); /* \u0027: single quote ' */ - put(new Integer(0x5C), "\\\\"); /* \u005c: backslash \ */ - }}; + private static final Map ESCAPES; + static { + ESCAPES = new HashMap<>(); + ESCAPES.put(new Integer(0x8), "\\b"); /* \u0008: backspace BS */ + ESCAPES.put(new Integer(0x9), "\\t"); /* \u0009: horizontal tab HT */ + ESCAPES.put(new Integer(0xA), "\\n"); /* \u000a: linefeed LF */ + ESCAPES.put(new Integer(0xC), "\\f"); /* \u000c: form feed FF */ + ESCAPES.put(new Integer(0xD), "\\r"); /* \u000d: carriage return CR */ + ESCAPES.put(new Integer(0x22), "\\\""); /* \u0022: double quote " */ + ESCAPES.put(new Integer(0x27), "\\\'"); /* \u0027: single quote ' */ + ESCAPES.put(new Integer(0x5C), "\\\\"); /* \u005c: backslash \ */ + } private VarType constType; private final Object value; @@ -432,5 +433,4 @@ public class ConstExprent extends Exprent { return true; } - -} +} \ No newline at end of file From 5795c1d9e0076e1732df1b9673e69e2ec39dec47 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 4 Mar 2016 15:32:42 +0100 Subject: [PATCH 028/252] [tests] test cases added --- .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TestMemberAnnotations$A.class | Bin 0 -> 438 bytes .../classes/pkg/TestMemberAnnotations.class | Bin 0 -> 619 bytes testData/results/TestMemberAnnotations.dec | 34 ++++++++++++++++++ testData/src/pkg/TestMemberAnnotations.java | 13 +++++++ 5 files changed, 48 insertions(+) create mode 100644 testData/classes/pkg/TestMemberAnnotations$A.class create mode 100644 testData/classes/pkg/TestMemberAnnotations.class create mode 100644 testData/results/TestMemberAnnotations.dec create mode 100644 testData/src/pkg/TestMemberAnnotations.java diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index e3a6f56..5647ab8 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -81,6 +81,7 @@ public class SingleClassesTest { @Test public void testJava9StringConcat() { doTest("java9/TestJava9StringConcat"); } @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } + @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestMemberAnnotations$A.class b/testData/classes/pkg/TestMemberAnnotations$A.class new file mode 100644 index 0000000000000000000000000000000000000000..f7fa7905d1df87219b377e5d8ec65948f42139ea GIT binary patch literal 438 zcmah_yG{c!5S+~eha*4&p#Taf&xN}~SB zNd_EPYBDGJ@jsTw%$muY7}enEe$?yVD0B#i^Vc-_wX2gZfdtK-bDUpU?LB)!s~r7d zJmrZ@c~nX(y_NmTXn&@}%NfDRRjuGk+Hh3+B(!7U)78mSZOtx0;T5TL$BIWp*>UmjtYK( zyR{>V51kNW*9p_)j`^Kd{;fdjSQ~9m1mgSUwm_mjxFvJ8sf{|1oLEcJj=+AS%-&Lg zvQc0JcEf|D8x6@5ohO znqKvybFaFbsQ52^w}vgQKfx`=P(TJ*#@wiyg2y-oZk%T(#4I7YvzP$p2*7nmXpvco zQ7|SeuMp2n1eSQGz8^;_%QSV=9aiphu2^|N>?U8id79vRlWr?mCB<_VKaCYAvBtL; Oiby*#LP;8=_A*}twS2Px literal 0 HcmV?d00001 diff --git a/testData/results/TestMemberAnnotations.dec b/testData/results/TestMemberAnnotations.dec new file mode 100644 index 0000000..1e3a41c --- /dev/null +++ b/testData/results/TestMemberAnnotations.dec @@ -0,0 +1,34 @@ +package pkg; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +class TestMemberAnnotations { + @TestMemberAnnotations.A("const") + public static final int CONST = 42; + @TestMemberAnnotations.A("field") + private int f; + + @TestMemberAnnotations.A("return") + private int f(@TestMemberAnnotations.A("arg") int var1) { + return var1 + this.f + 42;// 12 + } + + @Retention(RetentionPolicy.RUNTIME) + @interface A { + String value() default ""; + } +} + +class 'pkg/TestMemberAnnotations' { + method 'f (I)I' { + 2 13 + 5 13 + 6 13 + 8 13 + 9 13 + } +} + +Lines mapping: +12 <-> 14 diff --git a/testData/src/pkg/TestMemberAnnotations.java b/testData/src/pkg/TestMemberAnnotations.java new file mode 100644 index 0000000..b7c7da9 --- /dev/null +++ b/testData/src/pkg/TestMemberAnnotations.java @@ -0,0 +1,13 @@ +package pkg; + +import java.lang.annotation.*; + +class TestMemberAnnotations { + @Retention(RetentionPolicy.RUNTIME) + @interface A { String value() default ""; } + + @A("const") public static final int CONST = 42; + @A("field") private int f; + + @A("return") private int f(@A("arg") int i) { return i + f + CONST; } +} \ No newline at end of file From 7cf7bec4b68a70b7da6aed3cd41a375e67364626 Mon Sep 17 00:00:00 2001 From: Alexandru-Constantin Bledea Date: Mon, 7 Mar 2016 21:00:21 +0200 Subject: [PATCH 029/252] prevent static field name clashes in local methods --- .../modules/decompiler/exps/FieldExprent.java | 8 ++- .../java/decompiler/util/StructUtils.java | 65 ++++++++++++++++++ .../java/decompiler/SingleClassesTest.java | 3 +- .../classes/pkg/TestStaticNameClash.class | Bin 0 -> 443 bytes testData/results/TestStaticNameClash.dec | 20 ++++++ testData/src/pkg/TestStaticNameClash.java | 15 ++++ 6 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 src/org/jetbrains/java/decompiler/util/StructUtils.java create mode 100644 testData/classes/pkg/TestStaticNameClash.class create mode 100644 testData/results/TestStaticNameClash.dec create mode 100644 testData/src/pkg/TestStaticNameClash.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java index 4ac8123..28002ff 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java @@ -28,9 +28,9 @@ import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; -import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.StructUtils; import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; @@ -84,13 +84,17 @@ public class FieldExprent extends Exprent { return new FieldExprent(name, classname, isStatic, instance == null ? null : instance.copy(), descriptor, bytecode); } + private boolean isAmbiguous() { + return StructUtils.getCurrentMethodLocalVariableNames().contains(name); + } + @Override public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { TextBuffer buf = new TextBuffer(); if (isStatic) { ClassNode node = (ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); - if (node == null || !classname.equals(node.classStruct.qualifiedName)) { + if (node == null || !classname.equals(node.classStruct.qualifiedName) || isAmbiguous()) { buf.append(DecompilerContext.getImportCollector().getShortName(ExprProcessor.buildJavaClassName(classname))); buf.append("."); } diff --git a/src/org/jetbrains/java/decompiler/util/StructUtils.java b/src/org/jetbrains/java/decompiler/util/StructUtils.java new file mode 100644 index 0000000..d7dad68 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/util/StructUtils.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.util; + +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.struct.StructMember; +import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.jetbrains.java.decompiler.main.DecompilerContext.CURRENT_METHOD_WRAPPER; +import static org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE; + +/** + * @author Alexandru-Constantin Bledea + * @since March 07, 2016 + */ +public final class StructUtils { + + private StructUtils() { + } + + /** + * @return the local variables of the current method + */ + public static List getCurrentMethodLocalVariableNames() { + final MethodWrapper method = (MethodWrapper) DecompilerContext.getProperty(CURRENT_METHOD_WRAPPER); + if (null == method) { + return Collections.emptyList(); + } + return getLocalVariables(method.methodStruct); + } + + /** + * @param structMember the struct member from which to extract the local variables + * @return the local variables of the struct member + */ + public static List getLocalVariables(final StructMember structMember) { + final VBStyleCollection methodStruct = structMember.getAttributes(); + final StructGeneralAttribute generalAttribute = methodStruct.getWithKey(ATTRIBUTE_LOCAL_VARIABLE_TABLE); + if (generalAttribute instanceof StructLocalVariableTableAttribute) { + final StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute) generalAttribute; + return Collections.unmodifiableList(new ArrayList<>(table.getMapVarNames().values())); + } + return Collections.emptyList(); + } + +} diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 5647ab8..e39bb3a 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -82,6 +82,7 @@ public class SingleClassesTest { @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } + @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); @@ -128,4 +129,4 @@ public class SingleClassesTest { return files; } -} \ No newline at end of file +} diff --git a/testData/classes/pkg/TestStaticNameClash.class b/testData/classes/pkg/TestStaticNameClash.class new file mode 100644 index 0000000000000000000000000000000000000000..16a1da3eaa4b6d04a9ca9552b68470b096425ceb GIT binary patch literal 443 zcmZ`#%T9wp6g@*J6pB{S`dGTFE@YuQjhiN}NHwA9e!vNxN`b)C#LqG=OkDT@ew6VJ z7;B<#=H7emoX5=j$Lkw_bL_b=;XCMH$HuOWAw#dMic(bSk--la{DB7<&(k1MmCVx% z2J2GhQe820M#nP-b6ngBhCwKEFI)i%BY7iix$_VYAynsD5YnM)|0d4fD_u30oH)wLOi2)%F c^=DLD@-vJz*(DE6Gl}q1p!KJev^B8(3F 7 +13 <-> 8 diff --git a/testData/src/pkg/TestStaticNameClash.java b/testData/src/pkg/TestStaticNameClash.java new file mode 100644 index 0000000..ced8f12 --- /dev/null +++ b/testData/src/pkg/TestStaticNameClash.java @@ -0,0 +1,15 @@ +package pkg; + +/** + * @author Alexandru-Constantin Bledea + * @since March 07, 2016 + */ +public class TestStaticNameClash { + + public static String property; + + public static void setProperty(final String property) { + TestStaticNameClash.property = property; + } + +} From 23da5d99d2c4cc523067da0f3c1bb2a931dd47eb Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Mar 2016 11:22:21 +0100 Subject: [PATCH 030/252] Cleanup (I/O ops in java-decompiler) --- .../main/decompiler/ConsoleDecompiler.java | 38 +++-------- .../java/decompiler/struct/ContextUnit.java | 10 +-- .../java/decompiler/struct/StructContext.java | 29 +++------ .../java/decompiler/struct/StructMember.java | 10 +-- .../decompiler/struct/lazy/LazyLoader.java | 31 +++------ .../decompiler/util/DataInputFullStream.java | 31 ++------- .../java/decompiler/util/InterpreterUtil.java | 64 ++++++++----------- .../decompiler/BulkDecompilationTest.java | 26 +++----- 8 files changed, 78 insertions(+), 161 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java index 7924b1c..ea08023 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -150,17 +150,11 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { return InterpreterUtil.getBytes(file); } else { - ZipFile archive = new ZipFile(file); - try { + try (ZipFile archive = new ZipFile(file)) { ZipEntry entry = archive.getEntry(internalPath); - if (entry == null) { - throw new IOException("Entry not found: " + internalPath); - } + if (entry == null) throw new IOException("Entry not found: " + internalPath); return InterpreterUtil.getBytes(archive, entry); } - finally { - archive.close(); - } } } @@ -193,14 +187,8 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { @Override public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) { File file = new File(getAbsolutePath(path), entryName); - try { - Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8"); - try { - out.write(content); - } - finally { - out.close(); - } + try (Writer out = new OutputStreamWriter(new FileOutputStream(file), "UTF8")) { + out.write(content); } catch (IOException ex) { DecompilerContext.getLogger().writeMessage("Cannot write class file " + file, ex); @@ -238,21 +226,15 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { return; } - try { - ZipFile srcArchive = new ZipFile(new File(source)); - try { - ZipEntry entry = srcArchive.getEntry(entryName); - if (entry != null) { - InputStream in = srcArchive.getInputStream(entry); + try (ZipFile srcArchive = new ZipFile(new File(source))) { + ZipEntry entry = srcArchive.getEntry(entryName); + if (entry != null) { + try (InputStream in = srcArchive.getInputStream(entry)) { ZipOutputStream out = mapArchiveStreams.get(file); out.putNextEntry(new ZipEntry(entryName)); InterpreterUtil.copyStream(in, out); - in.close(); } } - finally { - srcArchive.close(); - } } catch (IOException ex) { String message = "Cannot copy entry " + entryName + " from " + source + " to " + file; @@ -306,4 +288,4 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { DecompilerContext.getLogger().writeMessage("Cannot close " + file, IFernflowerLogger.Severity.WARN); } } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java index 850c3d8..69125e1 100644 --- a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java +++ b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -78,13 +78,9 @@ public class ContextUnit { String oldName = cl.qualifiedName; StructClass newCl; - DataInputFullStream in = loader.getClassStream(oldName); - try { + try (DataInputFullStream in = loader.getClassStream(oldName)) { newCl = new StructClass(in, cl.isOwn(), loader); } - finally { - in.close(); - } lstClasses.add(newCl); @@ -168,4 +164,4 @@ public class ContextUnit { public List getClasses() { return classes; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java index 7bfb139..d47de60 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,17 +119,11 @@ public class StructContext { } if (filename.endsWith(".class")) { - try { - DataInputFullStream in = loader.getClassStream(file.getAbsolutePath(), null); - try { - StructClass cl = new StructClass(in, isOwn, loader); - classes.put(cl.qualifiedName, cl); - unit.addClass(cl, filename); - loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null)); - } - finally { - in.close(); - } + try (DataInputFullStream in = loader.getClassStream(file.getAbsolutePath(), null)) { + StructClass cl = new StructClass(in, isOwn, loader); + classes.put(cl.qualifiedName, cl); + unit.addClass(cl, filename); + loader.addClassLink(cl.qualifiedName, new LazyLoader.Link(LazyLoader.Link.CLASS, file.getAbsolutePath(), null)); } catch (IOException ex) { String message = "Corrupted class file: " + file; @@ -143,10 +137,8 @@ public class StructContext { } private void addArchive(String path, File file, int type, boolean isOwn) throws IOException { - @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") - ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file); - - try { + //noinspection IOResourceOpenedButNotSafelyClosed + try (ZipFile archive = type == ContextUnit.TYPE_JAR ? new JarFile(file) : new ZipFile(file)) { Enumeration entries = archive.entries(); while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); @@ -178,12 +170,9 @@ public class StructContext { } } } - finally { - archive.close(); - } } public Map getClasses() { return classes; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index f681e19..bc8b931 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,15 +73,15 @@ public class StructMember { protected StructGeneralAttribute readAttribute(DataInputFullStream in, ConstantPool pool, String name) throws IOException { StructGeneralAttribute attribute = StructGeneralAttribute.createAttribute(name); + int length = in.readInt(); if (attribute == null) { - in.discard(in.readInt()); + in.discard(length); } else { - byte[] data = new byte[in.readInt()]; - in.readFull(data); + byte[] data = in.read(length); attribute.setInfo(data); attribute.initContent(pool); } return attribute; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java index d75c93d..40944c1 100644 --- a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java +++ b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,17 +47,13 @@ public class LazyLoader { } public ConstantPool loadPool(String classname) { - try { - DataInputFullStream in = getClassStream(classname); - if (in == null) return null; - - try { + try (DataInputFullStream in = getClassStream(classname)) { + if (in != null) { in.discard(8); return new ConstantPool(in); } - finally { - in.close(); - } + + return null; } catch (IOException ex) { throw new RuntimeException(ex); @@ -67,11 +63,8 @@ public class LazyLoader { public byte[] loadBytecode(StructMethod mt, int codeFullLength) { String className = mt.getClassStruct().qualifiedName; - try { - DataInputFullStream in = getClassStream(className); - if (in == null) return null; - - try { + try (DataInputFullStream in = getClassStream(className)) { + if (in != null) { in.discard(8); ConstantPool pool = mt.getClassStruct().getPool(); @@ -118,17 +111,13 @@ public class LazyLoader { } in.discard(12); - byte[] code = new byte[codeFullLength]; - in.readFull(code); - return code; + + return in.read(codeFullLength); } break; } } - finally { - in.close(); - } return null; } @@ -170,4 +159,4 @@ public class LazyLoader { this.internalPath = internalPath; } } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java b/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java index 011edde..ac71e20 100644 --- a/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java +++ b/src/org/jetbrains/java/decompiler/util/DataInputFullStream.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,36 +20,15 @@ import java.io.DataInputStream; import java.io.IOException; public class DataInputFullStream extends DataInputStream { - public DataInputFullStream(byte[] bytes) { super(new ByteArrayInputStream(bytes)); } - public int readFull(byte[] b) throws IOException { - int length = b.length; - byte[] temp = new byte[length]; - int pos = 0; - - int bytes_read; - while (true) { - bytes_read = read(temp, 0, length - pos); - if (bytes_read == -1) { - return -1; - } - - System.arraycopy(temp, 0, b, pos, bytes_read); - pos += bytes_read; - if (pos == length) { - break; - } - } - - return length; + public byte[] read(int n) throws IOException { + return InterpreterUtil.readBytes(this, n); } public void discard(int n) throws IOException { - if (super.skip(n) != n) { - throw new IOException("Skip failed"); - } + InterpreterUtil.discardBytes(this, n); } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java index 8ec1aaa..8130145 100644 --- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import java.io.*; -import java.nio.channels.FileChannel; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -31,27 +30,11 @@ public class InterpreterUtil { public static final int[] EMPTY_INT_ARRAY = new int[0]; - private static final int CHANNEL_WINDOW_SIZE = IS_WINDOWS ? 64 * 1024 * 1024 - (32 * 1024) : 64 * 1024 * 1024; // magic number for Windows private static final int BUFFER_SIZE = 16 * 1024; - public static void copyFile(File in, File out) throws IOException { - FileInputStream inStream = new FileInputStream(in); - try { - FileOutputStream outStream = new FileOutputStream(out); - try { - FileChannel inChannel = inStream.getChannel(); - FileChannel outChannel = outStream.getChannel(); - long size = inChannel.size(), position = 0; - while (position < size) { - position += inChannel.transferTo(position, CHANNEL_WINDOW_SIZE, outChannel); - } - } - finally { - outStream.close(); - } - } - finally { - inStream.close(); + public static void copyFile(File source, File target) throws IOException { + try (FileInputStream in = new FileInputStream(source); FileOutputStream out = new FileOutputStream(target)) { + copyStream(in, out); } } @@ -64,28 +47,35 @@ public class InterpreterUtil { } public static byte[] getBytes(ZipFile archive, ZipEntry entry) throws IOException { - return readAndClose(archive.getInputStream(entry), (int)entry.getSize()); + try (InputStream stream = archive.getInputStream(entry)) { + return readBytes(stream, (int)entry.getSize()); + } } public static byte[] getBytes(File file) throws IOException { - return readAndClose(new FileInputStream(file), (int)file.length()); + try (FileInputStream stream = new FileInputStream(file)) { + return readBytes(stream, (int)file.length()); + } } - private static byte[] readAndClose(InputStream stream, int length) throws IOException { - try { - byte[] bytes = new byte[length]; - int n = 0, off = 0; - while (n < length) { - int count = stream.read(bytes, off + n, length - n); - if (count < 0) { - throw new IOException("premature end of stream"); - } - n += count; + public static byte[] readBytes(InputStream stream, int length) throws IOException { + byte[] bytes = new byte[length]; + + int n = 0, off = 0; + while (n < length) { + int count = stream.read(bytes, off + n, length - n); + if (count < 0) { + throw new IOException("premature end of stream"); } - return bytes; + n += count; } - finally { - stream.close(); + + return bytes; + } + + public static void discardBytes(InputStream stream, int length) throws IOException { + if (stream.skip(length) != length) { + throw new IOException("premature end of stream"); } } @@ -159,4 +149,4 @@ public class InterpreterUtil { public static String makeUniqueKey(String name, String descriptor1, String descriptor2) { return name + ' ' + descriptor1 + ' ' + descriptor2; } -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java index 31778cb..7837905 100644 --- a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java +++ b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,26 +69,18 @@ public class BulkDecompilationTest { } private static void unpack(File archive, File targetDir) { - try { - ZipFile zip = new ZipFile(archive); - try { - Enumeration entries = zip.entries(); - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - if (!entry.isDirectory()) { - File file = new File(targetDir, entry.getName()); - assertTrue(file.getParentFile().mkdirs() || file.getParentFile().isDirectory()); - InputStream in = zip.getInputStream(entry); - OutputStream out = new FileOutputStream(file); + try (ZipFile zip = new ZipFile(archive)) { + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + if (!entry.isDirectory()) { + File file = new File(targetDir, entry.getName()); + assertTrue(file.getParentFile().mkdirs() || file.getParentFile().isDirectory()); + try (InputStream in = zip.getInputStream(entry); OutputStream out = new FileOutputStream(file)) { InterpreterUtil.copyStream(in, out); - out.close(); - in.close(); } } } - finally { - zip.close(); - } } catch (IOException e) { throw new RuntimeException(e); From 35259c3e202294d1725666e544faa9ed95fdc272 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Mar 2016 11:49:15 +0100 Subject: [PATCH 031/252] Cleanup (formatting) --- test/org/jetbrains/java/decompiler/SingleClassesTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index e39bb3a..c5bcf8c 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -129,4 +129,4 @@ public class SingleClassesTest { return files; } -} +} \ No newline at end of file From 35569de64fd2c7eaf31cc15521a5605a32bfa44f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Mar 2016 12:20:26 +0100 Subject: [PATCH 032/252] [java-decompiler] build script corrected --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 3088f83..d23cf1f 100644 --- a/build.xml +++ b/build.xml @@ -39,7 +39,7 @@ - + From f643b1c870eb4f29f52109d8aee312f5042a79c4 Mon Sep 17 00:00:00 2001 From: Christopher Carpenter Date: Mon, 14 Mar 2016 01:55:49 -0400 Subject: [PATCH 033/252] Made ClassReference14Processor static similar to how InitializerProcessor and EnumProcessor are setup. This gets rid of a lot of unnecessary InvocationExprent creation. --- .../main/ClassReference14Processor.java | 32 +++--------- .../java/decompiler/main/ClassWriter.java | 52 +++++++++++++------ 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java index 677f457..a36c88e 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java @@ -38,12 +38,11 @@ import java.util.Map.Entry; public class ClassReference14Processor { - public final ExitExprent bodyexprent; + public static final ExitExprent bodyexprent; - public final ExitExprent handlerexprent; + public static final ExitExprent handlerexprent; - - public ClassReference14Processor() { + static { InvocationExprent invfor = new InvocationExprent(); invfor.setName("forName"); @@ -65,7 +64,7 @@ public class ClassReference14Processor { constr.setDescriptor(MethodDescriptor.parseDescriptor("()V")); NewExprent newexpr = - new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList(), null); + new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<>(), null); newexpr.setConstructor(constr); InvocationExprent invcause = new InvocationExprent(); @@ -82,32 +81,13 @@ public class ClassReference14Processor { null, null); } - - public void processClassReferences(ClassNode node) { - - ClassWrapper wrapper = node.getWrapper(); - - // int major_version = wrapper.getClassStruct().major_version; - // int minor_version = wrapper.getClassStruct().minor_version; - // - // if(major_version > 48 || (major_version == 48 && minor_version > 0)) { - // // version 1.5 or above - // return; - // } - - if (wrapper.getClassStruct().isVersionGE_1_5()) { - // version 1.5 or above - return; - } - + public static void processClassReferences(ClassNode node) { // find the synthetic method Class class$(String) if present HashMap mapClassMeths = new HashMap(); mapClassMethods(node, mapClassMeths); - if (mapClassMeths.isEmpty()) { return; } - HashSet setFound = new HashSet(); processClassRec(node, mapClassMeths, setFound); @@ -173,7 +153,7 @@ public class ClassReference14Processor { } } - private void mapClassMethods(ClassNode node, Map map) { + private static void mapClassMethods(ClassNode node, Map map) { boolean noSynthFlag = DecompilerContext.getOption(IFernflowerPreferences.SYNTHETIC_NOT_SET); ClassWrapper wrapper = node.getWrapper(); diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index b438695..0b016dd 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -43,14 +43,14 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.*; import org.jetbrains.java.decompiler.util.InterpreterUtil; -import java.util.*; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; public class ClassWriter { - private final ClassReference14Processor ref14processor; private final PoolInterceptor interceptor; public ClassWriter() { - ref14processor = new ClassReference14Processor(); interceptor = DecompilerContext.getPoolInterceptor(); } @@ -60,8 +60,10 @@ public class ClassWriter { InitializerProcessor.extractInitializers(wrapper); - if (node.type == ClassNode.CLASS_ROOT && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_CLASS_1_4)) { - ref14processor.processClassReferences(node); + if (node.type == ClassNode.CLASS_ROOT && + !cl.isVersionGE_1_5() && + DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_CLASS_1_4)) { + ClassReference14Processor.processClassReferences(node); } if (cl.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM)) { @@ -273,7 +275,8 @@ public class ClassWriter { } private static void addTracer(StructClass cls, StructMethod method, BytecodeMappingTracer tracer) { - StructLineNumberTableAttribute table = (StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); + StructLineNumberTableAttribute table = + (StructLineNumberTableAttribute)method.getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LINE_NUMBER_TABLE); tracer.setLineNumberTable(table); String key = InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor()); DecompilerContext.getBytecodeSourceMapper().addTracer(cls.qualifiedName, key, tracer); @@ -385,7 +388,12 @@ public class ClassWriter { buffer.append('{').appendLineSeparator(); } - private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { + private void fieldToJava(ClassWrapper wrapper, + StructClass cl, + StructField fd, + TextBuffer buffer, + int indent, + BytecodeMappingTracer tracer) { int start = buffer.length(); boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); boolean isDeprecated = fd.getAttributes().containsKey("Deprecated"); @@ -571,7 +579,9 @@ public class ClassWriter { changed = true; res.append("_"); } - else res.append(c); + else { + res.append(c); + } } if (!changed) { return name; @@ -661,7 +671,7 @@ public class ClassWriter { int actualParams = md.params.length; List sigFields = methodWrapper.signatureFields; if (sigFields != null) { - actualParams = 0; + actualParams = 0; for (VarVersionPair field : methodWrapper.signatureFields) { if (field == null) { actualParams++; @@ -670,7 +680,8 @@ public class ClassWriter { } else if (isEnum && init) actualParams -= 2; if (actualParams != descriptor.params.size()) { - String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor() + " in " + cl.qualifiedName; + String message = + "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor() + " in " + cl.qualifiedName; DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); descriptor = null; } @@ -732,7 +743,8 @@ public class ClassWriter { if (descriptor != null) { GenericType parameterType = descriptor.params.get(i); - boolean isVarArg = (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); + boolean isVarArg = + (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); if (isVarArg) { parameterType = parameterType.decreaseArrayDim(); } @@ -752,7 +764,8 @@ public class ClassWriter { else { VarType parameterType = md.params[i]; - boolean isVarArg = (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); + boolean isVarArg = + (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); if (isVarArg) { parameterType = parameterType.decreaseArrayDim(); } @@ -961,7 +974,8 @@ public class ClassWriter { } private static final String[] PARAMETER_ANNOTATION_ATTRIBUTES = { - StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; + StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, + StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; private static void appendParameterAnnotations(TextBuffer buffer, StructMethod mt, int param) { @@ -981,6 +995,7 @@ public class ClassWriter { } private static final Map MODIFIERS; + static { MODIFIERS = new LinkedHashMap<>(); MODIFIERS.put(CodeConstants.ACC_PUBLIC, "public"); @@ -1003,8 +1018,15 @@ public class ClassWriter { CodeConstants.ACC_PUBLIC | CodeConstants.ACC_PROTECTED | CodeConstants.ACC_PRIVATE | CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL | CodeConstants.ACC_TRANSIENT | CodeConstants.ACC_VOLATILE; private static final int METHOD_ALLOWED = - CodeConstants.ACC_PUBLIC | CodeConstants.ACC_PROTECTED | CodeConstants.ACC_PRIVATE | CodeConstants.ACC_ABSTRACT | - CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL | CodeConstants.ACC_SYNCHRONIZED | CodeConstants.ACC_NATIVE | CodeConstants.ACC_STRICT; + CodeConstants.ACC_PUBLIC | + CodeConstants.ACC_PROTECTED | + CodeConstants.ACC_PRIVATE | + CodeConstants.ACC_ABSTRACT | + CodeConstants.ACC_STATIC | + CodeConstants.ACC_FINAL | + CodeConstants.ACC_SYNCHRONIZED | + CodeConstants.ACC_NATIVE | + CodeConstants.ACC_STRICT; private static final int CLASS_EXCLUDED = CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_STATIC; private static final int FIELD_EXCLUDED = CodeConstants.ACC_PUBLIC | CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL; From c32fce0d025b222e2ade9b95cdd90be3c8a15f70 Mon Sep 17 00:00:00 2001 From: Christopher Carpenter Date: Mon, 14 Mar 2016 02:02:36 -0400 Subject: [PATCH 034/252] Fixed a typo in a comment and in a method name. Made ClassWriter.invokeProcessors static since it no longer relies on any non-static fields. --- .../java/decompiler/code/cfg/BasicBlock.java | 2 +- .../java/decompiler/main/ClassWriter.java | 2 +- .../modules/decompiler/ExprProcessor.java | 22 +++++++++++-------- .../decompiler/stats/BasicBlockStatement.java | 4 +++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java b/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java index 2e29529..0bbaf72 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java @@ -118,7 +118,7 @@ public class BasicBlock implements IGraphNode { block.removePredecessor(this); } - // FIXME: unify block comparisons: id or direkt equality + // FIXME: unify block comparisons: id or direct equality public void replaceSuccessor(BasicBlock oldBlock, BasicBlock newBlock) { for (int i = 0; i < succs.size(); i++) { if (succs.get(i).id == oldBlock.id) { diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 0b016dd..ed7c99d 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -54,7 +54,7 @@ public class ClassWriter { interceptor = DecompilerContext.getPoolInterceptor(); } - private void invokeProcessors(ClassNode node) { + private static void invokeProcessors(ClassNode node) { ClassWrapper wrapper = node.getWrapper(); StructClass cl = wrapper.getClassStruct(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 008d0bb..df1978f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -368,7 +368,7 @@ public class ExprProcessor implements CodeConstants { } else if (cn instanceof LinkConstant) { //TODO: for now treat Links as Strings - pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_STRING, ((LinkConstant)cn).elementname , bytecode_offsets)); + pushEx(stack, exprlist, new ConstExprent(VarType.VARTYPE_STRING, ((LinkConstant)cn).elementname, bytecode_offsets)); } break; case opc_iload: @@ -422,7 +422,8 @@ public class ExprProcessor implements CodeConstants { Exprent index_store = stack.pop(); Exprent arr_store = stack.pop(); AssignmentExprent arrassign = - new AssignmentExprent(new ArrayExprent(arr_store, index_store, arrtypes[instr.opcode - opc_iastore], bytecode_offsets), value, bytecode_offsets); + new AssignmentExprent(new ArrayExprent(arr_store, index_store, arrtypes[instr.opcode - opc_iastore], bytecode_offsets), value, + bytecode_offsets); exprlist.add(arrassign); break; case opc_iadd: @@ -523,7 +524,7 @@ public class ExprProcessor implements CodeConstants { case opc_tableswitch: case opc_lookupswitch: exprlist.add(new SwitchExprent(stack.pop(), bytecode_offsets)); - break; + break; case opc_ireturn: case opc_lreturn: case opc_freturn: @@ -538,7 +539,7 @@ public class ExprProcessor implements CodeConstants { : ((MethodDescriptor)DecompilerContext .getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret, bytecode_offsets)); - break; + break; case opc_monitorenter: case opc_monitorexit: exprlist.add(new MonitorExprent(func8[instr.opcode - opc_monitorenter], stack.pop(), bytecode_offsets)); @@ -552,13 +553,15 @@ public class ExprProcessor implements CodeConstants { case opc_getstatic: case opc_getfield: pushEx(stack, exprlist, - new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_getstatic ? null : stack.pop(), bytecode_offsets)); + new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_getstatic ? null : stack.pop(), + bytecode_offsets)); break; case opc_putstatic: case opc_putfield: Exprent valfield = stack.pop(); Exprent exprfield = - new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_putstatic ? null : stack.pop(), bytecode_offsets); + new FieldExprent(pool.getLinkConstant(instr.getOperand(0)), instr.opcode == opc_putstatic ? null : stack.pop(), + bytecode_offsets); exprlist.add(new AssignmentExprent(exprfield, valfield, bytecode_offsets)); break; case opc_invokevirtual: @@ -755,7 +758,7 @@ public class ExprProcessor implements CodeConstants { return prlst; } - public static boolean endsWithSemikolon(Exprent expr) { + public static boolean endsWithSemicolon(Exprent expr) { int type = expr.type; return !(type == Exprent.EXPRENT_SWITCH || type == Exprent.EXPRENT_MONITOR || @@ -768,7 +771,8 @@ public class ExprProcessor implements CodeConstants { if (stat instanceof BasicBlockStatement) { BasicBlock block = ((BasicBlockStatement)stat).getBlock(); List offsets = block.getInstrOldOffsets(); - if (!offsets.isEmpty() && offsets.size() > block.getSeq().length()) { // some instructions have been deleted, but we still have offsets + if (!offsets.isEmpty() && + offsets.size() > block.getSeq().length()) { // some instructions have been deleted, but we still have offsets tracer.addMapping(offsets.get(offsets.size() - 1)); // add the last offset } } @@ -840,7 +844,7 @@ public class ExprProcessor implements CodeConstants { if (expr.type == Exprent.EXPRENT_MONITOR && ((MonitorExprent)expr).getMonType() == MonitorExprent.MONITOR_ENTER) { buf.append("{}"); // empty synchronized block } - if (endsWithSemikolon(expr)) { + if (endsWithSemicolon(expr)) { buf.append(";"); } buf.appendLineSeparator(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java index 762fd01..334637c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/BasicBlockStatement.java @@ -68,7 +68,9 @@ public class BasicBlockStatement extends Statement { // ***************************************************************************** public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { - return ExprProcessor.listToJava(varDefinitions, indent, tracer).append(ExprProcessor.listToJava(exprents, indent, tracer)); + TextBuffer tb = ExprProcessor.listToJava(varDefinitions, indent, tracer); + tb.append(ExprProcessor.listToJava(exprents, indent, tracer)); + return tb; } public Statement getSimpleCopy() { From d50e8a860e9070c1f6685fcf0009316f55034a8f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 16 Mar 2016 17:34:59 +0100 Subject: [PATCH 035/252] Cleanup (formatting) --- .../main/ClassReference14Processor.java | 71 ++++++++----------- .../java/decompiler/main/ClassWriter.java | 29 ++------ 2 files changed, 38 insertions(+), 62 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java index a36c88e..e97c47e 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,48 +37,39 @@ import java.util.*; import java.util.Map.Entry; public class ClassReference14Processor { - - public static final ExitExprent bodyexprent; - - public static final ExitExprent handlerexprent; + private static final ExitExprent BODY_EXPR; + private static final ExitExprent HANDLER_EXPR; static { + InvocationExprent invFor = new InvocationExprent(); + invFor.setName("forName"); + invFor.setClassname("java/lang/Class"); + invFor.setStringDescriptor("(Ljava/lang/String;)Ljava/lang/Class;"); + invFor.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;")); + invFor.setStatic(true); + invFor.setLstParameters(Collections.singletonList(new VarExprent(0, VarType.VARTYPE_STRING, null))); + BODY_EXPR = new ExitExprent(ExitExprent.EXIT_RETURN, invFor, VarType.VARTYPE_CLASS, null); - InvocationExprent invfor = new InvocationExprent(); - invfor.setName("forName"); - invfor.setClassname("java/lang/Class"); - invfor.setStringDescriptor("(Ljava/lang/String;)Ljava/lang/Class;"); - invfor.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;")); - invfor.setStatic(true); - invfor.setLstParameters(Arrays.asList(new Exprent[]{new VarExprent(0, VarType.VARTYPE_STRING, null)})); + InvocationExprent ctor = new InvocationExprent(); + ctor.setName(CodeConstants.INIT_NAME); + ctor.setClassname("java/lang/NoClassDefFoundError"); + ctor.setStringDescriptor("()V"); + ctor.setFunctype(InvocationExprent.TYP_INIT); + ctor.setDescriptor(MethodDescriptor.parseDescriptor("()V")); - bodyexprent = new ExitExprent(ExitExprent.EXIT_RETURN, - invfor, - VarType.VARTYPE_CLASS, null); + NewExprent newExpr = new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<>(), null); + newExpr.setConstructor(ctor); - InvocationExprent constr = new InvocationExprent(); - constr.setName(CodeConstants.INIT_NAME); - constr.setClassname("java/lang/NoClassDefFoundError"); - constr.setStringDescriptor("()V"); - constr.setFunctype(InvocationExprent.TYP_INIT); - constr.setDescriptor(MethodDescriptor.parseDescriptor("()V")); + InvocationExprent invCause = new InvocationExprent(); + invCause.setName("initCause"); + invCause.setClassname("java/lang/NoClassDefFoundError"); + invCause.setStringDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); + invCause.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;")); + invCause.setInstance(newExpr); + invCause.setLstParameters( + Collections.singletonList(new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null))); - NewExprent newexpr = - new NewExprent(new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/NoClassDefFoundError"), new ArrayList<>(), null); - newexpr.setConstructor(constr); - - InvocationExprent invcause = new InvocationExprent(); - invcause.setName("initCause"); - invcause.setClassname("java/lang/NoClassDefFoundError"); - invcause.setStringDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); - invcause.setDescriptor(MethodDescriptor.parseDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;")); - invcause.setInstance(newexpr); - invcause.setLstParameters( - Arrays.asList(new Exprent[]{new VarExprent(2, new VarType(CodeConstants.TYPE_OBJECT, 0, "java/lang/ClassNotFoundException"), null)})); - - handlerexprent = new ExitExprent(ExitExprent.EXIT_THROW, - invcause, - null, null); + HANDLER_EXPR = new ExitExprent(ExitExprent.EXIT_THROW, invCause, null, null); } public static void processClassReferences(ClassNode node) { @@ -176,8 +167,8 @@ public class ClassReference14Processor { BasicBlockStatement handler = (BasicBlockStatement)cst.getStats().get(1); if (body.getExprents().size() == 1 && handler.getExprents().size() == 1) { - if (bodyexprent.equals(body.getExprents().get(0)) && - handlerexprent.equals(handler.getExprents().get(0))) { + if (BODY_EXPR.equals(body.getExprents().get(0)) && + HANDLER_EXPR.equals(handler.getExprents().get(0))) { map.put(wrapper, method); break; } @@ -273,4 +264,4 @@ public class ClassReference14Processor { return null; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index ed7c99d..f79198f 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -388,12 +388,7 @@ public class ClassWriter { buffer.append('{').appendLineSeparator(); } - private void fieldToJava(ClassWrapper wrapper, - StructClass cl, - StructField fd, - TextBuffer buffer, - int indent, - BytecodeMappingTracer tracer) { + private void fieldToJava(ClassWrapper wrapper, StructClass cl, StructField fd, TextBuffer buffer, int indent, BytecodeMappingTracer tracer) { int start = buffer.length(); boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); boolean isDeprecated = fd.getAttributes().containsKey("Deprecated"); @@ -680,8 +675,7 @@ public class ClassWriter { } else if (isEnum && init) actualParams -= 2; if (actualParams != descriptor.params.size()) { - String message = - "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor() + " in " + cl.qualifiedName; + String message = "Inconsistent generic signature in method " + mt.getName() + " " + mt.getDescriptor() + " in " + cl.qualifiedName; DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); descriptor = null; } @@ -743,8 +737,7 @@ public class ClassWriter { if (descriptor != null) { GenericType parameterType = descriptor.params.get(i); - boolean isVarArg = - (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); + boolean isVarArg = (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); if (isVarArg) { parameterType = parameterType.decreaseArrayDim(); } @@ -764,8 +757,7 @@ public class ClassWriter { else { VarType parameterType = md.params[i]; - boolean isVarArg = - (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); + boolean isVarArg = (i == lastVisibleParameterIndex && mt.hasModifier(CodeConstants.ACC_VARARGS) && parameterType.arrayDim > 0); if (isVarArg) { parameterType = parameterType.decreaseArrayDim(); } @@ -995,7 +987,6 @@ public class ClassWriter { } private static final Map MODIFIERS; - static { MODIFIERS = new LinkedHashMap<>(); MODIFIERS.put(CodeConstants.ACC_PUBLIC, "public"); @@ -1018,14 +1009,8 @@ public class ClassWriter { CodeConstants.ACC_PUBLIC | CodeConstants.ACC_PROTECTED | CodeConstants.ACC_PRIVATE | CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL | CodeConstants.ACC_TRANSIENT | CodeConstants.ACC_VOLATILE; private static final int METHOD_ALLOWED = - CodeConstants.ACC_PUBLIC | - CodeConstants.ACC_PROTECTED | - CodeConstants.ACC_PRIVATE | - CodeConstants.ACC_ABSTRACT | - CodeConstants.ACC_STATIC | - CodeConstants.ACC_FINAL | - CodeConstants.ACC_SYNCHRONIZED | - CodeConstants.ACC_NATIVE | + CodeConstants.ACC_PUBLIC | CodeConstants.ACC_PROTECTED | CodeConstants.ACC_PRIVATE | CodeConstants.ACC_ABSTRACT | + CodeConstants.ACC_STATIC | CodeConstants.ACC_FINAL | CodeConstants.ACC_SYNCHRONIZED | CodeConstants.ACC_NATIVE | CodeConstants.ACC_STRICT; private static final int CLASS_EXCLUDED = CodeConstants.ACC_ABSTRACT | CodeConstants.ACC_STATIC; @@ -1065,4 +1050,4 @@ public class ClassWriter { buffer.append('>'); } -} +} \ No newline at end of file From 06c993b508c2c9079d87cdeddd7c18ba2d842dfe Mon Sep 17 00:00:00 2001 From: Alexandru-Constantin Bledea Date: Mon, 7 Mar 2016 18:52:37 +0200 Subject: [PATCH 036/252] correctly decompile interface object fields --- .../decompiler/main/InitializerProcessor.java | 5 +++-- .../java/decompiler/SingleClassesTest.java | 5 +++-- .../classes/pkg/TestInterfaceWithObject.class | Bin 0 -> 329 bytes testData/results/TestInterfaceWithObject.dec | 8 ++++++++ testData/src/pkg/TestInterfaceWithObject.java | 13 +++++++++++++ 5 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 testData/classes/pkg/TestInterfaceWithObject.class create mode 100644 testData/results/TestInterfaceWithObject.dec create mode 100644 testData/src/pkg/TestInterfaceWithObject.java diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java index d9a0a3d..e1363d8 100644 --- a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -124,7 +124,7 @@ public class InitializerProcessor { RootStatement root = meth.root; StructClass cl = wrapper.getClassStruct(); - + boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); Statement firstdata = findFirstData(root); if (firstdata != null) { while (!firstdata.getExprents().isEmpty()) { @@ -139,7 +139,8 @@ public class InitializerProcessor { if (fexpr.isStatic() && fexpr.getClassname().equals(cl.qualifiedName) && cl.hasField(fexpr.getName(), fexpr.getDescriptor().descriptorString)) { - if (isExprentIndependent(asexpr.getRight(), meth)) { + // interfaces fields should always be initialized inline + if (isInterface || isExprentIndependent(asexpr.getRight(), meth)) { String keyField = InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString); if (!wrapper.getStaticFieldInitializers().containsKey(keyField)) { diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index c5bcf8c..180428d 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -83,6 +83,7 @@ public class SingleClassesTest { @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } + @Test public void testInterfaceWithObject() { doTest("pkg/TestInterfaceWithObject"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); @@ -107,7 +108,7 @@ public class SingleClassesTest { File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); assertTrue(decompiledFile.isFile()); File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); - assertTrue(referenceFile.isFile()); + assertTrue("Expecting " + referenceFile.getAbsolutePath() + " to be a file", referenceFile.isFile()); assertFilesEqual(referenceFile, decompiledFile); } @@ -129,4 +130,4 @@ public class SingleClassesTest { return files; } -} \ No newline at end of file +} diff --git a/testData/classes/pkg/TestInterfaceWithObject.class b/testData/classes/pkg/TestInterfaceWithObject.class new file mode 100644 index 0000000000000000000000000000000000000000..614da5e600cf35a42e4fa5b2bf313c42b99c74f5 GIT binary patch literal 329 zcmZ`!yH3ME5S)vHAHyOV(QG&JddhP_I@MkWlH)Uk*iQmw*x1A9l~l^}Vitk;7U>m@PNr?ae literal 0 HcmV?d00001 diff --git a/testData/results/TestInterfaceWithObject.dec b/testData/results/TestInterfaceWithObject.dec new file mode 100644 index 0000000..5afeed6 --- /dev/null +++ b/testData/results/TestInterfaceWithObject.dec @@ -0,0 +1,8 @@ +package pkg; + +import java.math.BigDecimal; + +public interface TestInterfaceWithObject { + BigDecimal BUGS_IN_THE_DECOMPILER = BigDecimal.ZERO; +} + diff --git a/testData/src/pkg/TestInterfaceWithObject.java b/testData/src/pkg/TestInterfaceWithObject.java new file mode 100644 index 0000000..4653d70 --- /dev/null +++ b/testData/src/pkg/TestInterfaceWithObject.java @@ -0,0 +1,13 @@ +package pkg; + +import java.math.BigDecimal; + +/** + * @author Alexandru-Constantin Bledea + * @since March 06, 2016 + */ +public interface TestInterfaceWithObject { + + BigDecimal BUGS_IN_THE_DECOMPILER = BigDecimal.ZERO; + +} From 13595773550f5511e8431058699d04faa8d0d6ad Mon Sep 17 00:00:00 2001 From: Alexandru-Constantin Bledea Date: Thu, 17 Mar 2016 23:15:54 +0200 Subject: [PATCH 037/252] add additional tests for static initializers --- .../java/decompiler/SingleClassesTest.java | 4 ++- testData/classes/pkg/TestClassFields.class | Bin 415 -> 513 bytes .../classes/pkg/TestInterfaceWithObject.class | Bin 329 -> 0 bytes .../pkg/TestInterfaceWithObjectField.class | Bin 0 -> 339 bytes .../pkg/TestInterfaceWithPrimitiveField.class | Bin 0 -> 225 bytes .../pkg/TestMutableStaticOtherClass.class | Bin 0 -> 462 bytes testData/results/TestClassFields.dec | 17 +++++------ ...t.dec => TestInterfaceWithObjectField.dec} | 2 +- .../TestInterfaceWithPrimitiveField.dec | 6 ++++ .../results/TestMutableStaticOtherClass.dec | 27 ++++++++++++++++++ testData/src/pkg/TestClassFields.java | 1 + ...java => TestInterfaceWithObjectField.java} | 2 +- .../pkg/TestInterfaceWithPrimitiveField.java | 13 +++++++++ .../src/pkg/TestMutableStaticOtherClass.java | 15 ++++++++++ 14 files changed, 76 insertions(+), 11 deletions(-) delete mode 100644 testData/classes/pkg/TestInterfaceWithObject.class create mode 100644 testData/classes/pkg/TestInterfaceWithObjectField.class create mode 100644 testData/classes/pkg/TestInterfaceWithPrimitiveField.class create mode 100644 testData/classes/pkg/TestMutableStaticOtherClass.class rename testData/results/{TestInterfaceWithObject.dec => TestInterfaceWithObjectField.dec} (68%) create mode 100644 testData/results/TestInterfaceWithPrimitiveField.dec create mode 100644 testData/results/TestMutableStaticOtherClass.dec rename testData/src/pkg/{TestInterfaceWithObject.java => TestInterfaceWithObjectField.java} (78%) create mode 100644 testData/src/pkg/TestInterfaceWithPrimitiveField.java create mode 100644 testData/src/pkg/TestMutableStaticOtherClass.java diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 180428d..cbbbc2d 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -83,7 +83,9 @@ public class SingleClassesTest { @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } - @Test public void testInterfaceWithObject() { doTest("pkg/TestInterfaceWithObject"); } + @Test public void testInterfaceWithPrimitiveField() { doTest("pkg/TestInterfaceWithPrimitiveField"); } + @Test public void testInterfaceWithObjectField() { doTest("pkg/TestInterfaceWithObjectField"); } + @Test public void testTestMutableStaticOtherClass() { doTest("pkg/TestMutableStaticOtherClass"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestClassFields.class b/testData/classes/pkg/TestClassFields.class index 603bab20676cb402340cf83eb6720ffaac0b2a17..a25091d6a5f2925bb6daf82bf43f81a91b474d8b 100644 GIT binary patch delta 274 zcmbQw+{j{c>ff$?3=9k=42oO~91N1|3{o5n(i{vjoDA#?vLHf^ok5Qj)Nt{;+GT;iOQ zSX}IunVOSQY(25skeQ!BVB&gJ4qgU69tLg(o{4vil9++kb24xN-NFSD0@FZwAkDHn5-&gD{ZI15v;r!XOIdaWIHMG*1p=)R6_L YyOV(QG&JddhP_I@MkWlH)Uk*iQmw*x1A9l~l^}Vitk;7U>m@PNr?ae diff --git a/testData/classes/pkg/TestInterfaceWithObjectField.class b/testData/classes/pkg/TestInterfaceWithObjectField.class new file mode 100644 index 0000000000000000000000000000000000000000..bf7ec687a2f7be273dd0d02d72e5c8dff7d985ac GIT binary patch literal 339 zcmaJ-Jx{|x41L#>e9%A(R7gy~1`Ao(iWu6a5GgdM4Ir^Zm-I-lBq<74{ui(@@B{c! z2q&xv5B7VuY(M+!`{NV9DY_OmuxUX<+d#*_7Q=4;=3*Lo<0!mzqoF$puC6`bolwDF z@E7jnT+N-nOot+oInR0w=2?=-LaK8H?dbTHp*dL21Vh`Gg&42$Sd<};Gs>(_m#Z=n zBUzEdP&_NIP@;U`iMW$$9>fcgsF4)e?4;UdVB5wHbQ^2X84jKvQ|G@XhE6Rp<3;NH z4rA#4rJ6L}yOV&1YG~3Y81||iH8Nqqq>M#upJHXk8`wJv9Pq`pFU7vtnMg{?dHvgoo)Z`L2Mg}GZkUJO| WBpFy3Sb;PfkjKQp4i@78vpE6pB04$% literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestMutableStaticOtherClass.class b/testData/classes/pkg/TestMutableStaticOtherClass.class new file mode 100644 index 0000000000000000000000000000000000000000..14b1efdd89c333e2f89f96ac09e3d32c47ea60c7 GIT binary patch literal 462 zcmah_O;5r=5PefhTS@^1Ke;G3KN5TKChm&Z|3cMe7?N{xJ2DY9@PSB*eSrqu8Tbv`vkk+xxXP$hu}2TLg{Nl?&NgH zOlvuogi2Q}jl;tIWvM_MwF4u#5N0kM*IiH7Ph|t|K(qA literal 0 HcmV?d00001 diff --git a/testData/results/TestClassFields.dec b/testData/results/TestClassFields.dec index 75ece1e..d139051 100644 --- a/testData/results/TestClassFields.dec +++ b/testData/results/TestClassFields.dec @@ -1,25 +1,26 @@ package pkg; public class TestClassFields { + static int staticMutable; private static int[] sizes; private static String[] names = new String[]{"name1", "name2"}; static { - sizes = new int[names.length];// 26 - }// 27 + sizes = new int[names.length];// 27 + }// 28 } class 'pkg/TestClassFields' { method ' ()V' { - 11 7 - 14 7 - 17 7 - 1a 8 + 11 8 + 14 8 + 17 8 + 1a 9 } } Lines mapping: -26 <-> 8 27 <-> 9 +28 <-> 10 Not mapped: -25 +26 diff --git a/testData/results/TestInterfaceWithObject.dec b/testData/results/TestInterfaceWithObjectField.dec similarity index 68% rename from testData/results/TestInterfaceWithObject.dec rename to testData/results/TestInterfaceWithObjectField.dec index 5afeed6..c9418d8 100644 --- a/testData/results/TestInterfaceWithObject.dec +++ b/testData/results/TestInterfaceWithObjectField.dec @@ -2,7 +2,7 @@ package pkg; import java.math.BigDecimal; -public interface TestInterfaceWithObject { +public interface TestInterfaceWithObjectField { BigDecimal BUGS_IN_THE_DECOMPILER = BigDecimal.ZERO; } diff --git a/testData/results/TestInterfaceWithPrimitiveField.dec b/testData/results/TestInterfaceWithPrimitiveField.dec new file mode 100644 index 0000000..542e858 --- /dev/null +++ b/testData/results/TestInterfaceWithPrimitiveField.dec @@ -0,0 +1,6 @@ +package pkg; + +public interface TestInterfaceWithPrimitiveField { + int MAX_BYTE_VALUE = 127; +} + diff --git a/testData/results/TestMutableStaticOtherClass.dec b/testData/results/TestMutableStaticOtherClass.dec new file mode 100644 index 0000000..6e7ed33 --- /dev/null +++ b/testData/results/TestMutableStaticOtherClass.dec @@ -0,0 +1,27 @@ +package pkg; + +import pkg.TestClassFields; + +public class TestMutableStaticOtherClass { + private static final int SIZE; + + static { + TestClassFields.staticMutable = 3;// 12 + SIZE = TestClassFields.staticMutable;// 13 + }// 14 +} + +class 'pkg/TestMutableStaticOtherClass' { + method ' ()V' { + 0 8 + 1 8 + 4 9 + 7 9 + a 10 + } +} + +Lines mapping: +12 <-> 9 +13 <-> 10 +14 <-> 11 diff --git a/testData/src/pkg/TestClassFields.java b/testData/src/pkg/TestClassFields.java index a1f2fac..2341ff7 100644 --- a/testData/src/pkg/TestClassFields.java +++ b/testData/src/pkg/TestClassFields.java @@ -17,6 +17,7 @@ package pkg; public class TestClassFields { + static int staticMutable; private static int[] sizes; private static String[] names; diff --git a/testData/src/pkg/TestInterfaceWithObject.java b/testData/src/pkg/TestInterfaceWithObjectField.java similarity index 78% rename from testData/src/pkg/TestInterfaceWithObject.java rename to testData/src/pkg/TestInterfaceWithObjectField.java index 4653d70..ac0bd64 100644 --- a/testData/src/pkg/TestInterfaceWithObject.java +++ b/testData/src/pkg/TestInterfaceWithObjectField.java @@ -6,7 +6,7 @@ import java.math.BigDecimal; * @author Alexandru-Constantin Bledea * @since March 06, 2016 */ -public interface TestInterfaceWithObject { +public interface TestInterfaceWithObjectField { BigDecimal BUGS_IN_THE_DECOMPILER = BigDecimal.ZERO; diff --git a/testData/src/pkg/TestInterfaceWithPrimitiveField.java b/testData/src/pkg/TestInterfaceWithPrimitiveField.java new file mode 100644 index 0000000..89d1b7a --- /dev/null +++ b/testData/src/pkg/TestInterfaceWithPrimitiveField.java @@ -0,0 +1,13 @@ +package pkg; + +import java.math.BigDecimal; + +/** + * @author Alexandru-Constantin Bledea + * @since March 06, 2016 + */ +public interface TestInterfaceWithPrimitiveField { + + int MAX_BYTE_VALUE = Byte.MAX_VALUE; + +} diff --git a/testData/src/pkg/TestMutableStaticOtherClass.java b/testData/src/pkg/TestMutableStaticOtherClass.java new file mode 100644 index 0000000..4015c83 --- /dev/null +++ b/testData/src/pkg/TestMutableStaticOtherClass.java @@ -0,0 +1,15 @@ +package pkg; + +/** + * @author Alexandru-Constantin Bledea + * @since March 17, 2016 + */ +public class TestMutableStaticOtherClass { + + private static final int SIZE; + + static { + TestClassFields.staticMutable = 3; + SIZE = TestClassFields.staticMutable; + } +} From 93a39b7b50beaec7b96adbb75141fe5ba3d39c47 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 18 Mar 2016 18:02:33 +0100 Subject: [PATCH 038/252] [java-decompiler] test data cleanup; warnings --- .../decompiler/DecompilerTestFixture.java | 10 ++++--- .../java/decompiler/SingleClassesTest.java | 8 ++---- .../classes/pkg/TestClassFields$Inner.class | Bin 0 -> 441 bytes testData/classes/pkg/TestClassFields.class | Bin 513 -> 592 bytes .../classes/pkg/TestInterfaceFields.class | Bin 0 -> 385 bytes .../pkg/TestInterfaceWithObjectField.class | Bin 339 -> 0 bytes .../pkg/TestInterfaceWithPrimitiveField.class | Bin 225 -> 0 bytes .../pkg/TestMutableStaticOtherClass.class | Bin 462 -> 0 bytes testData/results/TestClassFields.dec | 25 +++++++++++----- testData/results/TestInterfaceFields.dec | 9 ++++++ .../results/TestInterfaceWithObjectField.dec | 8 ------ .../TestInterfaceWithPrimitiveField.dec | 6 ---- .../results/TestMutableStaticOtherClass.dec | 27 ------------------ testData/src/pkg/TestClassFields.java | 27 ++++++------------ testData/src/pkg/TestInterfaceFields.java | 8 ++++++ .../src/pkg/TestInterfaceWithObjectField.java | 13 --------- .../pkg/TestInterfaceWithPrimitiveField.java | 13 --------- .../src/pkg/TestMutableStaticOtherClass.java | 15 ---------- 18 files changed, 53 insertions(+), 116 deletions(-) create mode 100644 testData/classes/pkg/TestClassFields$Inner.class create mode 100644 testData/classes/pkg/TestInterfaceFields.class delete mode 100644 testData/classes/pkg/TestInterfaceWithObjectField.class delete mode 100644 testData/classes/pkg/TestInterfaceWithPrimitiveField.class delete mode 100644 testData/classes/pkg/TestMutableStaticOtherClass.class create mode 100644 testData/results/TestInterfaceFields.dec delete mode 100644 testData/results/TestInterfaceWithObjectField.dec delete mode 100644 testData/results/TestInterfaceWithPrimitiveField.dec delete mode 100644 testData/results/TestMutableStaticOtherClass.dec create mode 100644 testData/src/pkg/TestInterfaceFields.java delete mode 100644 testData/src/pkg/TestInterfaceWithObjectField.java delete mode 100644 testData/src/pkg/TestInterfaceWithPrimitiveField.java delete mode 100644 testData/src/pkg/TestMutableStaticOtherClass.java diff --git a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java index b3385e2..58f6db0 100644 --- a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java +++ b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -104,13 +105,14 @@ public class DecompilerTestFixture { public static void assertFilesEqual(File expected, File actual) { if (expected.isDirectory()) { - assertThat(actual.list(), Matchers.arrayContainingInAnyOrder(expected.list())); - for (String name : expected.list()) { + String[] children = Objects.requireNonNull(expected.list()); + assertThat(actual.list(), Matchers.arrayContainingInAnyOrder(children)); + for (String name : children) { assertFilesEqual(new File(expected, name), new File(actual, name)); } } else { - assertThat(getContent(actual), Matchers.equalTo(getContent(expected))); + assertEquals(getContent(expected), getContent(actual)); } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index cbbbc2d..e905fb3 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -46,6 +46,7 @@ public class SingleClassesTest { } @Test public void testClassFields() { doTest("pkg/TestClassFields"); } + @Test public void testInterfaceFields() { doTest("pkg/TestInterfaceFields"); } @Test public void testClassLambda() { doTest("pkg/TestClassLambda"); } @Test public void testClassLoop() { doTest("pkg/TestClassLoop"); } @Test public void testClassSwitch() { doTest("pkg/TestClassSwitch"); } @@ -83,9 +84,6 @@ public class SingleClassesTest { @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } - @Test public void testInterfaceWithPrimitiveField() { doTest("pkg/TestInterfaceWithPrimitiveField"); } - @Test public void testInterfaceWithObjectField() { doTest("pkg/TestInterfaceWithObjectField"); } - @Test public void testTestMutableStaticOtherClass() { doTest("pkg/TestMutableStaticOtherClass"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); @@ -110,7 +108,7 @@ public class SingleClassesTest { File decompiledFile = new File(fixture.getTargetDir(), testName + ".java"); assertTrue(decompiledFile.isFile()); File referenceFile = new File(fixture.getTestDataDir(), "results/" + testName + ".dec"); - assertTrue("Expecting " + referenceFile.getAbsolutePath() + " to be a file", referenceFile.isFile()); + assertTrue(referenceFile.isFile()); assertFilesEqual(referenceFile, decompiledFile); } @@ -132,4 +130,4 @@ public class SingleClassesTest { return files; } -} +} \ No newline at end of file diff --git a/testData/classes/pkg/TestClassFields$Inner.class b/testData/classes/pkg/TestClassFields$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..1c16a7e3b3a72a2d00987cd024702775f328a0ae GIT binary patch literal 441 zcmZvYOH0E*6ot<;uQsMO+WM%dxagvFVS>06H-$pL$HF4GoTNiZO;gDv{wg=>LU7>^ z@JESvVnC3r&dizboIBjF?~hLaXXv+}VZ(-wO$$8>I}B}^^E{5OikyduU|<1*c^;>6 ze!-v(M|TYRcr~M!&Sjj6>tY#-Z2HUEJc@*r1K&R-Y8Z?t`{(&(URk%RB8$W%R{g!H zkoh>_Qchx#%;d>}KXC^JOa~U47Iqo>j}LS2A2$fnRAdZBrB113k&q0os__z@&b^y( zA)=h2ThoFgT7XWwpkJw(bkfjJgUM;p?SPb#8prQwyi_0vRHp7Wu?D9?4=JczbMO8Q h?74<*W4&VcOOhI1Ye?$pP`UvZ+oU$J8oJnm{R2F=OsoI^ literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestClassFields.class b/testData/classes/pkg/TestClassFields.class index a25091d6a5f2925bb6daf82bf43f81a91b474d8b..e8788e044b56381c8df5b82c7da5c6fa33ec8ee3 100644 GIT binary patch literal 592 zcmZva%TB^T6o&tyl$Kfr!5iKXMFcg1#+}9u(WD8%MU4hol{z8SQVgvwd@E%kG3o>O zP{uP2kx1N}f6isjd}n69zTZ9p9Aa0)1eO)7s905zjYGqlFgXo6)`i&+ZeGErf`WoA z2HEgD-eb^1t-6-)bDzS#^CUFVG|2I+j&Rb=+O73ym0ingm(8H(c=RS>Vb}Fq;w>Z)KNr9$2N9!q%lL__jm2`Snod_&s(?L4j3~3 z6y}FFq*=DjeLr8R9MEV*qeKIbVwG@c139|i33?2Plu&4;2`bzV9&H*SRfkxdsi@h9`~vy&UF#zj8$h`lKNN+Mc1;mRf*_`mC7exyiI697mMAAM=@XEhg!Tg~K5Qre delta 313 zcmX|5%}T>S7@SQ~vyExh)%w#^YY{;ODT=px69l0igd%ucYtUdoao4kW^ceae;z|7NK3Q+=1YU@%StdzBf1M*sHuvO7qPJ;=2&hgq6mm|pR` z<4<9__+FPa)MHE{9<{~h13Ek?`HoMlB4QP}uw-_UJqU1=I78JX3vy-a72>6g6>*|8 z6=qq-;|9#3K_xN&Kioq=2S_UK@XmbYkA8$&b6W)5mO9@6nmm*cTXYwwJuLnKU$ZPj diff --git a/testData/classes/pkg/TestInterfaceFields.class b/testData/classes/pkg/TestInterfaceFields.class new file mode 100644 index 0000000000000000000000000000000000000000..4f39e335d3d806c1938a24d5ac0a36a3deb8ea8e GIT binary patch literal 385 zcmZusyH3ME5S&Xw&VeKZ2zk)ZLW3JR5K>TET;~@KtM8!7&9R(l2 zM1K+Q#T#L&DL+)k`J*PeKT(T&Z(9EQel5vN+j+7nSG%XH$6)Q*El#Y&$rl=t>M zhRSd;l?>}670b(P?#sj#eniab^&(3Gd8YEA=gL$&v6jh$$T=BJ(}Ua$-7Y*uA`VUK zRZEUu9ewaRs^ARW=cmwIvdqx>-y8cg8EA&~vUp@MPhX{u6$()zb&@93hk+W%X~C`$ hGEhf@dXt!4>iOdzD1D;*PLN_!trj17ZP8T1#vecpQhWda literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestInterfaceWithObjectField.class b/testData/classes/pkg/TestInterfaceWithObjectField.class deleted file mode 100644 index bf7ec687a2f7be273dd0d02d72e5c8dff7d985ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmaJ-Jx{|x41L#>e9%A(R7gy~1`Ao(iWu6a5GgdM4Ir^Zm-I-lBq<74{ui(@@B{c! z2q&xv5B7VuY(M+!`{NV9DY_OmuxUX<+d#*_7Q=4;=3*Lo<0!mzqoF$puC6`bolwDF z@E7jnT+N-nOot+oInR0w=2?=-LaK8H?dbTHp*dL21Vh`Gg&42$Sd<};Gs>(_m#Z=n zBUzEdP&_NIP@;U`iMW$$9>fcgsF4)e?4;UdVB5wHbQ^2X84jKvQ|G@XhE6Rp<3;NH z4rA#4rJ6L}yOV&1YG~3Y81||iH8Nqqq>M#upJHXk8`wJv9Pq`pFU7vtnMg{?dHvgoo)Z`L2Mg}GZkUJO| WBpFy3Sb;PfkjKQp4i@78vpE6pB04$% diff --git a/testData/classes/pkg/TestMutableStaticOtherClass.class b/testData/classes/pkg/TestMutableStaticOtherClass.class deleted file mode 100644 index 14b1efdd89c333e2f89f96ac09e3d32c47ea60c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 462 zcmah_O;5r=5PefhTS@^1Ke;G3KN5TKChm&Z|3cMe7?N{xJ2DY9@PSB*eSrqu8Tbv`vkk+xxXP$hu}2TLg{Nl?&NgH zOlvuogi2Q}jl;tIWvM_MwF4u#5N0kM*IiH7Ph|t|K(qA diff --git a/testData/results/TestClassFields.dec b/testData/results/TestClassFields.dec index d139051..6917171 100644 --- a/testData/results/TestClassFields.dec +++ b/testData/results/TestClassFields.dec @@ -1,26 +1,37 @@ package pkg; public class TestClassFields { - static int staticMutable; private static int[] sizes; private static String[] names = new String[]{"name1", "name2"}; + private static final int SIZE; static { - sizes = new int[names.length];// 27 - }// 28 + sizes = new int[names.length];// 15 + TestClassFields.Inner.staticMutable = 3;// 17 + SIZE = TestClassFields.Inner.staticMutable;// 14 18 + }// 19 + + private static class Inner { + private static int staticMutable; + } } class 'pkg/TestClassFields' { method ' ()V' { + 0 10 + 2 9 11 8 14 8 17 8 1a 9 + 22 10 + 25 11 } } Lines mapping: -27 <-> 9 -28 <-> 10 -Not mapped: -26 +14 <-> 11 +15 <-> 9 +17 <-> 10 +18 <-> 11 +19 <-> 12 diff --git a/testData/results/TestInterfaceFields.dec b/testData/results/TestInterfaceFields.dec new file mode 100644 index 0000000..d08e2fe --- /dev/null +++ b/testData/results/TestInterfaceFields.dec @@ -0,0 +1,9 @@ +package pkg; + +import java.math.BigDecimal; + +public interface TestInterfaceFields { + BigDecimal BIG_ZERO = BigDecimal.ZERO; + int MAX_BYTE_VALUE = 127; +} + diff --git a/testData/results/TestInterfaceWithObjectField.dec b/testData/results/TestInterfaceWithObjectField.dec deleted file mode 100644 index c9418d8..0000000 --- a/testData/results/TestInterfaceWithObjectField.dec +++ /dev/null @@ -1,8 +0,0 @@ -package pkg; - -import java.math.BigDecimal; - -public interface TestInterfaceWithObjectField { - BigDecimal BUGS_IN_THE_DECOMPILER = BigDecimal.ZERO; -} - diff --git a/testData/results/TestInterfaceWithPrimitiveField.dec b/testData/results/TestInterfaceWithPrimitiveField.dec deleted file mode 100644 index 542e858..0000000 --- a/testData/results/TestInterfaceWithPrimitiveField.dec +++ /dev/null @@ -1,6 +0,0 @@ -package pkg; - -public interface TestInterfaceWithPrimitiveField { - int MAX_BYTE_VALUE = 127; -} - diff --git a/testData/results/TestMutableStaticOtherClass.dec b/testData/results/TestMutableStaticOtherClass.dec deleted file mode 100644 index 6e7ed33..0000000 --- a/testData/results/TestMutableStaticOtherClass.dec +++ /dev/null @@ -1,27 +0,0 @@ -package pkg; - -import pkg.TestClassFields; - -public class TestMutableStaticOtherClass { - private static final int SIZE; - - static { - TestClassFields.staticMutable = 3;// 12 - SIZE = TestClassFields.staticMutable;// 13 - }// 14 -} - -class 'pkg/TestMutableStaticOtherClass' { - method ' ()V' { - 0 8 - 1 8 - 4 9 - 7 9 - a 10 - } -} - -Lines mapping: -12 <-> 9 -13 <-> 10 -14 <-> 11 diff --git a/testData/src/pkg/TestClassFields.java b/testData/src/pkg/TestClassFields.java index 2341ff7..8a77fe0 100644 --- a/testData/src/pkg/TestClassFields.java +++ b/testData/src/pkg/TestClassFields.java @@ -1,29 +1,20 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package pkg; public class TestClassFields { + private static class Inner { + private static int staticMutable; + } - static int staticMutable; private static int[] sizes; private static String[] names; - static { + private static final int SIZE; + static { names = new String[]{"name1", "name2"}; sizes = new int[names.length]; + + Inner.staticMutable = 3; + SIZE = Inner.staticMutable; } -} +} \ No newline at end of file diff --git a/testData/src/pkg/TestInterfaceFields.java b/testData/src/pkg/TestInterfaceFields.java new file mode 100644 index 0000000..e117258 --- /dev/null +++ b/testData/src/pkg/TestInterfaceFields.java @@ -0,0 +1,8 @@ +package pkg; + +import java.math.BigDecimal; + +public interface TestInterfaceFields { + BigDecimal BIG_ZERO = BigDecimal.ZERO; + int MAX_BYTE_VALUE = Byte.MAX_VALUE; +} \ No newline at end of file diff --git a/testData/src/pkg/TestInterfaceWithObjectField.java b/testData/src/pkg/TestInterfaceWithObjectField.java deleted file mode 100644 index ac0bd64..0000000 --- a/testData/src/pkg/TestInterfaceWithObjectField.java +++ /dev/null @@ -1,13 +0,0 @@ -package pkg; - -import java.math.BigDecimal; - -/** - * @author Alexandru-Constantin Bledea - * @since March 06, 2016 - */ -public interface TestInterfaceWithObjectField { - - BigDecimal BUGS_IN_THE_DECOMPILER = BigDecimal.ZERO; - -} diff --git a/testData/src/pkg/TestInterfaceWithPrimitiveField.java b/testData/src/pkg/TestInterfaceWithPrimitiveField.java deleted file mode 100644 index 89d1b7a..0000000 --- a/testData/src/pkg/TestInterfaceWithPrimitiveField.java +++ /dev/null @@ -1,13 +0,0 @@ -package pkg; - -import java.math.BigDecimal; - -/** - * @author Alexandru-Constantin Bledea - * @since March 06, 2016 - */ -public interface TestInterfaceWithPrimitiveField { - - int MAX_BYTE_VALUE = Byte.MAX_VALUE; - -} diff --git a/testData/src/pkg/TestMutableStaticOtherClass.java b/testData/src/pkg/TestMutableStaticOtherClass.java deleted file mode 100644 index 4015c83..0000000 --- a/testData/src/pkg/TestMutableStaticOtherClass.java +++ /dev/null @@ -1,15 +0,0 @@ -package pkg; - -/** - * @author Alexandru-Constantin Bledea - * @since March 17, 2016 - */ -public class TestMutableStaticOtherClass { - - private static final int SIZE; - - static { - TestClassFields.staticMutable = 3; - SIZE = TestClassFields.staticMutable; - } -} From 0e514a62539310acfe380cbb71791656247cf23b Mon Sep 17 00:00:00 2001 From: Alexandru-Constantin Bledea Date: Sat, 19 Mar 2016 20:44:29 +0200 Subject: [PATCH 039/252] fix constructor arguments for extended inner classes --- .../decompiler/exps/InvocationExprent.java | 2 +- .../java/decompiler/SingleClassesTest.java | 3 +- .../pkg/TestExtendingSubclass$Subclass1.class | Bin 0 -> 555 bytes .../pkg/TestExtendingSubclass$Subclass2.class | Bin 0 -> 594 bytes .../classes/pkg/TestExtendingSubclass.class | Bin 0 -> 441 bytes testData/results/TestExtendingSubclass.dec | 35 ++++++++++++++++++ testData/src/pkg/TestExtendingSubclass.java | 18 +++++++++ 7 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 testData/classes/pkg/TestExtendingSubclass$Subclass1.class create mode 100644 testData/classes/pkg/TestExtendingSubclass$Subclass2.class create mode 100644 testData/classes/pkg/TestExtendingSubclass.class create mode 100644 testData/results/TestExtendingSubclass.dec create mode 100644 testData/src/pkg/TestExtendingSubclass.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 3ceb99c..758b93f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -334,7 +334,7 @@ public class InvocationExprent extends Exprent { boolean firstParameter = true; int start = isEnum ? 2 : 0; for (int i = start; i < lstParameters.size(); i++) { - if (sigFields == null) { + if (sigFields == null || null == sigFields.get(i)) { if (!firstParameter) { buf.append(", "); } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index e905fb3..260445d 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -84,6 +84,7 @@ public class SingleClassesTest { @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } + @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } protected void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); @@ -130,4 +131,4 @@ public class SingleClassesTest { return files; } -} \ No newline at end of file +} diff --git a/testData/classes/pkg/TestExtendingSubclass$Subclass1.class b/testData/classes/pkg/TestExtendingSubclass$Subclass1.class new file mode 100644 index 0000000000000000000000000000000000000000..fbf2ce2b4220de642b95b58ed3cbb2148db60da8 GIT binary patch literal 555 zcmaJ;O-sW-5Ph4*#>8l2{cL*?tWYbM3f?MSih>aI(9-)RU21B&l_VAamIo0$_yhb= z;!II{(8{vR%-c8f-tNACyuJZAMa@P5n+{BDS=h0#D^SdDM~{@)jw~2%xx}~P;_CTVxcOqzwnLb$^zb8@FpCoC>JO+_$4X}+p$MKW6~!H&tpl> zXj@pOXj2xzAO_$xkDei#FEE~{GT<;q5yZ4 Mo1tV7+gJrY0UM2l+yDRo literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestExtendingSubclass$Subclass2.class b/testData/classes/pkg/TestExtendingSubclass$Subclass2.class new file mode 100644 index 0000000000000000000000000000000000000000..d30cc61f527200abd5220e809d3632d540ce773b GIT binary patch literal 594 zcma)3T}uK%6g{(UZrb{heX1`(2Bnb}y&1hoL9q0Y;`^wBZLMSMuF>D>A%Y(I0sW}x zjPwO%#4>x&oqNx@XJ%erpPm66qMSkk%W2qHaj@oKT_71>`cb7JQ1))FhxLw%;*+~r z>4C3@?Mbg6$S7*E?a0@Dd@Rt|{-e*klDD!RNIk5#OhCZ3TC literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestExtendingSubclass.class b/testData/classes/pkg/TestExtendingSubclass.class new file mode 100644 index 0000000000000000000000000000000000000000..eb4f049285b0ef4ac6e9ef8c9d06eb0b0bc291bd GIT binary patch literal 441 zcma)2O-sW-5Pj38T^pmV@eB1NdQcCBiZ{heQ4oS2T6*84OWYbal1;?F@d@A@+b){$1=a;N1U3nsVHw4#wDyeP-5R6vLB*66*!orN z6WW*B=;DgdJUSi|oIy5Ggl?#fx+|X|m5*eUvf_tXEYq>fb;W0*Q#@!(*bAQ@lVGH5 zas65-GtnlQ|9?Snhgq4&>PA;>cK>vpPUVaA(1A (Lpkg/TestExtendingSubclass;Ljava/lang/String;)V' { + 8 5 + b 6 + } +} + +class 'pkg/TestExtendingSubclass$Subclass1' { + method ' (Lpkg/TestExtendingSubclass;Ljava/lang/String;)V' { + 9 11 + } +} + +Lines mapping: +9 <-> 12 +14 <-> 6 +15 <-> 7 +Not mapped: +8 +13 diff --git a/testData/src/pkg/TestExtendingSubclass.java b/testData/src/pkg/TestExtendingSubclass.java new file mode 100644 index 0000000..f63baed --- /dev/null +++ b/testData/src/pkg/TestExtendingSubclass.java @@ -0,0 +1,18 @@ +package pkg; + +import java.math.BigDecimal; + +public class TestExtendingSubclass { + + class Subclass1 { + Subclass1(String name) { + } + } + + class Subclass2 extends Subclass1 { + Subclass2(String name) { + super(name); + } + } + +} From 96ff7f787edd44b64dcf6f5cfd58440f7041d48c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 21 Mar 2016 12:26:50 +0100 Subject: [PATCH 040/252] Cleanup (formatting; typos) --- .../decompiler/exps/InvocationExprent.java | 72 +++++++++---------- .../java/decompiler/SingleClassesTest.java | 2 +- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 758b93f..1b8188a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -224,20 +224,20 @@ public class InvocationExprent extends Exprent { else { if (instance != null && instance.type == Exprent.EXPRENT_VAR) { - VarExprent instvar = (VarExprent)instance; - VarVersionPair varpaar = new VarVersionPair(instvar); + VarExprent instVar = (VarExprent)instance; + VarVersionPair varPair = new VarVersionPair(instVar); - VarProcessor vproc = instvar.getProcessor(); - if (vproc == null) { - MethodWrapper current_meth = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); - if (current_meth != null) { - vproc = current_meth.varproc; + VarProcessor varProc = instVar.getProcessor(); + if (varProc == null) { + MethodWrapper currentMethod = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); + if (currentMethod != null) { + varProc = currentMethod.varproc; } } String this_classname = null; - if (vproc != null) { - this_classname = vproc.getThisVars().get(varpaar); + if (varProc != null) { + this_classname = varProc.getThisVars().get(varPair); } if (this_classname != null) { @@ -334,7 +334,7 @@ public class InvocationExprent extends Exprent { boolean firstParameter = true; int start = isEnum ? 2 : 0; for (int i = start; i < lstParameters.size(); i++) { - if (sigFields == null || null == sigFields.get(i)) { + if (sigFields == null || sigFields.get(i) == null) { if (!firstParameter) { buf.append(", "); } @@ -512,43 +512,35 @@ public class InvocationExprent extends Exprent { // ***************************************************************************** // IMatchable implementation // ***************************************************************************** - - public boolean match(MatchNode matchNode, MatchEngine engine) { - if(!super.match(matchNode, engine)) { + @Override + public boolean match(MatchNode matchNode, MatchEngine engine) { + if (!super.match(matchNode, engine)) { return false; } - - for(Entry rule : matchNode.getRules().entrySet()) { + + for (Entry rule : matchNode.getRules().entrySet()) { RuleValue value = rule.getValue(); - - switch(rule.getKey()) { - case EXPRENT_INVOCATION_PARAMETER: - if(value.isVariable()) { - if(value.parameter < lstParameters.size()) { - if(!engine.checkAndSetVariableValue(value.value.toString(), lstParameters.get(value.parameter))) { - return false; - } - } else { - return false; - } - } - break; - case EXPRENT_INVOCATION_CLASS: - if(!value.value.equals(this.classname)) { + + MatchProperties key = rule.getKey(); + if (key == MatchProperties.EXPRENT_INVOCATION_PARAMETER) { + if (value.isVariable() && (value.parameter >= lstParameters.size() || + !engine.checkAndSetVariableValue(value.value.toString(), lstParameters.get(value.parameter)))) { + return false; + } + } + else if (key == MatchProperties.EXPRENT_INVOCATION_CLASS) { + if (!value.value.equals(this.classname)) { + return false; + } + } + else if (key == MatchProperties.EXPRENT_INVOCATION_SIGNATURE) { + if (!value.value.equals(this.name + this.stringDescriptor)) { return false; } - break; - case EXPRENT_INVOCATION_SIGNATURE: - if(!value.value.equals(this.name + this.stringDescriptor)) { - return false; - } - break; } - } - + return true; } - -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 260445d..100deeb 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -131,4 +131,4 @@ public class SingleClassesTest { return files; } -} +} \ No newline at end of file From 081a208a6a58e72c1ab4960ef74e482dfd1fe5df Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 28 Mar 2016 13:02:19 +0300 Subject: [PATCH 041/252] reasonalble toString for easier debugging --- .../java/decompiler/modules/decompiler/exps/Exprent.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java index fbd146e..42abbb2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -193,5 +193,9 @@ public class Exprent implements IMatchable { return true; } - + + @Override + public String toString() { + return toJava(0, new BytecodeMappingTracer()).toString(); + } } From 95215dc2e288013281baff74e2b2ae1cfe1c8871 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 28 Mar 2016 13:57:29 +0300 Subject: [PATCH 042/252] replace increment / decrement synthetic access method, pull-request #373 --- .../main/rels/NestedMemberAccess.java | 44 +++++++-- .../java/decompiler/SingleClassesTest.java | 5 +- .../pkg/TestSyntheticAccess$Assigner.class | Bin 0 -> 753 bytes .../pkg/TestSyntheticAccess$Incrementer.class | Bin 0 -> 928 bytes .../classes/pkg/TestSyntheticAccess.class | Bin 0 -> 1012 bytes testData/results/TestSyntheticAccess.dec | 85 ++++++++++++++++++ testData/src/pkg/TestSyntheticAccess.java | 44 +++++++++ 7 files changed, 169 insertions(+), 9 deletions(-) create mode 100644 testData/classes/pkg/TestSyntheticAccess$Assigner.class create mode 100644 testData/classes/pkg/TestSyntheticAccess$Incrementer.class create mode 100644 testData/classes/pkg/TestSyntheticAccess.class create mode 100644 testData/results/TestSyntheticAccess.dec create mode 100644 testData/src/pkg/TestSyntheticAccess.java diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java index 3fa8128..2ea32bd 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,10 +29,7 @@ import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.util.InterpreterUtil; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; public class NestedMemberAccess { @@ -40,6 +37,7 @@ public class NestedMemberAccess { private static final int METHOD_ACCESS_FIELD_GET = 2; private static final int METHOD_ACCESS_FIELD_SET = 3; private static final int METHOD_ACCESS_METHOD = 4; + private static final int METHOD_ACCESS_FUNCTION = 5; private boolean noSynthFlag; private final Map mapMethodType = new HashMap(); @@ -117,6 +115,16 @@ public class NestedMemberAccess { } } + break; + case Exprent.EXPRENT_FUNCTION: + // for now detect only increment/decrement + FunctionExprent functionExprent = (FunctionExprent)exprCore; + if (functionExprent.getFuncType() >= FunctionExprent.FUNCTION_IMM && + functionExprent.getFuncType() <= FunctionExprent.FUNCTION_PPI) { + if (functionExprent.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) { + type = METHOD_ACCESS_FUNCTION; + } + } break; case Exprent.EXPRENT_INVOCATION: type = METHOD_ACCESS_METHOD; @@ -139,7 +147,6 @@ public class NestedMemberAccess { } } - if (type == METHOD_ACCESS_METHOD) { // FIXME: check for private flag of the method type = METHOD_ACCESS_NORMAL; @@ -323,7 +330,6 @@ public class NestedMemberAccess { } private Exprent replaceAccessExprent(ClassNode caller, MethodWrapper methdest, InvocationExprent invexpr) { - ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(invexpr.getClassname()); MethodWrapper methsource = null; @@ -408,6 +414,9 @@ public class NestedMemberAccess { } retexprent = ret; break; + case METHOD_ACCESS_FUNCTION: + retexprent = replaceFunction(invexpr, source); + break; case METHOD_ACCESS_METHOD: if (source.type == Exprent.EXPRENT_EXIT) { source = ((ExitExprent)source).getValue(); @@ -446,4 +455,25 @@ public class NestedMemberAccess { return retexprent; } + + private static Exprent replaceFunction(final InvocationExprent invexpr, final Exprent source) { + FunctionExprent functionExprent = (FunctionExprent)((ExitExprent)source).getValue().copy(); + + List lstParameters = invexpr.getLstParameters(); + + FieldExprent fieldExprent = (FieldExprent)functionExprent.getLstOperands().get(0); + if (fieldExprent.isStatic()) { + if (!lstParameters.isEmpty()) { + return null; + } + return functionExprent; + } + + if (lstParameters.size() != 1) { + return null; + } + + fieldExprent.replaceExprent(fieldExprent.getInstance(), lstParameters.get(0)); + return functionExprent; + } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 100deeb..5bdbdc5 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -85,8 +85,9 @@ public class SingleClassesTest { @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } + @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } - protected void doTest(String testFile, String... companionFiles) { + private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); File classFile = new File(fixture.getTestDataDir(), "/classes/" + testFile + ".class"); @@ -131,4 +132,4 @@ public class SingleClassesTest { return files; } -} \ No newline at end of file +} diff --git a/testData/classes/pkg/TestSyntheticAccess$Assigner.class b/testData/classes/pkg/TestSyntheticAccess$Assigner.class new file mode 100644 index 0000000000000000000000000000000000000000..c15e644dbe8e817ab9b3a02a21438b287b356ff2 GIT binary patch literal 753 zcmZ{iT`vPc6o%ikt=(EntG>UBtrUrtxFZrIl1&;eDs??wlUmkRx?AFBNeFS_2l!Fq z%&L;GH#2i)-t(OI%*^}8>l=V=tn{M~Qzmpwo0!3@8s-el8(1Ld(S;Y<6~a{Y=Bimf zm0?u7526bhdG5aJ$}rqv(XJPG(H>#8l&D&*6VivRb4kcny+9s!t{bv_DjGiT`p$`)ZR`FfpI?&Vv&sl=*X2L*mxou8Rl+)T(U-o1&A#F8}2(yU0cs$xw=jv?-~EH|$+ z%+?<6Zpsbedi7`9YYERXPfSy|?ja=|S+?aJGb|KBvx=7t(bLYgU`W<1Tbw`MH-*zM znr%8s*E*)rzBC+5`rX5*e41gjYMYL@7q%xH2CZt_!Z~dlt}7_G9`;^7aElaj>km?8 zh!mt4el5COI_k&k!H9I~okzzMXO`4CGo=3QTjR;lkO0>(iYXO&4eQv@uqjOeMGYks z8FC^03o2zuNm{vW*f-^i=B+S2hHS`1(q{NyAg}8O|My;2*vsAPI~9G`Z$}_rspwdt z(HNmAVX2g?i*_+6RGbEeF@Jg#@&R7jdIKxHLwO-j!8qAC<$yAizLk596f(2|lbGrf z_Gy)|MCldm1Cgsffcxli5|9i)52LN*fm>&XAFiX`dm_wRYP8wAD>n5Q50*HiQV~*B2`N$p53MStPj#GCx+Qgx*G2G8 zyl@i|4}1V0g_yNdY9uUSX?JGVXU?3Nv48&h{sX`cS~uWe(`JG?3p^5N5UTrH zt5GZyg5QnV9*je+r50!sX1Z~d$O{>#<~?a%U0#adK2xzupA+mx^O)cqOooy$+f%W8 zd3iCA$x%2M^G&TciNf)5m?(3eUOMTSVy>m$o7bcEk<{to`#3$5sfzZaNNT-D@WRZi z2fyyUU-L-%OsL7 zlqq!aA9XxF58sA9X5jm{X|`LKB`lOwO_($I_Bf13?N@_y8Ks2v5^()`Y@20}!tk)p zv#;>CV8JtbGLI#(6}(s%I6Zr9w#2s5`Ud+WI~H#9?q-()HTL}+fIGMg%vEs@^L%51 zcR7g(_FMfguuh!QudqJwxs1cd!jxmNz+o3SoZ-oTb1Y$bs$+vQn#cPDa!&i7K}H1? zD`DL$1-$(S-*<*3_*JY;`S)OF8ANNPT;6;R$xCE 19 +15 <-> 20 +18 <-> 23 +19 <-> 24 +22 <-> 27 +23 <-> 27 +26 <-> 31 +27 <-> 32 +32 <-> 9 +33 <-> 10 +36 <-> 13 +37 <-> 14 diff --git a/testData/src/pkg/TestSyntheticAccess.java b/testData/src/pkg/TestSyntheticAccess.java new file mode 100644 index 0000000..0c4e3ea --- /dev/null +++ b/testData/src/pkg/TestSyntheticAccess.java @@ -0,0 +1,44 @@ +package pkg; + +/** + * @author Alexandru-Constantin Bledea + * @since March 20, 2016 + */ +class TestSyntheticAccess { + + private static int s; + private int i; + + private class Incrementer { + void orI() { + i|=1; + } + + void incrementI() { + i++; + } + + void decrementI() { + --i; + } + + void incrementS() { + ++s; + } + + void decrementS() { + s--; + } + } + + private class Assigner { + void assignI(int newValue) { + i = newValue; + } + + void assignS(int newValue) { + s = newValue; + } + } + +} From 6b5cd853c0aae1c3b7b09ae8f4495dc43611d157 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 28 Mar 2016 13:59:38 +0300 Subject: [PATCH 043/252] replaced constants with enum --- .../main/rels/NestedMemberAccess.java | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java index 2ea32bd..e7e0f01 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java @@ -33,14 +33,10 @@ import java.util.*; public class NestedMemberAccess { - private static final int METHOD_ACCESS_NORMAL = 1; - private static final int METHOD_ACCESS_FIELD_GET = 2; - private static final int METHOD_ACCESS_FIELD_SET = 3; - private static final int METHOD_ACCESS_METHOD = 4; - private static final int METHOD_ACCESS_FUNCTION = 5; + private enum MethodAccess {NORMAL, FIELD_GET, FIELD_SET, METHOD, FUNCTION} private boolean noSynthFlag; - private final Map mapMethodType = new HashMap(); + private final Map mapMethodType = new HashMap(); public void propagateMemberAccess(ClassNode root) { @@ -71,7 +67,7 @@ public class NestedMemberAccess { } private void computeMethodType(ClassNode node, MethodWrapper method) { - int type = METHOD_ACCESS_NORMAL; + MethodAccess type = MethodAccess.NORMAL; if (method.root != null) { DirectGraph graph = method.getOrBuildGraph(); @@ -102,7 +98,7 @@ public class NestedMemberAccess { if (fexpr.getClassname().equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpr.isStatic() || (fexpr.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpr.getInstance()).getIndex() == 0)) { - type = METHOD_ACCESS_FIELD_GET; + type = MethodAccess.FIELD_GET; } } } @@ -111,7 +107,7 @@ public class NestedMemberAccess { if (parcount == 1) { // this or final variable if (((VarExprent)exprCore).getIndex() != 0) { - type = METHOD_ACCESS_FIELD_GET; + type = MethodAccess.FIELD_GET; } } @@ -122,12 +118,12 @@ public class NestedMemberAccess { if (functionExprent.getFuncType() >= FunctionExprent.FUNCTION_IMM && functionExprent.getFuncType() <= FunctionExprent.FUNCTION_PPI) { if (functionExprent.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) { - type = METHOD_ACCESS_FUNCTION; + type = MethodAccess.FUNCTION; } } break; case Exprent.EXPRENT_INVOCATION: - type = METHOD_ACCESS_METHOD; + type = MethodAccess.METHOD; break; case Exprent.EXPRENT_ASSIGNMENT: AssignmentExprent asexpr = (AssignmentExprent)exprCore; @@ -139,7 +135,7 @@ public class NestedMemberAccess { if (fexpras.isStatic() || (fexpras.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)fexpras.getInstance()).getIndex() == 0)) { if (((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) { - type = METHOD_ACCESS_FIELD_SET; + type = MethodAccess.FIELD_SET; } } } @@ -147,9 +143,9 @@ public class NestedMemberAccess { } } - if (type == METHOD_ACCESS_METHOD) { // FIXME: check for private flag of the method + if (type == MethodAccess.METHOD) { // FIXME: check for private flag of the method - type = METHOD_ACCESS_NORMAL; + type = MethodAccess.NORMAL; InvocationExprent invexpr = (InvocationExprent)exprCore; @@ -169,7 +165,7 @@ public class NestedMemberAccess { } if (equalpars) { - type = METHOD_ACCESS_METHOD; + type = MethodAccess.METHOD; } } } @@ -198,7 +194,7 @@ public class NestedMemberAccess { if (exexpr.getExitType() == ExitExprent.EXIT_RETURN && exexpr.getValue() != null) { if (exexpr.getValue().type == Exprent.EXPRENT_VAR && ((VarExprent)asexpr.getRight()).getIndex() == parcount - 1) { - type = METHOD_ACCESS_FIELD_SET; + type = MethodAccess.FIELD_SET; } } } @@ -212,7 +208,7 @@ public class NestedMemberAccess { } } - if (type != METHOD_ACCESS_NORMAL) { + if (type != MethodAccess.NORMAL) { mapMethodType.put(method, type); } else { @@ -349,10 +345,10 @@ public class NestedMemberAccess { return null; } - int type = mapMethodType.get(methsource); + MethodAccess type = mapMethodType.get(methsource); - // // FIXME: impossible case. METHOD_ACCESS_NORMAL is not saved in the map - // if(type == METHOD_ACCESS_NORMAL) { + // // FIXME: impossible case. MethodAccess.NORMAL is not saved in the map + // if(type == MethodAccess.NORMAL) { // return null; // } @@ -366,7 +362,7 @@ public class NestedMemberAccess { Exprent retexprent = null; switch (type) { - case METHOD_ACCESS_FIELD_GET: + case FIELD_GET: ExitExprent exsource = (ExitExprent)source; if (exsource.getValue().type == Exprent.EXPRENT_VAR) { // qualified this VarExprent var = (VarExprent)exsource.getValue(); @@ -394,7 +390,7 @@ public class NestedMemberAccess { retexprent = ret; } break; - case METHOD_ACCESS_FIELD_SET: + case FIELD_SET: AssignmentExprent ret; if (source.type == Exprent.EXPRENT_EXIT) { ExitExprent extex = (ExitExprent)source; @@ -414,10 +410,10 @@ public class NestedMemberAccess { } retexprent = ret; break; - case METHOD_ACCESS_FUNCTION: + case FUNCTION: retexprent = replaceFunction(invexpr, source); break; - case METHOD_ACCESS_METHOD: + case METHOD: if (source.type == Exprent.EXPRENT_EXIT) { source = ((ExitExprent)source).getValue(); } From 404783c874d5d3b209995f22a9bb8ac640bb35b9 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 29 Mar 2016 17:52:23 +0300 Subject: [PATCH 044/252] decompiler: Setup increment/decrement test properly #376 --- .../pkg/TestSyntheticAccess$Assigner.class | Bin 753 -> 599 bytes .../pkg/TestSyntheticAccess$Incrementer.class | Bin 928 -> 914 bytes .../classes/pkg/TestSyntheticAccess.class | Bin 1012 -> 902 bytes testData/results/TestSyntheticAccess.dec | 74 +++++++++++------- 4 files changed, 44 insertions(+), 30 deletions(-) diff --git a/testData/classes/pkg/TestSyntheticAccess$Assigner.class b/testData/classes/pkg/TestSyntheticAccess$Assigner.class index c15e644dbe8e817ab9b3a02a21438b287b356ff2..4ebd715b0d13441e9e5adde75b14eeaf08bb901d 100644 GIT binary patch delta 275 zcmey!dYwh()W2Q(7#J8#7!)}fSQ&)47}ywuxfnzkL_vfYJA*hogVaQo41V^+;^NHo zJWoaj77b6$u*s~9)_l_J3^F_nvJ7%O4Dt*Lll>S~B{&?x%2JCM8F)PN@=}YObATFC zizgQ{POVpBU;;u01}-h_tqhD>+ZmWP0(n4{K#~neGcYItF)srjkj)KbslnB6VPKTr z!N44jP|pQ6Nri!vK^3TyAFf9Us25}h8&Ew9s(O&&8bD8K0u=}V*-Q+A43a>a3#f$^ J=vxT}CIJ5%A~yg4 delta 408 zcmZXQ%SyvQ6o&s9b1~EL(yDE>+9qu(S~m&>7X?9G1zbv8M+r6%A~cFipJC|Irw|my zg%98h_#D1K@FYqUWZ*xSIsZ4q`OrRf_dR=k12Dv<1s$sb2G#^xSkGm{MB7A1x#RuX z$<;*=`@tj%&g1Yj7Y6Nm9Hk7ihiMvJCgFrZdI`njI7riwZn|o>sWQtMF__e%A&*>J z-nLJ!B)s*5_=Y&lQ}?5)ZNic0q9@^^&tR*)hRQ0_9-H0`!RY{Eu=4~qcm{u%Kafd^FQ jUor@${e!u*&Hf*lQNoNL7Dt2J98D}z6hzZ$;Kov_qac9+DRza$|V7k+>r zCC(|TQtM*R&Y5}Mb7tP1eS3d-1+Weyh8V^rBqk&#F~wn;!wiQchglADQOrlNAQ17- zZ7*#Ij2~QIo)wOj=a=ss|6KXDwQE_*^R@`uwjJBw5tzyZQrQ!M@Ls*D1o{tbM;+c= zRg`;dR%$d8s=FnM8HS|oSgyKKj!#pvs@js)O1XW7lXCsWwbZ`N#m4^FWd6duHFfkr z*U^ha6pK2RkkOGvPRBBjRyeF8ucLsxKq}z4>C*T1lq=BlE7MDkqujlk>3PZ%h;!3I z&2-KRN0kd@`2wQ>Rp|(3)6KMDklFwF$gZ^5HG%11&r8`~@MgPm<0mN^>rM09;9}9h zEL{~zw?@R{Y#fau(8#?$&?ls9o-&QzGPnE$k$Z;rz%=4bQcz^g01{t(9w8b5iQFUM z^fV9(-!~9G{n5#0#XeGThryP1ft0L`ed@Y8BnfmA4h#iJA{~+ul8lmMxFwnU>eAIf kv;&_&n0^dkOx1{l+)T(U-o1&A#F8}2(yU0cs$xw=jv?-~EH|$+ z%+?<6Zpsbedi7`9YYERXPfSy|?ja=|S+?aJGb|KBvx=7t(bLYgU`W<1Tbw`MH-*zM znr%8s*E*)rzBC+5`rX5*e41gjYMYL@7q%xH2CZt_!Z~dlt}7_G9`;^7aElaj>km?8 zh!mt4el5COI_k&k!H9I~okzzMXO`4CGo=3QTjR;lkO0>(iYXO&4eQv@uqjOeMGYks z8FC^03o2zuNm{vW*f-^i=B+S2hHS`1(q{NyAg}8O|My;2*vsAPI~9G`Z$}_rspwdt z(HNmAVX2g?i*_+6RGbEeF@Jg#@&R7jdIKxHLwO-j!8qAC<$yAizLk596f(2|lbGrf z_Gy)|MCldm1Cgsffcxli5|9i)52LN*fm>&XAFiX`dm_wRYP8wAD>n5Q50*ff$?3=9k=3~HPVEDZ7>LV=5cl|hl6L5ZC~nVms}k%7apxHvOCFSUq~ zfyXlsNIT~w78j=$vookpw0Gg>N=!~pEiP6uFfd?bkkOd9K$1z*bFw(2J~u+fV&W_F z$-#`5>N$Xx@iFi-Ffs@LS+YQy5lFLYZD(NK2xKra2m(nqupqkt2ZIoUFp!O^bPEI1 z8Z1gh7(}5;HiQV~*B2`N$p53MStPj#GCx+Qgx*G2G8 zyl@i|4}1V0g_yNdY9uUSX?JGVXU?3Nv48&h{sX`cS~uWe(`JG?3p^5N5UTrH zt5GZyg5QnV9*je+r50!sX1Z~d$O{>#<~?a%U0#adK2xzupA+mx^O)cqOooy$+f%W8 zd3iCA$x%2M^G&TciNf)5m?(3eUOMTSVy>m$o7bcEk<{to`#3$5sfzZaNNT-D@WRZi z2fyyUU-L-%OsL7 zlqq!aA9XxF58sA9X5jm{X|`LKB`lOwO_($I_Bf13?N@_y8Ks2v5^()`Y@20}!tk)p zv#;>CV8JtbGLI#(6}(s%I6Zr9w#2s5`Ud+WI~H#9?q-()HTL}+fIGMg%vEs@^L%51 zcR7g(_FMfguuh!QudqJwxs1cd!jxmNz+o3SoZ-oTb1Y$bs$+vQn#cPDa!&i7K}H1? zD`DL$1-$(S-*<*3_*JY;`S)OF8ANNPT;6;R$xCE 23 19 <-> 24 22 <-> 27 -23 <-> 27 +23 <-> 28 26 <-> 31 -27 <-> 32 -32 <-> 9 -33 <-> 10 -36 <-> 13 -37 <-> 14 +27 <-> 31 +30 <-> 35 +31 <-> 36 +36 <-> 9 +37 <-> 10 +40 <-> 13 +41 <-> 14 From a57e42690be6cfc95cd462087f263fe64e76f357 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Apr 2016 20:32:26 +0200 Subject: [PATCH 045/252] Cleanup (duplicates extracted; formatting; typos) --- .../java/decompiler/main/EnumProcessor.java | 59 +----- .../decompiler/main/InitializerProcessor.java | 187 ++++++------------ .../modules/decompiler/stats/Statements.java | 60 ++++++ .../java/decompiler/util/StructUtils.java | 14 +- 4 files changed, 134 insertions(+), 186 deletions(-) create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statements.java diff --git a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java index 37a3384..7e83fe9 100644 --- a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,16 +20,14 @@ import org.jetbrains.java.decompiler.main.rels.ClassWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; -import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; -import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statements; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructField; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.util.InterpreterUtil; public class EnumProcessor { - public static void clearEnum(ClassWrapper wrapper) { StructClass cl = wrapper.getClassStruct(); @@ -50,12 +48,12 @@ public class EnumProcessor { } } else if (CodeConstants.INIT_NAME.equals(name)) { - Statement firstData = findFirstData(method.root); + Statement firstData = Statements.findFirstData(method.root); if (firstData != null && !firstData.getExprents().isEmpty()) { Exprent exprent = firstData.getExprents().get(0); if (exprent.type == Exprent.EXPRENT_INVOCATION) { - InvocationExprent invexpr = (InvocationExprent)exprent; - if (isInvocationSuperConstructor(invexpr, method, wrapper)) { + InvocationExprent invExpr = (InvocationExprent)exprent; + if (Statements.isInvocationInitConstructor(invExpr, method, wrapper, false)) { firstData.getExprents().remove(0); } } @@ -71,49 +69,4 @@ public class EnumProcessor { } } } - - // FIXME: move to a util class (see also InitializerProcessor) - private static Statement findFirstData(Statement stat) { - - if (stat.getExprents() != null) { - return stat; - } - else { - if (stat.isLabeled()) { - return null; - } - - switch (stat.type) { - case Statement.TYPE_SEQUENCE: - case Statement.TYPE_IF: - case Statement.TYPE_ROOT: - case Statement.TYPE_SWITCH: - case Statement.TYPE_SYNCRONIZED: - return findFirstData(stat.getFirst()); - default: - return null; - } - } - } - - // FIXME: move to util class (see also InitializerProcessor) - private static boolean isInvocationSuperConstructor(InvocationExprent inv, MethodWrapper meth, ClassWrapper wrapper) { - - if (inv.getFunctype() == InvocationExprent.TYP_INIT) { - if (inv.getInstance().type == Exprent.EXPRENT_VAR) { - VarExprent instvar = (VarExprent)inv.getInstance(); - VarVersionPair varpaar = new VarVersionPair(instvar); - - String classname = meth.varproc.getThisVars().get(varpaar); - - if (classname != null) { // any this instance. TODO: Restrict to current class? - if (!wrapper.getClassStruct().qualifiedName.equals(inv.getClassname())) { - return true; - } - } - } - } - - return false; - } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java index e1363d8..fe1a4f7 100644 --- a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.exps.*; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; +import org.jetbrains.java.decompiler.modules.decompiler.stats.Statements; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructField; @@ -31,14 +32,11 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.ArrayList; import java.util.List; - public class InitializerProcessor { - public static void extractInitializers(ClassWrapper wrapper) { - - MethodWrapper meth = wrapper.getMethodWrapper(CodeConstants.CLINIT_NAME, "()V"); - if (meth != null && meth.root != null) { // successfully decompiled static constructor - extractStaticInitializers(wrapper, meth); + MethodWrapper method = wrapper.getMethodWrapper(CodeConstants.CLINIT_NAME, "()V"); + if (method != null && method.root != null) { // successfully decompiled static constructor + extractStaticInitializers(wrapper, method); } extractDynamicInitializers(wrapper); @@ -52,30 +50,26 @@ public class InitializerProcessor { } } - private static void liftConstructor(ClassWrapper wrapper) { - - for (MethodWrapper meth : wrapper.getMethods()) { - if (CodeConstants.INIT_NAME.equals(meth.methodStruct.getName()) && meth.root != null) { - Statement firstdata = findFirstData(meth.root); - if (firstdata == null) { + for (MethodWrapper method : wrapper.getMethods()) { + if (CodeConstants.INIT_NAME.equals(method.methodStruct.getName()) && method.root != null) { + Statement firstData = Statements.findFirstData(method.root); + if (firstData == null) { return; } - int index = 0; - List lstExprents = firstdata.getExprents(); + List lstExprents = firstData.getExprents(); for (Exprent exprent : lstExprents) { - int action = 0; if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { - AssignmentExprent asexpr = (AssignmentExprent)exprent; - if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD && asexpr.getRight().type == Exprent.EXPRENT_VAR) { - FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); - if (fexpr.getClassname().equals(wrapper.getClassStruct().qualifiedName)) { - StructField structField = wrapper.getClassStruct().getField(fexpr.getName(), fexpr.getDescriptor().descriptorString); + AssignmentExprent assignExpr = (AssignmentExprent)exprent; + if (assignExpr.getLeft().type == Exprent.EXPRENT_FIELD && assignExpr.getRight().type == Exprent.EXPRENT_VAR) { + FieldExprent fExpr = (FieldExprent)assignExpr.getLeft(); + if (fExpr.getClassname().equals(wrapper.getClassStruct().qualifiedName)) { + StructField structField = wrapper.getClassStruct().getField(fExpr.getName(), fExpr.getDescriptor().descriptorString); if (structField != null && structField.hasModifier(CodeConstants.ACC_FINAL)) { action = 1; } @@ -83,7 +77,7 @@ public class InitializerProcessor { } } else if (index > 0 && exprent.type == Exprent.EXPRENT_INVOCATION && - isInvocationInitConstructor((InvocationExprent)exprent, meth, wrapper, true)) { + Statements.isInvocationInitConstructor((InvocationExprent)exprent, method, wrapper, true)) { // this() or super() lstExprents.add(0, lstExprents.remove(index)); action = 2; @@ -99,53 +93,50 @@ public class InitializerProcessor { } } - private static void hideEmptySuper(ClassWrapper wrapper) { - - for (MethodWrapper meth : wrapper.getMethods()) { - if (CodeConstants.INIT_NAME.equals(meth.methodStruct.getName()) && meth.root != null) { - Statement firstdata = findFirstData(meth.root); - if (firstdata == null || firstdata.getExprents().isEmpty()) { + for (MethodWrapper method : wrapper.getMethods()) { + if (CodeConstants.INIT_NAME.equals(method.methodStruct.getName()) && method.root != null) { + Statement firstData = Statements.findFirstData(method.root); + if (firstData == null || firstData.getExprents().isEmpty()) { return; } - Exprent exprent = firstdata.getExprents().get(0); + Exprent exprent = firstData.getExprents().get(0); if (exprent.type == Exprent.EXPRENT_INVOCATION) { - InvocationExprent invexpr = (InvocationExprent)exprent; - if (isInvocationInitConstructor(invexpr, meth, wrapper, false) && invexpr.getLstParameters().isEmpty()) { - firstdata.getExprents().remove(0); + InvocationExprent invExpr = (InvocationExprent)exprent; + if (Statements.isInvocationInitConstructor(invExpr, method, wrapper, false) && invExpr.getLstParameters().isEmpty()) { + firstData.getExprents().remove(0); } } } } } - private static void extractStaticInitializers(ClassWrapper wrapper, MethodWrapper meth) { - - RootStatement root = meth.root; + private static void extractStaticInitializers(ClassWrapper wrapper, MethodWrapper method) { + RootStatement root = method.root; StructClass cl = wrapper.getClassStruct(); - boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); - Statement firstdata = findFirstData(root); - if (firstdata != null) { - while (!firstdata.getExprents().isEmpty()) { - Exprent exprent = firstdata.getExprents().get(0); + Statement firstData = Statements.findFirstData(root); + if (firstData != null) { + boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); + while (!firstData.getExprents().isEmpty()) { + Exprent exprent = firstData.getExprents().get(0); boolean found = false; if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { - AssignmentExprent asexpr = (AssignmentExprent)exprent; - if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD) { - FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); - if (fexpr.isStatic() && fexpr.getClassname().equals(cl.qualifiedName) && - cl.hasField(fexpr.getName(), fexpr.getDescriptor().descriptorString)) { + AssignmentExprent assignExpr = (AssignmentExprent)exprent; + if (assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) { + FieldExprent fExpr = (FieldExprent)assignExpr.getLeft(); + if (fExpr.isStatic() && fExpr.getClassname().equals(cl.qualifiedName) && + cl.hasField(fExpr.getName(), fExpr.getDescriptor().descriptorString)) { // interfaces fields should always be initialized inline - if (isInterface || isExprentIndependent(asexpr.getRight(), meth)) { + if (isInterface || isExprentIndependent(assignExpr.getRight(), method)) { - String keyField = InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString); + String keyField = InterpreterUtil.makeUniqueKey(fExpr.getName(), fExpr.getDescriptor().descriptorString); if (!wrapper.getStaticFieldInitializers().containsKey(keyField)) { - wrapper.getStaticFieldInitializers().addWithKey(asexpr.getRight(), keyField); - firstdata.getExprents().remove(0); + wrapper.getStaticFieldInitializers().addWithKey(assignExpr.getRight(), keyField); + firstData.getExprents().remove(0); found = true; } } @@ -161,27 +152,26 @@ public class InitializerProcessor { } private static void extractDynamicInitializers(ClassWrapper wrapper) { - StructClass cl = wrapper.getClassStruct(); boolean isAnonymous = DecompilerContext.getClassProcessor().getMapRootClasses().get(cl.qualifiedName).type == ClassNode.CLASS_ANONYMOUS; List> lstFirst = new ArrayList>(); - List lstMethWrappers = new ArrayList(); + List lstMethodWrappers = new ArrayList(); - for (MethodWrapper meth : wrapper.getMethods()) { - if (CodeConstants.INIT_NAME.equals(meth.methodStruct.getName()) && meth.root != null) { // successfully decompiled constructor - Statement firstdata = findFirstData(meth.root); - if (firstdata == null || firstdata.getExprents().isEmpty()) { + for (MethodWrapper method : wrapper.getMethods()) { + if (CodeConstants.INIT_NAME.equals(method.methodStruct.getName()) && method.root != null) { // successfully decompiled constructor + Statement firstData = Statements.findFirstData(method.root); + if (firstData == null || firstData.getExprents().isEmpty()) { return; } - lstFirst.add(firstdata.getExprents()); - lstMethWrappers.add(meth); + lstFirst.add(firstData.getExprents()); + lstMethodWrappers.add(method); - Exprent exprent = firstdata.getExprents().get(0); + Exprent exprent = firstData.getExprents().get(0); if (!isAnonymous) { // FIXME: doesn't make sense if (exprent.type != Exprent.EXPRENT_INVOCATION || - !isInvocationInitConstructor((InvocationExprent)exprent, meth, wrapper, false)) { + !Statements.isInvocationInitConstructor((InvocationExprent)exprent, method, wrapper, false)) { return; } } @@ -193,12 +183,10 @@ public class InitializerProcessor { } while (true) { - String fieldWithDescr = null; Exprent value = null; for (int i = 0; i < lstFirst.size(); i++) { - List lst = lstFirst.get(i); if (lst.size() < (isAnonymous ? 1 : 2)) { @@ -210,22 +198,21 @@ public class InitializerProcessor { boolean found = false; if (exprent.type == Exprent.EXPRENT_ASSIGNMENT) { - AssignmentExprent asexpr = (AssignmentExprent)exprent; - if (asexpr.getLeft().type == Exprent.EXPRENT_FIELD) { - FieldExprent fexpr = (FieldExprent)asexpr.getLeft(); - if (!fexpr.isStatic() && fexpr.getClassname().equals(cl.qualifiedName) && - cl.hasField(fexpr.getName(), fexpr - .getDescriptor().descriptorString)) { // check for the physical existence of the field. Could be defined in a superclass. + AssignmentExprent assignExpr = (AssignmentExprent)exprent; + if (assignExpr.getLeft().type == Exprent.EXPRENT_FIELD) { + FieldExprent fExpr = (FieldExprent)assignExpr.getLeft(); + if (!fExpr.isStatic() && fExpr.getClassname().equals(cl.qualifiedName) && + cl.hasField(fExpr.getName(), fExpr.getDescriptor().descriptorString)) { // check for the physical existence of the field. Could be defined in a superclass. - if (isExprentIndependent(asexpr.getRight(), lstMethWrappers.get(i))) { - String fieldKey = InterpreterUtil.makeUniqueKey(fexpr.getName(), fexpr.getDescriptor().descriptorString); + if (isExprentIndependent(assignExpr.getRight(), lstMethodWrappers.get(i))) { + String fieldKey = InterpreterUtil.makeUniqueKey(fExpr.getName(), fExpr.getDescriptor().descriptorString); if (fieldWithDescr == null) { fieldWithDescr = fieldKey; - value = asexpr.getRight(); + value = assignExpr.getRight(); } else { if (!fieldWithDescr.equals(fieldKey) || - !value.equals(asexpr.getRight())) { + !value.equals(assignExpr.getRight())) { return; } } @@ -253,19 +240,17 @@ public class InitializerProcessor { } } - private static boolean isExprentIndependent(Exprent exprent, MethodWrapper meth) { - + private static boolean isExprentIndependent(Exprent exprent, MethodWrapper method) { List lst = exprent.getAllExprents(true); lst.add(exprent); for (Exprent expr : lst) { switch (expr.type) { case Exprent.EXPRENT_VAR: - VarVersionPair varpaar = new VarVersionPair((VarExprent)expr); - if (!meth.varproc.getExternalVars().contains(varpaar)) { - String varname = meth.varproc.getVarName(varpaar); - - if (!varname.equals("this") && !varname.endsWith(".this")) { // FIXME: remove direct comparison with strings + VarVersionPair varPair = new VarVersionPair((VarExprent)expr); + if (!method.varproc.getExternalVars().contains(varPair)) { + String varName = method.varproc.getVarName(varPair); + if (!varName.equals("this") && !varName.endsWith(".this")) { // FIXME: remove direct comparison with strings return false; } } @@ -277,48 +262,4 @@ public class InitializerProcessor { return true; } - - - private static Statement findFirstData(Statement stat) { - - if (stat.getExprents() != null) { - return stat; - } - else { - if (stat.isLabeled()) { // FIXME: Why?? - return null; - } - - switch (stat.type) { - case Statement.TYPE_SEQUENCE: - case Statement.TYPE_IF: - case Statement.TYPE_ROOT: - case Statement.TYPE_SWITCH: - case Statement.TYPE_SYNCRONIZED: - return findFirstData(stat.getFirst()); - default: - return null; - } - } - } - - private static boolean isInvocationInitConstructor(InvocationExprent inv, MethodWrapper meth, ClassWrapper wrapper, boolean withThis) { - - if (inv.getFunctype() == InvocationExprent.TYP_INIT) { - if (inv.getInstance().type == Exprent.EXPRENT_VAR) { - VarExprent instvar = (VarExprent)inv.getInstance(); - VarVersionPair varpaar = new VarVersionPair(instvar); - - String classname = meth.varproc.getThisVars().get(varpaar); - - if (classname != null) { // any this instance. TODO: Restrict to current class? - if (withThis || !wrapper.getClassStruct().qualifiedName.equals(inv.getClassname())) { - return true; - } - } - } - } - - return false; - } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statements.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statements.java new file mode 100644 index 0000000..52b7eda --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statements.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.modules.decompiler.stats; + +import org.jetbrains.java.decompiler.main.rels.ClassWrapper; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; +import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.InvocationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; +import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; + +public class Statements { + public static Statement findFirstData(Statement stat) { + if (stat.getExprents() != null) { + return stat; + } + else if (stat.isLabeled()) { // FIXME: Why?? + return null; + } + + switch (stat.type) { + case Statement.TYPE_SEQUENCE: + case Statement.TYPE_IF: + case Statement.TYPE_ROOT: + case Statement.TYPE_SWITCH: + case Statement.TYPE_SYNCRONIZED: + return findFirstData(stat.getFirst()); + default: + return null; + } + } + + public static boolean isInvocationInitConstructor(InvocationExprent inv, MethodWrapper method, ClassWrapper wrapper, boolean withThis) { + if (inv.getFunctype() == InvocationExprent.TYP_INIT && inv.getInstance().type == Exprent.EXPRENT_VAR) { + VarExprent instVar = (VarExprent)inv.getInstance(); + VarVersionPair varPair = new VarVersionPair(instVar); + String classname = method.varproc.getThisVars().get(varPair); + if (classname != null) { // any this instance. TODO: Restrict to current class? + if (withThis || !wrapper.getClassStruct().qualifiedName.equals(inv.getClassname())) { + return true; + } + } + } + + return false; + } +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/StructUtils.java b/src/org/jetbrains/java/decompiler/util/StructUtils.java index d7dad68..1d4042e 100644 --- a/src/org/jetbrains/java/decompiler/util/StructUtils.java +++ b/src/org/jetbrains/java/decompiler/util/StructUtils.java @@ -33,19 +33,14 @@ import static org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute.A * @since March 07, 2016 */ public final class StructUtils { - - private StructUtils() { - } + private StructUtils() { } /** * @return the local variables of the current method */ public static List getCurrentMethodLocalVariableNames() { final MethodWrapper method = (MethodWrapper) DecompilerContext.getProperty(CURRENT_METHOD_WRAPPER); - if (null == method) { - return Collections.emptyList(); - } - return getLocalVariables(method.methodStruct); + return method == null ? Collections.emptyList() : getLocalVariables(method.methodStruct); } /** @@ -56,10 +51,9 @@ public final class StructUtils { final VBStyleCollection methodStruct = structMember.getAttributes(); final StructGeneralAttribute generalAttribute = methodStruct.getWithKey(ATTRIBUTE_LOCAL_VARIABLE_TABLE); if (generalAttribute instanceof StructLocalVariableTableAttribute) { - final StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute) generalAttribute; + final StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)generalAttribute; return Collections.unmodifiableList(new ArrayList<>(table.getMapVarNames().values())); } return Collections.emptyList(); } - -} +} \ No newline at end of file From 1ac2304d60323d5ff439fe058f35825bafb366aa Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 11 Apr 2016 21:42:48 +0200 Subject: [PATCH 046/252] [java-decompiler] fixes enum constant initializer decompilation (IDEA-154547) --- .../decompiler/main/InitializerProcessor.java | 6 ++-- testData/classes/pkg/TestEnum$2.class | Bin 428 -> 506 bytes testData/classes/pkg/TestEnum$Type.class | Bin 0 -> 871 bytes testData/classes/pkg/TestEnum.class | Bin 1491 -> 1652 bytes testData/results/TestEnum.dec | 28 +++++++++++------- testData/src/pkg/TestEnum.java | 10 ++++--- 6 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 testData/classes/pkg/TestEnum$Type.class diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java index fe1a4f7..206b669 100644 --- a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -117,7 +117,8 @@ public class InitializerProcessor { StructClass cl = wrapper.getClassStruct(); Statement firstData = Statements.findFirstData(root); if (firstData != null) { - boolean isInterface = cl.hasModifier(CodeConstants.ACC_INTERFACE); + boolean inlineInitializers = cl.hasModifier(CodeConstants.ACC_INTERFACE) || cl.hasModifier(CodeConstants.ACC_ENUM); + while (!firstData.getExprents().isEmpty()) { Exprent exprent = firstData.getExprents().get(0); @@ -131,8 +132,7 @@ public class InitializerProcessor { cl.hasField(fExpr.getName(), fExpr.getDescriptor().descriptorString)) { // interfaces fields should always be initialized inline - if (isInterface || isExprentIndependent(assignExpr.getRight(), method)) { - + if (inlineInitializers || isExprentIndependent(assignExpr.getRight(), method)) { String keyField = InterpreterUtil.makeUniqueKey(fExpr.getName(), fExpr.getDescriptor().descriptorString); if (!wrapper.getStaticFieldInitializers().containsKey(keyField)) { wrapper.getStaticFieldInitializers().addWithKey(assignExpr.getRight(), keyField); diff --git a/testData/classes/pkg/TestEnum$2.class b/testData/classes/pkg/TestEnum$2.class index 99faf412adc5a16866dfbb7efba6b1040bcddadd..3dedba7752417dc953984d6750c47d95d9ff7410 100644 GIT binary patch delta 272 zcmZ3({EOM@)W2Q(7#J8#7{s|4m>C4v83frGgcupvY%=pQOYGPggc%uFLMjVV85wvy z^YT)QoO2S3i&Kjk8LTHNs!jaO2bP@Z7Re|&ae;_hL3X-+NNRD3YhGzCBZD9^R|RAW zJA)V_gEz9yU#9gO42%q%KsP8euraU#X>KiT8C^*h#_bG@8-ZL#1}-4U2BaAnB!MJ1 z0}oV#Bv=-x0$rIj&?~$^NhSt927VyT0^~C=umiCaki`nbYz|UDSs-xW;9wAeFaRi( BESvxU delta 232 zcmeyxyoOov)W2Q(7#J8#7(}=jm>GE48Ti;41Q;3EY%=pQOY9gKG$vZ9O)QQu6JliG zE67gQ4@oU9am_2uRWV{@;PK4MOD%HFNh~f-Ee3Lt<=Gj885t}lTA57tWmKzWWdIrp zv__GEm4O9Fb82bJ=rV3+VB84gFfy$N!|0v_RMX{#4P43A#=R4>7&guR6>+25yud$N>$A*UIs3<5Zc%ebZmbeTRS&fp0 zK$t4>!d4Y*GsxZjeFon9aOp7UhraJj_B?w!b*2o(&gJ`2z2{7WwjW+p1g1gQcE5eZ zpj7&AJI8H{q4aJpE`4Qtp=k5aFy|xq-uRSQmpZQR9EBGHXVS9=9z~R>w0p*|WpvK% zE4%L5{-|yR6W1R#%=vUp*LQZF3IE zE={jl<8U%`4qTx#`*$}rAyP*{ti7n?C0;40G2|2b)3J=YjxrwW$RejBj~v6|zZnHL zLu%-aeIh6sW=vOiaPABP5~0WYGQ5dT9R0mUtm=Mi|C2OYJM;*2dO31yMQ8!Yk{lpc z7L!nhBZCqifR;+$23c{m8Q5n?w~#-Q$MA^mbd*~o{4!SV@lq7k3cUISsaxd1@RNcf-$1=aCUP_$ISZ-pl#*xk i|4;Y~3)VGQvbT)8?(29;-6TB25?PH{I5x4^D*py=Ft1_& literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestEnum.class b/testData/classes/pkg/TestEnum.class index 01c608244d3bbc45b24058733d9c66c7ab99a89f..036f3e623b9467f49e9ec677abc19ea8c9156cb2 100644 GIT binary patch literal 1652 zcmZ`(>r&HD5dKatNg9JdfJ!S0)T%8PD+1n%P=ujZ2IusL2TEoI!U`$igW7?E*801VqgT+({GLUMyzPq z2eGVEvFroF$>H33dM}w}7<}2CLwau%YrMp8B--QjY?NOUnZdMWo7=V0zFFBd_KReZ zMO5YuLnzW)G1^^(l^EQSXpTWzv24p(W$^cjOL2rRYaQ5zQ>##!ct22Yy^eBWKEOE7 z6zLQFA82T&W;<5N%vn{78hmP0jFRb?m37-LJBDMGZJLn3t@5UMSTPHRW4@;OUg=XP z)mdplFxu)1>^ZT{P|;7PshLe#DHL1NoNA-Smt&;^A73SsYPMXf6wC(}Kfi&0TXc;V z*Ki$+Tr6m~!uR{Ch8@tlXzdH9VGg^rWosJ3xU69kQ?!%qh%m)Zb1R$Iu!o$6P%nm7 zmd$E-&fS-U`?P;foi?!}XY)RI3&pZc#7861wpKIyZ_R>3%`LYNR@|C+8?1E^+9O*x z$er2TWEkm~R&#;qCMI*q?Zh-)&hzv;kP-pjF+iGn6q>pdn%V&1;$s1Zf_#Sbt-yx} zqF|VzuMlbesCBr%!t)E>PxQqwOHvX(o$zy*Kf$|%Rn?`LZ;*dM>cul$L#%}lh-{Sc zb646aB1R`mvPr`WHzCxS*$G`?N4@wkZjj$aiFw>2p?O@Gw3oC-aYyjY%zuH}UFmWw zatX_X^l|<-=>dv7H@a+~jL^UM>bGGvVPan2Ajrq>W5Izbt z@ah;+UO(eLf~x`T7z26zEJY7CFeE&~UR|$agz_~odW^BW?w9m)b&MY&&_GcBLE-K? zv~1o}$51x!tz$Hsm+A;+8*ra;_KTT}(9eDpL5$P!1+WU8T5QhnF5<-Ag%w;R9VGh% RF}#on(r=%hghG)*{{2&;EmqRZVk~D>4YNo%F?_g{eV5KL^nd8g zA)INYIxjI8iFP?X+m&OTqOyjm@72pkdi6j%Dv?FBqxL^Cgd*J)qn$-qnZX^29x@0? z!!)c7hCq+F3`h8KM$y!)dX>sVdVzY>qp;x~P@XRIwr*NRSwA#t22p>bRkgBi>D4XM ztXP_5R7~nU;K;e7pH}sPX6eT?xqCgbW^QyBjwg7TwVuGPUGxf-l7&)xDANuee8@MwV>}Bd<}j7k71ElQt$vVE*2Do_({$xc!ew-lk;vAMDUu9WmCa4W)zHJ zoKDM$2*(vna4VxklihAQIySFh%Jy8h$O$ue3#E!l)cldCqnZ7q6TM&&{Z;3j?DI}I zVC{=_M%t&InxPjXNH3s}3Ua~#X`*OrVrXmPLkJh|3K$sWBcNvqK7?@>v`cylk>)?S z0rz)!F5vw_PYm}-3bs!rd<4-eyvw%AsxbEh;su0mJi{F3+j!2AS72W|(oPaFS`0}} zV+J0$N&DvJ$5pA-4G&?F+%C$?!(s&HVPVo9(h7yOD0tx;7N<;Kb^lY4~6#M(u+QPL{?^OHtOq6l061EUHa-T(jq diff --git a/testData/results/TestEnum.dec b/testData/results/TestEnum.dec index 06649c0..6fabfae 100644 --- a/testData/results/TestEnum.dec +++ b/testData/results/TestEnum.dec @@ -6,8 +6,8 @@ public enum TestEnum { public void m() { }// 22 }, - E3("-"), - E4("+") { + E3("-", TestEnum.Type.ODD), + E4("+", TestEnum.Type.EVEN) { public void m() { }// 27 }; @@ -15,14 +15,19 @@ public enum TestEnum { private String s; public void m() { - }// 30 + }// 32 private TestEnum() { - this("?");// 34 + this("?", (TestEnum.Type)null);// 36 } - private TestEnum(@Deprecated String var3) { - this.s = var3;// 35 + private TestEnum(@Deprecated String var3, TestEnum.Type var4) { + this.s = var3;// 37 + } + + private static enum Type { + ODD, + EVEN; } } @@ -46,10 +51,11 @@ class 'pkg/TestEnum' { method ' (Ljava/lang/String;I)V' { 3 20 5 20 - 8 21 + 6 20 + 9 21 } - method ' (Ljava/lang/String;ILjava/lang/String;)V' { + method ' (Ljava/lang/String;ILjava/lang/String;Lpkg/TestEnum$Type;)V' { 8 24 b 25 } @@ -58,6 +64,6 @@ class 'pkg/TestEnum' { Lines mapping: 22 <-> 7 27 <-> 12 -30 <-> 18 -34 <-> 21 -35 <-> 25 +32 <-> 18 +36 <-> 21 +37 <-> 25 diff --git a/testData/src/pkg/TestEnum.java b/testData/src/pkg/TestEnum.java index 43fab48..e474d34 100644 --- a/testData/src/pkg/TestEnum.java +++ b/testData/src/pkg/TestEnum.java @@ -21,16 +21,18 @@ public enum TestEnum { @Override public void m() { } }, - E3("-"), - E4("+") { + E3("-", Type.ODD), + E4("+", Type.EVEN) { @Override public void m() { } }; + private enum Type {ODD, EVEN} + public void m() { } private String s; - private TestEnum() { this("?"); } - private TestEnum(@Deprecated String s) { this.s = s; } + private TestEnum() { this("?", null); } + private TestEnum(@Deprecated String s, Type t) { this.s = s; } } From 77dc5c5f1e1888b1707137d61a7c5c8a61cb4a21 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 12:35:17 +0200 Subject: [PATCH 047/252] [java-decompiler] dead code --- .../modules/decompiler/ExitHelper.java | 105 +----------------- 1 file changed, 4 insertions(+), 101 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java index d467cdc..6d0d381 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,6 @@ import org.jetbrains.java.decompiler.main.collectors.CounterContainer; import org.jetbrains.java.decompiler.modules.decompiler.exps.ExitExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.*; -import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import java.util.ArrayList; import java.util.Arrays; @@ -29,32 +28,23 @@ import java.util.List; import java.util.Set; public class ExitHelper { - - public static boolean condenseExits(RootStatement root) { - int changed = integrateExits(root); if (changed > 0) { - cleanUpUnreachableBlocks(root); - SequenceHelper.condenseSequences(root); } return (changed > 0); } - private static void cleanUpUnreachableBlocks(Statement stat) { - boolean found; do { - found = false; for (int i = 0; i < stat.getStats().size(); i++) { - Statement st = stat.getStats().get(i); cleanUpUnreachableBlocks(st); @@ -83,16 +73,12 @@ public class ExitHelper { while (found); } - private static int integrateExits(Statement stat) { - int ret = 0; - Statement dest = null; + Statement dest; if (stat.getExprents() == null) { - while (true) { - int changed = 0; for (Statement st : stat.getStats()) { @@ -108,7 +94,6 @@ public class ExitHelper { } } - switch (stat.type) { case Statement.TYPE_IF: IfStatement ifst = (IfStatement)stat; @@ -168,15 +153,12 @@ public class ExitHelper { // LabelHelper.lowContinueLabels(block, new HashSet()); // do it by hand for (StatEdge prededge : block.getPredecessorEdges(StatEdge.TYPE_CONTINUE)) { - block.removePredecessor(prededge); prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, stat); stat.addPredecessor(prededge); - stat.addLabeledEdge(prededge); } - stat.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, stat, bstat)); for (StatEdge edge : dest.getAllPredecessorEdges()) { @@ -202,11 +184,9 @@ public class ExitHelper { } private static Statement isExitEdge(StatEdge edge) { - Statement dest = edge.getDestination(); - if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK - && edge.explicit && (edge.labeled || isOnlyEdge(edge))) { + if (edge.getType() == StatEdge.TYPE_BREAK && dest.type == Statement.TYPE_BASICBLOCK && edge.explicit && (edge.labeled || isOnlyEdge(edge))) { List data = dest.getExprents(); if (data != null && data.size() == 1) { @@ -220,7 +200,6 @@ public class ExitHelper { } private static boolean isOnlyEdge(StatEdge edge) { - Statement stat = edge.getDestination(); for (StatEdge ed : stat.getAllPredecessorEdges()) { @@ -244,7 +223,6 @@ public class ExitHelper { } public static boolean removeRedundantReturns(RootStatement root) { - boolean res = false; DummyExitStatement dummyExit = root.getDummyExit(); @@ -270,79 +248,4 @@ public class ExitHelper { return res; } - - public static boolean handleReturnFromInitializer(RootStatement root) { - - boolean res = false; - - Statement exit = root.getDummyExit(); - Statement top = root.getFirst(); - Statement newret = null; - - boolean sharedcreated = false; - - for (StatEdge edge : exit.getAllPredecessorEdges()) { - if (edge.explicit) { - - if (!sharedcreated) { - newret = addSharedInitializerReturn(root); - sharedcreated = true; - } - - Statement source = edge.getSource(); - List lstExpr = source.getExprents(); - if (lstExpr != null && !lstExpr.isEmpty()) { - Exprent expr = lstExpr.get(lstExpr.size() - 1); - if (expr.type == Exprent.EXPRENT_EXIT) { - ExitExprent ex = (ExitExprent)expr; - if (ex.getExitType() == ExitExprent.EXIT_RETURN && ex.getValue() == null) { - lstExpr.remove(lstExpr.size() - 1); - - source.removeSuccessor(edge); - source.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, source, newret, top)); - - res = true; - } - } - } - } - } - - return res; - } - - private static Statement addSharedInitializerReturn(RootStatement root) { - - Statement exit = root.getDummyExit(); - Statement top = root.getFirst(); - - // build a new statement with the single instruction 'return' - BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( - DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); - - ExitExprent retexpr = new ExitExprent(ExitExprent.EXIT_RETURN, null, - ((MethodDescriptor)DecompilerContext - .getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret, null); - // a changeable list needed - bstat.setExprents(new ArrayList(Arrays.asList(new Exprent[]{retexpr}))); - - // build sequence to replace the former top statement - SequenceStatement seq = new SequenceStatement(Arrays.asList(top, bstat)); - top.setParent(seq); - bstat.setParent(seq); - seq.setParent(root); - - root.getStats().removeWithKey(top.id); - root.getStats().addWithKeyAndIndex(0, seq, seq.id); - root.setFirst(seq); - - for (StatEdge succedge : top.getAllSuccessorEdges()) { - top.removeSuccessor(succedge); - } - - top.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, top, bstat)); - bstat.addSuccessor(new StatEdge(StatEdge.TYPE_BREAK, bstat, exit, seq)); - - return bstat; - } -} +} \ No newline at end of file From 857dc4d023529cdf48af02847565eced423706f9 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 12:54:57 +0200 Subject: [PATCH 048/252] [java-decompiler] unneeded context lookups --- .../decompiler/main/DecompilerContext.java | 6 ++-- .../decompiler/main/rels/ClassWrapper.java | 15 ++++---- .../main/rels/MethodProcessorRunnable.java | 20 ++++++----- .../modules/decompiler/ExprProcessor.java | 24 +++++-------- .../modules/decompiler/FinallyProcessor.java | 24 ++++++------- .../decompiler/SecondaryFunctionsHelper.java | 28 ++++++--------- .../modules/decompiler/vars/VarProcessor.java | 27 +++++++------- .../decompiler/vars/VarTypeProcessor.java | 36 ++++++++++--------- .../decompiler/vars/VarVersionsProcessor.java | 19 +++++----- 9 files changed, 94 insertions(+), 105 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java index d105959..c31c57a 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,8 +32,6 @@ public class DecompilerContext { public static final String CURRENT_CLASS = "CURRENT_CLASS"; public static final String CURRENT_CLASS_WRAPPER = "CURRENT_CLASS_WRAPPER"; public static final String CURRENT_CLASS_NODE = "CURRENT_CLASS_NODE"; - public static final String CURRENT_METHOD = "CURRENT_METHOD"; - public static final String CURRENT_METHOD_DESCRIPTOR = "CURRENT_METHOD_DESCRIPTOR"; public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER"; public static final String CURRENT_VAR_PROCESSOR = "CURRENT_VAR_PROCESSOR"; @@ -158,4 +156,4 @@ public class DecompilerContext { return getOption(IFernflowerPreferences.NEW_LINE_SEPARATOR) ? IFernflowerPreferences.LINE_SEPARATOR_UNX : IFernflowerPreferences.LINE_SEPARATOR_WIN; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java index 18f05a3..cc7eeab 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,10 +73,8 @@ public class ClassWrapper { CounterContainer counter = new CounterContainer(); DecompilerContext.setCounterContainer(counter); - DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD, mt); - DecompilerContext.setProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR, MethodDescriptor.parseDescriptor(mt.getDescriptor())); - - VarProcessor varProc = new VarProcessor(); + MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); + VarProcessor varProc = new VarProcessor(mt, md); DecompilerContext.setProperty(DecompilerContext.CURRENT_VAR_PROCESSOR, varProc); RootStatement root = null; @@ -86,10 +84,10 @@ public class ClassWrapper { try { if (mt.containsCode()) { if (maxSec == 0 || testMode) { - root = MethodProcessorRunnable.codeToJava(mt, varProc); + root = MethodProcessorRunnable.codeToJava(mt, md, varProc); } else { - MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, varProc, DecompilerContext.getCurrentContext()); + MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext.getCurrentContext()); Thread mtThread = new Thread(mtProc, "Java decompiler"); long stopAt = System.currentTimeMillis() + maxSec * 1000; @@ -123,7 +121,6 @@ public class ClassWrapper { } else { boolean thisVar = !mt.hasModifier(CodeConstants.ACC_STATIC); - MethodDescriptor md = MethodDescriptor.parseDescriptor(mt.getDescriptor()); int paramCount = 0; if (thisVar) { @@ -207,4 +204,4 @@ public class ClassWrapper { public VBStyleCollection getDynamicFieldInitializers() { return dynamicFieldInitializers; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java index 1c90fb6..4b47425 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodProcessorRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,14 +29,15 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import java.io.IOException; public class MethodProcessorRunnable implements Runnable { - public final Object lock = new Object(); private final StructMethod method; + private final MethodDescriptor methodDescriptor; private final VarProcessor varProc; private final DecompilerContext parentContext; @@ -44,8 +45,9 @@ public class MethodProcessorRunnable implements Runnable { private volatile Throwable error; private volatile boolean finished = false; - public MethodProcessorRunnable(StructMethod method, VarProcessor varProc, DecompilerContext parentContext) { + public MethodProcessorRunnable(StructMethod method, MethodDescriptor methodDescriptor, VarProcessor varProc, DecompilerContext parentContext) { this.method = method; + this.methodDescriptor = methodDescriptor; this.varProc = varProc; this.parentContext = parentContext; } @@ -58,7 +60,7 @@ public class MethodProcessorRunnable implements Runnable { root = null; try { - root = codeToJava(method, varProc); + root = codeToJava(method, methodDescriptor, varProc); } catch (ThreadDeath ex) { throw ex; @@ -76,7 +78,7 @@ public class MethodProcessorRunnable implements Runnable { } } - public static RootStatement codeToJava(StructMethod mt, VarProcessor varProc) throws IOException { + public static RootStatement codeToJava(StructMethod mt, MethodDescriptor md, VarProcessor varProc) throws IOException { StructClass cl = mt.getClassStruct(); boolean isInitializer = CodeConstants.CLINIT_NAME.equals(mt.getName()); // for now static initializer only @@ -119,7 +121,7 @@ public class MethodProcessorRunnable implements Runnable { RootStatement root = DomHelper.parseGraph(graph); - FinallyProcessor fProc = new FinallyProcessor(varProc); + FinallyProcessor fProc = new FinallyProcessor(md, varProc); while (fProc.iterateGraph(mt, root, graph)) { root = DomHelper.parseGraph(graph); } @@ -134,7 +136,7 @@ public class MethodProcessorRunnable implements Runnable { ClearStructHelper.clearStatements(root); - ExprProcessor proc = new ExprProcessor(); + ExprProcessor proc = new ExprProcessor(md, varProc); proc.processStatement(root, cl); SequenceHelper.condenseSequences(root); @@ -195,7 +197,7 @@ public class MethodProcessorRunnable implements Runnable { ExitHelper.removeRedundantReturns(root); - SecondaryFunctionsHelper.identifySecondaryFunctions(root); + SecondaryFunctionsHelper.identifySecondaryFunctions(root, varProc); varProc.setVarDefinitions(root); @@ -217,4 +219,4 @@ public class MethodProcessorRunnable implements Runnable { public boolean isFinished() { return finished; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index df1978f..9d81e07 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -42,7 +42,6 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.*; public class ExprProcessor implements CodeConstants { - public static final String UNDEFINED_TYPE_STRING = ""; public static final String UNKNOWN_TYPE_STRING = ""; public static final String NULL_TYPE_STRING = ""; @@ -50,7 +49,6 @@ public class ExprProcessor implements CodeConstants { private static final HashMap mapConsts = new HashMap(); static { - // mapConsts.put(new Integer(opc_i2l), new // Integer(FunctionExprent.FUNCTION_I2L)); // mapConsts.put(new Integer(opc_i2f), new @@ -141,19 +139,18 @@ public class ExprProcessor implements CodeConstants { private static final String[] typeNames = new String[]{"byte", "char", "double", "float", "int", "long", "short", "boolean",}; - private final VarProcessor varProcessor = (VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR); + private final MethodDescriptor methodDescriptor; + private final VarProcessor varProcessor; + + public ExprProcessor(MethodDescriptor md, VarProcessor varProc) { + methodDescriptor = md; + varProcessor = varProc; + } public void processStatement(RootStatement root, StructClass cl) { - FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); - // try { - // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot")); - // } catch (Exception ex) { - // ex.printStackTrace(); - // } - // collect finally entry points Set setFinallyShortRangeEntryPoints = new HashSet(); for (List lst : dgraph.mapShortRangeFinallyPaths.values()) { @@ -534,10 +531,7 @@ public class ExprProcessor implements CodeConstants { case opc_athrow: exprlist.add(new ExitExprent(instr.opcode == opc_athrow ? ExitExprent.EXIT_THROW : ExitExprent.EXIT_RETURN, instr.opcode == opc_return ? null : stack.pop(), - instr.opcode == opc_athrow - ? null - : ((MethodDescriptor)DecompilerContext - .getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR)).ret, + instr.opcode == opc_athrow ? null : methodDescriptor.ret, bytecode_offsets)); break; case opc_monitorenter: @@ -933,4 +927,4 @@ public class ExprProcessor implements CodeConstants { return false; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java index 9f1c11b..d3e1d04 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,6 +38,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.InterpreterUtil; @@ -45,23 +46,22 @@ import java.util.*; import java.util.Map.Entry; public class FinallyProcessor { - private final Map finallyBlockIDs = new HashMap(); private final Map catchallBlockIDs = new HashMap(); - private final VarProcessor varprocessor; + private final MethodDescriptor methodDescriptor; + private final VarProcessor varProcessor; - public FinallyProcessor(VarProcessor varprocessor) { - this.varprocessor = varprocessor; + public FinallyProcessor(MethodDescriptor md, VarProcessor varProc) { + methodDescriptor = md; + varProcessor = varProc; } public boolean iterateGraph(StructMethod mt, RootStatement root, ControlFlowGraph graph) { - // return processStatement(mt, root, graph, root); return processStatementEx(mt, root, graph); } private boolean processStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph graph) { - int bytecode_version = mt.getClassStruct().getBytecodeVersion(); LinkedList stack = new LinkedList(); @@ -87,7 +87,7 @@ public class FinallyProcessor { fin.setFinally(true); Integer var = finallyBlockIDs.get(handler.id); - fin.setMonitor(var == null ? null : new VarExprent(var.intValue(), VarType.VARTYPE_INT, varprocessor)); + fin.setMonitor(var == null ? null : new VarExprent(var.intValue(), VarType.VARTYPE_INT, varProcessor)); } else { @@ -190,9 +190,7 @@ public class FinallyProcessor { } } - - private static Record getFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { - + private Record getFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { Map mapLast = new HashMap(); BasicBlockStatement firstBlockStatement = fstat.getHandler().getBasichead(); @@ -209,7 +207,7 @@ public class FinallyProcessor { firstcode = 2; } - ExprProcessor proc = new ExprProcessor(); + ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor); proc.processStatement(root, mt.getClassStruct()); SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); @@ -1087,4 +1085,4 @@ public class FinallyProcessor { } } } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java index f57457c..12aecbb 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -56,9 +56,7 @@ public class SecondaryFunctionsHelper { mapNumComparisons.put(FunctionExprent.FUNCTION_LE, new Integer[]{FunctionExprent.FUNCTION_LT, FunctionExprent.FUNCTION_LE, null}); } - - public static boolean identifySecondaryFunctions(Statement stat) { - + public static boolean identifySecondaryFunctions(Statement stat, VarProcessor varProc) { if (stat.getExprents() == null) { // if(){;}else{...} -> if(!){...} if (stat.type == Statement.TYPE_IF) { @@ -100,7 +98,6 @@ public class SecondaryFunctionsHelper { } } - boolean replaced = true; while (replaced) { replaced = false; @@ -111,13 +108,13 @@ public class SecondaryFunctionsHelper { Object obj = lstObjects.get(i); if (obj instanceof Statement) { - if (identifySecondaryFunctions((Statement)obj)) { + if (identifySecondaryFunctions((Statement)obj, varProc)) { replaced = true; break; } } else if (obj instanceof Exprent) { - Exprent retexpr = identifySecondaryFunctions((Exprent)obj, true); + Exprent retexpr = identifySecondaryFunctions((Exprent)obj, true, varProc); if (retexpr != null) { if (stat.getExprents() == null) { // only head expressions can be replaced! @@ -136,9 +133,7 @@ public class SecondaryFunctionsHelper { return false; } - - private static Exprent identifySecondaryFunctions(Exprent exprent, boolean statement_level) { - + private static Exprent identifySecondaryFunctions(Exprent exprent, boolean statement_level, VarProcessor varProc) { if (exprent.type == Exprent.EXPRENT_FUNCTION) { FunctionExprent fexpr = (FunctionExprent)exprent; @@ -202,7 +197,7 @@ public class SecondaryFunctionsHelper { replaced = false; for (Exprent expr : exprent.getAllExprents()) { - Exprent retexpr = identifySecondaryFunctions(expr, false); + Exprent retexpr = identifySecondaryFunctions(expr, false, varProc); if (retexpr != null) { exprent.replaceExprent(expr, retexpr); replaced = true; @@ -301,21 +296,20 @@ public class SecondaryFunctionsHelper { case FunctionExprent.FUNCTION_DCMPG: int var = DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER); VarType type = lstOperands.get(0).getExprType(); - VarProcessor processor = (VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR); FunctionExprent iff = new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList( - new FunctionExprent(FunctionExprent.FUNCTION_LT, Arrays.asList(new VarExprent(var, type, processor), + new FunctionExprent(FunctionExprent.FUNCTION_LT, Arrays.asList(new VarExprent(var, type, varProc), ConstExprent.getZeroConstant(type.type)), null), new ConstExprent(VarType.VARTYPE_INT, new Integer(-1), null), new ConstExprent(VarType.VARTYPE_INT, new Integer(1), null)), null); FunctionExprent head = new FunctionExprent(FunctionExprent.FUNCTION_EQ, Arrays.asList( - new AssignmentExprent(new VarExprent(var, type, processor), new FunctionExprent(FunctionExprent.FUNCTION_SUB, - Arrays.asList(lstOperands.get(0), - lstOperands.get(1)), null), null), + new AssignmentExprent(new VarExprent(var, type, varProc), + new FunctionExprent(FunctionExprent.FUNCTION_SUB, Arrays.asList(lstOperands.get(0), lstOperands.get(1)), null), + null), ConstExprent.getZeroConstant(type.type)), null); - processor.setVarType(new VarVersionPair(var, 0), type); + varProc.setVarType(new VarVersionPair(var, 0), type); return new FunctionExprent(FunctionExprent.FUNCTION_IIF, Arrays.asList( head, new ConstExprent(VarType.VARTYPE_INT, new Integer(0), null), iff), fexpr.bytecode); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index ce81474..2dc207e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,33 +15,37 @@ */ package org.jetbrains.java.decompiler.modules.decompiler.vars; -import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import java.util.*; import java.util.Map.Entry; public class VarProcessor { - + private final StructMethod method; + private final MethodDescriptor methodDescriptor; private Map mapVarNames = new HashMap(); private VarVersionsProcessor varVersions; private final Map thisVars = new HashMap(); private final Set externalVars = new HashSet(); + public VarProcessor(StructMethod mt, MethodDescriptor md) { + method = mt; + methodDescriptor = md; + } + public void setVarVersions(RootStatement root) { - varVersions = new VarVersionsProcessor(); + varVersions = new VarVersionsProcessor(method, methodDescriptor); varVersions.setVarVersions(root); } public void setVarDefinitions(Statement root) { mapVarNames = new HashMap(); - - StructMethod mt = (StructMethod)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD); - new VarDefinitionHelper(root, mt, this).setVarDefinitions(); + new VarDefinitionHelper(root, method, this).setVarDefinitions(); } public void setDebugVarNames(Map mapDebugVarNames) { @@ -52,12 +56,7 @@ public class VarProcessor { Map mapOriginalVarIndices = varVersions.getMapOriginalVarIndices(); List listVars = new ArrayList(mapVarNames.keySet()); - Collections.sort(listVars, new Comparator() { - @Override - public int compare(VarVersionPair o1, VarVersionPair o2) { - return o1.var - o2.var; - } - }); + Collections.sort(listVars, (o1, o2) -> o1.var - o2.var); Map mapNames = new HashMap(); @@ -118,4 +117,4 @@ public class VarProcessor { public Set getExternalVars() { return externalVars; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java index d6c746b..ea95ed0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,21 +34,34 @@ import java.util.List; import java.util.Map; public class VarTypeProcessor { - public static final int VAR_NON_FINAL = 1; public static final int VAR_EXPLICIT_FINAL = 2; public static final int VAR_FINAL = 3; + private final StructMethod method; + private final MethodDescriptor methodDescriptor; private final Map mapExprentMinTypes = new HashMap(); private final Map mapExprentMaxTypes = new HashMap(); private final Map mapFinalVars = new HashMap(); + public VarTypeProcessor(StructMethod mt, MethodDescriptor md) { + method = mt; + methodDescriptor = md; + } + + public void calculateVarTypes(RootStatement root, DirectGraph graph) { + setInitVars(root); + + resetExprentTypes(graph); + + //noinspection StatementWithEmptyBody + while (!processVarTypes(graph)) ; + } + private void setInitVars(RootStatement root) { - StructMethod mt = (StructMethod)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD); + boolean thisVar = !method.hasModifier(CodeConstants.ACC_STATIC); - boolean thisVar = !mt.hasModifier(CodeConstants.ACC_STATIC); - - MethodDescriptor md = (MethodDescriptor)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_DESCRIPTOR); + MethodDescriptor md = methodDescriptor; if (thisVar) { StructClass cl = (StructClass)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS); @@ -90,15 +103,6 @@ public class VarTypeProcessor { } } - public void calculateVarTypes(RootStatement root, DirectGraph graph) { - setInitVars(root); - - resetExprentTypes(graph); - - //noinspection StatementWithEmptyBody - while (!processVarTypes(graph)) ; - } - private static void resetExprentTypes(DirectGraph graph) { graph.iterateExprents(new DirectGraph.ExprentIterator() { @Override @@ -274,4 +278,4 @@ public class VarTypeProcessor { public VarType getVarType(VarVersionPair pair) { return mapExprentMinTypes.get(pair); } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java index 31f0f86..cadaf83 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.sforms.FlattenStatements import org.jetbrains.java.decompiler.modules.decompiler.sforms.SSAConstructorSparseEx; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.struct.StructMethod; +import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.util.FastSparseSetFactory.FastSparseSet; @@ -33,25 +34,27 @@ import java.util.*; import java.util.Map.Entry; public class VarVersionsProcessor { - + private final StructMethod method; private Map mapOriginalVarIndices = new HashMap(); private VarTypeProcessor typeProcessor; - public void setVarVersions(RootStatement root) { - StructMethod mt = (StructMethod)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD); + public VarVersionsProcessor(StructMethod mt, MethodDescriptor md) { + method = mt; + typeProcessor = new VarTypeProcessor(mt, md); + } + public void setVarVersions(RootStatement root) { SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); - ssa.splitVariables(root, mt); + ssa.splitVariables(root, method); FlattenStatementsHelper flattenHelper = new FlattenStatementsHelper(); DirectGraph graph = flattenHelper.buildDirectGraph(root); mergePhiVersions(ssa, graph); - typeProcessor = new VarTypeProcessor(); typeProcessor.calculateVarTypes(root, graph); - simpleMerge(typeProcessor, graph, mt); + simpleMerge(typeProcessor, graph, method); // FIXME: advanced merging @@ -311,4 +314,4 @@ public class VarVersionsProcessor { public Map getMapOriginalVarIndices() { return mapOriginalVarIndices; } -} +} \ No newline at end of file From b96586cc2f8dd79be6d20df1379ee36e92316165 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 14:06:28 +0200 Subject: [PATCH 049/252] [java-decompiler] utility classes reorganized --- .../decompiler/code/InstructionSequence.java | 6 +- .../main/decompiler/PrintStreamLogger.java | 6 +- .../decompiler/main/rels/ClassWrapper.java | 5 +- .../decompiler/main/rels/MethodWrapper.java | 17 ++---- .../modules/decompiler/exps/ConstExprent.java | 9 +-- .../modules/decompiler/exps/FieldExprent.java | 18 ++++-- .../modules/decompiler/stats/IfStatement.java | 7 +-- .../java/decompiler/struct/StructMethod.java | 10 +++- .../java/decompiler/util/InterpreterUtil.java | 25 -------- .../java/decompiler/util/StructUtils.java | 59 ------------------- .../java/decompiler/util/TextUtil.java | 27 ++++++++- 11 files changed, 63 insertions(+), 126 deletions(-) delete mode 100644 src/org/jetbrains/java/decompiler/util/StructUtils.java diff --git a/src/org/jetbrains/java/decompiler/code/InstructionSequence.java b/src/org/jetbrains/java/decompiler/code/InstructionSequence.java index 51951ab..bce3b60 100644 --- a/src/org/jetbrains/java/decompiler/code/InstructionSequence.java +++ b/src/org/jetbrains/java/decompiler/code/InstructionSequence.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package org.jetbrains.java.decompiler.code; import org.jetbrains.java.decompiler.code.interpreter.Util; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.struct.StructContext; -import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.TextUtil; import org.jetbrains.java.decompiler.util.VBStyleCollection; import java.io.DataOutputStream; @@ -157,7 +157,7 @@ public int getOffset(int index) { StringBuilder buf = new StringBuilder(); for (int i = 0; i < collinstr.size(); i++) { - buf.append(InterpreterUtil.getIndentString(indent)); + buf.append(TextUtil.getIndentString(indent)); buf.append(collinstr.getKey(i).intValue()); buf.append(": "); buf.append(collinstr.get(i).toString()); diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/PrintStreamLogger.java b/src/org/jetbrains/java/decompiler/main/decompiler/PrintStreamLogger.java index 0995613..a201000 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/PrintStreamLogger.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/PrintStreamLogger.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,7 @@ package org.jetbrains.java.decompiler.main.decompiler; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; -import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.TextUtil; import java.io.PrintStream; @@ -33,7 +33,7 @@ public class PrintStreamLogger extends IFernflowerLogger { @Override public void writeMessage(String message, Severity severity) { if (accepts(severity)) { - stream.println(severity.prefix + InterpreterUtil.getIndentString(indent) + message); + stream.println(severity.prefix + TextUtil.getIndentString(indent) + message); } } diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java index cc7eeab..ef09bd0 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -28,7 +28,6 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.StructField; import org.jetbrains.java.decompiler.struct.StructMethod; -import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.util.InterpreterUtil; @@ -162,9 +161,7 @@ public class ClassWrapper { // if debug information present and should be used if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_VAR_NAMES)) { - StructLocalVariableTableAttribute attr = (StructLocalVariableTableAttribute)mt.getAttributes().getWithKey( - StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE); - + StructLocalVariableTableAttribute attr = mt.getLocalVariableAttr(); if (attr != null) { varProc.setDebugVarNames(attr.getMapVarNames()); } diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java index 0f44e42..eb397d1 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,25 +26,17 @@ import org.jetbrains.java.decompiler.struct.StructMethod; import java.util.HashSet; import java.util.List; - public class MethodWrapper { - public final RootStatement root; - public final VarProcessor varproc; - public final StructMethod methodStruct; - public final CounterContainer counter; + public final HashSet setOuterVarNames = new HashSet(); public DirectGraph graph; - public List signatureFields; - public boolean decompiledWithErrors; - public final HashSet setOuterVarNames = new HashSet(); - public MethodWrapper(RootStatement root, VarProcessor varproc, StructMethod methodStruct, CounterContainer counter) { this.root = root; this.varproc = varproc; @@ -54,9 +46,8 @@ public class MethodWrapper { public DirectGraph getOrBuildGraph() { if (graph == null && root != null) { - FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); - graph = flatthelper.buildDirectGraph(root); + graph = new FlattenStatementsHelper().buildDirectGraph(root); } return graph; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index 8fcf176..908611a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -27,6 +27,7 @@ import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.TextUtil; import java.util.*; import java.util.Map.Entry; @@ -131,11 +132,11 @@ public class ConstExprent extends Exprent { String ret = ESCAPES.get(val); if (ret == null) { char c = (char)val.intValue(); - if (c >= 32 && c < 127 || !ascii && InterpreterUtil.isPrintableUnicode(c)) { + if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) { ret = String.valueOf(c); } else { - ret = InterpreterUtil.charToUnicodeLiteral(c); + ret = TextUtil.charToUnicodeLiteral(c); } } return new TextBuffer(ret).enclose("\'", "\'"); @@ -307,11 +308,11 @@ public class ConstExprent extends Exprent { buffer.append("\\\'"); break; default: - if (c >= 32 && c < 127 || !ascii && InterpreterUtil.isPrintableUnicode(c)) { + if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) { buffer.append(c); } else { - buffer.append(InterpreterUtil.charToUnicodeLiteral(c)); + buffer.append(TextUtil.charToUnicodeLiteral(c)); } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java index 28002ff..5e6a6b5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,6 +23,7 @@ import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; @@ -30,7 +31,6 @@ import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import org.jetbrains.java.decompiler.util.InterpreterUtil; -import org.jetbrains.java.decompiler.util.StructUtils; import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; @@ -38,7 +38,6 @@ import java.util.List; import java.util.Set; public class FieldExprent extends Exprent { - private final String name; private final String classname; private final boolean isStatic; @@ -85,7 +84,15 @@ public class FieldExprent extends Exprent { } private boolean isAmbiguous() { - return StructUtils.getCurrentMethodLocalVariableNames().contains(name); + MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); + if (method != null) { + StructLocalVariableTableAttribute attr = method.methodStruct.getLocalVariableAttr(); + if (attr != null) { + return attr.getMapVarNames().containsValue(name); + } + } + + return false; } @Override @@ -215,5 +222,4 @@ public class FieldExprent extends Exprent { return true; } - -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java index 8be0dcc..ab48ce1 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.exps.IfExprent; import org.jetbrains.java.decompiler.struct.match.IMatchable; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; -import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; -import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; import java.util.List; @@ -205,7 +204,7 @@ public class IfStatement extends Statement { } public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { - String indstr = InterpreterUtil.getIndentString(indent); + String indstr = TextUtil.getIndentString(indent); TextBuffer buf = new TextBuffer(); buf.append(ExprProcessor.listToJava(varDefinitions, indent, tracer)); diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java index 2b5249f..4ed9be3 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.jetbrains.java.decompiler.struct; import org.jetbrains.java.decompiler.code.*; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.util.DataInputFullStream; import org.jetbrains.java.decompiler.util.VBStyleCollection; @@ -37,7 +38,6 @@ import static org.jetbrains.java.decompiler.code.CodeConstants.*; } */ public class StructMethod extends StructMember { - private static final int[] opr_iconst = {-1, 0, 1, 2, 3, 4, 5}; private static final int[] opr_loadstore = {0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3}; private static final int[] opcs_load = {opc_iload, opc_lload, opc_fload, opc_dload, opc_aload}; @@ -389,4 +389,8 @@ public class StructMethod extends StructMember { public InstructionSequence getInstructionSequence() { return seq; } -} + + public StructLocalVariableTableAttribute getLocalVariableAttr() { + return (StructLocalVariableTableAttribute)getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE); + } +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java index 8130145..5576aa1 100644 --- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -15,9 +15,6 @@ */ package org.jetbrains.java.decompiler.util; -import org.jetbrains.java.decompiler.main.DecompilerContext; -import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; - import java.io.*; import java.util.Collection; import java.util.HashSet; @@ -79,16 +76,6 @@ public class InterpreterUtil { } } - public static String getIndentString(int length) { - if (length == 0) return ""; - StringBuilder buf = new StringBuilder(); - String indent = (String)DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING); - while (length-- > 0) { - buf.append(indent); - } - return buf.toString(); - } - public static boolean equalSets(Collection c1, Collection c2) { if (c1 == null) { return c2 == null; @@ -130,18 +117,6 @@ public class InterpreterUtil { return false; } - public static boolean isPrintableUnicode(char c) { - int t = Character.getType(c); - return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR && - t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE; - } - - public static String charToUnicodeLiteral(int value) { - String sTemp = Integer.toHexString(value); - sTemp = ("0000" + sTemp).substring(sTemp.length()); - return "\\u" + sTemp; - } - public static String makeUniqueKey(String name, String descriptor) { return name + ' ' + descriptor; } diff --git a/src/org/jetbrains/java/decompiler/util/StructUtils.java b/src/org/jetbrains/java/decompiler/util/StructUtils.java deleted file mode 100644 index 1d4042e..0000000 --- a/src/org/jetbrains/java/decompiler/util/StructUtils.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2000-2016 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.java.decompiler.util; - -import org.jetbrains.java.decompiler.main.DecompilerContext; -import org.jetbrains.java.decompiler.main.rels.MethodWrapper; -import org.jetbrains.java.decompiler.struct.StructMember; -import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; -import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static org.jetbrains.java.decompiler.main.DecompilerContext.CURRENT_METHOD_WRAPPER; -import static org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE; - -/** - * @author Alexandru-Constantin Bledea - * @since March 07, 2016 - */ -public final class StructUtils { - private StructUtils() { } - - /** - * @return the local variables of the current method - */ - public static List getCurrentMethodLocalVariableNames() { - final MethodWrapper method = (MethodWrapper) DecompilerContext.getProperty(CURRENT_METHOD_WRAPPER); - return method == null ? Collections.emptyList() : getLocalVariables(method.methodStruct); - } - - /** - * @param structMember the struct member from which to extract the local variables - * @return the local variables of the struct member - */ - public static List getLocalVariables(final StructMember structMember) { - final VBStyleCollection methodStruct = structMember.getAttributes(); - final StructGeneralAttribute generalAttribute = methodStruct.getWithKey(ATTRIBUTE_LOCAL_VARIABLE_TABLE); - if (generalAttribute instanceof StructLocalVariableTableAttribute) { - final StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)generalAttribute; - return Collections.unmodifiableList(new ArrayList<>(table.getMapVarNames().values())); - } - return Collections.emptyList(); - } -} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/util/TextUtil.java b/src/org/jetbrains/java/decompiler/util/TextUtil.java index 14e24f9..8957fe1 100644 --- a/src/org/jetbrains/java/decompiler/util/TextUtil.java +++ b/src/org/jetbrains/java/decompiler/util/TextUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.util; import org.jetbrains.java.decompiler.main.ClassesProcessor; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; public class TextUtil { @@ -28,4 +29,26 @@ public class TextUtil { } buf.append("super"); } -} + + public static String getIndentString(int length) { + if (length == 0) return ""; + StringBuilder buf = new StringBuilder(); + String indent = (String)DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING); + while (length-- > 0) { + buf.append(indent); + } + return buf.toString(); + } + + public static boolean isPrintableUnicode(char c) { + int t = Character.getType(c); + return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR && + t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE; + } + + public static String charToUnicodeLiteral(int value) { + String sTemp = Integer.toHexString(value); + sTemp = ("0000" + sTemp).substring(sTemp.length()); + return "\\u" + sTemp; + } +} \ No newline at end of file From eaa61a1f81ab060fad7ec482c57a134b53559303 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 15:02:39 +0200 Subject: [PATCH 050/252] [java-decompiler] skips illegal local variable names --- .../modules/decompiler/vars/VarProcessor.java | 8 +++-- .../java/decompiler/util/TextUtil.java | 32 +++++++++++++++++ .../java/decompiler/SingleClassesTest.java | 3 +- testData/classes/pkg/TestIllegalVarName.class | Bin 0 -> 1224 bytes testData/results/TestIllegalVarName.dec | 33 ++++++++++++++++++ testData/src/pkg/TestIllegalVarName.kt | 7 ++++ 6 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 testData/classes/pkg/TestIllegalVarName.class create mode 100644 testData/results/TestIllegalVarName.dec create mode 100644 testData/src/pkg/TestIllegalVarName.kt diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index 2dc207e..2ba0490 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -21,6 +21,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement; import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.gen.MethodDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.util.TextUtil; import java.util.*; import java.util.Map.Entry; @@ -64,8 +65,11 @@ public class VarProcessor { String name = mapVarNames.get(pair); Integer index = mapOriginalVarIndices.get(pair.var); - if (index != null && mapDebugVarNames.containsKey(index)) { - name = mapDebugVarNames.get(index); + if (index != null) { + String debugName = mapDebugVarNames.get(index); + if (debugName != null && TextUtil.isValidIdentifier(debugName, method.getClassStruct().getBytecodeVersion())) { + name = debugName; + } } Integer counter = mapNames.get(name); diff --git a/src/org/jetbrains/java/decompiler/util/TextUtil.java b/src/org/jetbrains/java/decompiler/util/TextUtil.java index 8957fe1..21f10e4 100644 --- a/src/org/jetbrains/java/decompiler/util/TextUtil.java +++ b/src/org/jetbrains/java/decompiler/util/TextUtil.java @@ -15,13 +15,23 @@ */ package org.jetbrains.java.decompiler.util; +import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.main.ClassesProcessor; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; +import java.util.Arrays; +import java.util.HashSet; + public class TextUtil { + private static final HashSet KEYWORDS = new HashSet<>(Arrays.asList( + "abstract", "default", "if", "private", "this", "boolean", "do", "implements", "protected", "throw", "break", "double", "import", + "public", "throws", "byte", "else", "instanceof", "return", "transient", "case", "extends", "int", "short", "try", "catch", "final", + "interface", "static", "void", "char", "finally", "long", "strictfp", "volatile", "class", "float", "native", "super", "while", + "const", "for", "new", "switch", "continue", "goto", "package", "synchronized", "true", "false", "null", "assert")); + public static void writeQualifiedSuper(TextBuffer buf, String qualifier) { ClassesProcessor.ClassNode classNode = (ClassesProcessor.ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE); if (!qualifier.equals(classNode.classStruct.qualifiedName)) { @@ -51,4 +61,26 @@ public class TextUtil { sTemp = ("0000" + sTemp).substring(sTemp.length()); return "\\u" + sTemp; } + + public static boolean isValidIdentifier(String id, int version) { + return isJavaIdentifier(id) && !isKeyword(id, version); + } + + private static boolean isJavaIdentifier(String id) { + if (id.isEmpty() || !Character.isJavaIdentifierStart(id.charAt(0))) { + return false; + } + + for (int i = 1; i < id.length(); i++) { + if (!Character.isJavaIdentifierPart(id.charAt(i))) { + return false; + } + } + + return true; + } + + private static boolean isKeyword(String id, int version) { + return KEYWORDS.contains(id) || version > CodeConstants.BYTECODE_JAVA_5 && "enum".equals(id); + } } \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 5bdbdc5..dd509f6 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -86,6 +86,7 @@ public class SingleClassesTest { @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } + @Test public void testIllegalVarName() { doTest("pkg/TestIllegalVarName"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); @@ -132,4 +133,4 @@ public class SingleClassesTest { return files; } -} +} \ No newline at end of file diff --git a/testData/classes/pkg/TestIllegalVarName.class b/testData/classes/pkg/TestIllegalVarName.class new file mode 100644 index 0000000000000000000000000000000000000000..5fd5ec6e5243567cc1230201037e04e6d262721b GIT binary patch literal 1224 zcmaJD z0>%)pS#8U-EvIVkmukE$BM33D2E$6aaCvtiJ>gVy`PD%m!(zeps%DMLl4l9WH!a6; zr6q++deN1|mTl)4hUAIxqlhxh*Ij7~$E>v*rf?+p9LqNIjw<1cvLAuLFjYR`<@#I8 zqecml_k%=N`a179H`vwcQ4BHMG;jkWlyu-oTJzVXP30>kXGy#gY~UYK^vf8&e0! zEVU`1PD*8qVXxPjF|?FsXz^ah(4tBi31rmhbyB@fR@-Dd;j@pr7T5NY@z9L6Ih57o z;XvvnBWIs<+7+#mWvWC{O)yj8Ww+53Huo}3yHynq!{p#%Z`36{W7n;4^+dPa-*{n_ zY<{Q?hS7p>c(K(eaWC-9zH2#BG_zHLA9Lj8Go;`(Fkd7gi>Z3{3K3^BBx0Dze8I V_Oa~afsb(?;l2{}vC>x_{stzQ9s2+P literal 0 HcmV?d00001 diff --git a/testData/results/TestIllegalVarName.dec b/testData/results/TestIllegalVarName.dec new file mode 100644 index 0000000..3eb1ea5 --- /dev/null +++ b/testData/results/TestIllegalVarName.dec @@ -0,0 +1,33 @@ +package pkg; + +import kotlin.Metadata; +import kotlin.jvm.internal.Intrinsics; +import org.jetbrains.annotations.NotNull; + +@Metadata( + mv = {1, 1, 0}, + bv = {1, 0, 0}, + k = 1, + d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0002\n\u0002\u0010\b\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u0016\u0010\u0003\u001a\u00020\u00042\u0006\u0010\u0005\u001a\u00020\u00042\u0006\u0010\u0006\u001a\u00020\u0007¨\u0006\b"}, + d2 = {"Lpkg/TestIllegalVarName;", "", "()V", "m", "", "this", "enum", "", "java-decompiler-plugin"} +) +public final class TestIllegalVarName { + @NotNull + public final String m(@NotNull String var1, int var2) { + Intrinsics.checkParameterIsNotNull(var1, "this"); + return var1 + '/' + var2;// 5 + } +} + +class 'pkg/TestIllegalVarName' { + method 'm (Ljava/lang/String;I)Ljava/lang/String;' { + 1 16 + 3 16 + 11 17 + 1a 17 + 1d 17 + } +} + +Lines mapping: +5 <-> 18 diff --git a/testData/src/pkg/TestIllegalVarName.kt b/testData/src/pkg/TestIllegalVarName.kt new file mode 100644 index 0000000..cf47c6e --- /dev/null +++ b/testData/src/pkg/TestIllegalVarName.kt @@ -0,0 +1,7 @@ +package pkg + +class TestIllegalVarName { + fun m(`this`: String, `enum`: Int): String { + return `this` + '/' + `enum` + } +} \ No newline at end of file From 4a1a747bdcf930235a4469a8dfb9d4595dcb0d95 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 17:57:57 +0200 Subject: [PATCH 051/252] [java-decompiler] fixes indentation in annotations --- .../java/decompiler/main/ClassWriter.java | 3 +- .../decompiler/exps/AnnotationExprent.java | 17 ++- .../java/decompiler/SingleClassesTest.java | 1 + .../MoreAnnotations$NestedAnnotation.class | Bin 0 -> 325 bytes .../pkg/MoreAnnotations$TestEnum.class | Bin 0 -> 1069 bytes testData/classes/pkg/MoreAnnotations.class | Bin 0 -> 2662 bytes testData/results/MoreAnnotations.dec | 107 ++++++++++++++++++ testData/src/pkg/MoreAnnotations.java | 89 +++++++++++++++ 8 files changed, 206 insertions(+), 11 deletions(-) create mode 100644 testData/classes/pkg/MoreAnnotations$NestedAnnotation.class create mode 100644 testData/classes/pkg/MoreAnnotations$TestEnum.class create mode 100644 testData/classes/pkg/MoreAnnotations.class create mode 100644 testData/results/MoreAnnotations.dec create mode 100644 testData/src/pkg/MoreAnnotations.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index f79198f..cded67e 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -816,7 +816,7 @@ public class ClassWriter { StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttributes().getWithKey("AnnotationDefault"); if (attr != null) { buffer.append(" default "); - buffer.append(attr.getDefaultValue().toJava(indent + 1, new BytecodeMappingTracer())); // dummy tracer + buffer.append(attr.getDefaultValue().toJava(0, new BytecodeMappingTracer())); // dummy tracer } } @@ -970,7 +970,6 @@ public class ClassWriter { StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; private static void appendParameterAnnotations(TextBuffer buffer, StructMethod mt, int param) { - BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one for (String name : PARAMETER_ANNOTATION_ATTRIBUTES) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java index 905bc21..9b797a9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.List; public class AnnotationExprent extends Exprent { - public static final int ANNOTATION_NORMAL = 1; public static final int ANNOTATION_MARKER = 2; public static final int ANNOTATION_SINGLE_ELEMENT = 3; @@ -45,12 +44,12 @@ public class AnnotationExprent extends Exprent { TextBuffer buffer = new TextBuffer(); buffer.appendIndent(indent); - buffer.append("@"); + buffer.append('@'); buffer.append(DecompilerContext.getImportCollector().getShortName(ExprProcessor.buildJavaClassName(className))); if (!parNames.isEmpty()) { - buffer.append("("); - if (parNames.size() == 1 && "value".equals(parNames.get(0))) { + buffer.append('('); + if (getAnnotationType() == ANNOTATION_SINGLE_ELEMENT) { buffer.append(parValues.get(0).toJava(indent + 1, tracer)); } else { @@ -58,16 +57,16 @@ public class AnnotationExprent extends Exprent { buffer.appendLineSeparator().appendIndent(indent + 1); buffer.append(parNames.get(i)); buffer.append(" = "); - buffer.append(parValues.get(i).toJava(indent + 2, tracer)); + buffer.append(parValues.get(i).toJava(0, tracer)); if (i < parNames.size() - 1) { - buffer.append(","); + buffer.append(','); } } buffer.appendLineSeparator().appendIndent(indent); } - buffer.append(")"); + buffer.append(')'); } return buffer; @@ -99,4 +98,4 @@ public class AnnotationExprent extends Exprent { InterpreterUtil.equalLists(parNames, ann.parNames) && InterpreterUtil.equalLists(parValues, ann.parValues); } -} +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index dd509f6..84434a9 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -83,6 +83,7 @@ public class SingleClassesTest { @Test public void testMethodReferenceSameName() { doTest("pkg/TestMethodReferenceSameName"); } @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } + @Test public void testMoreAnnotations() { doTest("pkg/MoreAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } diff --git a/testData/classes/pkg/MoreAnnotations$NestedAnnotation.class b/testData/classes/pkg/MoreAnnotations$NestedAnnotation.class new file mode 100644 index 0000000000000000000000000000000000000000..b4204ad3a434dbbfd0c2d47904f1c5fb030992d9 GIT binary patch literal 325 zcmZut%W48a5Ulo*QKM0b_gqBcC40%ulPH4VloD7V1 zj-4At#ZSk5GY7KvB9E>GBRrppuk1lu?sh5lD_j HwNpL;eL`3# literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/MoreAnnotations$TestEnum.class b/testData/classes/pkg/MoreAnnotations$TestEnum.class new file mode 100644 index 0000000000000000000000000000000000000000..d221ad65a1982f7d75e376d7b71c225510c00175 GIT binary patch literal 1069 zcmah|QBTuQ6#nkoty?K$Y^X3NFrB&$+!)TMEo6j1LNei@u!Q*3l{$;vt!X=cmySe? zM#Hl|%6M)!Whh~{$vrvueD{3cIrsGEudhD<)KO1B#xoVqQB;soP*$N~O>FCN%&HVz z7l;>e%nMslP-Rf}Y|jrmhBL4j;zyPr?D9dMLEGot@^&1<_bs1cx&7gNulm~ctZmNS zzzA%Y`-MO72E&YQnJzyaCsGQX?e_7m&am=k+RfOxASaG|u{0Gd@3^NVbgpf4>tN9D zTHcY-b?8J1vmCx<*etfsjB}&v7`#{21JCBYMroReblWuzr(<}wNH@+YbE8kG)BopV zh&63)2U`sHZ=u^Sbr|H}olR9Gbi2omVBk?EsVD;Rrs<3?Z%m{XeQ(~abBh|S>h8cZ ztvy>*z3|VAR7B+((&G6u8a7Z+v)!;-!X1Sk^F$l!kev7?RgL91TR&bX+bd zi=_$Chut&F3`kby77B(}lg$Z-sWEZ+@8jI$YP4!Jo*K=x)LIgf0J5YCNM%KB6p@j@ z0`7tOPu^p)VyQ#0&xl+>`bZwb1KML@Oeg#zmd5xxBH^i;mdjrdy@D+8ksJ6dooFKz z9wHaUsYiqoj5SE~0ZMr-cZt}iFg!_jeOYbJBZ0S+3z?3r16&z`;3>Lyc_F>(tmm5|;HM2}TJa}Hq zK62b3%tV8Aog+#HLSU$T)U;Gmf#goZF?%P();e_KLe*(8v+~E+{^AyX$gb=-4a>Cs zecrC)_VzJh!?A11G0+QFr&M-LSAp`_B%>_Kq_@w6l{)8Z$(oaey6gG*N3>{EQ171) z-G5qc<{3DY5(@~E%seHnPC-t|io7hnPMx@!js1h>(F4~tk0`7ZP|dY=dfwAcFSKlW z<*VgKDz)@NspZe5Nd8>vqvrv}8qvk;Rj+crIN4JQ^rYs9w!7VKv?FKywxe8iVw@q? zrbo_1to@r@c4)dZaboHdZ~w_?etbm4+kg8m-4yYzo-lj6%j_Na_m6?L+THCAbb7l~ z2__@EUEV~=syKF4D=*5tryY6U0&!1y1X6*Ygh7!?){B;9S1jIXI^gR4T5_#=qiVVI zMHezffwBJYB5&=Otp+pGlT)^!Y+l(dWlPF#Dr-oomIbaXWI}r^(4!0IgoL!=Btt`f z;)$wX-NcCi^@xzoP^n(C&1TDG2QQtCxVIQcdP1c8+#FlTY*Pz4khmPkTn?lz2XdDK z$;*N4$ne$>oxKGL05c1R{i2IzgA@F|_O_rRNTd@lD24$K&_5Ll%llkt3 zJdJ#y`(-^T?^zYL$>l!Oe|56`eiE1tNp<{m3CxALPs_r$Tp+@4lz(XqA<5MRc3uR- zxXAH+`d;FEq=-?BsfVBeFWf2Jy&Er8HMjjh^yq8BY zPf=J|gzUGlD(j0;gA!ItcvQk;S!;}XY~sl#KG;M_)*UzSG37BZYGBpCQ(DO+qSTV+ zndB7dt9Cs5MDmP!_|(Ie6q1Ca6>L+^3O++BCNP4}$@L5B5G7FpWBAesNR+@hzVZPw zBQOcm2gr%QC6s-DvhbvOZM@IL8W#DR9E&bwPi-N1`LROmf3 z>Ly$rHFSLEgqPq2&JW%{omn&k&R{Rlxr|o88SDr;Z{bio2e%=78E@n30O~7w2j6IP qIM^Y~vVtQmsr2-_rKjz;^nIsP{$Bl`9p^g6Oatp_BsdPv5B&?0+gXhO literal 0 HcmV?d00001 diff --git a/testData/results/MoreAnnotations.dec b/testData/results/MoreAnnotations.dec new file mode 100644 index 0000000..7ca5d12 --- /dev/null +++ b/testData/results/MoreAnnotations.dec @@ -0,0 +1,107 @@ +package pkg; + +public @interface MoreAnnotations { + @MoreAnnotations( + intValue = 1, + byteValue = 1, + floatValue = 1.0F, + doubleValue = 1.0D, + booleanValue = true, + shortValue = 1, + longValue = 1L, + charValue = '\n', + enumValue = MoreAnnotations.TestEnum.FirstValue, + annotationValue = @MoreAnnotations.NestedAnnotation("a"), + stringValue = "", + classValue = String.class + ) + String annotatedWithValues = ""; + @MoreAnnotations( + intArray = {}, + byteArray = {}, + floatArray = {}, + doubleArray = {}, + booleanArray = {}, + shortArray = {}, + longArray = {}, + charArray = {}, + enumArray = {}, + annotationArray = {}, + stringArray = {}, + classArray = {} + ) + String annotatedWithEmptyArrays = ""; + @MoreAnnotations( + intArray = {1, 0, 2147483647, -2147483648}, + byteArray = {(byte)1, (byte)0, (byte)127, (byte)-128}, + floatArray = {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}, + doubleArray = {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}, + booleanArray = {true, false}, + shortArray = {(short)1, (short)0, (short)32767, (short)-32768}, + longArray = {1L, 0L, 9223372036854775807L, -9223372036854775808L}, + charArray = {'a', '\n', '\u0001', '\u0000', '\uffff', '\u0000'}, + enumArray = {MoreAnnotations.TestEnum.FirstValue, MoreAnnotations.TestEnum.SecondValue}, + annotationArray = {@MoreAnnotations.NestedAnnotation("a"), @MoreAnnotations.NestedAnnotation("b")}, + stringArray = {"first", "second", ""}, + classArray = {CharSequence.class, String.class, StringBuilder.class} + ) + String annotatedWithArrays = ""; + + int intValue() default 1; + + byte byteValue() default 1; + + float floatValue() default 1.0F / 0.0; + + double doubleValue() default 0.0D / 0.0; + + boolean booleanValue() default true; + + short shortValue() default 1; + + long longValue() default 1L; + + char charValue() default '0'; + + MoreAnnotations.TestEnum enumValue() default MoreAnnotations.TestEnum.FirstValue; + + MoreAnnotations.NestedAnnotation annotationValue() default @MoreAnnotations.NestedAnnotation; + + String stringValue() default "default"; + + Class classValue() default CharSequence.class; + + int[] intArray() default {1, 0, 2147483647, -2147483648}; + + byte[] byteArray() default {(byte)1, (byte)0, (byte)127, (byte)-128}; + + float[] floatArray() default {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}; + + double[] doubleArray() default {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}; + + boolean[] booleanArray() default {true, false}; + + short[] shortArray() default {(short)1, (short)0, (short)32767, (short)-32768}; + + long[] longArray() default {1L, 0L, 9223372036854775807L, -9223372036854775808L}; + + char[] charArray() default {'\u0001', '\u0000', '\uffff', '\u0000'}; + + MoreAnnotations.TestEnum[] enumArray() default {MoreAnnotations.TestEnum.FirstValue}; + + MoreAnnotations.NestedAnnotation[] annotationArray() default {@MoreAnnotations.NestedAnnotation}; + + String[] stringArray() default {"first", "second", ""}; + + Class[] classArray() default {CharSequence.class, String.class, StringBuilder.class}; + + public static enum TestEnum { + FirstValue, + SecondValue; + } + + public @interface NestedAnnotation { + String value() default "MyString"; + } +} + diff --git a/testData/src/pkg/MoreAnnotations.java b/testData/src/pkg/MoreAnnotations.java new file mode 100644 index 0000000..e66835e --- /dev/null +++ b/testData/src/pkg/MoreAnnotations.java @@ -0,0 +1,89 @@ +package pkg; + +public @interface MoreAnnotations { + + int intValue() default 1; + byte byteValue() default 1; + float floatValue() default Float.POSITIVE_INFINITY; + double doubleValue() default Double.NaN; + boolean booleanValue() default true; + short shortValue() default 1; + long longValue() default 1; + char charValue() default '0'; + TestEnum enumValue() default TestEnum.FirstValue; + NestedAnnotation annotationValue() default @NestedAnnotation; + String stringValue() default "default"; + Class classValue() default CharSequence.class; + + int[] intArray() default { 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE }; + byte[] byteArray() default { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE }; + float[] floatArray() default { 1, 0, Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY }; + double[] doubleArray() default { 1, 0, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }; + boolean[] booleanArray() default { true, false }; + short[] shortArray() default { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE }; + long[] longArray() default { 1, 0, Long.MAX_VALUE, Long.MIN_VALUE }; + char[] charArray() default { 1, 0, Character.MAX_VALUE, Character.MIN_VALUE }; + TestEnum[] enumArray() default { TestEnum.FirstValue }; + NestedAnnotation[] annotationArray() default { @NestedAnnotation }; + String[] stringArray() default { "first", "second", ""}; + Class[] classArray() default { CharSequence.class, String.class, StringBuilder.class }; + + @interface NestedAnnotation { + String value() default "MyString"; + } + + @MoreAnnotations( + intValue = 1, + byteValue = 1, + floatValue = 1, + doubleValue = 1, + booleanValue = true, + shortValue = 1, + longValue = 1, + charValue = '\n', + enumValue = TestEnum.FirstValue, + annotationValue = @NestedAnnotation("a"), + stringValue = "", + classValue = String.class + ) + String annotatedWithValues = ""; + + @MoreAnnotations( + intArray = {}, + byteArray = {}, + floatArray = {}, + doubleArray = {}, + booleanArray = {}, + shortArray = {}, + longArray = {}, + charArray = {}, + enumArray = {}, + annotationArray = {}, + stringArray = {}, + classArray = {} + ) + String annotatedWithEmptyArrays = ""; + + @MoreAnnotations( + intArray = { 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE }, + byteArray = { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE }, + floatArray = { 1, 0, Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY }, + doubleArray = { 1, 0, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }, + booleanArray = { true, false }, + shortArray = { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE }, + longArray = { 1, 0, Long.MAX_VALUE, Long.MIN_VALUE }, + charArray = { 'a', '\n', 1, 0, Character.MAX_VALUE, Character.MIN_VALUE }, + enumArray = { TestEnum.FirstValue , TestEnum.SecondValue}, + annotationArray = { @NestedAnnotation("a"), @NestedAnnotation("b") }, + stringArray = { "first", "second", ""}, + classArray = { CharSequence.class, String.class, StringBuilder.class } + ) + String annotatedWithArrays = ""; + + public enum TestEnum { + + FirstValue, + SecondValue + + } +} From df19689f2b57aa221eb0102e893a883cec8a06b1 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 18:36:35 +0200 Subject: [PATCH 052/252] Cleanup (formatting) --- .../modules/decompiler/exps/ConstExprent.java | 276 ++++++++---------- 1 file changed, 121 insertions(+), 155 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index 908611a..e618235 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -123,158 +123,128 @@ public class ConstExprent extends Exprent { if (constType.type != CodeConstants.TYPE_NULL && value == null) { return new TextBuffer(ExprProcessor.getCastTypeName(constType)); } - else { - switch (constType.type) { - case CodeConstants.TYPE_BOOLEAN: - return new TextBuffer(Boolean.toString(((Integer)value).intValue() != 0)); - case CodeConstants.TYPE_CHAR: - Integer val = (Integer)value; - String ret = ESCAPES.get(val); - if (ret == null) { - char c = (char)val.intValue(); - if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) { - ret = String.valueOf(c); - } - else { - ret = TextUtil.charToUnicodeLiteral(c); - } - } - return new TextBuffer(ret).enclose("\'", "\'"); - case CodeConstants.TYPE_BYTE: - case CodeConstants.TYPE_BYTECHAR: - case CodeConstants.TYPE_SHORT: - case CodeConstants.TYPE_SHORTCHAR: - case CodeConstants.TYPE_INT: - int ival = ((Integer)value).intValue(); - String intfield; - if (literal) { - return new TextBuffer(value.toString()); - } - else if (ival == Integer.MAX_VALUE) { - intfield = "MAX_VALUE"; - } - else if (ival == Integer.MIN_VALUE) { - intfield = "MIN_VALUE"; + switch (constType.type) { + case CodeConstants.TYPE_BOOLEAN: + return new TextBuffer(Boolean.toString(((Integer)value).intValue() != 0)); + + case CodeConstants.TYPE_CHAR: + Integer val = (Integer)value; + String ret = ESCAPES.get(val); + if (ret == null) { + char c = (char)val.intValue(); + if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) { + ret = String.valueOf(c); } else { - return new TextBuffer(value.toString()); + ret = TextUtil.charToUnicodeLiteral(c); } - return new FieldExprent(intfield, "java/lang/Integer", true, null, FieldDescriptor.INTEGER_DESCRIPTOR, bytecode).toJava(0, tracer); - case CodeConstants.TYPE_LONG: - long lval = ((Long)value).longValue(); + } + return new TextBuffer().append('\'').append(ret).append('\''); - String longfield; - if (literal) { - return new TextBuffer(value.toString()).append("L"); + case CodeConstants.TYPE_BYTE: + case CodeConstants.TYPE_BYTECHAR: + case CodeConstants.TYPE_SHORT: + case CodeConstants.TYPE_SHORTCHAR: + case CodeConstants.TYPE_INT: + int intVal = ((Integer)value).intValue(); + if (!literal) { + if (intVal == Integer.MAX_VALUE) { + return new FieldExprent("MAX_VALUE", "java/lang/Integer", true, null, FieldDescriptor.INTEGER_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (lval == Long.MAX_VALUE) { - longfield = "MAX_VALUE"; + else if (intVal == Integer.MIN_VALUE) { + return new FieldExprent("MIN_VALUE", "java/lang/Integer", true, null, FieldDescriptor.INTEGER_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (lval == Long.MIN_VALUE) { - longfield = "MIN_VALUE"; - } - else { - return new TextBuffer(value.toString()).append("L"); - } - return new FieldExprent(longfield, "java/lang/Long", true, null, FieldDescriptor.LONG_DESCRIPTOR, bytecode).toJava(0, tracer); - case CodeConstants.TYPE_DOUBLE: - double dval = ((Double)value).doubleValue(); + } + return new TextBuffer(value.toString()); - String doublefield; - if (literal) { - if (Double.isNaN(dval)) { - return new TextBuffer("0.0D / 0.0"); - } - else if (dval == Double.POSITIVE_INFINITY) { - return new TextBuffer("1.0D / 0.0"); - } - else if (dval == Double.NEGATIVE_INFINITY) { - return new TextBuffer("-1.0D / 0.0"); - } - else { - return new TextBuffer(value.toString()).append("D"); - } + case CodeConstants.TYPE_LONG: + long longVal = ((Long)value).longValue(); + if (!literal) { + if (longVal == Long.MAX_VALUE) { + return new FieldExprent("MAX_VALUE", "java/lang/Long", true, null, FieldDescriptor.LONG_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (Double.isNaN(dval)) { - doublefield = "NaN"; + else if (longVal == Long.MIN_VALUE) { + return new FieldExprent("MIN_VALUE", "java/lang/Long", true, null, FieldDescriptor.LONG_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (dval == Double.POSITIVE_INFINITY) { - doublefield = "POSITIVE_INFINITY"; - } - else if (dval == Double.NEGATIVE_INFINITY) { - doublefield = "NEGATIVE_INFINITY"; - } - else if (dval == Double.MAX_VALUE) { - doublefield = "MAX_VALUE"; - } - else if (dval == Double.MIN_VALUE) { - doublefield = "MIN_VALUE"; - } - else { - return new TextBuffer(value.toString()).append("D"); - } - return new FieldExprent(doublefield, "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); - case CodeConstants.TYPE_FLOAT: - float fval = ((Float)value).floatValue(); + } + return new TextBuffer(value.toString()).append('L'); - String floatfield; - if (literal) { - if (Double.isNaN(fval)) { - return new TextBuffer("0.0F / 0.0"); - } - else if (fval == Double.POSITIVE_INFINITY) { - return new TextBuffer("1.0F / 0.0"); - } - else if (fval == Double.NEGATIVE_INFINITY) { - return new TextBuffer("-1.0F / 0.0"); - } - else { - return new TextBuffer(value.toString()).append("F"); - } + case CodeConstants.TYPE_FLOAT: + float floatVal = ((Float)value).floatValue(); + if (!literal) { + if (Float.isNaN(floatVal)) { + return new FieldExprent("NaN", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (Float.isNaN(fval)) { - floatfield = "NaN"; + else if (floatVal == Float.POSITIVE_INFINITY) { + return new FieldExprent("POSITIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (fval == Float.POSITIVE_INFINITY) { - floatfield = "POSITIVE_INFINITY"; + else if (floatVal == Float.NEGATIVE_INFINITY) { + return new FieldExprent("NEGATIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (fval == Float.NEGATIVE_INFINITY) { - floatfield = "NEGATIVE_INFINITY"; + else if (floatVal == Float.MAX_VALUE) { + return new FieldExprent("MAX_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (fval == Float.MAX_VALUE) { - floatfield = "MAX_VALUE"; + else if (floatVal == Float.MIN_VALUE) { + return new FieldExprent("MIN_VALUE", "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); } - else if (fval == Float.MIN_VALUE) { - floatfield = "MIN_VALUE"; - } - else { - return new TextBuffer(value.toString()).append("F"); - } - return new FieldExprent(floatfield, "java/lang/Float", true, null, FieldDescriptor.FLOAT_DESCRIPTOR, bytecode).toJava(0, tracer); - case CodeConstants.TYPE_NULL: - return new TextBuffer("null"); - case CodeConstants.TYPE_OBJECT: - if (constType.equals(VarType.VARTYPE_STRING)) { - return new TextBuffer(convertStringToJava(value.toString(), ascii)).enclose("\"", "\""); - } - else if (constType.equals(VarType.VARTYPE_CLASS)) { - String strval = value.toString(); + } + else if (Float.isNaN(floatVal)) { + return new TextBuffer("0.0F / 0.0"); + } + else if (floatVal == Float.POSITIVE_INFINITY) { + return new TextBuffer("1.0F / 0.0"); + } + else if (floatVal == Float.NEGATIVE_INFINITY) { + return new TextBuffer("-1.0F / 0.0"); + } + return new TextBuffer(value.toString()).append('F'); - VarType classtype; - if (strval.startsWith("[")) { // array of simple type - classtype = new VarType(strval, false); - } - else { // class - classtype = new VarType(strval, true); - } - - return new TextBuffer(ExprProcessor.getCastTypeName(classtype)).append(".class"); + case CodeConstants.TYPE_DOUBLE: + double doubleVal = ((Double)value).doubleValue(); + if (!literal) { + if (Double.isNaN(doubleVal)) { + return new FieldExprent("NaN", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); } - } + else if (doubleVal == Double.POSITIVE_INFINITY) { + return new FieldExprent("POSITIVE_INFINITY", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); + } + else if (doubleVal == Double.NEGATIVE_INFINITY) { + return new FieldExprent("NEGATIVE_INFINITY", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); + } + else if (doubleVal == Double.MAX_VALUE) { + return new FieldExprent("MAX_VALUE", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); + } + else if (doubleVal == Double.MIN_VALUE) { + return new FieldExprent("MIN_VALUE", "java/lang/Double", true, null, FieldDescriptor.DOUBLE_DESCRIPTOR, bytecode).toJava(0, tracer); + } + } + else if (Double.isNaN(doubleVal)) { + return new TextBuffer("0.0D / 0.0"); + } + else if (doubleVal == Double.POSITIVE_INFINITY) { + return new TextBuffer("1.0D / 0.0"); + } + else if (doubleVal == Double.NEGATIVE_INFINITY) { + return new TextBuffer("-1.0D / 0.0"); + } + return new TextBuffer(value.toString()).append('D'); + + case CodeConstants.TYPE_NULL: + return new TextBuffer("null"); + + case CodeConstants.TYPE_OBJECT: + if (constType.equals(VarType.VARTYPE_STRING)) { + return new TextBuffer().append('"').append(convertStringToJava(value.toString(), ascii)).append('"'); + } + else if (constType.equals(VarType.VARTYPE_CLASS)) { + String stringVal = value.toString(); + VarType type = new VarType(stringVal, !stringVal.startsWith("[")); + return new TextBuffer(ExprProcessor.getCastTypeName(type)).append(".class"); + } } - throw new RuntimeException("invalid constant type"); + throw new RuntimeException("invalid constant type: " + constType); } private static String convertStringToJava(String value, boolean ascii) { @@ -339,9 +309,8 @@ public class ConstExprent extends Exprent { case CodeConstants.TYPE_SHORT: case CodeConstants.TYPE_SHORTCHAR: case CodeConstants.TYPE_INT: - Integer ival = (Integer)value; - return ival.intValue() == 0 || - (DecompilerContext.getOption(IFernflowerPreferences.BOOLEAN_TRUE_ONE) && ival.intValue() == 1); + int value = ((Integer)this.value).intValue(); + return value == 0 || (DecompilerContext.getOption(IFernflowerPreferences.BOOLEAN_TRUE_ONE) && value == 1); } return false; @@ -380,7 +349,7 @@ public class ConstExprent extends Exprent { return new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0), null); } - throw new RuntimeException("Invalid argument!"); + throw new RuntimeException("Invalid argument: " + type); } public VarType getConstType() { @@ -406,32 +375,29 @@ public class ConstExprent extends Exprent { // ***************************************************************************** // IMatchable implementation // ***************************************************************************** - - public boolean match(MatchNode matchNode, MatchEngine engine) { - if(!super.match(matchNode, engine)) { + @Override + public boolean match(MatchNode matchNode, MatchEngine engine) { + if (!super.match(matchNode, engine)) { return false; } - - for(Entry rule : matchNode.getRules().entrySet()) { - RuleValue rule_value = rule.getValue(); - - switch(rule.getKey()) { - case EXPRENT_CONSTTYPE: - if(!rule_value.value.equals(this.constType)) { + + for (Entry rule : matchNode.getRules().entrySet()) { + RuleValue value = rule.getValue(); + MatchProperties key = rule.getKey(); + + if (key == MatchProperties.EXPRENT_CONSTTYPE) { + if (!value.value.equals(this.constType)) { + return false; + } + } + else if (key == MatchProperties.EXPRENT_CONSTVALUE) { + if (value.isVariable() && !engine.checkAndSetVariableValue(value.value.toString(), this.value)) { return false; } - break; - case EXPRENT_CONSTVALUE: - if(rule_value.isVariable()) { - if(!engine.checkAndSetVariableValue(rule_value.value.toString(), this.value)) { - return false; - } - } - break; } } - + return true; } } \ No newline at end of file From a00952f3384c142ef435e3503fc54c461ce0e970 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 19:37:40 +0200 Subject: [PATCH 053/252] Cleanup (formatting) --- .../modules/decompiler/ExprProcessor.java | 47 ++++++++----------- .../modules/decompiler/exps/ArrayExprent.java | 7 ++- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 9d81e07..50c206c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -849,26 +849,24 @@ public class ExprProcessor implements CodeConstants { return buf; } - public static ConstExprent getDefaultArrayValue(VarType arrtype) { - - ConstExprent defaultval; - if (arrtype.type == CodeConstants.TYPE_OBJECT || arrtype.arrayDim > 0) { - defaultval = new ConstExprent(VarType.VARTYPE_NULL, null, null); + public static ConstExprent getDefaultArrayValue(VarType arrType) { + ConstExprent defaultVal; + if (arrType.type == CodeConstants.TYPE_OBJECT || arrType.arrayDim > 0) { + defaultVal = new ConstExprent(VarType.VARTYPE_NULL, null, null); } - else if (arrtype.type == CodeConstants.TYPE_FLOAT) { - defaultval = new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0), null); + else if (arrType.type == CodeConstants.TYPE_FLOAT) { + defaultVal = new ConstExprent(VarType.VARTYPE_FLOAT, new Float(0), null); } - else if (arrtype.type == CodeConstants.TYPE_LONG) { - defaultval = new ConstExprent(VarType.VARTYPE_LONG, new Long(0), null); + else if (arrType.type == CodeConstants.TYPE_LONG) { + defaultVal = new ConstExprent(VarType.VARTYPE_LONG, new Long(0), null); } - else if (arrtype.type == CodeConstants.TYPE_DOUBLE) { - defaultval = new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0), null); + else if (arrType.type == CodeConstants.TYPE_DOUBLE) { + defaultVal = new ConstExprent(VarType.VARTYPE_DOUBLE, new Double(0), null); } else { // integer types - defaultval = new ConstExprent(0, true, null); + defaultVal = new ConstExprent(0, true, null); } - - return defaultval; + return defaultVal; } public static boolean getCastedExprent(Exprent exprent, @@ -887,35 +885,30 @@ public class ExprProcessor implements CodeConstants { boolean castNull, boolean castAlways, BytecodeMappingTracer tracer) { - VarType rightType = exprent.getExprType(); - TextBuffer res = exprent.toJava(indent, tracer); - boolean cast = castAlways || (!leftType.isSuperset(rightType) && (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.type != CodeConstants.TYPE_OBJECT)) || (castNull && rightType.type == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType))) || (isIntConstant(exprent) && VarType.VARTYPE_INT.isStrictSuperset(leftType)); - if (cast) { - if (exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST)) { - res.enclose("(", ")"); - } + boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST); - res.prepend("(" + getCastTypeName(leftType) + ")"); - } + if (cast) buffer.append('(').append(getCastTypeName(leftType)).append(')'); - buffer.append(res); + if (quote) buffer.append('('); + + buffer.append(exprent.toJava(indent, tracer)); + + if (quote) buffer.append(')'); return cast; } private static boolean isIntConstant(Exprent exprent) { - if (exprent.type == Exprent.EXPRENT_CONST) { - ConstExprent cexpr = (ConstExprent)exprent; - switch (cexpr.getConstType().type) { + switch (((ConstExprent)exprent).getConstType().type) { case CodeConstants.TYPE_BYTE: case CodeConstants.TYPE_BYTECHAR: case CodeConstants.TYPE_SHORT: diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java index 8f7269b..c8db797 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import java.util.List; import java.util.Set; public class ArrayExprent extends Exprent { - private Exprent array; private Exprent index; private final VarType hardType; @@ -91,7 +90,7 @@ public class ArrayExprent extends Exprent { tracer.addMapping(bytecode); - return res.append("[").append(index.toJava(indent, tracer)).append("]"); + return res.append('[').append(index.toJava(indent, tracer)).append(']'); } @Override @@ -121,4 +120,4 @@ public class ArrayExprent extends Exprent { public Exprent getIndex() { return index; } -} +} \ No newline at end of file From b366de8eb4354b33b8f0eeb9962d4d0b3d4e8aec Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 20 Apr 2016 19:52:08 +0200 Subject: [PATCH 054/252] [java-decompiler] unneeded cast around byte/short constants --- .../modules/decompiler/ExprProcessor.java | 2 +- .../pkg/MoreAnnotations$TestEnum.class | Bin 1069 -> 977 bytes testData/classes/pkg/MoreAnnotations.class | Bin 2662 -> 2679 bytes testData/results/MoreAnnotations.dec | 8 ++++---- testData/src/pkg/MoreAnnotations.java | 14 +++++++------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 50c206c..b791e62 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -891,7 +891,7 @@ public class ExprProcessor implements CodeConstants { castAlways || (!leftType.isSuperset(rightType) && (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.type != CodeConstants.TYPE_OBJECT)) || (castNull && rightType.type == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType))) || - (isIntConstant(exprent) && VarType.VARTYPE_INT.isStrictSuperset(leftType)); + (isIntConstant(exprent) && rightType.isStrictSuperset(leftType)); boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST); diff --git a/testData/classes/pkg/MoreAnnotations$TestEnum.class b/testData/classes/pkg/MoreAnnotations$TestEnum.class index d221ad65a1982f7d75e376d7b71c225510c00175..5e4765d3df9a82e432b3c4efd62b67ad9d289c81 100644 GIT binary patch delta 245 zcmZ3>agp8T)W2Q(7#J8#7z{WWSQwPJ7?c@Q*cpV`8PvEKco@_{ga!u#FBec!1EfNe zgFz5PYq2wEZ?xfLY2MJ8o7eI5oW z2ICsf!1*ev1sjJU_HRVvH{3rWDp0EY+#vSpbDUBASnhElV@NCLIwtQ zEp3_Y3~U=Q6w3fbm>6UkI2hy@WG8QBj+BRp$TKK_WfU3sfixG;Xch)l20jN#0MBk4 Ag8%>k delta 344 zcmZvW%}T>S6ot?o$Ahz67J6vlA+&CM^Q3tGZf~z! Sn+4j!EV-ne9Cgf`EdBuy87@fx diff --git a/testData/classes/pkg/MoreAnnotations.class b/testData/classes/pkg/MoreAnnotations.class index 36178dea70f2c1bd9ea20087baa77a1fda68c668..85146c8c8b7174ee28a29cc5be67b7ecd55225ea 100644 GIT binary patch delta 877 zcmZva$!^n77==G)z@@6xP=W}Qc@&-7L}7+v8;e+|AW|{J3@ssyZGgIE1~WWDCEf$E zW5FICgat3a4me5eVnujy<@=p;uYLai|B?TdFMj|15Htdl_n(R%Q`z(%J)gg&W-`Xl?@ z8IR2#=RGcXOf%-Q#^$2U*3c$rQ?|LJm2utEU^_cn%Vj3Con#jVy94&DzFnc{lMbi_ z_yPMUX;iS&K3z1)w_1w0Vg&m5_h07}NZ zlB8%#IKacm*{h-|T!nIlgB1=*9Nyg<47;WO%6M|EZYzZ3EO`=F4r(Y z`~@ZRCI!yAXx;jKmfLZX(Y z+sg|UL-lq$S@h@UluDGtyN~4$_NQ<5Y|i@LDLPxyTn)EIwZ@?uhZ%`+Le_^I2{{^a zEaZ5|iI6EqMG4pta5BITm<~7zK{bv!0rc-WXwwvn*|XL((XDt zzw%!CFgr6W^_ue&+X#;`(fi*l#Wl)f!}ZU(iffF;%(Z4^#)8LFl<@=Rz(p;xWQgYQ zMJ%ywi2W7lZ-9ssJjuj-jHO$f#f4%n^DM(d=1PcC;d$0zSNXdh{VHFG_Oe&% JtIo`z_Xjg~bO!(c diff --git a/testData/results/MoreAnnotations.dec b/testData/results/MoreAnnotations.dec index 7ca5d12..37302cc 100644 --- a/testData/results/MoreAnnotations.dec +++ b/testData/results/MoreAnnotations.dec @@ -33,11 +33,11 @@ public @interface MoreAnnotations { String annotatedWithEmptyArrays = ""; @MoreAnnotations( intArray = {1, 0, 2147483647, -2147483648}, - byteArray = {(byte)1, (byte)0, (byte)127, (byte)-128}, + byteArray = {1, 0, 127, -128, -1}, floatArray = {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}, doubleArray = {1.0D, 0.0D, 1.7976931348623157E308D, 4.9E-324D, 0.0D / 0.0, 1.0D / 0.0, -1.0D / 0.0}, booleanArray = {true, false}, - shortArray = {(short)1, (short)0, (short)32767, (short)-32768}, + shortArray = {1, 0, 32767, -32768, -1}, longArray = {1L, 0L, 9223372036854775807L, -9223372036854775808L}, charArray = {'a', '\n', '\u0001', '\u0000', '\uffff', '\u0000'}, enumArray = {MoreAnnotations.TestEnum.FirstValue, MoreAnnotations.TestEnum.SecondValue}, @@ -73,7 +73,7 @@ public @interface MoreAnnotations { int[] intArray() default {1, 0, 2147483647, -2147483648}; - byte[] byteArray() default {(byte)1, (byte)0, (byte)127, (byte)-128}; + byte[] byteArray() default {1, 0, 127, -128, -1}; float[] floatArray() default {1.0F, 0.0F, 3.4028235E38F, 1.4E-45F, 0.0F / 0.0, 1.0F / 0.0, -1.0F / 0.0}; @@ -81,7 +81,7 @@ public @interface MoreAnnotations { boolean[] booleanArray() default {true, false}; - short[] shortArray() default {(short)1, (short)0, (short)32767, (short)-32768}; + short[] shortArray() default {1, 0, 32767, -32768, -1}; long[] longArray() default {1L, 0L, 9223372036854775807L, -9223372036854775808L}; diff --git a/testData/src/pkg/MoreAnnotations.java b/testData/src/pkg/MoreAnnotations.java index e66835e..d29abce 100644 --- a/testData/src/pkg/MoreAnnotations.java +++ b/testData/src/pkg/MoreAnnotations.java @@ -16,16 +16,16 @@ public @interface MoreAnnotations { Class classValue() default CharSequence.class; int[] intArray() default { 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE }; - byte[] byteArray() default { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE }; + byte[] byteArray() default { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE, (byte)0xFF }; float[] floatArray() default { 1, 0, Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY }; double[] doubleArray() default { 1, 0, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }; boolean[] booleanArray() default { true, false }; - short[] shortArray() default { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE }; + short[] shortArray() default { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE, (short)0xFFFF }; long[] longArray() default { 1, 0, Long.MAX_VALUE, Long.MIN_VALUE }; char[] charArray() default { 1, 0, Character.MAX_VALUE, Character.MIN_VALUE }; TestEnum[] enumArray() default { TestEnum.FirstValue }; NestedAnnotation[] annotationArray() default { @NestedAnnotation }; - String[] stringArray() default { "first", "second", ""}; + String[] stringArray() default { "first", "second", "" }; Class[] classArray() default { CharSequence.class, String.class, StringBuilder.class }; @interface NestedAnnotation { @@ -66,16 +66,16 @@ public @interface MoreAnnotations { @MoreAnnotations( intArray = { 1, 0, Integer.MAX_VALUE, Integer.MIN_VALUE }, - byteArray = { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE }, + byteArray = { 1, 0, Byte.MAX_VALUE, Byte.MIN_VALUE, (byte)0xFF }, floatArray = { 1, 0, Float.MAX_VALUE, Float.MIN_VALUE, Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY }, doubleArray = { 1, 0, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY }, booleanArray = { true, false }, - shortArray = { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE }, + shortArray = { 1, 0, Short.MAX_VALUE, Short.MIN_VALUE, (short)0xFFFF }, longArray = { 1, 0, Long.MAX_VALUE, Long.MIN_VALUE }, charArray = { 'a', '\n', 1, 0, Character.MAX_VALUE, Character.MIN_VALUE }, - enumArray = { TestEnum.FirstValue , TestEnum.SecondValue}, + enumArray = { TestEnum.FirstValue , TestEnum.SecondValue }, annotationArray = { @NestedAnnotation("a"), @NestedAnnotation("b") }, - stringArray = { "first", "second", ""}, + stringArray = { "first", "second", "" }, classArray = { CharSequence.class, String.class, StringBuilder.class } ) String annotatedWithArrays = ""; From a67808d3aa3fb0d91926e0d707e5315a5768909e Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Apr 2016 10:16:32 +0200 Subject: [PATCH 055/252] Cleanup (formatting) --- .../modules/decompiler/ExprProcessor.java | 150 +++++++----------- 1 file changed, 59 insertions(+), 91 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index b791e62..71e2231 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -46,98 +46,66 @@ public class ExprProcessor implements CodeConstants { public static final String UNKNOWN_TYPE_STRING = ""; public static final String NULL_TYPE_STRING = ""; - private static final HashMap mapConsts = new HashMap(); - + private static final Map mapConsts = new HashMap(); static { - // mapConsts.put(new Integer(opc_i2l), new - // Integer(FunctionExprent.FUNCTION_I2L)); - // mapConsts.put(new Integer(opc_i2f), new - // Integer(FunctionExprent.FUNCTION_I2F)); - // mapConsts.put(new Integer(opc_i2d), new - // Integer(FunctionExprent.FUNCTION_I2D)); - // mapConsts.put(new Integer(opc_l2i), new - // Integer(FunctionExprent.FUNCTION_L2I)); - // mapConsts.put(new Integer(opc_l2f), new - // Integer(FunctionExprent.FUNCTION_L2F)); - // mapConsts.put(new Integer(opc_l2d), new - // Integer(FunctionExprent.FUNCTION_L2D)); - // mapConsts.put(new Integer(opc_f2i), new - // Integer(FunctionExprent.FUNCTION_F2I)); - // mapConsts.put(new Integer(opc_f2l), new - // Integer(FunctionExprent.FUNCTION_F2L)); - // mapConsts.put(new Integer(opc_f2d), new - // Integer(FunctionExprent.FUNCTION_F2D)); - // mapConsts.put(new Integer(opc_d2i), new - // Integer(FunctionExprent.FUNCTION_D2I)); - // mapConsts.put(new Integer(opc_d2l), new - // Integer(FunctionExprent.FUNCTION_D2L)); - // mapConsts.put(new Integer(opc_d2f), new - // Integer(FunctionExprent.FUNCTION_D2F)); - // mapConsts.put(new Integer(opc_i2b), new - // Integer(FunctionExprent.FUNCTION_I2B)); - // mapConsts.put(new Integer(opc_i2c), new - // Integer(FunctionExprent.FUNCTION_I2C)); - // mapConsts.put(new Integer(opc_i2s), new - // Integer(FunctionExprent.FUNCTION_I2S)); - - mapConsts.put(new Integer(opc_arraylength), new Integer(FunctionExprent.FUNCTION_ARRAY_LENGTH)); - mapConsts.put(new Integer(opc_checkcast), new Integer(FunctionExprent.FUNCTION_CAST)); - mapConsts.put(new Integer(opc_instanceof), new Integer(FunctionExprent.FUNCTION_INSTANCEOF)); + mapConsts.put(opc_arraylength, FunctionExprent.FUNCTION_ARRAY_LENGTH); + mapConsts.put(opc_checkcast, FunctionExprent.FUNCTION_CAST); + mapConsts.put(opc_instanceof, FunctionExprent.FUNCTION_INSTANCEOF); } - private static final VarType[] consts = - new VarType[]{VarType.VARTYPE_INT, VarType.VARTYPE_FLOAT, VarType.VARTYPE_LONG, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_CLASS, - VarType.VARTYPE_STRING}; + private static final VarType[] consts = { + VarType.VARTYPE_INT, VarType.VARTYPE_FLOAT, VarType.VARTYPE_LONG, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_CLASS, VarType.VARTYPE_STRING + }; - private static final VarType[] vartypes = - new VarType[]{VarType.VARTYPE_INT, VarType.VARTYPE_LONG, VarType.VARTYPE_FLOAT, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_OBJECT}; + private static final VarType[] varTypes = { + VarType.VARTYPE_INT, VarType.VARTYPE_LONG, VarType.VARTYPE_FLOAT, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_OBJECT + }; - private static final VarType[] arrtypes = - new VarType[]{VarType.VARTYPE_INT, VarType.VARTYPE_LONG, VarType.VARTYPE_FLOAT, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_OBJECT, - VarType.VARTYPE_BOOLEAN, VarType.VARTYPE_CHAR, VarType.VARTYPE_SHORT}; + private static final VarType[] arrTypes = { + VarType.VARTYPE_INT, VarType.VARTYPE_LONG, VarType.VARTYPE_FLOAT, VarType.VARTYPE_DOUBLE, VarType.VARTYPE_OBJECT, + VarType.VARTYPE_BOOLEAN, VarType.VARTYPE_CHAR, VarType.VARTYPE_SHORT + }; - private static final int[] func1 = - new int[]{FunctionExprent.FUNCTION_ADD, FunctionExprent.FUNCTION_SUB, FunctionExprent.FUNCTION_MUL, FunctionExprent.FUNCTION_DIV, - FunctionExprent.FUNCTION_REM}; + private static final int[] func1 = { + FunctionExprent.FUNCTION_ADD, FunctionExprent.FUNCTION_SUB, FunctionExprent.FUNCTION_MUL, FunctionExprent.FUNCTION_DIV, + FunctionExprent.FUNCTION_REM + }; + private static final int[] func2 = { + FunctionExprent.FUNCTION_SHL, FunctionExprent.FUNCTION_SHR, FunctionExprent.FUNCTION_USHR, FunctionExprent.FUNCTION_AND, + FunctionExprent.FUNCTION_OR, FunctionExprent.FUNCTION_XOR + }; + private static final int[] func3 = { + FunctionExprent.FUNCTION_I2L, FunctionExprent.FUNCTION_I2F, FunctionExprent.FUNCTION_I2D, FunctionExprent.FUNCTION_L2I, + FunctionExprent.FUNCTION_L2F, FunctionExprent.FUNCTION_L2D, FunctionExprent.FUNCTION_F2I, FunctionExprent.FUNCTION_F2L, + FunctionExprent.FUNCTION_F2D, FunctionExprent.FUNCTION_D2I, FunctionExprent.FUNCTION_D2L, FunctionExprent.FUNCTION_D2F, + FunctionExprent.FUNCTION_I2B, FunctionExprent.FUNCTION_I2C, FunctionExprent.FUNCTION_I2S + }; + private static final int[] func4 = { + FunctionExprent.FUNCTION_LCMP, FunctionExprent.FUNCTION_FCMPL, FunctionExprent.FUNCTION_FCMPG, FunctionExprent.FUNCTION_DCMPL, + FunctionExprent.FUNCTION_DCMPG + }; + private static final int[] func5 = { + IfExprent.IF_EQ, IfExprent.IF_NE, IfExprent.IF_LT, IfExprent.IF_GE, IfExprent.IF_GT, IfExprent.IF_LE + }; + private static final int[] func6 = { + IfExprent.IF_ICMPEQ, IfExprent.IF_ICMPNE, IfExprent.IF_ICMPLT, IfExprent.IF_ICMPGE, IfExprent.IF_ICMPGT, IfExprent.IF_ICMPLE, + IfExprent.IF_ACMPEQ, IfExprent.IF_ACMPNE + }; + private static final int[] func7 = {IfExprent.IF_NULL, IfExprent.IF_NONNULL}; + private static final int[] func8 = {MonitorExprent.MONITOR_ENTER, MonitorExprent.MONITOR_EXIT}; - private static final int[] func2 = - new int[]{FunctionExprent.FUNCTION_SHL, FunctionExprent.FUNCTION_SHR, FunctionExprent.FUNCTION_USHR, FunctionExprent.FUNCTION_AND, - FunctionExprent.FUNCTION_OR, FunctionExprent.FUNCTION_XOR}; + private static final int[] arrTypeIds = { + CodeConstants.TYPE_BOOLEAN, CodeConstants.TYPE_CHAR, CodeConstants.TYPE_FLOAT, CodeConstants.TYPE_DOUBLE, + CodeConstants.TYPE_BYTE, CodeConstants.TYPE_SHORT, CodeConstants.TYPE_INT, CodeConstants.TYPE_LONG + }; - private static final int[] func3 = - new int[]{FunctionExprent.FUNCTION_I2L, FunctionExprent.FUNCTION_I2F, FunctionExprent.FUNCTION_I2D, FunctionExprent.FUNCTION_L2I, - FunctionExprent.FUNCTION_L2F, FunctionExprent.FUNCTION_L2D, FunctionExprent.FUNCTION_F2I, FunctionExprent.FUNCTION_F2L, - FunctionExprent.FUNCTION_F2D, - FunctionExprent.FUNCTION_D2I, FunctionExprent.FUNCTION_D2L, FunctionExprent.FUNCTION_D2F, FunctionExprent.FUNCTION_I2B, - FunctionExprent.FUNCTION_I2C, - FunctionExprent.FUNCTION_I2S}; + private static final int[] negIfs = { + IfExprent.IF_NE, IfExprent.IF_EQ, IfExprent.IF_GE, IfExprent.IF_LT, IfExprent.IF_LE, IfExprent.IF_GT, IfExprent.IF_NONNULL, + IfExprent.IF_NULL, IfExprent.IF_ICMPNE, IfExprent.IF_ICMPEQ, IfExprent.IF_ICMPGE, IfExprent.IF_ICMPLT, IfExprent.IF_ICMPLE, + IfExprent.IF_ICMPGT, IfExprent.IF_ACMPNE, IfExprent.IF_ACMPEQ + }; - private static final int[] func4 = - new int[]{FunctionExprent.FUNCTION_LCMP, FunctionExprent.FUNCTION_FCMPL, FunctionExprent.FUNCTION_FCMPG, FunctionExprent.FUNCTION_DCMPL, - FunctionExprent.FUNCTION_DCMPG}; - - private static final int[] func5 = - new int[]{IfExprent.IF_EQ, IfExprent.IF_NE, IfExprent.IF_LT, IfExprent.IF_GE, IfExprent.IF_GT, IfExprent.IF_LE}; - - private static final int[] func6 = - new int[]{IfExprent.IF_ICMPEQ, IfExprent.IF_ICMPNE, IfExprent.IF_ICMPLT, IfExprent.IF_ICMPGE, IfExprent.IF_ICMPGT, IfExprent.IF_ICMPLE, - IfExprent.IF_ACMPEQ, IfExprent.IF_ACMPNE}; - - private static final int[] func7 = new int[]{IfExprent.IF_NULL, IfExprent.IF_NONNULL}; - - private static final int[] func8 = new int[]{MonitorExprent.MONITOR_ENTER, MonitorExprent.MONITOR_EXIT}; - - private static final int[] arr_type = - new int[]{CodeConstants.TYPE_BOOLEAN, CodeConstants.TYPE_CHAR, CodeConstants.TYPE_FLOAT, CodeConstants.TYPE_DOUBLE, - CodeConstants.TYPE_BYTE, CodeConstants.TYPE_SHORT, CodeConstants.TYPE_INT, CodeConstants.TYPE_LONG}; - - private static final int[] negifs = - new int[]{IfExprent.IF_NE, IfExprent.IF_EQ, IfExprent.IF_GE, IfExprent.IF_LT, IfExprent.IF_LE, IfExprent.IF_GT, IfExprent.IF_NONNULL, - IfExprent.IF_NULL, IfExprent.IF_ICMPNE, IfExprent.IF_ICMPEQ, IfExprent.IF_ICMPGE, IfExprent.IF_ICMPLT, IfExprent.IF_ICMPLE, - IfExprent.IF_ICMPGT, IfExprent.IF_ACMPNE, - IfExprent.IF_ACMPEQ}; - - private static final String[] typeNames = new String[]{"byte", "char", "double", "float", "int", "long", "short", "boolean",}; + private static final String[] typeNames = {"byte", "char", "double", "float", "int", "long", "short", "boolean"}; private final MethodDescriptor methodDescriptor; private final VarProcessor varProcessor; @@ -373,7 +341,7 @@ public class ExprProcessor implements CodeConstants { case opc_fload: case opc_dload: case opc_aload: - pushEx(stack, exprlist, new VarExprent(instr.getOperand(0), vartypes[instr.opcode - opc_iload], varProcessor)); + pushEx(stack, exprlist, new VarExprent(instr.getOperand(0), varTypes[instr.opcode - opc_iload], varProcessor)); break; case opc_iaload: case opc_laload: @@ -394,7 +362,7 @@ public class ExprProcessor implements CodeConstants { case opc_daload: vartype = VarType.VARTYPE_DOUBLE; } - pushEx(stack, exprlist, new ArrayExprent(arr, index, arrtypes[instr.opcode - opc_iaload], bytecode_offsets), vartype); + pushEx(stack, exprlist, new ArrayExprent(arr, index, arrTypes[instr.opcode - opc_iaload], bytecode_offsets), vartype); break; case opc_istore: case opc_lstore: @@ -404,7 +372,7 @@ public class ExprProcessor implements CodeConstants { Exprent top = stack.pop(); int varindex = instr.getOperand(0); AssignmentExprent assign = - new AssignmentExprent(new VarExprent(varindex, vartypes[instr.opcode - opc_istore], varProcessor), top, bytecode_offsets); + new AssignmentExprent(new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor), top, bytecode_offsets); exprlist.add(assign); break; case opc_iastore: @@ -419,7 +387,7 @@ public class ExprProcessor implements CodeConstants { Exprent index_store = stack.pop(); Exprent arr_store = stack.pop(); AssignmentExprent arrassign = - new AssignmentExprent(new ArrayExprent(arr_store, index_store, arrtypes[instr.opcode - opc_iastore], bytecode_offsets), value, + new AssignmentExprent(new ArrayExprent(arr_store, index_store, arrTypes[instr.opcode - opc_iastore], bytecode_offsets), value, bytecode_offsets); exprlist.add(arrassign); break; @@ -502,7 +470,7 @@ public class ExprProcessor implements CodeConstants { case opc_ifge: case opc_ifgt: case opc_ifle: - exprlist.add(new IfExprent(negifs[func5[instr.opcode - opc_ifeq]], stack, bytecode_offsets)); + exprlist.add(new IfExprent(negIfs[func5[instr.opcode - opc_ifeq]], stack, bytecode_offsets)); break; case opc_if_icmpeq: case opc_if_icmpne: @@ -512,11 +480,11 @@ public class ExprProcessor implements CodeConstants { case opc_if_icmple: case opc_if_acmpeq: case opc_if_acmpne: - exprlist.add(new IfExprent(negifs[func6[instr.opcode - opc_if_icmpeq]], stack, bytecode_offsets)); + exprlist.add(new IfExprent(negIfs[func6[instr.opcode - opc_if_icmpeq]], stack, bytecode_offsets)); break; case opc_ifnull: case opc_ifnonnull: - exprlist.add(new IfExprent(negifs[func7[instr.opcode - opc_ifnull]], stack, bytecode_offsets)); + exprlist.add(new IfExprent(negIfs[func7[instr.opcode - opc_ifnull]], stack, bytecode_offsets)); break; case opc_tableswitch: case opc_lookupswitch: @@ -591,7 +559,7 @@ public class ExprProcessor implements CodeConstants { pushEx(stack, exprlist, new NewExprent(arrType, stack, dimensions, bytecode_offsets)); break; case opc_newarray: - pushEx(stack, exprlist, new NewExprent(new VarType(arr_type[instr.getOperand(0) - 4], 1), stack, 1, bytecode_offsets)); + pushEx(stack, exprlist, new NewExprent(new VarType(arrTypeIds[instr.getOperand(0) - 4], 1), stack, 1, bytecode_offsets)); break; case opc_dup: pushEx(stack, exprlist, stack.getByOffset(-1).copy()); From 249903478c597db1c489baea8834dc78cb56d95f Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Apr 2016 15:49:10 +0200 Subject: [PATCH 056/252] Cleanup (test data) --- .../classes/pkg/TestStaticNameClash.class | Bin 443 -> 351 bytes .../pkg/TestSyntheticAccess$Assigner.class | Bin 599 -> 599 bytes .../pkg/TestSyntheticAccess$Incrementer.class | Bin 914 -> 914 bytes .../classes/pkg/TestSyntheticAccess.class | Bin 902 -> 902 bytes testData/results/TestStaticNameClash.dec | 10 ++-- testData/results/TestSyntheticAccess.dec | 54 +++++++++--------- testData/src/pkg/TestStaticNameClash.java | 4 -- testData/src/pkg/TestSyntheticAccess.java | 4 -- 8 files changed, 32 insertions(+), 40 deletions(-) diff --git a/testData/classes/pkg/TestStaticNameClash.class b/testData/classes/pkg/TestStaticNameClash.class index 16a1da3eaa4b6d04a9ca9552b68470b096425ceb..1573836f0fc84d5481c052752a2de61e3671342b 100644 GIT binary patch delta 125 zcmdnZe4k0`)W2Q(7#J8#7=*bPSQz*@8JHOa*ck-b8H6TEc}<+NBwUt(5eOL=Shcn@ zFm41g7#X;LBpXTQge4YbCMM;i zhJXl029}bH%wk3cNuP;(#Tl(9CM~PhXJ7 diff --git a/testData/classes/pkg/TestSyntheticAccess$Assigner.class b/testData/classes/pkg/TestSyntheticAccess$Assigner.class index 4ebd715b0d13441e9e5adde75b14eeaf08bb901d..a089dba7e5be86d809e93ff6e85bf981f1259591 100644 GIT binary patch delta 33 pcmcc4a-C(v4Ms+}$u}AGSrr&K85Ae;GHJ7_Ft9SHPPS!|0sx>V2UY+8 delta 33 pcmcc4a-C(v4Ms+#$u}AGSydP~8B{0pGHJ7FFt9RcPPS!|0sx^)2WkKS diff --git a/testData/classes/pkg/TestSyntheticAccess$Incrementer.class b/testData/classes/pkg/TestSyntheticAccess$Incrementer.class index d446c62ee10cfbbb1947afdba7c8b76961f555de..d592c3413e4a9f7bc59b753b260433e2a4d0145c 100644 GIT binary patch delta 85 zcmbQlK8bxpITItt 7 -13 <-> 8 +8 <-> 7 +9 <-> 8 diff --git a/testData/results/TestSyntheticAccess.dec b/testData/results/TestSyntheticAccess.dec index ef400d7..9f1c0ee 100644 --- a/testData/results/TestSyntheticAccess.dec +++ b/testData/results/TestSyntheticAccess.dec @@ -6,34 +6,34 @@ class TestSyntheticAccess { private class Assigner { void assignI(int var1) { - TestSyntheticAccess.this.i = var1;// 36 - }// 37 + TestSyntheticAccess.this.i = var1;// 32 + }// 33 void assignS(int var1) { - TestSyntheticAccess.s = var1;// 40 - }// 41 + TestSyntheticAccess.s = var1;// 36 + }// 37 } private class Incrementer { void orI() { - TestSyntheticAccess.this.i = TestSyntheticAccess.this.i | 1;// 14 - }// 15 + TestSyntheticAccess.this.i = TestSyntheticAccess.this.i | 1;// 10 + }// 11 void incrementI() { - TestSyntheticAccess.this.i++;// 18 - }// 19 + TestSyntheticAccess.this.i++;// 14 + }// 15 void decrementI() { - --TestSyntheticAccess.this.i;// 22 - }// 23 + --TestSyntheticAccess.this.i;// 18 + }// 19 void incrementS() { - ++TestSyntheticAccess.s;// 26 27 + ++TestSyntheticAccess.s;// 22 23 } void decrementS() { - TestSyntheticAccess.s--;// 30 - }// 31 + TestSyntheticAccess.s--;// 26 + }// 27 } } @@ -83,17 +83,17 @@ class 'pkg/TestSyntheticAccess$Incrementer' { } Lines mapping: -14 <-> 19 -15 <-> 20 -18 <-> 23 -19 <-> 24 -22 <-> 27 -23 <-> 28 -26 <-> 31 -27 <-> 31 -30 <-> 35 -31 <-> 36 -36 <-> 9 -37 <-> 10 -40 <-> 13 -41 <-> 14 +10 <-> 19 +11 <-> 20 +14 <-> 23 +15 <-> 24 +18 <-> 27 +19 <-> 28 +22 <-> 31 +23 <-> 31 +26 <-> 35 +27 <-> 36 +32 <-> 9 +33 <-> 10 +36 <-> 13 +37 <-> 14 diff --git a/testData/src/pkg/TestStaticNameClash.java b/testData/src/pkg/TestStaticNameClash.java index ced8f12..5f5a08f 100644 --- a/testData/src/pkg/TestStaticNameClash.java +++ b/testData/src/pkg/TestStaticNameClash.java @@ -1,9 +1,5 @@ package pkg; -/** - * @author Alexandru-Constantin Bledea - * @since March 07, 2016 - */ public class TestStaticNameClash { public static String property; diff --git a/testData/src/pkg/TestSyntheticAccess.java b/testData/src/pkg/TestSyntheticAccess.java index 0c4e3ea..5ef41e8 100644 --- a/testData/src/pkg/TestSyntheticAccess.java +++ b/testData/src/pkg/TestSyntheticAccess.java @@ -1,9 +1,5 @@ package pkg; -/** - * @author Alexandru-Constantin Bledea - * @since March 20, 2016 - */ class TestSyntheticAccess { private static int s; From a8403429efcc52bf9aa8b5c0f2bcddadc6702248 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Apr 2016 21:18:37 +0200 Subject: [PATCH 057/252] Cleanup (minor optimization) --- .../collectors/BytecodeMappingTracer.java | 6 +- .../modules/decompiler/exps/Exprent.java | 64 ++++++++----------- .../modules/decompiler/stats/Statement.java | 7 +- 3 files changed, 32 insertions(+), 45 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java index 94c2993..a72f988 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,8 @@ import java.util.*; import java.util.Map.Entry; public class BytecodeMappingTracer { + public static final BytecodeMappingTracer DUMMY = new BytecodeMappingTracer(); + private int currentSourceLine; private StructLineNumberTableAttribute lineNumberTable = null; private final Map mapping = new HashMap(); // bytecode offset, source line @@ -116,4 +118,4 @@ public class BytecodeMappingTracer { } return res; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java index 42abbb2..77b35b3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -15,13 +15,6 @@ */ package org.jetbrains.java.decompiler.modules.decompiler.exps; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map.Entry; -import java.util.Set; - import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; @@ -34,8 +27,10 @@ import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; -public class Exprent implements IMatchable { +import java.util.*; +import java.util.Map.Entry; +public class Exprent implements IMatchable { public static final int MULTIPLE_USES = 1; public static final int SIDE_EFFECTS_FREE = 2; public static final int BOTH_FLAGS = 3; @@ -144,58 +139,53 @@ public class Exprent implements IMatchable { // ***************************************************************************** // IMatchable implementation // ***************************************************************************** - + + @Override public IMatchable findObject(MatchNode matchNode, int index) { - - if(matchNode.getType() != MatchNode.MATCHNODE_EXPRENT) { + if (matchNode.getType() != MatchNode.MATCHNODE_EXPRENT) { return null; } List lstAllExprents = getAllExprents(); - - if(lstAllExprents == null || lstAllExprents.isEmpty()) { + if (lstAllExprents == null || lstAllExprents.isEmpty()) { return null; } - + String position = (String)matchNode.getRuleValue(MatchProperties.EXPRENT_POSITION); - if(position != null) { - if(position.matches("-?\\d+")) { - return lstAllExprents.get((lstAllExprents.size() + Integer.parseInt(position)) % lstAllExprents.size()); // care for negative positions + if (position != null) { + if (position.matches("-?\\d+")) { + return lstAllExprents + .get((lstAllExprents.size() + Integer.parseInt(position)) % lstAllExprents.size()); // care for negative positions } - } else if(index < lstAllExprents.size()) { // use 'index' parameter + } + else if (index < lstAllExprents.size()) { // use 'index' parameter return lstAllExprents.get(index); } return null; } + @Override public boolean match(MatchNode matchNode, MatchEngine engine) { - - if(matchNode.getType() != MatchNode.MATCHNODE_EXPRENT) { + if (matchNode.getType() != MatchNode.MATCHNODE_EXPRENT) { return false; } - - for(Entry rule : matchNode.getRules().entrySet()) { - switch(rule.getKey()) { - case EXPRENT_TYPE: - if(this.type != ((Integer)rule.getValue().value).intValue()) { - return false; - } - break; - case EXPRENT_RET: - if(!engine.checkAndSetVariableValue((String)rule.getValue().value, this)) { - return false; - } - break; + + for (Entry rule : matchNode.getRules().entrySet()) { + MatchProperties key = rule.getKey(); + if (key == MatchProperties.EXPRENT_TYPE && this.type != ((Integer)rule.getValue().value).intValue()) { + return false; + } + if (key == MatchProperties.EXPRENT_RET && !engine.checkAndSetVariableValue((String)rule.getValue().value, this)) { + return false; } - } - + return true; } @Override public String toString() { - return toJava(0, new BytecodeMappingTracer()).toString(); + return toJava(0, BytecodeMappingTracer.DUMMY).toString(); } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java index ced701f..5efa6cf 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -494,11 +494,6 @@ public class Statement implements IMatchable { return false; } - // to be overwritten - public TextBuffer toJava() { - return toJava(0, new BytecodeMappingTracer()); - } - public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { throw new RuntimeException("not implemented"); } From 52b31bf325fd1ff5006841e5d4b7ce24275718f5 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 21 Apr 2016 21:22:36 +0200 Subject: [PATCH 058/252] [java, java-decompiler] type annotations in class files Step 1: add top-level field/method/parameter annotations to stubs; include them in decompiled text. --- .../java/decompiler/main/ClassWriter.java | 65 ++++-- .../decompiler/exps/AnnotationExprent.java | 31 ++- .../decompiler/exps/TypeAnnotation.java | 67 ++++++ .../attr/StructAnnotationAttribute.java | 7 +- .../attr/StructAnnotationTypeAttribute.java | 194 ------------------ .../struct/attr/StructGeneralAttribute.java | 19 +- .../attr/StructTypeAnnotationAttribute.java | 107 ++++++++++ .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TypeAnnotations$MixA.class | Bin 0 -> 404 bytes testData/classes/pkg/TypeAnnotations$TA.class | Bin 0 -> 387 bytes testData/classes/pkg/TypeAnnotations.class | Bin 0 -> 745 bytes testData/results/TypeAnnotations.dec | 44 ++++ testData/src/pkg/TypeAnnotations.java | 22 ++ 13 files changed, 316 insertions(+), 241 deletions(-) create mode 100644 src/org/jetbrains/java/decompiler/modules/decompiler/exps/TypeAnnotation.java delete mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java create mode 100644 testData/classes/pkg/TypeAnnotations$MixA.class create mode 100644 testData/classes/pkg/TypeAnnotations$TA.class create mode 100644 testData/classes/pkg/TypeAnnotations.class create mode 100644 testData/results/TypeAnnotations.dec create mode 100644 testData/src/pkg/TypeAnnotations.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index cded67e..2386798 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -23,10 +23,7 @@ import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.main.rels.ClassWrapper; import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; -import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; -import org.jetbrains.java.decompiler.modules.decompiler.exps.ConstExprent; -import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; -import org.jetbrains.java.decompiler.modules.decompiler.exps.NewExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.*; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; @@ -43,9 +40,7 @@ import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.*; import org.jetbrains.java.decompiler.util.InterpreterUtil; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class ClassWriter { private final PoolInterceptor interceptor; @@ -311,7 +306,7 @@ public class ClassWriter { appendComment(buffer, "synthetic class", indent); } - appendAnnotations(buffer, cl, indent); + appendAnnotations(buffer, indent, cl, -1); buffer.appendIndent(indent); @@ -407,7 +402,7 @@ public class ClassWriter { appendComment(buffer, "synthetic field", indent); } - appendAnnotations(buffer, fd, indent); + appendAnnotations(buffer, indent, fd, TypeAnnotation.FIELD); buffer.appendIndent(indent); @@ -630,7 +625,7 @@ public class ClassWriter { appendComment(buffer, "bridge method", indent); } - appendAnnotations(buffer, mt, indent); + appendAnnotations(buffer, indent, mt, TypeAnnotation.METHOD_RETURN_TYPE); buffer.appendIndent(indent); @@ -816,7 +811,7 @@ public class ClassWriter { StructAnnDefaultAttribute attr = (StructAnnDefaultAttribute)mt.getAttributes().getWithKey("AnnotationDefault"); if (attr != null) { buffer.append(" default "); - buffer.append(attr.getDefaultValue().toJava(0, new BytecodeMappingTracer())); // dummy tracer + buffer.append(attr.getDefaultValue().toJava(0, BytecodeMappingTracer.DUMMY)); } } @@ -951,26 +946,30 @@ public class ClassWriter { private static final String[] ANNOTATION_ATTRIBUTES = { StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS}; + private static final String[] PARAMETER_ANNOTATION_ATTRIBUTES = { + StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; + private static final String[] TYPE_ANNOTATION_ATTRIBUTES = { + StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS}; - private static void appendAnnotations(TextBuffer buffer, StructMember mb, int indent) { - BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one + private static void appendAnnotations(TextBuffer buffer, int indent, StructMember mb, int targetType) { + Set filter = new HashSet<>(); for (String name : ANNOTATION_ATTRIBUTES) { StructAnnotationAttribute attribute = (StructAnnotationAttribute)mb.getAttributes().getWithKey(name); if (attribute != null) { for (AnnotationExprent annotation : attribute.getAnnotations()) { - buffer.append(annotation.toJava(indent, tracer_dummy)).appendLineSeparator(); + String text = annotation.toJava(indent, BytecodeMappingTracer.DUMMY).toString(); + filter.add(text); + buffer.append(text).appendLineSeparator(); } } } + + appendTypeAnnotations(buffer, indent, mb, targetType, -1, filter); } - private static final String[] PARAMETER_ANNOTATION_ATTRIBUTES = { - StructGeneralAttribute.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, - StructGeneralAttribute.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS}; - private static void appendParameterAnnotations(TextBuffer buffer, StructMethod mt, int param) { - BytecodeMappingTracer tracer_dummy = new BytecodeMappingTracer(); // FIXME: replace with a real one + Set filter = new HashSet<>(); for (String name : PARAMETER_ANNOTATION_ATTRIBUTES) { StructAnnotationParameterAttribute attribute = (StructAnnotationParameterAttribute)mt.getAttributes().getWithKey(name); @@ -978,7 +977,33 @@ public class ClassWriter { List> annotations = attribute.getParamAnnotations(); if (param < annotations.size()) { for (AnnotationExprent annotation : annotations.get(param)) { - buffer.append(annotation.toJava(0, tracer_dummy)).append(' '); + String text = annotation.toJava(-1, BytecodeMappingTracer.DUMMY).toString(); + filter.add(text); + buffer.append(text).append(' '); + } + } + } + } + + appendTypeAnnotations(buffer, -1, mt, TypeAnnotation.METHOD_PARAMETER, param, filter); + } + + private static void appendTypeAnnotations(TextBuffer buffer, int indent, StructMember mb, int targetType, int index, Set filter) { + for (String name : TYPE_ANNOTATION_ATTRIBUTES) { + StructTypeAnnotationAttribute attribute = (StructTypeAnnotationAttribute)mb.getAttributes().getWithKey(name); + if (attribute != null) { + for (TypeAnnotation annotation : attribute.getAnnotations()) { + if (annotation.isTopLevel() && annotation.getTargetType() == targetType && (index < 0 || annotation.getIndex() == index)) { + String text = annotation.getAnnotation().toJava(indent, BytecodeMappingTracer.DUMMY).toString(); + if (!filter.contains(text)) { + buffer.append(text); + if (indent < 0) { + buffer.append(' '); + } + else { + buffer.appendLineSeparator(); + } + } } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java index 9b797a9..c17d921 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AnnotationExprent.java @@ -47,22 +47,31 @@ public class AnnotationExprent extends Exprent { buffer.append('@'); buffer.append(DecompilerContext.getImportCollector().getShortName(ExprProcessor.buildJavaClassName(className))); - if (!parNames.isEmpty()) { + int type = getAnnotationType(); + + if (type != ANNOTATION_MARKER) { buffer.append('('); - if (getAnnotationType() == ANNOTATION_SINGLE_ELEMENT) { - buffer.append(parValues.get(0).toJava(indent + 1, tracer)); - } - else { - for (int i = 0; i < parNames.size(); i++) { + + boolean oneLiner = type == ANNOTATION_SINGLE_ELEMENT || indent < 0; + + for (int i = 0; i < parNames.size(); i++) { + if (!oneLiner) { buffer.appendLineSeparator().appendIndent(indent + 1); + } + + if (type != ANNOTATION_SINGLE_ELEMENT) { buffer.append(parNames.get(i)); buffer.append(" = "); - buffer.append(parValues.get(i).toJava(0, tracer)); - - if (i < parNames.size() - 1) { - buffer.append(','); - } } + + buffer.append(parValues.get(i).toJava(0, tracer)); + + if (i < parNames.size() - 1) { + buffer.append(','); + } + } + + if (!oneLiner) { buffer.appendLineSeparator().appendIndent(indent); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/TypeAnnotation.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/TypeAnnotation.java new file mode 100644 index 0000000..93ab87b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/TypeAnnotation.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.modules.decompiler.exps; + +public class TypeAnnotation { + public static final int CLASS_TYPE_PARAMETER = 0x00; + public static final int METHOD_TYPE_PARAMETER = 0x01; + public static final int SUPER_TYPE_REFERENCE = 0x10; + public static final int CLASS_TYPE_PARAMETER_BOUND = 0x11; + public static final int METHOD_TYPE_PARAMETER_BOUND = 0x12; + public static final int FIELD = 0x13; + public static final int METHOD_RETURN_TYPE = 0x14; + public static final int METHOD_RECEIVER = 0x15; + public static final int METHOD_PARAMETER = 0x16; + public static final int THROWS_REFERENCE = 0x17; + public static final int LOCAL_VARIABLE = 0x40; + public static final int RESOURCE_VARIABLE = 0x41; + public static final int CATCH_CLAUSE = 0x42; + public static final int EXPR_INSTANCEOF = 0x43; + public static final int EXPR_NEW = 0x44; + public static final int EXPR_CONSTRUCTOR_REF = 0x45; + public static final int EXPR_METHOD_REF = 0x46; + public static final int TYPE_ARG_CAST = 0x47; + public static final int TYPE_ARG_CONSTRUCTOR_CALL = 0x48; + public static final int TYPE_ARG_METHOD_CALL = 0x49; + public static final int TYPE_ARG_CONSTRUCTOR_REF = 0x4A; + public static final int TYPE_ARG_METHOD_REF = 0x4B; + + private final int target; + private final byte[] path; + private final AnnotationExprent annotation; + + public TypeAnnotation(int target, byte[] path, AnnotationExprent annotation) { + this.target = target; + this.path = path; + this.annotation = annotation; + } + + public int getTargetType() { + return target >> 24; + } + + public int getIndex() { + return target & 0x0FFFF; + } + + public boolean isTopLevel() { + return path == null; + } + + public AnnotationExprent getAnnotation() { + return annotation; + } +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java index 73af88d..1380427 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,6 @@ import java.util.Collections; import java.util.List; public class StructAnnotationAttribute extends StructGeneralAttribute { - private List annotations; @Override @@ -143,7 +142,7 @@ public class StructAnnotationAttribute extends StructGeneralAttribute { newType = new VarType(elementType.type, 1, elementType.value); } - NewExprent newExpr = new NewExprent(newType, Collections.emptyList(), null); + NewExprent newExpr = new NewExprent(newType, Collections.emptyList(), null); newExpr.setDirectArrayInit(true); newExpr.setLstArrayElements(elements); return newExpr; @@ -181,4 +180,4 @@ public class StructAnnotationAttribute extends StructGeneralAttribute { public List getAnnotations() { return annotations; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java deleted file mode 100644 index 59324e3..0000000 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationTypeAttribute.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.jetbrains.java.decompiler.struct.attr; - -import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; -import org.jetbrains.java.decompiler.struct.consts.ConstantPool; - -import java.io.DataInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class StructAnnotationTypeAttribute extends StructGeneralAttribute { - - private static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS = 0x00; - private static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD = 0x01; - private static final int ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS = 0x10; - private static final int ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND = 0x11; - private static final int ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND = 0x12; - private static final int ANNOTATION_TARGET_TYPE_FIELD = 0x13; - private static final int ANNOTATION_TARGET_TYPE_RETURN = 0x14; - private static final int ANNOTATION_TARGET_TYPE_RECEIVER = 0x15; - private static final int ANNOTATION_TARGET_TYPE_FORMAL = 0x16; - private static final int ANNOTATION_TARGET_TYPE_THROWS = 0x17; - private static final int ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE = 0x40; - private static final int ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE = 0x41; - private static final int ANNOTATION_TARGET_TYPE_EXCEPTION = 0x42; - private static final int ANNOTATION_TARGET_TYPE_INSTANCEOF = 0x43; - private static final int ANNOTATION_TARGET_TYPE_NEW = 0x44; - private static final int ANNOTATION_TARGET_TYPE_DOUBLE_COLON_NEW = 0x45; - private static final int ANNOTATION_TARGET_TYPE_DOUBLE_COLON_ID = 0x46; - private static final int ANNOTATION_TARGET_TYPE_CAST = 0x47; - private static final int ANNOTATION_TARGET_TYPE_INVOCATION_CONSTRUCTOR = 0x48; - private static final int ANNOTATION_TARGET_TYPE_INVOCATION_METHOD = 0x49; - private static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_NEW = 0x4A; - private static final int ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_ID = 0x4B; - - private static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER = 1; - private static final int ANNOTATION_TARGET_UNION_SUPERTYPE = 2; - private static final int ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND = 3; - private static final int ANNOTATION_TARGET_UNION_EMPTY = 4; - private static final int ANNOTATION_TARGET_UNION_FORMAL_PARAMETER = 5; - private static final int ANNOTATION_TARGET_UNION_THROWS = 6; - private static final int ANNOTATION_TARGET_UNION_LOCAL_VAR = 7; - private static final int ANNOTATION_TARGET_UNION_CATCH = 8; - private static final int ANNOTATION_TARGET_UNION_OFFSET = 9; - private static final int ANNOTATION_TARGET_UNION_TYPE_ARGUMENT = 10; - - @SuppressWarnings("FieldCanBeLocal") private List locations; - @SuppressWarnings("FieldCanBeLocal") private List annotations; - - @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); - - int len = data.readUnsignedByte(); - if (len > 0) { - locations = new ArrayList(len); - annotations = new ArrayList(len); - for (int i = 0; i < len; i++) { - locations.add(parseAnnotationLocation(data)); - annotations.add(StructAnnotationAttribute.parseAnnotation(data, pool)); - } - } - else { - locations = Collections.emptyList(); - annotations = Collections.emptyList(); - } - } - - private static AnnotationLocation parseAnnotationLocation(DataInputStream data) throws IOException { - AnnotationLocation ann_location = new AnnotationLocation(); - - // target type - ann_location.target_type = data.readUnsignedByte(); - - // target union - switch (ann_location.target_type) { - case ANNOTATION_TARGET_TYPE_GENERIC_CLASS: - case ANNOTATION_TARGET_TYPE_GENERIC_METHOD: - ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_PARAMETER; - break; - case ANNOTATION_TARGET_TYPE_EXTENDS_IMPLEMENTS: - ann_location.target_union = ANNOTATION_TARGET_UNION_SUPERTYPE; - break; - case ANNOTATION_TARGET_TYPE_GENERIC_CLASS_BOUND: - case ANNOTATION_TARGET_TYPE_GENERIC_METHOD_BOUND: - ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND; - break; - case ANNOTATION_TARGET_TYPE_FIELD: - case ANNOTATION_TARGET_TYPE_RETURN: - case ANNOTATION_TARGET_TYPE_RECEIVER: - ann_location.target_union = ANNOTATION_TARGET_UNION_EMPTY; - break; - case ANNOTATION_TARGET_TYPE_FORMAL: - ann_location.target_union = ANNOTATION_TARGET_UNION_FORMAL_PARAMETER; - break; - case ANNOTATION_TARGET_TYPE_THROWS: - ann_location.target_union = ANNOTATION_TARGET_UNION_THROWS; - break; - case ANNOTATION_TARGET_TYPE_LOCAL_VARIABLE: - case ANNOTATION_TARGET_TYPE_RESOURCE_VARIABLE: - ann_location.target_union = ANNOTATION_TARGET_UNION_LOCAL_VAR; - break; - case ANNOTATION_TARGET_TYPE_EXCEPTION: - ann_location.target_union = ANNOTATION_TARGET_UNION_CATCH; - break; - case ANNOTATION_TARGET_TYPE_INSTANCEOF: - case ANNOTATION_TARGET_TYPE_NEW: - case ANNOTATION_TARGET_TYPE_DOUBLE_COLON_NEW: - case ANNOTATION_TARGET_TYPE_DOUBLE_COLON_ID: - ann_location.target_union = ANNOTATION_TARGET_UNION_OFFSET; - break; - case ANNOTATION_TARGET_TYPE_CAST: - case ANNOTATION_TARGET_TYPE_INVOCATION_CONSTRUCTOR: - case ANNOTATION_TARGET_TYPE_INVOCATION_METHOD: - case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_NEW: - case ANNOTATION_TARGET_TYPE_GENERIC_DOUBLE_COLON_ID: - ann_location.target_union = ANNOTATION_TARGET_UNION_TYPE_ARGUMENT; - break; - default: - throw new RuntimeException("Unknown target type in a type annotation!"); - } - - // target union data - - switch (ann_location.target_union) { - case ANNOTATION_TARGET_UNION_TYPE_PARAMETER: - case ANNOTATION_TARGET_UNION_FORMAL_PARAMETER: - ann_location.data = new int[]{data.readUnsignedByte()}; - break; - case ANNOTATION_TARGET_UNION_SUPERTYPE: - case ANNOTATION_TARGET_UNION_THROWS: - case ANNOTATION_TARGET_UNION_CATCH: - case ANNOTATION_TARGET_UNION_OFFSET: - ann_location.data = new int[]{data.readUnsignedShort()}; - break; - case ANNOTATION_TARGET_UNION_TYPE_PARAMETER_BOUND: - ann_location.data = new int[]{data.readUnsignedByte(), data.readUnsignedByte()}; - break; - case ANNOTATION_TARGET_UNION_EMPTY: - break; - case ANNOTATION_TARGET_UNION_LOCAL_VAR: - int table_length = data.readUnsignedShort(); - - ann_location.data = new int[table_length * 3 + 1]; - ann_location.data[0] = table_length; - - for (int i = 0; i < table_length; ++i) { - ann_location.data[3 * i + 1] = data.readUnsignedShort(); - ann_location.data[3 * i + 2] = data.readUnsignedShort(); - ann_location.data[3 * i + 3] = data.readUnsignedShort(); - } - break; - case ANNOTATION_TARGET_UNION_TYPE_ARGUMENT: - ann_location.data = new int[]{data.readUnsignedShort(), data.readUnsignedByte()}; - } - - // target path - int path_length = data.readUnsignedByte(); - - ann_location.target_path_kind = new int[path_length]; - ann_location.target_argument_index = new int[path_length]; - - for (int i = 0; i < path_length; ++i) { - ann_location.target_path_kind[i] = data.readUnsignedByte(); - ann_location.target_argument_index[i] = data.readUnsignedByte(); - } - - return ann_location; - } - - private static class AnnotationLocation { - public int target_type; - public int target_union; - public int[] data; - public int[] target_path_kind; - public int[] target_argument_index; - } -} diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java index dc0ebc6..73cc535 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import java.io.IOException; } */ public class StructGeneralAttribute { - public static final String ATTRIBUTE_CODE = "Code"; public static final String ATTRIBUTE_INNER_CLASSES = "InnerClasses"; public static final String ATTRIBUTE_SIGNATURE = "Signature"; @@ -73,17 +72,14 @@ public class StructGeneralAttribute { else if (ATTRIBUTE_ENCLOSING_METHOD.equals(name)) { attr = new StructEnclosingMethodAttribute(); } - else if (ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS.equals(name) || - ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS.equals(name)) { + else if (ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS.equals(name) || ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS.equals(name)) { attr = new StructAnnotationAttribute(); } - else if (ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS.equals(name) || - ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS.equals(name)) { + else if (ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS.equals(name) || ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS.equals(name)) { attr = new StructAnnotationParameterAttribute(); } - else if (ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(name) || - ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(name)) { - attr = new StructAnnotationTypeAttribute(); + else if (ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS.equals(name) || ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS.equals(name)) { + attr = new StructTypeAnnotationAttribute(); } else if (ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(name)) { attr = new StructLocalVariableTableAttribute(); @@ -91,8 +87,7 @@ public class StructGeneralAttribute { else if (ATTRIBUTE_BOOTSTRAP_METHODS.equals(name)) { attr = new StructBootstrapMethodsAttribute(); } - else if (ATTRIBUTE_SYNTHETIC.equals(name) || - ATTRIBUTE_DEPRECATED.equals(name)) { + else if (ATTRIBUTE_SYNTHETIC.equals(name) || ATTRIBUTE_DEPRECATED.equals(name)) { attr = new StructGeneralAttribute(); } else if (ATTRIBUTE_LINE_NUMBER_TABLE.equals(name)) { @@ -123,4 +118,4 @@ public class StructGeneralAttribute { public String getName() { return name; } -} +} \ No newline at end of file diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java new file mode 100644 index 0000000..1cb9485 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java @@ -0,0 +1,107 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.struct.attr; + +import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.TypeAnnotation; +import org.jetbrains.java.decompiler.struct.consts.ConstantPool; + +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class StructTypeAnnotationAttribute extends StructGeneralAttribute { + private List annotations = Collections.emptyList(); + + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputStream data = stream(); + + int len = data.readUnsignedShort(); + if (len > 0) { + annotations = new ArrayList<>(len); + for (int i = 0; i < len; i++) { + annotations.add(parse(data, pool)); + } + } + else { + annotations = Collections.emptyList(); + } + } + + private static TypeAnnotation parse(DataInputStream data, ConstantPool pool) throws IOException { + int targetType = data.readUnsignedByte(); + int target = targetType << 24; + + switch (targetType) { + case TypeAnnotation.CLASS_TYPE_PARAMETER: + case TypeAnnotation.METHOD_TYPE_PARAMETER: + case TypeAnnotation.METHOD_PARAMETER: + target |= data.readUnsignedByte(); + break; + + case TypeAnnotation.SUPER_TYPE_REFERENCE: + case TypeAnnotation.CLASS_TYPE_PARAMETER_BOUND: + case TypeAnnotation.METHOD_TYPE_PARAMETER_BOUND: + case TypeAnnotation.THROWS_REFERENCE: + case TypeAnnotation.CATCH_CLAUSE: + case TypeAnnotation.EXPR_INSTANCEOF: + case TypeAnnotation.EXPR_NEW: + case TypeAnnotation.EXPR_CONSTRUCTOR_REF: + case TypeAnnotation.EXPR_METHOD_REF: + target |= data.readUnsignedShort(); + break; + + case TypeAnnotation.TYPE_ARG_CAST: + case TypeAnnotation.TYPE_ARG_CONSTRUCTOR_CALL: + case TypeAnnotation.TYPE_ARG_METHOD_CALL: + case TypeAnnotation.TYPE_ARG_CONSTRUCTOR_REF: + case TypeAnnotation.TYPE_ARG_METHOD_REF: + data.skipBytes(3); + break; + + case TypeAnnotation.LOCAL_VARIABLE: + case TypeAnnotation.RESOURCE_VARIABLE: + data.skipBytes(data.readUnsignedShort() * 6); + break; + + case TypeAnnotation.FIELD: + case TypeAnnotation.METHOD_RETURN_TYPE: + case TypeAnnotation.METHOD_RECEIVER: + break; + + default: + throw new RuntimeException("unknown target type: " + targetType); + } + + int pathLength = data.readUnsignedByte(); + byte[] path = null; + if (pathLength > 0) { + path = new byte[2 * pathLength]; + data.readFully(path); + } + + AnnotationExprent annotation = StructAnnotationAttribute.parseAnnotation(data, pool); + + return new TypeAnnotation(target, path, annotation); + } + + public List getAnnotations() { + return annotations; + } +} \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 84434a9..3d14216 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -84,6 +84,7 @@ public class SingleClassesTest { @Test public void testMethodReferenceLetterClass() { doTest("pkg/TestMethodReferenceLetterClass"); } @Test public void testMemberAnnotations() { doTest("pkg/TestMemberAnnotations"); } @Test public void testMoreAnnotations() { doTest("pkg/MoreAnnotations"); } + @Test public void testTypeAnnotations() { doTest("pkg/TypeAnnotations"); } @Test public void testStaticNameClash() { doTest("pkg/TestStaticNameClash"); } @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } diff --git a/testData/classes/pkg/TypeAnnotations$MixA.class b/testData/classes/pkg/TypeAnnotations$MixA.class new file mode 100644 index 0000000000000000000000000000000000000000..2795bce3a3ce50fbdd6f761accd7a5745bb9129a GIT binary patch literal 404 zcmZutO-sW-5Pg#-CdR7OR?ve8B1JFe;>}ah6bco^L_s{rwk%<5x+%$~=wI{T5Aa8c z69f~ahxuUMn|U+y_5JY)-~v4tTP}87>=K-%NJ~lRot}+nVkv@D=p=|tu5@xq@T08E zr*f#$iW9#t968zif2=;GikF=KgRVs=?7KBcH-|b{3 zr-pD;mm1sEClb0VRQdqHVr%g`$!0w`oVBpV-hvB{;~wMdZ1yuO2_GAkYoo)E&t<|U Hw)@@>xdm&8 literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TypeAnnotations$TA.class b/testData/classes/pkg/TypeAnnotations$TA.class new file mode 100644 index 0000000000000000000000000000000000000000..d02171e1070d5a4a5a106a5c0ebe06920d3b2385 GIT binary patch literal 387 zcmZutO-sW-5Pj38CdRL5MerbkNYRVAc=J>wf*>d+3gSVwWe8iho04n_{xuK&0DqJ? zxtJh5%K#?ByYOdrA`@dxV3#p-ZHDg!cD|*?>PYp>L??O>s^HgHb&VNWY4yk? z0vrADk6|a1ZU 14 +21 <-> 18 diff --git a/testData/src/pkg/TypeAnnotations.java b/testData/src/pkg/TypeAnnotations.java new file mode 100644 index 0000000..0760dde --- /dev/null +++ b/testData/src/pkg/TypeAnnotations.java @@ -0,0 +1,22 @@ +package pkg; + +import java.lang.annotation.*; +import java.util.*; + +class TypeAnnotations { + @Target(ElementType.TYPE_USE) + @interface TA { String value(); } + + @Target({ElementType.FIELD, ElementType.TYPE_USE}) + @interface MixA { String value(); } + + private @TA("field type") String f1; + + private @MixA("field and type") String f2; + + @TA("return type") int m1() { + return 42; + } + + void m2(@TA("parameter") int i) { } +} \ No newline at end of file From aaca7aa494e23d0e9f41636591bd07b0c6f27cef Mon Sep 17 00:00:00 2001 From: dw Date: Tue, 26 Apr 2016 15:13:24 +0200 Subject: [PATCH 059/252] Supports Asserts that have the throw in the else clause instead of the if clause --- .../java/decompiler/main/AssertProcessor.java | 95 ++++++++++++++----- 1 file changed, 69 insertions(+), 26 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/AssertProcessor.java b/src/org/jetbrains/java/decompiler/main/AssertProcessor.java index abb51ce..18f1ca9 100644 --- a/src/org/jetbrains/java/decompiler/main/AssertProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/AssertProcessor.java @@ -157,14 +157,24 @@ public class AssertProcessor { private static boolean replaceAssertion(Statement parent, IfStatement stat, String classname, String key) { + boolean throwInIf = true; Statement ifstat = stat.getIfstat(); InvocationExprent throwError = isAssertionError(ifstat); if (throwError == null) { - return false; + //check else: + Statement elsestat = stat.getElsestat(); + throwError = isAssertionError(elsestat); + if (throwError == null) { + return false; + } + else { + throwInIf = false; + } } - Object[] exprres = getAssertionExprent(stat.getHeadexprent().getCondition().copy(), classname, key); + + Object[] exprres = getAssertionExprent(stat.getHeadexprent().getCondition().copy(), classname, key, throwInIf); if (!(Boolean)exprres[1]) { return false; } @@ -172,10 +182,17 @@ public class AssertProcessor { List lstParams = new ArrayList(); Exprent ascond = null, retcond = null; - if (exprres[0] != null) { - ascond = new FunctionExprent(FunctionExprent.FUNCTION_BOOL_NOT, (Exprent)exprres[0], throwError.bytecode); - retcond = SecondaryFunctionsHelper.propagateBoolNot(ascond); + if (throwInIf) { + if (exprres[0] != null) { + ascond = new FunctionExprent(FunctionExprent.FUNCTION_BOOL_NOT, (Exprent)exprres[0], throwError.bytecode); + retcond = SecondaryFunctionsHelper.propagateBoolNot(ascond); + } } + else { + ascond = (Exprent) exprres[0]; + retcond = ascond; + } + lstParams.add(retcond == null ? ascond : retcond); if (!throwError.getLstParameters().isEmpty()) { @@ -202,7 +219,12 @@ public class AssertProcessor { } lstStatements.add(newstat); if (stat.iftype == IfStatement.IFTYPE_IFELSE) { - lstStatements.add(stat.getElsestat()); + if (throwInIf) { + lstStatements.add(stat.getElsestat()); + } + else { + lstStatements.add(stat.getIfstat()); + } } SequenceStatement sequence = new SequenceStatement(lstStatements); @@ -213,10 +235,16 @@ public class AssertProcessor { sequence.getStats().get(i), sequence.getStats().get(i + 1))); } - if (stat.iftype == IfStatement.IFTYPE_IFELSE) { - Statement ifelse = stat.getElsestat(); + if (stat.iftype == IfStatement.IFTYPE_IFELSE || !throwInIf) { + Statement stmts; + if (throwInIf) { + stmts = stat.getElsestat(); + } + else { + stmts = stat.getIfstat(); + } - List lstSuccs = ifelse.getAllSuccessorEdges(); + List lstSuccs = stmts.getAllSuccessorEdges(); if (!lstSuccs.isEmpty()) { StatEdge endedge = lstSuccs.get(0); if (endedge.closure == stat) { @@ -255,16 +283,21 @@ public class AssertProcessor { return null; } - private static Object[] getAssertionExprent(Exprent exprent, String classname, String key) { + private static Object[] getAssertionExprent(Exprent exprent, String classname, String key, boolean throwInIf) { if (exprent.type == Exprent.EXPRENT_FUNCTION) { + int desiredOperation = FunctionExprent.FUNCTION_CADD; + if (!throwInIf) { + desiredOperation = FunctionExprent.FUNCTION_COR; + } + FunctionExprent fexpr = (FunctionExprent)exprent; - if (fexpr.getFuncType() == FunctionExprent.FUNCTION_CADD) { + if (fexpr.getFuncType() == desiredOperation) { for (int i = 0; i < 2; i++) { Exprent param = fexpr.getLstOperands().get(i); - if (isAssertionField(param, classname, key)) { + if (isAssertionField(param, classname, key, throwInIf)) { return new Object[]{fexpr.getLstOperands().get(1 - i), true}; } } @@ -272,7 +305,7 @@ public class AssertProcessor { for (int i = 0; i < 2; i++) { Exprent param = fexpr.getLstOperands().get(i); - Object[] res = getAssertionExprent(param, classname, key); + Object[] res = getAssertionExprent(param, classname, key, throwInIf); if ((Boolean)res[1]) { if (param != res[0]) { fexpr.getLstOperands().set(i, (Exprent)res[0]); @@ -281,7 +314,7 @@ public class AssertProcessor { } } } - else if (isAssertionField(fexpr, classname, key)) { + else if (isAssertionField(fexpr, classname, key, throwInIf)) { // assert false; return new Object[]{null, true}; } @@ -290,20 +323,30 @@ public class AssertProcessor { return new Object[]{exprent, false}; } - private static boolean isAssertionField(Exprent exprent, String classname, String key) { - - if (exprent.type == Exprent.EXPRENT_FUNCTION) { - FunctionExprent fparam = (FunctionExprent)exprent; - if (fparam.getFuncType() == FunctionExprent.FUNCTION_BOOL_NOT && - fparam.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) { - FieldExprent fdparam = (FieldExprent)fparam.getLstOperands().get(0); - if (classname.equals(fdparam.getClassname()) - && key.equals(InterpreterUtil.makeUniqueKey(fdparam.getName(), fdparam.getDescriptor().descriptorString))) { - return true; + private static boolean isAssertionField(Exprent exprent, String classname, String key, boolean throwInIf) { + if (throwInIf) { + if (exprent.type == Exprent.EXPRENT_FUNCTION) { + FunctionExprent fparam = (FunctionExprent)exprent; + if (fparam.getFuncType() == FunctionExprent.FUNCTION_BOOL_NOT && + fparam.getLstOperands().get(0).type == Exprent.EXPRENT_FIELD) { + FieldExprent fdparam = (FieldExprent)fparam.getLstOperands().get(0); + if (classname.equals(fdparam.getClassname()) + && key.equals(InterpreterUtil.makeUniqueKey(fdparam.getName(), fdparam.getDescriptor().descriptorString))) { + return true; + } } } + return false; + } + else { + if (exprent.type == Exprent.EXPRENT_FIELD) { + FieldExprent fdparam = (FieldExprent) exprent; + if (classname.equals(fdparam.getClassname()) + && key.equals(InterpreterUtil.makeUniqueKey(fdparam.getName(), fdparam.getDescriptor().descriptorString))) { + return true; + } + } + return false; } - - return false; } } From ffd54ff4f47019a7647b66877e2593f419fadc62 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 18 May 2016 11:57:04 +0200 Subject: [PATCH 060/252] anonym -> lambda --- .../decompiler/code/InstructionSequence.java | 45 +++++++++---------- .../main/collectors/ImportCollector.java | 12 +++-- .../modules/decompiler/DomHelper.java | 6 +-- .../java/decompiler/SingleClassesTest.java | 7 +-- 4 files changed, 29 insertions(+), 41 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/code/InstructionSequence.java b/src/org/jetbrains/java/decompiler/code/InstructionSequence.java index bce3b60..cde9284 100644 --- a/src/org/jetbrains/java/decompiler/code/InstructionSequence.java +++ b/src/org/jetbrains/java/decompiler/code/InstructionSequence.java @@ -186,35 +186,32 @@ public int getOffset(int index) { public void sortHandlers(final StructContext context) { - Collections.sort(exceptionTable.getHandlers(), new Comparator() { + Collections.sort(exceptionTable.getHandlers(), (handler0, handler1) -> { - public int compare(ExceptionHandler handler0, ExceptionHandler handler1) { - - if (handler0.to == handler1.to) { - if (handler0.exceptionClass == null) { - return 1; - } - else { - if (handler1.exceptionClass == null) { - return -1; - } - else if (handler0.exceptionClass.equals(handler1.exceptionClass)) { - return (handler0.from > handler1.from) ? -1 : 1; // invalid code - } - else { - if (Util.instanceOf(context, handler0.exceptionClass, handler1.exceptionClass)) { - return -1; - } - else { - return 1; - } - } - } + if (handler0.to == handler1.to) { + if (handler0.exceptionClass == null) { + return 1; } else { - return (handler0.to > handler1.to) ? 1 : -1; + if (handler1.exceptionClass == null) { + return -1; + } + else if (handler0.exceptionClass.equals(handler1.exceptionClass)) { + return (handler0.from > handler1.from) ? -1 : 1; // invalid code + } + else { + if (Util.instanceOf(context, handler0.exceptionClass, handler1.exceptionClass)) { + return -1; + } + else { + return 1; + } + } } } + else { + return (handler0.to > handler1.to) ? 1 : -1; + } }); } diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index ada6abc..48f8db8 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -133,14 +133,12 @@ public class ImportCollector { private List packImports() { List> lst = new ArrayList>(mapSimpleNames.entrySet()); - Collections.sort(lst, new Comparator>() { - public int compare(Entry par0, Entry par1) { - int res = par0.getValue().compareTo(par1.getValue()); - if (res == 0) { - res = par0.getKey().compareTo(par1.getKey()); - } - return res; + Collections.sort(lst, (par0, par1) -> { + int res = par0.getValue().compareTo(par1.getValue()); + if (res == 0) { + res = par0.getKey().compareTo(par1.getKey()); } + return res; }); List res = new ArrayList(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java index c93be38..00eea78 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java @@ -191,11 +191,7 @@ public class DomHelper { lstPosts.add(stt.id); } - Collections.sort(lstPosts, new Comparator() { - public int compare(Integer o1, Integer o2) { - return mapSortOrder.get(o1).compareTo(mapSortOrder.get(o2)); - } - }); + Collections.sort(lstPosts, (o1, o2) -> mapSortOrder.get(o1).compareTo(mapSortOrder.get(o2))); if (lstPosts.size() > 1 && lstPosts.get(0).intValue() == st.id) { lstPosts.add(lstPosts.remove(0)); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 3d14216..f20ae55 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -124,11 +124,8 @@ public class SingleClassesTest { File parent = classFile.getParentFile(); if (parent != null) { final String pattern = classFile.getName().replace(".class", "") + "\\$.+\\.class"; - File[] inner = parent.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.matches(pattern); - } + File[] inner = parent.listFiles((dir, name) -> { + return name.matches(pattern); }); if (inner != null) Collections.addAll(files, inner); } From f0e7494a6525181eed83ff69548a7f7b62f76369 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 20 May 2016 19:40:42 +0200 Subject: [PATCH 061/252] Cleanup (formatting; typos) --- .../main/collectors/ImportCollector.java | 89 +++++++++---------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index 48f8db8..b0c311f 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,24 +24,25 @@ import org.jetbrains.java.decompiler.struct.StructContext; import java.util.*; import java.util.Map.Entry; - public class ImportCollector { - private static final String JAVA_LANG_PACKAGE = "java.lang"; private final Map mapSimpleNames = new HashMap(); private final Set setNotImportedNames = new HashSet(); - private String currentPackageSlash = ""; - private String currentPackagePoint = ""; + private final String currentPackageSlash; + private final String currentPackagePoint; public ImportCollector(ClassNode root) { - - String clname = root.classStruct.qualifiedName; - int index = clname.lastIndexOf("/"); + String clName = root.classStruct.qualifiedName; + int index = clName.lastIndexOf('/'); if (index >= 0) { - currentPackageSlash = clname.substring(0, index); - currentPackagePoint = currentPackageSlash.replace('/', '.'); - currentPackageSlash += "/"; + String packageName = clName.substring(0, index); + currentPackageSlash = packageName + '/'; + currentPackagePoint = packageName.replace('/', '.'); + } + else { + currentPackageSlash = ""; + currentPackagePoint = ""; } } @@ -49,42 +50,38 @@ public class ImportCollector { return getShortName(fullname, true); } - public String getShortName(String fullname, boolean imported) { - - ClassesProcessor clproc = DecompilerContext.getClassProcessor(); - ClassNode node = clproc.getMapRootClasses().get(fullname.replace('.', '/')); - - String retname = null; + public String getShortName(String fullName, boolean imported) { + ClassesProcessor clProc = DecompilerContext.getClassProcessor(); + ClassNode node = clProc.getMapRootClasses().get(fullName.replace('.', '/')); + String result = null; if (node != null && node.classStruct.isOwn()) { - - retname = node.simpleName; + result = node.simpleName; while (node.parent != null && node.type == ClassNode.CLASS_MEMBER) { - retname = node.parent.simpleName + "." + retname; + result = node.parent.simpleName + '.' + result; node = node.parent; } if (node.type == ClassNode.CLASS_ROOT) { - fullname = node.classStruct.qualifiedName; - fullname = fullname.replace('/', '.'); + fullName = node.classStruct.qualifiedName; + fullName = fullName.replace('/', '.'); } else { - return retname; + return result; } } else { - fullname = fullname.replace('$', '.'); + fullName = fullName.replace('$', '.'); } - String nshort = fullname; - String npackage = ""; + String shortName = fullName; + String packageName = ""; - int lastpoint = fullname.lastIndexOf("."); - - if (lastpoint >= 0) { - nshort = fullname.substring(lastpoint + 1); - npackage = fullname.substring(0, lastpoint); + int lastDot = fullName.lastIndexOf('.'); + if (lastDot >= 0) { + shortName = fullName.substring(lastDot + 1); + packageName = fullName.substring(0, lastDot); } StructContext context = DecompilerContext.getStructContext(); @@ -92,42 +89,40 @@ public class ImportCollector { // check for another class which could 'shadow' this one. Two cases: // 1) class with the same short name in the current package // 2) class with the same short name in the default package - boolean existsDefaultClass = (context.getClass(currentPackageSlash + nshort) != null - && !npackage.equals(currentPackagePoint)) // current package - || (context.getClass(nshort) != null - && !currentPackagePoint.isEmpty()); // default package + boolean existsDefaultClass = + (context.getClass(currentPackageSlash + shortName) != null && !packageName.equals(currentPackagePoint)) || // current package + (context.getClass(shortName) != null && !currentPackagePoint.isEmpty()); // default package if (existsDefaultClass || - (mapSimpleNames.containsKey(nshort) && !npackage.equals(mapSimpleNames.get(nshort)))) { + (mapSimpleNames.containsKey(shortName) && !packageName.equals(mapSimpleNames.get(shortName)))) { // don't return full name because if the class is a inner class, full name refers to the parent full name, not the child full name - return retname == null ? fullname : (npackage + "." + retname); + return result == null ? fullName : (packageName + "." + result); } - else if (!mapSimpleNames.containsKey(nshort)) { - mapSimpleNames.put(nshort, npackage); - + else if (!mapSimpleNames.containsKey(shortName)) { + mapSimpleNames.put(shortName, packageName); if (!imported) { - setNotImportedNames.add(nshort); + setNotImportedNames.add(shortName); } } - return retname == null ? nshort : retname; + return result == null ? shortName : result; } public int writeImports(TextBuffer buffer) { - int importlines_written = 0; + int importLinesWritten = 0; List imports = packImports(); for (String s : imports) { buffer.append("import "); buffer.append(s); - buffer.append(";"); + buffer.append(';'); buffer.appendLineSeparator(); - importlines_written++; + importLinesWritten++; } - return importlines_written; + return importLinesWritten; } private List packImports() { @@ -153,4 +148,4 @@ public class ImportCollector { return res; } -} +} \ No newline at end of file From 2867a8d41fc0e398de4160b9b4f3b4bebbab9b75 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 20 May 2016 19:41:40 +0200 Subject: [PATCH 062/252] Cleanup (formatting; typos) --- .../java/decompiler/main/collectors/ImportCollector.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index b0c311f..eea621b 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -15,7 +15,6 @@ */ package org.jetbrains.java.decompiler.main.collectors; -import org.jetbrains.java.decompiler.main.ClassesProcessor; import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; @@ -46,13 +45,12 @@ public class ImportCollector { } } - public String getShortName(String fullname) { - return getShortName(fullname, true); + public String getShortName(String fullName) { + return getShortName(fullName, true); } public String getShortName(String fullName, boolean imported) { - ClassesProcessor clProc = DecompilerContext.getClassProcessor(); - ClassNode node = clProc.getMapRootClasses().get(fullName.replace('.', '/')); + ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(fullName.replace('.', '/')); String result = null; if (node != null && node.classStruct.isOwn()) { From 71bb82acbefa2ed4b29bee0881067c10d8859ff2 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 20 May 2016 20:15:46 +0200 Subject: [PATCH 063/252] [java-decompiler] correct decompilation of refs to inner generic classes (IDEA-155430) --- .../java/decompiler/struct/gen/generics/GenericMain.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java index 0a3f9d3..509783a 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -209,7 +209,7 @@ public class GenericMain { else { for (GenericType tp : enclosingClasses) { if (buffer.length() == 0) { - buffer.append(DecompilerContext.getImportCollector().getShortName(tp.value)); + buffer.append(DecompilerContext.getImportCollector().getShortName(tp.value.replace('/', '.'))); } else { buffer.append(tp.value); From 7067504c27fdd71272588a2ce1ecd1f86c023564 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 24 May 2016 12:25:16 +0200 Subject: [PATCH 064/252] block lambda -> expr lambda --- test/org/jetbrains/java/decompiler/SingleClassesTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index f20ae55..f715f4f 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -124,9 +124,7 @@ public class SingleClassesTest { File parent = classFile.getParentFile(); if (parent != null) { final String pattern = classFile.getName().replace(".class", "") + "\\$.+\\.class"; - File[] inner = parent.listFiles((dir, name) -> { - return name.matches(pattern); - }); + File[] inner = parent.listFiles((dir, name) -> name.matches(pattern)); if (inner != null) Collections.addAll(files, inner); } From 7628ddfd2c8c2b038bdca8e538e116ec33cc3fc5 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 26 May 2016 13:53:27 +0300 Subject: [PATCH 065/252] toString impls for debug --- src/org/jetbrains/java/decompiler/struct/StructClass.java | 5 +++++ src/org/jetbrains/java/decompiler/struct/StructField.java | 5 +++++ src/org/jetbrains/java/decompiler/struct/StructMethod.java | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java index 895e4c1..9a355ab 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java @@ -194,4 +194,9 @@ public class StructClass extends StructMember { return CodeConstants.BYTECODE_JAVA_LE_4; } + + @Override + public String toString() { + return qualifiedName; + } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructField.java b/src/org/jetbrains/java/decompiler/struct/StructField.java index 796d77f..87ba1d8 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructField.java +++ b/src/org/jetbrains/java/decompiler/struct/StructField.java @@ -55,4 +55,9 @@ public class StructField extends StructMember { public String getDescriptor() { return descriptor; } + + @Override + public String toString() { + return name; + } } diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java index 4ed9be3..48362f3 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java @@ -393,4 +393,9 @@ public class StructMethod extends StructMember { public StructLocalVariableTableAttribute getLocalVariableAttr() { return (StructLocalVariableTableAttribute)getAttributes().getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE); } + + @Override + public String toString() { + return name; + } } \ No newline at end of file From 9d5a863e4d63b62c8041d034b23b7425e5cec620 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 30 May 2016 16:30:00 +0300 Subject: [PATCH 066/252] Cleanup (minor optimization) --- .../modules/decompiler/exps/ExitExprent.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java index 7b4a5ac..c6b962c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import org.jetbrains.java.decompiler.struct.attr.StructExceptionsAttribute; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; -import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; import org.jetbrains.java.decompiler.util.InterpreterUtil; import java.util.ArrayList; @@ -83,14 +82,14 @@ public class ExitExprent extends Exprent { tracer.addMapping(bytecode); if (exitType == EXIT_RETURN) { - TextBuffer buffer = new TextBuffer(); + TextBuffer buffer = new TextBuffer("return"); if (retType.type != CodeConstants.TYPE_VOID) { - buffer.append(" "); + buffer.append(' '); ExprProcessor.getCastedExprent(value, retType, buffer, indent, false, tracer); } - return buffer.prepend("return"); + return buffer; } else { MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); @@ -115,9 +114,9 @@ public class ExitExprent extends Exprent { if (classname != null) { VarType exType = new VarType(classname, true); - TextBuffer buffer = new TextBuffer(); + TextBuffer buffer = new TextBuffer("throw "); ExprProcessor.getCastedExprent(value, exType, buffer, indent, false, tracer); - return buffer.prepend("throw "); + return buffer; } } } From d586edbb3fb56d911af032ff6661492209d57c81 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Tue, 26 Jul 2016 15:15:04 +0200 Subject: [PATCH 067/252] use assertJ instead of hamcrest --- java-decompiler-engine.iml | 2 +- .../java/decompiler/DecompilerTestFixture.java | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/java-decompiler-engine.iml b/java-decompiler-engine.iml index 5880ebf..dc3ddfe 100644 --- a/java-decompiler-engine.iml +++ b/java-decompiler-engine.iml @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java index 58f6db0..1621142 100644 --- a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java +++ b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java @@ -15,7 +15,6 @@ */ package org.jetbrains.java.decompiler; -import org.hamcrest.Matchers; import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.util.InterpreterUtil; @@ -26,8 +25,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; import static org.junit.Assert.assertTrue; public class DecompilerTestFixture { @@ -37,7 +35,7 @@ public class DecompilerTestFixture { private ConsoleDecompiler decompiler; public void setUp(String... optionPairs) throws IOException { - assertEquals(0, optionPairs.length % 2); + assertThat(optionPairs.length % 2).isEqualTo(0); testDataDir = new File("testData"); if (!isTestDataDir(testDataDir)) testDataDir = new File("community/plugins/java-decompiler/engine/testData"); @@ -49,10 +47,10 @@ public class DecompilerTestFixture { //noinspection SSBasedInspection tempDir = File.createTempFile("decompiler_test_", "_dir"); - assertTrue(tempDir.delete()); + assertThat(tempDir.delete()).isTrue(); targetDir = new File(tempDir, "decompiled"); - assertTrue(targetDir.mkdirs()); + assertThat(targetDir.mkdirs()).isTrue(); Map options = new HashMap(); options.put(IFernflowerPreferences.LOG_LEVEL, "warn"); @@ -106,13 +104,13 @@ public class DecompilerTestFixture { public static void assertFilesEqual(File expected, File actual) { if (expected.isDirectory()) { String[] children = Objects.requireNonNull(expected.list()); - assertThat(actual.list(), Matchers.arrayContainingInAnyOrder(children)); + assertThat(actual.list()).contains(children); for (String name : children) { assertFilesEqual(new File(expected, name), new File(actual, name)); } } else { - assertEquals(getContent(expected), getContent(actual)); + assertThat(getContent(actual)).isEqualTo(getContent(expected)); } } From 21668f8479890b3abdbfb58d156d21396c062c94 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 1 Aug 2016 08:48:08 -0700 Subject: [PATCH 068/252] [java-decompiler] fixes standalone build --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index d23cf1f..04cbf1a 100644 --- a/build.xml +++ b/build.xml @@ -13,7 +13,7 @@ - + From 947fae191f9365bc45120cf19c574a85afca8c9e Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Mon, 8 Aug 2016 16:41:19 +0200 Subject: [PATCH 069/252] explicit types to diamonds --- .../decompiler/code/InstructionSequence.java | 2 +- .../java/decompiler/code/cfg/BasicBlock.java | 12 ++-- .../decompiler/code/cfg/ControlFlowGraph.java | 56 +++++++++---------- .../code/cfg/ExceptionRangeCFG.java | 6 +- .../java/decompiler/main/AssertProcessor.java | 4 +- .../main/ClassReference14Processor.java | 4 +- .../decompiler/main/ClassesProcessor.java | 24 ++++---- .../decompiler/main/DecompilerContext.java | 4 +- .../decompiler/main/InitializerProcessor.java | 4 +- .../java/decompiler/main/TextBuffer.java | 14 ++--- .../collectors/BytecodeMappingTracer.java | 6 +- .../main/collectors/BytecodeSourceMapper.java | 14 ++--- .../main/collectors/ImportCollector.java | 8 +-- .../main/collectors/VarNamesCollector.java | 2 +- .../main/decompiler/ConsoleDecompiler.java | 12 ++-- .../decompiler/main/rels/ClassWrapper.java | 10 ++-- .../decompiler/main/rels/LambdaProcessor.java | 2 +- .../decompiler/main/rels/MethodWrapper.java | 2 +- .../main/rels/NestedClassProcessor.java | 44 +++++++-------- .../main/rels/NestedMemberAccess.java | 6 +- .../modules/code/DeadCodeHelper.java | 32 +++++------ .../modules/decompiler/ClearStructHelper.java | 2 +- .../decompiler/ConcatenationHelper.java | 6 +- .../modules/decompiler/DecHelper.java | 10 ++-- .../modules/decompiler/DomHelper.java | 46 +++++++-------- .../decompiler/EliminateLoopsHelper.java | 8 +-- .../modules/decompiler/ExitHelper.java | 2 +- .../modules/decompiler/ExprProcessor.java | 24 ++++---- .../modules/decompiler/FinallyProcessor.java | 54 +++++++++--------- .../modules/decompiler/IfHelper.java | 18 +++--- .../decompiler/InlineSingleBlockHelper.java | 2 +- .../modules/decompiler/LabelHelper.java | 20 +++---- .../modules/decompiler/LoopExtractHelper.java | 2 +- .../modules/decompiler/MergeHelper.java | 6 +- .../modules/decompiler/PPandMMHelper.java | 4 +- .../decompiler/PrimitiveExprsList.java | 2 +- .../decompiler/SecondaryFunctionsHelper.java | 8 +-- .../modules/decompiler/SequenceHelper.java | 6 +- .../decompiler/SimplifyExprentsHelper.java | 10 ++-- .../decompiler/StackVarsProcessor.java | 40 ++++++------- .../modules/decompiler/StatEdge.java | 2 +- .../decompiler/StrongConnectivityHelper.java | 18 +++--- .../decompiler/decompose/DominatorEngine.java | 2 +- .../DominatorTreeExceptionFilter.java | 16 +++--- .../FastExtendedPostdominanceHelper.java | 26 ++++----- .../decompose/GenericDominatorEngine.java | 2 +- .../deobfuscator/ExceptionDeobfuscator.java | 32 +++++------ .../IrreducibleCFGDeobfuscator.java | 8 +-- .../modules/decompiler/exps/ArrayExprent.java | 2 +- .../decompiler/exps/AssignmentExprent.java | 2 +- .../modules/decompiler/exps/ConstExprent.java | 2 +- .../modules/decompiler/exps/ExitExprent.java | 2 +- .../modules/decompiler/exps/Exprent.java | 6 +- .../modules/decompiler/exps/FieldExprent.java | 2 +- .../decompiler/exps/FunctionExprent.java | 10 ++-- .../modules/decompiler/exps/IfExprent.java | 2 +- .../decompiler/exps/InvocationExprent.java | 10 ++-- .../decompiler/exps/MonitorExprent.java | 2 +- .../modules/decompiler/exps/NewExprent.java | 14 ++--- .../decompiler/exps/SwitchExprent.java | 8 +-- .../modules/decompiler/exps/VarExprent.java | 2 +- .../decompiler/sforms/DirectGraph.java | 22 ++++---- .../modules/decompiler/sforms/DirectNode.java | 6 +- .../sforms/FlattenStatementsHelper.java | 34 +++++------ .../sforms/SSAConstructorSparseEx.java | 22 ++++---- .../sforms/SSAUConstructorSparseEx.java | 38 ++++++------- .../decompiler/stats/CatchAllStatement.java | 2 +- .../decompiler/stats/CatchStatement.java | 10 ++-- .../modules/decompiler/stats/DoStatement.java | 8 +-- .../decompiler/stats/DummyExitStatement.java | 2 +- .../decompiler/stats/GeneralStatement.java | 2 +- .../modules/decompiler/stats/IfStatement.java | 6 +- .../modules/decompiler/stats/Statement.java | 50 ++++++++--------- .../decompiler/stats/SwitchStatement.java | 34 +++++------ .../stats/SynchronizedStatement.java | 4 +- .../decompiler/vars/CheckTypesResult.java | 4 +- .../decompiler/vars/VarDefinitionHelper.java | 22 ++++---- .../modules/decompiler/vars/VarProcessor.java | 14 ++--- .../decompiler/vars/VarTypeProcessor.java | 8 +-- .../decompiler/vars/VarVersionNode.java | 6 +- .../decompiler/vars/VarVersionsGraph.java | 22 ++++---- .../decompiler/vars/VarVersionsProcessor.java | 26 ++++----- .../modules/renamer/ClassWrapperNode.java | 2 +- .../modules/renamer/ConverterHelper.java | 6 +- .../modules/renamer/IdentifierConverter.java | 40 ++++++------- .../modules/renamer/PoolInterceptor.java | 4 +- .../java/decompiler/struct/ContextUnit.java | 10 ++-- .../java/decompiler/struct/StructClass.java | 4 +- .../java/decompiler/struct/StructContext.java | 4 +- .../java/decompiler/struct/StructMember.java | 2 +- .../java/decompiler/struct/StructMethod.java | 6 +- .../attr/StructAnnotationAttribute.java | 8 +-- .../StructAnnotationParameterAttribute.java | 2 +- .../attr/StructBootstrapMethodsAttribute.java | 6 +- .../attr/StructExceptionsAttribute.java | 2 +- .../attr/StructInnerClassesAttribute.java | 2 +- .../StructLocalVariableTableAttribute.java | 2 +- .../struct/consts/ConstantPool.java | 2 +- .../java/decompiler/struct/gen/DataPoint.java | 6 +- .../struct/gen/MethodDescriptor.java | 2 +- .../gen/generics/GenericClassDescriptor.java | 6 +- .../struct/gen/generics/GenericMain.java | 2 +- .../gen/generics/GenericMethodDescriptor.java | 8 +-- .../struct/gen/generics/GenericType.java | 6 +- .../decompiler/struct/lazy/LazyLoader.java | 2 +- .../decompiler/struct/match/MatchEngine.java | 22 ++++---- .../decompiler/struct/match/MatchNode.java | 4 +- .../decompiler/util/FastFixedSetFactory.java | 12 ++-- .../java/decompiler/util/FastSetFactory.java | 10 ++-- .../decompiler/util/FastSparseSetFactory.java | 10 ++-- .../java/decompiler/util/InterpreterUtil.java | 2 +- .../java/decompiler/util/ListStack.java | 2 +- .../decompiler/util/SFormsFastMapDirect.java | 2 +- .../decompiler/util/VBStyleCollection.java | 16 +++--- .../decompiler/DecompilerTestFixture.java | 2 +- .../java/decompiler/SingleClassesTest.java | 2 +- 116 files changed, 634 insertions(+), 634 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/code/InstructionSequence.java b/src/org/jetbrains/java/decompiler/code/InstructionSequence.java index cde9284..ec22827 100644 --- a/src/org/jetbrains/java/decompiler/code/InstructionSequence.java +++ b/src/org/jetbrains/java/decompiler/code/InstructionSequence.java @@ -41,7 +41,7 @@ public abstract class InstructionSequence { protected ExceptionTable exceptionTable = ExceptionTable.EMPTY; protected InstructionSequence() { - this(new VBStyleCollection()); + this(new VBStyleCollection<>()); } protected InstructionSequence(VBStyleCollection collinstr) { diff --git a/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java b/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java index 0bbaf72..55d7462 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/BasicBlock.java @@ -40,15 +40,15 @@ public class BasicBlock implements IGraphNode { private InstructionSequence seq = new SimpleInstructionSequence(); - private List preds = new ArrayList(); + private List preds = new ArrayList<>(); - private List succs = new ArrayList(); + private List succs = new ArrayList<>(); - private final List instrOldOffsets = new ArrayList(); + private final List instrOldOffsets = new ArrayList<>(); - private List predExceptions = new ArrayList(); + private List predExceptions = new ArrayList<>(); - private List succExceptions = new ArrayList(); + private List succExceptions = new ArrayList<>(); public BasicBlock(int id) { this.id = id; @@ -216,7 +216,7 @@ public class BasicBlock implements IGraphNode { } public List getPredecessors() { - List lst = new ArrayList(preds); + List lst = new ArrayList<>(preds); lst.addAll(predExceptions); return lst; } diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java index 2f4761e..4706bf6 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java @@ -47,7 +47,7 @@ public class ControlFlowGraph implements CodeConstants { private Map subroutines; - private Set finallyExits = new HashSet(); + private Set finallyExits = new HashSet<>(); // ***************************************************************************** // constructors @@ -225,7 +225,7 @@ public class ControlFlowGraph implements CodeConstants { short[] states = findStartInstructions(instrseq); - Map mapInstrBlocks = new HashMap(); + Map mapInstrBlocks = new HashMap<>(); VBStyleCollection colBlocks = createBasicBlocks(states, instrseq, mapInstrBlocks); blocks = colBlocks; @@ -244,7 +244,7 @@ public class ControlFlowGraph implements CodeConstants { int len = seq.length(); short[] inststates = new short[len]; - Set excSet = new HashSet(); + Set excSet = new HashSet<>(); for (ExceptionHandler handler : seq.getExceptionTable().getHandlers()) { excSet.add(handler.from_instr); @@ -293,7 +293,7 @@ public class ControlFlowGraph implements CodeConstants { InstructionSequence instrseq, Map mapInstrBlocks) { - VBStyleCollection col = new VBStyleCollection(); + VBStyleCollection col = new VBStyleCollection<>(); InstructionSequence currseq = null; List lstOffs = null; @@ -367,9 +367,9 @@ public class ControlFlowGraph implements CodeConstants { private void setExceptionEdges(InstructionSequence instrseq, Map instrBlocks) { - exceptions = new ArrayList(); + exceptions = new ArrayList<>(); - Map mapRanges = new HashMap(); + Map mapRanges = new HashMap<>(); for (ExceptionHandler handler : instrseq.getExceptionTable().getHandlers()) { @@ -385,7 +385,7 @@ public class ControlFlowGraph implements CodeConstants { } else { - List protectedRange = new ArrayList(); + List protectedRange = new ArrayList<>(); for (int j = from.id; j < to.id; j++) { BasicBlock block = blocks.getWithKey(j); protectedRange.add(block); @@ -404,19 +404,19 @@ public class ControlFlowGraph implements CodeConstants { private void setSubroutineEdges() { - final Map subroutines = new HashMap(); + final Map subroutines = new HashMap<>(); for (BasicBlock block : blocks) { if (block.getSeq().getLastInstr().opcode == CodeConstants.opc_jsr) { - LinkedList stack = new LinkedList(); - LinkedList> stackJsrStacks = new LinkedList>(); + LinkedList stack = new LinkedList<>(); + LinkedList> stackJsrStacks = new LinkedList<>(); - Set setVisited = new HashSet(); + Set setVisited = new HashSet<>(); stack.add(block); - stackJsrStacks.add(new LinkedList()); + stackJsrStacks.add(new LinkedList<>()); while (!stack.isEmpty()) { @@ -449,7 +449,7 @@ public class ControlFlowGraph implements CodeConstants { for (BasicBlock succ : node.getSuccs()) { if (!setVisited.contains(succ)) { stack.add(succ); - stackJsrStacks.add(new LinkedList(jsrstack)); + stackJsrStacks.add(new LinkedList<>(jsrstack)); } } } @@ -480,7 +480,7 @@ public class ControlFlowGraph implements CodeConstants { private int processJsrRanges() { - List lstJsrAll = new ArrayList(); + List lstJsrAll = new ArrayList<>(); // get all jsr ranges for (Entry ent : subroutines.entrySet()) { @@ -492,7 +492,7 @@ public class ControlFlowGraph implements CodeConstants { // sort ranges // FIXME: better sort order - List lstJsr = new ArrayList(); + List lstJsr = new ArrayList<>(); for (JsrRecord arr : lstJsrAll) { int i = 0; for (; i < lstJsr.size(); i++) { @@ -514,7 +514,7 @@ public class ControlFlowGraph implements CodeConstants { Set set1 = arr1.range; if (!set.contains(arr1.jsr) && !set1.contains(arr.jsr)) { // rang 0 doesn't contain entry 1 and vice versa - Set setc = new HashSet(set); + Set setc = new HashSet<>(set); setc.retainAll(set1); if (!setc.isEmpty()) { @@ -530,9 +530,9 @@ public class ControlFlowGraph implements CodeConstants { private Set getJsrRange(BasicBlock jsr, BasicBlock ret) { - Set blocks = new HashSet(); + Set blocks = new HashSet<>(); - List lstNodes = new LinkedList(); + List lstNodes = new LinkedList<>(); lstNodes.add(jsr); BasicBlock dom = jsr.getSuccs().get(0); @@ -594,8 +594,8 @@ public class ControlFlowGraph implements CodeConstants { private void splitJsrRange(BasicBlock jsr, BasicBlock ret, Set common_blocks) { - List lstNodes = new LinkedList(); - Map mapNewNodes = new HashMap(); + List lstNodes = new LinkedList<>(); + Map mapNewNodes = new HashMap<>(); lstNodes.add(jsr); mapNewNodes.put(jsr.id, jsr); @@ -680,14 +680,14 @@ public class ControlFlowGraph implements CodeConstants { ExceptionRangeCFG range = exceptions.get(i); List lstRange = range.getProtectedRange(); - HashSet setBoth = new HashSet(common_blocks); + HashSet setBoth = new HashSet<>(common_blocks); setBoth.retainAll(lstRange); if (setBoth.size() > 0) { List lstNewRange; if (setBoth.size() == lstRange.size()) { - lstNewRange = new ArrayList(); + lstNewRange = new ArrayList<>(); ExceptionRangeCFG newRange = new ExceptionRangeCFG(lstNewRange, mapNewNodes.get(range.getHandler().id), range.getExceptionTypes()); exceptions.add(newRange); @@ -751,7 +751,7 @@ public class ControlFlowGraph implements CodeConstants { if (suc.mark != 1) { DataPoint point = new DataPoint(); - point.setLocalVariables(new ArrayList(data.getLocalVariables())); + point.setLocalVariables(new ArrayList<>(data.getLocalVariables())); point.getStack().push(new VarType(CodeConstants.TYPE_OBJECT, 0, null)); removeJsrInstructions(pool, suc, point); @@ -774,7 +774,7 @@ public class ControlFlowGraph implements CodeConstants { public List getReversePostOrder() { - List res = new LinkedList(); + List res = new LinkedList<>(); addToReversePostOrderListIterative(first, res); return res; @@ -782,10 +782,10 @@ public class ControlFlowGraph implements CodeConstants { private static void addToReversePostOrderListIterative(BasicBlock root, List lst) { - LinkedList stackNode = new LinkedList(); - LinkedList stackIndex = new LinkedList(); + LinkedList stackNode = new LinkedList<>(); + LinkedList stackIndex = new LinkedList<>(); - Set setVisited = new HashSet(); + Set setVisited = new HashSet<>(); stackNode.add(root); stackIndex.add(0); @@ -797,7 +797,7 @@ public class ControlFlowGraph implements CodeConstants { setVisited.add(node); - List lstSuccs = new ArrayList(node.getSuccs()); + List lstSuccs = new ArrayList<>(node.getSuccs()); lstSuccs.addAll(node.getSuccExceptions()); for (; index < lstSuccs.size(); index++) { diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java b/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java index 47e0e21..38a105b 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/ExceptionRangeCFG.java @@ -24,7 +24,7 @@ import java.util.Set; public class ExceptionRangeCFG { - private List protectedRange = new ArrayList(); // FIXME: replace with set + private List protectedRange = new ArrayList<>(); // FIXME: replace with set private BasicBlock handler; @@ -35,7 +35,7 @@ public class ExceptionRangeCFG { this.handler = handler; if (exceptionType != null) { - this.exceptionTypes = new ArrayList(exceptionType); + this.exceptionTypes = new ArrayList<>(exceptionType); } } @@ -105,7 +105,7 @@ public class ExceptionRangeCFG { return null; } - Set setExceptionStrings = new HashSet(); + Set setExceptionStrings = new HashSet<>(); for (String exceptionType : exceptionTypes) { // normalize order setExceptionStrings.add(exceptionType); diff --git a/src/org/jetbrains/java/decompiler/main/AssertProcessor.java b/src/org/jetbrains/java/decompiler/main/AssertProcessor.java index abb51ce..2ccbe3d 100644 --- a/src/org/jetbrains/java/decompiler/main/AssertProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/AssertProcessor.java @@ -169,7 +169,7 @@ public class AssertProcessor { return false; } - List lstParams = new ArrayList(); + List lstParams = new ArrayList<>(); Exprent ascond = null, retcond = null; if (exprres[0] != null) { @@ -196,7 +196,7 @@ public class AssertProcessor { first.removeSuccessor(stat.getIfEdge()); first.removeSuccessor(stat.getElseEdge()); - List lstStatements = new ArrayList(); + List lstStatements = new ArrayList<>(); if (first.getExprents() != null && !first.getExprents().isEmpty()) { lstStatements.add(first); } diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java index e97c47e..3ccc2d7 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java @@ -74,12 +74,12 @@ public class ClassReference14Processor { public static void processClassReferences(ClassNode node) { // find the synthetic method Class class$(String) if present - HashMap mapClassMeths = new HashMap(); + HashMap mapClassMeths = new HashMap<>(); mapClassMethods(node, mapClassMeths); if (mapClassMeths.isEmpty()) { return; } - HashSet setFound = new HashSet(); + HashSet setFound = new HashSet<>(); processClassRec(node, mapClassMeths, setFound); if (!setFound.isEmpty()) { diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 17331e9..4afeddf 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -42,7 +42,7 @@ import java.util.Map.Entry; public class ClassesProcessor { public static final int AVERAGE_CLASS_SIZE = 16 * 1024; - private final Map mapRootClasses = new HashMap(); + private final Map mapRootClasses = new HashMap<>(); private static class Inner { private String simpleName; @@ -55,10 +55,10 @@ public class ClassesProcessor { } public ClassesProcessor(StructContext context) { - Map mapInnerClasses = new HashMap(); - Map> mapNestedClassReferences = new HashMap>(); - Map> mapEnclosingClassReferences = new HashMap>(); - Map mapNewSimpleNames = new HashMap(); + Map mapInnerClasses = new HashMap<>(); + Map> mapNestedClassReferences = new HashMap<>(); + Map> mapEnclosingClassReferences = new HashMap<>(); + Map mapNewSimpleNames = new HashMap<>(); boolean bDecompileInner = DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_INNER); @@ -116,14 +116,14 @@ public class ClassesProcessor { // reference to the nested class Set set = mapNestedClassReferences.get(enclClassName); if (set == null) { - mapNestedClassReferences.put(enclClassName, set = new HashSet()); + mapNestedClassReferences.put(enclClassName, set = new HashSet<>()); } set.add(innerName); // reference to the enclosing class set = mapEnclosingClassReferences.get(innerName); if (set == null) { - mapEnclosingClassReferences.put(innerName, set = new HashSet()); + mapEnclosingClassReferences.put(innerName, set = new HashSet<>()); } set.add(enclClassName); } @@ -143,8 +143,8 @@ public class ClassesProcessor { for (Entry ent : mapRootClasses.entrySet()) { // root class? if (!mapInnerClasses.containsKey(ent.getKey())) { - Set setVisited = new HashSet(); - LinkedList stack = new LinkedList(); + Set setVisited = new HashSet<>(); + LinkedList stack = new LinkedList<>(); stack.add(ent.getKey()); setVisited.add(ent.getKey()); @@ -347,10 +347,10 @@ public class ClassesProcessor { private ClassWrapper wrapper; public String enclosingMethod; public InvocationExprent superInvocation; - public final Map mapFieldsToVars = new HashMap(); + public final Map mapFieldsToVars = new HashMap<>(); public VarType anonymousClassType; - public final List nested = new ArrayList(); - public final Set enclosingClasses = new HashSet(); + public final List nested = new ArrayList<>(); + public final Set enclosingClasses = new HashSet<>(); public ClassNode parent; public LambdaInformation lambdaInformation; public boolean namelessConstructorStub = false; diff --git a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java index c31c57a..39619ce 100644 --- a/src/org/jetbrains/java/decompiler/main/DecompilerContext.java +++ b/src/org/jetbrains/java/decompiler/main/DecompilerContext.java @@ -35,7 +35,7 @@ public class DecompilerContext { public static final String CURRENT_METHOD_WRAPPER = "CURRENT_METHOD_WRAPPER"; public static final String CURRENT_VAR_PROCESSOR = "CURRENT_VAR_PROCESSOR"; - private static final ThreadLocal currentContext = new ThreadLocal(); + private static final ThreadLocal currentContext = new ThreadLocal<>(); private final Map properties; private StructContext structContext; @@ -52,7 +52,7 @@ public class DecompilerContext { } public static void initContext(Map propertiesCustom) { - Map properties = new HashMap(IFernflowerPreferences.DEFAULTS); + Map properties = new HashMap<>(IFernflowerPreferences.DEFAULTS); if (propertiesCustom != null) { properties.putAll(propertiesCustom); } diff --git a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java index 206b669..18a13d9 100644 --- a/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/InitializerProcessor.java @@ -156,8 +156,8 @@ public class InitializerProcessor { boolean isAnonymous = DecompilerContext.getClassProcessor().getMapRootClasses().get(cl.qualifiedName).type == ClassNode.CLASS_ANONYMOUS; - List> lstFirst = new ArrayList>(); - List lstMethodWrappers = new ArrayList(); + List> lstFirst = new ArrayList<>(); + List lstMethodWrappers = new ArrayList<>(); for (MethodWrapper method : wrapper.getMethods()) { if (CodeConstants.INIT_NAME.equals(method.methodStruct.getName()) && method.root != null) { // successfully decompiled constructor diff --git a/src/org/jetbrains/java/decompiler/main/TextBuffer.java b/src/org/jetbrains/java/decompiler/main/TextBuffer.java index 952b26f..4e0b09a 100644 --- a/src/org/jetbrains/java/decompiler/main/TextBuffer.java +++ b/src/org/jetbrains/java/decompiler/main/TextBuffer.java @@ -105,7 +105,7 @@ public class TextBuffer { int currentLine = 0; int previousMarkLine = 0; int dumpedLines = 0; - ArrayList linesWithMarks = new ArrayList(myLineToOffsetMapping.keySet()); + ArrayList linesWithMarks = new ArrayList<>(myLineToOffsetMapping.keySet()); Collections.sort(linesWithMarks); for (Integer markLine : linesWithMarks) { Integer markOffset = myLineToOffsetMapping.get(markLine); @@ -194,7 +194,7 @@ public class TextBuffer { public void setLength(int position) { myStringBuilder.setLength(position); if (myLineToOffsetMapping != null) { - HashMap newMap = new HashMap(); + HashMap newMap = new HashMap<>(); for (Map.Entry entry : myLineToOffsetMapping.entrySet()) { if (entry.getValue() <= position) { newMap.put(entry.getKey(), entry.getValue()); @@ -217,7 +217,7 @@ public class TextBuffer { private void shiftMapping(int startOffset, int shiftOffset) { if (myLineToOffsetMapping != null) { - HashMap newMap = new HashMap(); + HashMap newMap = new HashMap<>(); for (Map.Entry entry : myLineToOffsetMapping.entrySet()) { int newValue = entry.getValue(); if (newValue >= startOffset) { @@ -233,7 +233,7 @@ public class TextBuffer { private void checkMapCreated() { if (myLineToOffsetMapping == null) { - myLineToOffsetMapping = new HashMap(); + myLineToOffsetMapping = new HashMap<>(); } } @@ -264,7 +264,7 @@ public class TextBuffer { if (srcLines.size() < 2 || srcLines.size() <= requiredLineNumber) { return srcLines; } - List res = new LinkedList(srcLines); + List res = new LinkedList<>(srcLines); // first join lines with a single { or } for (int i = res.size()-1; i > 0 ; i--) { String s = res.get(i); @@ -294,12 +294,12 @@ public class TextBuffer { public void dumpOriginalLineNumbers(int[] lineMapping) { if (lineMapping.length > 0) { - myLineMapping = new HashMap>(); + myLineMapping = new HashMap<>(); for (int i = 0; i < lineMapping.length; i += 2) { int key = lineMapping[i + 1]; Set existing = myLineMapping.get(key); if (existing == null) { - existing = new TreeSet(); + existing = new TreeSet<>(); myLineMapping.put(key, existing); } existing.add(lineMapping[i]); diff --git a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java index a72f988..18e1b78 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeMappingTracer.java @@ -25,7 +25,7 @@ public class BytecodeMappingTracer { private int currentSourceLine; private StructLineNumberTableAttribute lineNumberTable = null; - private final Map mapping = new HashMap(); // bytecode offset, source line + private final Map mapping = new HashMap<>(); // bytecode offset, source line public BytecodeMappingTracer() { } @@ -81,7 +81,7 @@ public class BytecodeMappingTracer { this.lineNumberTable = lineNumberTable; } - private final Set unmappedLines = new HashSet(); + private final Set unmappedLines = new HashSet<>(); public Set getUnmappedLines() { return unmappedLines; @@ -92,7 +92,7 @@ public class BytecodeMappingTracer { return Collections.emptyMap(); } - Map res = new HashMap(); + Map res = new HashMap<>(); // first match offsets from line number table int[] data = lineNumberTable.getRawData(); diff --git a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java index 8d3770b..8531f50 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/BytecodeSourceMapper.java @@ -26,21 +26,21 @@ public class BytecodeSourceMapper { private int offset_total; // class, method, bytecode offset, source line - private final Map>> mapping = new LinkedHashMap>>(); + private final Map>> mapping = new LinkedHashMap<>(); // original line to decompiled line - private final Map linesMapping = new HashMap(); - private final Set unmappedLines = new TreeSet(); + private final Map linesMapping = new HashMap<>(); + private final Set unmappedLines = new TreeSet<>(); public void addMapping(String className, String methodName, int bytecodeOffset, int sourceLine) { Map> class_mapping = mapping.get(className); if (class_mapping == null) { - mapping.put(className, class_mapping = new LinkedHashMap>()); // need to preserve order + mapping.put(className, class_mapping = new LinkedHashMap<>()); // need to preserve order } Map method_mapping = class_mapping.get(methodName); if (method_mapping == null) { - class_mapping.put(methodName, method_mapping = new HashMap()); + class_mapping.put(methodName, method_mapping = new HashMap<>()); } // don't overwrite @@ -78,7 +78,7 @@ public class BytecodeSourceMapper { buffer.appendIndent(1).append("method '" + method_entry.getKey() + "' {" + lineSeparator); - List lstBytecodeOffsets = new ArrayList(method_mapping.keySet()); + List lstBytecodeOffsets = new ArrayList<>(method_mapping.keySet()); Collections.sort(lstBytecodeOffsets); for (Integer offset : lstBytecodeOffsets) { @@ -97,7 +97,7 @@ public class BytecodeSourceMapper { // lines mapping buffer.append("Lines mapping:").appendLineSeparator(); - Map sorted = new TreeMap(linesMapping); + Map sorted = new TreeMap<>(linesMapping); for (Entry entry : sorted.entrySet()) { buffer.append(entry.getKey()).append(" <-> ").append(entry.getValue() + offset_total + 1).appendLineSeparator(); } diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index eea621b..cb13140 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -26,8 +26,8 @@ import java.util.Map.Entry; public class ImportCollector { private static final String JAVA_LANG_PACKAGE = "java.lang"; - private final Map mapSimpleNames = new HashMap(); - private final Set setNotImportedNames = new HashSet(); + private final Map mapSimpleNames = new HashMap<>(); + private final Set setNotImportedNames = new HashSet<>(); private final String currentPackageSlash; private final String currentPackagePoint; @@ -124,7 +124,7 @@ public class ImportCollector { } private List packImports() { - List> lst = new ArrayList>(mapSimpleNames.entrySet()); + List> lst = new ArrayList<>(mapSimpleNames.entrySet()); Collections.sort(lst, (par0, par1) -> { int res = par0.getValue().compareTo(par1.getValue()); @@ -134,7 +134,7 @@ public class ImportCollector { return res; }); - List res = new ArrayList(); + List res = new ArrayList<>(); for (Entry ent : lst) { // exclude a current class or one of the nested ones, java.lang and empty packages if (!setNotImportedNames.contains(ent.getKey()) && diff --git a/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java index 33bf42c..05aac72 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/VarNamesCollector.java @@ -20,7 +20,7 @@ import java.util.Set; public class VarNamesCollector { - private final Set usedNames = new HashSet(); + private final Set usedNames = new HashSet<>(); public VarNamesCollector() { } diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java index ea08023..8925ad7 100644 --- a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java +++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java @@ -41,9 +41,9 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { return; } - Map mapOptions = new HashMap(); - List lstSources = new ArrayList(); - List lstLibraries = new ArrayList(); + Map mapOptions = new HashMap<>(); + List lstSources = new ArrayList<>(); + List lstLibraries = new ArrayList<>(); boolean isOption = true; for (int i = 0; i < args.length - 1; ++i) { // last parameter - destination @@ -113,8 +113,8 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { private final File root; private final Fernflower fernflower; - private final Map mapArchiveStreams = new HashMap(); - private final Map> mapArchiveEntries = new HashMap>(); + private final Map mapArchiveStreams = new HashMap<>(); + private final Map> mapArchiveEntries = new HashMap<>(); @SuppressWarnings("UseOfSystemOutOrSystemErr") public ConsoleDecompiler(File destination, Map options) { @@ -266,7 +266,7 @@ public class ConsoleDecompiler implements IBytecodeProvider, IResultSaver { private boolean checkEntry(String entryName, String file) { Set set = mapArchiveEntries.get(file); if (set == null) { - mapArchiveEntries.put(file, set = new HashSet()); + mapArchiveEntries.put(file, set = new HashSet<>()); } boolean added = set.add(entryName); diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java index ef09bd0..39adbc9 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -40,10 +40,10 @@ import java.util.Set; public class ClassWrapper { private final StructClass classStruct; - private final Set hiddenMembers = new HashSet(); - private final VBStyleCollection staticFieldInitializers = new VBStyleCollection(); - private final VBStyleCollection dynamicFieldInitializers = new VBStyleCollection(); - private final VBStyleCollection methods = new VBStyleCollection(); + private final Set hiddenMembers = new HashSet<>(); + private final VBStyleCollection staticFieldInitializers = new VBStyleCollection<>(); + private final VBStyleCollection dynamicFieldInitializers = new VBStyleCollection<>(); + private final VBStyleCollection methods = new VBStyleCollection<>(); public ClassWrapper(StructClass classStruct) { this.classStruct = classStruct; @@ -55,7 +55,7 @@ public class ClassWrapper { DecompilerContext.getLogger().startClass(classStruct.qualifiedName); // collect field names - Set setFieldNames = new HashSet(); + Set setFieldNames = new HashSet<>(); for (StructField fd : classStruct.getFields()) { setFieldNames.add(fd.getName()); } diff --git a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java index b5ac0fb..0063a15 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/LambdaProcessor.java @@ -78,7 +78,7 @@ public class LambdaProcessor { return false; // no lambda bootstrap constant found } - Map mapMethodsLambda = new HashMap(); + Map mapMethodsLambda = new HashMap<>(); // iterate over code and find invocations of bootstrap methods. Replace them with anonymous classes. for (StructMethod mt : cl.getMethods()) { diff --git a/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java index eb397d1..3060c73 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/MethodWrapper.java @@ -31,7 +31,7 @@ public class MethodWrapper { public final VarProcessor varproc; public final StructMethod methodStruct; public final CounterContainer counter; - public final HashSet setOuterVarNames = new HashSet(); + public final HashSet setOuterVarNames = new HashSet<>(); public DirectGraph graph; public List signatureFields; diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index c529a44..12e2de1 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -130,7 +130,7 @@ public class NestedClassProcessor { method.varproc.setVarName(new VarVersionPair(0, 0), parent.simpleName + ".this"); } - final Map mapNewNames = new HashMap(); + final Map mapNewNames = new HashMap<>(); enclosingMethod.getOrBuildGraph().iterateExprents(new DirectGraph.ExprentIterator() { @Override @@ -168,7 +168,7 @@ public class NestedClassProcessor { }); // update names of local variables - Set setNewOuterNames = new HashSet(mapNewNames.values()); + Set setNewOuterNames = new HashSet<>(mapNewNames.values()); setNewOuterNames.removeAll(method.setOuterVarNames); method.varproc.refreshVarNames(new VarNamesCollector(setNewOuterNames)); @@ -180,7 +180,7 @@ public class NestedClassProcessor { } private static void checkNotFoundClasses(ClassNode root, ClassNode node) { - List copy = new ArrayList(node.nested); + List copy = new ArrayList<>(node.nested); for (ClassNode child : copy) { if (child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { @@ -225,7 +225,7 @@ public class NestedClassProcessor { private static boolean insertNestedClass(ClassNode root, ClassNode child) { Set setEnclosing = child.enclosingClasses; - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { @@ -248,7 +248,7 @@ public class NestedClassProcessor { private static void computeLocalVarsAndDefinitions(final ClassNode node) { // local var masks // class name, constructor descriptor, field mask - final Map>> mapVarMasks = new HashMap>>(); + final Map>> mapVarMasks = new HashMap<>(); int clTypes = 0; @@ -274,7 +274,7 @@ public class NestedClassProcessor { } // local var masks - final Map>> mapVarFieldPairs = new HashMap>>(); + final Map>> mapVarFieldPairs = new HashMap<>(); if (clTypes != ClassNode.CLASS_MEMBER) { // iterate enclosing class @@ -298,10 +298,10 @@ public class NestedClassProcessor { List mask = mapVarMasks.get(refClassName).get(constructor.getStringDescriptor()); if (!mapVarFieldPairs.containsKey(refClassName)) { - mapVarFieldPairs.put(refClassName, new HashMap>()); + mapVarFieldPairs.put(refClassName, new HashMap<>()); } - List lstTemp = new ArrayList(); + List lstTemp = new ArrayList<>(); for (int i = 0; i < mask.size(); i++) { Exprent param = constructor.getLstParameters().get(i); @@ -356,7 +356,7 @@ public class NestedClassProcessor { if (mapVarFieldPairs.containsKey(enclosing.getKey())) { for (List mask : mapVarFieldPairs.get(enclosing.getKey()).values()) { if (interPairMask == null) { - interPairMask = new ArrayList(mask); + interPairMask = new ArrayList<>(mask); } else { mergeListSignatures(interPairMask, mask, false); @@ -368,7 +368,7 @@ public class NestedClassProcessor { // merge all constructors for (List mask : enclosing.getValue().values()) { if (interMask == null) { - interMask = new ArrayList(mask); + interMask = new ArrayList<>(mask); } else { mergeListSignatures(interMask, mask, false); @@ -376,7 +376,7 @@ public class NestedClassProcessor { } if (interPairMask == null) { // member or local and never instantiated - interPairMask = interMask != null ? new ArrayList(interMask) : new ArrayList(); + interPairMask = interMask != null ? new ArrayList<>(interMask) : new ArrayList<>(); boolean found = false; @@ -403,7 +403,7 @@ public class NestedClassProcessor { mergeListSignatures(entry.getValue(), interPairMask, false); MethodWrapper method = nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entry.getKey()); - method.signatureFields = new ArrayList(); + method.signatureFields = new ArrayList<>(); for (VarFieldPair pair : entry.getValue()) { method.signatureFields.add(pair == null ? null : pair.varPair); @@ -419,10 +419,10 @@ public class NestedClassProcessor { // iterate all child methods for (final MethodWrapper method : child.getWrapper().getMethods()) { if (method.root != null) { // neither abstract nor native - Map mapNewNames = new HashMap(); // local var names - Map mapNewTypes = new HashMap(); // local var types + Map mapNewNames = new HashMap<>(); // local var names + Map mapNewTypes = new HashMap<>(); // local var types - final Map mapParamsToNewVars = new HashMap(); + final Map mapParamsToNewVars = new HashMap<>(); if (method.signatureFields != null) { int index = 0, varIndex = 1; MethodDescriptor md = MethodDescriptor.parseDescriptor(method.methodStruct.getDescriptor()); @@ -462,7 +462,7 @@ public class NestedClassProcessor { } } - final Map mapFieldsToNewVars = new HashMap(); + final Map mapFieldsToNewVars = new HashMap<>(); for (ClassNode classNode = child; classNode != null; classNode = classNode.parent) { for (Entry entry : classNode.mapFieldsToVars.entrySet()) { VarVersionPair newVar = new VarVersionPair(method.counter.getCounterAndIncrement(CounterContainer.VAR_COUNTER), 0); @@ -503,7 +503,7 @@ public class NestedClassProcessor { } } - Set setNewOuterNames = new HashSet(mapNewNames.values()); + Set setNewOuterNames = new HashSet<>(mapNewNames.values()); setNewOuterNames.removeAll(method.setOuterVarNames); method.varproc.refreshVarNames(new VarNamesCollector(setNewOuterNames)); @@ -593,7 +593,7 @@ public class NestedClassProcessor { } private static Map> getMaskLocalVars(ClassWrapper wrapper) { - Map> mapMasks = new HashMap>(); + Map> mapMasks = new HashMap<>(); StructClass cl = wrapper.getClassStruct(); @@ -605,7 +605,7 @@ public class NestedClassProcessor { DirectGraph graph = method.getOrBuildGraph(); if (graph != null) { // something gone wrong, should not be null - List fields = new ArrayList(); + List fields = new ArrayList<>(); int varIndex = 1; for (int i = 0; i < md.params.length; i++) { // no static methods allowed @@ -754,7 +754,7 @@ public class NestedClassProcessor { private static void setLocalClassDefinition(MethodWrapper method, ClassNode node) { RootStatement root = method.root; - Set setStats = new HashSet(); + Set setStats = new HashSet<>(); VarType classType = new VarType(node.classStruct.qualifiedName, true); Statement statement = getDefStatement(root, classType, setStats); @@ -793,7 +793,7 @@ public class NestedClassProcessor { } private static Statement findFirstBlock(Statement stat, Set setStats) { - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(stat); while (!stack.isEmpty()) { @@ -827,7 +827,7 @@ public class NestedClassProcessor { } private static Statement getDefStatement(Statement stat, VarType classType, Set setStats) { - List lst = new ArrayList(); + List lst = new ArrayList<>(); Statement retStat = null; if (stat.getExprents() == null) { diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java index e7e0f01..a460ef9 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java @@ -36,7 +36,7 @@ public class NestedMemberAccess { private enum MethodAccess {NORMAL, FIELD_GET, FIELD_SET, METHOD, FUNCTION} private boolean noSynthFlag; - private final Map mapMethodType = new HashMap(); + private final Map mapMethodType = new HashMap<>(); public void propagateMemberAccess(ClassNode root) { @@ -231,8 +231,8 @@ public class NestedMemberAccess { DirectGraph graph = meth.getOrBuildGraph(); - HashSet setVisited = new HashSet(); - LinkedList stack = new LinkedList(); + HashSet setVisited = new HashSet<>(); + LinkedList stack = new LinkedList<>(); stack.add(graph.first); while (!stack.isEmpty()) { // TODO: replace with interface iterator? diff --git a/src/org/jetbrains/java/decompiler/modules/code/DeadCodeHelper.java b/src/org/jetbrains/java/decompiler/modules/code/DeadCodeHelper.java index d79367f..2522489 100644 --- a/src/org/jetbrains/java/decompiler/modules/code/DeadCodeHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/code/DeadCodeHelper.java @@ -30,8 +30,8 @@ public class DeadCodeHelper { public static void removeDeadBlocks(ControlFlowGraph graph) { - LinkedList stack = new LinkedList(); - HashSet setStacked = new HashSet(); + LinkedList stack = new LinkedList<>(); + HashSet setStacked = new HashSet<>(); stack.add(graph.getFirst()); setStacked.add(graph.getFirst()); @@ -39,7 +39,7 @@ public class DeadCodeHelper { while (!stack.isEmpty()) { BasicBlock block = stack.removeFirst(); - List lstSuccs = new ArrayList(block.getSuccs()); + List lstSuccs = new ArrayList<>(block.getSuccs()); lstSuccs.addAll(block.getSuccExceptions()); for (BasicBlock succ : lstSuccs) { @@ -50,7 +50,7 @@ public class DeadCodeHelper { } } - HashSet setAllBlocks = new HashSet(graph.getBlocks()); + HashSet setAllBlocks = new HashSet<>(graph.getBlocks()); setAllBlocks.removeAll(setStacked); for (BasicBlock block : setAllBlocks) { @@ -94,7 +94,7 @@ public class DeadCodeHelper { } } - HashSet setExits = new HashSet(graph.getLast().getPreds()); + HashSet setExits = new HashSet<>(graph.getLast().getPreds()); if (block.getPredExceptions().isEmpty() && (!setExits.contains(block) || block.getPreds().size() == 1)) { @@ -109,15 +109,15 @@ public class DeadCodeHelper { } } - HashSet setPreds = new HashSet(block.getPreds()); - HashSet setSuccs = new HashSet(block.getSuccs()); + HashSet setPreds = new HashSet<>(block.getPreds()); + HashSet setSuccs = new HashSet<>(block.getSuccs()); // collect common exception ranges of predecessors and successors HashSet setCommonExceptionHandlers = null; for (int i = 0; i < 2; ++i) { for (BasicBlock pred : i == 0 ? setPreds : setSuccs) { if (setCommonExceptionHandlers == null) { - setCommonExceptionHandlers = new HashSet(pred.getSuccExceptions()); + setCommonExceptionHandlers = new HashSet<>(pred.getSuccExceptions()); } else { setCommonExceptionHandlers.retainAll(pred.getSuccExceptions()); @@ -159,7 +159,7 @@ public class DeadCodeHelper { BasicBlock pred = block.getPreds().get(0); pred.removeSuccessor(block); - List lstSuccs = new ArrayList(block.getSuccs()); + List lstSuccs = new ArrayList<>(block.getSuccs()); for (BasicBlock succ : lstSuccs) { block.removeSuccessor(succ); pred.addSuccessor(succ); @@ -205,13 +205,13 @@ public class DeadCodeHelper { public static boolean isDominator(ControlFlowGraph graph, BasicBlock block, BasicBlock dom) { - HashSet marked = new HashSet(); + HashSet marked = new HashSet<>(); if (block == dom) { return true; } - LinkedList lstNodes = new LinkedList(); + LinkedList lstNodes = new LinkedList<>(); lstNodes.add(block); while (!lstNodes.isEmpty()) { @@ -262,7 +262,7 @@ public class DeadCodeHelper { public static void connectDummyExitBlock(ControlFlowGraph graph) { BasicBlock exit = graph.getLast(); - for (BasicBlock block : new HashSet(exit.getPreds())) { + for (BasicBlock block : new HashSet<>(exit.getPreds())) { exit.removePredecessor(block); block.addSuccessor(exit); } @@ -311,8 +311,8 @@ public class DeadCodeHelper { if (!block.getPreds().isEmpty()) { - HashSet setPredHandlersUnion = new HashSet(); - HashSet setPredHandlersIntersection = new HashSet(); + HashSet setPredHandlersUnion = new HashSet<>(); + HashSet setPredHandlersIntersection = new HashSet<>(); boolean firstpred = true; for (BasicBlock pred : block.getPreds()) { @@ -339,7 +339,7 @@ public class DeadCodeHelper { } // remove redundant ranges - HashSet setRangesToBeRemoved = new HashSet(block.getSuccExceptions()); + HashSet setRangesToBeRemoved = new HashSet<>(block.getSuccExceptions()); setRangesToBeRemoved.removeAll(setPredHandlersUnion); for (BasicBlock handler : setRangesToBeRemoved) { @@ -369,7 +369,7 @@ public class DeadCodeHelper { } // remove superfluous ranges from successors - for (BasicBlock succ : new HashSet(block.getSuccExceptions())) { + for (BasicBlock succ : new HashSet<>(block.getSuccExceptions())) { if (!bpred.getSuccExceptions().contains(succ)) { ExceptionRangeCFG range = graph.getExceptionRange(succ, block); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ClearStructHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ClearStructHelper.java index c6495e6..30d39fb 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ClearStructHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ClearStructHelper.java @@ -25,7 +25,7 @@ public class ClearStructHelper { public static void clearStatements(RootStatement root) { - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java index 90d2732..aea5afa 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ConcatenationHelper.java @@ -70,7 +70,7 @@ public class ConcatenationHelper { // iterate in depth, collecting possible operands - List lstOperands = new ArrayList(); + List lstOperands = new ArrayList<>(); while (true) { @@ -160,7 +160,7 @@ public class ConcatenationHelper { if (constant.type == CodeConstants.CONSTANT_String) { String recipe = ((PrimitiveConstant)constant).getString(); - List res = new ArrayList(); + List res = new ArrayList<>(); StringBuilder acc = new StringBuilder(); int parameterId = 0; for (int i = 0; i < recipe.length(); i++) { @@ -195,7 +195,7 @@ public class ConcatenationHelper { return res; } } - return new ArrayList(parameters); + return new ArrayList<>(parameters); } private static boolean isAppendConcat(InvocationExprent expr, VarType cltype) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java index 9c719db..3dc4cf0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java @@ -25,9 +25,9 @@ public class DecHelper { public static boolean checkStatementExceptions(List lst) { - Set all = new HashSet(lst); + Set all = new HashSet<>(lst); - Set handlers = new HashSet(); + Set handlers = new HashSet<>(); Set intersection = null; for (Statement stat : lst) { @@ -37,7 +37,7 @@ public class DecHelper { intersection = setNew; } else { - HashSet interclone = new HashSet(intersection); + HashSet interclone = new HashSet<>(intersection); interclone.removeAll(setNew); intersection.retainAll(setNew); @@ -197,7 +197,7 @@ public class DecHelper { public static HashSet getUniquePredExceptions(Statement head) { - HashSet setHandlers = new HashSet(head.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD)); + HashSet setHandlers = new HashSet<>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD)); Iterator it = setHandlers.iterator(); while (it.hasNext()) { @@ -209,7 +209,7 @@ public class DecHelper { } public static List copyExprentList(List lst) { - List ret = new ArrayList(); + List ret = new ArrayList<>(); for (Exprent expr : lst) { ret.add(expr.copy()); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java index 00eea78..ea8e537 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java @@ -35,7 +35,7 @@ public class DomHelper { private static RootStatement graphToStatement(ControlFlowGraph graph) { - VBStyleCollection stats = new VBStyleCollection(); + VBStyleCollection stats = new VBStyleCollection<>(); VBStyleCollection blocks = graph.getBlocks(); for (BasicBlock block : blocks) { @@ -103,14 +103,14 @@ public class DomHelper { public static VBStyleCollection, Integer> calcPostDominators(Statement container) { - HashMap> lists = new HashMap>(); + HashMap> lists = new HashMap<>(); StrongConnectivityHelper schelper = new StrongConnectivityHelper(container); List> components = schelper.getComponents(); List lstStats = container.getPostReversePostOrderList(StrongConnectivityHelper.getExitReps(components)); - FastFixedSetFactory factory = new FastFixedSetFactory(lstStats); + FastFixedSetFactory factory = new FastFixedSetFactory<>(lstStats); FastFixedSet setFlagNodes = factory.spawnEmptySet(); setFlagNodes.setAllElements(); @@ -176,17 +176,17 @@ public class DomHelper { } while (!setFlagNodes.isEmpty()); - VBStyleCollection, Integer> ret = new VBStyleCollection, Integer>(); + VBStyleCollection, Integer> ret = new VBStyleCollection<>(); List lstRevPost = container.getReversePostOrderList(); // sort order crucial! - final HashMap mapSortOrder = new HashMap(); + final HashMap mapSortOrder = new HashMap<>(); for (int i = 0; i < lstRevPost.size(); i++) { mapSortOrder.put(lstRevPost.get(i).id, i); } for (Statement st : lstStats) { - List lstPosts = new ArrayList(); + List lstPosts = new ArrayList<>(); for (Statement stt : lists.get(st)) { lstPosts.add(stt.id); } @@ -207,7 +207,7 @@ public class DomHelper { RootStatement root = graphToStatement(graph); - if (!processStatement(root, new HashMap>())) { + if (!processStatement(root, new HashMap<>())) { // try { // DotExporter.toDotFile(root.getFirst().getStats().get(13), new File("c:\\Temp\\stat1.dot")); @@ -217,7 +217,7 @@ public class DomHelper { throw new RuntimeException("parsing failure!"); } - LabelHelper.lowContinueLabels(root, new HashSet()); + LabelHelper.lowContinueLabels(root, new HashSet<>()); SequenceHelper.condenseSequences(root); root.buildMonitorFlags(); @@ -287,7 +287,7 @@ public class DomHelper { SynchronizedStatement sync = new SynchronizedStatement(current, ca.getFirst(), ca.getHandler()); sync.setAllParent(); - for (StatEdge edge : new HashSet(ca.getLabelEdges())) { + for (StatEdge edge : new HashSet<>(ca.getLabelEdges())) { sync.addLabeledEdge(edge); } @@ -357,7 +357,7 @@ public class DomHelper { // DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot")); // } catch(Exception ex) {ex.printStackTrace();} - mapExtPost = new HashMap>(); + mapExtPost = new HashMap<>(); mapRefreshed = true; } @@ -378,7 +378,7 @@ public class DomHelper { Statement stat = findGeneralStatement(general, forceall, mapExtPost); if (stat != null) { - boolean complete = processStatement(stat, general.getFirst() == stat ? mapExtPost : new HashMap>()); + boolean complete = processStatement(stat, general.getFirst() == stat ? mapExtPost : new HashMap<>()); if (complete) { // replace general purpose statement with simple one @@ -388,7 +388,7 @@ public class DomHelper { return false; } - mapExtPost = new HashMap>(); + mapExtPost = new HashMap<>(); mapRefreshed = true; reducibility = 0; } @@ -409,7 +409,7 @@ public class DomHelper { break; } else { - mapExtPost = new HashMap>(); + mapExtPost = new HashMap<>(); } } @@ -427,13 +427,13 @@ public class DomHelper { } if (forceall) { - vbPost = new VBStyleCollection, Integer>(); + vbPost = new VBStyleCollection<>(); List lstAll = stat.getPostReversePostOrderList(); for (Statement st : lstAll) { Set set = mapExtPost.get(st.id); if (set != null) { - vbPost.addWithKey(new ArrayList(set), st.id); // FIXME: sort order!! + vbPost.addWithKey(new ArrayList<>(set), st.id); // FIXME: sort order!! } } @@ -443,7 +443,7 @@ public class DomHelper { for (Integer id : setFirst) { List lst = vbPost.getWithKey(id); if (lst == null) { - vbPost.addWithKey(lst = new ArrayList(), id); + vbPost.addWithKey(lst = new ArrayList<>(), id); } lst.add(id); } @@ -482,11 +482,11 @@ public class DomHelper { boolean same = (post == head); - HashSet setNodes = new HashSet(); - HashSet setPreds = new HashSet(); + HashSet setNodes = new HashSet<>(); + HashSet setPreds = new HashSet<>(); // collect statement nodes - HashSet setHandlers = new HashSet(); + HashSet setHandlers = new HashSet<>(); setHandlers.add(head); while (true) { @@ -504,7 +504,7 @@ public class DomHelper { } if (addhd) { - LinkedList lstStack = new LinkedList(); + LinkedList lstStack = new LinkedList<>(); lstStack.add(handler); while (!lstStack.isEmpty()) { @@ -618,14 +618,14 @@ public class DomHelper { // update the postdominator map if (!mapExtPost.isEmpty()) { - HashSet setOldNodes = new HashSet(); + HashSet setOldNodes = new HashSet<>(); for (Statement old : result.getStats()) { setOldNodes.add(old.id); } Integer newid = result.id; - for (Integer key : new ArrayList(mapExtPost.keySet())) { + for (Integer key : new ArrayList<>(mapExtPost.keySet())) { Set set = mapExtPost.get(key); int oldsize = set.size(); @@ -634,7 +634,7 @@ public class DomHelper { if (setOldNodes.contains(key)) { Set setNew = mapExtPost.get(newid); if (setNew == null) { - mapExtPost.put(newid, setNew = new HashSet()); + mapExtPost.put(newid, setNew = new HashSet<>()); } setNew.addAll(set); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java index 16f7da0..3bad6c6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java @@ -76,7 +76,7 @@ public class EliminateLoopsHelper { } // collect relevant break edges - List lstBreakEdges = new ArrayList(); + List lstBreakEdges = new ArrayList<>(); for (StatEdge edge : loop.getLabelEdges()) { if (edge.getType() == StatEdge.TYPE_BREAK) { // all break edges are explicit because of LOOP_DO type lstBreakEdges.add(edge); @@ -99,8 +99,8 @@ public class EliminateLoopsHelper { if (!lstBreakEdges.isEmpty()) { if (firstok) { - HashMap statLabeled = new HashMap(); - List lstEdgeClosures = new ArrayList(); + HashMap statLabeled = new HashMap<>(); + List lstEdgeClosures = new ArrayList<>(); for (StatEdge edge : lstBreakEdges) { Statement minclosure = LowBreakHelper.getMinClosure(loopcontent, edge.getSource()); @@ -193,7 +193,7 @@ public class EliminateLoopsHelper { private static void eliminateLoop(Statement loop, Statement parentloop) { // move continue edges to the parent loop - List lst = new ArrayList(loop.getLabelEdges()); + List lst = new ArrayList<>(loop.getLabelEdges()); for (StatEdge edge : lst) { loop.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, parentloop); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java index 6d0d381..26a3b23 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExitHelper.java @@ -61,7 +61,7 @@ public class ExitHelper { set.remove(secondlast); if (set.isEmpty()) { - last.setExprents(new ArrayList()); + last.setExprents(new ArrayList<>()); found = true; break; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 71e2231..5931826 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -46,7 +46,7 @@ public class ExprProcessor implements CodeConstants { public static final String UNKNOWN_TYPE_STRING = ""; public static final String NULL_TYPE_STRING = ""; - private static final Map mapConsts = new HashMap(); + private static final Map mapConsts = new HashMap<>(); static { mapConsts.put(opc_arraylength, FunctionExprent.FUNCTION_ARRAY_LENGTH); mapConsts.put(opc_checkcast, FunctionExprent.FUNCTION_CAST); @@ -120,32 +120,32 @@ public class ExprProcessor implements CodeConstants { DirectGraph dgraph = flatthelper.buildDirectGraph(root); // collect finally entry points - Set setFinallyShortRangeEntryPoints = new HashSet(); + Set setFinallyShortRangeEntryPoints = new HashSet<>(); for (List lst : dgraph.mapShortRangeFinallyPaths.values()) { for (FinallyPathWrapper finwrap : lst) { setFinallyShortRangeEntryPoints.add(finwrap.entry); } } - Set setFinallyLongRangeEntryPaths = new HashSet(); + Set setFinallyLongRangeEntryPaths = new HashSet<>(); for (List lst : dgraph.mapLongRangeFinallyPaths.values()) { for (FinallyPathWrapper finwrap : lst) { setFinallyLongRangeEntryPaths.add(finwrap.source + "##" + finwrap.entry); } } - Map mapCatch = new HashMap(); + Map mapCatch = new HashMap<>(); collectCatchVars(root, flatthelper, mapCatch); - Map> mapData = new HashMap>(); + Map> mapData = new HashMap<>(); - LinkedList stack = new LinkedList(); - LinkedList> stackEntryPoint = new LinkedList>(); + LinkedList stack = new LinkedList<>(); + LinkedList> stackEntryPoint = new LinkedList<>(); stack.add(dgraph.first); - stackEntryPoint.add(new LinkedList()); + stackEntryPoint.add(new LinkedList<>()); - Map map = new HashMap(); + Map map = new HashMap<>(); map.put(null, new PrimitiveExprsList()); mapData.put(dgraph.first, map); @@ -187,10 +187,10 @@ public class ExprProcessor implements CodeConstants { Map mapSucc = mapData.get(nd); if (mapSucc == null) { - mapData.put(nd, mapSucc = new HashMap()); + mapData.put(nd, mapSucc = new HashMap<>()); } - LinkedList ndentrypoints = new LinkedList(entrypoints); + LinkedList ndentrypoints = new LinkedList<>(entrypoints); if (setFinallyLongRangeEntryPaths.contains(node.id + "##" + nd.id)) { ndentrypoints.addLast(node.id); @@ -641,7 +641,7 @@ public class ExprProcessor implements CodeConstants { int base = VarExprent.STACK_BASE + stack.size(); - LinkedList lst = new LinkedList(); + LinkedList lst = new LinkedList<>(); for (int i = -1; i >= offset; i--) { Exprent varex = stack.pop(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java index d3e1d04..0123691 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/FinallyProcessor.java @@ -46,8 +46,8 @@ import java.util.*; import java.util.Map.Entry; public class FinallyProcessor { - private final Map finallyBlockIDs = new HashMap(); - private final Map catchallBlockIDs = new HashMap(); + private final Map finallyBlockIDs = new HashMap<>(); + private final Map catchallBlockIDs = new HashMap<>(); private final MethodDescriptor methodDescriptor; private final VarProcessor varProcessor; @@ -64,7 +64,7 @@ public class FinallyProcessor { private boolean processStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph graph) { int bytecode_version = mt.getClassStruct().getBytecodeVersion(); - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { @@ -191,7 +191,7 @@ public class FinallyProcessor { } private Record getFinallyInformation(StructMethod mt, RootStatement root, CatchAllStatement fstat) { - Map mapLast = new HashMap(); + Map mapLast = new HashMap<>(); BasicBlockStatement firstBlockStatement = fstat.getHandler().getBasichead(); BasicBlock firstBasicBlock = firstBlockStatement.getBlock(); @@ -220,10 +220,10 @@ public class FinallyProcessor { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(dgraph.first); - Set setVisited = new HashSet(); + Set setVisited = new HashSet<>(); while (!stack.isEmpty()) { @@ -374,7 +374,7 @@ public class FinallyProcessor { Record information, int bytecode_version) { - Set setCopy = new HashSet(setTry); + Set setCopy = new HashSet<>(setTry); int finallytype = information.firstCode; Map mapLast = information.mapLast; @@ -464,7 +464,7 @@ public class FinallyProcessor { setCopy.add(newhead); setCopy.add(newheadinit); - for (BasicBlock hd : new HashSet(newheadinit.getSuccExceptions())) { + for (BasicBlock hd : new HashSet<>(newheadinit.getSuccExceptions())) { ExceptionRangeCFG range = graph.getExceptionRange(hd, newheadinit); if (setCopy.containsAll(range.getProtectedRange())) { @@ -477,7 +477,7 @@ public class FinallyProcessor { private static void insertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock, BasicBlock newblock) { - List lstTemp = new ArrayList(); + List lstTemp = new ArrayList<>(); lstTemp.addAll(oldblock.getPreds()); lstTemp.addAll(oldblock.getPredExceptions()); @@ -510,7 +510,7 @@ public class FinallyProcessor { private static HashSet getAllBasicBlocks(Statement stat) { - List lst = new LinkedList(); + List lst = new LinkedList<>(); lst.add(stat); int index = 0; @@ -527,7 +527,7 @@ public class FinallyProcessor { } while (index < lst.size()); - HashSet res = new HashSet(); + HashSet res = new HashSet<>(); for (Statement st : lst) { res.add(((BasicBlockStatement)st).getBlock()); @@ -569,7 +569,7 @@ public class FinallyProcessor { } // identify start blocks - HashSet startBlocks = new HashSet(); + HashSet startBlocks = new HashSet<>(); for (BasicBlock block : tryBlocks) { startBlocks.addAll(block.getSuccs()); } @@ -578,7 +578,7 @@ public class FinallyProcessor { startBlocks.remove(graph.getLast()); startBlocks.removeAll(tryBlocks); - List lstAreas = new ArrayList(); + List lstAreas = new ArrayList<>(); for (BasicBlock start : startBlocks) { @@ -648,17 +648,17 @@ public class FinallyProcessor { public BlockStackEntry(BasicBlock blockCatch, BasicBlock blockSample, List lstStoreVars) { this.blockCatch = blockCatch; this.blockSample = blockSample; - this.lstStoreVars = new ArrayList(lstStoreVars); + this.lstStoreVars = new ArrayList<>(lstStoreVars); } } - List stack = new LinkedList(); + List stack = new LinkedList<>(); - Set setSample = new HashSet(); + Set setSample = new HashSet<>(); - Map mapNext = new HashMap(); + Map mapNext = new HashMap<>(); - stack.add(new BlockStackEntry(startCatch, startSample, new ArrayList())); + stack.add(new BlockStackEntry(startCatch, startSample, new ArrayList<>())); while (!stack.isEmpty()) { @@ -719,7 +719,7 @@ public class FinallyProcessor { if (instrCatch.opcode == CodeConstants.opc_astore && instrSample.opcode == CodeConstants.opc_astore) { - lst = new ArrayList(lst); + lst = new ArrayList<>(lst); lst.add(new int[]{instrCatch.getOperand(0), instrSample.getOperand(0)}); } } @@ -738,7 +738,7 @@ public class FinallyProcessor { } if (isLastBlock) { - Set setSuccs = new HashSet(blockSample.getSuccs()); + Set setSuccs = new HashSet<>(blockSample.getSuccs()); setSuccs.removeAll(setSample); for (BlockStackEntry stackent : stack) { @@ -753,7 +753,7 @@ public class FinallyProcessor { } } - return new Area(startSample, setSample, getUniqueNext(graph, new HashSet(mapNext.values()))); + return new Area(startSample, setSample, getUniqueNext(graph, new HashSet<>(mapNext.values()))); } private static BasicBlock getUniqueNext(ControlFlowGraph graph, Set setNext) { @@ -887,7 +887,7 @@ public class FinallyProcessor { if (seqPattern.length() < seqSample.length()) { // split in two blocks SimpleInstructionSequence seq = new SimpleInstructionSequence(); - LinkedList oldOffsets = new LinkedList(); + LinkedList oldOffsets = new LinkedList<>(); for (int i = seqSample.length() - 1; i >= seqPattern.length(); i--) { seq.addInstruction(0, seqSample.getInstr(i), -1); oldOffsets.addFirst(sample.getOldOffset(i)); @@ -898,7 +898,7 @@ public class FinallyProcessor { newblock.setSeq(seq); newblock.getInstrOldOffsets().addAll(oldOffsets); - List lstTemp = new ArrayList(); + List lstTemp = new ArrayList<>(); lstTemp.addAll(sample.getSuccs()); // move successors @@ -976,14 +976,14 @@ public class FinallyProcessor { } // collect common exception ranges of predecessors and successors - Set setCommonExceptionHandlers = new HashSet(next.getSuccExceptions()); + Set setCommonExceptionHandlers = new HashSet<>(next.getSuccExceptions()); for (BasicBlock pred : start.getPreds()) { setCommonExceptionHandlers.retainAll(pred.getSuccExceptions()); } boolean is_outside_range = false; - Set setPredecessors = new HashSet(start.getPreds()); + Set setPredecessors = new HashSet<>(start.getPreds()); // replace start with next for (BasicBlock pred : setPredecessors) { @@ -1005,7 +1005,7 @@ public class FinallyProcessor { is_outside_range = true; } - Set setRemovedExceptionRanges = new HashSet(); + Set setRemovedExceptionRanges = new HashSet<>(); for (BasicBlock handler : block.getSuccExceptions()) { setRemovedExceptionRanges.add(graph.getExceptionRange(handler, block)); } @@ -1020,7 +1020,7 @@ public class FinallyProcessor { // shift extern edges on splitted blocks if (block.getSeq().isEmpty() && block.getSuccs().size() == 1) { BasicBlock succs = block.getSuccs().get(0); - for (BasicBlock pred : new ArrayList(block.getPreds())) { + for (BasicBlock pred : new ArrayList<>(block.getPreds())) { if (!setBlocks.contains(pred)) { pred.replaceSuccessor(block, succs); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java index 3adf70c..3a88aca 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java @@ -34,7 +34,7 @@ public class IfHelper { public static boolean mergeAllIfs(RootStatement root) { - boolean res = mergeAllIfsRec(root, new HashSet()); + boolean res = mergeAllIfsRec(root, new HashSet<>()); if (res) { SequenceHelper.condenseSequences(root); @@ -88,7 +88,7 @@ public class IfHelper { boolean updated = false; - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (statement.type == Statement.TYPE_IF) { lst.add(statement); } @@ -196,7 +196,7 @@ public class IfHelper { // merge if conditions IfExprent statexpr = ifparent.getHeadexprent(); - List lstOperands = new ArrayList(); + List lstOperands = new ArrayList<>(); lstOperands.add(statexpr.getCondition()); lstOperands.add(ifchild.getHeadexprent().getCondition()); @@ -250,7 +250,7 @@ public class IfHelper { // merge if conditions IfExprent statexpr = ifparent.getHeadexprent(); - List lstOperands = new ArrayList(); + List lstOperands = new ArrayList<>(); lstOperands.add(statexpr.getCondition()); lstOperands.add(new FunctionExprent(FunctionExprent.FUNCTION_BOOL_NOT, ifchild.getHeadexprent().getCondition(), null)); statexpr.setCondition(new FunctionExprent(FunctionExprent.FUNCTION_CADD, lstOperands, null)); @@ -305,7 +305,7 @@ public class IfHelper { // merge if conditions IfExprent statexpr = secondif.getHeadexprent(); - List lstOperands = new ArrayList(); + List lstOperands = new ArrayList<>(); lstOperands.add(firstif.getHeadexprent().getCondition()); if (path == 2) { @@ -509,7 +509,7 @@ public class IfHelper { SequenceStatement sequence = (SequenceStatement)parent; // build and cut the new else statement - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (int i = sequence.getStats().size() - 1; i >= 0; i--) { Statement sttemp = sequence.getStats().get(i); if (sttemp == ifstat) { @@ -597,7 +597,7 @@ public class IfHelper { SequenceStatement sequence = (SequenceStatement)parent; // build and cut the new else statement - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (int i = sequence.getStats().size() - 1; i >= 0; i--) { Statement sttemp = sequence.getStats().get(i); if (sttemp == ifstat) { @@ -735,8 +735,8 @@ public class IfHelper { private static class IfNode { public final Statement value; - public final List succs = new ArrayList(); - public final List edgetypes = new ArrayList(); + public final List succs = new ArrayList<>(); + public final List edgetypes = new ArrayList<>(); public IfNode(Statement value) { this.value = value; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java index adeda02..205e25c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/InlineSingleBlockHelper.java @@ -68,7 +68,7 @@ public class InlineSingleBlockHelper { Statement parent = source.getParent(); source.removeSuccessor(edge); - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (int i = seq.getStats().size() - 1; i >= index; i--) { lst.add(0, seq.getStats().remove(i)); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java index 26cc638..bba1484 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/LabelHelper.java @@ -33,7 +33,7 @@ public class LabelHelper { liftClosures(root); - lowContinueLabels(root, new HashSet()); + lowContinueLabels(root, new HashSet<>()); lowClosures(root); } @@ -63,7 +63,7 @@ public class LabelHelper { if (dest.type != Statement.TYPE_DUMMYEXIT) { Statement parent = dest.getParent(); - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (parent.type == Statement.TYPE_SEQUENCE) { lst.addAll(parent.getStats()); } @@ -131,14 +131,14 @@ public class LabelHelper { lowContinueLabels(st, edges); } else { - lowContinueLabels(st, new HashSet()); + lowContinueLabels(st, new HashSet<>()); } } } public static void lowClosures(Statement stat) { - for (StatEdge edge : new ArrayList(stat.getLabelEdges())) { + for (StatEdge edge : new ArrayList<>(stat.getLabelEdges())) { if (edge.getType() == StatEdge.TYPE_BREAK) { // FIXME: ? for (Statement st : stat.getStats()) { @@ -181,7 +181,7 @@ public class LabelHelper { private static HashMap> setExplicitEdges(Statement stat) { - HashMap> mapEdges = new HashMap>(); + HashMap> mapEdges = new HashMap<>(); if (stat.getExprents() != null) { return mapEdges; @@ -279,7 +279,7 @@ public class LabelHelper { Statement stlast = swst.getCaseStatements().get(last); if (stlast.getExprents() != null && stlast.getExprents().isEmpty()) { StatEdge edge = stlast.getAllSuccessorEdges().get(0); - mapEdges.put(edge.getDestination(), new ArrayList(Arrays.asList(new StatEdge[]{edge}))); + mapEdges.put(edge.getDestination(), new ArrayList<>(Arrays.asList(new StatEdge[]{edge}))); } else { mapEdges = setExplicitEdges(stlast); @@ -340,7 +340,7 @@ public class LabelHelper { edge.explicit = false; } - mapEdges.put(newedge.getDestination(), new ArrayList(Arrays.asList(new StatEdge[]{newedge}))); + mapEdges.put(newedge.getDestination(), new ArrayList<>(Arrays.asList(new StatEdge[]{newedge}))); } } } @@ -388,7 +388,7 @@ public class LabelHelper { } if (statedge != null) { - mapEdges.put(statedge.getDestination(), new ArrayList(Arrays.asList(new StatEdge[]{statedge}))); + mapEdges.put(statedge.getDestination(), new ArrayList<>(Arrays.asList(new StatEdge[]{statedge}))); } } @@ -422,8 +422,8 @@ public class LabelHelper { private static HashSet[] processStatementLabel(Statement stat) { - HashSet setBreak = new HashSet(); - HashSet setContinue = new HashSet(); + HashSet setBreak = new HashSet<>(); + HashSet setContinue = new HashSet<>(); if (stat.getExprents() == null) { for (Statement st : stat.getStats()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java index d5c9e8f..1fac826 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/LoopExtractHelper.java @@ -189,7 +189,7 @@ public class LoopExtractHelper { loop.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, loop, target)); - for (StatEdge edge : new ArrayList(block.getLabelEdges())) { + for (StatEdge edge : new ArrayList<>(block.getLabelEdges())) { if (edge.getType() == StatEdge.TYPE_CONTINUE || edge == ifedge) { loop.addLabeledEdge(edge); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java index 71d3d79..0bc723d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/MergeHelper.java @@ -185,7 +185,7 @@ public class MergeHelper { if (firstif == stat.getFirst()) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); - bstat.setExprents(new ArrayList()); + bstat.setExprents(new ArrayList<>()); stat.replaceStatement(firstif, bstat); } else { @@ -224,7 +224,7 @@ public class MergeHelper { if (firstif.getIfstat() == null) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); - bstat.setExprents(new ArrayList()); + bstat.setExprents(new ArrayList<>()); ifedge.setSource(bstat); bstat.addSuccessor(ifedge); @@ -382,7 +382,7 @@ public class MergeHelper { if (stat == dostat.getFirst()) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); - bstat.setExprents(new ArrayList()); + bstat.setExprents(new ArrayList<>()); dostat.replaceStatement(stat, bstat); } else { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java index 4eb366b..2371a72 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/PPandMMHelper.java @@ -38,10 +38,10 @@ public class PPandMMHelper { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(dgraph.first); - HashSet setVisited = new HashSet(); + HashSet setVisited = new HashSet<>(); boolean res = false; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/PrimitiveExprsList.java b/src/org/jetbrains/java/decompiler/modules/decompiler/PrimitiveExprsList.java index 0a1831e..fff1841 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/PrimitiveExprsList.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/PrimitiveExprsList.java @@ -22,7 +22,7 @@ import java.util.List; public class PrimitiveExprsList { - private final List lstExprents = new ArrayList(); + private final List lstExprents = new ArrayList<>(); private ExprentStack stack = new ExprentStack(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java index 12aecbb..f95d2c3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SecondaryFunctionsHelper.java @@ -43,7 +43,7 @@ public class SecondaryFunctionsHelper { FunctionExprent.FUNCTION_CADD }; - private static final HashMap mapNumComparisons = new HashMap(); + private static final HashMap mapNumComparisons = new HashMap<>(); static { mapNumComparisons.put(FunctionExprent.FUNCTION_EQ, @@ -102,7 +102,7 @@ public class SecondaryFunctionsHelper { while (replaced) { replaced = false; - List lstObjects = new ArrayList(stat.getExprents() == null ? stat.getSequentialObjects() : stat.getExprents()); + List lstObjects = new ArrayList<>(stat.getExprents() == null ? stat.getSequentialObjects() : stat.getExprents()); for (int i = 0; i < lstObjects.size(); i++) { Object obj = lstObjects.get(i); @@ -229,7 +229,7 @@ public class SecondaryFunctionsHelper { } if (val == -1) { - List lstBitNotOperand = new ArrayList(); + List lstBitNotOperand = new ArrayList<>(); lstBitNotOperand.add(lstOperands.get(1 - i)); return new FunctionExprent(FunctionExprent.FUNCTION_BIT_NOT, lstBitNotOperand, fexpr.bytecode); } @@ -250,7 +250,7 @@ public class SecondaryFunctionsHelper { return lstOperands.get(1 - i); } else { - List lstNotOperand = new ArrayList(); + List lstNotOperand = new ArrayList<>(); lstNotOperand.add(lstOperands.get(1 - i)); return new FunctionExprent(FunctionExprent.FUNCTION_BOOL_NOT, lstNotOperand, fexpr.bytecode); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SequenceHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SequenceHelper.java index 75bbd39..05c7bd5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SequenceHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SequenceHelper.java @@ -39,7 +39,7 @@ public class SequenceHelper { if (stat.type == Statement.TYPE_SEQUENCE) { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.addAll(stat.getStats()); boolean unfolded = false; @@ -84,7 +84,7 @@ public class SequenceHelper { st.removeSuccessor(edge); } - for (StatEdge edge : new HashSet(st.getLabelEdges())) { + for (StatEdge edge : new HashSet<>(st.getLabelEdges())) { if (edge.getSource() != last) { last.addLabeledEdge(edge); } @@ -302,7 +302,7 @@ public class SequenceHelper { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); if (stat.getExprents() == null) { - bstat.setExprents(new ArrayList()); + bstat.setExprents(new ArrayList<>()); } else { bstat.setExprents(DecHelper.copyExprentList(stat.getExprents())); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java index ddf6865..28b76e9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java @@ -310,7 +310,7 @@ public class SimplifyExprentsHelper { VarExprent arrvar = (VarExprent)as.getLeft(); - HashMap mapInit = new HashMap(); + HashMap mapInit = new HashMap<>(); int i = 1; while (index + i < list.size() && i <= size) { @@ -350,7 +350,7 @@ public class SimplifyExprentsHelper { if ((arrvar.isStack() && fraction > 0) || (size <= 7 && fraction >= 0.3) || (size > 7 && fraction >= 0.7)) { - List lstRet = new ArrayList(); + List lstRet = new ArrayList<>(); VarType arrtype = newex.getNewType().decreaseArrayDim(); @@ -813,7 +813,7 @@ public class SimplifyExprentsHelper { } if (found) { - List data = new ArrayList(); + List data = new ArrayList<>(); data.addAll(stif.getFirst().getExprents()); data.add(new AssignmentExprent(ifvar, new FunctionExprent(FunctionExprent.FUNCTION_IIF, @@ -854,7 +854,7 @@ public class SimplifyExprentsHelper { return false; } - List data = new ArrayList(); + List data = new ArrayList<>(); data.addAll(stif.getFirst().getExprents()); data.add(new ExitExprent(ifex.getExitType(), new FunctionExprent(FunctionExprent.FUNCTION_IIF, @@ -918,7 +918,7 @@ public class SimplifyExprentsHelper { assfirst.replaceExprent(assfirst.getRight(), new ConstExprent(VarType.VARTYPE_CLASS, class_name, null)); - List data = new ArrayList(); + List data = new ArrayList<>(); data.addAll(stat.getFirst().getExprents()); stat.setExprents(data); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java index 62d3465..ea52cb3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StackVarsProcessor.java @@ -39,7 +39,7 @@ public class StackVarsProcessor { public void simplifyStackVars(RootStatement root, StructMethod mt, StructClass cl) { - HashSet setReorderedIfs = new HashSet(); + HashSet setReorderedIfs = new HashSet<>(); SSAUConstructorSparseEx ssau = null; @@ -149,12 +149,12 @@ public class StackVarsProcessor { boolean res = false; - HashSet setVisited = new HashSet(); - LinkedList stack = new LinkedList(); - LinkedList> stackMaps = new LinkedList>(); + HashSet setVisited = new HashSet<>(); + LinkedList stack = new LinkedList<>(); + LinkedList> stackMaps = new LinkedList<>(); stack.add(dgraph.first); - stackMaps.add(new HashMap()); + stackMaps.add(new HashMap<>()); while (!stack.isEmpty()) { @@ -166,7 +166,7 @@ public class StackVarsProcessor { } setVisited.add(nd); - List> lstLists = new ArrayList>(); + List> lstLists = new ArrayList<>(); if (!nd.exprents.isEmpty()) { lstLists.add(nd.exprents); @@ -211,7 +211,7 @@ public class StackVarsProcessor { for (DirectNode ndx : nd.succs) { stack.add(ndx); - stackMaps.add(new HashMap(mapVarValues)); + stackMaps.add(new HashMap<>(mapVarValues)); } // make sure the 3 special exprent lists in a loop (init, condition, increment) are not empty @@ -329,7 +329,7 @@ public class StackVarsProcessor { VarVersionPair leftpaar = new VarVersionPair(left); - List usedVers = new ArrayList(); + List usedVers = new ArrayList<>(); boolean notdom = getUsedVersions(ssau, leftpaar, usedVers); if (!notdom && usedVers.isEmpty()) { @@ -395,7 +395,7 @@ public class StackVarsProcessor { boolean verreplaced = false; - HashSet setTempUsedVers = new HashSet(); + HashSet setTempUsedVers = new HashSet<>(); for (VarVersionNode usedvar : usedVers) { VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version); @@ -440,9 +440,9 @@ public class StackVarsProcessor { private static HashSet getAllVersions(Exprent exprent) { - HashSet res = new HashSet(); + HashSet res = new HashSet<>(); - List listTemp = new ArrayList(exprent.getAllExprents(true)); + List listTemp = new ArrayList<>(exprent.getAllExprents(true)); listTemp.add(exprent); for (Exprent expr : listTemp) { @@ -523,7 +523,7 @@ public class StackVarsProcessor { VarVersionPair leftpaar = new VarVersionPair(left); - List usedVers = new ArrayList(); + List usedVers = new ArrayList<>(); boolean notdom = getUsedVersions(ssau, leftpaar, usedVers); if (!notdom && usedVers.isEmpty()) { @@ -557,7 +557,7 @@ public class StackVarsProcessor { boolean vernotreplaced = false; - HashSet setTempUsedVers = new HashSet(); + HashSet setTempUsedVers = new HashSet<>(); for (VarVersionNode usedvar : usedVers) { VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version); @@ -594,11 +594,11 @@ public class StackVarsProcessor { VarVersionsGraph ssuversions = ssa.getSsuversions(); VarVersionNode varnode = ssuversions.nodes.getWithKey(var); - HashSet setVisited = new HashSet(); + HashSet setVisited = new HashSet<>(); - HashSet setNotDoms = new HashSet(); + HashSet setNotDoms = new HashSet<>(); - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(varnode); while (!stack.isEmpty()) { @@ -663,7 +663,7 @@ public class StackVarsProcessor { return false; } - HashSet domset = new HashSet(); + HashSet domset = new HashSet<>(); for (VarVersionPair verpaar : ent.getValue()) { domset.add(ssuversions.nodes.getWithKey(verpaar)); } @@ -691,7 +691,7 @@ public class StackVarsProcessor { Exprent exprent, SSAUConstructorSparseEx ssau) { - HashMap> map = new HashMap>(); + HashMap> map = new HashMap<>(); SFormsFastMapDirect mapLiveVars = ssau.getLiveVarVersionsMap(leftvar); List lst = exprent.getAllExprents(true); @@ -702,7 +702,7 @@ public class StackVarsProcessor { int varindex = ((VarExprent)expr).getIndex(); if (leftvar.var != varindex) { if (mapLiveVars.containsKey(varindex)) { - HashSet verset = new HashSet(); + HashSet verset = new HashSet<>(); for (Integer vers : mapLiveVars.get(varindex)) { verset.add(new VarVersionPair(varindex, vers.intValue())); } @@ -720,7 +720,7 @@ public class StackVarsProcessor { if (ssau.getMapFieldVars().containsKey(expr.id)) { int varindex = ssau.getMapFieldVars().get(expr.id); if (mapLiveVars.containsKey(varindex)) { - HashSet verset = new HashSet(); + HashSet verset = new HashSet<>(); for (Integer vers : mapLiveVars.get(varindex)) { verset.add(new VarVersionPair(varindex, vers.intValue())); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java index 26d427b..8d5e762 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StatEdge.java @@ -66,7 +66,7 @@ public class StatEdge { public StatEdge(Statement source, Statement destination, List exceptions) { this(TYPE_EXCEPTION, source, destination); if (exceptions != null) { - this.exceptions = new ArrayList(exceptions); + this.exceptions = new ArrayList<>(exceptions); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/StrongConnectivityHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/StrongConnectivityHelper.java index 23f778d..047accd 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/StrongConnectivityHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/StrongConnectivityHelper.java @@ -92,8 +92,8 @@ public class StrongConnectivityHelper { public List> findComponents(Statement stat) { - components = new ArrayList>(); - setProcessed = new HashSet(); + components = new ArrayList<>(); + setProcessed = new HashSet<>(); visitTree(stat.getFirst()); @@ -115,7 +115,7 @@ public class StrongConnectivityHelper { public static boolean isExitComponent(List lst) { - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); for (Statement stat : lst) { set.addAll(stat.getNeighbours(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD)); } @@ -126,7 +126,7 @@ public class StrongConnectivityHelper { public static List getExitReps(List> lst) { - List res = new ArrayList(); + List res = new ArrayList<>(); for (List comp : lst) { if (isExitComponent(comp)) { @@ -142,11 +142,11 @@ public class StrongConnectivityHelper { // ***************************************************************************** private void visitTree(Statement stat) { - lstack = new ListStack(); + lstack = new ListStack<>(); ncounter = 0; - tset = new HashSet(); - dfsnummap = new HashMap(); - lowmap = new HashMap(); + tset = new HashSet<>(); + dfsnummap = new HashMap<>(); + lowmap = new HashMap<>(); visit(stat); @@ -181,7 +181,7 @@ public class StrongConnectivityHelper { if (lowmap.get(stat).intValue() == dfsnummap.get(stat).intValue()) { - List lst = new ArrayList(); + List lst = new ArrayList<>(); Statement v; do { v = lstack.pop(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorEngine.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorEngine.java index a61d44c..608d56c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorEngine.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorEngine.java @@ -25,7 +25,7 @@ public class DominatorEngine { private final Statement statement; - private final VBStyleCollection colOrderedIDoms = new VBStyleCollection(); + private final VBStyleCollection colOrderedIDoms = new VBStyleCollection<>(); public DominatorEngine(Statement statement) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java index 89e6849..59b6b15 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/DominatorTreeExceptionFilter.java @@ -27,16 +27,16 @@ public class DominatorTreeExceptionFilter { private final Statement statement; // idom, nodes - private final Map> mapTreeBranches = new HashMap>(); + private final Map> mapTreeBranches = new HashMap<>(); // handler, range nodes - private final Map> mapExceptionRanges = new HashMap>(); + private final Map> mapExceptionRanges = new HashMap<>(); // handler, head dom - private Map mapExceptionDoms = new HashMap(); + private Map mapExceptionDoms = new HashMap<>(); // statement, handler, exit nodes - private final Map> mapExceptionRangeUniqueExit = new HashMap>(); + private final Map> mapExceptionRangeUniqueExit = new HashMap<>(); private DominatorEngine domEngine; @@ -86,7 +86,7 @@ public class DominatorTreeExceptionFilter { Set set = mapTreeBranches.get(idom); if (set == null) { - mapTreeBranches.put(idom, set = new HashSet()); + mapTreeBranches.put(idom, set = new HashSet<>()); } set.add(key); } @@ -101,7 +101,7 @@ public class DominatorTreeExceptionFilter { List lstPreds = stat.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD); if (!lstPreds.isEmpty()) { - Set set = new HashSet(); + Set set = new HashSet<>(); for (Statement st : lstPreds) { set.add(st.id); @@ -116,7 +116,7 @@ public class DominatorTreeExceptionFilter { private Map buildExceptionDoms(Integer id) { - Map map = new HashMap(); + Map map = new HashMap<>(); Set children = mapTreeBranches.get(id); if (children != null) { @@ -140,7 +140,7 @@ public class DominatorTreeExceptionFilter { private void buildFilter(Integer id) { - Map map = new HashMap(); + Map map = new HashMap<>(); Set children = mapTreeBranches.get(id); if (children != null) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java index 52338f9..f37aedc 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/FastExtendedPostdominanceHelper.java @@ -28,9 +28,9 @@ public class FastExtendedPostdominanceHelper { private List lstReversePostOrderList; - private HashMap> mapSupportPoints = new HashMap>(); + private HashMap> mapSupportPoints = new HashMap<>(); - private final HashMap> mapExtPostdominators = new HashMap>(); + private final HashMap> mapExtPostdominators = new HashMap<>(); private Statement statement; @@ -40,11 +40,11 @@ public class FastExtendedPostdominanceHelper { this.statement = statement; - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); for (Statement st : statement.getStats()) { set.add(st.id); } - this.factory = new FastFixedSetFactory(set); + this.factory = new FastFixedSetFactory<>(set); lstReversePostOrderList = statement.getReversePostOrderList(); @@ -65,7 +65,7 @@ public class FastExtendedPostdominanceHelper { filterOnDominance(filter); - HashMap> res = new HashMap>(); + HashMap> res = new HashMap<>(); for (Entry> entry : mapExtPostdominators.entrySet()) { res.put(entry.getKey(), entry.getValue().toPlainSet()); } @@ -78,17 +78,17 @@ public class FastExtendedPostdominanceHelper { DominatorEngine engine = filter.getDomEngine(); - for (Integer head : new HashSet(mapExtPostdominators.keySet())) { + for (Integer head : new HashSet<>(mapExtPostdominators.keySet())) { FastFixedSet setPostdoms = mapExtPostdominators.get(head); - LinkedList stack = new LinkedList(); - LinkedList> stackPath = new LinkedList>(); + LinkedList stack = new LinkedList<>(); + LinkedList> stackPath = new LinkedList<>(); stack.add(statement.getStats().getWithKey(head)); stackPath.add(factory.spawnEmptySet()); - Set setVisited = new HashSet(); + Set setVisited = new HashSet<>(); setVisited.add(stack.getFirst()); @@ -134,7 +134,7 @@ public class FastExtendedPostdominanceHelper { private void filterOnExceptionRanges(DominatorTreeExceptionFilter filter) { - for (Integer head : new HashSet(mapExtPostdominators.keySet())) { + for (Integer head : new HashSet<>(mapExtPostdominators.keySet())) { FastFixedSet set = mapExtPostdominators.get(head); for (Iterator it = set.iterator(); it.hasNext(); ) { @@ -151,7 +151,7 @@ public class FastExtendedPostdominanceHelper { private void removeErroneousNodes() { - mapSupportPoints = new HashMap>(); + mapSupportPoints = new HashMap<>(); calcReachabilitySuppPoints(StatEdge.TYPE_REGULAR); @@ -161,7 +161,7 @@ public class FastExtendedPostdominanceHelper { Integer nodeid = node.id; FastFixedSet setReachability = mapSets.get(nodeid); - List> lstPredSets = new ArrayList>(); + List> lstPredSets = new ArrayList<>(); for (StatEdge prededge : node.getPredecessorEdges(StatEdge.TYPE_REGULAR)) { FastFixedSet setPred = mapSets.get(prededge.getSource().id); @@ -285,7 +285,7 @@ public class FastExtendedPostdominanceHelper { boolean iterate = false; - HashMap> mapSets = new HashMap>(); + HashMap> mapSets = new HashMap<>(); for (Statement stat : lstReversePostOrderList) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/GenericDominatorEngine.java b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/GenericDominatorEngine.java index fa5ccf3..d1830f3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/GenericDominatorEngine.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/decompose/GenericDominatorEngine.java @@ -24,7 +24,7 @@ public class GenericDominatorEngine { private final IGraph graph; - private final VBStyleCollection colOrderedIDoms = new VBStyleCollection(); + private final VBStyleCollection colOrderedIDoms = new VBStyleCollection<>(); private Set setRoots; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java index 7614807..0826e8b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/ExceptionDeobfuscator.java @@ -48,7 +48,7 @@ public class ExceptionDeobfuscator { public static void restorePopRanges(ControlFlowGraph graph) { - List lstRanges = new ArrayList(); + List lstRanges = new ArrayList<>(); // aggregate ranges for (ExceptionRangeCFG range : graph.getExceptions()) { @@ -63,7 +63,7 @@ public class ExceptionDeobfuscator { if (!found) { // doesn't matter, which range chosen - lstRanges.add(new Range(range.getHandler(), range.getUniqueExceptionsString(), new HashSet(range.getProtectedRange()), range)); + lstRanges.add(new Range(range.getHandler(), range.getUniqueExceptionsString(), new HashSet<>(range.getProtectedRange()), range)); } } @@ -81,13 +81,13 @@ public class ExceptionDeobfuscator { if (firstinstr.opcode == CodeConstants.opc_pop || firstinstr.opcode == CodeConstants.opc_astore) { - Set setrange = new HashSet(range.protectedRange); + Set setrange = new HashSet<>(range.protectedRange); for (Range range_super : lstRanges) { // finally or strict superset if (range != range_super) { - Set setrange_super = new HashSet(range_super.protectedRange); + Set setrange_super = new HashSet<>(range_super.protectedRange); if (!setrange.contains(range_super.handler) && !setrange_super.contains(handler) && (range_super.uniqueStr == null || setrange_super.containsAll(setrange))) { @@ -113,7 +113,7 @@ public class ExceptionDeobfuscator { graph.getBlocks().addWithKey(newblock, newblock.id); - List lstTemp = new ArrayList(); + List lstTemp = new ArrayList<>(); lstTemp.addAll(handler.getPreds()); lstTemp.addAll(handler.getPredExceptions()); @@ -159,7 +159,7 @@ public class ExceptionDeobfuscator { public static void insertEmptyExceptionHandlerBlocks(ControlFlowGraph graph) { - Set setVisited = new HashSet(); + Set setVisited = new HashSet<>(); for (ExceptionRangeCFG range : graph.getExceptions()) { BasicBlock handler = range.getHandler(); @@ -172,7 +172,7 @@ public class ExceptionDeobfuscator { BasicBlock emptyblock = new BasicBlock(++graph.last_id); graph.getBlocks().addWithKey(emptyblock, emptyblock.id); - List lstTemp = new ArrayList(); + List lstTemp = new ArrayList<>(); // only exception predecessors considered lstTemp.addAll(handler.getPredExceptions()); @@ -231,7 +231,7 @@ public class ExceptionDeobfuscator { } public Set getRoots() { - return new HashSet(Arrays.asList(new IGraphNode[]{graph.getFirst()})); + return new HashSet<>(Arrays.asList(new IGraphNode[]{graph.getFirst()})); } }); @@ -264,10 +264,10 @@ public class ExceptionDeobfuscator { private static List getReachableBlocksRestricted(ExceptionRangeCFG range, GenericDominatorEngine engine) { - List lstRes = new ArrayList(); + List lstRes = new ArrayList<>(); - LinkedList stack = new LinkedList(); - Set setVisited = new HashSet(); + LinkedList stack = new LinkedList<>(); + Set setVisited = new HashSet<>(); BasicBlock handler = range.getHandler(); stack.addFirst(handler); @@ -280,7 +280,7 @@ public class ExceptionDeobfuscator { if (range.getProtectedRange().contains(block) && engine.isDominator(block, handler)) { lstRes.add(block); - List lstSuccs = new ArrayList(block.getSuccs()); + List lstSuccs = new ArrayList<>(block.getSuccs()); lstSuccs.addAll(block.getSuccExceptions()); for (BasicBlock succ : lstSuccs) { @@ -297,20 +297,20 @@ public class ExceptionDeobfuscator { public static boolean hasObfuscatedExceptions(ControlFlowGraph graph) { - Map> mapRanges = new HashMap>(); + Map> mapRanges = new HashMap<>(); for (ExceptionRangeCFG range : graph.getExceptions()) { Set set = mapRanges.get(range.getHandler()); if (set == null) { - mapRanges.put(range.getHandler(), set = new HashSet()); + mapRanges.put(range.getHandler(), set = new HashSet<>()); } set.addAll(range.getProtectedRange()); } for (Entry> ent : mapRanges.entrySet()) { - Set setEntries = new HashSet(); + Set setEntries = new HashSet<>(); for (BasicBlock block : ent.getValue()) { - Set setTemp = new HashSet(block.getPreds()); + Set setTemp = new HashSet<>(block.getPreds()); setTemp.removeAll(ent.getValue()); if (!setTemp.isEmpty()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java index 42ba76f..12840f2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java @@ -31,15 +31,15 @@ public class IrreducibleCFGDeobfuscator { class Node { public Integer id; - public final Set preds = new HashSet(); - public final Set succs = new HashSet(); + public final Set preds = new HashSet<>(); + public final Set succs = new HashSet<>(); public Node(Integer id) { this.id = id; } } - HashMap mapNodes = new HashMap(); + HashMap mapNodes = new HashMap<>(); // checking exceptions and creating nodes for (Statement stat : statement.getStats()) { @@ -145,7 +145,7 @@ public class IrreducibleCFGDeobfuscator { StatEdge enteredge = splitnode.getPredecessorEdges(StatEdge.TYPE_REGULAR).iterator().next(); // copy the smallest statement - Statement splitcopy = copyStatement(splitnode, null, new HashMap()); + Statement splitcopy = copyStatement(splitnode, null, new HashMap<>()); initCopiedStatement(splitcopy); // insert the copy diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java index c8db797..3590b48 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ArrayExprent.java @@ -68,7 +68,7 @@ public class ArrayExprent extends Exprent { } public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.add(array); lst.add(index); return lst; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java index 95ebdc5..957f3f5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java @@ -87,7 +87,7 @@ public class AssignmentExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.add(left); lst.add(right); return lst; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index e618235..e82fec7 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -110,7 +110,7 @@ public class ConstExprent extends Exprent { } public List getAllExprents() { - return new ArrayList(); + return new ArrayList<>(); } @Override diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java index c6b962c..abfc4ab 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ExitExprent.java @@ -70,7 +70,7 @@ public class ExitExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (value != null) { lst.add(value); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java index 77b35b3..a530915 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/Exprent.java @@ -76,7 +76,7 @@ public class Exprent implements IMatchable { } public boolean containsExprent(Exprent exprent) { - List listTemp = new ArrayList(getAllExprents(true)); + List listTemp = new ArrayList<>(getAllExprents(true)); listTemp.add(this); for (Exprent lstExpr : listTemp) { @@ -102,7 +102,7 @@ public class Exprent implements IMatchable { List lstAllExprents = getAllExprents(true); lstAllExprents.add(this); - Set set = new HashSet(); + Set set = new HashSet<>(); for (Exprent expr : lstAllExprents) { if (expr.type == EXPRENT_VAR) { set.add(new VarVersionPair((VarExprent)expr)); @@ -128,7 +128,7 @@ public class Exprent implements IMatchable { public void addBytecodeOffsets(Collection bytecodeOffsets) { if (bytecodeOffsets != null && !bytecodeOffsets.isEmpty()) { if (bytecode == null) { - bytecode = new HashSet(bytecodeOffsets); + bytecode = new HashSet<>(bytecodeOffsets); } else { bytecode.addAll(bytecodeOffsets); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java index 5e6a6b5..f1c65d1 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java @@ -71,7 +71,7 @@ public class FieldExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (instance != null) { lst.add(instance); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java index 48206a7..faaa6d2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java @@ -191,7 +191,7 @@ public class FunctionExprent extends Exprent { 3 // FUNCTION_STR_CONCAT = 49; }; - private static final Set ASSOCIATIVITY = new HashSet(Arrays.asList( + private static final Set ASSOCIATIVITY = new HashSet<>(Arrays.asList( FUNCTION_ADD, FUNCTION_MUL, FUNCTION_AND, FUNCTION_OR, FUNCTION_XOR, FUNCTION_CADD, FUNCTION_COR, FUNCTION_STR_CONCAT)); private int funcType; @@ -199,7 +199,7 @@ public class FunctionExprent extends Exprent { private final List lstOperands; public FunctionExprent(int funcType, ListStack stack, Set bytecodeOffsets) { - this(funcType, new ArrayList(), bytecodeOffsets); + this(funcType, new ArrayList<>(), bytecodeOffsets); if (funcType >= FUNCTION_BIT_NOT && funcType <= FUNCTION_PPI && funcType != FUNCTION_CAST && funcType != FUNCTION_INSTANCEOF) { lstOperands.add(stack.pop()); @@ -223,7 +223,7 @@ public class FunctionExprent extends Exprent { } public FunctionExprent(int funcType, Exprent operand, Set bytecodeOffsets) { - this(funcType, new ArrayList(1), bytecodeOffsets); + this(funcType, new ArrayList<>(1), bytecodeOffsets); lstOperands.add(operand); } @@ -413,14 +413,14 @@ public class FunctionExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.addAll(lstOperands); return lst; } @Override public Exprent copy() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (Exprent expr : lstOperands) { lst.add(expr.copy()); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java index 059270f..be4d6f6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/IfExprent.java @@ -107,7 +107,7 @@ public class IfExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.add(condition); return lst; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 1b8188a..94c1b5d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -65,7 +65,7 @@ public class InvocationExprent extends Exprent { private String stringDescriptor; private String invokeDynamicClassSuffix; private int invocationTyp = INVOKE_VIRTUAL; - private List lstParameters = new ArrayList(); + private List lstParameters = new ArrayList<>(); private List bootstrapArguments; public InvocationExprent() { @@ -162,7 +162,7 @@ public class InvocationExprent extends Exprent { invokeDynamicClassSuffix = expr.getInvokeDynamicClassSuffix(); stringDescriptor = expr.getStringDescriptor(); descriptor = expr.getDescriptor(); - lstParameters = new ArrayList(expr.getLstParameters()); + lstParameters = new ArrayList<>(expr.getLstParameters()); ExprProcessor.copyEntries(lstParameters); addBytecodeOffsets(expr.bytecode); @@ -192,7 +192,7 @@ public class InvocationExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (instance != null) { lst.add(instance); } @@ -321,7 +321,7 @@ public class InvocationExprent extends Exprent { } else { if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0) { // non-static member class - sigFields = new ArrayList(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); + sigFields = new ArrayList<>(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); sigFields.set(0, new VarVersionPair(-1, 0)); } } @@ -358,7 +358,7 @@ public class InvocationExprent extends Exprent { if (cl == null) return EMPTY_BIT_SET; // check number of matches - List matches = new ArrayList(); + List matches = new ArrayList<>(); nextMethod: for (StructMethod mt : cl.getMethods()) { if (name.equals(mt.getName())) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java index 0ece9aa..1546064 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/MonitorExprent.java @@ -46,7 +46,7 @@ public class MonitorExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.add(value); return lst; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index 1edd0e4..b6a67d2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -38,8 +38,8 @@ import java.util.Set; public class NewExprent extends Exprent { private InvocationExprent constructor; private final VarType newType; - private List lstDims = new ArrayList(); - private List lstArrayElements = new ArrayList(); + private List lstDims = new ArrayList<>(); + private List lstArrayElements = new ArrayList<>(); private boolean directArrayInit; private boolean anonymous; private boolean lambda; @@ -70,7 +70,7 @@ public class NewExprent extends Exprent { } private static List getDimensions(int arrayDim, ListStack stack) { - List lstDims = new ArrayList(); + List lstDims = new ArrayList<>(); for (int i = 0; i < arrayDim; i++) { lstDims.add(0, stack.pop()); } @@ -111,7 +111,7 @@ public class NewExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (newType.arrayDim == 0) { if (constructor != null) { Exprent constructor_instance = constructor.getInstance(); @@ -133,7 +133,7 @@ public class NewExprent extends Exprent { @Override public Exprent copy() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (Exprent expr : lstDims) { lst.add(expr.copy()); } @@ -199,7 +199,7 @@ public class NewExprent extends Exprent { else { if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && !constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance - sigFields = new ArrayList(Collections.nCopies(constructor.getLstParameters().size(), (VarVersionPair)null)); + sigFields = new ArrayList<>(Collections.nCopies(constructor.getLstParameters().size(), (VarVersionPair)null)); sigFields.set(0, new VarVersionPair(-1, 0)); } } @@ -304,7 +304,7 @@ public class NewExprent extends Exprent { } else if (newNode.type == ClassNode.CLASS_MEMBER && (newNode.access & CodeConstants.ACC_STATIC) == 0 && !constructor.getLstParameters().isEmpty()) { // member non-static class invoked with enclosing class instance - sigFields = new ArrayList(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); + sigFields = new ArrayList<>(Collections.nCopies(lstParameters.size(), (VarVersionPair)null)); sigFields.set(0, new VarVersionPair(-1, 0)); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java index fd77112..27730a9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/SwitchExprent.java @@ -28,7 +28,7 @@ import java.util.Set; public class SwitchExprent extends Exprent { private Exprent value; - private List> caseValues = new ArrayList>(); + private List> caseValues = new ArrayList<>(); public SwitchExprent(Exprent value, Set bytecodeOffsets) { super(EXPRENT_SWITCH); @@ -41,9 +41,9 @@ public class SwitchExprent extends Exprent { public Exprent copy() { SwitchExprent swExpr = new SwitchExprent(value.copy(), bytecode); - List> lstCaseValues = new ArrayList>(); + List> lstCaseValues = new ArrayList<>(); for (List lst : caseValues) { - lstCaseValues.add(new ArrayList(lst)); + lstCaseValues.add(new ArrayList<>(lst)); } swExpr.setCaseValues(lstCaseValues); @@ -80,7 +80,7 @@ public class SwitchExprent extends Exprent { @Override public List getAllExprents() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.add(value); return lst; } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java index 4436cb5..fdd8bb9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -67,7 +67,7 @@ public class VarExprent extends Exprent { @Override public List getAllExprents() { - return new ArrayList(); + return new ArrayList<>(); } @Override diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java index abd844c..413cdf6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectGraph.java @@ -27,24 +27,24 @@ import java.util.List; public class DirectGraph { - public final VBStyleCollection nodes = new VBStyleCollection(); + public final VBStyleCollection nodes = new VBStyleCollection<>(); public DirectNode first; // exit, [source, destination] - public final HashMap> mapShortRangeFinallyPaths = new HashMap>(); + public final HashMap> mapShortRangeFinallyPaths = new HashMap<>(); // exit, [source, destination] - public final HashMap> mapLongRangeFinallyPaths = new HashMap>(); + public final HashMap> mapLongRangeFinallyPaths = new HashMap<>(); // negative if branches (recorded for handling of && and ||) - public final HashMap mapNegIfBranch = new HashMap(); + public final HashMap mapNegIfBranch = new HashMap<>(); // nodes, that are exception exits of a finally block with monitor variable - public final HashMap mapFinallyMonitorExceptionPathExits = new HashMap(); + public final HashMap mapFinallyMonitorExceptionPathExits = new HashMap<>(); public void sortReversePostOrder() { - LinkedList res = new LinkedList(); + LinkedList res = new LinkedList<>(); addToReversePostOrderListIterative(first, res); nodes.clear(); @@ -55,10 +55,10 @@ public class DirectGraph { private static void addToReversePostOrderListIterative(DirectNode root, List lst) { - LinkedList stackNode = new LinkedList(); - LinkedList stackIndex = new LinkedList(); + LinkedList stackNode = new LinkedList<>(); + LinkedList stackIndex = new LinkedList<>(); - HashSet setVisited = new HashSet(); + HashSet setVisited = new HashSet<>(); stackNode.add(root); stackIndex.add(0); @@ -94,10 +94,10 @@ public class DirectGraph { public boolean iterateExprents(ExprentIterator iter) { - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(first); - HashSet setVisited = new HashSet(); + HashSet setVisited = new HashSet<>(); while (!stack.isEmpty()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectNode.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectNode.java index 8a39531..b71330a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectNode.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/DirectNode.java @@ -40,11 +40,11 @@ public class DirectNode { public final Statement statement; - public List exprents = new ArrayList(); + public List exprents = new ArrayList<>(); - public final List succs = new ArrayList(); + public final List succs = new ArrayList<>(); - public final List preds = new ArrayList(); + public final List preds = new ArrayList<>(); public DirectNode(int type, Statement statement, String id) { this.type = type; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java index 971ace5..43c63f6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/FlattenStatementsHelper.java @@ -26,19 +26,19 @@ import java.util.Map.Entry; public class FlattenStatementsHelper { // statement.id, node.id(direct), node.id(continue) - private final Map mapDestinationNodes = new HashMap(); + private final Map mapDestinationNodes = new HashMap<>(); // node.id(source), statement.id(destination), edge type - private final List listEdges = new ArrayList(); + private final List listEdges = new ArrayList<>(); // node.id(exit), [node.id(source), statement.id(destination)] - private final Map> mapShortRangeFinallyPathIds = new HashMap>(); + private final Map> mapShortRangeFinallyPathIds = new HashMap<>(); // node.id(exit), [node.id(source), statement.id(destination)] - private final Map> mapLongRangeFinallyPathIds = new HashMap>(); + private final Map> mapLongRangeFinallyPathIds = new HashMap<>(); // positive if branches - private final Map mapPosIfBranch = new HashMap(); + private final Map mapPosIfBranch = new HashMap<>(); private DirectGraph graph; @@ -55,7 +55,7 @@ public class FlattenStatementsHelper { // dummy exit node Statement dummyexit = root.getDummyExit(); DirectNode node = new DirectNode(DirectNode.NODE_DIRECT, dummyexit, dummyexit.id.toString()); - node.exprents = new ArrayList(); + node.exprents = new ArrayList<>(); graph.nodes.addWithKey(node, node.id); mapDestinationNodes.put(dummyexit.id, new String[]{node.id, null}); @@ -85,9 +85,9 @@ public class FlattenStatementsHelper { } } - LinkedList lstStackStatements = new LinkedList(); + LinkedList lstStackStatements = new LinkedList<>(); - lstStackStatements.add(new StatementStackEntry(root, new LinkedList(), null)); + lstStackStatements.add(new StatementStackEntry(root, new LinkedList<>(), null)); mainloop: while (!lstStackStatements.isEmpty()) { @@ -100,7 +100,7 @@ public class FlattenStatementsHelper { DirectNode node, nd; - List lstSuccEdges = new ArrayList(); + List lstSuccEdges = new ArrayList<>(); DirectNode sourcenode = null; if (statEntry.succEdges == null) { @@ -143,14 +143,14 @@ public class FlattenStatementsHelper { mapDestinationNodes.put(stat.id, new String[]{firstnd.id, null}); graph.nodes.putWithKey(firstnd, firstnd.id); - LinkedList lst = new LinkedList(); + LinkedList lst = new LinkedList<>(); for (Statement st : stat.getStats()) { listEdges.add(new Edge(firstnd.id, st.id, StatEdge.TYPE_REGULAR)); LinkedList stack = stackFinally; if (stat.type == Statement.TYPE_CATCHALL && ((CatchAllStatement)stat).isFinally()) { - stack = new LinkedList(stackFinally); + stack = new LinkedList<>(stackFinally); if (st == stat.getFirst()) { // catch head stack.add(new StackEntry((CatchAllStatement)stat, Boolean.FALSE)); @@ -306,7 +306,7 @@ public class FlattenStatementsHelper { StatEdge edge = lstSuccEdges.get(edgeindex); - LinkedList stack = new LinkedList(stackFinally); + LinkedList stack = new LinkedList<>(stackFinally); int edgetype = edge.getType(); Statement destination = edge.getDestination(); @@ -417,14 +417,14 @@ public class FlattenStatementsHelper { List lst = mapShortRangeFinallyPathIds.get(sourcenode.id); if (lst == null) { - mapShortRangeFinallyPathIds.put(sourcenode.id, lst = new ArrayList()); + mapShortRangeFinallyPathIds.put(sourcenode.id, lst = new ArrayList<>()); } lst.add(new String[]{finallyShortRangeSource.id, destination.id.toString(), finallyShortRangeEntry.id.toString(), isFinallyMonitorExceptionPath ? "1" : null, isContinueEdge ? "1" : null}); lst = mapLongRangeFinallyPathIds.get(sourcenode.id); if (lst == null) { - mapLongRangeFinallyPathIds.put(sourcenode.id, lst = new ArrayList()); + mapLongRangeFinallyPathIds.put(sourcenode.id, lst = new ArrayList<>()); } lst.add(new String[]{finallyLongRangeSource.id, destination.id.toString(), finallyLongRangeEntry.id.toString(), isContinueEdge ? "1" : null}); @@ -458,7 +458,7 @@ public class FlattenStatementsHelper { for (int i = 0; i < 2; i++) { for (Entry> ent : (i == 0 ? mapShortRangeFinallyPathIds : mapLongRangeFinallyPathIds).entrySet()) { - List newLst = new ArrayList(); + List newLst = new ArrayList<>(); List lst = ent.getValue(); for (String[] arr : lst) { @@ -477,8 +477,8 @@ public class FlattenStatementsHelper { if (!newLst.isEmpty()) { (i == 0 ? graph.mapShortRangeFinallyPaths : graph.mapLongRangeFinallyPaths).put(ent.getKey(), - new ArrayList( - new HashSet(newLst))); + new ArrayList<>( + new HashSet<>(newLst))); } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java index 76a973f..7aff2d2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAConstructorSparseEx.java @@ -42,24 +42,24 @@ import java.util.Map.Entry; public class SSAConstructorSparseEx { // node id, var, version - private final HashMap inVarVersions = new HashMap(); + private final HashMap inVarVersions = new HashMap<>(); // node id, var, version (direct branch) - private final HashMap outVarVersions = new HashMap(); + private final HashMap outVarVersions = new HashMap<>(); // node id, var, version (negative branch) - private final HashMap outNegVarVersions = new HashMap(); + private final HashMap outNegVarVersions = new HashMap<>(); // node id, var, version - private final HashMap extraVarVersions = new HashMap(); + private final HashMap extraVarVersions = new HashMap<>(); // (var, version), version - private final HashMap> phi = new HashMap>(); + private final HashMap> phi = new HashMap<>(); // var, version - private final HashMap lastversion = new HashMap(); + private final HashMap lastversion = new HashMap<>(); - private final List startVars = new ArrayList(); + private final List startVars = new ArrayList<>(); // set factory private FastSparseSetFactory factory; @@ -73,18 +73,18 @@ public class SSAConstructorSparseEx { // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot")); // } catch(Exception ex) {ex.printStackTrace();} - HashSet setInit = new HashSet(); + HashSet setInit = new HashSet<>(); for (int i = 0; i < 64; i++) { setInit.add(i); } - factory = new FastSparseSetFactory(setInit); + factory = new FastSparseSetFactory<>(setInit); SFormsFastMapDirect firstmap = createFirstMap(mt); extraVarVersions.put(dgraph.first.id, firstmap); setCatchMaps(root, dgraph, flatthelper); - HashSet updated = new HashSet(); + HashSet updated = new HashSet<>(); do { // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava()); ssaStatements(dgraph, updated); @@ -348,7 +348,7 @@ public class SSAConstructorSparseEx { String exceptionDest = dgraph.mapFinallyMonitorExceptionPathExits.get(predid); boolean isExceptionMonitorExit = (exceptionDest != null && !nodeid.equals(exceptionDest)); - HashSet setLongPathWrapper = new HashSet(); + HashSet setLongPathWrapper = new HashSet<>(); for (FinallyPathWrapper finwraplong : dgraph.mapLongRangeFinallyPaths.get(predid)) { setLongPathWrapper.add(finwraplong.destination + "##" + finwraplong.source); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java index 95cefcf..5beb232 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/sforms/SSAUConstructorSparseEx.java @@ -40,42 +40,42 @@ import java.util.Map.Entry; public class SSAUConstructorSparseEx { // node id, var, version - private final HashMap inVarVersions = new HashMap(); + private final HashMap inVarVersions = new HashMap<>(); //private HashMap>> inVarVersions = new HashMap>>(); // node id, var, version (direct branch) - private final HashMap outVarVersions = new HashMap(); + private final HashMap outVarVersions = new HashMap<>(); //private HashMap>> outVarVersions = new HashMap>>(); // node id, var, version (negative branch) - private final HashMap outNegVarVersions = new HashMap(); + private final HashMap outNegVarVersions = new HashMap<>(); //private HashMap>> outNegVarVersions = new HashMap>>(); // node id, var, version - private final HashMap extraVarVersions = new HashMap(); + private final HashMap extraVarVersions = new HashMap<>(); //private HashMap>> extraVarVersions = new HashMap>>(); // (var, version), version - private final HashMap> phi = new HashMap>(); + private final HashMap> phi = new HashMap<>(); // var, version - private final HashMap lastversion = new HashMap(); + private final HashMap lastversion = new HashMap<>(); // version, protected ranges (catch, finally) - private final HashMap mapVersionFirstRange = new HashMap(); + private final HashMap mapVersionFirstRange = new HashMap<>(); // version, version - private final HashMap phantomppnodes = new HashMap(); // ++ and -- + private final HashMap phantomppnodes = new HashMap<>(); // ++ and -- // node.id, version, version private final HashMap> phantomexitnodes = - new HashMap>(); // finally exits + new HashMap<>(); // finally exits // versions memory dependencies private final VarVersionsGraph ssuversions = new VarVersionsGraph(); // field access vars (exprent id, var id) - private final HashMap mapFieldVars = new HashMap(); + private final HashMap mapFieldVars = new HashMap<>(); // field access counter private int fieldvarcounter = -1; @@ -88,11 +88,11 @@ public class SSAUConstructorSparseEx { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.buildDirectGraph(root); - HashSet setInit = new HashSet(); + HashSet setInit = new HashSet<>(); for (int i = 0; i < 64; i++) { setInit.add(i); } - factory = new FastSparseSetFactory(setInit); + factory = new FastSparseSetFactory<>(setInit); extraVarVersions.put(dgraph.first.id, createFirstMap(mt, root)); @@ -102,7 +102,7 @@ public class SSAUConstructorSparseEx { // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot")); // } catch(Exception ex) {ex.printStackTrace();} - HashSet updated = new HashSet(); + HashSet updated = new HashSet<>(); do { // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava()); ssaStatements(dgraph, updated, false); @@ -426,14 +426,14 @@ public class SSAUConstructorSparseEx { private void createOrUpdatePhiNode(VarVersionPair phivar, FastSparseSet vers, Statement stat) { FastSparseSet versCopy = vers.getCopy(); - HashSet phiVers = new HashSet(); + HashSet phiVers = new HashSet<>(); // take into account the corresponding mm/pp node if existing int ppvers = phantomppnodes.containsKey(phivar) ? phantomppnodes.get(phivar).version : -1; // ssu graph VarVersionNode phinode = ssuversions.nodes.getWithKey(phivar); - List lstPreds = new ArrayList(phinode.preds); + List lstPreds = new ArrayList<>(phinode.preds); if (lstPreds.size() == 1) { // not yet a phi node VarVersionEdge edge = lstPreds.get(0); @@ -454,8 +454,8 @@ public class SSAUConstructorSparseEx { } } - List colnodes = new ArrayList(); - List colpaars = new ArrayList(); + List colnodes = new ArrayList<>(); + List colpaars = new ArrayList<>(); for (Integer ver : versCopy) { @@ -571,7 +571,7 @@ public class SSAUConstructorSparseEx { String exceptionDest = dgraph.mapFinallyMonitorExceptionPathExits.get(predid); boolean isExceptionMonitorExit = (exceptionDest != null && !nodeid.equals(exceptionDest)); - HashSet setLongPathWrapper = new HashSet(); + HashSet setLongPathWrapper = new HashSet<>(); for (List lstwrapper : dgraph.mapLongRangeFinallyPaths.values()) { for (FinallyPathWrapper finwraplong : lstwrapper) { setLongPathWrapper.add(finwraplong.destination + "##" + finwraplong.source); @@ -635,7 +635,7 @@ public class SSAUConstructorSparseEx { // replace phi versions with corresponding phantom ones HashMap mapPhantom = phantomexitnodes.get(predid); if (mapPhantom == null) { - mapPhantom = new HashMap(); + mapPhantom = new HashMap<>(); } SFormsFastMapDirect mapExitVar = mapNew.getCopy(); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java index 812ed10..4b06411 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchAllStatement.java @@ -40,7 +40,7 @@ public class CatchAllStatement extends Statement { private VarExprent monitor; - private final List vars = new ArrayList(); + private final List vars = new ArrayList<>(); // ***************************************************************************** // constructors diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java index 8d56042..db6b79d 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/CatchStatement.java @@ -34,9 +34,9 @@ import java.util.List; public class CatchStatement extends Statement { - private final List> exctstrings = new ArrayList>(); + private final List> exctstrings = new ArrayList<>(); - private final List vars = new ArrayList(); + private final List vars = new ArrayList<>(); // ***************************************************************************** // constructors @@ -58,7 +58,7 @@ public class CatchStatement extends Statement { if (setHandlers.contains(stat)) { stats.addWithKey(stat, stat.id); - exctstrings.add(new ArrayList(edge.getExceptions())); + exctstrings.add(new ArrayList<>(edge.getExceptions())); vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), new VarType(CodeConstants.TYPE_OBJECT, 0, edge.getExceptions().get(0)), @@ -133,7 +133,7 @@ public class CatchStatement extends Statement { } if (hnextcount != 1 && !setHandlers.isEmpty()) { - List lst = new ArrayList(); + List lst = new ArrayList<>(); lst.add(head); lst.addAll(setHandlers); @@ -204,7 +204,7 @@ public class CatchStatement extends Statement { CatchStatement cs = new CatchStatement(); for (List exc : this.exctstrings) { - cs.exctstrings.add(new ArrayList(exc)); + cs.exctstrings.add(new ArrayList<>(exc)); cs.vars.add(new VarExprent(DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.VAR_COUNTER), new VarType(CodeConstants.TYPE_OBJECT, 0, exc.get(0)), (VarProcessor)DecompilerContext.getProperty(DecompilerContext.CURRENT_VAR_PROCESSOR))); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java index ef5ea76..3339218 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DoStatement.java @@ -34,9 +34,9 @@ public class DoStatement extends Statement { private int looptype; - private final List initExprent = new ArrayList(); - private final List conditionExprent = new ArrayList(); - private final List incExprent = new ArrayList(); + private final List initExprent = new ArrayList<>(); + private final List conditionExprent = new ArrayList<>(); + private final List incExprent = new ArrayList<>(); // ***************************************************************************** // constructors @@ -142,7 +142,7 @@ public class DoStatement extends Statement { public List getSequentialObjects() { - List lst = new ArrayList(); + List lst = new ArrayList<>(); switch (looptype) { case LOOP_FOR: diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java index ba82182..f74e745 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/DummyExitStatement.java @@ -32,7 +32,7 @@ public class DummyExitStatement extends Statement { public void addBytecodeOffsets(Collection bytecodeOffsets) { if (bytecodeOffsets != null && !bytecodeOffsets.isEmpty()) { if (bytecode == null) { - bytecode = new HashSet(bytecodeOffsets); + bytecode = new HashSet<>(bytecodeOffsets); } else { bytecode.addAll(bytecodeOffsets); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java index 4f22cf7..b2321e5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/GeneralStatement.java @@ -39,7 +39,7 @@ public class GeneralStatement extends Statement { first = head; stats.addWithKey(head, head.id); - HashSet set = new HashSet(statements); + HashSet set = new HashSet<>(statements); set.remove(head); for (Statement st : set) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java index ab48ce1..9cb7ddb 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/IfStatement.java @@ -52,7 +52,7 @@ public class IfStatement extends Statement { private boolean iffflag; - private final List headexprent = new ArrayList(); // contains IfExprent + private final List headexprent = new ArrayList<>(); // contains IfExprent // ***************************************************************************** // constructors @@ -181,7 +181,7 @@ public class IfStatement extends Statement { boolean ok = (regsize < 2); if (!ok) { - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (DecHelper.isChoiceStatement(head, lst)) { p = lst.remove(0); @@ -295,7 +295,7 @@ public class IfStatement extends Statement { public List getSequentialObjects() { - List lst = new ArrayList(stats); + List lst = new ArrayList<>(stats); lst.add(1, headexprent.get(0)); return lst; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java index 5efa6cf..a199c28 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/Statement.java @@ -73,14 +73,14 @@ public class Statement implements IMatchable { // private fields // ***************************************************************************** - private final Map> mapSuccEdges = new HashMap>(); - private final Map> mapPredEdges = new HashMap>(); + private final Map> mapSuccEdges = new HashMap<>(); + private final Map> mapPredEdges = new HashMap<>(); - private final Map> mapSuccStates = new HashMap>(); - private final Map> mapPredStates = new HashMap>(); + private final Map> mapSuccStates = new HashMap<>(); + private final Map> mapPredStates = new HashMap<>(); // statement as graph - protected final VBStyleCollection stats = new VBStyleCollection(); + protected final VBStyleCollection stats = new VBStyleCollection<>(); protected Statement parent; @@ -88,9 +88,9 @@ public class Statement implements IMatchable { protected List exprents; - protected final HashSet labelEdges = new HashSet(); + protected final HashSet labelEdges = new HashSet<>(); - protected final List varDefinitions = new ArrayList(); + protected final List varDefinitions = new ArrayList<>(); // copied statement, s. deobfuscating of irreducible CFGs private boolean copied = false; @@ -106,7 +106,7 @@ public class Statement implements IMatchable { protected boolean containsMonitorExit; - protected HashSet continueSet = new HashSet(); + protected HashSet continueSet = new HashSet<>(); // ***************************************************************************** // initializers @@ -143,7 +143,7 @@ public class Statement implements IMatchable { List lst = map.get(STATEDGE_DIRECT_ALL); if (lst != null) { - map.put(STATEDGE_ALL, new ArrayList(lst)); + map.put(STATEDGE_ALL, new ArrayList<>(lst)); } else { map.remove(STATEDGE_ALL); @@ -186,7 +186,7 @@ public class Statement implements IMatchable { } // exception edges - Set setHandlers = new HashSet(head.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); + Set setHandlers = new HashSet<>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); for (Statement node : setNodes) { setHandlers.retainAll(node.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); } @@ -260,13 +260,13 @@ public class Statement implements IMatchable { List lst = mapEdges.get(edgetype); if (lst == null) { - mapEdges.put(edgetype, lst = new ArrayList()); + mapEdges.put(edgetype, lst = new ArrayList<>()); } lst.add(edge); List lstStates = mapStates.get(edgetype); if (lstStates == null) { - mapStates.put(edgetype, lstStates = new ArrayList()); + mapStates.put(edgetype, lstStates = new ArrayList<>()); } lstStates.add(direction == DIRECTION_BACKWARD ? edge.getSource() : edge.getDestination()); } @@ -442,7 +442,7 @@ public class Statement implements IMatchable { } public List getReversePostOrderList(Statement stat) { - List res = new ArrayList(); + List res = new ArrayList<>(); addToReversePostOrderListIterative(stat, res); @@ -455,14 +455,14 @@ public class Statement implements IMatchable { public List getPostReversePostOrderList(List lstexits) { - List res = new ArrayList(); + List res = new ArrayList<>(); if (lstexits == null) { StrongConnectivityHelper schelper = new StrongConnectivityHelper(this); lstexits = StrongConnectivityHelper.getExitReps(schelper.getComponents()); } - HashSet setVisited = new HashSet(); + HashSet setVisited = new HashSet<>(); for (Statement exit : lstexits) { addToPostReversePostOrderList(exit, res, setVisited); @@ -500,7 +500,7 @@ public class Statement implements IMatchable { // TODO: make obsolete and remove public List getSequentialObjects() { - return new ArrayList(stats); + return new ArrayList<>(stats); } public void initExprents() { @@ -546,7 +546,7 @@ public class Statement implements IMatchable { first = newstat; } - List lst = new ArrayList(oldstat.getLabelEdges()); + List lst = new ArrayList<>(oldstat.getLabelEdges()); for (int i = lst.size() - 1; i >= 0; i--) { StatEdge edge = lst.get(i); @@ -573,9 +573,9 @@ public class Statement implements IMatchable { private static void addToReversePostOrderListIterative(Statement root, List lst) { - LinkedList stackNode = new LinkedList(); - LinkedList stackIndex = new LinkedList(); - HashSet setVisited = new HashSet(); + LinkedList stackNode = new LinkedList<>(); + LinkedList stackIndex = new LinkedList<>(); + HashSet setVisited = new HashSet<>(); stackNode.add(root); stackIndex.add(0); @@ -697,10 +697,10 @@ public class Statement implements IMatchable { List res; if ((type & (type - 1)) == 0) { res = map.get(type); - res = res == null ? new ArrayList() : new ArrayList(res); + res = res == null ? new ArrayList<>() : new ArrayList<>(res); } else { - res = new ArrayList(); + res = new ArrayList<>(); for (int edgetype : StatEdge.TYPES) { if ((type & edgetype) != 0) { List lst = map.get(edgetype); @@ -721,10 +721,10 @@ public class Statement implements IMatchable { List res; if ((type & (type - 1)) == 0) { res = map.get(type); - res = res == null ? new ArrayList() : new ArrayList(res); + res = res == null ? new ArrayList<>() : new ArrayList<>(res); } else { - res = new ArrayList(); + res = new ArrayList<>(); for (int edgetype : StatEdge.TYPES) { if ((type & edgetype) != 0) { List lst = map.get(edgetype); @@ -739,7 +739,7 @@ public class Statement implements IMatchable { } public Set getNeighboursSet(int type, int direction) { - return new HashSet(getNeighbours(type, direction)); + return new HashSet<>(getNeighbours(type, direction)); } public List getSuccessorEdges(int type) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java index 5916490..d3cc7f2 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SwitchStatement.java @@ -37,15 +37,15 @@ public class SwitchStatement extends Statement { // private fields // ***************************************************************************** - private List caseStatements = new ArrayList(); + private List caseStatements = new ArrayList<>(); - private List> caseEdges = new ArrayList>(); + private List> caseEdges = new ArrayList<>(); - private List> caseValues = new ArrayList>(); + private List> caseValues = new ArrayList<>(); private StatEdge default_edge; - private final List headexprent = new ArrayList(); + private final List headexprent = new ArrayList<>(); // ***************************************************************************** // constructors @@ -65,7 +65,7 @@ public class SwitchStatement extends Statement { stats.addWithKey(head, head.id); // find post node - Set lstNodes = new HashSet(head.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_FORWARD)); + Set lstNodes = new HashSet<>(head.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_FORWARD)); // cluster nodes if (poststat != null) { @@ -88,7 +88,7 @@ public class SwitchStatement extends Statement { if (head.type == Statement.TYPE_BASICBLOCK && head.getLastBasicType() == Statement.LASTBASICTYPE_SWITCH) { - List lst = new ArrayList(); + List lst = new ArrayList<>(); if (DecHelper.isChoiceStatement(head, lst)) { Statement post = lst.remove(0); @@ -160,7 +160,7 @@ public class SwitchStatement extends Statement { public List getSequentialObjects() { - List lst = new ArrayList(stats); + List lst = new ArrayList<>(stats); lst.add(1, headexprent.get(0)); return lst; @@ -200,7 +200,7 @@ public class SwitchStatement extends Statement { public void sortEdgesAndNodes() { - HashMap mapEdgeIndex = new HashMap(); + HashMap mapEdgeIndex = new HashMap<>(); List lstFirstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL); for (int i = 0; i < lstFirstSuccs.size(); i++) { @@ -211,15 +211,15 @@ public class SwitchStatement extends Statement { BasicBlockStatement bbstat = (BasicBlockStatement)first; int[] values = ((SwitchInstruction)bbstat.getBlock().getLastInstruction()).getValues(); - List nodes = new ArrayList(); - List> edges = new ArrayList>(); + List nodes = new ArrayList<>(); + List> edges = new ArrayList<>(); // collect regular edges for (int i = 1; i < stats.size(); i++) { Statement stat = stats.get(i); - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (StatEdge edge : stat.getPredecessorEdges(StatEdge.TYPE_REGULAR)) { if (edge.getSource() == first) { lst.add(mapEdgeIndex.get(edge)); @@ -236,7 +236,7 @@ public class SwitchStatement extends Statement { while (!lstExitEdges.isEmpty()) { StatEdge edge = lstExitEdges.get(0); - List lst = new ArrayList(); + List lst = new ArrayList<>(); for (int i = lstExitEdges.size() - 1; i >= 0; i--) { StatEdge edgeTemp = lstExitEdges.get(i); if (edgeTemp.getDestination() == edge.getDestination() && edgeTemp.getType() == edge.getType()) { @@ -265,7 +265,7 @@ public class SwitchStatement extends Statement { Statement stat = nodes.get(index); if (stat != null) { - HashSet setPreds = new HashSet(stat.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_BACKWARD)); + HashSet setPreds = new HashSet<>(stat.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_BACKWARD)); setPreds.remove(first); if (!setPreds.isEmpty()) { @@ -293,12 +293,12 @@ public class SwitchStatement extends Statement { } // translate indices back into edges - List> lstEdges = new ArrayList>(); - List> lstValues = new ArrayList>(); + List> lstEdges = new ArrayList<>(); + List> lstValues = new ArrayList<>(); for (List lst : edges) { - List lste = new ArrayList(); - List lstv = new ArrayList(); + List lste = new ArrayList<>(); + List lstv = new ArrayList<>(); List lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL); for (Integer in : lst) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SynchronizedStatement.java b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SynchronizedStatement.java index b71531f..04b03fe 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SynchronizedStatement.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/stats/SynchronizedStatement.java @@ -32,7 +32,7 @@ public class SynchronizedStatement extends Statement { private Statement body; - private final List headexprent = new ArrayList(); + private final List headexprent = new ArrayList<>(); // ***************************************************************************** // constructors @@ -106,7 +106,7 @@ public class SynchronizedStatement extends Statement { public List getSequentialObjects() { - List lst = new ArrayList(stats); + List lst = new ArrayList<>(stats); lst.add(1, headexprent.get(0)); return lst; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/CheckTypesResult.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/CheckTypesResult.java index 12bcc32..883a684 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/CheckTypesResult.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/CheckTypesResult.java @@ -23,9 +23,9 @@ import java.util.List; public class CheckTypesResult { - private final List lstMaxTypeExprents = new ArrayList(); + private final List lstMaxTypeExprents = new ArrayList<>(); - private final List lstMinTypeExprents = new ArrayList(); + private final List lstMinTypeExprents = new ArrayList<>(); public void addMaxTypeExprent(Exprent exprent, VarType type) { lstMaxTypeExprents.add(new ExprentTypePair(exprent, type, null)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java index 23b1c5e..a0a14cb 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java @@ -45,9 +45,9 @@ public class VarDefinitionHelper { public VarDefinitionHelper(Statement root, StructMethod mt, VarProcessor varproc) { - mapVarDefStatements = new HashMap(); - mapStatementVars = new HashMap>(); - implDefVars = new HashSet(); + mapVarDefStatements = new HashMap<>(); + mapStatementVars = new HashMap<>(); + implDefVars = new HashSet<>(); this.varproc = varproc; @@ -92,7 +92,7 @@ public class VarDefinitionHelper { } // catch variables are implicitly defined - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { @@ -211,7 +211,7 @@ public class VarDefinitionHelper { private Statement findFirstBlock(Statement stat, Integer varindex) { - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(stat); while (!stack.isEmpty()) { @@ -251,15 +251,15 @@ public class VarDefinitionHelper { private Set initStatement(Statement stat) { - HashMap mapCount = new HashMap(); + HashMap mapCount = new HashMap<>(); List condlst; if (stat.getExprents() == null) { // recurse on children statements - List childVars = new ArrayList(); - List currVars = new ArrayList(); + List childVars = new ArrayList<>(); + List currVars = new ArrayList<>(); for (Object obj : stat.getSequentialObjects()) { if (obj instanceof Statement) { @@ -306,7 +306,7 @@ public class VarDefinitionHelper { } - HashSet set = new HashSet(mapCount.keySet()); + HashSet set = new HashSet<>(mapCount.keySet()); // put all variables defined in this statement into the set for (Entry en : mapCount.entrySet()) { @@ -322,8 +322,8 @@ public class VarDefinitionHelper { private static List getAllVars(List lst) { - List res = new ArrayList(); - List listTemp = new ArrayList(); + List res = new ArrayList<>(); + List listTemp = new ArrayList<>(); for (Exprent expr : lst) { listTemp.addAll(expr.getAllExprents(true)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index 2ba0490..5483f78 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -29,10 +29,10 @@ import java.util.Map.Entry; public class VarProcessor { private final StructMethod method; private final MethodDescriptor methodDescriptor; - private Map mapVarNames = new HashMap(); + private Map mapVarNames = new HashMap<>(); private VarVersionsProcessor varVersions; - private final Map thisVars = new HashMap(); - private final Set externalVars = new HashSet(); + private final Map thisVars = new HashMap<>(); + private final Set externalVars = new HashSet<>(); public VarProcessor(StructMethod mt, MethodDescriptor md) { method = mt; @@ -45,7 +45,7 @@ public class VarProcessor { } public void setVarDefinitions(Statement root) { - mapVarNames = new HashMap(); + mapVarNames = new HashMap<>(); new VarDefinitionHelper(root, method, this).setVarDefinitions(); } @@ -56,10 +56,10 @@ public class VarProcessor { Map mapOriginalVarIndices = varVersions.getMapOriginalVarIndices(); - List listVars = new ArrayList(mapVarNames.keySet()); + List listVars = new ArrayList<>(mapVarNames.keySet()); Collections.sort(listVars, (o1, o2) -> o1.var - o2.var); - Map mapNames = new HashMap(); + Map mapNames = new HashMap<>(); for (VarVersionPair pair : listVars) { String name = mapVarNames.get(pair); @@ -84,7 +84,7 @@ public class VarProcessor { } public void refreshVarNames(VarNamesCollector vc) { - Map tempVarNames = new HashMap(mapVarNames); + Map tempVarNames = new HashMap<>(mapVarNames); for (Entry ent : tempVarNames.entrySet()) { mapVarNames.put(ent.getKey(), vc.getFreeName(ent.getValue())); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java index ea95ed0..a142eee 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarTypeProcessor.java @@ -40,9 +40,9 @@ public class VarTypeProcessor { private final StructMethod method; private final MethodDescriptor methodDescriptor; - private final Map mapExprentMinTypes = new HashMap(); - private final Map mapExprentMaxTypes = new HashMap(); - private final Map mapFinalVars = new HashMap(); + private final Map mapExprentMinTypes = new HashMap<>(); + private final Map mapExprentMaxTypes = new HashMap<>(); + private final Map mapFinalVars = new HashMap<>(); public VarTypeProcessor(StructMethod mt, MethodDescriptor md) { method = mt; @@ -78,7 +78,7 @@ public class VarTypeProcessor { } // catch variables - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); stack.add(root); while (!stack.isEmpty()) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java index 9b57833..d0010ca 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionNode.java @@ -31,9 +31,9 @@ public class VarVersionNode implements IGraphNode { public final int version; - public final Set succs = new HashSet(); + public final Set succs = new HashSet<>(); - public final Set preds = new HashSet(); + public final Set preds = new HashSet<>(); public int flags; @@ -50,7 +50,7 @@ public class VarVersionNode implements IGraphNode { } public List getPredecessors() { - List lst = new ArrayList(preds.size()); + List lst = new ArrayList<>(preds.size()); for (VarVersionEdge edge : preds) { lst.add(edge.source); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java index 8cc11fa..5fd619c 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsGraph.java @@ -27,7 +27,7 @@ public class VarVersionsGraph { public int counter = 0; - public final VBStyleCollection nodes = new VBStyleCollection(); + public final VBStyleCollection nodes = new VBStyleCollection<>(); private GenericDominatorEngine engine; @@ -48,13 +48,13 @@ public class VarVersionsGraph { } else { - HashSet marked = new HashSet(); + HashSet marked = new HashSet<>(); if (domnodes.contains(node)) { return true; } - LinkedList lstNodes = new LinkedList(); + LinkedList lstNodes = new LinkedList<>(); lstNodes.add(node); while (!lstNodes.isEmpty()) { @@ -85,7 +85,7 @@ public class VarVersionsGraph { public void initDominators() { - final HashSet roots = new HashSet(); + final HashSet roots = new HashSet<>(); for (VarVersionNode node : nodes) { if (node.preds.isEmpty()) { @@ -108,12 +108,12 @@ public class VarVersionsGraph { private static LinkedList getReversedPostOrder(Collection roots) { - LinkedList lst = new LinkedList(); - HashSet setVisited = new HashSet(); + LinkedList lst = new LinkedList<>(); + HashSet setVisited = new HashSet<>(); for (VarVersionNode root : roots) { - LinkedList lstTemp = new LinkedList(); + LinkedList lstTemp = new LinkedList<>(); addToReversePostOrderListIterative(root, lstTemp, setVisited); lst.addAll(lstTemp); @@ -124,10 +124,10 @@ public class VarVersionsGraph { private static void addToReversePostOrderListIterative(VarVersionNode root, List lst, HashSet setVisited) { - HashMap> mapNodeSuccs = new HashMap>(); + HashMap> mapNodeSuccs = new HashMap<>(); - LinkedList stackNode = new LinkedList(); - LinkedList stackIndex = new LinkedList(); + LinkedList stackNode = new LinkedList<>(); + LinkedList stackIndex = new LinkedList<>(); stackNode.add(root); stackIndex.add(0); @@ -141,7 +141,7 @@ public class VarVersionsGraph { List lstSuccs = mapNodeSuccs.get(node); if (lstSuccs == null) { - mapNodeSuccs.put(node, lstSuccs = new ArrayList(node.succs)); + mapNodeSuccs.put(node, lstSuccs = new ArrayList<>(node.succs)); } for (; index < lstSuccs.size(); index++) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java index cadaf83..e68282e 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java @@ -35,7 +35,7 @@ import java.util.Map.Entry; public class VarVersionsProcessor { private final StructMethod method; - private Map mapOriginalVarIndices = new HashMap(); + private Map mapOriginalVarIndices = new HashMap<>(); private VarTypeProcessor typeProcessor; public VarVersionsProcessor(StructMethod mt, MethodDescriptor md) { @@ -65,9 +65,9 @@ public class VarVersionsProcessor { private static void mergePhiVersions(SSAConstructorSparseEx ssa, DirectGraph graph) { // collect phi versions - List> lst = new ArrayList>(); + List> lst = new ArrayList<>(); for (Entry> ent : ssa.getPhi().entrySet()) { - Set set = new HashSet(); + Set set = new HashSet<>(); set.add(ent.getKey()); for (Integer version : ent.getValue()) { set.add(new VarVersionPair(ent.getKey().var, version.intValue())); @@ -75,7 +75,7 @@ public class VarVersionsProcessor { for (int i = lst.size() - 1; i >= 0; i--) { Set tset = lst.get(i); - Set intersection = new HashSet(set); + Set intersection = new HashSet<>(set); intersection.retainAll(tset); if (!intersection.isEmpty()) { @@ -87,7 +87,7 @@ public class VarVersionsProcessor { lst.add(set); } - Map phiVersions = new HashMap(); + Map phiVersions = new HashMap<>(); for (Set set : lst) { int min = Integer.MAX_VALUE; for (VarVersionPair paar : set) { @@ -130,7 +130,7 @@ public class VarVersionsProcessor { Map mapExprentMaxTypes = typeProcessor.getMapExprentMaxTypes(); Map mapExprentMinTypes = typeProcessor.getMapExprentMinTypes(); - Set set = new HashSet(mapExprentMinTypes.keySet()); + Set set = new HashSet<>(mapExprentMinTypes.keySet()); for (VarVersionPair paar : set) { VarType type = mapExprentMinTypes.get(paar); VarType maxType = mapExprentMaxTypes.get(paar); @@ -156,13 +156,13 @@ public class VarVersionsProcessor { Map mapExprentMaxTypes = typeProcessor.getMapExprentMaxTypes(); Map mapExprentMinTypes = typeProcessor.getMapExprentMinTypes(); - Map> mapVarVersions = new HashMap>(); + Map> mapVarVersions = new HashMap<>(); for (VarVersionPair pair : mapExprentMinTypes.keySet()) { if (pair.version >= 0) { // don't merge constants Set set = mapVarVersions.get(pair.var); if (set == null) { - set = new HashSet(); + set = new HashSet<>(); mapVarVersions.put(pair.var, set); } set.add(pair.version); @@ -171,12 +171,12 @@ public class VarVersionsProcessor { boolean is_method_static = mt.hasModifier(CodeConstants.ACC_STATIC); - Map mapMergedVersions = new HashMap(); + Map mapMergedVersions = new HashMap<>(); for (Entry> ent : mapVarVersions.entrySet()) { if (ent.getValue().size() > 1) { - List lstVersions = new ArrayList(ent.getValue()); + List lstVersions = new ArrayList<>(ent.getValue()); Collections.sort(lstVersions); for (int i = 0; i < lstVersions.size(); i++) { @@ -234,11 +234,11 @@ public class VarVersionsProcessor { CounterContainer counters = DecompilerContext.getCounterContainer(); - final Map mapVarPaar = new HashMap(); - Map mapOriginalVarIndices = new HashMap(); + final Map mapVarPaar = new HashMap<>(); + Map mapOriginalVarIndices = new HashMap<>(); // map var-version pairs on new var indexes - Set set = new HashSet(mapExprentMinTypes.keySet()); + Set set = new HashSet<>(mapExprentMinTypes.keySet()); for (VarVersionPair pair : set) { if (pair.version >= 0) { diff --git a/src/org/jetbrains/java/decompiler/modules/renamer/ClassWrapperNode.java b/src/org/jetbrains/java/decompiler/modules/renamer/ClassWrapperNode.java index 566508b..ce2a5c1 100644 --- a/src/org/jetbrains/java/decompiler/modules/renamer/ClassWrapperNode.java +++ b/src/org/jetbrains/java/decompiler/modules/renamer/ClassWrapperNode.java @@ -26,7 +26,7 @@ public class ClassWrapperNode { private ClassWrapperNode superclass; - private final List subclasses = new ArrayList(); + private final List subclasses = new ArrayList<>(); public ClassWrapperNode(StructClass cl) { this.classStruct = cl; diff --git a/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java b/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java index 8a431df..71dc351 100644 --- a/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/renamer/ConverterHelper.java @@ -23,12 +23,12 @@ import java.util.Set; public class ConverterHelper implements IIdentifierRenamer { - private static final Set KEYWORDS = new HashSet(Arrays.asList( + private static final Set KEYWORDS = new HashSet<>(Arrays.asList( "abstract", "do", "if", "package", "synchronized", "boolean", "double", "implements", "private", "this", "break", "else", "import", "protected", "throw", "byte", "extends", "instanceof", "public", "throws", "case", "false", "int", "return", "transient", "catch", "final", "interface", "short", "true", "char", "finally", "long", "static", "try", "class", "float", "native", "strictfp", "void", "const", "for", "new", "super", "volatile", "continue", "goto", "null", "switch", "while", "default", "assert", "enum")); - private static final Set RESERVED_WINDOWS_NAMESPACE = new HashSet(Arrays.asList( + private static final Set RESERVED_WINDOWS_NAMESPACE = new HashSet<>(Arrays.asList( "aux", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9")); @@ -36,7 +36,7 @@ public class ConverterHelper implements IIdentifierRenamer { private int classCounter = 0; private int fieldCounter = 0; private int methodCounter = 0; - private final Set setNonStandardClassNames = new HashSet(); + private final Set setNonStandardClassNames = new HashSet<>(); @Override public boolean toBeRenamed(Type elementType, String className, String element, String descriptor) { diff --git a/src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java b/src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java index ee268e6..223065a 100644 --- a/src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java +++ b/src/org/jetbrains/java/decompiler/modules/renamer/IdentifierConverter.java @@ -36,9 +36,9 @@ public class IdentifierConverter implements NewClassNameBuilder { private StructContext context; private IIdentifierRenamer helper; private PoolInterceptor interceptor; - private List rootClasses = new ArrayList(); - private List rootInterfaces = new ArrayList(); - private Map> interfaceNameMaps = new HashMap>(); + private List rootClasses = new ArrayList<>(); + private List rootInterfaces = new ArrayList<>(); + private Map> interfaceNameMaps = new HashMap<>(); public void rename(StructContext context) { try { @@ -76,11 +76,11 @@ public class IdentifierConverter implements NewClassNameBuilder { private void renameClasses() { List lstClasses = getReversePostOrderListIterative(rootClasses); - Map> classNameMaps = new HashMap>(); + Map> classNameMaps = new HashMap<>(); for (ClassWrapperNode node : lstClasses) { StructClass cl = node.getClassStruct(); - Map names = new HashMap(); + Map names = new HashMap<>(); // merge information on super class if (cl.superClass != null) { @@ -113,7 +113,7 @@ public class IdentifierConverter implements NewClassNameBuilder { } private Map processExternalInterface(StructClass cl) { - Map names = new HashMap(); + Map names = new HashMap<>(); for (String ifName : cl.getInterfaceNames()) { Map mapInt = interfaceNameMaps.get(ifName); @@ -135,13 +135,13 @@ public class IdentifierConverter implements NewClassNameBuilder { private void renameInterfaces() { List lstInterfaces = getReversePostOrderListIterative(rootInterfaces); - Map> interfaceNameMaps = new HashMap>(); + Map> interfaceNameMaps = new HashMap<>(); // rename methods and fields for (ClassWrapperNode node : lstInterfaces) { StructClass cl = node.getClassStruct(); - Map names = new HashMap(); + Map names = new HashMap<>(); // merge information on super interfaces for (String ifName : cl.getInterfaceNames()) { @@ -161,7 +161,7 @@ public class IdentifierConverter implements NewClassNameBuilder { private void renameAllClasses() { // order not important - List lstAllClasses = new ArrayList(getReversePostOrderListIterative(rootInterfaces)); + List lstAllClasses = new ArrayList<>(getReversePostOrderListIterative(rootInterfaces)); lstAllClasses.addAll(getReversePostOrderListIterative(rootClasses)); // rename all interfaces and classes @@ -203,7 +203,7 @@ public class IdentifierConverter implements NewClassNameBuilder { } // methods - HashSet setMethodNames = new HashSet(); + HashSet setMethodNames = new HashSet<>(); for (StructMethod md : cl.getMethods()) { setMethodNames.add(md.getName()); } @@ -250,7 +250,7 @@ public class IdentifierConverter implements NewClassNameBuilder { // fields // FIXME: should overloaded fields become the same name? - HashSet setFieldNames = new HashSet(); + HashSet setFieldNames = new HashSet<>(); for (StructField fd : cl.getFields()) { setFieldNames.add(fd.getName()); } @@ -286,12 +286,12 @@ public class IdentifierConverter implements NewClassNameBuilder { } private static List getReversePostOrderListIterative(List roots) { - List res = new ArrayList(); + List res = new ArrayList<>(); - LinkedList stackNode = new LinkedList(); - LinkedList stackIndex = new LinkedList(); + LinkedList stackNode = new LinkedList<>(); + LinkedList stackIndex = new LinkedList<>(); - Set setVisited = new HashSet(); + Set setVisited = new HashSet<>(); for (ClassWrapperNode root : roots) { stackNode.add(root); @@ -326,19 +326,19 @@ public class IdentifierConverter implements NewClassNameBuilder { } private void buildInheritanceTree() { - Map nodes = new HashMap(); + Map nodes = new HashMap<>(); Map classes = context.getClasses(); - List rootClasses = new ArrayList(); - List rootInterfaces = new ArrayList(); + List rootClasses = new ArrayList<>(); + List rootInterfaces = new ArrayList<>(); for (StructClass cl : classes.values()) { if (!cl.isOwn()) { continue; } - LinkedList stack = new LinkedList(); - LinkedList stackSubNodes = new LinkedList(); + LinkedList stack = new LinkedList<>(); + LinkedList stackSubNodes = new LinkedList<>(); stack.add(cl); stackSubNodes.add(null); diff --git a/src/org/jetbrains/java/decompiler/modules/renamer/PoolInterceptor.java b/src/org/jetbrains/java/decompiler/modules/renamer/PoolInterceptor.java index 7d589cc..9b4b6c6 100644 --- a/src/org/jetbrains/java/decompiler/modules/renamer/PoolInterceptor.java +++ b/src/org/jetbrains/java/decompiler/modules/renamer/PoolInterceptor.java @@ -23,9 +23,9 @@ public class PoolInterceptor { private final IIdentifierRenamer helper; - private final HashMap mapOldToNewNames = new HashMap(); + private final HashMap mapOldToNewNames = new HashMap<>(); - private final HashMap mapNewToOldNames = new HashMap(); + private final HashMap mapNewToOldNames = new HashMap<>(); public PoolInterceptor(IIdentifierRenamer helper) { this.helper = helper; diff --git a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java index 69125e1..38c9487 100644 --- a/src/org/jetbrains/java/decompiler/struct/ContextUnit.java +++ b/src/org/jetbrains/java/decompiler/struct/ContextUnit.java @@ -42,11 +42,11 @@ public class ContextUnit { private final IResultSaver resultSaver; private final IDecompiledData decompiledData; - private final List classEntries = new ArrayList(); // class file or jar/zip entry - private final List dirEntries = new ArrayList(); - private final List otherEntries = new ArrayList(); + private final List classEntries = new ArrayList<>(); // class file or jar/zip entry + private final List dirEntries = new ArrayList<>(); + private final List otherEntries = new ArrayList<>(); - private List classes = new ArrayList(); + private List classes = new ArrayList<>(); private Manifest manifest; public ContextUnit(int type, String archivePath, String filename, boolean own, IResultSaver resultSaver, IDecompiledData decompiledData) { @@ -72,7 +72,7 @@ public class ContextUnit { } public void reload(LazyLoader loader) throws IOException { - List lstClasses = new ArrayList(); + List lstClasses = new ArrayList<>(); for (StructClass cl : classes) { String oldName = cl.qualifiedName; diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java index 9a355ab..33dc178 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java @@ -93,7 +93,7 @@ public class StructClass extends StructMember { // fields length = in.readUnsignedShort(); - fields = new VBStyleCollection(); + fields = new VBStyleCollection<>(); for (int i = 0; i < length; i++) { StructField field = new StructField(in, this); fields.addWithKey(field, InterpreterUtil.makeUniqueKey(field.getName(), field.getDescriptor())); @@ -101,7 +101,7 @@ public class StructClass extends StructMember { // methods length = in.readUnsignedShort(); - methods = new VBStyleCollection(); + methods = new VBStyleCollection<>(); for (int i = 0; i < length; i++) { StructMethod method = new StructMethod(in, this); methods.addWithKey(method, InterpreterUtil.makeUniqueKey(method.getName(), method.getDescriptor())); diff --git a/src/org/jetbrains/java/decompiler/struct/StructContext.java b/src/org/jetbrains/java/decompiler/struct/StructContext.java index d47de60..f11e4a4 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructContext.java +++ b/src/org/jetbrains/java/decompiler/struct/StructContext.java @@ -35,8 +35,8 @@ public class StructContext { private final IResultSaver saver; private final IDecompiledData decompiledData; private final LazyLoader loader; - private final Map units = new HashMap(); - private final Map classes = new HashMap(); + private final Map units = new HashMap<>(); + private final Map classes = new HashMap<>(); public StructContext(IResultSaver saver, IDecompiledData decompiledData, LazyLoader loader) { this.saver = saver; diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index bc8b931..3bc93a1 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -47,7 +47,7 @@ public class StructMember { } protected VBStyleCollection readAttributes(DataInputFullStream in, ConstantPool pool) throws IOException { - VBStyleCollection attributes = new VBStyleCollection(); + VBStyleCollection attributes = new VBStyleCollection<>(); int length = in.readUnsignedShort(); for (int i = 0; i < length; i++) { diff --git a/src/org/jetbrains/java/decompiler/struct/StructMethod.java b/src/org/jetbrains/java/decompiler/struct/StructMethod.java index 48362f3..d398c5e 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMethod.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMethod.java @@ -119,7 +119,7 @@ public class StructMethod extends StructMember { @SuppressWarnings("AssignmentToForLoopParameter") private InstructionSequence parseBytecode(DataInputFullStream in, int length, ConstantPool pool) throws IOException { - VBStyleCollection instructions = new VBStyleCollection(); + VBStyleCollection instructions = new VBStyleCollection<>(); int bytecode_version = classStruct.getBytecodeVersion(); @@ -137,7 +137,7 @@ public class StructMethod extends StructMember { opcode = in.readUnsignedByte(); } - List operands = new ArrayList(); + List operands = new ArrayList<>(); if (opcode >= opc_iconst_m1 && opcode <= opc_iconst_5) { operands.add(new Integer(opr_iconst[opcode - opc_iconst_m1])); @@ -331,7 +331,7 @@ public class StructMethod extends StructMember { } // initialize exception table - List lstHandlers = new ArrayList(); + List lstHandlers = new ArrayList<>(); int exception_count = in.readUnsignedShort(); for (int i = 0; i < exception_count; i++) { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java index 1380427..55c138c 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java @@ -39,7 +39,7 @@ public class StructAnnotationAttribute extends StructGeneralAttribute { public static List parseAnnotations(ConstantPool pool, DataInputStream data) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { - List annotations = new ArrayList(len); + List annotations = new ArrayList<>(len); for (int i = 0; i < len; i++) { annotations.add(parseAnnotation(data, pool)); } @@ -57,8 +57,8 @@ public class StructAnnotationAttribute extends StructGeneralAttribute { List values; int len = data.readUnsignedShort(); if (len > 0) { - names = new ArrayList(len); - values = new ArrayList(len); + names = new ArrayList<>(len); + values = new ArrayList<>(len); for (int i = 0; i < len; i++) { names.add(pool.getPrimitiveConstant(data.readUnsignedShort()).getString()); values.add(parseAnnotationElement(data, pool)); @@ -127,7 +127,7 @@ public class StructAnnotationAttribute extends StructGeneralAttribute { List elements = Collections.emptyList(); int len = data.readUnsignedShort(); if (len > 0) { - elements = new ArrayList(len); + elements = new ArrayList<>(len); for (int i = 0; i < len; i++) { elements.add(parseAnnotationElement(data, pool)); } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java index a33c7bb..cee629c 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java @@ -34,7 +34,7 @@ public class StructAnnotationParameterAttribute extends StructGeneralAttribute { int len = data.readUnsignedByte(); if (len > 0) { - paramAnnotations = new ArrayList>(len); + paramAnnotations = new ArrayList<>(len); for (int i = 0; i < len; i++) { List annotations = StructAnnotationAttribute.parseAnnotations(pool, data); paramAnnotations.add(annotations); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java index 597bc7a..f9b5561 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java @@ -26,8 +26,8 @@ import java.util.List; public class StructBootstrapMethodsAttribute extends StructGeneralAttribute { - private final List methodRefs = new ArrayList(); - private final List> methodArguments = new ArrayList>(); + private final List methodRefs = new ArrayList<>(); + private final List> methodArguments = new ArrayList<>(); @Override public void initContent(ConstantPool pool) throws IOException { @@ -39,7 +39,7 @@ public class StructBootstrapMethodsAttribute extends StructGeneralAttribute { int bootstrap_method_ref = data.readUnsignedShort(); int num_bootstrap_arguments = data.readUnsignedShort(); - List list_arguments = new ArrayList(); + List list_arguments = new ArrayList<>(); for (int j = 0; j < num_bootstrap_arguments; ++j) { int bootstrap_argument_ref = data.readUnsignedShort(); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java index 5eda047..946fa3c 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java @@ -32,7 +32,7 @@ public class StructExceptionsAttribute extends StructGeneralAttribute { DataInputStream data = stream(); int len = data.readUnsignedShort(); if (len > 0) { - throwsExceptions = new ArrayList(len); + throwsExceptions = new ArrayList<>(len); for (int i = 0; i < len; i++) { throwsExceptions.add(data.readUnsignedShort()); } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java index 3c9f760..f576ecf 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java @@ -52,7 +52,7 @@ public class StructInnerClassesAttribute extends StructGeneralAttribute { int len = data.readUnsignedShort(); if (len > 0) { - entries = new ArrayList(len); + entries = new ArrayList<>(len); for (int i = 0; i < len; i++) { int innerNameIdx = data.readUnsignedShort(); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java index fceae35..b57d0cf 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java @@ -43,7 +43,7 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { int len = data.readUnsignedShort(); if (len > 0) { - mapVarNames = new HashMap(len); + mapVarNames = new HashMap<>(len); for (int i = 0; i < len; i++) { data.discard(4); int nameIndex = data.readUnsignedShort(); diff --git a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java index a204910..8f07b4c 100644 --- a/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java +++ b/src/org/jetbrains/java/decompiler/struct/consts/ConstantPool.java @@ -40,7 +40,7 @@ public class ConstantPool implements NewClassNameBuilder { public ConstantPool(DataInputStream in) throws IOException { int size = in.readUnsignedShort(); - pool = new ArrayList(size); + pool = new ArrayList<>(size); BitSet[] nextPass = {new BitSet(size), new BitSet(size), new BitSet(size)}; // first dummy constant diff --git a/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java b/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java index 506a51f..546c5a5 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/DataPoint.java @@ -24,9 +24,9 @@ import java.util.List; public class DataPoint { - private List localVariables = new ArrayList(); + private List localVariables = new ArrayList<>(); - private ListStack stack = new ListStack(); + private ListStack stack = new ListStack<>(); public void setVariable(int index, VarType value) { @@ -53,7 +53,7 @@ public class DataPoint { public DataPoint copy() { DataPoint point = new DataPoint(); - point.setLocalVariables(new ArrayList(localVariables)); + point.setLocalVariables(new ArrayList<>(localVariables)); point.setStack(stack.clone()); return point; } diff --git a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java index 2465382..3b5abb4 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/MethodDescriptor.java @@ -41,7 +41,7 @@ public class MethodDescriptor { if (parenth > 1) { String parameters = descriptor.substring(1, parenth); - List lst = new ArrayList(); + List lst = new ArrayList<>(); int indexFrom = -1, ind, len = parameters.length(), index = 0; while (index < len) { diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java index 2ff2954..077814c 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericClassDescriptor.java @@ -22,9 +22,9 @@ public class GenericClassDescriptor { public GenericType superclass; - public final List superinterfaces = new ArrayList(); + public final List superinterfaces = new ArrayList<>(); - public final List fparameters = new ArrayList(); + public final List fparameters = new ArrayList<>(); - public final List> fbounds = new ArrayList>(); + public final List> fbounds = new ArrayList<>(); } diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java index 509783a..a5760a3 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMain.java @@ -142,7 +142,7 @@ public class GenericMain { String param = value.substring(0, to); value = value.substring(to + 1); - List lstBounds = new ArrayList(); + List lstBounds = new ArrayList<>(); while (true) { if (value.charAt(0) == ':') { diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java index 7ef9399..2d38084 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericMethodDescriptor.java @@ -20,13 +20,13 @@ import java.util.List; public class GenericMethodDescriptor { - public final List fparameters = new ArrayList(); + public final List fparameters = new ArrayList<>(); - public final List> fbounds = new ArrayList>(); + public final List> fbounds = new ArrayList<>(); - public final List params = new ArrayList(); + public final List params = new ArrayList<>(); public GenericType ret; - public final List exceptions = new ArrayList(); + public final List exceptions = new ArrayList<>(); } diff --git a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java index d3b3896..ee71f5b 100644 --- a/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java +++ b/src/org/jetbrains/java/decompiler/struct/gen/generics/GenericType.java @@ -32,9 +32,9 @@ public class GenericType { public final int arrayDim; public final String value; - private final List enclosingClasses = new ArrayList(); - private final List arguments = new ArrayList(); - private final List wildcards = new ArrayList(); + private final List enclosingClasses = new ArrayList<>(); + private final List arguments = new ArrayList<>(); + private final List wildcards = new ArrayList<>(); public GenericType(int type, int arrayDim, String value) { this.type = type; diff --git a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java index 40944c1..e0bf3cb 100644 --- a/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java +++ b/src/org/jetbrains/java/decompiler/struct/lazy/LazyLoader.java @@ -27,7 +27,7 @@ import java.util.Map; public class LazyLoader { - private final Map mapClassLinks = new HashMap(); + private final Map mapClassLinks = new HashMap<>(); private final IBytecodeProvider provider; public LazyLoader(IBytecodeProvider provider) { diff --git a/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java b/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java index bdef810..a222d67 100644 --- a/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java +++ b/src/org/jetbrains/java/decompiler/struct/match/MatchEngine.java @@ -36,16 +36,16 @@ public class MatchEngine { private MatchNode rootNode = null; - private final Map variables = new HashMap(); + private final Map variables = new HashMap<>(); - private static final Map stat_properties = new HashMap(); - private static final Map expr_properties = new HashMap(); - private static final Map stat_type = new HashMap(); - private static final Map expr_type = new HashMap(); - private static final Map expr_func_type = new HashMap(); - private static final Map expr_exit_type = new HashMap(); - private static final Map stat_if_type = new HashMap(); - private static final Map expr_const_type = new HashMap(); + private static final Map stat_properties = new HashMap<>(); + private static final Map expr_properties = new HashMap<>(); + private static final Map stat_type = new HashMap<>(); + private static final Map expr_type = new HashMap<>(); + private static final Map expr_func_type = new HashMap<>(); + private static final Map expr_exit_type = new HashMap<>(); + private static final Map stat_if_type = new HashMap<>(); + private static final Map expr_const_type = new HashMap<>(); static { stat_properties.put("type", MatchProperties.STATEMENT_TYPE); @@ -109,11 +109,11 @@ public class MatchEngine { String[] lines = description.split("\n"); int depth = 0; - LinkedList stack = new LinkedList(); + LinkedList stack = new LinkedList<>(); for(String line : lines) { - List properties = new ArrayList(Arrays.asList(line.split("\\s+"))); // split on any number of whitespaces + List properties = new ArrayList<>(Arrays.asList(line.split("\\s+"))); // split on any number of whitespaces if(properties.get(0).isEmpty()) { properties.remove(0); } diff --git a/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java b/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java index f922a3c..8d52aa9 100644 --- a/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java +++ b/src/org/jetbrains/java/decompiler/struct/match/MatchNode.java @@ -48,9 +48,9 @@ public class MatchNode { private final int type; - private final Map rules = new HashMap(); + private final Map rules = new HashMap<>(); - private final List children = new ArrayList(); + private final List children = new ArrayList<>(); public MatchNode(int type) { diff --git a/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java b/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java index 09ce36b..cd568a8 100644 --- a/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java +++ b/src/org/jetbrains/java/decompiler/util/FastFixedSetFactory.java @@ -19,7 +19,7 @@ import java.util.*; public class FastFixedSetFactory { - private final VBStyleCollection colValuesInternal = new VBStyleCollection(); + private final VBStyleCollection colValuesInternal = new VBStyleCollection<>(); private final int dataLength; @@ -46,7 +46,7 @@ public class FastFixedSetFactory { } public FastFixedSet spawnEmptySet() { - return new FastFixedSet(this); + return new FastFixedSet<>(this); } private int getDataLength() { @@ -74,7 +74,7 @@ public class FastFixedSetFactory { public FastFixedSet getCopy() { - FastFixedSet copy = new FastFixedSet(factory); + FastFixedSet copy = new FastFixedSet<>(factory); int arrlength = data.length; int[] cpdata = new int[arrlength]; @@ -201,15 +201,15 @@ public class FastFixedSetFactory { } public Iterator iterator() { - return new FastFixedSetIterator(this); + return new FastFixedSetIterator<>(this); } public Set toPlainSet() { - return toPlainCollection(new HashSet()); + return toPlainCollection(new HashSet<>()); } public List toPlainList() { - return toPlainCollection(new ArrayList()); + return toPlainCollection(new ArrayList<>()); } diff --git a/src/org/jetbrains/java/decompiler/util/FastSetFactory.java b/src/org/jetbrains/java/decompiler/util/FastSetFactory.java index ab80150..94ddfce 100644 --- a/src/org/jetbrains/java/decompiler/util/FastSetFactory.java +++ b/src/org/jetbrains/java/decompiler/util/FastSetFactory.java @@ -22,7 +22,7 @@ import java.util.Set; public class FastSetFactory { - private final VBStyleCollection colValuesInternal = new VBStyleCollection(); + private final VBStyleCollection colValuesInternal = new VBStyleCollection<>(); private int lastBlock; @@ -71,7 +71,7 @@ public class FastSetFactory { } public FastSet spawnEmptySet() { - return new FastSet(this); + return new FastSet<>(this); } public int getLastBlock() { @@ -103,7 +103,7 @@ public class FastSetFactory { public FastSet getCopy() { - FastSet copy = new FastSet(factory); + FastSet copy = new FastSet<>(factory); int arrlength = data.length; int[] cpdata = new int[arrlength]; @@ -363,11 +363,11 @@ public class FastSetFactory { } public Iterator iterator() { - return new FastSetIterator(this); + return new FastSetIterator<>(this); } public Set toPlainSet() { - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); int[] intdata = data; diff --git a/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java b/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java index a4ad9ac..563a404 100644 --- a/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java +++ b/src/org/jetbrains/java/decompiler/util/FastSparseSetFactory.java @@ -22,7 +22,7 @@ import java.util.Set; public class FastSparseSetFactory { - private final VBStyleCollection colValuesInternal = new VBStyleCollection(); + private final VBStyleCollection colValuesInternal = new VBStyleCollection<>(); private int lastBlock; @@ -71,7 +71,7 @@ public class FastSparseSetFactory { } public FastSparseSet spawnEmptySet() { - return new FastSparseSet(this); + return new FastSparseSet<>(this); } public int getLastBlock() { @@ -123,7 +123,7 @@ public class FastSparseSetFactory { System.arraycopy(data, 0, cpdata, 0, arrlength); System.arraycopy(next, 0, cpnext, 0, arrlength); - return new FastSparseSet(factory, cpdata, cpnext); + return new FastSparseSet<>(factory, cpdata, cpnext); } private int[] ensureCapacity(int index) { @@ -410,11 +410,11 @@ public class FastSparseSetFactory { } public Iterator iterator() { - return new FastSparseSetIterator(this); + return new FastSparseSetIterator<>(this); } public Set toPlainSet() { - HashSet set = new HashSet(); + HashSet set = new HashSet<>(); int[] intdata = data; diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java index 5576aa1..a70f0b3 100644 --- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java +++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java @@ -88,7 +88,7 @@ public class InterpreterUtil { return false; } - HashSet set = new HashSet(c1); + HashSet set = new HashSet<>(c1); set.removeAll(c2); return (set.size() == 0); } diff --git a/src/org/jetbrains/java/decompiler/util/ListStack.java b/src/org/jetbrains/java/decompiler/util/ListStack.java index 19c2416..b4aa978 100644 --- a/src/org/jetbrains/java/decompiler/util/ListStack.java +++ b/src/org/jetbrains/java/decompiler/util/ListStack.java @@ -30,7 +30,7 @@ public class ListStack extends ArrayList { } public ListStack clone() { - ListStack newstack = new ListStack(this); + ListStack newstack = new ListStack<>(this); newstack.pointer = this.pointer; return newstack; } diff --git a/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java b/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java index fd9d5c4..0537e4e 100644 --- a/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java +++ b/src/org/jetbrains/java/decompiler/util/SFormsFastMapDirect.java @@ -353,7 +353,7 @@ public class SFormsFastMapDirect { } public List>> entryList() { - List>> list = new ArrayList>>(); + List>> list = new ArrayList<>(); for (int i = 2; i >= 0; i--) { int ikey = 0; diff --git a/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java b/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java index cdc1762..000581d 100644 --- a/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java +++ b/src/org/jetbrains/java/decompiler/util/VBStyleCollection.java @@ -22,9 +22,9 @@ import java.util.HashMap; public class VBStyleCollection extends ArrayList { - private HashMap map = new HashMap(); + private HashMap map = new HashMap<>(); - private ArrayList lstKeys = new ArrayList(); + private ArrayList lstKeys = new ArrayList<>(); public VBStyleCollection() { super(); @@ -32,8 +32,8 @@ public class VBStyleCollection extends ArrayList { public VBStyleCollection(int initialCapacity) { super(initialCapacity); - lstKeys = new ArrayList(initialCapacity); - map = new HashMap(initialCapacity); + lstKeys = new ArrayList<>(initialCapacity); + map = new HashMap<>(initialCapacity); } public VBStyleCollection(Collection c) { @@ -150,10 +150,10 @@ public class VBStyleCollection extends ArrayList { } public VBStyleCollection clone() { - VBStyleCollection c = new VBStyleCollection(); - c.addAll(new ArrayList(this)); - c.setMap(new HashMap(map)); - c.setLstKeys(new ArrayList(lstKeys)); + VBStyleCollection c = new VBStyleCollection<>(); + c.addAll(new ArrayList<>(this)); + c.setMap(new HashMap<>(map)); + c.setLstKeys(new ArrayList<>(lstKeys)); return c; } diff --git a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java index 1621142..df27781 100644 --- a/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java +++ b/test/org/jetbrains/java/decompiler/DecompilerTestFixture.java @@ -52,7 +52,7 @@ public class DecompilerTestFixture { targetDir = new File(tempDir, "decompiled"); assertThat(targetDir.mkdirs()).isTrue(); - Map options = new HashMap(); + Map options = new HashMap<>(); options.put(IFernflowerPreferences.LOG_LEVEL, "warn"); options.put(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES, "1"); options.put(IFernflowerPreferences.REMOVE_SYNTHETIC, "1"); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index f715f4f..d571281 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -118,7 +118,7 @@ public class SingleClassesTest { } private static List collectClasses(File classFile) { - List files = new ArrayList(); + List files = new ArrayList<>(); files.add(classFile); File parent = classFile.getParentFile(); From bc728c9daf2ed8f357a09bc791ffcc5d4edf3aa8 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 9 Sep 2016 12:47:19 +0700 Subject: [PATCH 070/252] Stream.sum() used (via StreamApiMigrationInspection); cleanup --- .../modules/decompiler/EliminateLoopsHelper.java | 7 ++----- .../deobfuscator/IrreducibleCFGDeobfuscator.java | 8 +++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java index 3bad6c6..bf94124 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -135,10 +135,7 @@ public class EliminateLoopsHelper { statLabeled.put(st.id, LowBreakHelper.isBreakEdgeLabeled(lstBreakEdges.get(i).getSource(), st) | statLabeled.get(st.id)); } - int postcount = 0; - for (Boolean val : statLabeled.values()) { - postcount += val ? 1 : 0; - } + int postcount = statLabeled.values().stream().mapToInt(val -> val ? 1 : 0).sum(); if (precount <= postcount) { return false; diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java index 12840f2..9ab65e0 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/deobfuscator/IrreducibleCFGDeobfuscator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -172,15 +172,13 @@ public class IrreducibleCFGDeobfuscator { private static int getStatementSize(Statement statement) { - int res = 0; + int res; if (statement.type == Statement.TYPE_BASICBLOCK) { res = ((BasicBlockStatement)statement).getBlock().getSeq().length(); } else { - for (Statement stat : statement.getStats()) { - res += getStatementSize(stat); - } + res = statement.getStats().stream().mapToInt(IrreducibleCFGDeobfuscator::getStatementSize).sum(); } return res; From 0912e3788ce0a47a0d743f8fe95da3a7a2b87984 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 9 Sep 2016 14:51:12 +0700 Subject: [PATCH 071/252] IDEA-CR-13652 filter(Boolean::booleanValue).count() used --- .../decompiler/modules/decompiler/EliminateLoopsHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java index bf94124..0b145a6 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/EliminateLoopsHelper.java @@ -135,7 +135,7 @@ public class EliminateLoopsHelper { statLabeled.put(st.id, LowBreakHelper.isBreakEdgeLabeled(lstBreakEdges.get(i).getSource(), st) | statLabeled.get(st.id)); } - int postcount = statLabeled.values().stream().mapToInt(val -> val ? 1 : 0).sum(); + long postcount = statLabeled.values().stream().filter(Boolean::booleanValue).count(); if (precount <= postcount) { return false; From 77d6c2906f29492a568eedf5e553767d65350ccc Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 13 Sep 2016 17:04:15 +0300 Subject: [PATCH 072/252] project configuration: use 'test' scope for assertj library used in tests only --- java-decompiler-engine.iml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java-decompiler-engine.iml b/java-decompiler-engine.iml index dc3ddfe..8daf525 100644 --- a/java-decompiler-engine.iml +++ b/java-decompiler-engine.iml @@ -9,6 +9,6 @@ - + \ No newline at end of file From ee83b25d1de324cd84c8fc750cb24a907e6f37c9 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 14 Oct 2016 14:40:00 +0300 Subject: [PATCH 073/252] IDEA-162579 "Unrecognized invocation of " when decompiling kotlin bytecode --- .../decompiler/exps/InvocationExprent.java | 7 +- .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TestKotlinConstructorKt.class | Bin 0 -> 2124 bytes testData/results/TestKotlinConstructorKt.dec | 75 ++++++++++++++++++ testData/src/pkg/TestKotlinConstructor.kt | 8 ++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 testData/classes/pkg/TestKotlinConstructorKt.class create mode 100644 testData/results/TestKotlinConstructorKt.dec create mode 100644 testData/src/pkg/TestKotlinConstructor.kt diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java index 94c1b5d..5b2ffbd 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java @@ -306,7 +306,12 @@ public class InvocationExprent extends Exprent { buf.append("this("); } else { - throw new RuntimeException("Unrecognized invocation of " + CodeConstants.INIT_NAME); + if (instance != null) { + buf.append(instance.toJava(indent, tracer)).append(".("); + } + else { + throw new RuntimeException("Unrecognized invocation of " + CodeConstants.INIT_NAME); + } } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index d571281..48e8b7d 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -89,6 +89,7 @@ public class SingleClassesTest { @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } @Test public void testIllegalVarName() { doTest("pkg/TestIllegalVarName"); } + @Test public void testKotlinConstructor() { doTest("pkg/TestKotlinConstructorKt"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestKotlinConstructorKt.class b/testData/classes/pkg/TestKotlinConstructorKt.class new file mode 100644 index 0000000000000000000000000000000000000000..28766ddcedf80efbaa7dfb3654228025fa6a41a2 GIT binary patch literal 2124 zcmbVNT~`}b6x}xoOqc`;lv09NV~H5T=cJ--f*|tIMgr6ZQA!nuWS~>R3~Oe>qCWL+ z_zU#WH;OEk<%?_iqr`nD2}zN@xYlHH?m6e4v+q9V-1+;TUw;RX#`glZ*A3TOw!N}x z&D)miIhCSkJIkH|A<+3kKhh`4y0tg4w)4U$QX3Qq?%K9MGMV?S70)bB%-iKM&8BT- zhnv)S)Ah0f-Hk9g&v5jevY|i`xY-CW=Q#RH>8_wnAinPdnkZg|b(>PS5?zGQ8|H%f zgR$l;7`u9<>x*#NvO|8aT|RRgb}Ns+b5`QSMZL2@?3XUjbj20CWoI!@hs~zZbSA!^^Cd`DM&=Lpwp@7Iy!BQS1%p*Q;Zm9tkxRG#-qG28xPTj4iDe@&C zfvyr~$h36HZr!!FX$%@o#9@#?b|s8;4pFo@1>37`V<(h-4!ZKSGOie&UeZ0C5dsHC zL5?ryGqB@J;EDF7DnM096PP`J)vKPrQUjfFHP9ERig&o|px8gq$yc~L)E$@%Op0{0 zGgw=-Ooko>{`|SMRfb6mra)W1)>F)@9N48w*YcGxQeUcxVw@Zd3)Gq4f4c#&2 zw6Dt-3C)|9v06FUF`SyFz2ND^eWs|b+Y06$d8|0}et7)_Gu>2!T6JgsbLmW9!k&?o z7wn2tG?q*WqNlo8Fm@_?i^rZ}xvZK%>`BG)%mZV?bWMVtlY`+G)MdK{5F)#hkAAeE zmFus$IHVM%)=ixwoX5z@8Pv^@PW3f9PtbFY-c^jAqF*2riiJ)Q7x)pgQc6(OG8St& z$55sVjP04@kA zaz(2kq+p1Fr>xOF$%N{qST0Z8{rYqAMS&?d|3r43f&L+MqW2Afu_8c7JLxozW&$ zEj>kP^j=2O)YM`Fs^6q)>VM*8s`Q{H foo(Collection list) { + Iterable $receiver$iv = (Iterable)list;// 2 + Collection destination$iv$iv = (Collection)(new ArrayList(CollectionsKt.collectionSizeOrDefault($receiver$iv, 10)));// 10 + Iterator var4 = $receiver$iv.iterator();// 11 + + while(var4.hasNext()) { + Object item$iv$iv = var4.next(); + String it = (String)item$iv$iv;// 12 + Mapping var10000 = new Mapping; + if(it == null) {// 3 + throw new TypeCastException("null cannot be cast to non-null type kotlin.String"); + } + + var10000.((String)it); + Mapping var11 = var10000; + destination$iv$iv.add(var11); + } + + return CollectionsKt.toList((Iterable)((List)destination$iv$iv));// 4 13 + } +} + +class 'TestKotlinConstructorKt' { + method 'foo (Ljava/util/Collection;)Ljava/util/List;' { + 1 17 + 4 17 + d 18 + f 18 + 15 18 + 18 18 + 1b 19 + 20 19 + 24 21 + 2e 22 + 33 22 + 38 23 + 3b 23 + 46 25 + 4d 26 + 52 26 + 53 29 + 56 29 + 59 30 + 5f 31 + 69 34 + 6c 34 + 6f 34 + 72 34 + } +} + +Lines mapping: +2 <-> 18 +3 <-> 26 +4 <-> 35 +10 <-> 19 +11 <-> 20 +12 <-> 24 +13 <-> 35 diff --git a/testData/src/pkg/TestKotlinConstructor.kt b/testData/src/pkg/TestKotlinConstructor.kt new file mode 100644 index 0000000..cb9a363 --- /dev/null +++ b/testData/src/pkg/TestKotlinConstructor.kt @@ -0,0 +1,8 @@ +private fun foo(list: Collection): List { + return list.map { + Mapping(it as String) + }.toList() +} + +class Mapping(c: String) { +} From 7bdec4ffc724ef6730143be200df32ec189ba8a5 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 14 Oct 2016 18:29:00 +0300 Subject: [PATCH 074/252] decompiler: a test for the pull request #394 --- .../java/decompiler/SingleClassesTest.java | 1 + testData/classes/pkg/TestAsserts.class | Bin 0 -> 557 bytes testData/results/TestAsserts.dec | 34 ++++++++++++++++++ testData/src/pkg/TestAsserts.java | 26 ++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 testData/classes/pkg/TestAsserts.class create mode 100644 testData/results/TestAsserts.dec create mode 100644 testData/src/pkg/TestAsserts.java diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 48e8b7d..ac0e891 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -90,6 +90,7 @@ public class SingleClassesTest { @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } @Test public void testIllegalVarName() { doTest("pkg/TestIllegalVarName"); } @Test public void testKotlinConstructor() { doTest("pkg/TestKotlinConstructorKt"); } + @Test public void testAsserts() { doTest("pkg/TestAsserts"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestAsserts.class b/testData/classes/pkg/TestAsserts.class new file mode 100644 index 0000000000000000000000000000000000000000..1c42d7ea7b76a8ad9cbc3fd852ddafcd8f0572ff GIT binary patch literal 557 zcmYjOO-sW-5Ph3$n;4_5t*JFyLGYl0=Hg8e#SaktI4FX>rR^%QH7QBzkMSl7Uc9KF zprChulZdn1YQ4pOrYOj$56I)Dru10@SOMh%QvC}Z4!%TS#0lSIU6 z5QWKRkodKhXfUuULv|$ygLIWapPf5q;2TjxFywZFQ0#XuY9c<8WGbIVks|Fd3>~I^ zy}9SNdo^>V-s-7Xhfyc4i|s)6uB*Yx;<_HMSL@}$tA~g&nN4cc>&=l(NiX8U~CMGSA3f c!Qgk``V%zivMc!OQi^1t*=ur_f+`n(05yVU4FCWD literal 0 HcmV?d00001 diff --git a/testData/results/TestAsserts.dec b/testData/results/TestAsserts.dec new file mode 100644 index 0000000..f260d9e --- /dev/null +++ b/testData/results/TestAsserts.dec @@ -0,0 +1,34 @@ +package pkg; + +public class TestAsserts { + public static int foo() { + byte var0 = 1;// 21 + + assert var0 > 1;// 22 + + assert var0 > 1 && var0 < 5;// 23 + + return 1;// 24 + } +} + +class 'pkg/TestAsserts' { + method 'foo ()I' { + 0 4 + 1 4 + 9 6 + a 6 + 1c 8 + 1d 8 + 21 8 + 22 8 + 2d 10 + 2e 10 + } +} + +Lines mapping: +21 <-> 5 +22 <-> 7 +23 <-> 9 +24 <-> 11 diff --git a/testData/src/pkg/TestAsserts.java b/testData/src/pkg/TestAsserts.java new file mode 100644 index 0000000..29c7480 --- /dev/null +++ b/testData/src/pkg/TestAsserts.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + + +public class TestAsserts { + public static int foo() { + int i=1; + assert i > 1; + assert i> 1 && i < 5; + return 1; + } +} From a7654eb8c9c1c7541218242c898c8ebd39d4aa6d Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 9 Dec 2016 12:39:18 +0100 Subject: [PATCH 075/252] assertj-core-3.6.1 --- build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.xml b/build.xml index 04cbf1a..0b00f6c 100644 --- a/build.xml +++ b/build.xml @@ -13,7 +13,7 @@ - + From fe5260df8a577524d29aeddb53dd7879d053e1e2 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 9 Jan 2017 17:53:02 +0300 Subject: [PATCH 076/252] IDEA-166101 Imports Added for Classes in Same Package --- .../main/collectors/ImportCollector.java | 37 +++++++------------ testData/results/InvalidMethodSignature.dec | 35 +++++++++--------- 2 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java index cb13140..3bc5383 100644 --- a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.struct.StructContext; import java.util.*; -import java.util.Map.Entry; +import java.util.stream.Collectors; public class ImportCollector { private static final String JAVA_LANG_PACKAGE = "java.lang"; @@ -124,26 +124,17 @@ public class ImportCollector { } private List packImports() { - List> lst = new ArrayList<>(mapSimpleNames.entrySet()); - - Collections.sort(lst, (par0, par1) -> { - int res = par0.getValue().compareTo(par1.getValue()); - if (res == 0) { - res = par0.getKey().compareTo(par1.getKey()); - } - return res; - }); - - List res = new ArrayList<>(); - for (Entry ent : lst) { - // exclude a current class or one of the nested ones, java.lang and empty packages - if (!setNotImportedNames.contains(ent.getKey()) && - !JAVA_LANG_PACKAGE.equals(ent.getValue()) && - !ent.getValue().isEmpty()) { - res.add(ent.getValue() + "." + ent.getKey()); - } - } - - return res; + return mapSimpleNames.entrySet().stream() + .filter(ent -> + // exclude the current class or one of the nested ones + // empty, java.lang and the current packages + !setNotImportedNames.contains(ent.getKey()) && + !ent.getValue().isEmpty() && + !JAVA_LANG_PACKAGE.equals(ent.getValue()) && + !ent.getValue().equals(currentPackagePoint) + ) + .sorted(Map.Entry.comparingByValue().thenComparing(Map.Entry.comparingByKey())) + .map(ent -> ent.getValue() + "." + ent.getKey()) + .collect(Collectors.toList()); } } \ No newline at end of file diff --git a/testData/results/InvalidMethodSignature.dec b/testData/results/InvalidMethodSignature.dec index 7b4f8c5..e2a15b3 100644 --- a/testData/results/InvalidMethodSignature.dec +++ b/testData/results/InvalidMethodSignature.dec @@ -4,7 +4,6 @@ import a.a.a.a.a.k; import a.a.a.a.c.c; import a.a.a.a.c.j; import a.a.a.a.e.bg; -import a.a.a.a.e.f.b; import java.io.File; class i implements bg { @@ -27,30 +26,30 @@ class i implements bg { class 'a/a/a/a/e/f/i' { method ' (La/a/a/a/e/f/b;La/a/a/a/c/j;)V' { - 2 14 - 7 15 - e 16 + 2 13 + 7 14 + e 15 } method 'a (La/a/a/a/c/c;La/a/a/a/a/k;Z)V' { - 1 19 - 4 19 - a 19 - f 19 - 12 20 - 15 20 - 1a 20 - 20 21 + 1 18 + 4 18 + a 18 + f 18 + 12 19 + 15 19 + 1a 19 + 20 20 } method 'a (La/a/a/a/c/b;)V' { - 0 24 + 0 23 } } Lines mapping: -0 <-> 25 -1 <-> 15 -2 <-> 20 -3 <-> 21 -4 <-> 22 +0 <-> 24 +1 <-> 14 +2 <-> 19 +3 <-> 20 +4 <-> 21 From 32693c314a77222b46bec900059257af741e8159 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 10 Jan 2017 12:03:26 +0300 Subject: [PATCH 077/252] IDEA-149813 Decompiler has lost generic parameter --- .../java/decompiler/main/ClassWriter.java | 23 ++++---- .../modules/decompiler/exps/NewExprent.java | 23 +++++++- .../java/decompiler/SingleClassesTest.java | 3 +- .../pkg/TestAnonymousSignature$1.class | Bin 0 -> 485 bytes .../pkg/TestAnonymousSignature$2.class | Bin 0 -> 680 bytes .../classes/pkg/TestAnonymousSignature.class | Bin 0 -> 575 bytes testData/results/TestAnonymousSignature.dec | 50 ++++++++++++++++++ testData/src/pkg/TestAnonymousSignature.java | 40 ++++++++++++++ 8 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 testData/classes/pkg/TestAnonymousSignature$1.class create mode 100644 testData/classes/pkg/TestAnonymousSignature$2.class create mode 100644 testData/classes/pkg/TestAnonymousSignature.class create mode 100644 testData/results/TestAnonymousSignature.dec create mode 100644 testData/src/pkg/TestAnonymousSignature.java diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 2386798..d80090d 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -331,16 +331,9 @@ public class ClassWriter { buffer.append("class "); } - GenericClassDescriptor descriptor = null; - if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)cl.getAttributes().getWithKey("Signature"); - if (attr != null) { - descriptor = GenericMain.parseClassSignature(attr.getSignature()); - } - } - buffer.append(node.simpleName); + GenericClassDescriptor descriptor = getGenericClassDescriptor(cl); if (descriptor != null && !descriptor.fparameters.isEmpty()) { appendTypeParameters(buffer, descriptor.fparameters, descriptor.fbounds); } @@ -1051,7 +1044,17 @@ public class ClassWriter { } } - private static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { + public static GenericClassDescriptor getGenericClassDescriptor(StructClass cl) { + if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { + StructGenericSignatureAttribute attr = (StructGenericSignatureAttribute)cl.getAttributes().getWithKey("Signature"); + if (attr != null) { + return GenericMain.parseClassSignature(attr.getSignature()); + } + } + return null; + } + + public static void appendTypeParameters(TextBuffer buffer, List parameters, List> bounds) { buffer.append('<'); for (int i = 0; i < parameters.size(); i++) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index b6a67d2..f72e764 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,12 +21,15 @@ import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; +import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.CheckTypesResult; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.StructClass; import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericClassDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; import org.jetbrains.java.decompiler.util.InterpreterUtil; import org.jetbrains.java.decompiler.util.ListStack; @@ -181,7 +184,23 @@ public class NewExprent extends Exprent { typename = typename.substring(typename.lastIndexOf('.') + 1); } } - buf.append(typename); + + GenericClassDescriptor descriptor = ClassWriter.getGenericClassDescriptor(child.classStruct); + if (descriptor != null) { + if (descriptor.superinterfaces.isEmpty()) { + buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); + } + else { + if (descriptor.superinterfaces.size() > 1) { + DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class signature: " + child.classStruct.qualifiedName, + IFernflowerLogger.Severity.WARN); + } + buf.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(0))); + } + } + else { + buf.append(typename); + } } buf.append('('); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index ac0e891..e7ede30 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -76,6 +76,7 @@ public class SingleClassesTest { @Test public void testInnerLocal() { doTest("pkg/TestInnerLocal"); } @Test public void testInnerLocalPkg() { doTest("pkg/TestInnerLocalPkg"); } @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } + @Test public void testAnonymousSignature() { doTest("pkg/TestAnonymousSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } diff --git a/testData/classes/pkg/TestAnonymousSignature$1.class b/testData/classes/pkg/TestAnonymousSignature$1.class new file mode 100644 index 0000000000000000000000000000000000000000..e60ba5d7aa0a4025a3d899131b7d7ffe2f73f855 GIT binary patch literal 485 zcmZ`#u}%U(6r2aA2Y8B#q9Aq_VBu+E2O%Lu6B4w6&{!?7IaiN8b9-lk-(+KDV&Mn) zQO38LSRih)GcU96P3G;#=i57gb5sj(ux+8_V#h_9u-Z~uC2c~s-WU;_ZZwsIVqa-_ zozBKG9*S|uieuCh6L<9p`GE?wNYa>H*cWG>|hgH*yYOFWSN277Z0Lo ALI3~& literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousSignature$2.class b/testData/classes/pkg/TestAnonymousSignature$2.class new file mode 100644 index 0000000000000000000000000000000000000000..6865a4933a279f16db5d2c259325611cfcba40e6 GIT binary patch literal 680 zcmZ`$O-n*S6g`t4PwkmjX5~jA7^y`@v{M9;0>NsbxM?*$2YdFMC+{QZKecI7&>~v* zqoVsv!jD?aJ$EkWp1Ei4=hxdifOG6e5Wtp#WCVU}E7(zxQjlf{R&}X6H3nay*k$lH z%)VfVwR9=2-BC|i9o{pjqG;x5%q_|e3#}o4;AMl$LAmW%x*SxNE5+sl^QJcxnlsCs zRy=07tq&x3Tu;9`BR1FMI=WGAOvd1jY0dJcW7H}Pk+$htnz+=xsnZ={J9TNw$C2sU zzmJ@F2FT@w)C|)m16RViGy4iMDzey9p&-N%U$m)W6)Hn!d_O4vEu24NP@7T;t6^~4 z7WSOVj~j->M0mjtL+XEBTFi*+k|9~Ro%x=r?P3?FwAKJMgzB9C*EYr1w zZFZx;5q3)!YF$4L2K>U2;%bkF(Yf%&*z@DC>)67I;(#B@N*&A4Rn&CUvB^*yJ=*5) z^4%j9TROJU_+NI+Q2DzHLw^3?>;8}rqJ>m<97fzD|9(sd#hE+DH*d&VL9r7_zi0(`1QCa>!FG zr7ikNDXqRB@s8x(1gTe~r$iy55}7y1k{BpcVFMNH(XFe*6DU9() {// 25 + public int size() { + return super.size();// 28 + } + }); + System.out.println(new Comparator() {// 33 + public int compare(String var1, String var2) { + return 0;// 36 + } + }); + }// 39 +} + +class 'pkg/TestAnonymousSignature$1' { + method 'size ()I' { + 1 9 + 4 9 + } +} + +class 'pkg/TestAnonymousSignature$2' { + method 'compare (Ljava/lang/String;Ljava/lang/String;)I' { + 0 14 + 1 14 + } +} + +class 'pkg/TestAnonymousSignature' { + method 'main ([Ljava/lang/String;)V' { + 0 7 + a 7 + d 12 + 17 12 + 1a 17 + } +} + +Lines mapping: +25 <-> 8 +28 <-> 10 +33 <-> 13 +36 <-> 15 +39 <-> 18 diff --git a/testData/src/pkg/TestAnonymousSignature.java b/testData/src/pkg/TestAnonymousSignature.java new file mode 100644 index 0000000..7837c75 --- /dev/null +++ b/testData/src/pkg/TestAnonymousSignature.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg; + +import java.util.ArrayList; +import java.util.Comparator; + +public class TestAnonymousSignature { + public static void main(String[] args) { + // anonymous from class + System.out.println(new ArrayList() { + @Override + public int size() { + return super.size(); + } + }); + + // anonymous from class + System.out.println(new Comparator() { + @Override + public int compare(String o1, String o2) { + return 0; + } + }); + } +} \ No newline at end of file From 1d331ddd6ddb8fd6638b69237e10a7927b4e5be2 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 10 Jan 2017 14:30:58 +0300 Subject: [PATCH 078/252] cleanup - use Comparator --- .../java/decompiler/modules/decompiler/DomHelper.java | 4 ++-- .../java/decompiler/modules/decompiler/vars/VarProcessor.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java index ea8e537..144db3b 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/DomHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -191,7 +191,7 @@ public class DomHelper { lstPosts.add(stt.id); } - Collections.sort(lstPosts, (o1, o2) -> mapSortOrder.get(o1).compareTo(mapSortOrder.get(o2))); + Collections.sort(lstPosts, Comparator.comparing(mapSortOrder::get)); if (lstPosts.size() > 1 && lstPosts.get(0).intValue() == st.id) { lstPosts.add(lstPosts.remove(0)); diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index 5483f78..b15fed5 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ public class VarProcessor { Map mapOriginalVarIndices = varVersions.getMapOriginalVarIndices(); List listVars = new ArrayList<>(mapVarNames.keySet()); - Collections.sort(listVars, (o1, o2) -> o1.var - o2.var); + Collections.sort(listVars, Comparator.comparingInt(o -> o.var)); Map mapNames = new HashMap<>(); From cb133af01e456e4795c9efa5ee0327d5f21f29b0 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 10 Jan 2017 17:09:09 +0300 Subject: [PATCH 079/252] IDEA-166363 Support LocalVariableTypeTable attribute --- .../modules/decompiler/exps/VarExprent.java | 33 ++++++++- .../modules/decompiler/vars/VarProcessor.java | 8 +++ .../java/decompiler/struct/StructMember.java | 8 ++- .../struct/attr/StructGeneralAttribute.java | 6 +- ...StructLocalVariableTypeTableAttribute.java | 65 ++++++++++++++++++ .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TestLocalsSignature.class | Bin 0 -> 647 bytes testData/results/TestLocalsSignature.dec | 25 +++++++ testData/src/pkg/TestLocalsSignature.java | 27 ++++++++ 9 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java create mode 100644 testData/classes/pkg/TestLocalsSignature.class create mode 100644 testData/results/TestLocalsSignature.dec create mode 100644 testData/src/pkg/TestLocalsSignature.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java index fdd8bb9..a4e25c9 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,14 +21,19 @@ import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; import org.jetbrains.java.decompiler.main.DecompilerContext; import org.jetbrains.java.decompiler.main.TextBuffer; import org.jetbrains.java.decompiler.main.collectors.BytecodeMappingTracer; +import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; +import org.jetbrains.java.decompiler.main.rels.MethodWrapper; import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAttribute; import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericFieldDescriptor; +import org.jetbrains.java.decompiler.struct.gen.generics.GenericMain; import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; -import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import org.jetbrains.java.decompiler.util.InterpreterUtil; @@ -101,7 +106,29 @@ public class VarExprent extends Exprent { if (processor != null && processor.getVarFinal(new VarVersionPair(index, version)) == VarTypeProcessor.VAR_EXPLICIT_FINAL) { buffer.append("final "); } - buffer.append(ExprProcessor.getCastTypeName(getVarType())).append(" "); + boolean generic = false; + if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { + MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); + StructLocalVariableTypeTableAttribute attr = (StructLocalVariableTypeTableAttribute)method.methodStruct.getAttributes() + .getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE); + if (attr != null && processor != null) { + Integer index = processor.getVarOriginalIndex(new VarVersionPair(this.index, version)); + if (index != null) { + String signature = attr.getMapVarSignatures().get(index); + if (signature != null) { + GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(signature); + if (descriptor != null) { + buffer.append(GenericMain.getGenericCastTypeName(descriptor.type)); + generic = true; + } + } + } + } + } + if (!generic) { + buffer.append(ExprProcessor.getCastTypeName(getVarType())); + } + buffer.append(" "); } buffer.append(name == null ? ("var" + index + (version == 0 ? "" : "_" + version)) : name); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index b15fed5..fa79849 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -83,6 +83,14 @@ public class VarProcessor { } } + public Integer getVarOriginalIndex(VarVersionPair pair) { + if (varVersions == null) { + return null; + } + + return varVersions.getMapOriginalVarIndices().get(pair.var); + } + public void refreshVarNames(VarNamesCollector vc) { Map tempVarNames = new HashMap<>(mapVarNames); for (Entry ent : tempVarNames.entrySet()) { diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index 3bc93a1..6f6d09e 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.struct; import org.jetbrains.java.decompiler.code.CodeConstants; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAttribute; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.util.DataInputFullStream; import org.jetbrains.java.decompiler.util.VBStyleCollection; @@ -62,6 +63,11 @@ public class StructMember { StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)attributes.getWithKey(name); table.addLocalVariableTable((StructLocalVariableTableAttribute)attribute); } + else if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE.equals(name) && attributes.containsKey(name)) { + // merge all variable tables + StructLocalVariableTypeTableAttribute table = (StructLocalVariableTypeTableAttribute)attributes.getWithKey(name); + table.add((StructLocalVariableTypeTableAttribute)attribute); + } else { attributes.addWithKey(attribute, attribute.getName()); } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java index 73cc535..98a4bae 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ public class StructGeneralAttribute { public static final String ATTRIBUTE_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations"; public static final String ATTRIBUTE_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations"; public static final String ATTRIBUTE_LOCAL_VARIABLE_TABLE = "LocalVariableTable"; + public static final String ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; public static final String ATTRIBUTE_CONSTANT_VALUE = "ConstantValue"; public static final String ATTRIBUTE_BOOTSTRAP_METHODS = "BootstrapMethods"; public static final String ATTRIBUTE_SYNTHETIC = "Synthetic"; @@ -84,6 +85,9 @@ public class StructGeneralAttribute { else if (ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(name)) { attr = new StructLocalVariableTableAttribute(); } + else if (ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE.equals(name)) { + attr = new StructLocalVariableTypeTableAttribute(); + } else if (ATTRIBUTE_BOOTSTRAP_METHODS.equals(name)) { attr = new StructBootstrapMethodsAttribute(); } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java new file mode 100644 index 0000000..6fb2f4b --- /dev/null +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.java.decompiler.struct.attr; + +import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/* + u2 local_variable_type_table_length; + { u2 start_pc; + u2 length; + u2 name_index; + u2 signature_index; + u2 index; + } local_variable_type_table[local_variable_type_table_length]; +*/ +public class StructLocalVariableTypeTableAttribute extends StructGeneralAttribute { + + private Map mapVarSignatures = Collections.emptyMap(); + + @Override + public void initContent(ConstantPool pool) throws IOException { + DataInputFullStream data = stream(); + + int len = data.readUnsignedShort(); + if (len > 0) { + mapVarSignatures = new HashMap<>(len); + for (int i = 0; i < len; i++) { + data.discard(6); + int signatureIndex = data.readUnsignedShort(); + int varIndex = data.readUnsignedShort(); + mapVarSignatures.put(varIndex, pool.getPrimitiveConstant(signatureIndex).getString()); + } + } + else { + mapVarSignatures = Collections.emptyMap(); + } + } + + public void add(StructLocalVariableTypeTableAttribute attr) { + mapVarSignatures.putAll(attr.getMapVarSignatures()); + } + + public Map getMapVarSignatures() { + return mapVarSignatures; + } +} diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index e7ede30..993b9c4 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -77,6 +77,7 @@ public class SingleClassesTest { @Test public void testInnerLocalPkg() { doTest("pkg/TestInnerLocalPkg"); } @Test public void testInnerSignature() { doTest("pkg/TestInnerSignature"); } @Test public void testAnonymousSignature() { doTest("pkg/TestAnonymousSignature"); } + @Test public void testLocalsSignature() { doTest("pkg/TestLocalsSignature"); } @Test public void testParameterizedTypes() { doTest("pkg/TestParameterizedTypes"); } @Test public void testShadowing() { doTest("pkg/TestShadowing", "pkg/Shadow", "ext/Shadow"); } @Test public void testStringConcat() { doTest("pkg/TestStringConcat"); } diff --git a/testData/classes/pkg/TestLocalsSignature.class b/testData/classes/pkg/TestLocalsSignature.class new file mode 100644 index 0000000000000000000000000000000000000000..8f6b2fb7b5667f4e4b8c5e5104ea4823b0cd412b GIT binary patch literal 647 zcmZ{h%TB^T6o&sPmvR#jqypYA3(&-F+(Af;iK|8z5RAHUfTj*YA*C32ELTKLd;lNH zc&5eRwTn4(Zr}OO^zHrm6~Hm}Vo*^~QH()BA%e9y*0G^tQ^giTxGHSn)))e%a+4u= zI_Q`TDMQ%i`MBRQod$39D3UP-ZQg5gM@WAj47zt>#85DX_md309g7gzKhg}0GHJhW?24Xlh>=T7?Yoxg@KewJ zkJ{?*nKkN<)dypzZJr6aSpE;)M^b765kyIuC)*o;;y8RNHPCBKCKDCg3G85(VfCN= zN&RB!i&occQ)_YooU?eR!;mX|5$o4h%GbmX)9;g?0wxvF86!_8%gBZfW?+wAI!eH%2}$yzNFhxT*?dbdg>2>p%GC@3<1iC^LP)`-Bn2QzNwPqmMi#J)qDR#H cF7h*!ix4Y|6=LSdlhgc&MmKsBiYdr{0PdoU^8f$< literal 0 HcmV?d00001 diff --git a/testData/results/TestLocalsSignature.dec b/testData/results/TestLocalsSignature.dec new file mode 100644 index 0000000..2948bfd --- /dev/null +++ b/testData/results/TestLocalsSignature.dec @@ -0,0 +1,25 @@ +package pkg; + +import java.util.ArrayList; +import java.util.List; + +public class TestLocalsSignature { + public static void main(String[] args) { + List s = new ArrayList();// 24 + s.add("xxx");// 25 + }// 26 +} + +class 'pkg/TestLocalsSignature' { + method 'main ([Ljava/lang/String;)V' { + 7 7 + 9 8 + b 8 + 11 9 + } +} + +Lines mapping: +24 <-> 8 +25 <-> 9 +26 <-> 10 diff --git a/testData/src/pkg/TestLocalsSignature.java b/testData/src/pkg/TestLocalsSignature.java new file mode 100644 index 0000000..9a52d54 --- /dev/null +++ b/testData/src/pkg/TestLocalsSignature.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg; + +import java.util.ArrayList; +import java.util.List; + +public class TestLocalsSignature { + public static void main(String[] args) { + List s = new ArrayList(); + s.add("xxx"); + } +} \ No newline at end of file From 0255eb3ba5b32358b7f6dd92e6036b6857314374 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 10 Jan 2017 18:49:05 +0300 Subject: [PATCH 080/252] IDEA-149813 Decompiler has lost generic parameter - fixed incorrect warning for lambdas --- .../java/decompiler/modules/decompiler/exps/NewExprent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index f72e764..2db188f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -191,7 +191,7 @@ public class NewExprent extends Exprent { buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); } else { - if (descriptor.superinterfaces.size() > 1) { + if (descriptor.superinterfaces.size() > 1 && !lambda) { DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class signature: " + child.classStruct.qualifiedName, IFernflowerLogger.Severity.WARN); } From 6a09fe2524a2226cfec5706e8f62971b6a8f7f3f Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 11 Jan 2017 13:15:21 +0300 Subject: [PATCH 081/252] avoid stream to array copying --- .../java/decompiler/struct/StructMember.java | 4 +--- .../struct/attr/StructAnnDefaultAttribute.java | 7 ++++--- .../struct/attr/StructAnnotationAttribute.java | 7 ++++--- .../attr/StructAnnotationParameterAttribute.java | 8 +++----- .../struct/attr/StructBootstrapMethodsAttribute.java | 7 +++---- .../struct/attr/StructConstantValueAttribute.java | 7 ++++--- .../struct/attr/StructEnclosingMethodAttribute.java | 6 +++--- .../struct/attr/StructExceptionsAttribute.java | 7 +++---- .../struct/attr/StructGeneralAttribute.java | 11 +---------- .../struct/attr/StructGenericSignatureAttribute.java | 7 ++++--- .../struct/attr/StructInnerClassesAttribute.java | 8 +++----- .../struct/attr/StructLineNumberTableAttribute.java | 6 ++---- .../attr/StructLocalVariableTableAttribute.java | 6 ++---- .../attr/StructLocalVariableTypeTableAttribute.java | 4 +--- .../struct/attr/StructSourceFileAttribute.java | 7 ++++--- .../struct/attr/StructTypeAnnotationAttribute.java | 7 +++---- 16 files changed, 45 insertions(+), 64 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index 6f6d09e..1b6866e 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -84,9 +84,7 @@ public class StructMember { in.discard(length); } else { - byte[] data = in.read(length); - attribute.setInfo(data); - attribute.initContent(pool); + attribute.initContent(in, pool); } return attribute; } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java index fbad47e..93a660f 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnDefaultAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; @@ -25,8 +26,8 @@ public class StructAnnDefaultAttribute extends StructGeneralAttribute { private Exprent defaultValue; @Override - public void initContent(ConstantPool pool) throws IOException { - defaultValue = StructAnnotationAttribute.parseAnnotationElement(stream(), pool); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { + defaultValue = StructAnnotationAttribute.parseAnnotationElement(data, pool); } public Exprent getDefaultValue() { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java index 55c138c..500e63c 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,6 +21,7 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; import org.jetbrains.java.decompiler.struct.gen.FieldDescriptor; import org.jetbrains.java.decompiler.struct.gen.VarType; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.DataInputStream; import java.io.IOException; @@ -32,8 +33,8 @@ public class StructAnnotationAttribute extends StructGeneralAttribute { private List annotations; @Override - public void initContent(ConstantPool pool) throws IOException { - annotations = parseAnnotations(pool, stream()); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { + annotations = parseAnnotations(pool, data); } public static List parseAnnotations(ConstantPool pool, DataInputStream data) throws IOException { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java index cee629c..4c2f804 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructAnnotationParameterAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,8 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; -import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -29,9 +29,7 @@ public class StructAnnotationParameterAttribute extends StructGeneralAttribute { private List> paramAnnotations; @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedByte(); if (len > 0) { paramAnnotations = new ArrayList<>(len); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java index f9b5561..e3e203f 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructBootstrapMethodsAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; import org.jetbrains.java.decompiler.struct.consts.PooledConstant; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.DataInputStream; import java.io.IOException; @@ -30,9 +31,7 @@ public class StructBootstrapMethodsAttribute extends StructGeneralAttribute { private final List> methodArguments = new ArrayList<>(); @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int method_number = data.readUnsignedShort(); for (int i = 0; i < method_number; ++i) { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java index 07a5073..9dc636e 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructConstantValueAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; @@ -24,8 +25,8 @@ public class StructConstantValueAttribute extends StructGeneralAttribute { private int index; @Override - public void initContent(ConstantPool pool) throws IOException { - index = stream().readUnsignedShort(); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { + index = data.readUnsignedShort(); } public int getIndex() { diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java index c9b9ebb..f869f96 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructEnclosingMethodAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.struct.consts.LinkConstant; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.DataInputStream; import java.io.IOException; @@ -28,8 +29,7 @@ public class StructEnclosingMethodAttribute extends StructGeneralAttribute { private String methodDescriptor; @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int classIndex = data.readUnsignedShort(); int methodIndex = data.readUnsignedShort(); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java index 946fa3c..0ac54c8 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructExceptionsAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; -import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -28,8 +28,7 @@ public class StructExceptionsAttribute extends StructGeneralAttribute { private List throwsExceptions; @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { throwsExceptions = new ArrayList<>(len); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java index 98a4bae..1e8894a 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGeneralAttribute.java @@ -50,7 +50,6 @@ public class StructGeneralAttribute { public static final String ATTRIBUTE_SOURCE_FILE = "SourceFile"; private String name; - private byte[] info; public static StructGeneralAttribute createAttribute(String name) { StructGeneralAttribute attr; @@ -109,15 +108,7 @@ public class StructGeneralAttribute { return attr; } - protected DataInputFullStream stream() { - return new DataInputFullStream(info); - } - - public void initContent(ConstantPool pool) throws IOException { } - - public void setInfo(byte[] info) { - this.info = info; - } + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { } public String getName() { return name; diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java index 62c892f..a6a1c2b 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructGenericSignatureAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; @@ -24,8 +25,8 @@ public class StructGenericSignatureAttribute extends StructGeneralAttribute { private String signature; @Override - public void initContent(ConstantPool pool) throws IOException { - int index = stream().readUnsignedShort(); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { + int index = data.readUnsignedShort(); signature = pool.getPrimitiveConstant(index).getString(); } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java index f576ecf..d55adec 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructInnerClassesAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,8 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; -import java.io.DataInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -47,9 +47,7 @@ public class StructInnerClassesAttribute extends StructGeneralAttribute { private List entries; @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { entries = new ArrayList<>(len); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLineNumberTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLineNumberTableAttribute.java index 3cd757b..f21cf97 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLineNumberTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLineNumberTableAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,9 +33,7 @@ public class StructLineNumberTableAttribute extends StructGeneralAttribute { private int[] myLineInfo = InterpreterUtil.EMPTY_INT_ARRAY; @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputFullStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort() * 2; if (len > 0) { myLineInfo = new int[len]; diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java index b57d0cf..9564814 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,9 +38,7 @@ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { private Map mapVarNames = Collections.emptyMap(); @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputFullStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { mapVarNames = new HashMap<>(len); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java index 6fb2f4b..96bf630 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java @@ -37,9 +37,7 @@ public class StructLocalVariableTypeTableAttribute extends StructGeneralAttribut private Map mapVarSignatures = Collections.emptyMap(); @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputFullStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { mapVarSignatures = new HashMap<>(len); diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructSourceFileAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructSourceFileAttribute.java index 596d30f..85a7dff 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructSourceFileAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructSourceFileAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; @@ -24,8 +25,8 @@ public class StructSourceFileAttribute extends StructGeneralAttribute { private String fileName; @Override - public void initContent(ConstantPool pool) throws IOException { - int index = stream().readUnsignedShort(); + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { + int index = data.readUnsignedShort(); fileName = pool.getPrimitiveConstant(index).getString(); } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java index 1cb9485..e7d7ac0 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructTypeAnnotationAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.jetbrains.java.decompiler.struct.attr; import org.jetbrains.java.decompiler.modules.decompiler.exps.AnnotationExprent; import org.jetbrains.java.decompiler.modules.decompiler.exps.TypeAnnotation; import org.jetbrains.java.decompiler.struct.consts.ConstantPool; +import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.DataInputStream; import java.io.IOException; @@ -29,9 +30,7 @@ public class StructTypeAnnotationAttribute extends StructGeneralAttribute { private List annotations = Collections.emptyList(); @Override - public void initContent(ConstantPool pool) throws IOException { - DataInputStream data = stream(); - + public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { annotations = new ArrayList<>(len); From 5e45e5ac4071d5b63f591992138d0d309dba66b2 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 12 Jan 2017 15:03:43 +0300 Subject: [PATCH 082/252] IDEA-130708 Incorrect locals names --- .../decompiler/main/rels/ClassWrapper.java | 5 +- .../modules/decompiler/ExprProcessor.java | 25 ++++- .../modules/decompiler/exps/FieldExprent.java | 4 +- .../modules/decompiler/exps/VarExprent.java | 94 ++++++++++++++---- .../modules/decompiler/vars/VarProcessor.java | 3 +- .../decompiler/vars/VarVersionsProcessor.java | 24 +++-- .../java/decompiler/struct/StructMember.java | 2 +- .../StructLocalVariableTableAttribute.java | 65 +++++++++--- ...StructLocalVariableTypeTableAttribute.java | 28 ++---- .../java/decompiler/SingleClassesTest.java | 1 + testData/bulk/pkg/res/Loader.java | 6 +- testData/classes/pkg/TestLocalsNames.class | Bin 0 -> 1707 bytes .../TestAmbiguousCallWithDebugInfo.dec | 2 +- testData/results/TestLocalsNames.dec | 77 ++++++++++++++ testData/src/pkg/TestLocalsNames.java | 35 +++++++ 15 files changed, 296 insertions(+), 75 deletions(-) create mode 100644 testData/classes/pkg/TestLocalsNames.class create mode 100644 testData/results/TestLocalsNames.dec create mode 100644 testData/src/pkg/TestLocalsNames.java diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java index 39adbc9..f5cd82c 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -163,7 +163,8 @@ public class ClassWrapper { if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_VAR_NAMES)) { StructLocalVariableTableAttribute attr = mt.getLocalVariableAttr(); if (attr != null) { - varProc.setDebugVarNames(attr.getMapVarNames()); + // only param names here + varProc.setDebugVarNames(attr.getMapParamNames()); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java index 5931826..cffc5ac 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -341,7 +341,7 @@ public class ExprProcessor implements CodeConstants { case opc_fload: case opc_dload: case opc_aload: - pushEx(stack, exprlist, new VarExprent(instr.getOperand(0), varTypes[instr.opcode - opc_iload], varProcessor)); + pushEx(stack, exprlist, new VarExprent(instr.getOperand(0), varTypes[instr.opcode - opc_iload], varProcessor, bytecode_offset)); break; case opc_iaload: case opc_laload: @@ -371,8 +371,8 @@ public class ExprProcessor implements CodeConstants { case opc_astore: Exprent top = stack.pop(); int varindex = instr.getOperand(0); - AssignmentExprent assign = - new AssignmentExprent(new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor), top, bytecode_offsets); + AssignmentExprent assign = new AssignmentExprent( + new VarExprent(varindex, varTypes[instr.opcode - opc_istore], varProcessor, nextMeaningfulOffset(block, i)), top, bytecode_offsets); exprlist.add(assign); break; case opc_iastore: @@ -624,6 +624,23 @@ public class ExprProcessor implements CodeConstants { } } + private static int nextMeaningfulOffset(BasicBlock block, int index) { + InstructionSequence seq = block.getSeq(); + while (++index < seq.length()) { + switch (seq.getInstr(index).opcode) { + case opc_nop: + case opc_istore: + case opc_lstore: + case opc_fstore: + case opc_dstore: + case opc_astore: + continue; + } + return block.getOldOffset(index); + } + return -1; + } + private void pushEx(ExprentStack stack, List exprlist, Exprent exprent) { pushEx(stack, exprlist, exprent, null); } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java index f1c65d1..472823f 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FieldExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,7 @@ public class FieldExprent extends Exprent { if (method != null) { StructLocalVariableTableAttribute attr = method.methodStruct.getLocalVariableAttr(); if (attr != null) { - return attr.getMapVarNames().containsValue(name); + return attr.containsName(name); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java index a4e25c9..8fc43ff 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -28,6 +28,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; +import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAttribute; import org.jetbrains.java.decompiler.struct.gen.VarType; import org.jetbrains.java.decompiler.struct.gen.generics.GenericFieldDescriptor; @@ -36,6 +37,7 @@ import org.jetbrains.java.decompiler.struct.match.MatchEngine; import org.jetbrains.java.decompiler.struct.match.MatchNode; import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue; import org.jetbrains.java.decompiler.util.InterpreterUtil; +import org.jetbrains.java.decompiler.util.TextUtil; import java.util.ArrayList; import java.util.List; @@ -49,15 +51,21 @@ public class VarExprent extends Exprent { private VarType varType; private boolean definition = false; private VarProcessor processor; + private final int visibleOffset; private int version = 0; private boolean classDef = false; private boolean stack = false; public VarExprent(int index, VarType varType, VarProcessor processor) { + this(index, varType, processor, -1); + } + + public VarExprent(int index, VarType varType, VarProcessor processor, int visibleOffset) { super(EXPRENT_VAR); this.index = index; this.varType = varType; this.processor = processor; + this.visibleOffset = visibleOffset; } @Override @@ -77,7 +85,7 @@ public class VarExprent extends Exprent { @Override public Exprent copy() { - VarExprent var = new VarExprent(index, getVarType(), processor); + VarExprent var = new VarExprent(index, getVarType(), processor, visibleOffset); var.setDefinition(definition); var.setVersion(version); var.setClassDef(classDef); @@ -97,43 +105,85 @@ public class VarExprent extends Exprent { tracer.incrementCurrentSourceLine(buffer.countLines()); } else { - String name = null; - if (processor != null) { - name = processor.getVarName(new VarVersionPair(index, version)); - } + VarVersionPair varVersion = new VarVersionPair(index, version); + String name = getName(varVersion); if (definition) { - if (processor != null && processor.getVarFinal(new VarVersionPair(index, version)) == VarTypeProcessor.VAR_EXPLICIT_FINAL) { + if (processor != null && processor.getVarFinal(varVersion) == VarTypeProcessor.VAR_EXPLICIT_FINAL) { buffer.append("final "); } - boolean generic = false; - if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { - MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); - StructLocalVariableTypeTableAttribute attr = (StructLocalVariableTypeTableAttribute)method.methodStruct.getAttributes() - .getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE); - if (attr != null && processor != null) { - Integer index = processor.getVarOriginalIndex(new VarVersionPair(this.index, version)); - if (index != null) { - String signature = attr.getMapVarSignatures().get(index); + appendDefinitionType(buffer, varVersion); + buffer.append(" "); + } + + buffer.append(name == null ? ("var" + index + (this.version == 0 ? "" : "_" + this.version)) : name); + } + + return buffer; + } + + private String getName(VarVersionPair varVersion) { + String name = null; + if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_VAR_NAMES)) { + MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); + if (method != null) { + StructLocalVariableTableAttribute attr = method.methodStruct.getLocalVariableAttr(); + if (attr != null && processor != null) { + Integer index = processor.getVarOriginalIndex(varVersion); + if (index != null) { + name = attr.getName(index, visibleOffset); + if (name != null && TextUtil.isValidIdentifier(name, method.methodStruct.getClassStruct().getBytecodeVersion())) { + return name; + } + } + } + } + } + if (processor != null) { + name = processor.getVarName(varVersion); + } + return name; + } + + private void appendDefinitionType(TextBuffer buffer, VarVersionPair varVersion) { + if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_VAR_NAMES)) { + MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); + if (method != null) { + Integer originalIndex = null; + if (processor != null) { + originalIndex = processor.getVarOriginalIndex(varVersion); + } + if (originalIndex != null) { + // first try from signature + if (DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_GENERIC_SIGNATURES)) { + StructLocalVariableTypeTableAttribute attr = (StructLocalVariableTypeTableAttribute)method.methodStruct.getAttributes() + .getWithKey(StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE); + if (attr != null) { + String signature = attr.getSignature(originalIndex, visibleOffset); if (signature != null) { GenericFieldDescriptor descriptor = GenericMain.parseFieldSignature(signature); if (descriptor != null) { buffer.append(GenericMain.getGenericCastTypeName(descriptor.type)); - generic = true; + return; } } } } + + // then try from descriptor + StructLocalVariableTableAttribute attr = method.methodStruct.getLocalVariableAttr(); + if (attr != null) { + String descriptor = attr.getDescriptor(originalIndex, visibleOffset); + if (descriptor != null) { + buffer.append(ExprProcessor.getCastTypeName(new VarType(descriptor))); + return; + } + } } - if (!generic) { - buffer.append(ExprProcessor.getCastTypeName(getVarType())); - } - buffer.append(" "); } - buffer.append(name == null ? ("var" + index + (version == 0 ? "" : "_" + version)) : name); } - return buffer; + buffer.append(ExprProcessor.getCastTypeName(getVarType())); } @Override diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index fa79849..7e3da59 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -40,8 +40,9 @@ public class VarProcessor { } public void setVarVersions(RootStatement root) { + VarVersionsProcessor oldProcessor = varVersions; varVersions = new VarVersionsProcessor(method, methodDescriptor); - varVersions.setVarVersions(root); + varVersions.setVarVersions(root, oldProcessor); } public void setVarDefinitions(Statement root) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java index e68282e..4544004 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarVersionsProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ import java.util.Map.Entry; public class VarVersionsProcessor { private final StructMethod method; - private Map mapOriginalVarIndices = new HashMap<>(); + private Map mapOriginalVarIndices = Collections.emptyMap(); private VarTypeProcessor typeProcessor; public VarVersionsProcessor(StructMethod mt, MethodDescriptor md) { @@ -43,7 +43,7 @@ public class VarVersionsProcessor { typeProcessor = new VarTypeProcessor(mt, md); } - public void setVarVersions(RootStatement root) { + public void setVarVersions(RootStatement root, VarVersionsProcessor previousVersionsProcessor) { SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.splitVariables(root, method); @@ -60,7 +60,7 @@ public class VarVersionsProcessor { eliminateNonJavaTypes(typeProcessor); - setNewVarIndices(typeProcessor, graph); + setNewVarIndices(typeProcessor, graph, previousVersionsProcessor); } private static void mergePhiVersions(SSAConstructorSparseEx ssa, DirectGraph graph) { @@ -227,7 +227,7 @@ public class VarVersionsProcessor { } } - private void setNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph) { + private void setNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph, VarVersionsProcessor previousVersionsProcessor) { final Map mapExprentMaxTypes = typeProcessor.getMapExprentMaxTypes(); Map mapExprentMinTypes = typeProcessor.getMapExprentMinTypes(); Map mapFinalVars = typeProcessor.getMapFinalVars(); @@ -286,7 +286,19 @@ public class VarVersionsProcessor { } }); - this.mapOriginalVarIndices = mapOriginalVarIndices; + if (previousVersionsProcessor != null) { + Map oldIndices = previousVersionsProcessor.getMapOriginalVarIndices(); + this.mapOriginalVarIndices = new HashMap<>(mapOriginalVarIndices.size()); + for (Entry entry : mapOriginalVarIndices.entrySet()) { + Integer value = entry.getValue(); + Integer oldValue = oldIndices.get(value); + value = oldValue != null ? oldValue : value; + this.mapOriginalVarIndices.put(entry.getKey(), value); + } + } + else { + this.mapOriginalVarIndices = mapOriginalVarIndices; + } } public VarType getVarType(VarVersionPair pair) { diff --git a/src/org/jetbrains/java/decompiler/struct/StructMember.java b/src/org/jetbrains/java/decompiler/struct/StructMember.java index 1b6866e..86f79b4 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructMember.java +++ b/src/org/jetbrains/java/decompiler/struct/StructMember.java @@ -61,7 +61,7 @@ public class StructMember { if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TABLE.equals(name) && attributes.containsKey(name)) { // merge all variable tables StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)attributes.getWithKey(name); - table.addLocalVariableTable((StructLocalVariableTableAttribute)attribute); + table.add((StructLocalVariableTableAttribute)attribute); } else if (StructGeneralAttribute.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE.equals(name) && attributes.containsKey(name)) { // merge all variable tables diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java index 9564814..0a06ea0 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTableAttribute.java @@ -19,9 +19,12 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; /* u2 local_variable_table_length; @@ -34,32 +37,70 @@ import java.util.Map; } */ public class StructLocalVariableTableAttribute extends StructGeneralAttribute { - - private Map mapVarNames = Collections.emptyMap(); + private List localVariables = Collections.emptyList(); @Override public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { int len = data.readUnsignedShort(); if (len > 0) { - mapVarNames = new HashMap<>(len); + localVariables = new ArrayList<>(len); + for (int i = 0; i < len; i++) { - data.discard(4); + int start_pc = data.readUnsignedShort(); + int length = data.readUnsignedShort(); int nameIndex = data.readUnsignedShort(); - data.discard(2); + int descriptorIndex = data.readUnsignedShort(); int varIndex = data.readUnsignedShort(); - mapVarNames.put(varIndex, pool.getPrimitiveConstant(nameIndex).getString()); + localVariables.add(new LocalVariable(start_pc, + length, + pool.getPrimitiveConstant(nameIndex).getString(), + pool.getPrimitiveConstant(descriptorIndex).getString(), + varIndex)); } } else { - mapVarNames = Collections.emptyMap(); + localVariables = Collections.emptyList(); } } - public void addLocalVariableTable(StructLocalVariableTableAttribute attr) { - mapVarNames.putAll(attr.getMapVarNames()); + public void add(StructLocalVariableTableAttribute attr) { + localVariables.addAll(attr.localVariables); } - public Map getMapVarNames() { - return mapVarNames; + public String getName(int index, int visibleOffset) { + return matchingVars(index, visibleOffset).map(v -> v.name).findFirst().orElse(null); + } + + public String getDescriptor(int index, int visibleOffset) { + return matchingVars(index, visibleOffset).map(v -> v.descriptor).findFirst().orElse(null); + } + + private Stream matchingVars(int index, int visibleOffset) { + return localVariables.stream() + .filter(v -> v.index == index && (visibleOffset >= v.start_pc && visibleOffset < v.start_pc + v.length)); + } + + public boolean containsName(String name) { + return localVariables.stream().anyMatch(v -> v.name == name); + } + + public Map getMapParamNames() { + return localVariables.stream().filter(v -> v.start_pc == 0).collect(Collectors.toMap(v -> v.index, v -> v.name, (n1, n2) -> n2)); + } + + private static class LocalVariable { + final int start_pc; + final int length; + final String name; + final String descriptor; + final int index; + + private LocalVariable(int start_pc, int length, String name, String descriptor, int index) { + this.start_pc = start_pc; + this.length = length; + this.name = name; + this.descriptor = descriptor; + this.index = index; + } } } diff --git a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java index 96bf630..719b333 100644 --- a/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java +++ b/src/org/jetbrains/java/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java @@ -19,9 +19,7 @@ import org.jetbrains.java.decompiler.struct.consts.ConstantPool; import org.jetbrains.java.decompiler.util.DataInputFullStream; import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.Set; /* u2 local_variable_type_table_length; @@ -33,31 +31,19 @@ import java.util.Map; } local_variable_type_table[local_variable_type_table_length]; */ public class StructLocalVariableTypeTableAttribute extends StructGeneralAttribute { - - private Map mapVarSignatures = Collections.emptyMap(); + // store signature instead of descriptor + private final StructLocalVariableTableAttribute backingAttribute = new StructLocalVariableTableAttribute(); @Override public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { - int len = data.readUnsignedShort(); - if (len > 0) { - mapVarSignatures = new HashMap<>(len); - for (int i = 0; i < len; i++) { - data.discard(6); - int signatureIndex = data.readUnsignedShort(); - int varIndex = data.readUnsignedShort(); - mapVarSignatures.put(varIndex, pool.getPrimitiveConstant(signatureIndex).getString()); - } - } - else { - mapVarSignatures = Collections.emptyMap(); - } + backingAttribute.initContent(data, pool); } public void add(StructLocalVariableTypeTableAttribute attr) { - mapVarSignatures.putAll(attr.getMapVarSignatures()); + backingAttribute.add(attr.backingAttribute); } - public Map getMapVarSignatures() { - return mapVarSignatures; + public String getSignature(int index, int visibleOffset) { + return backingAttribute.getDescriptor(index, visibleOffset); } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 993b9c4..6bcf941 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -93,6 +93,7 @@ public class SingleClassesTest { @Test public void testIllegalVarName() { doTest("pkg/TestIllegalVarName"); } @Test public void testKotlinConstructor() { doTest("pkg/TestKotlinConstructorKt"); } @Test public void testAsserts() { doTest("pkg/TestAsserts"); } + @Test public void testLocalsNames() { doTest("pkg/TestLocalsNames"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/bulk/pkg/res/Loader.java b/testData/bulk/pkg/res/Loader.java index b0326dd..22a31bb 100644 --- a/testData/bulk/pkg/res/Loader.java +++ b/testData/bulk/pkg/res/Loader.java @@ -11,9 +11,9 @@ public class Loader { throw new RuntimeException("Resource missing"); } else { try { - File e = new File(resource.toURI()); - byte[] bytes = new byte[(int)e.length()]; - FileInputStream stream = new FileInputStream(e); + File file = new File(resource.toURI()); + byte[] bytes = new byte[(int)file.length()]; + FileInputStream stream = new FileInputStream(file); stream.read(bytes); stream.close(); return new String(bytes, "UTF-8"); diff --git a/testData/classes/pkg/TestLocalsNames.class b/testData/classes/pkg/TestLocalsNames.class new file mode 100644 index 0000000000000000000000000000000000000000..f24049e31bf69e1c88eb16c71e76a89c67bcc8f3 GIT binary patch literal 1707 zcmaJ?-%}e^6#g#RWH-xFNFYF3lvJxG*n+l56|k1l*2=G&_Nn`~xx)0sXx zqvMvuO$Lg_TKv-jL{zjM#I-*@ijum67E12BrJi2;0Q zB94ztjAKGslR7@uamhrYx$=p!E*qFq;}wONPU0l4D(jk#>jpkmD>n>$W}*`_Np3W2 zU`{#b4J;VAX<`wd>-fUN5|(v*DbRh!4g%?ij#mw?I)PnuWm!P12_z<+suNxkh~*0_ z0@}1!mI9q~PE{_{D@ExqE3iO%&MVpOitRgUzVFn+yG|gGnX7GWj4aC_j6lJHU6H{A z_x5F#CWG^HoAy0>#PLS1JFc8qi&B*tAaLU76072l@gTH)E{Yl2>kOf<^Y)8KUAlHH zP$$t8Mxfo7rMe$D_oRDYpkpbtOI!1HEvh!6d04=hEV=tfHkZ7*Uy`aMfu0xYA66Ax z7(~v(3U2B6%EBtvEZoM|0#@sJ1p1<>Ygac$mO|gDZd|E5Zdv*kzQMN^?%+GtI2=}L z7Hs7hMA5=)c-=w?EWiISeCj}_YrgOK0;zgc5uOXZT$4?fa|f(fQ!cgBx`hqgB~PK} zZAGgNS1Um-PeM44KI;PhijpNTLN8&#oR1z$`WO0ci1)LHuQY* z%1&Y9w7{0`2cfL6R+7&m!)2!;=N;Eoy+JTFOwtY&&-A47g=0!~Zpd(|7+NgkDn_w(HA6+51M5;AKzMc(m8lfsbTt zGBfe2j7QQO;F%`o)k$gQd4fguOUT-!U16OA`I%R3+I`S>El~n`P3_@Uc}Wh%n|68U z1$ueSs9pJaWARpm^#G^&Q5oP@Np$tAPNWrsQ0>n5Y0gGC3Xbui9f(IX+VBS7iOAW5 zH)&f<0M6ho&P=?Gcj#fTaEUYNdpguW+XFm#g4h&IZCuN03t1ye&xvgmcF}o&Pj?Zgf>PC`-5mj%nc%EF@`(}ND{e%AzB7wA8~e;RHpDN z&S4lD^F2Amr(5;N1Jt72|dP18!rA2sicK1 literal 0 HcmV?d00001 diff --git a/testData/results/TestAmbiguousCallWithDebugInfo.dec b/testData/results/TestAmbiguousCallWithDebugInfo.dec index 40f1eaf..b697e79 100644 --- a/testData/results/TestAmbiguousCallWithDebugInfo.dec +++ b/testData/results/TestAmbiguousCallWithDebugInfo.dec @@ -11,7 +11,7 @@ class TestAmbiguousCall { IllegalArgumentException iae = new IllegalArgumentException();// 8 this.m1((RuntimeException)iae, "RE");// 9 this.m1(iae, "IAE");// 10 - IllegalArgumentException re = new IllegalArgumentException();// 12 + RuntimeException re = new IllegalArgumentException();// 12 this.m1((RuntimeException)re, "RE");// 13 this.m1((IllegalArgumentException)re, "IAE");// 14 }// 15 diff --git a/testData/results/TestLocalsNames.dec b/testData/results/TestLocalsNames.dec new file mode 100644 index 0000000..a5dc96f --- /dev/null +++ b/testData/results/TestLocalsNames.dec @@ -0,0 +1,77 @@ +package pkg; + +import java.io.File; + +public class TestLocalsNames { + private static void rename(File file, boolean recursively) { + if(file.isDirectory()) {// 22 + long start = System.currentTimeMillis();// 23 + File[] files = file.listFiles();// 25 + File[] var5 = files; + int var6 = files.length; + + for(int var7 = 0; var7 < var6; ++var7) {// 26 + File s = var5[var7]; + File dest = new File(s.getAbsolutePath() + ".tmp");// 27 + + assert s.renameTo(dest) : "unable to rename " + s + " to " + dest;// 28 + } + + long elapsed = System.currentTimeMillis() - start;// 31 + System.out.println("took " + elapsed + "ms (" + elapsed / (long)files.length + "ms per dir)");// 32 + } + + }// 34 +} + +class 'pkg/TestLocalsNames' { + method 'rename (Ljava/io/File;Z)V' { + 1 6 + 4 6 + 7 7 + a 7 + c 8 + f 8 + 13 9 + 17 10 + 18 10 + 1a 12 + 1b 12 + 21 12 + 28 13 + 29 13 + 38 14 + 3e 14 + 43 14 + 49 14 + 55 16 + 66 16 + 70 16 + 7a 16 + 81 12 + 87 19 + 8b 19 + 8c 19 + 8e 20 + 98 20 + a2 20 + ab 20 + ac 20 + ad 20 + b1 20 + b6 20 + b9 20 + bc 23 + } +} + +Lines mapping: +22 <-> 7 +23 <-> 8 +25 <-> 9 +26 <-> 13 +27 <-> 15 +28 <-> 17 +31 <-> 20 +32 <-> 21 +34 <-> 24 diff --git a/testData/src/pkg/TestLocalsNames.java b/testData/src/pkg/TestLocalsNames.java new file mode 100644 index 0000000..0049554 --- /dev/null +++ b/testData/src/pkg/TestLocalsNames.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +import java.io.File; + +public class TestLocalsNames { + private static void rename(File file, boolean recursively) { + if (file.isDirectory()) { + long start = System.currentTimeMillis(); + + File[] files = file.listFiles(); + for (File s : files) { + File dest = new File(s.getAbsolutePath() + ".tmp"); + assert s.renameTo(dest) : "unable to rename " + s + " to " + dest; + } + + long elapsed = System.currentTimeMillis() - start; + System.out.println("took " + elapsed + "ms (" + elapsed / files.length + "ms per dir)"); + } + } +} From abbf2daf305258a2d661edd901bbb41cebf4be75 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 13 Jan 2017 13:04:32 +0300 Subject: [PATCH 083/252] use known list size --- .../java/decompiler/main/rels/NestedClassProcessor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 12e2de1..ef64f2c 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -605,7 +605,7 @@ public class NestedClassProcessor { DirectGraph graph = method.getOrBuildGraph(); if (graph != null) { // something gone wrong, should not be null - List fields = new ArrayList<>(); + List fields = new ArrayList<>(md.params.length); int varIndex = 1; for (int i = 0; i < md.params.length; i++) { // no static methods allowed From 0684264b3a82dd96c86fac422a1a033eef2fe9d0 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 13 Jan 2017 17:57:21 +0300 Subject: [PATCH 084/252] IDEA-166073 Extended Width (long, double) constructors cause issues with anonymous classes --- .../main/rels/NestedClassProcessor.java | 4 +- .../modules/decompiler/exps/NewExprent.java | 24 +- .../java/decompiler/SingleClassesTest.java | 2 + .../pkg/TestAnonymousClassConstructor$1.class | Bin 0 -> 786 bytes .../TestAnonymousClassConstructor$10.class | Bin 0 -> 682 bytes .../TestAnonymousClassConstructor$11.class | Bin 0 -> 596 bytes .../TestAnonymousClassConstructor$12.class | Bin 0 -> 564 bytes .../pkg/TestAnonymousClassConstructor$2.class | Bin 0 -> 788 bytes .../pkg/TestAnonymousClassConstructor$3.class | Bin 0 -> 817 bytes .../pkg/TestAnonymousClassConstructor$4.class | Bin 0 -> 770 bytes .../pkg/TestAnonymousClassConstructor$5.class | Bin 0 -> 708 bytes .../pkg/TestAnonymousClassConstructor$6.class | Bin 0 -> 660 bytes .../pkg/TestAnonymousClassConstructor$7.class | Bin 0 -> 686 bytes .../pkg/TestAnonymousClassConstructor$8.class | Bin 0 -> 655 bytes .../pkg/TestAnonymousClassConstructor$9.class | Bin 0 -> 727 bytes ...onymousClassConstructor$InnerPrivate.class | Bin 0 -> 1201 bytes ...sClassConstructor$InnerPrivateString.class | Bin 0 -> 976 bytes ...nonymousClassConstructor$InnerPublic.class | Bin 0 -> 894 bytes ...usClassConstructor$InnerPublicString.class | Bin 0 -> 670 bytes ...sClassConstructor$InnerStaticPrivate.class | Bin 0 -> 1051 bytes ...Constructor$InnerStaticPrivateString.class | Bin 0 -> 804 bytes ...usClassConstructor$InnerStaticPublic.class | Bin 0 -> 796 bytes ...sConstructor$InnerStaticPublicString.class | Bin 0 -> 549 bytes .../pkg/TestAnonymousClassConstructor.class | Bin 0 -> 3315 bytes .../pkg/TestAnonymousParamNames$1.class | Bin 0 -> 586 bytes .../pkg/TestAnonymousParamNames$Clazz.class | Bin 0 -> 537 bytes .../classes/pkg/TestAnonymousParamNames.class | Bin 0 -> 556 bytes .../results/TestAnonymousClassConstructor.dec | 308 ++++++++++++++++++ testData/results/TestAnonymousParamNames.dec | 22 ++ .../pkg/TestAnonymousClassConstructor.java | 103 ++++++ testData/src/pkg/TestAnonymousParamNames.java | 27 ++ 31 files changed, 471 insertions(+), 19 deletions(-) create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$1.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$10.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$11.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$12.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$2.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$3.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$4.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$5.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$6.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$7.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$8.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$9.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerPrivate.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerPrivateString.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerPublic.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerPublicString.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPrivate.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPrivateString.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPublic.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPublicString.class create mode 100644 testData/classes/pkg/TestAnonymousClassConstructor.class create mode 100644 testData/classes/pkg/TestAnonymousParamNames$1.class create mode 100644 testData/classes/pkg/TestAnonymousParamNames$Clazz.class create mode 100644 testData/classes/pkg/TestAnonymousParamNames.class create mode 100644 testData/results/TestAnonymousClassConstructor.dec create mode 100644 testData/results/TestAnonymousParamNames.dec create mode 100644 testData/src/pkg/TestAnonymousClassConstructor.java create mode 100644 testData/src/pkg/TestAnonymousParamNames.java diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index ef64f2c..b456cc8 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -393,7 +393,7 @@ public class NestedClassProcessor { mergeListSignatures(interPairMask, interMask, true); for (VarFieldPair pair : interPairMask) { - if (pair != null && pair.fieldKey.length() > 0) { + if (pair != null && !pair.fieldKey.isEmpty()) { nestedNode.mapFieldsToVars.put(pair.fieldKey, pair.varPair); } } @@ -406,7 +406,7 @@ public class NestedClassProcessor { method.signatureFields = new ArrayList<>(); for (VarFieldPair pair : entry.getValue()) { - method.signatureFields.add(pair == null ? null : pair.varPair); + method.signatureFields.add(pair == null || pair.fieldKey.isEmpty() ? null : pair.varPair); } } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index 2db188f..f31f3a8 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -210,8 +210,8 @@ public class NewExprent extends Exprent { ClassNode newNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(invSuper.getClassname()); - List sigFields = null; - if (newNode != null) { // own class + List sigFields = child.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, constructor.getStringDescriptor()).signatureFields; + if (sigFields == null && newNode != null) { // own class if (newNode.getWrapper() != null) { sigFields = newNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, invSuper.getStringDescriptor()).signatureFields; } @@ -224,27 +224,17 @@ public class NewExprent extends Exprent { } } + List lstParameters = constructor.getLstParameters(); + + int start = enumConst ? 2 : 0; boolean firstParam = true; - int start = 0, end = invSuper.getLstParameters().size(); - if (enumConst) { - start += 2; - end -= 1; - } - for (int i = start; i < end; i++) { + for (int i = start; i < lstParameters.size(); i++) { if (sigFields == null || sigFields.get(i) == null) { if (!firstParam) { buf.append(", "); } - Exprent param = invSuper.getLstParameters().get(i); - if (param.type == Exprent.EXPRENT_VAR) { - int varIndex = ((VarExprent)param).getIndex(); - if (varIndex > 0 && varIndex <= constructor.getLstParameters().size()) { - param = constructor.getLstParameters().get(varIndex - 1); - } - } - - ExprProcessor.getCastedExprent(param, invSuper.getDescriptor().params[i], buf, indent, true, tracer); + ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buf, indent, true, tracer); firstParam = false; } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 6bcf941..7c1cc33 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -62,6 +62,7 @@ public class SingleClassesTest { @Test public void testEnum() { doTest("pkg/TestEnum"); } @Test public void testDebugSymbols() { doTest("pkg/TestDebugSymbols"); } @Test public void testInvalidMethodSignature() { doTest("InvalidMethodSignature"); } + @Test public void testAnonymousClassConstructor() { doTest("pkg/TestAnonymousClassConstructor"); } @Test public void testInnerClassConstructor() { doTest("pkg/TestInnerClassConstructor"); } @Test public void testInnerClassConstructor11() { doTest("v11/TestInnerClassConstructor"); } @Test public void testTryCatchFinally() { doTest("pkg/TestTryCatchFinally"); } @@ -94,6 +95,7 @@ public class SingleClassesTest { @Test public void testKotlinConstructor() { doTest("pkg/TestKotlinConstructorKt"); } @Test public void testAsserts() { doTest("pkg/TestAsserts"); } @Test public void testLocalsNames() { doTest("pkg/TestLocalsNames"); } + @Test public void testAnonymousParamNames() { doTest("pkg/TestAnonymousParamNames"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$1.class b/testData/classes/pkg/TestAnonymousClassConstructor$1.class new file mode 100644 index 0000000000000000000000000000000000000000..5c42a2c56ec8ee956af92bcf01739e5107a0a354 GIT binary patch literal 786 zcmbVKTT22#7(Jt_o3^Ie{eCm>5}DvbPy`_bkwu{R*2B6EI8UvX{UuPEsUUe5`XcSP`GAw_V)aF`tfU%j*YcG0zEyI2c6A=^i}27^&iEzXdv z3dyf~-6r?ycGIOyx~d%8ZP=dB@mJE&12R|_QgUxF5vOo>^y!%r&C3Xz{y7Fiyrz1d z!_S32c>7P<`TDx!E!dZP6xBt7wvDD8suu1RDpr^-DDXo(BXqlKG8zb+Ms$sH; zeBl`^U)W_`#Ww z;&CEFzvY^~-;%-)ywDD$cTDsXE_iUtP^EtimD zSK6jKFg>pPZ%|VWF&J$j953p?A$Mo`Y1M-!HONeo4v9t5X2|qp=-JK%R|jtWIo{r_ z`9RsZb78yE=VEl}1YW1NPIxQNr7nlLJuS3h_HbdbT ztTMF{<#BaoKWoKnY6FRy+62n9eT^Oh%jeZB$|BK`BAq7dhN215*~acOSfgChUJ!dC zAchS6lM%g+8L}Hup)3r{l1C{~K~*k`9P*T*tOAO}i(`(w80JwTtziL+6a&R#6#M!V Hx`xyzvQMd0 literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$11.class b/testData/classes/pkg/TestAnonymousClassConstructor$11.class new file mode 100644 index 0000000000000000000000000000000000000000..4cc1fb9b1800a7e384d2278b8dbde240af2bf272 GIT binary patch literal 596 zcma)3(MrQG6g_F{I%joS-KK&MipZwu9QdLWL56}*McCMT)|D;VCDNvXpXHO_gCF2W zi8q^XLuVk|d(OEzxi|Uzdj9}$g3SVKth!ipQDVrQ3n}ykL#Y}(@Mm6+xg6BnIuUZv ztaTZjmg+|g#X!jDE*tftq{DkLF@B&z9(Q>n4E`Y2Xl+ zM5(@%O1_L#mX5WSlBrIzP^)CO(P%O-D)y)QU?{XzmW0u@FgNe~>2zeqpoXtx7^{@V zxQ+Bs^<7jvtYgE2gE@xX|8&G~I=gH2Q2P1AWJ8$01yxrM-|9E`^aEi@5Of1`2u~BBoo(n1T1w*FRY1an~R#Oc*L!m1q zzlkRv5Bshc5L4)N&zA%GXs}FDlgMKJk zjEu%0pC!~HY>~J3x3^xvo(USTY0svG4de({(pDQYn5Bq{;b1P!+n7gzvL+UYH&8^0 VyoE(9Ay248oIxI>V-mZH+$UZDiWvX^ literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$2.class b/testData/classes/pkg/TestAnonymousClassConstructor$2.class new file mode 100644 index 0000000000000000000000000000000000000000..fb671b11eb6b4db812e816cfdd8fcd8e4bb87fad GIT binary patch literal 788 zcma)4+fKqj5IqZp3Ra6KUhu}vgiC@#e8ZR+q6q|yi3FbuG_VT0rY$6XmJi0n2S31% zGR{`Rqp+Ll%$d%aotfRQ?~hLa=g3A7#BLNC_H-n5>@$SD5qEQE4B6K6)9|!oyWW+M z;$gI0-NB;;?r_fs*hPDO_Cl-gCTk^r%vC#;p)81zulD| ztr@Y+YtbJ|my2QB_C|7`0-*oG(*bV$f&T%uu^-tYgMj9WR8?p zkN3JARRbPHRjncuwtb_+eWD*oCCwqjZm|b`?Ur|VCE%)6shd!$)_$qM;8b-}FbvnE z5*O|JYY|@Y>ws2rHSP1D!9!{D??uN7WbjUv5@D=JP`cW^dtsaOGUDcb%3#RUbvyLM ziL{NE{~de7PC(X&)ef+g@vRG=kSR#GJpN{q5_g4IOd$3>&OLPw%x{@rLweDF& zuZw<)X+meTpQPxO*Pg-3>+A)IC(0AZ&^Hyc2Qfg{Rw5ofLliBt^=vf{!^qN!Bt|Gp aAcs+k4#qH!K|(X%JqX6DGt_;-Ccr08bl?U6 literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$4.class b/testData/classes/pkg/TestAnonymousClassConstructor$4.class new file mode 100644 index 0000000000000000000000000000000000000000..74820acdeed679038981bd12419950d1314bc138 GIT binary patch literal 770 zcma)4TT22_5dMy?ZrbLp>|!@>ff`hTZ$=POpjZTk@9VngDLp54k3v7IhX{J;2lS(& zIZICw>B8*HeEZFunQzbM*ZT*621+r6u^oqj9TPbdy9`k^=6?B%q11hP9G%{~zPc1r zJWu7!Z%u69Z%N@RZ{{fJHHm)C1y>ggmC6$QPP^J?Fj{ixG9NZS&vCE0KCk%ib|(+^ zoT`&o!kI{)i_wj%#&T$4-@*Y7EkqEtV4^@;EtIOYC Xz$Uh^Mp2HwgvskiqkA+-KFIJ5DGbLN literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$5.class b/testData/classes/pkg/TestAnonymousClassConstructor$5.class new file mode 100644 index 0000000000000000000000000000000000000000..c32a742c0732fffdf98b7230aa7b6f1d1b9cba0d GIT binary patch literal 708 zcma)4TT22#6#mBD+%n6uG_wnI11-peddUbv3W6;H#rJU?bZVW6-BIXg^%V5b59mil zXIJ04=)lZ5=R4n=IhXnTdj9}$imenZtTG$R2~X>B*2GeXEoR>OK!cLFR$`{M4;9 zMQE;+Rxf=$2xDJetIz}k&*)(Ptj55IoBf#vL#m+%fhTTc^ziP#fsUgpDBo-4`8uR3 z?u6;-j)S!{3Rq9W#syD#tg|MX*EI3WRY-M-;f)^D*ylh literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$6.class b/testData/classes/pkg/TestAnonymousClassConstructor$6.class new file mode 100644 index 0000000000000000000000000000000000000000..2dde5175e4c2ee33081bf9db238cda9691302818 GIT binary patch literal 660 zcma)3-Alqy6#rc}-LjQsUuv0sg8EPi(u)yo$q=U2H$2sS2_neQRI-yxD71=A;3-JUDdZ*&bJWS$yaj%I5ERv#X nSXhelCYF(*tcDfx6Iex-P{$h9ktSB4OoA}#(a6ma?!+2jN^z+! literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$7.class b/testData/classes/pkg/TestAnonymousClassConstructor$7.class new file mode 100644 index 0000000000000000000000000000000000000000..6f08d90d5ead067f7d06644b5ce93123fd7da270 GIT binary patch literal 686 zcma)4+e*Vg5Ix((#@1-tc)wJIWv29_MBng-d|n;>|-?p4RcxOm^ZLsV38pm4R~1EW!SXuZu|AN7e>cI ziie?$!1D*Ve#&6TUduRe zy;H6Z-uTn@j&ebIPlW5skX&4N(LnYLESp$C(Zm?iCJczIM?NTK2%XcqM$xR+p1`WL?PsJO zDNi9w|8&AGVuG;hL_B(@C@Q4-sct56$kPrD1pKtE~j#17aiIpr2teRLevCfbVCc>{CG3@pp?#G9H?g!^m z$)~9b{kCiSep^XD@Ioh0-U*eT3Mqm!hFa|(_1#W=z+kl1h%*#=Lh|cyI^rTG+z2g%r{jOw7=(VpmmdG3>`zMVGt@hpuoKa=%z5)=dtf zm-ORL*6IV4>4gn?Y*sAlfiXMizmcRlQDH~YAGG+;tNJ~=IpH?@3FBsyWe*gdg literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$9.class b/testData/classes/pkg/TestAnonymousClassConstructor$9.class new file mode 100644 index 0000000000000000000000000000000000000000..ab22f7bda022e3c1564cef3d20d8c26f22d29b7c GIT binary patch literal 727 zcma)4%TB^T6g>l#@~DFKf$t|KfJR)nkYG#<(S!tz35IJS*O|qa4NE ztElI5_sc(q;;&ye$Ewn4u3h{|H(A!dX0H6*t4bFebZrc}L99^F%W6cAi8RFwp%xOv z0CLscXRzwt3ldM1CXl6fDkkqBM_3CH4Hl*-YNX|~SPppl6?bJ4_Y|x`laNs$LgOMEL5|P& zx!C0*ub_aUgpz~@3}Nr1>86SdJI%qTUg6kqy?x8JKA+mYTkGqtTeB_KbNr5HI~6kD zGcD7rGHBWo_KkX`#UR$~uEDV0G%e%6KW!V%vEJ^}PONEn^nOcsOun9OikuLGTDL62 zdFPmCx<{syWkATF)8gXbseb{8In!x0XtZh6B|Kz!yIc-S#41&IqQa2sC=5$nP-%rB z#YivZ&7d6FzSA+@n7lCCbK8(V(a&@hQCwEBhIOu$88-QDp|4xL!jb2gR`0cM_Pd6o z;t?KG$~mq);o_-^XLv55qGAs(81f4nf3B7c(OIa&_KDH)=<8XGL1hVPyi8$zFfgnx zLqcn0nlr3(w5eme+J(c)Jo|)JpLZPb>`4TM4eg>K1>9Pg1l7@Ei2sjR3rV_wt8^h* zG|Kxznm{kL3G}Jc%0~z*G^ew_&@~0bS7tW$+$QM zn}rDn?$rRk9PpI?!ppcbg_kMI3A~Ig4$r}`jUDn3h#t>5jZKg>|3YOP)WM4BmMm}>Ls;qkR-K8Cu!Vkr%_xb{6nb2bWgBT8UbHF3C@E` zH_)BRQ5uK3Q(bEcvbE@|5=_=Ztv>ZmTPkh@tu8HvdejcO%^(hq-Zy4Vg7kgVTE(B^ z@H|M>Et$Z#Mw_N0=H2j=ii0$)O3VR+$+}n;e7RqtBc!rrZ^OCZh=gPdFqxOP^a_-?)U_QRi&Pj-@Q$ oLjF>^nCVlxm^GA!08cSTG6&D7Id~49g94>7{-=|ar?~k10q*hk?EnA( literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$InnerPublic.class b/testData/classes/pkg/TestAnonymousClassConstructor$InnerPublic.class new file mode 100644 index 0000000000000000000000000000000000000000..b984943441530396685c2a2d23857208bdde7afc GIT binary patch literal 894 zcma)5Yi|-k6g?NVEG%n5EY=5F+Cp7Gx>ftF#zaX>AVf{tp#8YJOz76_EZK*NKg$nN zqlrJjA7#9QCatLfvzc=rb7t?En>#;#e*F$$ANvIqao>Q64IOm@S!^iS%wtR0Z3PVl zO#?f4pu^J9BIJ@2KW^+1wujUA6Z=TS$#WUXk7r>T_W~!5d!dYzDD{#sI$-)!U;4>2 zf@S>&f6#A@2wE>33qon=OYtf_b47IIxB+J>!_aerkrVkU{*%;{AVRS(rHJ07Zs2JyB^FpWI%(pNgR7T$XI)cN3;xQ0~|CA10aDq#nX zoY;p+n}Zg?XGoY^I#FbX7v|s=acYv1;UzjmBrWQ@N}ft~~xqC^KH?DCPNGVcTqXK7-ol$b3Wg_#9e&hLuWg2ED4yke{LO1;!^P zW>8^V5tYMw4@>D^Zd$(|#PpaG<++|({HI6d4hns8-W)=Aj GRe@jN?%+EB literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$InnerPublicString.class b/testData/classes/pkg/TestAnonymousClassConstructor$InnerPublicString.class new file mode 100644 index 0000000000000000000000000000000000000000..e96ecf433a49c078201bc02d4eed2d3d0cdbd649 GIT binary patch literal 670 zcma)4+e*Vg5IviwO&epIR_pyzwGV9-E2tn;1StqY@Yd4zB!-%rZX_4M&+Nk7m;|dB53-0+;t&^&W%V z_HP}Ag5h%KA|6^!&^0ZOn3Cb!rq?qASKuE~76uuL=bSsiRcv{#J*vf^C0ydtA<5xn zN7b<^)DxrJ(zsOywd2Qu?VP#7+~%L7*%h5?$UxDM#j=7G4XapV*q=DnaZe2T@8B-2 zfn!GushXJG#>8^e4`(RX#v7{lP@yGA(>^d=7hXj~CyN~2DxoeUr0C5zwqL*+uaI`$ zka{LY!j#~X-)qv}U>Y50#8pNagmpqfBPz2bDxyT05@rZVm_>nJmHuQ}!94H{1*fij literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPrivate.class b/testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPrivate.class new file mode 100644 index 0000000000000000000000000000000000000000..9e7f68865684b5753547dd34dd0cd40ff970d6c7 GIT binary patch literal 1051 zcmbVL>uwT36#j=hyE54)D~(9M(-(C>hu=kwi(0%`EQe{k|5q z7G)C^Y#Df9V4ETH%$2Ts&XBg7jdGhIRrh;>;i}_G@g_R!h~R{GJhJ2*zstQg4_vK} zjVbls4awJ#QUoo_MU`Pi8>$|c{c1}EuI#^zT(2hr3%ej5Y)c>ZwRmXJ+dVRHXyGxQFdY2P zB{3{c3LbY(MOQJDE=D3MNn2l0h7Sfp_89VZv+PW;{vuCLv29N|YqR3>c4L-1tNh;; z7?$kmKq|O)VH0$ll41E@#M)S;nXqU)fCT;NeL!C}X@ce;MSHO_LgE{e??y-!he+o# zLl}i2vO`??0`qg6xJYt=5`b5fH1q?&`u>b%7 literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPrivateString.class b/testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPrivateString.class new file mode 100644 index 0000000000000000000000000000000000000000..9352fd7392b93dfb2c181bd59368156fd90e2376 GIT binary patch literal 804 zcmbVL+fExX5IwV5cF8tC2&B+*X}C#TB+^Jc6;!DTP$5MvQX<}+trZ*+FWPlb_$;1+ zc<2Z4QHb#d!9$@Sypm_fbLM!?*uK5H`3qnN%K==>1{lGo0G~1EW8TLC!P`?>neT++ zdaW%kM7bk$t6Vp+(yiT%6M|cf{z$?^O=C0}^OVU_1(us+Cp^4(v zm&kSr#1w^p3-_@|`1XvVH|$nPWjp<^1gBpiti36R5Y(ey9Lhswo3s31MccO1Ie75x z^u#)sk4&ZEEBXgBPvOJF?lLA~EGV~_`_C5~5_`p#+vY0>~lm}B59w_%2V>7+YtpVtX s&*M0-pYoK3h({g|Q}H5lx3gh)R`6%} zl8S;qz#k=^i9(S`1P9J{Zr{1gFyDWC`3B$&Pdvht;}=6T+nGZ`h;RD8A!rnS84e=zYb-3A;Op=m2MJ=xGz#={olc&d8abM za$9Se_KYwpdYgx_iU|HB)`~@zNv1sQj@}QO7cw(1bfQ0ACwVr>wGy3~G>=S@?oV|& zCy-$2u!Jmag4av(G?K5B-D!7bzmqHRLHO|Th_G($W-Rou*)yrq!fPgz6 zS)*a$(8m!TyEyi7f+pegKlUap-OhUxUdhN13W0s!k{FGo9uTTQr_sG-{jn9_`#6|N zp3mY}gZ8X+*(ARv5LSa}A`jg8=RNtEG-2&;i}g{5{d@K>jo+d8 literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPublicString.class b/testData/classes/pkg/TestAnonymousClassConstructor$InnerStaticPublicString.class new file mode 100644 index 0000000000000000000000000000000000000000..8eec4e1ecd2f61463863fe5f1b42e30fd35d4241 GIT binary patch literal 549 zcmbV~!Ab)$5QhJ3YqwojTdQr=lZuC`U@u;zB1lmX78P20Q^~HOP2DDv%?du2C&hyg z;6sVCt>8gaFozkw$;{8pByaC8uK@P2>LHJ+hea&8sJW;!6b_`4_K>003`YE(w_>ga zt*$jv4cc3MhI~ig2!?VXl{ibsp)frj#uTXrI^uDk8=3KEFmH!4VQ8ExB}~_HE2E1v zjAb-cWbh|9otP(ypu~1?cROhHL}HJWRu5yHCX>64R*5xfWVPA+L95NcNTK?@Z3eHa zQxl03nKioctNd;@wT~GzTrB%oL4jfa-%T-8zP5NCjznY`a?Na!>wk*UKniQf(IaJt zklHGcb%~D2JLF5-PhdOGa2^R96v@t032;eeSH#yS5!I*3@GwV2Wt3H(NK}X%EWju4 LQ6xv-VHU*?tG|v3 literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousClassConstructor.class b/testData/classes/pkg/TestAnonymousClassConstructor.class new file mode 100644 index 0000000000000000000000000000000000000000..7c692b8115bf9f88cbead56bd6376f7acd690eb9 GIT binary patch literal 3315 zcmbVP>sH%F5dIcp%a(-+28RHJ0&yDKEjU~gE=`-zrXisTttqLS-ejW^5hJ;_Oha$! zv-AzxA8<~6P9LBT)zewsyjY>=WY3XCnw|Ofo0;9Q{LjCC{S9Cdzsb0UZ3&;m@u`d+ zlqBp#X@-x8j3_>nuqz|MC!WYi^7qeW^r0-_3mN@*D&b2R1AP7~8H0TOYZ)2-{*8=b z{{F3u5pJ)_7{k*9DyT}>lQDtqI5aN5)QR_9Yk$Nqf?9mSB3Aj>5C6Go(e3hJK`4nuPBet_1a- zSHmN-?b$ay99QF5GQ`$(L$_`-L~{9EhTaWxPh;rc(hcoV>#(9VcGOCZH0dp~s@8VZ zhR)wzWv}&2C*Z4F_2>J=9j$5IF-+t5&}=pBBy5;Q(`vM;mf2V%1f6HBYk5UfQb_iz zn^lLpN7QjYGsQ4*p1ost4j``?W!qWWuAR3?QqWQLMD#Ouj;~9`t^W8q)*h8tp*c(# zZH7#4>p(qHi#65QFFJJActIF1TyTm(E}5-HRlBG2>P-J{@@F}+f}6NSwYsoW**V$< zmiEHp9#$xid2ZSYWx5c`YB7}65?}UVDAQ$bdKAj^W+mhDi90aAs7PFlh4< zeo*iN$FzgH_tf2%Ufa{CJw%OMesxm8kN8Q!&-g{cuL@rBY))NBnBh_f_i^PwtI{@E zxX>-T8Ely=ui@n#)|rsLUV9G9P;9^qiy>F(>P)MzCaL5S=^N ze0X2Vg>ikb$xWj{bIz_dR;U27-nA8 z90R=Ey-kjB%k)w?l*nt@4V>C=Oc6kXIf!LUM4MUsqUv~UXc z2R-y)mF_WH8NnJoD~Eyl%Ve*SwKqpNbmbd0;7b(NDkoi5u=oV(_wVS#}ODMJw{3Z zX@D4|1tgDA9Cv-B>xkG{OSaKh<|#_qFw9P~lcEfTbs2GN_)d9B8y|gb^p~A{Tnf02 zP-RBR=mXzPhrL1(2pF`e^~liypY=BMFQ$4x`Hf zoNL7BEdi&)=p!FTU^MJ8x)MOj6QhEF;5J9~m?yUfcu1#$AFlgUdw#e^|HOD36XjF9nVvksRDrG&OrPLt_i0(8Z}(*( zf>CVYV?yY`Bm4dsIg-C)h%%PNby_V?vOw}}lJC&m49QuNMUpp2KSz?YS|GVd`X!Rf rB**9i=|@~SY)jC831PJZT9+HI!O}_6wKVhX4Qo literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousParamNames$Clazz.class b/testData/classes/pkg/TestAnonymousParamNames$Clazz.class new file mode 100644 index 0000000000000000000000000000000000000000..9e4c76a529c6e681fdbf61f60b9464bc43bf66b1 GIT binary patch literal 537 zcmaJ;O;5r=5Pee$m0G3ZCjyBd91s)n;7wzqBqovuO(Yz+Ex5sAKS*0ld|JC-Fa`{?3ll+FAs8_yQI_7QjMc;!a~iNK7;YO(Z0`8|sL~c50@@ME=T!A<@JS z@S}`(z^$FdedV5W?%ezR^YI1X7 (JI)V' { + f 69 + 18 69 + 1b 69 + 1e 70 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerStaticPublicString' { + method ' (Ljava/lang/String;)V' { + 5 75 + 8 76 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerPublic' { + method ' (Lpkg/TestAnonymousClassConstructor;JI)V' { + 14 81 + 1e 81 + 21 81 + 24 82 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerPublicString' { + method ' (Lpkg/TestAnonymousClassConstructor;Ljava/lang/String;)V' { + a 87 + d 88 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerStaticPrivate' { + method ' (JI)V' { + f 93 + 18 93 + 1b 93 + 1e 94 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerStaticPrivateString' { + method ' (Ljava/lang/String;)V' { + 5 99 + 8 100 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerPrivate' { + method ' (Lpkg/TestAnonymousClassConstructor;JI)V' { + 14 105 + 1e 105 + 21 105 + 24 106 + } +} + +class 'pkg/TestAnonymousClassConstructor$InnerPrivateString' { + method ' (Lpkg/TestAnonymousClassConstructor;Ljava/lang/String;)V' { + a 111 + d 112 + } +} + +Lines mapping: +5 <-> 5 +6 <-> 7 +9 <-> 10 +10 <-> 12 +13 <-> 15 +14 <-> 17 +17 <-> 20 +18 <-> 22 +21 <-> 25 +22 <-> 27 +25 <-> 30 +26 <-> 32 +29 <-> 35 +30 <-> 37 +33 <-> 40 +34 <-> 42 +37 <-> 45 +38 <-> 47 +41 <-> 50 +42 <-> 52 +45 <-> 55 +46 <-> 57 +49 <-> 60 +50 <-> 62 +53 <-> 65 +54 <-> 66 +58 <-> 112 +59 <-> 113 +64 <-> 106 +65 <-> 107 +70 <-> 100 +71 <-> 101 +76 <-> 94 +77 <-> 95 +82 <-> 88 +83 <-> 89 +88 <-> 82 +89 <-> 83 +94 <-> 76 +95 <-> 77 +100 <-> 70 +101 <-> 71 +Not mapped: +57 +63 +69 +75 +81 +87 +93 +99 diff --git a/testData/results/TestAnonymousParamNames.dec b/testData/results/TestAnonymousParamNames.dec new file mode 100644 index 0000000..810799c --- /dev/null +++ b/testData/results/TestAnonymousParamNames.dec @@ -0,0 +1,22 @@ +package pkg; + +public class TestAnonymousParamNames { + private final TestAnonymousParamNames.Clazz reference = new TestAnonymousParamNames.Clazz(0L, false) { + }; + + private class Clazz { + public Clazz(long paramL, boolean paramB) { + }// 25 + } +} + +class 'pkg/TestAnonymousParamNames$Clazz' { + method ' (Lpkg/TestAnonymousParamNames;JZ)V' { + 9 8 + } +} + +Lines mapping: +25 <-> 9 +Not mapped: +24 diff --git a/testData/src/pkg/TestAnonymousClassConstructor.java b/testData/src/pkg/TestAnonymousClassConstructor.java new file mode 100644 index 0000000..5104b50 --- /dev/null +++ b/testData/src/pkg/TestAnonymousClassConstructor.java @@ -0,0 +1,103 @@ +package pkg; + +class TestAnonymousClassConstructor { + void innerPrivateString() { + new InnerPrivateString("text"){}; + } + + void innerPrivate() { + new InnerPrivate(3, 4){}; + } + + void innerStaticPrivateString() { + new InnerStaticPrivateString("text"){}; + } + + void innerStaticPrivate() { + new InnerStaticPrivate(3, 4){}; + } + + static void innerStaticPrivateStringStatic() { + new InnerStaticPrivateString("text"){}; + } + + static void innerStaticPrivateStatic() { + new InnerStaticPrivate(3, 4){}; + } + + void innerPublicString() { + new InnerPublicString("text"){}; + } + + void innerPublic() { + new InnerPublic(3, 4){}; + } + + void innerStaticPublicString() { + new InnerStaticPublicString("text"){}; + } + + void innerStaticPublic() { + new InnerStaticPublic(3, 4){}; + } + + static void innerStaticPublicStringStatic() { + new InnerStaticPublicString("text"){}; + } + + static void innerStaticPublicStatic() { + new InnerStaticPublic(3, 4){}; + } + + static void n(String s) { + System.out.println("n(): " + s); + } + + class InnerPrivateString { + private InnerPrivateString(String s) { + n(s); + } + } + + class InnerPrivate { + private InnerPrivate(long a, int b) { + n(a + "+" + b); + } + } + + static class InnerStaticPrivateString { + private InnerStaticPrivateString(String s) { + n(s); + } + } + + static class InnerStaticPrivate { + private InnerStaticPrivate(long a, int b) { + n(a + "+" + b); + } + } + + class InnerPublicString { + public InnerPublicString(String s) { + n(s); + } + } + + class InnerPublic { + public InnerPublic(long a, int b) { + n(a + "+" + b); + } + } + + static class InnerStaticPublicString { + public InnerStaticPublicString(String s) { + n(s); + } + } + + static class InnerStaticPublic { + public InnerStaticPublic(long a, int b) { + n(a + "+" + b); + } + } +} diff --git a/testData/src/pkg/TestAnonymousParamNames.java b/testData/src/pkg/TestAnonymousParamNames.java new file mode 100644 index 0000000..5c83de9 --- /dev/null +++ b/testData/src/pkg/TestAnonymousParamNames.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +import java.io.File; + +public class TestAnonymousParamNames { + private final Clazz reference = new Clazz(0, false) {}; + + private class Clazz { + public Clazz(long paramL, boolean paramB) { + } + } +} From f466a2bc55c977d7bd8240fba59240f7896df455 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Fri, 13 Jan 2017 21:01:29 +0300 Subject: [PATCH 085/252] more correct variable name in cases where definition is not inside debug name offsets --- .../decompiler/main/rels/ClassWrapper.java | 18 +++++++ .../modules/decompiler/exps/VarExprent.java | 47 +++++++++---------- .../modules/decompiler/vars/VarProcessor.java | 4 +- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java index f5cd82c..d0efaae 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java +++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java @@ -22,6 +22,7 @@ import org.jetbrains.java.decompiler.main.collectors.VarNamesCollector; import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences; import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent; +import org.jetbrains.java.decompiler.modules.decompiler.exps.VarExprent; import org.jetbrains.java.decompiler.modules.decompiler.stats.RootStatement; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; @@ -35,6 +36,7 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection; import java.io.IOException; import java.util.HashSet; +import java.util.List; import java.util.Set; public class ClassWrapper { @@ -165,6 +167,22 @@ public class ClassWrapper { if (attr != null) { // only param names here varProc.setDebugVarNames(attr.getMapParamNames()); + + // the rest is here + methodWrapper.getOrBuildGraph().iterateExprents(exprent -> { + List lst = exprent.getAllExprents(true); + lst.add(exprent); + lst.stream() + .filter(e -> e.type == Exprent.EXPRENT_VAR) + .forEach(e -> { + VarExprent varExprent = (VarExprent)e; + String name = varExprent.getDebugName(mt); + if (name != null) { + varProc.setVarName(varExprent.getVarVersionPair(), name); + } + }); + return 0; + }); } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java index 8fc43ff..0cb7fd1 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/VarExprent.java @@ -27,6 +27,7 @@ import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarTypeProcessor; import org.jetbrains.java.decompiler.modules.decompiler.vars.VarVersionPair; +import org.jetbrains.java.decompiler.struct.StructMethod; import org.jetbrains.java.decompiler.struct.attr.StructGeneralAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTableAttribute; import org.jetbrains.java.decompiler.struct.attr.StructLocalVariableTypeTableAttribute; @@ -105,14 +106,17 @@ public class VarExprent extends Exprent { tracer.incrementCurrentSourceLine(buffer.countLines()); } else { - VarVersionPair varVersion = new VarVersionPair(index, version); - String name = getName(varVersion); + VarVersionPair varVersion = getVarVersionPair(); + String name = null; + if (processor != null) { + name = processor.getVarName(varVersion); + } if (definition) { if (processor != null && processor.getVarFinal(varVersion) == VarTypeProcessor.VAR_EXPLICIT_FINAL) { buffer.append("final "); } - appendDefinitionType(buffer, varVersion); + appendDefinitionType(buffer); buffer.append(" "); } @@ -122,36 +126,31 @@ public class VarExprent extends Exprent { return buffer; } - private String getName(VarVersionPair varVersion) { - String name = null; - if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_VAR_NAMES)) { - MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); - if (method != null) { - StructLocalVariableTableAttribute attr = method.methodStruct.getLocalVariableAttr(); - if (attr != null && processor != null) { - Integer index = processor.getVarOriginalIndex(varVersion); - if (index != null) { - name = attr.getName(index, visibleOffset); - if (name != null && TextUtil.isValidIdentifier(name, method.methodStruct.getClassStruct().getBytecodeVersion())) { - return name; - } - } + public VarVersionPair getVarVersionPair() { + return new VarVersionPair(index, version); + } + + public String getDebugName(StructMethod method) { + StructLocalVariableTableAttribute attr = method.getLocalVariableAttr(); + if (attr != null && processor != null) { + Integer origIndex = processor.getVarOriginalIndex(index); + if (origIndex != null) { + String name = attr.getName(origIndex, visibleOffset); + if (name != null && TextUtil.isValidIdentifier(name, method.getClassStruct().getBytecodeVersion())) { + return name; } } } - if (processor != null) { - name = processor.getVarName(varVersion); - } - return name; + return null; } - private void appendDefinitionType(TextBuffer buffer, VarVersionPair varVersion) { + private void appendDefinitionType(TextBuffer buffer) { if (DecompilerContext.getOption(IFernflowerPreferences.USE_DEBUG_VAR_NAMES)) { MethodWrapper method = (MethodWrapper)DecompilerContext.getProperty(DecompilerContext.CURRENT_METHOD_WRAPPER); if (method != null) { Integer originalIndex = null; if (processor != null) { - originalIndex = processor.getVarOriginalIndex(varVersion); + originalIndex = processor.getVarOriginalIndex(index); } if (originalIndex != null) { // first try from signature @@ -208,7 +207,7 @@ public class VarExprent extends Exprent { public VarType getVarType() { VarType vt = null; if (processor != null) { - vt = processor.getVarType(new VarVersionPair(index, version)); + vt = processor.getVarType(getVarVersionPair()); } if (vt == null || (varType != null && varType.type != CodeConstants.TYPE_UNKNOWN)) { diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java index 7e3da59..728addf 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarProcessor.java @@ -84,12 +84,12 @@ public class VarProcessor { } } - public Integer getVarOriginalIndex(VarVersionPair pair) { + public Integer getVarOriginalIndex(int index) { if (varVersions == null) { return null; } - return varVersions.getMapOriginalVarIndices().get(pair.var); + return varVersions.getMapOriginalVarIndices().get(index); } public void refreshVarNames(VarNamesCollector vc) { From 9ee45b3f5a69b4a7ce1bb21fed322fcda99fbb95 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 17 Jan 2017 20:45:27 +0300 Subject: [PATCH 086/252] cleanup: use streams --- src/org/jetbrains/java/decompiler/main/ClassWriter.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index d80090d..0986a22 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -651,15 +651,10 @@ public class ClassWriter { if (attr != null) { descriptor = GenericMain.parseMethodSignature(attr.getSignature()); if (descriptor != null) { - int actualParams = md.params.length; + long actualParams = md.params.length; List sigFields = methodWrapper.signatureFields; if (sigFields != null) { - actualParams = 0; - for (VarVersionPair field : methodWrapper.signatureFields) { - if (field == null) { - actualParams++; - } - } + actualParams = sigFields.stream().filter(Objects::isNull).count(); } else if (isEnum && init) actualParams -= 2; if (actualParams != descriptor.params.size()) { From 6713b9c495e32b500ba5c0dc7facaec9e0bbcccb Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 17 Jan 2017 20:46:58 +0300 Subject: [PATCH 087/252] test for anonymous class with params --- .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TestAnonymousParams$1.class | Bin 0 -> 771 bytes .../classes/pkg/TestAnonymousParams.class | Bin 0 -> 749 bytes testData/results/TestAnonymousParams.dec | 36 ++++++++++++++++++ testData/src/pkg/TestAnonymousParams.java | 32 ++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 testData/classes/pkg/TestAnonymousParams$1.class create mode 100644 testData/classes/pkg/TestAnonymousParams.class create mode 100644 testData/results/TestAnonymousParams.dec create mode 100644 testData/src/pkg/TestAnonymousParams.java diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 7c1cc33..7a69a8e 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -96,6 +96,7 @@ public class SingleClassesTest { @Test public void testAsserts() { doTest("pkg/TestAsserts"); } @Test public void testLocalsNames() { doTest("pkg/TestLocalsNames"); } @Test public void testAnonymousParamNames() { doTest("pkg/TestAnonymousParamNames"); } + @Test public void testAnonymousParams() { doTest("pkg/TestAnonymousParams"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestAnonymousParams$1.class b/testData/classes/pkg/TestAnonymousParams$1.class new file mode 100644 index 0000000000000000000000000000000000000000..dccd219da7f3606a18053add2e5edc0c9b0e936e GIT binary patch literal 771 zcmZ`%!EVz)5Pj=7F%5>gEu|@;5U7D9AVLwhA|zB5$xP)!PLO&;Jr;{!X*hU$%WdKxpPf9l4f_+2wh zZLZDnTUDIcQGm@5F&>1tf`t$@1R?5p$TiN{V!XxL<%-y@P}zTr5?HycCGY-96j+FN=du|h6^8(5`x+&xCFR_%U;_n8+D{|K8U hVfY7dL3ooGpP4nbX_WYN+$wWT+-3_WoIjhM-)~lVs&fDU literal 0 HcmV?d00001 diff --git a/testData/classes/pkg/TestAnonymousParams.class b/testData/classes/pkg/TestAnonymousParams.class new file mode 100644 index 0000000000000000000000000000000000000000..0946b63019f38000bada2e6df2089716088d128d GIT binary patch literal 749 zcmZ`%T~8B16g{(Dy1HGV3j(d6e27wNbffVNV`7LVn>1ho!T2~W0}gIyn%%9@pXG}r zn)n0!QO2`dU5V03X71dtbMLt`KYo7w4&W)aeblkyVbzC&+dl4K&BMBf4S^swMx}d+ z%rcb;)Sqdi^XCG!&d#xbyJt_7z+6uowLc#AReB`*2`%$IJCMn-Om(6EHoEycO^kML z^!_Y5Qd$1OSo3LU$JuL{%3-!k*i&m6(dnJb4>Hm=ip^-8ALgl&!`-+j>1ZRcc%@%J zNbXo5Jk?3A(o4w#D^<>`f1NDszx+5*qg-2)dDx_WXvgV5F_dgtS2X*m=rF)FTxY*i z2yHzs0`7X)3UCki1(v4-3N%Z?i8N=?LH}G0a)E_v1_xDh0#7 13 +27 <-> 11 +30 <-> 14 +31 <-> 15 diff --git a/testData/src/pkg/TestAnonymousParams.java b/testData/src/pkg/TestAnonymousParams.java new file mode 100644 index 0000000..55e58bf --- /dev/null +++ b/testData/src/pkg/TestAnonymousParams.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +import java.io.FilterInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class TestAnonymousParams { + void foo(InputStream in, int a) throws IOException { + FilterInputStream filterInputStream = new FilterInputStream(in) { + @Override + public int read() throws IOException { + return a; + } + }; + filterInputStream.read(); + } +} From 85f61bee8194ab69afa746b965973a18eda67608 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 17 Jan 2017 21:38:48 +0300 Subject: [PATCH 088/252] fixed IdeaDecompilerTest.testStubCompatibility --- .../java/decompiler/main/rels/NestedClassProcessor.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index b456cc8..897b394 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -405,8 +405,10 @@ public class NestedClassProcessor { MethodWrapper method = nestedNode.getWrapper().getMethodWrapper(CodeConstants.INIT_NAME, entry.getKey()); method.signatureFields = new ArrayList<>(); + boolean firstSignField = nestedNode.type != ClassNode.CLASS_ANONYMOUS; for (VarFieldPair pair : entry.getValue()) { - method.signatureFields.add(pair == null || pair.fieldKey.isEmpty() ? null : pair.varPair); + method.signatureFields.add(pair == null || (!firstSignField && pair.fieldKey.isEmpty()) ? null : pair.varPair); + firstSignField = false; } } } From 45384fb8c5f5903b707da79a047a1bb6ac640979 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 23 Jan 2017 18:07:50 +0300 Subject: [PATCH 089/252] fixed access to private outer class methods with params --- .../main/rels/NestedMemberAccess.java | 12 +-- .../java/decompiler/SingleClassesTest.java | 1 + .../classes/pkg/TestAccessReplace$Inner.class | Bin 0 -> 723 bytes testData/classes/pkg/TestAccessReplace.class | Bin 0 -> 1079 bytes testData/results/TestAccessReplace.dec | 69 ++++++++++++++++++ testData/src/pkg/TestAccessReplace.java | 32 ++++++++ 6 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 testData/classes/pkg/TestAccessReplace$Inner.class create mode 100644 testData/classes/pkg/TestAccessReplace.class create mode 100644 testData/results/TestAccessReplace.dec create mode 100644 testData/src/pkg/TestAccessReplace.java diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java index a460ef9..5be55d0 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -149,19 +149,21 @@ public class NestedMemberAccess { InvocationExprent invexpr = (InvocationExprent)exprCore; - if ((invexpr.isStatic() && invexpr.getLstParameters().size() == parcount) || - (!invexpr.isStatic() && invexpr.getInstance().type == Exprent.EXPRENT_VAR + boolean isStatic = invexpr.isStatic(); + if ((isStatic && invexpr.getLstParameters().size() == parcount) || + (!isStatic && invexpr.getInstance().type == Exprent.EXPRENT_VAR && ((VarExprent)invexpr.getInstance()).getIndex() == 0 && invexpr.getLstParameters().size() == parcount - 1)) { boolean equalpars = true; + int index = isStatic ? 0 : 1; for (int i = 0; i < invexpr.getLstParameters().size(); i++) { Exprent parexpr = invexpr.getLstParameters().get(i); - if (parexpr.type != Exprent.EXPRENT_VAR || - ((VarExprent)parexpr).getIndex() != i + (invexpr.isStatic() ? 0 : 1)) { + if (parexpr.type != Exprent.EXPRENT_VAR || ((VarExprent)parexpr).getIndex() != index) { equalpars = false; break; } + index += mtdesc.params[i + (isStatic ? 0 : 1)].stackSize; } if (equalpars) { diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 7a69a8e..8b876c8 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -97,6 +97,7 @@ public class SingleClassesTest { @Test public void testLocalsNames() { doTest("pkg/TestLocalsNames"); } @Test public void testAnonymousParamNames() { doTest("pkg/TestAnonymousParamNames"); } @Test public void testAnonymousParams() { doTest("pkg/TestAnonymousParams"); } + @Test public void testAccessReplace() { doTest("pkg/TestAccessReplace"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestAccessReplace$Inner.class b/testData/classes/pkg/TestAccessReplace$Inner.class new file mode 100644 index 0000000000000000000000000000000000000000..a339ed0fd9f6e56b0a11d258692b121b58baf5c9 GIT binary patch literal 723 zcmZ`%+fKqj5ItKcNG*zYLm;-;}NZ(f!&Wz4n9I&WH z(Pr6yWe6Bo-AB(-r#2^E{P(?Weqv%0rinNTQ4~$AqhMkKnEZxF!C8yB?mn&*6Y;yAF#t9Ij+Yn_ru&}re10^{s#9rm>&0>xyaLO z7&HeWk>D@$iFO=QWTy#v&=De^t5jbgDzDJ`2vz$C8}rcnh*pPw;+Z%a5@eHzkX_-K uBfS*G(pW+UtH@%8m4z2LKEe3l z2l!ErXOk3TDamB_-o1Oy-m{zEe}4V~@B|NYaBx@5Ju&yi)N*jK>7wpp%f$l)`(3YR z1`1x}ce^?aO{n0!2ztTrr9!5*d7zNp?SD23bM2sK-k%|w^)uK%xUg`8)`@}z%yBKLOh6tt>2q>9Mg+XXPaY*el>*L_ zhC-6Gt>`pKOY<+J_$evjXB!gWQv$PN{xq-{0ZXhRbxT;Jm(?w (Lpkg/TestAccessReplace;Ljava/lang/String;)V' { + 0 17 + 1 18 + 2 19 + 3 20 + 10 19 + 11 19 + 18 20 + 19 20 + 1f 21 + } +} + +Lines mapping: +19 <-> 5 +20 <-> 8 +21 <-> 11 +22 <-> 14 +25 <-> 18 +28 <-> 20 +29 <-> 21 +30 <-> 22 +Not mapped: +26 +27 diff --git a/testData/src/pkg/TestAccessReplace.java b/testData/src/pkg/TestAccessReplace.java new file mode 100644 index 0000000..e5a21bc --- /dev/null +++ b/testData/src/pkg/TestAccessReplace.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +public class TestAccessReplace { + private static void fooS() {}; + private void foo() {}; + private static void fooSParams(long a, long b) {}; + private void fooParams(long a, long b) {}; + + public class Inner { + public Inner(String b) { + fooS(); + foo(); + fooSParams(1,2); + fooParams(1,2); + } + } +} From f53a873116342516ddd358a0eee8feaa9fd6dcdf Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 7 Feb 2017 17:51:02 +0300 Subject: [PATCH 090/252] IDEA-167346 Do not escape single quote in strings --- .../modules/decompiler/exps/ConstExprent.java | 34 ++++++++-------- .../java/decompiler/SingleClassesTest.java | 6 ++- testData/classes/pkg/TestStringLiterals.class | Bin 0 -> 534 bytes testData/results/TestStringLiterals.dec | 38 ++++++++++++++++++ testData/src/pkg/TestStringLiterals.java | 25 ++++++++++++ 5 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 testData/classes/pkg/TestStringLiterals.class create mode 100644 testData/results/TestStringLiterals.dec create mode 100644 testData/src/pkg/TestStringLiterals.java diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index e82fec7..962bb77 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,17 +33,17 @@ import java.util.*; import java.util.Map.Entry; public class ConstExprent extends Exprent { - private static final Map ESCAPES; + private static final Map CHAR_ESCAPES; static { - ESCAPES = new HashMap<>(); - ESCAPES.put(new Integer(0x8), "\\b"); /* \u0008: backspace BS */ - ESCAPES.put(new Integer(0x9), "\\t"); /* \u0009: horizontal tab HT */ - ESCAPES.put(new Integer(0xA), "\\n"); /* \u000a: linefeed LF */ - ESCAPES.put(new Integer(0xC), "\\f"); /* \u000c: form feed FF */ - ESCAPES.put(new Integer(0xD), "\\r"); /* \u000d: carriage return CR */ - ESCAPES.put(new Integer(0x22), "\\\""); /* \u0022: double quote " */ - ESCAPES.put(new Integer(0x27), "\\\'"); /* \u0027: single quote ' */ - ESCAPES.put(new Integer(0x5C), "\\\\"); /* \u005c: backslash \ */ + CHAR_ESCAPES = new HashMap<>(); + CHAR_ESCAPES.put(new Integer(0x8), "\\b"); /* \u0008: backspace BS */ + CHAR_ESCAPES.put(new Integer(0x9), "\\t"); /* \u0009: horizontal tab HT */ + CHAR_ESCAPES.put(new Integer(0xA), "\\n"); /* \u000a: linefeed LF */ + CHAR_ESCAPES.put(new Integer(0xC), "\\f"); /* \u000c: form feed FF */ + CHAR_ESCAPES.put(new Integer(0xD), "\\r"); /* \u000d: carriage return CR */ + //CHAR_ESCAPES.put(new Integer(0x22), "\\\""); /* \u0022: double quote " */ + CHAR_ESCAPES.put(new Integer(0x27), "\\\'"); /* \u0027: single quote ' */ + CHAR_ESCAPES.put(new Integer(0x5C), "\\\\"); /* \u005c: backslash \ */ } private VarType constType; @@ -130,7 +130,7 @@ public class ConstExprent extends Exprent { case CodeConstants.TYPE_CHAR: Integer val = (Integer)value; - String ret = ESCAPES.get(val); + String ret = CHAR_ESCAPES.get(val); if (ret == null) { char c = (char)val.intValue(); if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) { @@ -140,7 +140,7 @@ public class ConstExprent extends Exprent { ret = TextUtil.charToUnicodeLiteral(c); } } - return new TextBuffer().append('\'').append(ret).append('\''); + return new TextBuffer(ret).enclose("'", "'"); case CodeConstants.TYPE_BYTE: case CodeConstants.TYPE_BYTECHAR: @@ -235,7 +235,7 @@ public class ConstExprent extends Exprent { case CodeConstants.TYPE_OBJECT: if (constType.equals(VarType.VARTYPE_STRING)) { - return new TextBuffer().append('"').append(convertStringToJava(value.toString(), ascii)).append('"'); + return new TextBuffer(convertStringToJava(value.toString(), ascii)).enclose("\"", "\""); } else if (constType.equals(VarType.VARTYPE_CLASS)) { String stringVal = value.toString(); @@ -274,9 +274,9 @@ public class ConstExprent extends Exprent { case 0x22: //"\\\\\""); // u0022: double quote " buffer.append("\\\""); break; - case 0x27: //"\\\\'"); // u0027: single quote ' - buffer.append("\\\'"); - break; + //case 0x27: //"\\\\'"); // u0027: single quote ' + // buffer.append("\\\'"); + // break; default: if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) { buffer.append(c); diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 8b876c8..2388d8d 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -22,9 +22,10 @@ import org.junit.Before; import org.junit.Test; import java.io.File; -import java.io.FilenameFilter; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import static org.jetbrains.java.decompiler.DecompilerTestFixture.assertFilesEqual; import static org.junit.Assert.assertTrue; @@ -98,6 +99,7 @@ public class SingleClassesTest { @Test public void testAnonymousParamNames() { doTest("pkg/TestAnonymousParamNames"); } @Test public void testAnonymousParams() { doTest("pkg/TestAnonymousParams"); } @Test public void testAccessReplace() { doTest("pkg/TestAccessReplace"); } + @Test public void testStringLiterals() { doTest("pkg/TestStringLiterals"); } private void doTest(String testFile, String... companionFiles) { ConsoleDecompiler decompiler = fixture.getDecompiler(); diff --git a/testData/classes/pkg/TestStringLiterals.class b/testData/classes/pkg/TestStringLiterals.class new file mode 100644 index 0000000000000000000000000000000000000000..f4cb2b9568d3e936cfb164a575f43dfb2f01d16c GIT binary patch literal 534 zcmZut$xZ@65Pc1^F%HrqiyJOnz$KCxF9u^YCZ2Ffa7ZR_8K5PtFc=t2{470SVvHZ) zM;WW(V2JkNRrTvvRj>N%`~4HZAvSH8;1(8QNMg}O3TXuy6Il~W492kxWO%|5EpFEs zwDW#jFeEB65LcsKQw(nXW|tVP=gWX0Q><6+{U^WF^@C2S8V+R8DXT)e+8+&C;zBBM z_ErqT>0?EPV&Hd&`>M);g&4!U-)vbi+ll83jkdTmvFu<4t0vYQ*w1wY{8&!RVMN{^>FO)FM5gHRRNiqj<%9T_?LzLoKGE(8zhweqW z<$4;Axt`8#*E6`|dM1y%p2hR7#|>T}G 5 +21 <-> 6 +22 <-> 7 +23 <-> 8 +24 <-> 9 diff --git a/testData/src/pkg/TestStringLiterals.java b/testData/src/pkg/TestStringLiterals.java new file mode 100644 index 0000000..ebefa32 --- /dev/null +++ b/testData/src/pkg/TestStringLiterals.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package pkg; + +public class TestStringLiterals { + public static void main(String[] args) { + String a = "abc\b\t\n\f\r\"'\\def"; + char chars[] = {'\b', '\t', '\n', '\f', '\r', '"', '\'', '\\'}; + System.out.println(a); + System.out.println(chars); + } +} From 024978848c5ebe05de8b7e11f6f0827d3a219c0d Mon Sep 17 00:00:00 2001 From: DMP9 Date: Sat, 11 Feb 2017 19:32:41 +0000 Subject: [PATCH 091/252] Fernflower readme markdown --- readme.txt => README.md | 67 ++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 34 deletions(-) rename readme.txt => README.md (60%) diff --git a/readme.txt b/README.md similarity index 60% rename from readme.txt rename to README.md index cd47656..28b82dc 100644 --- a/readme.txt +++ b/README.md @@ -1,4 +1,4 @@ -1. About the decompiler +## About fernflower Fernflower is the first actually working analytical decompiler for Java and probably for a high-level programming language in general. Naturally it is still @@ -6,12 +6,11 @@ under development, please send your bug reports and improvement suggestions at fernflower.decompiler@gmail.com -2. License +## Licence -http://www.apache.org/licenses/LICENSE-2.0 +Fernflower is licenced under the Apache Licence Version 2.0. It can be found here: http://www.apache.org/licenses/LICENSE-2.0 - -3. Running from the command line +## Running from command line java -jar fernflower.jar [-