From 2b2249e873c4adfd2dd6e8f1f2489ccd9f6aa021 Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Sat, 19 May 2018 17:02:46 +0200 Subject: Initial port to ASM --- src/test/java/cuchaz/enigma/TestDeobfed.java | 6 +- src/test/java/cuchaz/enigma/TestEntryFactory.java | 28 +-- src/test/java/cuchaz/enigma/TestInnerClasses.java | 47 +--- .../enigma/TestJarIndexConstructorReferences.java | 78 +++--- .../cuchaz/enigma/TestJarIndexInheritanceTree.java | 111 ++++----- .../java/cuchaz/enigma/TestJarIndexLoneClass.java | 37 ++- .../java/cuchaz/enigma/TestMethodDescriptor.java | 247 +++++++++++++++++++ src/test/java/cuchaz/enigma/TestSignature.java | 270 --------------------- .../java/cuchaz/enigma/TestTokensConstructors.java | 90 ++++--- .../java/cuchaz/enigma/TestTypeDescriptor.java | 243 +++++++++++++++++++ 10 files changed, 655 insertions(+), 502 deletions(-) create mode 100644 src/test/java/cuchaz/enigma/TestMethodDescriptor.java delete mode 100644 src/test/java/cuchaz/enigma/TestSignature.java create mode 100644 src/test/java/cuchaz/enigma/TestTypeDescriptor.java (limited to 'src/test/java') diff --git a/src/test/java/cuchaz/enigma/TestDeobfed.java b/src/test/java/cuchaz/enigma/TestDeobfed.java index e6c1b746..fbdebd61 100644 --- a/src/test/java/cuchaz/enigma/TestDeobfed.java +++ b/src/test/java/cuchaz/enigma/TestDeobfed.java @@ -12,6 +12,8 @@ package cuchaz.enigma; import cuchaz.enigma.analysis.JarIndex; +import cuchaz.enigma.analysis.ParsedJar; +import cuchaz.enigma.mapping.ReferencedEntryPool; import org.junit.BeforeClass; import org.junit.Test; @@ -30,8 +32,8 @@ public class TestDeobfed { public static void beforeClass() throws Exception { jar = new JarFile("build/test-deobf/translation.jar"); - index = new JarIndex(); - index.indexJar(jar, true); + index = new JarIndex(new ReferencedEntryPool()); + index.indexJar(new ParsedJar(jar), true); } @Test diff --git a/src/test/java/cuchaz/enigma/TestEntryFactory.java b/src/test/java/cuchaz/enigma/TestEntryFactory.java index 1c527f53..067dcbfe 100644 --- a/src/test/java/cuchaz/enigma/TestEntryFactory.java +++ b/src/test/java/cuchaz/enigma/TestEntryFactory.java @@ -25,7 +25,7 @@ public class TestEntryFactory { } public static FieldEntry newField(ClassEntry classEntry, String fieldName, String fieldType) { - return new FieldEntry(classEntry, fieldName, new Type(fieldType)); + return new FieldEntry(classEntry, fieldName, new TypeDescriptor(fieldType)); } public static MethodEntry newMethod(String className, String methodName, String methodSignature) { @@ -33,30 +33,14 @@ public class TestEntryFactory { } public static MethodEntry newMethod(ClassEntry classEntry, String methodName, String methodSignature) { - return new MethodEntry(classEntry, methodName, new Signature(methodSignature)); + return new MethodEntry(classEntry, methodName, new MethodDescriptor(methodSignature)); } - public static ConstructorEntry newConstructor(String className, String signature) { - return newConstructor(newClass(className), signature); + public static EntryReference newFieldReferenceByMethod(FieldEntry fieldEntry, String callerClassName, String callerName, String callerSignature) { + return new EntryReference<>(fieldEntry, "", newMethod(callerClassName, callerName, callerSignature)); } - public static ConstructorEntry newConstructor(ClassEntry classEntry, String signature) { - return new ConstructorEntry(classEntry, new Signature(signature)); - } - - public static EntryReference newFieldReferenceByMethod(FieldEntry fieldEntry, String callerClassName, String callerName, String callerSignature) { - return new EntryReference(fieldEntry, "", newMethod(callerClassName, callerName, callerSignature)); - } - - public static EntryReference newFieldReferenceByConstructor(FieldEntry fieldEntry, String callerClassName, String callerSignature) { - return new EntryReference(fieldEntry, "", newConstructor(callerClassName, callerSignature)); - } - - public static EntryReference newBehaviorReferenceByMethod(BehaviorEntry behaviorEntry, String callerClassName, String callerName, String callerSignature) { - return new EntryReference(behaviorEntry, "", newMethod(callerClassName, callerName, callerSignature)); - } - - public static EntryReference newBehaviorReferenceByConstructor(BehaviorEntry behaviorEntry, String callerClassName, String callerSignature) { - return new EntryReference(behaviorEntry, "", newConstructor(callerClassName, callerSignature)); + public static EntryReference newBehaviorReferenceByMethod(MethodEntry methodEntry, String callerClassName, String callerName, String callerSignature) { + return new EntryReference<>(methodEntry, "", newMethod(callerClassName, callerName, callerSignature)); } } diff --git a/src/test/java/cuchaz/enigma/TestInnerClasses.java b/src/test/java/cuchaz/enigma/TestInnerClasses.java index 38db0df9..30e127e6 100644 --- a/src/test/java/cuchaz/enigma/TestInnerClasses.java +++ b/src/test/java/cuchaz/enigma/TestInnerClasses.java @@ -12,7 +12,9 @@ package cuchaz.enigma; import cuchaz.enigma.analysis.JarIndex; +import cuchaz.enigma.analysis.ParsedJar; import cuchaz.enigma.mapping.ClassEntry; +import cuchaz.enigma.mapping.ReferencedEntryPool; import org.junit.Test; import java.util.jar.JarFile; @@ -26,16 +28,10 @@ import static org.hamcrest.Matchers.nullValue; public class TestInnerClasses { - private static final ClassEntry AnonymousOuter = newClass("a"); - private static final ClassEntry AnonymousInner = newClass("a$1"); private static final ClassEntry SimpleOuter = newClass("d"); private static final ClassEntry SimpleInner = newClass("d$a"); private static final ClassEntry ConstructorArgsOuter = newClass("c"); private static final ClassEntry ConstructorArgsInner = newClass("c$a"); - private static final ClassEntry AnonymousWithScopeArgsOuter = newClass("b"); - private static final ClassEntry AnonymousWithScopeArgsInner = newClass("b$1"); - private static final ClassEntry AnonymousWithOuterAccessOuter = newClass("e"); - private static final ClassEntry AnonymousWithOuterAccessInner = newClass("e$1"); private static final ClassEntry ClassTreeRoot = newClass("f"); private static final ClassEntry ClassTreeLevel1 = newClass("f$a"); private static final ClassEntry ClassTreeLevel2 = newClass("f$a$a"); @@ -45,9 +41,9 @@ public class TestInnerClasses { public TestInnerClasses() throws Exception { - index = new JarIndex(); + index = new JarIndex(new ReferencedEntryPool()); JarFile jar = new JarFile("build/test-obf/innerClasses.jar"); - index.indexJar(jar, true); + index.indexJar(new ParsedJar(jar), true); deobfuscator = new Deobfuscator(jar); } @@ -55,42 +51,16 @@ public class TestInnerClasses { public void simple() { assertThat(index.getOuterClass(SimpleInner), is(SimpleOuter)); assertThat(index.getInnerClasses(SimpleOuter), containsInAnyOrder(SimpleInner)); - assertThat(index.isAnonymousClass(SimpleInner), is(false)); decompile(SimpleOuter); } - @Test - public void anonymous() { - assertThat(index.getOuterClass(AnonymousInner), is(AnonymousOuter)); - assertThat(index.getInnerClasses(AnonymousOuter), containsInAnyOrder(AnonymousInner)); - assertThat(index.isAnonymousClass(AnonymousInner), is(true)); - decompile(AnonymousOuter); - } - @Test public void constructorArgs() { assertThat(index.getOuterClass(ConstructorArgsInner), is(ConstructorArgsOuter)); assertThat(index.getInnerClasses(ConstructorArgsOuter), containsInAnyOrder(ConstructorArgsInner)); - assertThat(index.isAnonymousClass(ConstructorArgsInner), is(false)); decompile(ConstructorArgsOuter); } - @Test - public void anonymousWithScopeArgs() { - assertThat(index.getOuterClass(AnonymousWithScopeArgsInner), is(AnonymousWithScopeArgsOuter)); - assertThat(index.getInnerClasses(AnonymousWithScopeArgsOuter), containsInAnyOrder(AnonymousWithScopeArgsInner)); - assertThat(index.isAnonymousClass(AnonymousWithScopeArgsInner), is(true)); - decompile(AnonymousWithScopeArgsOuter); - } - - @Test - public void anonymousWithOuterAccess() { - assertThat(index.getOuterClass(AnonymousWithOuterAccessInner), is(AnonymousWithOuterAccessOuter)); - assertThat(index.getInnerClasses(AnonymousWithOuterAccessOuter), containsInAnyOrder(AnonymousWithOuterAccessInner)); - assertThat(index.isAnonymousClass(AnonymousWithOuterAccessInner), is(true)); - decompile(AnonymousWithOuterAccessOuter); - } - @Test public void classTree() { @@ -101,8 +71,7 @@ public class TestInnerClasses { // level 1 ClassEntry fullClassEntry = new ClassEntry(ClassTreeRoot.getName() - + "$" + ClassTreeLevel1.getInnermostClassName() - ); + + "$" + ClassTreeLevel1.getInnermostClassName()); assertThat(index.containsObfClass(fullClassEntry), is(true)); assertThat(index.getOuterClass(ClassTreeLevel1), is(ClassTreeRoot)); assertThat(index.getInnerClasses(ClassTreeLevel1), containsInAnyOrder(ClassTreeLevel2)); @@ -110,8 +79,7 @@ public class TestInnerClasses { // level 2 fullClassEntry = new ClassEntry(ClassTreeRoot.getName() + "$" + ClassTreeLevel1.getInnermostClassName() - + "$" + ClassTreeLevel2.getInnermostClassName() - ); + + "$" + ClassTreeLevel2.getInnermostClassName()); assertThat(index.containsObfClass(fullClassEntry), is(true)); assertThat(index.getOuterClass(ClassTreeLevel2), is(ClassTreeLevel1)); assertThat(index.getInnerClasses(ClassTreeLevel2), containsInAnyOrder(ClassTreeLevel3)); @@ -120,8 +88,7 @@ public class TestInnerClasses { fullClassEntry = new ClassEntry(ClassTreeRoot.getName() + "$" + ClassTreeLevel1.getInnermostClassName() + "$" + ClassTreeLevel2.getInnermostClassName() - + "$" + ClassTreeLevel3.getInnermostClassName() - ); + + "$" + ClassTreeLevel3.getInnermostClassName()); assertThat(index.containsObfClass(fullClassEntry), is(true)); assertThat(index.getOuterClass(ClassTreeLevel3), is(ClassTreeLevel2)); assertThat(index.getInnerClasses(ClassTreeLevel3), is(empty())); diff --git a/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java b/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java index edb859a7..b20b27b6 100644 --- a/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java +++ b/src/test/java/cuchaz/enigma/TestJarIndexConstructorReferences.java @@ -13,22 +13,20 @@ package cuchaz.enigma; import cuchaz.enigma.analysis.EntryReference; import cuchaz.enigma.analysis.JarIndex; -import cuchaz.enigma.mapping.BehaviorEntry; +import cuchaz.enigma.analysis.ParsedJar; import cuchaz.enigma.mapping.ClassEntry; +import cuchaz.enigma.mapping.MethodDefEntry; +import cuchaz.enigma.mapping.MethodEntry; +import cuchaz.enigma.mapping.ReferencedEntryPool; import org.junit.Test; import java.io.File; import java.util.Collection; import java.util.jar.JarFile; -import static cuchaz.enigma.TestEntryFactory.newBehaviorReferenceByConstructor; -import static cuchaz.enigma.TestEntryFactory.newBehaviorReferenceByMethod; -import static cuchaz.enigma.TestEntryFactory.newClass; -import static cuchaz.enigma.TestEntryFactory.newConstructor; +import static cuchaz.enigma.TestEntryFactory.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.*; public class TestJarIndexConstructorReferences { @@ -41,90 +39,90 @@ public class TestJarIndexConstructorReferences { private ClassEntry callerClass = newClass("b"); public TestJarIndexConstructorReferences() - throws Exception { + throws Exception { File jarFile = new File("build/test-obf/constructors.jar"); - index = new JarIndex(); - index.indexJar(new JarFile(jarFile), false); + index = new JarIndex(new ReferencedEntryPool()); + index.indexJar(new ParsedJar(new JarFile(jarFile)), false); } @Test public void obfEntries() { assertThat(index.getObfClassEntries(), containsInAnyOrder(newClass("cuchaz/enigma/inputs/Keep"), baseClass, - subClass, subsubClass, defaultClass, callerClass)); + subClass, subsubClass, defaultClass, callerClass)); } @Test @SuppressWarnings("unchecked") public void baseDefault() { - BehaviorEntry source = newConstructor(baseClass, "()V"); - Collection> references = index.getBehaviorReferences(source); + MethodEntry source = newMethod(baseClass, "", "()V"); + Collection> references = index.getMethodReferences(source); assertThat(references, containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "a", "()V"), - newBehaviorReferenceByConstructor(source, subClass.getName(), "()V"), - newBehaviorReferenceByConstructor(source, subClass.getName(), "(III)V") + newBehaviorReferenceByMethod(source, callerClass.getName(), "a", "()V"), + newBehaviorReferenceByMethod(source, subClass.getName(), "", "()V"), + newBehaviorReferenceByMethod(source, subClass.getName(), "", "(III)V") )); } @Test @SuppressWarnings("unchecked") public void baseInt() { - BehaviorEntry source = newConstructor(baseClass, "(I)V"); - assertThat(index.getBehaviorReferences(source), containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "b", "()V") + MethodEntry source = newMethod(baseClass, "", "(I)V"); + assertThat(index.getMethodReferences(source), containsInAnyOrder( + newBehaviorReferenceByMethod(source, callerClass.getName(), "b", "()V") )); } @Test @SuppressWarnings("unchecked") public void subDefault() { - BehaviorEntry source = newConstructor(subClass, "()V"); - assertThat(index.getBehaviorReferences(source), containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "c", "()V"), - newBehaviorReferenceByConstructor(source, subClass.getName(), "(I)V") + MethodEntry source = newMethod(subClass, "", "()V"); + assertThat(index.getMethodReferences(source), containsInAnyOrder( + newBehaviorReferenceByMethod(source, callerClass.getName(), "c", "()V"), + newBehaviorReferenceByMethod(source, subClass.getName(), "", "(I)V") )); } @Test @SuppressWarnings("unchecked") public void subInt() { - BehaviorEntry source = newConstructor(subClass, "(I)V"); - assertThat(index.getBehaviorReferences(source), containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "d", "()V"), - newBehaviorReferenceByConstructor(source, subClass.getName(), "(II)V"), - newBehaviorReferenceByConstructor(source, subsubClass.getName(), "(I)V") + MethodEntry source = newMethod(subClass, "", "(I)V"); + assertThat(index.getMethodReferences(source), containsInAnyOrder( + newBehaviorReferenceByMethod(source, callerClass.getName(), "d", "()V"), + newBehaviorReferenceByMethod(source, subClass.getName(), "", "(II)V"), + newBehaviorReferenceByMethod(source, subsubClass.getName(), "", "(I)V") )); } @Test @SuppressWarnings("unchecked") public void subIntInt() { - BehaviorEntry source = newConstructor(subClass, "(II)V"); - assertThat(index.getBehaviorReferences(source), containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "e", "()V") + MethodEntry source = newMethod(subClass, "", "(II)V"); + assertThat(index.getMethodReferences(source), containsInAnyOrder( + newBehaviorReferenceByMethod(source, callerClass.getName(), "e", "()V") )); } @Test public void subIntIntInt() { - BehaviorEntry source = newConstructor(subClass, "(III)V"); - assertThat(index.getBehaviorReferences(source), is(empty())); + MethodEntry source = newMethod(subClass, "", "(III)V"); + assertThat(index.getMethodReferences(source), is(empty())); } @Test @SuppressWarnings("unchecked") public void subsubInt() { - BehaviorEntry source = newConstructor(subsubClass, "(I)V"); - assertThat(index.getBehaviorReferences(source), containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "f", "()V") + MethodEntry source = newMethod(subsubClass, "", "(I)V"); + assertThat(index.getMethodReferences(source), containsInAnyOrder( + newBehaviorReferenceByMethod(source, callerClass.getName(), "f", "()V") )); } @Test @SuppressWarnings("unchecked") public void defaultConstructable() { - BehaviorEntry source = newConstructor(defaultClass, "()V"); - assertThat(index.getBehaviorReferences(source), containsInAnyOrder( - newBehaviorReferenceByMethod(source, callerClass.getName(), "g", "()V") + MethodEntry source = newMethod(defaultClass, "", "()V"); + assertThat(index.getMethodReferences(source), containsInAnyOrder( + newBehaviorReferenceByMethod(source, callerClass.getName(), "g", "()V") )); } } diff --git a/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java b/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java index 62469780..d1c85964 100644 --- a/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java +++ b/src/test/java/cuchaz/enigma/TestJarIndexInheritanceTree.java @@ -11,14 +11,8 @@ package cuchaz.enigma; -import cuchaz.enigma.analysis.Access; -import cuchaz.enigma.analysis.EntryReference; -import cuchaz.enigma.analysis.JarIndex; -import cuchaz.enigma.analysis.TranslationIndex; -import cuchaz.enigma.mapping.BehaviorEntry; -import cuchaz.enigma.mapping.ClassEntry; -import cuchaz.enigma.mapping.FieldEntry; -import cuchaz.enigma.mapping.MethodEntry; +import cuchaz.enigma.analysis.*; +import cuchaz.enigma.mapping.*; import org.junit.Test; import java.util.Collection; @@ -27,10 +21,7 @@ import java.util.jar.JarFile; import static cuchaz.enigma.TestEntryFactory.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.*; public class TestJarIndexInheritanceTree { @@ -45,15 +36,15 @@ public class TestJarIndexInheritanceTree { private FieldEntry numThingsField = newField(subClassB, "a", "I"); public TestJarIndexInheritanceTree() - throws Exception { - index = new JarIndex(); - index.indexJar(new JarFile("build/test-obf/inheritanceTree.jar"), false); + throws Exception { + index = new JarIndex(new ReferencedEntryPool()); + index.indexJar(new ParsedJar(new JarFile("build/test-obf/inheritanceTree.jar")), false); } @Test public void obfEntries() { assertThat(index.getObfClassEntries(), containsInAnyOrder( - newClass("cuchaz/enigma/inputs/Keep"), baseClass, subClassA, subClassAA, subClassB + newClass("cuchaz/enigma/inputs/Keep"), baseClass, subClassA, subClassAA, subClassB )); } @@ -98,33 +89,33 @@ public class TestJarIndexInheritanceTree { // getName() entries = index.getRelatedMethodImplementations(newMethod(baseClass, "a", "()Ljava/lang/String;")); assertThat(entries, containsInAnyOrder( - newMethod(baseClass, "a", "()Ljava/lang/String;"), - newMethod(subClassAA, "a", "()Ljava/lang/String;") + newMethod(baseClass, "a", "()Ljava/lang/String;"), + newMethod(subClassAA, "a", "()Ljava/lang/String;") )); entries = index.getRelatedMethodImplementations(newMethod(subClassAA, "a", "()Ljava/lang/String;")); assertThat(entries, containsInAnyOrder( - newMethod(baseClass, "a", "()Ljava/lang/String;"), - newMethod(subClassAA, "a", "()Ljava/lang/String;") + newMethod(baseClass, "a", "()Ljava/lang/String;"), + newMethod(subClassAA, "a", "()Ljava/lang/String;") )); // doBaseThings() entries = index.getRelatedMethodImplementations(newMethod(baseClass, "a", "()V")); assertThat(entries, containsInAnyOrder( - newMethod(baseClass, "a", "()V"), - newMethod(subClassAA, "a", "()V"), - newMethod(subClassB, "a", "()V") + newMethod(baseClass, "a", "()V"), + newMethod(subClassAA, "a", "()V"), + newMethod(subClassB, "a", "()V") )); entries = index.getRelatedMethodImplementations(newMethod(subClassAA, "a", "()V")); assertThat(entries, containsInAnyOrder( - newMethod(baseClass, "a", "()V"), - newMethod(subClassAA, "a", "()V"), - newMethod(subClassB, "a", "()V") + newMethod(baseClass, "a", "()V"), + newMethod(subClassAA, "a", "()V"), + newMethod(subClassB, "a", "()V") )); entries = index.getRelatedMethodImplementations(newMethod(subClassB, "a", "()V")); assertThat(entries, containsInAnyOrder( - newMethod(baseClass, "a", "()V"), - newMethod(subClassAA, "a", "()V"), - newMethod(subClassB, "a", "()V") + newMethod(baseClass, "a", "()V"), + newMethod(subClassAA, "a", "()V"), + newMethod(subClassB, "a", "()V") )); // doBThings @@ -135,20 +126,20 @@ public class TestJarIndexInheritanceTree { @Test @SuppressWarnings("unchecked") public void fieldReferences() { - Collection> references; + Collection> references; // name references = index.getFieldReferences(nameField); assertThat(references, containsInAnyOrder( - newFieldReferenceByConstructor(nameField, baseClass.getName(), "(Ljava/lang/String;)V"), - newFieldReferenceByMethod(nameField, baseClass.getName(), "a", "()Ljava/lang/String;") + newFieldReferenceByMethod(nameField, baseClass.getName(), "", "(Ljava/lang/String;)V"), + newFieldReferenceByMethod(nameField, baseClass.getName(), "a", "()Ljava/lang/String;") )); // numThings references = index.getFieldReferences(numThingsField); assertThat(references, containsInAnyOrder( - newFieldReferenceByConstructor(numThingsField, subClassB.getName(), "()V"), - newFieldReferenceByMethod(numThingsField, subClassB.getName(), "b", "()V") + newFieldReferenceByMethod(numThingsField, subClassB.getName(), "", "()V"), + newFieldReferenceByMethod(numThingsField, subClassB.getName(), "b", "()V") )); } @@ -156,37 +147,37 @@ public class TestJarIndexInheritanceTree { @SuppressWarnings("unchecked") public void behaviorReferences() { - BehaviorEntry source; - Collection> references; + MethodEntry source; + Collection> references; // baseClass constructor - source = newConstructor(baseClass, "(Ljava/lang/String;)V"); - references = index.getBehaviorReferences(source); + source = newMethod(baseClass, "", "(Ljava/lang/String;)V"); + references = index.getMethodReferences(source); assertThat(references, containsInAnyOrder( - newBehaviorReferenceByConstructor(source, subClassA.getName(), "(Ljava/lang/String;)V"), - newBehaviorReferenceByConstructor(source, subClassB.getName(), "()V") + newBehaviorReferenceByMethod(source, subClassA.getName(), "", "(Ljava/lang/String;)V"), + newBehaviorReferenceByMethod(source, subClassB.getName(), "", "()V") )); // subClassA constructor - source = newConstructor(subClassA, "(Ljava/lang/String;)V"); - references = index.getBehaviorReferences(source); + source = newMethod(subClassA, "", "(Ljava/lang/String;)V"); + references = index.getMethodReferences(source); assertThat(references, containsInAnyOrder( - newBehaviorReferenceByConstructor(source, subClassAA.getName(), "()V") + newBehaviorReferenceByMethod(source, subClassAA.getName(), "", "()V") )); // baseClass.getName() source = newMethod(baseClass, "a", "()Ljava/lang/String;"); - references = index.getBehaviorReferences(source); + references = index.getMethodReferences(source); assertThat(references, containsInAnyOrder( - newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()Ljava/lang/String;"), - newBehaviorReferenceByMethod(source, subClassB.getName(), "a", "()V") + newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()Ljava/lang/String;"), + newBehaviorReferenceByMethod(source, subClassB.getName(), "a", "()V") )); // subclassAA.getName() source = newMethod(subClassAA, "a", "()Ljava/lang/String;"); - references = index.getBehaviorReferences(source); + references = index.getMethodReferences(source); assertThat(references, containsInAnyOrder( - newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()V") + newBehaviorReferenceByMethod(source, subClassAA.getName(), "a", "()V") )); } @@ -205,22 +196,22 @@ public class TestJarIndexInheritanceTree { // methods // getName() - assertThat(index.containsObfBehavior(newMethod(baseClass, "a", "()Ljava/lang/String;")), is(true)); - assertThat(index.containsObfBehavior(newMethod(subClassA, "a", "()Ljava/lang/String;")), is(false)); - assertThat(index.containsObfBehavior(newMethod(subClassAA, "a", "()Ljava/lang/String;")), is(true)); - assertThat(index.containsObfBehavior(newMethod(subClassB, "a", "()Ljava/lang/String;")), is(false)); + assertThat(index.containsObfMethod(newMethod(baseClass, "a", "()Ljava/lang/String;")), is(true)); + assertThat(index.containsObfMethod(newMethod(subClassA, "a", "()Ljava/lang/String;")), is(false)); + assertThat(index.containsObfMethod(newMethod(subClassAA, "a", "()Ljava/lang/String;")), is(true)); + assertThat(index.containsObfMethod(newMethod(subClassB, "a", "()Ljava/lang/String;")), is(false)); // doBaseThings() - assertThat(index.containsObfBehavior(newMethod(baseClass, "a", "()V")), is(true)); - assertThat(index.containsObfBehavior(newMethod(subClassA, "a", "()V")), is(false)); - assertThat(index.containsObfBehavior(newMethod(subClassAA, "a", "()V")), is(true)); - assertThat(index.containsObfBehavior(newMethod(subClassB, "a", "()V")), is(true)); + assertThat(index.containsObfMethod(newMethod(baseClass, "a", "()V")), is(true)); + assertThat(index.containsObfMethod(newMethod(subClassA, "a", "()V")), is(false)); + assertThat(index.containsObfMethod(newMethod(subClassAA, "a", "()V")), is(true)); + assertThat(index.containsObfMethod(newMethod(subClassB, "a", "()V")), is(true)); // doBThings() - assertThat(index.containsObfBehavior(newMethod(baseClass, "b", "()V")), is(false)); - assertThat(index.containsObfBehavior(newMethod(subClassA, "b", "()V")), is(false)); - assertThat(index.containsObfBehavior(newMethod(subClassAA, "b", "()V")), is(false)); - assertThat(index.containsObfBehavior(newMethod(subClassB, "b", "()V")), is(true)); + assertThat(index.containsObfMethod(newMethod(baseClass, "b", "()V")), is(false)); + assertThat(index.containsObfMethod(newMethod(subClassA, "b", "()V")), is(false)); + assertThat(index.containsObfMethod(newMethod(subClassAA, "b", "()V")), is(false)); + assertThat(index.containsObfMethod(newMethod(subClassB, "b", "()V")), is(true)); } } diff --git a/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java b/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java index 6cab1c84..d03f3fb4 100644 --- a/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java +++ b/src/test/java/cuchaz/enigma/TestJarIndexLoneClass.java @@ -28,16 +28,16 @@ public class TestJarIndexLoneClass { private JarIndex index; public TestJarIndexLoneClass() - throws Exception { - index = new JarIndex(); - index.indexJar(new JarFile("build/test-obf/loneClass.jar"), false); + throws Exception { + index = new JarIndex(new ReferencedEntryPool()); + index.indexJar(new ParsedJar(new JarFile("build/test-obf/loneClass.jar")), false); } @Test public void obfEntries() { assertThat(index.getObfClassEntries(), containsInAnyOrder( - newClass("cuchaz/enigma/inputs/Keep"), - newClass("a") + newClass("cuchaz/enigma/inputs/Keep"), + newClass("a") )); } @@ -61,7 +61,7 @@ public class TestJarIndexLoneClass { @Test public void classInheritance() { - ClassInheritanceTreeNode node = index.getClassInheritance(new Translator(), newClass("a")); + ClassInheritanceTreeNode node = index.getClassInheritance(new DirectionalTranslator(new ReferencedEntryPool()), newClass("a")); assertThat(node, is(not(nullValue()))); assertThat(node.getObfClassName(), is("a")); assertThat(node.getChildCount(), is(0)); @@ -70,7 +70,7 @@ public class TestJarIndexLoneClass { @Test public void methodInheritance() { MethodEntry source = newMethod("a", "a", "()Ljava/lang/String;"); - MethodInheritanceTreeNode node = index.getMethodInheritance(new Translator(), source); + MethodInheritanceTreeNode node = index.getMethodInheritance(new DirectionalTranslator(new ReferencedEntryPool()), source); assertThat(node, is(not(nullValue()))); assertThat(node.getMethodEntry(), is(source)); assertThat(node.getChildCount(), is(0)); @@ -78,21 +78,21 @@ public class TestJarIndexLoneClass { @Test public void classImplementations() { - ClassImplementationsTreeNode node = index.getClassImplementations(new Translator(), newClass("a")); + ClassImplementationsTreeNode node = index.getClassImplementations(new DirectionalTranslator(new ReferencedEntryPool()), newClass("a")); assertThat(node, is(nullValue())); } @Test public void methodImplementations() { MethodEntry source = newMethod("a", "a", "()Ljava/lang/String;"); - assertThat(index.getMethodImplementations(new Translator(), source), is(empty())); + assertThat(index.getMethodImplementations(new DirectionalTranslator(new ReferencedEntryPool()), source), is(empty())); } @Test public void relatedMethodImplementations() { Set entries = index.getRelatedMethodImplementations(newMethod("a", "a", "()Ljava/lang/String;")); assertThat(entries, containsInAnyOrder( - newMethod("a", "a", "()Ljava/lang/String;") + newMethod("a", "a", "()Ljava/lang/String;") )); } @@ -100,16 +100,16 @@ public class TestJarIndexLoneClass { @SuppressWarnings("unchecked") public void fieldReferences() { FieldEntry source = newField("a", "a", "Ljava/lang/String;"); - Collection> references = index.getFieldReferences(source); + Collection> references = index.getFieldReferences(source); assertThat(references, containsInAnyOrder( - newFieldReferenceByConstructor(source, "a", "(Ljava/lang/String;)V"), - newFieldReferenceByMethod(source, "a", "a", "()Ljava/lang/String;") + newFieldReferenceByMethod(source, "a", "", "(Ljava/lang/String;)V"), + newFieldReferenceByMethod(source, "a", "a", "()Ljava/lang/String;") )); } @Test public void behaviorReferences() { - assertThat(index.getBehaviorReferences(newMethod("a", "a", "()Ljava/lang/String;")), is(empty())); + assertThat(index.getMethodReferences(newMethod("a", "a", "()Ljava/lang/String;")), is(empty())); } @Test @@ -122,11 +122,6 @@ public class TestJarIndexLoneClass { assertThat(index.getOuterClass(newClass("a")), is(nullValue())); } - @Test - public void isAnonymousClass() { - assertThat(index.isAnonymousClass(newClass("a")), is(false)); - } - @Test public void interfaces() { assertThat(index.getInterfaces("a"), is(empty())); @@ -149,7 +144,7 @@ public class TestJarIndexLoneClass { assertThat(index.containsObfField(newField("a", "a", "Ljava/lang/String;")), is(true)); assertThat(index.containsObfField(newField("a", "b", "Ljava/lang/String;")), is(false)); assertThat(index.containsObfField(newField("a", "a", "LFoo;")), is(false)); - assertThat(index.containsObfBehavior(newMethod("a", "a", "()Ljava/lang/String;")), is(true)); - assertThat(index.containsObfBehavior(newMethod("a", "b", "()Ljava/lang/String;")), is(false)); + assertThat(index.containsObfMethod(newMethod("a", "a", "()Ljava/lang/String;")), is(true)); + assertThat(index.containsObfMethod(newMethod("a", "b", "()Ljava/lang/String;")), is(false)); } } diff --git a/src/test/java/cuchaz/enigma/TestMethodDescriptor.java b/src/test/java/cuchaz/enigma/TestMethodDescriptor.java new file mode 100644 index 00000000..48c46e52 --- /dev/null +++ b/src/test/java/cuchaz/enigma/TestMethodDescriptor.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma; + +import cuchaz.enigma.mapping.MethodDescriptor; +import cuchaz.enigma.mapping.TypeDescriptor; +import org.junit.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +public class TestMethodDescriptor { + + @Test + public void easiest() { + final MethodDescriptor sig = new MethodDescriptor("()V"); + assertThat(sig.getArgumentDescs(), is(empty())); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("V"))); + } + + @Test + public void primitives() { + { + final MethodDescriptor sig = new MethodDescriptor("(I)V"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("I") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("V"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("(I)I"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("I") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("I"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("(IBCJ)Z"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("I"), + new TypeDescriptor("B"), + new TypeDescriptor("C"), + new TypeDescriptor("J") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("Z"))); + } + } + + @Test + public void classes() { + { + final MethodDescriptor sig = new MethodDescriptor("([LFoo;)V"); + assertThat(sig.getArgumentDescs().size(), is(1)); + assertThat(sig.getArgumentDescs().get(0), is(new TypeDescriptor("[LFoo;"))); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("V"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("(LFoo;)LBar;"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("LFoo;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("LBar;"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("(LFoo;LMoo;LZoo;)LBar;"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("LFoo;"), + new TypeDescriptor("LMoo;"), + new TypeDescriptor("LZoo;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("LBar;"))); + } + } + + @Test + public void arrays() { + { + final MethodDescriptor sig = new MethodDescriptor("([I)V"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("[I") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("V"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("([I)[J"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("[I") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("[J"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("([I[Z[F)[D"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("[I"), + new TypeDescriptor("[Z"), + new TypeDescriptor("[F") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("[D"))); + } + } + + @Test + public void mixed() { + { + final MethodDescriptor sig = new MethodDescriptor("(I[JLFoo;)Z"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("I"), + new TypeDescriptor("[J"), + new TypeDescriptor("LFoo;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("Z"))); + } + { + final MethodDescriptor sig = new MethodDescriptor("(III)[LFoo;"); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("I"), + new TypeDescriptor("I"), + new TypeDescriptor("I") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("[LFoo;"))); + } + } + + @Test + public void replaceClasses() { + { + final MethodDescriptor oldSig = new MethodDescriptor("()V"); + final MethodDescriptor sig = oldSig.remap(s -> null); + assertThat(sig.getArgumentDescs(), is(empty())); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("V"))); + } + { + final MethodDescriptor oldSig = new MethodDescriptor("(IJLFoo;)V"); + final MethodDescriptor sig = oldSig.remap(s -> null); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("I"), + new TypeDescriptor("J"), + new TypeDescriptor("LFoo;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("V"))); + } + { + final MethodDescriptor oldSig = new MethodDescriptor("(LFoo;LBar;)LMoo;"); + final MethodDescriptor sig = oldSig.remap(s -> { + if (s.equals("Foo")) { + return "Bar"; + } + return null; + }); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("LBar;"), + new TypeDescriptor("LBar;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("LMoo;"))); + } + { + final MethodDescriptor oldSig = new MethodDescriptor("(LFoo;LBar;)LMoo;"); + final MethodDescriptor sig = oldSig.remap(s -> { + if (s.equals("Moo")) { + return "Cow"; + } + return null; + }); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("LFoo;"), + new TypeDescriptor("LBar;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("LCow;"))); + } + } + + @Test + public void replaceArrayClasses() { + { + final MethodDescriptor oldSig = new MethodDescriptor("([LFoo;)[[[LBar;"); + final MethodDescriptor sig = oldSig.remap(s -> { + if (s.equals("Foo")) { + return "Food"; + } else if (s.equals("Bar")) { + return "Beer"; + } + return null; + }); + assertThat(sig.getArgumentDescs(), contains( + new TypeDescriptor("[LFood;") + )); + assertThat(sig.getReturnDesc(), is(new TypeDescriptor("[[[LBeer;"))); + } + } + + @Test + public void equals() { + + // base + assertThat(new MethodDescriptor("()V"), is(new MethodDescriptor("()V"))); + + // arguments + assertThat(new MethodDescriptor("(I)V"), is(new MethodDescriptor("(I)V"))); + assertThat(new MethodDescriptor("(ZIZ)V"), is(new MethodDescriptor("(ZIZ)V"))); + assertThat(new MethodDescriptor("(LFoo;)V"), is(new MethodDescriptor("(LFoo;)V"))); + assertThat(new MethodDescriptor("(LFoo;LBar;)V"), is(new MethodDescriptor("(LFoo;LBar;)V"))); + assertThat(new MethodDescriptor("([I)V"), is(new MethodDescriptor("([I)V"))); + assertThat(new MethodDescriptor("([[D[[[J)V"), is(new MethodDescriptor("([[D[[[J)V"))); + + assertThat(new MethodDescriptor("()V"), is(not(new MethodDescriptor("(I)V")))); + assertThat(new MethodDescriptor("(I)V"), is(not(new MethodDescriptor("()V")))); + assertThat(new MethodDescriptor("(IJ)V"), is(not(new MethodDescriptor("(JI)V")))); + assertThat(new MethodDescriptor("([[Z)V"), is(not(new MethodDescriptor("([[LFoo;)V")))); + assertThat(new MethodDescriptor("(LFoo;LBar;)V"), is(not(new MethodDescriptor("(LFoo;LCow;)V")))); + assertThat(new MethodDescriptor("([LFoo;LBar;)V"), is(not(new MethodDescriptor("(LFoo;LCow;)V")))); + + // return desc + assertThat(new MethodDescriptor("()I"), is(new MethodDescriptor("()I"))); + assertThat(new MethodDescriptor("()Z"), is(new MethodDescriptor("()Z"))); + assertThat(new MethodDescriptor("()[D"), is(new MethodDescriptor("()[D"))); + assertThat(new MethodDescriptor("()[[[Z"), is(new MethodDescriptor("()[[[Z"))); + assertThat(new MethodDescriptor("()LFoo;"), is(new MethodDescriptor("()LFoo;"))); + assertThat(new MethodDescriptor("()[LFoo;"), is(new MethodDescriptor("()[LFoo;"))); + + assertThat(new MethodDescriptor("()I"), is(not(new MethodDescriptor("()Z")))); + assertThat(new MethodDescriptor("()Z"), is(not(new MethodDescriptor("()I")))); + assertThat(new MethodDescriptor("()[D"), is(not(new MethodDescriptor("()[J")))); + assertThat(new MethodDescriptor("()[[[Z"), is(not(new MethodDescriptor("()[[Z")))); + assertThat(new MethodDescriptor("()LFoo;"), is(not(new MethodDescriptor("()LBar;")))); + assertThat(new MethodDescriptor("()[LFoo;"), is(not(new MethodDescriptor("()[LBar;")))); + } + + @Test + public void testToString() { + assertThat(new MethodDescriptor("()V").toString(), is("()V")); + assertThat(new MethodDescriptor("(I)V").toString(), is("(I)V")); + assertThat(new MethodDescriptor("(ZIZ)V").toString(), is("(ZIZ)V")); + assertThat(new MethodDescriptor("(LFoo;)V").toString(), is("(LFoo;)V")); + assertThat(new MethodDescriptor("(LFoo;LBar;)V").toString(), is("(LFoo;LBar;)V")); + assertThat(new MethodDescriptor("([I)V").toString(), is("([I)V")); + assertThat(new MethodDescriptor("([[D[[[J)V").toString(), is("([[D[[[J)V")); + } +} diff --git a/src/test/java/cuchaz/enigma/TestSignature.java b/src/test/java/cuchaz/enigma/TestSignature.java deleted file mode 100644 index 534b43ae..00000000 --- a/src/test/java/cuchaz/enigma/TestSignature.java +++ /dev/null @@ -1,270 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ - -package cuchaz.enigma; - -import cuchaz.enigma.mapping.ClassNameReplacer; -import cuchaz.enigma.mapping.Signature; -import cuchaz.enigma.mapping.Type; -import org.junit.Test; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - -public class TestSignature { - - @Test - public void easiest() { - final Signature sig = new Signature("()V"); - assertThat(sig.getArgumentTypes(), is(empty())); - assertThat(sig.getReturnType(), is(new Type("V"))); - } - - @Test - public void primitives() { - { - final Signature sig = new Signature("(I)V"); - assertThat(sig.getArgumentTypes(), contains( - new Type("I") - )); - assertThat(sig.getReturnType(), is(new Type("V"))); - } - { - final Signature sig = new Signature("(I)I"); - assertThat(sig.getArgumentTypes(), contains( - new Type("I") - )); - assertThat(sig.getReturnType(), is(new Type("I"))); - } - { - final Signature sig = new Signature("(IBCJ)Z"); - assertThat(sig.getArgumentTypes(), contains( - new Type("I"), - new Type("B"), - new Type("C"), - new Type("J") - )); - assertThat(sig.getReturnType(), is(new Type("Z"))); - } - } - - @Test - public void classes() { - { - final Signature sig = new Signature("([LFoo;)V"); - assertThat(sig.getArgumentTypes().size(), is(1)); - assertThat(sig.getArgumentTypes().get(0), is(new Type("[LFoo;"))); - assertThat(sig.getReturnType(), is(new Type("V"))); - } - { - final Signature sig = new Signature("(LFoo;)LBar;"); - assertThat(sig.getArgumentTypes(), contains( - new Type("LFoo;") - )); - assertThat(sig.getReturnType(), is(new Type("LBar;"))); - } - { - final Signature sig = new Signature("(LFoo;LMoo;LZoo;)LBar;"); - assertThat(sig.getArgumentTypes(), contains( - new Type("LFoo;"), - new Type("LMoo;"), - new Type("LZoo;") - )); - assertThat(sig.getReturnType(), is(new Type("LBar;"))); - } - } - - @Test - public void arrays() { - { - final Signature sig = new Signature("([I)V"); - assertThat(sig.getArgumentTypes(), contains( - new Type("[I") - )); - assertThat(sig.getReturnType(), is(new Type("V"))); - } - { - final Signature sig = new Signature("([I)[J"); - assertThat(sig.getArgumentTypes(), contains( - new Type("[I") - )); - assertThat(sig.getReturnType(), is(new Type("[J"))); - } - { - final Signature sig = new Signature("([I[Z[F)[D"); - assertThat(sig.getArgumentTypes(), contains( - new Type("[I"), - new Type("[Z"), - new Type("[F") - )); - assertThat(sig.getReturnType(), is(new Type("[D"))); - } - } - - @Test - public void mixed() { - { - final Signature sig = new Signature("(I[JLFoo;)Z"); - assertThat(sig.getArgumentTypes(), contains( - new Type("I"), - new Type("[J"), - new Type("LFoo;") - )); - assertThat(sig.getReturnType(), is(new Type("Z"))); - } - { - final Signature sig = new Signature("(III)[LFoo;"); - assertThat(sig.getArgumentTypes(), contains( - new Type("I"), - new Type("I"), - new Type("I") - )); - assertThat(sig.getReturnType(), is(new Type("[LFoo;"))); - } - } - - @Test - public void replaceClasses() { - { - final Signature oldSig = new Signature("()V"); - final Signature sig = new Signature(oldSig, new ClassNameReplacer() { - @Override - public String replace(String val) { - return null; - } - }); - assertThat(sig.getArgumentTypes(), is(empty())); - assertThat(sig.getReturnType(), is(new Type("V"))); - } - { - final Signature oldSig = new Signature("(IJLFoo;)V"); - final Signature sig = new Signature(oldSig, new ClassNameReplacer() { - @Override - public String replace(String val) { - return null; - } - }); - assertThat(sig.getArgumentTypes(), contains( - new Type("I"), - new Type("J"), - new Type("LFoo;") - )); - assertThat(sig.getReturnType(), is(new Type("V"))); - } - { - final Signature oldSig = new Signature("(LFoo;LBar;)LMoo;"); - final Signature sig = new Signature(oldSig, new ClassNameReplacer() { - @Override - public String replace(String val) { - if (val.equals("Foo")) { - return "Bar"; - } - return null; - } - }); - assertThat(sig.getArgumentTypes(), contains( - new Type("LBar;"), - new Type("LBar;") - )); - assertThat(sig.getReturnType(), is(new Type("LMoo;"))); - } - { - final Signature oldSig = new Signature("(LFoo;LBar;)LMoo;"); - final Signature sig = new Signature(oldSig, new ClassNameReplacer() { - @Override - public String replace(String val) { - if (val.equals("Moo")) { - return "Cow"; - } - return null; - } - }); - assertThat(sig.getArgumentTypes(), contains( - new Type("LFoo;"), - new Type("LBar;") - )); - assertThat(sig.getReturnType(), is(new Type("LCow;"))); - } - } - - @Test - public void replaceArrayClasses() { - { - final Signature oldSig = new Signature("([LFoo;)[[[LBar;"); - final Signature sig = new Signature(oldSig, new ClassNameReplacer() { - @Override - public String replace(String val) { - if (val.equals("Foo")) { - return "Food"; - } else if (val.equals("Bar")) { - return "Beer"; - } - return null; - } - }); - assertThat(sig.getArgumentTypes(), contains( - new Type("[LFood;") - )); - assertThat(sig.getReturnType(), is(new Type("[[[LBeer;"))); - } - } - - @Test - public void equals() { - - // base - assertThat(new Signature("()V"), is(new Signature("()V"))); - - // arguments - assertThat(new Signature("(I)V"), is(new Signature("(I)V"))); - assertThat(new Signature("(ZIZ)V"), is(new Signature("(ZIZ)V"))); - assertThat(new Signature("(LFoo;)V"), is(new Signature("(LFoo;)V"))); - assertThat(new Signature("(LFoo;LBar;)V"), is(new Signature("(LFoo;LBar;)V"))); - assertThat(new Signature("([I)V"), is(new Signature("([I)V"))); - assertThat(new Signature("([[D[[[J)V"), is(new Signature("([[D[[[J)V"))); - - assertThat(new Signature("()V"), is(not(new Signature("(I)V")))); - assertThat(new Signature("(I)V"), is(not(new Signature("()V")))); - assertThat(new Signature("(IJ)V"), is(not(new Signature("(JI)V")))); - assertThat(new Signature("([[Z)V"), is(not(new Signature("([[LFoo;)V")))); - assertThat(new Signature("(LFoo;LBar;)V"), is(not(new Signature("(LFoo;LCow;)V")))); - assertThat(new Signature("([LFoo;LBar;)V"), is(not(new Signature("(LFoo;LCow;)V")))); - - // return type - assertThat(new Signature("()I"), is(new Signature("()I"))); - assertThat(new Signature("()Z"), is(new Signature("()Z"))); - assertThat(new Signature("()[D"), is(new Signature("()[D"))); - assertThat(new Signature("()[[[Z"), is(new Signature("()[[[Z"))); - assertThat(new Signature("()LFoo;"), is(new Signature("()LFoo;"))); - assertThat(new Signature("()[LFoo;"), is(new Signature("()[LFoo;"))); - - assertThat(new Signature("()I"), is(not(new Signature("()Z")))); - assertThat(new Signature("()Z"), is(not(new Signature("()I")))); - assertThat(new Signature("()[D"), is(not(new Signature("()[J")))); - assertThat(new Signature("()[[[Z"), is(not(new Signature("()[[Z")))); - assertThat(new Signature("()LFoo;"), is(not(new Signature("()LBar;")))); - assertThat(new Signature("()[LFoo;"), is(not(new Signature("()[LBar;")))); - } - - @Test - public void testToString() { - assertThat(new Signature("()V").toString(), is("()V")); - assertThat(new Signature("(I)V").toString(), is("(I)V")); - assertThat(new Signature("(ZIZ)V").toString(), is("(ZIZ)V")); - assertThat(new Signature("(LFoo;)V").toString(), is("(LFoo;)V")); - assertThat(new Signature("(LFoo;LBar;)V").toString(), is("(LFoo;LBar;)V")); - assertThat(new Signature("([I)V").toString(), is("([I)V")); - assertThat(new Signature("([[D[[[J)V").toString(), is("([[D[[[J)V")); - } -} diff --git a/src/test/java/cuchaz/enigma/TestTokensConstructors.java b/src/test/java/cuchaz/enigma/TestTokensConstructors.java index e40d5fdc..0148f2c3 100644 --- a/src/test/java/cuchaz/enigma/TestTokensConstructors.java +++ b/src/test/java/cuchaz/enigma/TestTokensConstructors.java @@ -11,131 +11,127 @@ package cuchaz.enigma; -import cuchaz.enigma.mapping.BehaviorEntry; +import cuchaz.enigma.mapping.MethodEntry; import org.junit.Test; import java.util.jar.JarFile; -import static cuchaz.enigma.TestEntryFactory.newBehaviorReferenceByConstructor; import static cuchaz.enigma.TestEntryFactory.newBehaviorReferenceByMethod; -import static cuchaz.enigma.TestEntryFactory.newConstructor; +import static cuchaz.enigma.TestEntryFactory.newMethod; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.*; public class TestTokensConstructors extends TokenChecker { public TestTokensConstructors() - throws Exception { + throws Exception { super(new JarFile("build/test-obf/constructors.jar")); } @Test public void baseDeclarations() { - assertThat(getDeclarationToken(newConstructor("a", "()V")), is("a")); - assertThat(getDeclarationToken(newConstructor("a", "(I)V")), is("a")); + assertThat(getDeclarationToken(newMethod("a", "", "()V")), is("a")); + assertThat(getDeclarationToken(newMethod("a", "", "(I)V")), is("a")); } @Test public void subDeclarations() { - assertThat(getDeclarationToken(newConstructor("d", "()V")), is("d")); - assertThat(getDeclarationToken(newConstructor("d", "(I)V")), is("d")); - assertThat(getDeclarationToken(newConstructor("d", "(II)V")), is("d")); - assertThat(getDeclarationToken(newConstructor("d", "(III)V")), is("d")); + assertThat(getDeclarationToken(newMethod("d", "", "()V")), is("d")); + assertThat(getDeclarationToken(newMethod("d", "", "(I)V")), is("d")); + assertThat(getDeclarationToken(newMethod("d", "", "(II)V")), is("d")); + assertThat(getDeclarationToken(newMethod("d", "", "(III)V")), is("d")); } @Test public void subsubDeclarations() { - assertThat(getDeclarationToken(newConstructor("e", "(I)V")), is("e")); + assertThat(getDeclarationToken(newMethod("e", "", "(I)V")), is("e")); } @Test public void defaultDeclarations() { - assertThat(getDeclarationToken(newConstructor("c", "()V")), nullValue()); + assertThat(getDeclarationToken(newMethod("c", "", "()V")), nullValue()); } @Test public void baseDefaultReferences() { - BehaviorEntry source = newConstructor("a", "()V"); + MethodEntry source = newMethod("a", "", "()V"); assertThat( - getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "a", "()V")), - containsInAnyOrder("a") + getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "a", "()V")), + containsInAnyOrder("a") ); assertThat( - getReferenceTokens(newBehaviorReferenceByConstructor(source, "d", "()V")), - is(empty()) // implicit call, not decompiled to token + getReferenceTokens(newBehaviorReferenceByMethod(source, "d", "", "()V")), + is(empty()) // implicit call, not decompiled to token ); assertThat( - getReferenceTokens(newBehaviorReferenceByConstructor(source, "d", "(III)V")), - is(empty()) // implicit call, not decompiled to token + getReferenceTokens(newBehaviorReferenceByMethod(source, "d", "", "(III)V")), + is(empty()) // implicit call, not decompiled to token ); } @Test public void baseIntReferences() { - BehaviorEntry source = newConstructor("a", "(I)V"); + MethodEntry source = newMethod("a", "", "(I)V"); assertThat( - getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "b", "()V")), - containsInAnyOrder("a") + getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "b", "()V")), + containsInAnyOrder("a") ); } @Test public void subDefaultReferences() { - BehaviorEntry source = newConstructor("d", "()V"); + MethodEntry source = newMethod("d", "", "()V"); assertThat( - getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "c", "()V")), - containsInAnyOrder("d") + getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "c", "()V")), + containsInAnyOrder("d") ); assertThat( - getReferenceTokens(newBehaviorReferenceByConstructor(source, "d", "(I)V")), - containsInAnyOrder("this") + getReferenceTokens(newBehaviorReferenceByMethod(source, "d", "", "(I)V")), + containsInAnyOrder("this") ); } @Test public void subIntReferences() { - BehaviorEntry source = newConstructor("d", "(I)V"); + MethodEntry source = newMethod("d", "", "(I)V"); assertThat(getReferenceTokens( - newBehaviorReferenceByMethod(source, "b", "d", "()V")), - containsInAnyOrder("d") + newBehaviorReferenceByMethod(source, "b", "d", "()V")), + containsInAnyOrder("d") ); assertThat(getReferenceTokens( - newBehaviorReferenceByConstructor(source, "d", "(II)V")), - containsInAnyOrder("this") + newBehaviorReferenceByMethod(source, "d", "", "(II)V")), + containsInAnyOrder("this") ); assertThat(getReferenceTokens( - newBehaviorReferenceByConstructor(source, "e", "(I)V")), - containsInAnyOrder("super") + newBehaviorReferenceByMethod(source, "e", "", "(I)V")), + containsInAnyOrder("super") ); } @Test public void subIntIntReferences() { - BehaviorEntry source = newConstructor("d", "(II)V"); + MethodEntry source = newMethod("d", "", "(II)V"); assertThat( - getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "e", "()V")), - containsInAnyOrder("d") + getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "e", "()V")), + containsInAnyOrder("d") ); } @Test public void subsubIntReferences() { - BehaviorEntry source = newConstructor("e", "(I)V"); + MethodEntry source = newMethod("e", "", "(I)V"); assertThat( - getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "f", "()V")), - containsInAnyOrder("e") + getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "f", "()V")), + containsInAnyOrder("e") ); } @Test public void defaultConstructableReferences() { - BehaviorEntry source = newConstructor("c", "()V"); + MethodEntry source = newMethod("c", "", "()V"); assertThat( - getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "g", "()V")), - containsInAnyOrder("c") + getReferenceTokens(newBehaviorReferenceByMethod(source, "b", "g", "()V")), + containsInAnyOrder("c") ); } } diff --git a/src/test/java/cuchaz/enigma/TestTypeDescriptor.java b/src/test/java/cuchaz/enigma/TestTypeDescriptor.java new file mode 100644 index 00000000..b874f629 --- /dev/null +++ b/src/test/java/cuchaz/enigma/TestTypeDescriptor.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ + +package cuchaz.enigma; + +import cuchaz.enigma.mapping.TypeDescriptor; +import org.junit.Test; + +import static cuchaz.enigma.TestEntryFactory.newClass; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; + +public class TestTypeDescriptor { + + @Test + public void isVoid() { + assertThat(new TypeDescriptor("V").isVoid(), is(true)); + assertThat(new TypeDescriptor("Z").isVoid(), is(false)); + assertThat(new TypeDescriptor("B").isVoid(), is(false)); + assertThat(new TypeDescriptor("C").isVoid(), is(false)); + assertThat(new TypeDescriptor("I").isVoid(), is(false)); + assertThat(new TypeDescriptor("J").isVoid(), is(false)); + assertThat(new TypeDescriptor("F").isVoid(), is(false)); + assertThat(new TypeDescriptor("D").isVoid(), is(false)); + assertThat(new TypeDescriptor("LFoo;").isVoid(), is(false)); + assertThat(new TypeDescriptor("[I").isVoid(), is(false)); + } + + @Test + public void isPrimitive() { + assertThat(new TypeDescriptor("V").isPrimitive(), is(false)); + assertThat(new TypeDescriptor("Z").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("B").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("C").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("I").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("J").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("F").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("D").isPrimitive(), is(true)); + assertThat(new TypeDescriptor("LFoo;").isPrimitive(), is(false)); + assertThat(new TypeDescriptor("[I").isPrimitive(), is(false)); + } + + @Test + public void getPrimitive() { + assertThat(new TypeDescriptor("Z").getPrimitive(), is(TypeDescriptor.Primitive.Boolean)); + assertThat(new TypeDescriptor("B").getPrimitive(), is(TypeDescriptor.Primitive.Byte)); + assertThat(new TypeDescriptor("C").getPrimitive(), is(TypeDescriptor.Primitive.Character)); + assertThat(new TypeDescriptor("I").getPrimitive(), is(TypeDescriptor.Primitive.Integer)); + assertThat(new TypeDescriptor("J").getPrimitive(), is(TypeDescriptor.Primitive.Long)); + assertThat(new TypeDescriptor("F").getPrimitive(), is(TypeDescriptor.Primitive.Float)); + assertThat(new TypeDescriptor("D").getPrimitive(), is(TypeDescriptor.Primitive.Double)); + } + + @Test + public void isClass() { + assertThat(new TypeDescriptor("V").isType(), is(false)); + assertThat(new TypeDescriptor("Z").isType(), is(false)); + assertThat(new TypeDescriptor("B").isType(), is(false)); + assertThat(new TypeDescriptor("C").isType(), is(false)); + assertThat(new TypeDescriptor("I").isType(), is(false)); + assertThat(new TypeDescriptor("J").isType(), is(false)); + assertThat(new TypeDescriptor("F").isType(), is(false)); + assertThat(new TypeDescriptor("D").isType(), is(false)); + assertThat(new TypeDescriptor("LFoo;").isType(), is(true)); + assertThat(new TypeDescriptor("[I").isType(), is(false)); + } + + @Test + public void getClassEntry() { + assertThat(new TypeDescriptor("LFoo;").getOwnerEntry(), is(newClass("Foo"))); + assertThat(new TypeDescriptor("Ljava/lang/String;").getOwnerEntry(), is(newClass("java/lang/String"))); + } + + @Test + public void getArrayClassEntry() { + assertThat(new TypeDescriptor("[LFoo;").getOwnerEntry(), is(newClass("Foo"))); + assertThat(new TypeDescriptor("[[[Ljava/lang/String;").getOwnerEntry(), is(newClass("java/lang/String"))); + } + + @Test + public void isArray() { + assertThat(new TypeDescriptor("V").isArray(), is(false)); + assertThat(new TypeDescriptor("Z").isArray(), is(false)); + assertThat(new TypeDescriptor("B").isArray(), is(false)); + assertThat(new TypeDescriptor("C").isArray(), is(false)); + assertThat(new TypeDescriptor("I").isArray(), is(false)); + assertThat(new TypeDescriptor("J").isArray(), is(false)); + assertThat(new TypeDescriptor("F").isArray(), is(false)); + assertThat(new TypeDescriptor("D").isArray(), is(false)); + assertThat(new TypeDescriptor("LFoo;").isArray(), is(false)); + assertThat(new TypeDescriptor("[I").isArray(), is(true)); + } + + @Test + public void getArrayDimension() { + assertThat(new TypeDescriptor("[I").getArrayDimension(), is(1)); + assertThat(new TypeDescriptor("[[I").getArrayDimension(), is(2)); + assertThat(new TypeDescriptor("[[[I").getArrayDimension(), is(3)); + } + + @Test + public void getArrayType() { + assertThat(new TypeDescriptor("[I").getArrayType(), is(new TypeDescriptor("I"))); + assertThat(new TypeDescriptor("[[I").getArrayType(), is(new TypeDescriptor("I"))); + assertThat(new TypeDescriptor("[[[I").getArrayType(), is(new TypeDescriptor("I"))); + assertThat(new TypeDescriptor("[Ljava/lang/String;").getArrayType(), is(new TypeDescriptor("Ljava/lang/String;"))); + } + + @Test + public void hasClass() { + assertThat(new TypeDescriptor("LFoo;").containsType(), is(true)); + assertThat(new TypeDescriptor("Ljava/lang/String;").containsType(), is(true)); + assertThat(new TypeDescriptor("[LBar;").containsType(), is(true)); + assertThat(new TypeDescriptor("[[[LCat;").containsType(), is(true)); + + assertThat(new TypeDescriptor("V").containsType(), is(false)); + assertThat(new TypeDescriptor("[I").containsType(), is(false)); + assertThat(new TypeDescriptor("[[[I").containsType(), is(false)); + assertThat(new TypeDescriptor("Z").containsType(), is(false)); + } + + @Test + public void parseVoid() { + final String answer = "V"; + assertThat(TypeDescriptor.parseFirst("V"), is(answer)); + assertThat(TypeDescriptor.parseFirst("VVV"), is(answer)); + assertThat(TypeDescriptor.parseFirst("VIJ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("V[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("VLFoo;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("V[LFoo;"), is(answer)); + } + + @Test + public void parsePrimitive() { + final String answer = "I"; + assertThat(TypeDescriptor.parseFirst("I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("III"), is(answer)); + assertThat(TypeDescriptor.parseFirst("IJZ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("I[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("ILFoo;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("I[LFoo;"), is(answer)); + } + + @Test + public void parseClass() { + { + final String answer = "LFoo;"; + assertThat(TypeDescriptor.parseFirst("LFoo;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("LFoo;I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("LFoo;JZ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("LFoo;[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("LFoo;LFoo;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("LFoo;[LFoo;"), is(answer)); + } + { + final String answer = "Ljava/lang/String;"; + assertThat(TypeDescriptor.parseFirst("Ljava/lang/String;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("Ljava/lang/String;I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("Ljava/lang/String;JZ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("Ljava/lang/String;[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("Ljava/lang/String;LFoo;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("Ljava/lang/String;[LFoo;"), is(answer)); + } + } + + @Test + public void parseArray() { + { + final String answer = "[I"; + assertThat(TypeDescriptor.parseFirst("[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[III"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[IJZ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[I[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[ILFoo;"), is(answer)); + } + { + final String answer = "[[I"; + assertThat(TypeDescriptor.parseFirst("[[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[[III"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[[IJZ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[[I[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[[ILFoo;"), is(answer)); + } + { + final String answer = "[LFoo;"; + assertThat(TypeDescriptor.parseFirst("[LFoo;"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[LFoo;II"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[LFoo;JZ"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[LFoo;[I"), is(answer)); + assertThat(TypeDescriptor.parseFirst("[LFoo;LFoo;"), is(answer)); + } + } + + @Test + public void equals() { + assertThat(new TypeDescriptor("V"), is(new TypeDescriptor("V"))); + assertThat(new TypeDescriptor("Z"), is(new TypeDescriptor("Z"))); + assertThat(new TypeDescriptor("B"), is(new TypeDescriptor("B"))); + assertThat(new TypeDescriptor("C"), is(new TypeDescriptor("C"))); + assertThat(new TypeDescriptor("I"), is(new TypeDescriptor("I"))); + assertThat(new TypeDescriptor("J"), is(new TypeDescriptor("J"))); + assertThat(new TypeDescriptor("F"), is(new TypeDescriptor("F"))); + assertThat(new TypeDescriptor("D"), is(new TypeDescriptor("D"))); + assertThat(new TypeDescriptor("LFoo;"), is(new TypeDescriptor("LFoo;"))); + assertThat(new TypeDescriptor("[I"), is(new TypeDescriptor("[I"))); + assertThat(new TypeDescriptor("[[[I"), is(new TypeDescriptor("[[[I"))); + assertThat(new TypeDescriptor("[LFoo;"), is(new TypeDescriptor("[LFoo;"))); + + assertThat(new TypeDescriptor("V"), is(not(new TypeDescriptor("I")))); + assertThat(new TypeDescriptor("I"), is(not(new TypeDescriptor("J")))); + assertThat(new TypeDescriptor("I"), is(not(new TypeDescriptor("LBar;")))); + assertThat(new TypeDescriptor("I"), is(not(new TypeDescriptor("[I")))); + assertThat(new TypeDescriptor("LFoo;"), is(not(new TypeDescriptor("LBar;")))); + assertThat(new TypeDescriptor("[I"), is(not(new TypeDescriptor("[Z")))); + assertThat(new TypeDescriptor("[[[I"), is(not(new TypeDescriptor("[I")))); + assertThat(new TypeDescriptor("[LFoo;"), is(not(new TypeDescriptor("[LBar;")))); + } + + @Test + public void testToString() { + assertThat(new TypeDescriptor("V").toString(), is("V")); + assertThat(new TypeDescriptor("Z").toString(), is("Z")); + assertThat(new TypeDescriptor("B").toString(), is("B")); + assertThat(new TypeDescriptor("C").toString(), is("C")); + assertThat(new TypeDescriptor("I").toString(), is("I")); + assertThat(new TypeDescriptor("J").toString(), is("J")); + assertThat(new TypeDescriptor("F").toString(), is("F")); + assertThat(new TypeDescriptor("D").toString(), is("D")); + assertThat(new TypeDescriptor("LFoo;").toString(), is("LFoo;")); + assertThat(new TypeDescriptor("[I").toString(), is("[I")); + assertThat(new TypeDescriptor("[[[I").toString(), is("[[[I")); + assertThat(new TypeDescriptor("[LFoo;").toString(), is("[LFoo;")); + } +} -- cgit v1.2.3