summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/analysis/JarIndex.java
diff options
context:
space:
mode:
authorGravatar jeff2014-08-26 00:27:44 -0400
committerGravatar jeff2014-08-26 00:27:44 -0400
commit5f44aac70f59898197c2a7625b74f901c3b31106 (patch)
tree7d2cc2e48201c92867786793966f356810b464fa /src/cuchaz/enigma/analysis/JarIndex.java
parentwrote CheckCastIterator to try to do generic type inference. It's too hard to... (diff)
downloadenigma-fork-5f44aac70f59898197c2a7625b74f901c3b31106.tar.gz
enigma-fork-5f44aac70f59898197c2a7625b74f901c3b31106.tar.xz
enigma-fork-5f44aac70f59898197c2a7625b74f901c3b31106.zip
implemented proper support for interfaces
Diffstat (limited to 'src/cuchaz/enigma/analysis/JarIndex.java')
-rw-r--r--src/cuchaz/enigma/analysis/JarIndex.java107
1 files changed, 100 insertions, 7 deletions
diff --git a/src/cuchaz/enigma/analysis/JarIndex.java b/src/cuchaz/enigma/analysis/JarIndex.java
index cb7508e..eaf6352 100644
--- a/src/cuchaz/enigma/analysis/JarIndex.java
+++ b/src/cuchaz/enigma/analysis/JarIndex.java
@@ -93,7 +93,12 @@ public class JarIndex
93 for( CtClass c : JarClassIterator.classes( jar ) ) 93 for( CtClass c : JarClassIterator.classes( jar ) )
94 { 94 {
95 fixClass( c ); 95 fixClass( c );
96 m_ancestries.addSuperclass( c.getName(), c.getClassFile().getSuperclass() ); 96 String className = Descriptor.toJvmName( c.getName() );
97 m_ancestries.addSuperclass( className, Descriptor.toJvmName( c.getClassFile().getSuperclass() ) );
98 for( String interfaceName : c.getClassFile().getInterfaces() )
99 {
100 m_ancestries.addInterface( className, Descriptor.toJvmName( interfaceName ) );
101 }
97 for( CtBehavior behavior : c.getDeclaredBehaviors() ) 102 for( CtBehavior behavior : c.getDeclaredBehaviors() )
98 { 103 {
99 indexBehavior( behavior ); 104 indexBehavior( behavior );
@@ -354,7 +359,6 @@ public class JarIndex
354 } 359 }
355 else if( callerClasses.size() > 1 ) 360 else if( callerClasses.size() > 1 )
356 { 361 {
357 // TEMP
358 System.out.println( "WARNING: Illegal constructor called by more than one class!" + callerClasses ); 362 System.out.println( "WARNING: Illegal constructor called by more than one class!" + callerClasses );
359 } 363 }
360 } 364 }
@@ -542,6 +546,13 @@ public class JarIndex
542 return rootNode; 546 return rootNode;
543 } 547 }
544 548
549 public ClassImplementationsTreeNode getClassImplementations( Translator deobfuscatingTranslator, ClassEntry obfClassEntry )
550 {
551 ClassImplementationsTreeNode node = new ClassImplementationsTreeNode( deobfuscatingTranslator, obfClassEntry );
552 node.load( m_ancestries );
553 return node;
554 }
555
545 public MethodInheritanceTreeNode getMethodInheritance( Translator deobfuscatingTranslator, MethodEntry obfMethodEntry ) 556 public MethodInheritanceTreeNode getMethodInheritance( Translator deobfuscatingTranslator, MethodEntry obfMethodEntry )
546 { 557 {
547 // travel to the ancestor implementation 558 // travel to the ancestor implementation
@@ -577,6 +588,90 @@ public class JarIndex
577 return rootNode; 588 return rootNode;
578 } 589 }
579 590
591 public MethodImplementationsTreeNode getMethodImplementations( Translator deobfuscatingTranslator, MethodEntry obfMethodEntry )
592 {
593 MethodEntry interfaceMethodEntry;
594
595 // is this method on an interface?
596 if( m_ancestries.isInterface( obfMethodEntry.getClassName() ) )
597 {
598 interfaceMethodEntry = obfMethodEntry;
599 }
600 else
601 {
602 // get the interface class
603 List<MethodEntry> methodInterfaces = Lists.newArrayList();
604 for( String interfaceName : m_ancestries.getInterfaces( obfMethodEntry.getClassName() ) )
605 {
606 // is this method defined in this interface?
607 MethodEntry methodInterface = new MethodEntry(
608 new ClassEntry( interfaceName ),
609 obfMethodEntry.getName(),
610 obfMethodEntry.getSignature()
611 );
612 if( isMethodImplemented( methodInterface ) )
613 {
614 methodInterfaces.add( methodInterface );
615 }
616 }
617 if( methodInterfaces.isEmpty() )
618 {
619 return null;
620 }
621 if( methodInterfaces.size() > 1 )
622 {
623 throw new Error( "Too many interfaces define this method! This is not yet supported by Enigma!" );
624 }
625 interfaceMethodEntry = methodInterfaces.get( 0 );
626 }
627
628 MethodImplementationsTreeNode rootNode = new MethodImplementationsTreeNode( deobfuscatingTranslator, interfaceMethodEntry );
629 rootNode.load( this );
630 return rootNode;
631 }
632
633 public Set<MethodEntry> getRelatedMethodImplementations( MethodEntry obfMethodEntry )
634 {
635 Set<MethodEntry> methodEntries = Sets.newHashSet();
636 getRelatedMethodImplementations( methodEntries, getMethodInheritance( null, obfMethodEntry ) );
637 return methodEntries;
638 }
639
640 private void getRelatedMethodImplementations( Set<MethodEntry> methodEntries, MethodInheritanceTreeNode node )
641 {
642 MethodEntry methodEntry = node.getMethodEntry();
643 if( isMethodImplemented( methodEntry ) )
644 {
645 // collect the entry
646 methodEntries.add( methodEntry );
647 }
648
649 // look at interface methods too
650 getRelatedMethodImplementations( methodEntries, getMethodImplementations( null, methodEntry ) );
651
652 // recurse
653 for( int i=0; i<node.getChildCount(); i++ )
654 {
655 getRelatedMethodImplementations( methodEntries, (MethodInheritanceTreeNode)node.getChildAt( i ) );
656 }
657 }
658
659 private void getRelatedMethodImplementations( Set<MethodEntry> methodEntries, MethodImplementationsTreeNode node )
660 {
661 MethodEntry methodEntry = node.getMethodEntry();
662 if( isMethodImplemented( methodEntry ) )
663 {
664 // collect the entry
665 methodEntries.add( methodEntry );
666 }
667
668 // recurse
669 for( int i=0; i<node.getChildCount(); i++ )
670 {
671 getRelatedMethodImplementations( methodEntries, (MethodImplementationsTreeNode)node.getChildAt( i ) );
672 }
673 }
674
580 public Collection<EntryReference<FieldEntry,BehaviorEntry>> getFieldReferences( FieldEntry fieldEntry ) 675 public Collection<EntryReference<FieldEntry,BehaviorEntry>> getFieldReferences( FieldEntry fieldEntry )
581 { 676 {
582 return m_fieldReferences.get( fieldEntry ); 677 return m_fieldReferences.get( fieldEntry );
@@ -626,16 +721,14 @@ public class JarIndex
626 { 721 {
627 // for each key/value pair... 722 // for each key/value pair...
628 Set<Map.Entry<Key,Val>> entriesToAdd = Sets.newHashSet(); 723 Set<Map.Entry<Key,Val>> entriesToAdd = Sets.newHashSet();
629 Iterator<Map.Entry<Key,Val>> iter = map.entries().iterator(); 724 for( Map.Entry<Key,Val> entry : map.entries() )
630 while( iter.hasNext() )
631 { 725 {
632 Map.Entry<Key,Val> entry = iter.next();
633 iter.remove();
634 entriesToAdd.add( new AbstractMap.SimpleEntry<Key,Val>( 726 entriesToAdd.add( new AbstractMap.SimpleEntry<Key,Val>(
635 renameClassesInThing( renames, entry.getKey() ), 727 renameClassesInThing( renames, entry.getKey() ),
636 renameClassesInThing( renames, entry.getValue() ) 728 renameClassesInThing( renames, entry.getValue() )
637 ) ); 729 ) );
638 } 730 }
731 map.clear();
639 for( Map.Entry<Key,Val> entry : entriesToAdd ) 732 for( Map.Entry<Key,Val> entry : entriesToAdd )
640 { 733 {
641 map.put( entry.getKey(), entry.getValue() ); 734 map.put( entry.getKey(), entry.getValue() );
@@ -761,5 +854,5 @@ public class JarIndex
761 return thing; 854 return thing;
762 } 855 }
763 return thing; 856 return thing;
764 } 857 }
765} 858}