From 663631f0456fcc245dd835889f86541d75161c53 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 28 Aug 2014 20:52:43 +0400 Subject: java-decompiler: post-import cleanup (classes moved) --- .../main/collectors/ImportCollector.java | 157 +++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java (limited to 'src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java') diff --git a/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java new file mode 100644 index 0000000..cdc6529 --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/collectors/ImportCollector.java @@ -0,0 +1,157 @@ +/* + * Fernflower - The Analytical Java Decompiler + * http://www.reversed-java.com + * + * (C) 2008 - 2010, Stiver + * + * This software is NEITHER public domain NOR free software + * as per GNU License. See license.txt for more details. + * + * This software is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. + */ + +package org.jetbrains.java.decompiler.main.collectors; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map.Entry; + +import org.jetbrains.java.decompiler.main.ClassesProcessor; +import org.jetbrains.java.decompiler.main.DecompilerContext; +import org.jetbrains.java.decompiler.main.ClassesProcessor.ClassNode; +import org.jetbrains.java.decompiler.struct.StructContext; + + +public class ImportCollector { + + private static final String JAVA_LANG_PACKAGE = "java.lang"; + + private HashMap mapSimpleNames = new HashMap(); + + private HashSet setNotImportedNames = new HashSet(); + + private String currentPackageSlash = ""; + + private String currentPackagePoint = ""; + + public ImportCollector(ClassNode root) { + + String clname = root.classStruct.qualifiedName; + int index = clname.lastIndexOf("/"); + if(index >= 0) { + currentPackageSlash = clname.substring(0, index); + currentPackagePoint = currentPackageSlash.replace('/', '.'); + currentPackageSlash += "/"; + } + } + + 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('.', '/')); + + String retname = null; + + if(node != null && node.classStruct.isOwn()) { + + retname = node.simpleName; + + while(node.parent != null && node.type == ClassNode.CLASS_MEMBER) { + retname = node.parent.simpleName+"."+retname; + node = node.parent; + } + + if(node.type == ClassNode.CLASS_ROOT) { + fullname = node.classStruct.qualifiedName; + fullname = fullname.replace('/', '.'); + } else { + return retname; + } + + } else if(node == null || !node.classStruct.isOwn()) { + fullname = fullname.replace('$', '.'); + } + + String nshort = fullname; + String npackage = ""; + + int lastpoint = fullname.lastIndexOf("."); + + if(lastpoint >= 0) { + nshort = fullname.substring(lastpoint+1); + npackage = fullname.substring(0, lastpoint); + } + + StructContext context = DecompilerContext.getStructcontext(); + + boolean existsDefaultClass = (context.getClass(currentPackageSlash+nshort) != null + && !npackage.equals(currentPackagePoint)) // current package + || (context.getClass(nshort) != null); // default package + + if(existsDefaultClass || + (mapSimpleNames.containsKey(nshort) && !npackage.equals(mapSimpleNames.get(nshort)))) { + return fullname; + } else if(!mapSimpleNames.containsKey(nshort)) { + mapSimpleNames.put(nshort, npackage); + + if(!imported) { + setNotImportedNames.add(nshort); + } + } + + return retname==null?nshort:retname; + } + + public void writeImports(BufferedWriter writer) throws IOException { + + for(String s: packImports()) { + writer.write("import "); + writer.write(s); + writer.write(";"); + writer.write(DecompilerContext.getNewLineSeparator()); + } + + } + + 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; + } + }); + + List res = new ArrayList(); + for(Entry ent: lst) { + if(!setNotImportedNames.contains(ent.getKey()) // not the current class or one of the nested ones. Also not the empty package. + && !JAVA_LANG_PACKAGE.equals(ent.getValue()) + && ent.getValue().length() > 0) { + + String imp = ent.getValue()+"."+ent.getKey(); + res.add(imp); + } + } + + return res; + } + + +} -- cgit v1.2.3