summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/org/jetbrains/java/decompiler/main/AssertProcessor.java2
-rw-r--r--src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java4
-rw-r--r--src/org/jetbrains/java/decompiler/main/ClassWriter.java6
-rw-r--r--src/org/jetbrains/java/decompiler/main/ClassesProcessor.java20
-rw-r--r--src/org/jetbrains/java/decompiler/main/EnumProcessor.java6
-rw-r--r--src/org/jetbrains/java/decompiler/main/Fernflower.java55
-rw-r--r--src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java4
-rw-r--r--src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java2
-rw-r--r--src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java5
-rw-r--r--src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java19
-rw-r--r--src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java4
-rw-r--r--src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java2
-rw-r--r--src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java2
-rw-r--r--src/org/jetbrains/java/decompiler/util/InterpreterUtil.java23
14 files changed, 68 insertions, 86 deletions
diff --git a/src/org/jetbrains/java/decompiler/main/AssertProcessor.java b/src/org/jetbrains/java/decompiler/main/AssertProcessor.java
index da703fd..a58b689 100644
--- a/src/org/jetbrains/java/decompiler/main/AssertProcessor.java
+++ b/src/org/jetbrains/java/decompiler/main/AssertProcessor.java
@@ -60,7 +60,7 @@ public class AssertProcessor {
if (res) {
// hide the helper field
- wrapper.getHideMembers().add(key);
+ wrapper.getHiddenMembers().add(key);
}
}
}
diff --git a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
index 4552b1d..3807d2e 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassReference14Processor.java
@@ -114,7 +114,7 @@ public class ClassReference14Processor {
if (!setFound.isEmpty()) {
for (ClassWrapper wrp : setFound) {
StructMethod mt = mapClassMeths.get(wrp).methodStruct;
- wrp.getHideMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
+ wrp.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
}
}
}
@@ -276,7 +276,7 @@ public class ClassReference14Processor {
invexpr.getStringDescriptor().equals(meth.methodStruct.getDescriptor())) {
if (invexpr.getLstParameters().get(0).type == Exprent.EXPRENT_CONST) {
- wrapper.getHideMembers()
+ wrapper.getHiddenMembers()
.add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor())); // hide synthetic field
return ((ConstExprent)invexpr.getLstParameters().get(0)).getValue().toString();
}
diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index c6dc7a4..ffc57d8 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -239,7 +239,7 @@ public class ClassWriter {
if ((!isSynthetic || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC)) &&
(!isBridge || !DecompilerContext.getOption(IFernflowerPreferences.REMOVE_BRIDGE)) &&
- !wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()))) {
+ !wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()))) {
if (!mthidden && (!firstmt || node.type != ClassNode.CLASS_ANONYMOUS)) {
bufstrwriter.write(DecompilerContext.getNewLineSeparator());
firstmt = false;
@@ -260,7 +260,7 @@ public class ClassWriter {
// fields
for (StructField fd : cl.getFields()) {
boolean hide = fd.isSynthetic() && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
- wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
+ wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
if (!hide) {
boolean isEnum = fd.hasModifier(CodeConstants.ACC_ENUM) && DecompilerContext.getOption(IFernflowerPreferences.DECOMPILE_ENUM);
if (isEnum) {
@@ -308,7 +308,7 @@ public class ClassWriter {
StructClass innerCl = inner.classStruct;
boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic();
boolean hide = isSynthetic && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) ||
- wrapper.getHideMembers().contains(innerCl.qualifiedName);
+ wrapper.getHiddenMembers().contains(innerCl.qualifiedName);
if (!hide) {
writer.write(DecompilerContext.getNewLineSeparator());
classToJava(inner, writer, indent + 1);
diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
index a16e4e0..034efb1 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java
@@ -235,7 +235,7 @@ public class ClassesProcessor {
}
- public void writeClass(StructContext context, StructClass cl, BufferedWriter outwriter) throws IOException {
+ public void writeClass(StructClass cl, BufferedWriter writer) throws IOException {
ClassNode root = mapRootClasses.get(cl.qualifiedName);
if (root.type != ClassNode.CLASS_ROOT) {
@@ -270,20 +270,20 @@ public class ClassesProcessor {
int index = cl.qualifiedName.lastIndexOf("/");
if (index >= 0) {
String packageName = cl.qualifiedName.substring(0, index).replace('/', '.');
- outwriter.write("package ");
- outwriter.write(packageName);
- outwriter.write(";");
- outwriter.write(DecompilerContext.getNewLineSeparator());
- outwriter.write(DecompilerContext.getNewLineSeparator());
+ writer.write("package ");
+ writer.write(packageName);
+ writer.write(";");
+ writer.write(DecompilerContext.getNewLineSeparator());
+ writer.write(DecompilerContext.getNewLineSeparator());
}
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS_NODE, root);
- DecompilerContext.getImportCollector().writeImports(outwriter);
- outwriter.write(DecompilerContext.getNewLineSeparator());
+ DecompilerContext.getImportCollector().writeImports(writer);
+ writer.write(DecompilerContext.getNewLineSeparator());
- outwriter.write(strwriter.toString());
- outwriter.flush();
+ writer.write(strwriter.toString());
+ writer.flush();
}
finally {
destroyWrappers(root);
diff --git a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
index d6ae2b9..be408e8 100644
--- a/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
+++ b/src/org/jetbrains/java/decompiler/main/EnumProcessor.java
@@ -40,12 +40,12 @@ public class EnumProcessor {
if ("values".equals(name)) {
if (descriptor.equals("()[L" + cl.qualifiedName + ";")) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
+ wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
}
}
else if ("valueOf".equals(name)) {
if (descriptor.equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
+ wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(name, descriptor));
}
}
else if ("<init>".equals(name)) {
@@ -66,7 +66,7 @@ public class EnumProcessor {
for (StructField fd : cl.getFields()) {
String descriptor = fd.getDescriptor();
if (fd.isSynthetic() && descriptor.equals("[L" + cl.qualifiedName + ";")) {
- wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor));
+ wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), descriptor));
}
}
}
diff --git a/src/org/jetbrains/java/decompiler/main/Fernflower.java b/src/org/jetbrains/java/decompiler/main/Fernflower.java
index 6d60f6e..67596be 100644
--- a/src/org/jetbrains/java/decompiler/main/Fernflower.java
+++ b/src/org/jetbrains/java/decompiler/main/Fernflower.java
@@ -28,81 +28,66 @@ import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
import java.io.BufferedWriter;
import java.io.StringWriter;
-import java.util.HashMap;
+import java.util.Map;
public class Fernflower implements IDecompiledData {
- public static final String version = "v0.8.4";
-
- private StructContext structcontext;
-
- private ClassesProcessor clprocessor;
-
- public Fernflower(IBytecodeProvider provider, IDecompilatSaver saver, HashMap<String, Object> propertiesCustom) {
-
- structcontext = new StructContext(saver, this, new LazyLoader(provider));
+ private StructContext structContext;
+ private ClassesProcessor classesProcessor;
+ public Fernflower(IBytecodeProvider provider, IDecompilatSaver saver, Map<String, Object> propertiesCustom) {
+ structContext = new StructContext(saver, this, new LazyLoader(provider));
DecompilerContext.initContext(propertiesCustom);
DecompilerContext.setCounterContainer(new CounterContainer());
}
public void decompileContext() {
-
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
- new IdentifierConverter().rename(structcontext);
+ new IdentifierConverter().rename(structContext);
}
- clprocessor = new ClassesProcessor(structcontext);
+ classesProcessor = new ClassesProcessor(structContext);
- DecompilerContext.setClassProcessor(clprocessor);
- DecompilerContext.setStructContext(structcontext);
+ DecompilerContext.setClassProcessor(classesProcessor);
+ DecompilerContext.setStructContext(structContext);
- structcontext.saveContext();
+ structContext.saveContext();
}
public void clearContext() {
DecompilerContext.setCurrentContext(null);
}
- public String getClassEntryName(StructClass cl, String entryname) {
-
- ClassNode node = clprocessor.getMapRootClasses().get(cl.qualifiedName);
+ public String getClassEntryName(StructClass cl, String entryName) {
+ ClassNode node = classesProcessor.getMapRootClasses().get(cl.qualifiedName);
if (node.type != ClassNode.CLASS_ROOT) {
return null;
}
else {
if (DecompilerContext.getOption(IFernflowerPreferences.RENAME_ENTITIES)) {
String simple_classname = cl.qualifiedName.substring(cl.qualifiedName.lastIndexOf('/') + 1);
- return entryname.substring(0, entryname.lastIndexOf('/') + 1) + simple_classname + ".java";
+ return entryName.substring(0, entryName.lastIndexOf('/') + 1) + simple_classname + ".java";
}
else {
- return entryname.substring(0, entryname.lastIndexOf(".class")) + ".java";
+ return entryName.substring(0, entryName.lastIndexOf(".class")) + ".java";
}
}
}
- public StructContext getStructcontext() {
- return structcontext;
+ public StructContext getStructContext() {
+ return structContext;
}
public String getClassContent(StructClass cl) {
-
- String res = null;
-
try {
- StringWriter strwriter = new StringWriter();
- clprocessor.writeClass(structcontext, cl, new BufferedWriter(strwriter));
-
- res = strwriter.toString();
- }
- catch (ThreadDeath ex) {
- throw ex;
+ StringWriter writer = new StringWriter();
+ classesProcessor.writeClass(cl, new BufferedWriter(writer));
+ return writer.toString();
}
catch (Throwable ex) {
DecompilerContext.getLogger().writeMessage("Class " + cl.qualifiedName + " couldn't be fully decompiled.", ex);
+ return null;
}
-
- return res;
}
}
diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
index bfb4e70..d499324 100644
--- a/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
+++ b/src/org/jetbrains/java/decompiler/main/decompiler/ConsoleDecompiler.java
@@ -128,7 +128,7 @@ public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver {
}
public void addSpace(File file, boolean isOwn) throws IOException {
- fernflower.getStructcontext().addSpace(file, isOwn);
+ fernflower.getStructContext().addSpace(file, isOwn);
}
public void decompileContext(File root) {
@@ -213,7 +213,7 @@ public class ConsoleDecompiler implements IBytecodeProvider, IDecompilatSaver {
ZipOutputStream out = mapArchiveStreams.get(filename);
out.putNextEntry(new ZipEntry(entryName));
- InterpreterUtil.copyInputStream(in, out);
+ InterpreterUtil.copyStream(in, out);
in.close();
}
}
diff --git a/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java b/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java
index dab59e9..212a8bd 100644
--- a/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java
+++ b/src/org/jetbrains/java/decompiler/main/decompiler/IdeDecompiler.java
@@ -40,7 +40,7 @@ public class IdeDecompiler {
}
public void addSpace(File file, boolean isOwn) throws IOException {
- fernflower.getStructcontext().addSpace(file, isOwn);
+ fernflower.getStructContext().addSpace(file, isOwn);
}
public void decompileContext() {
diff --git a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
index 4ef8ba9..c942bad 100644
--- a/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
+++ b/src/org/jetbrains/java/decompiler/main/extern/IFernflowerPreferences.java
@@ -15,6 +15,8 @@
*/
package org.jetbrains.java.decompiler.main.extern;
+import org.jetbrains.java.decompiler.util.InterpreterUtil;
+
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -75,10 +77,9 @@ public interface IFernflowerPreferences {
put(IDEA_NOT_NULL_ANNOTATION, "1");
put(LAMBDA_TO_ANONYMOUS_CLASS, "0");
- boolean win = System.getProperty("os.name", "").startsWith("Windows");
put(MAX_PROCESSING_METHOD, "0");
put(RENAME_ENTITIES, "0");
- put(NEW_LINE_SEPARATOR, (win ? "0" : "1"));
+ put(NEW_LINE_SEPARATOR, (InterpreterUtil.IS_WINDOWS ? "0" : "1"));
put(INDENT_STRING, " ");
}});
}
diff --git a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
index cbaf227..ae251b9 100644
--- a/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
+++ b/src/org/jetbrains/java/decompiler/main/rels/ClassWrapper.java
@@ -36,17 +36,14 @@ import org.jetbrains.java.decompiler.util.VBStyleCollection;
import java.io.IOException;
import java.util.HashSet;
+import java.util.Set;
public class ClassWrapper {
private StructClass classStruct;
-
- private HashSet<String> hideMembers = new HashSet<String>();
-
+ private Set<String> hiddenMembers = new HashSet<String>();
private VBStyleCollection<Exprent, String> staticFieldInitializers = new VBStyleCollection<Exprent, String>();
-
private VBStyleCollection<Exprent, String> dynamicFieldInitializers = new VBStyleCollection<Exprent, String>();
-
private VBStyleCollection<MethodWrapper, String> methods = new VBStyleCollection<MethodWrapper, String>();
@@ -54,7 +51,6 @@ public class ClassWrapper {
this.classStruct = classStruct;
}
- @SuppressWarnings("deprecation")
public void init() throws IOException {
DecompilerContext.setProperty(DecompilerContext.CURRENT_CLASS, classStruct);
@@ -111,7 +107,7 @@ public class ClassWrapper {
if (System.currentTimeMillis() >= stopAt) {
String message = "Processing time limit exceeded for method " + mt.getName() + ", execution interrupted.";
DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.ERROR);
- mtthread.stop();
+ killThread(mtthread);
isError = true;
break;
}
@@ -180,6 +176,11 @@ public class ClassWrapper {
DecompilerContext.getLogger().endClass();
}
+ @SuppressWarnings("deprecation")
+ private static void killThread(Thread thread) {
+ thread.stop();
+ }
+
public MethodWrapper getMethodWrapper(String name, String descriptor) {
return methods.getWithKey(InterpreterUtil.makeUniqueKey(name, descriptor));
}
@@ -192,8 +193,8 @@ public class ClassWrapper {
return methods;
}
- public HashSet<String> getHideMembers() {
- return hideMembers;
+ public Set<String> getHiddenMembers() {
+ return hiddenMembers;
}
public VBStyleCollection<Exprent, String> getStaticFieldInitializers() {
diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
index 003bdc2..3757d7e 100644
--- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
+++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java
@@ -50,7 +50,7 @@ public class NestedClassProcessor {
if (node.type == ClassNode.CLASS_LAMBDA && !node.lambda_information.is_method_reference) {
ClassNode node_content = DecompilerContext.getClassProcessor().getMapRootClasses().get(node.classStruct.qualifiedName);
if (node_content != null && node_content.wrapper != null) {
- node_content.wrapper.getHideMembers().add(node.lambda_information.content_method_key);
+ node_content.wrapper.getHiddenMembers().add(node.lambda_information.content_method_key);
}
}
@@ -528,7 +528,7 @@ public class NestedClassProcessor {
// 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());
- child.wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
+ child.wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()));
}
}
}
diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
index f61de85..7e5eaa5 100644
--- a/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
+++ b/src/org/jetbrains/java/decompiler/main/rels/NestedMemberAccess.java
@@ -440,7 +440,7 @@ public class NestedMemberAccess {
}
}
if (hide) {
- node.wrapper.getHideMembers().add(InterpreterUtil.makeUniqueKey(invexpr.getName(), invexpr.getStringDescriptor()));
+ node.wrapper.getHiddenMembers().add(InterpreterUtil.makeUniqueKey(invexpr.getName(), invexpr.getStringDescriptor()));
}
}
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 8790624..8ff9fe5 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
@@ -117,7 +117,7 @@ public class AssignmentExprent extends Exprent {
if (field.isStatic() && fd.hasModifier(CodeConstants.ACC_FINAL)) {
fieldInClassInit = true;
}
- if (node.wrapper.getHideMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) {
+ if (node.wrapper.getHiddenMembers().contains(InterpreterUtil.makeUniqueKey(fd.getName(), fd.getDescriptor()))) {
hiddenField = true;
}
}
diff --git a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
index 89e11c0..cc4e4bd 100644
--- a/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
+++ b/src/org/jetbrains/java/decompiler/util/InterpreterUtil.java
@@ -25,6 +25,10 @@ import java.util.HashSet;
import java.util.List;
public class InterpreterUtil {
+ public static final boolean IS_WINDOWS = System.getProperty("os.name", "").startsWith("Windows");
+
+ 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);
@@ -33,12 +37,9 @@ public class InterpreterUtil {
try {
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
- // magic number for Windows, 64Mb - 32Kb)
- int maxCount = (64 * 1024 * 1024) - (32 * 1024);
- long size = inChannel.size();
- long position = 0;
+ long size = inChannel.size(), position = 0;
while (position < size) {
- position += inChannel.transferTo(position, maxCount, outChannel);
+ position += inChannel.transferTo(position, CHANNEL_WINDOW_SIZE, outChannel);
}
}
finally {
@@ -50,11 +51,9 @@ public class InterpreterUtil {
}
}
- public static void copyInputStream(InputStream in, OutputStream out) throws IOException {
-
- byte[] buffer = new byte[1024];
+ public static void copyStream(InputStream in, OutputStream out) throws IOException {
+ byte[] buffer = new byte[BUFFER_SIZE];
int len;
-
while ((len = in.read(buffer)) >= 0) {
out.write(buffer, 0, len);
}
@@ -69,9 +68,7 @@ public class InterpreterUtil {
return buf.toString();
}
-
public static boolean equalSets(Collection<?> c1, Collection<?> c2) {
-
if (c1 == null) {
return c2 == null;
}
@@ -93,7 +90,6 @@ public class InterpreterUtil {
}
public static boolean equalObjectArrays(Object[] first, Object[] second) {
-
if (first == null || second == null) {
return equalObjects(first, second);
}
@@ -113,12 +109,11 @@ public class InterpreterUtil {
}
public static boolean equalLists(List<?> first, List<?> second) {
-
if (first == null) {
return second == null;
}
else if (second == null) {
- return first == null;
+ return false;
}
if (first.size() == second.size()) {