diff options
| author | 2014-08-26 00:27:44 -0400 | |
|---|---|---|
| committer | 2014-08-26 00:27:44 -0400 | |
| commit | 5f44aac70f59898197c2a7625b74f901c3b31106 (patch) | |
| tree | 7d2cc2e48201c92867786793966f356810b464fa /src/cuchaz/enigma/analysis/JarIndex.java | |
| parent | wrote CheckCastIterator to try to do generic type inference. It's too hard to... (diff) | |
| download | enigma-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.java | 107 |
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 | } |