cfrOptionsDict, Path output, String outputPrefix) throws IOException {
18 | DecompilationTestImplementation.assertClassFile(classFilePath, cfrOptionsDict, output, outputPrefix);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/decompilation-test/test-data-expected-output/classes/CondJumpTest2c.10.expected.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Decompiled with CFR.
3 | */
4 | package org.benf.cfr.tests;
5 |
6 | public class CondJumpTest2c {
7 | public boolean test(boolean a, boolean b) {
8 | boolean c;
9 | return b && a == (c = b) || b && (c = a);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/decompilation-test/test-data-expected-output/classes/CondJumpTest2c.6.expected.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Decompiled with CFR.
3 | */
4 | package org.benf.cfr.tests;
5 |
6 | public class CondJumpTest2c {
7 | public boolean test(boolean bl, boolean bl2) {
8 | boolean bl3;
9 | return bl2 && bl == (bl3 = bl2) || bl2 && (bl3 = bl);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/decompilation-test/test-data-expected-output/classes/EnumTestEmpty.13.expected.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Decompiled with CFR.
3 | */
4 | package org.benf.cfr.tests;
5 |
6 | public enum EnumTestEmpty {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/decompilation-test/test-data-expected-output/classes/EnumTestEmpty.6.expected.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Decompiled with CFR.
3 | */
4 | package org.benf.cfr.tests;
5 |
6 | public enum EnumTestEmpty {
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/decompilation-test/test-data-expected-output/classes/TryTest1.10.expected.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Decompiled with CFR.
3 | */
4 | package org.benf.cfr.tests;
5 |
6 | public class TryTest1 {
7 | public void test1() {
8 | try {
9 | try {
10 | System.out.print(3);
11 | throw new NoSuchFieldException();
12 | } catch (NoSuchFieldException noSuchFieldException) {
13 | System.out.print("Finally!");
14 | }
15 | } catch (Throwable throwable) {
16 | System.out.print("Finally!");
17 | throw throwable;
18 | }
19 | System.out.print(5);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/decompilation-test/test-specs/classes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 | precompiled_tests/java_6/org/benf/cfr/tests
8 | CondJumpTest2c
9 |
10 | 6
11 |
12 |
13 |
14 |
15 |
16 |
17 | precompiled_tests/java_10/org/benf/cfr/tests
18 | CondJumpTest2c
19 | 10
20 |
21 |
22 | precompiled_tests/java_6/org/benf/cfr/tests
23 | EnumTestEmpty
24 | 6
25 |
26 |
27 | precompiled_tests/java_13/org/benf/cfr/tests
28 | EnumTestEmpty
29 | 13
30 |
31 |
32 | precompiled_tests/java_10/org/benf/cfr/tests
33 | TryTest1
34 | 10
35 |
36 |
--------------------------------------------------------------------------------
/src-templates/org/benf/cfr/reader/util/CfrVersionInfo.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | /**
4 | * Provides information about the CFR build.
5 | *
6 | * The information in this class is automatically generated when the project
7 | * is built.
8 | */
9 | public class CfrVersionInfo {
10 | private CfrVersionInfo() {}
11 |
12 | /** CFR version */
13 | public static final String VERSION = "${project.version}";
14 |
15 | /** Are we a snapshot? */
16 | public static final boolean SNAPSHOT = CfrVersionInfo.VERSION.contains("SNAPSHOT");
17 | /**
18 | * Abbreviated Git commit hash of the commit representing this state
19 | * of the project.
20 | */
21 | public static final String GIT_COMMIT_ABBREVIATED = "${git.commit.id.abbrev}";
22 | /**
23 | * Whether the working tree contained not yet committed changes when
24 | * the project was built.
25 | *
26 | *
This information can be useful for error reports to find out
27 | * if changes have been made.
28 | */
29 | public static final boolean GIT_IS_DIRTY = "${git.dirty}".equals("true");
30 |
31 | /** String consisting of CFR version and Git commit hash */
32 | public static final String VERSION_INFO =
33 | VERSION +
34 | (SNAPSHOT ?
35 | " (" + GIT_COMMIT_ABBREVIATED + (GIT_IS_DIRTY ? "-dirty" : "") + ")" :
36 | "");
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/apiunreleased/ClassFileSource2.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.apiunreleased;
2 |
3 | import org.benf.cfr.reader.api.ClassFileSource;
4 | import org.benf.cfr.reader.util.AnalysisType;
5 |
6 | // TODO : Experimental API - before moving, snip ClassFileSource link.
7 | public interface ClassFileSource2 extends ClassFileSource {
8 | /**
9 | * CFR would like to know about all classes contained within the jar at {@code jarPath}
10 | *
11 | * @param jarPath path to a jar.
12 | * @return @{link JarContent} for this jar.
13 | */
14 | JarContent addJarContent(String jarPath, AnalysisType analysisType);
15 | }
16 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/apiunreleased/JarContent.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.apiunreleased;
2 |
3 | import org.benf.cfr.reader.util.AnalysisType;
4 |
5 | import java.util.Collection;
6 | import java.util.Map;
7 |
8 | public interface JarContent {
9 | /**
10 | * @return All files which we may want to process.
11 | */
12 | Collection getClassFiles();
13 |
14 | /**
15 | * Nb: Java has a perfectly good {@link java.util.jar.Manifest} class since 1.2
16 | * which could be used here. This simplifies the content.
17 | * @return Map of manifest entries.
18 | */
19 | Map getManifestEntries();
20 |
21 | /**
22 | * @return source of data - jar? war?
23 | */
24 | AnalysisType getAnalysisType();
25 | }
26 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/AnalysisResult.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public interface AnalysisResult {
7 | boolean isFailed();
8 | boolean isThrown();
9 | Op04StructuredStatement getCode();
10 | DecompilerComments getComments();
11 | AnonymousClassUsage getAnonymousClassUsage();
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/loc/BytecodeLocFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.loc;
2 |
3 | import org.benf.cfr.reader.entities.Method;
4 |
5 | public interface BytecodeLocFactory {
6 | BytecodeLoc DISABLED = new BytecodeLocSpecific(BytecodeLocSpecific.Specific.DISABLED);
7 | BytecodeLoc NONE = new BytecodeLocSpecific(BytecodeLocSpecific.Specific.NONE);
8 | BytecodeLoc TODO = new BytecodeLocSpecific(BytecodeLocSpecific.Specific.TODO);
9 |
10 | BytecodeLoc at(int originalRawOffset, Method method);
11 | }
12 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/loc/BytecodeLocFactoryStub.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.loc;
2 |
3 | import org.benf.cfr.reader.entities.Method;
4 |
5 | public class BytecodeLocFactoryStub implements BytecodeLocFactory {
6 | public static BytecodeLocFactory INSTANCE = new BytecodeLocFactoryStub();
7 |
8 | private BytecodeLocFactoryStub() {
9 | }
10 |
11 | @Override
12 | public BytecodeLoc at(int originalRawOffset, Method method) {
13 | return BytecodeLocFactory.DISABLED;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/loc/BytecodeLocSpecific.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.loc;
2 |
3 | import org.benf.cfr.reader.entities.Method;
4 |
5 | import java.util.Collection;
6 | import java.util.Collections;
7 |
8 | class BytecodeLocSpecific extends BytecodeLoc {
9 | enum Specific {
10 | DISABLED,
11 | TODO,
12 | NONE
13 | }
14 |
15 | private final Specific type;
16 |
17 | BytecodeLocSpecific(Specific type) {
18 | this.type = type;
19 | }
20 |
21 | @Override
22 | void addTo(BytecodeLocCollector collector) {
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | return type.name();
28 | }
29 |
30 | @Override
31 | public Collection getMethods() {
32 | return Collections.emptyList();
33 | }
34 |
35 | @Override
36 | public Collection getOffsetsForMethod(Method method) {
37 | return Collections.emptyList();
38 | }
39 |
40 | @Override
41 | public boolean isEmpty() {
42 | return true;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/loc/HasByteCodeLoc.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.loc;
2 |
3 | public interface HasByteCodeLoc {
4 | BytecodeLoc getCombinedLoc();
5 |
6 | BytecodeLoc getLoc();
7 |
8 | void addLoc(HasByteCodeLoc loc);
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/Graph.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph;
2 |
3 | import java.util.List;
4 |
5 | public interface Graph {
6 | List getSources();
7 | List getTargets();
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/GraphConversionHelper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph;
2 |
3 | import org.benf.cfr.reader.util.ConfusedCFRException;
4 | import org.benf.cfr.reader.util.collections.MapFactory;
5 |
6 | import java.util.Map;
7 |
8 | class GraphConversionHelper, Y extends MutableGraph> {
9 | private final Map correspondance;
10 |
11 | GraphConversionHelper() {
12 | this.correspondance = MapFactory.newMap();
13 | }
14 |
15 | private Y findEntry(X key, X orig, String dbg) {
16 | Y value = correspondance.get(key);
17 | if (value == null)
18 | throw new ConfusedCFRException("Missing key when tying up graph " + key + ", was " + dbg + " of " + orig);
19 | return value;
20 | }
21 |
22 | void patchUpRelations() {
23 | for (Map.Entry entry : correspondance.entrySet()) {
24 | X orig = entry.getKey();
25 | Y newnode = entry.getValue();
26 |
27 | for (X source : orig.getSources()) {
28 | newnode.addSource(findEntry(source, orig, "source"));
29 | }
30 |
31 | for (X target : orig.getTargets()) {
32 | newnode.addTarget(findEntry(target, orig, "target"));
33 | }
34 | }
35 | }
36 |
37 | void registerOriginalAndNew(X original, Y newnode) {
38 | correspondance.put(original, newnode);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/IndexedStatement.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph;
2 |
3 | public interface IndexedStatement {
4 | InstrIndex getIndex();
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/MutableGraph.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph;
2 |
3 | public interface MutableGraph extends Graph {
4 | void addSource(T source);
5 | void addTarget(T target);
6 | }
7 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op02obf/Op02Obf.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op02obf;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op02WithProcessedDataAndRefs;
4 | import org.benf.cfr.reader.entities.Method;
5 | import org.benf.cfr.reader.entities.exceptions.ExceptionAggregator;
6 |
7 | import java.util.List;
8 | import java.util.SortedMap;
9 |
10 | public class Op02Obf {
11 | public static void removeControlFlowExceptions(Method method, ExceptionAggregator exceptions, List op2list, SortedMap lutByOffset) {
12 | ControlFlowIntDiv0Exception.Instance.process(method, exceptions, op2list, lutByOffset);
13 | ControlFlowNullException.Instance.process(method, exceptions, op2list, lutByOffset);
14 | }
15 |
16 | public static void removeNumericObf(Method method, List op2list) {
17 | ControlFlowNumericObf.Instance.process(method, op2list);
18 | }
19 |
20 | public static boolean detectObfuscations(Method method, ExceptionAggregator exceptions, List op2list, SortedMap lutByOffset) {
21 | if (ControlFlowIntDiv0Exception.Instance.check(exceptions, op2list, lutByOffset)) return true;
22 | if (ControlFlowNullException.Instance.check(exceptions, op2list, lutByOffset)) return true;
23 | return false;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op03obf/Op03Obf.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op03obf;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement;
4 |
5 | import java.util.List;
6 |
7 | public class Op03Obf {
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op2rewriters/GetClassTest.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op2rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op02WithProcessedDataAndRefs;
4 | import org.benf.cfr.reader.bytecode.opcode.JVMInstr;
5 | import org.benf.cfr.reader.entities.ClassFile;
6 |
7 | public interface GetClassTest {
8 | JVMInstr getInstr();
9 |
10 | boolean test(ClassFile classFile, Op02WithProcessedDataAndRefs item);
11 | }
12 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op2rewriters/TypeHintRecovery.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op2rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.discovery.InferredJavaType;
4 |
5 | public interface TypeHintRecovery {
6 | void improve(InferredJavaType type);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op2rewriters/TypeHintRecoveryNone.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op2rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.discovery.InferredJavaType;
4 |
5 | public class TypeHintRecoveryNone implements TypeHintRecovery {
6 | public static final TypeHintRecoveryNone INSTANCE = new TypeHintRecoveryNone();
7 |
8 | private TypeHintRecoveryNone() {
9 | }
10 |
11 | @Override
12 | public void improve(InferredJavaType type) {}
13 | }
14 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op3rewriters/CompareByIndex.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement;
4 | import org.benf.cfr.reader.util.ConfusedCFRException;
5 |
6 | import java.util.Comparator;
7 |
8 | public class CompareByIndex implements Comparator {
9 |
10 | private boolean asc;
11 |
12 | public CompareByIndex() {
13 | this(true);
14 | }
15 |
16 | public CompareByIndex(boolean asc) {
17 | this.asc = asc;
18 | }
19 |
20 | @Override
21 | public int compare(Op03SimpleStatement a, Op03SimpleStatement b) {
22 | int res = a.getIndex().compareTo(b.getIndex());
23 | if (!asc) res = -res;
24 | if (res == 0) {
25 | throw new ConfusedCFRException("Can't sort instructions [" + a + ", " + b + "]");
26 | }
27 | //noinspection ComparatorMethodParameterNotUsed
28 | return res;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op3rewriters/CondenseConstruction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.AnonymousClassUsage;
4 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.CreationCollector;
6 | import org.benf.cfr.reader.entities.Method;
7 | import org.benf.cfr.reader.state.DCCommonState;
8 |
9 | import java.util.List;
10 |
11 | class CondenseConstruction {
12 | /*
13 | * Find all the constructors and initialisers. If something is initialised and
14 | * constructed in one place each, we can guarantee that the construction happened
15 | * after the initialisation, so replace
16 | *
17 | * a1 = new foo
18 | * a1.(x, y, z)
19 | *
20 | * with
21 | *
22 | * a1 = new foo(x,y,z)
23 | */
24 | static void condenseConstruction(DCCommonState state, Method method, List statements, AnonymousClassUsage anonymousClassUsage) {
25 | CreationCollector creationCollector = new CreationCollector(anonymousClassUsage);
26 | for (Op03SimpleStatement statement : statements) {
27 | statement.findCreation(creationCollector);
28 | }
29 | creationCollector.condenseConstructions(method, state);
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op3rewriters/ExactTypeFilter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement;
4 | import org.benf.cfr.reader.util.functors.Predicate;
5 |
6 | public class ExactTypeFilter implements Predicate {
7 | private final Class clazz;
8 |
9 | public ExactTypeFilter(Class clazz) {
10 | this.clazz = clazz;
11 | }
12 |
13 | @Override
14 | public boolean test(Op03SimpleStatement in) {
15 | return clazz == (in.getStatement().getClass());
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op3rewriters/NullTypedLValueRewriter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.StatementContainer;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.AbstractExpressionRewriter;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.ExpressionRewriterFlags;
7 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.SSAIdentifiers;
8 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
9 | import org.benf.cfr.reader.bytecode.analysis.types.RawJavaType;
10 | import org.benf.cfr.reader.bytecode.analysis.types.discovery.InferredJavaType;
11 |
12 | public class NullTypedLValueRewriter extends AbstractExpressionRewriter {
13 | @Override
14 | public LValue rewriteExpression(LValue lValue, SSAIdentifiers ssaIdentifiers, StatementContainer statementContainer, ExpressionRewriterFlags flags) {
15 | InferredJavaType inferredJavaType = lValue.getInferredJavaType();
16 | JavaTypeInstance javaTypeInstance = inferredJavaType.getJavaTypeInstance();
17 | if (javaTypeInstance == RawJavaType.NULL || javaTypeInstance == RawJavaType.VOID) {
18 | inferredJavaType.applyKnownBaseType();
19 | }
20 | return lValue;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op3rewriters/TypeFilter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement;
4 | import org.benf.cfr.reader.util.functors.Predicate;
5 |
6 | public class TypeFilter implements Predicate {
7 | private final Class clazz;
8 | private final boolean positive;
9 |
10 | public TypeFilter(Class clazz) {
11 | this.clazz = clazz;
12 | this.positive = true;
13 | }
14 |
15 | public TypeFilter(Class clazz, boolean positive) {
16 | this.clazz = clazz;
17 | this.positive = positive;
18 | }
19 |
20 | @Override
21 | public boolean test(Op03SimpleStatement in) {
22 | return (positive == clazz.isInstance(in.getStatement()));
23 | }
24 | }
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op3rewriters/UselessNops.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op03SimpleStatement;
4 | import org.benf.cfr.reader.util.collections.Functional;
5 | import org.benf.cfr.reader.util.functors.Predicate;
6 |
7 | import java.util.List;
8 |
9 | public class UselessNops {
10 | public static List removeUselessNops(List in) {
11 | return Functional.filter(in, new Predicate() {
12 | @Override
13 | public boolean test(Op03SimpleStatement in) {
14 | return !(in.getSources().isEmpty() && in.getTargets().isEmpty());
15 | }
16 | });
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/EnumAllSuperRewriter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.SuperFunctionInvokation;
4 |
5 | public class EnumAllSuperRewriter extends RedundantSuperRewriter {
6 |
7 | @Override
8 | protected boolean canBeNopped(SuperFunctionInvokation superInvokation) {
9 | return true;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/LValueReplacingRewriter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.StatementContainer;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.AbstractExpressionRewriter;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.ExpressionRewriterFlags;
7 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.SSAIdentifiers;
8 |
9 | import java.util.Map;
10 |
11 | public class LValueReplacingRewriter extends AbstractExpressionRewriter {
12 | private final Map replacements;
13 |
14 | public LValueReplacingRewriter(Map replacements) {
15 | this.replacements = replacements;
16 | }
17 |
18 | @Override
19 | public LValue rewriteExpression(LValue lValue, SSAIdentifiers ssaIdentifiers, StatementContainer statementContainer, ExpressionRewriterFlags flags) {
20 | LValue replacement = replacements.get(lValue);
21 | if (replacement != null) {
22 | return replacement;
23 | }
24 | return lValue.applyExpressionRewriter(this, ssaIdentifiers, statementContainer, flags);
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/Op04Rewriter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement;
4 |
5 | public interface Op04Rewriter {
6 | void rewrite(Op04StructuredStatement root);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/PointlessStructuredExpressions.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op3rewriters.PointlessExpressions;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
6 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
7 | import org.benf.cfr.reader.bytecode.analysis.structured.statement.StructuredAssignment;
8 |
9 | public class PointlessStructuredExpressions {
10 | // Same as the op03 version, but we need to unpick the temporary we introduced.
11 | public static void removePointlessExpression(StructuredStatement stm) {
12 | if (stm instanceof StructuredAssignment) {
13 | StructuredAssignment ass = (StructuredAssignment)stm;
14 | LValue lv = ass.getLvalue();
15 | if (lv.isFakeIgnored()) {
16 | Expression e = ass.getRvalue();
17 | // This didn't used to be. But after some rewriting it might now be.
18 | if (PointlessExpressions.isSafeToIgnore(e)) {
19 | stm.getContainer().nopOut();
20 | }
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/checker/Op04Checker.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.checker;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.transformers.StructuredStatementTransformer;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public interface Op04Checker extends StructuredStatementTransformer {
7 | void commentInto(DecompilerComments comments);
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/AbstractMatchResultIterator.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.wildcard.WildcardMatch;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 |
6 | public abstract class AbstractMatchResultIterator implements MatchResultCollector {
7 | @Override
8 | public void clear() {
9 |
10 | }
11 |
12 | @Override
13 | public void collectStatement(String name, StructuredStatement statement) {
14 | }
15 |
16 | @Override
17 | public void collectMatches(String name, WildcardMatch wcm) {
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/CollectMatch.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | public class CollectMatch implements Matcher {
6 | private final Matcher inner;
7 | private final String name;
8 |
9 | public CollectMatch(String name, Matcher inner) {
10 | this.inner = inner;
11 | this.name = name;
12 | }
13 |
14 | @Override
15 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
16 | MatchIterator orig = matchIterator.copy();
17 | boolean res = inner.match(matchIterator, matchResultCollector);
18 | if (res) {
19 | matchResultCollector.collectStatement(name, orig.getCurrent());
20 | }
21 | return res;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/DeadMethodRemover.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 | import org.benf.cfr.reader.bytecode.analysis.structured.statement.Block;
6 | import org.benf.cfr.reader.bytecode.analysis.structured.statement.StructuredComment;
7 | import org.benf.cfr.reader.entities.ClassFile;
8 | import org.benf.cfr.reader.entities.Method;
9 |
10 | public class DeadMethodRemover {
11 |
12 | public static void removeDeadMethod(ClassFile classFile, Method method) {
13 | Op04StructuredStatement code = method.getAnalysis();
14 | StructuredStatement statement = code.getStatement();
15 | if (!(statement instanceof Block)) return;
16 |
17 | Block block = (Block) statement;
18 | for (Op04StructuredStatement inner : block.getBlockStatements()) {
19 | StructuredStatement innerStatement = inner.getStatement();
20 | if (!(innerStatement instanceof StructuredComment)) {
21 | return;
22 | }
23 | }
24 | method.hideDead();
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/EmptyMatchResultCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.wildcard.WildcardMatch;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 |
6 | public class EmptyMatchResultCollector implements MatchResultCollector {
7 | @Override
8 | public void clear() {
9 |
10 | }
11 |
12 | @Override
13 | public void collectStatement(String name, StructuredStatement statement) {
14 |
15 | }
16 |
17 | @Override
18 | public void collectMatches(String name, WildcardMatch wcm) {
19 |
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/KleeneN.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | public class KleeneN implements Matcher {
6 | private final Matcher inner;
7 | private final int nRequired;
8 |
9 | public KleeneN(int nRequired, Matcher inner) {
10 | this.inner = inner;
11 | this.nRequired = nRequired;
12 | }
13 |
14 | public KleeneN(int nRequired, Matcher... matchers) {
15 | this.inner = new MatchSequence(matchers);
16 | this.nRequired = nRequired;
17 | }
18 |
19 | @Override
20 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
21 | MatchIterator mi = matchIterator.copy();
22 |
23 | int nMatches = 0;
24 | while (inner.match(mi, matchResultCollector)) {
25 | nMatches++;
26 | }
27 |
28 | if (nMatches >= nRequired) {
29 | matchIterator.advanceTo(mi);
30 | return true;
31 | }
32 | return false;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/KleenePlus.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | public class KleenePlus extends KleeneN {
6 | public KleenePlus(Matcher inner) {
7 | super(1, inner);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/KleeneStar.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | public class KleeneStar extends KleeneN {
6 | public KleeneStar(Matcher inner) {
7 | super(0, inner);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/MatchOneOf.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | /**
6 | * Note that this will match the FIRST match, not necessarily the best.
7 | * I.e. no backtracking.
8 | */
9 | public class MatchOneOf implements Matcher {
10 | private final Matcher[] matchers;
11 |
12 | public MatchOneOf(Matcher... matchers) {
13 | this.matchers = matchers;
14 | }
15 |
16 | @Override
17 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
18 |
19 | for (Matcher matcher : matchers) {
20 | MatchIterator mi = matchIterator.copy();
21 | if (matcher.match(mi, matchResultCollector)) {
22 | matchIterator.advanceTo(mi);
23 | return true;
24 | }
25 | }
26 | return false;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/MatchOpt.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | /**
6 | * Note that this will match the FIRST match, not necessarily the best.
7 | * I.e. no backtracking.
8 | */
9 | public class MatchOpt implements Matcher {
10 | private final Matcher matcher;
11 |
12 | public MatchOpt(Matcher matcher) {
13 | this.matcher = matcher;
14 | }
15 |
16 | @Override
17 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
18 | MatchIterator mi = matchIterator.copy();
19 | if (matcher.match(mi, matchResultCollector)) {
20 | matchIterator.advanceTo(mi);
21 | return true;
22 | }
23 | return true;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/MatchResultCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.wildcard.WildcardMatch;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 |
6 | public interface MatchResultCollector {
7 | void clear();
8 |
9 | void collectStatement(String name, StructuredStatement statement);
10 |
11 | void collectMatches(String name, WildcardMatch wcm);
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/MatchSequence.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 |
5 | public class MatchSequence implements Matcher {
6 |
7 | private final Matcher[] inner;
8 | @SuppressWarnings("unused")
9 | private final String name; // useful for breakpointing.
10 |
11 | public MatchSequence(Matcher... inner) {
12 | this.inner = inner;
13 | this.name = "";
14 | }
15 |
16 | public MatchSequence(String name, Matcher... inner) {
17 | this.inner = inner;
18 | this.name = name;
19 | }
20 |
21 | @Override
22 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
23 | MatchIterator mi = matchIterator.copy();
24 |
25 | for (Matcher matcher : inner) {
26 | if (!matcher.match(mi, matchResultCollector)) {
27 | return false;
28 | }
29 | }
30 |
31 | matchIterator.advanceTo(mi);
32 | return true;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/Matcher.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | public interface Matcher {
4 | boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/matchutil/ResetAfterTest.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.wildcard.WildcardMatch;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 |
6 | public class ResetAfterTest implements Matcher {
7 | private final WildcardMatch wildcardMatch;
8 | private final Matcher inner;
9 | private final String name;
10 |
11 | public ResetAfterTest(WildcardMatch wildcardMatch, Matcher inner) {
12 | this(wildcardMatch, "", inner);
13 | }
14 |
15 | public ResetAfterTest(WildcardMatch wildcardMatch, String name, Matcher inner) {
16 | this.inner = inner;
17 | this.wildcardMatch = wildcardMatch;
18 | this.name = name;
19 | }
20 |
21 | @Override
22 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
23 | boolean result = inner.match(matchIterator, matchResultCollector);
24 | if (result) matchResultCollector.collectMatches(name, wildcardMatch);
25 | wildcardMatch.reset();
26 | return result;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/transformers/CanRemovePointlessBlock.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.transformers;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredScope;
4 |
5 | public interface CanRemovePointlessBlock {
6 | void removePointlessBlocks(StructuredScope scope);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/transformers/ExpressionRewriterTransformer.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.transformers;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.ExpressionRewriter;
5 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredScope;
6 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
7 |
8 | public class ExpressionRewriterTransformer implements StructuredStatementTransformer {
9 | private final ExpressionRewriter expressionRewriter;
10 |
11 | public ExpressionRewriterTransformer(ExpressionRewriter expressionRewriter) {
12 | this.expressionRewriter = expressionRewriter;
13 | }
14 |
15 | public void transform(Op04StructuredStatement root) {
16 | StructuredScope structuredScope = new StructuredScope();
17 | root.transform(this, structuredScope);
18 | }
19 |
20 | @Override
21 | public StructuredStatement transform(StructuredStatement in, StructuredScope scope) {
22 | // This is incapable of fundamentally changing the statement type.
23 | // Need a different rewriter if we're going to do that.
24 | in.rewriteExpressions(expressionRewriter);
25 | in.transformStructuredChildren(this, scope);
26 | return in;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/transformers/StructuredStatementTransformer.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.transformers;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredScope;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 |
6 | public interface StructuredStatementTransformer {
7 | StructuredStatement transform(StructuredStatement in, StructuredScope scope);
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/transformers/TryResourceTransformerFinally.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.transformers;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op04StructuredStatement;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredScope;
5 | import org.benf.cfr.reader.bytecode.analysis.structured.statement.StructuredTry;
6 | import org.benf.cfr.reader.entities.ClassFile;
7 |
8 | public abstract class TryResourceTransformerFinally extends TryResourcesTransformerBase{
9 | public TryResourceTransformerFinally(ClassFile classFile) {
10 | super(classFile);
11 | }
12 |
13 | @Override
14 | protected ResourceMatch getResourceMatch(StructuredTry structuredTry, StructuredScope scope) {
15 | Op04StructuredStatement finallyBlock = structuredTry.getFinallyBlock();
16 | return findResourceFinally(finallyBlock);
17 | }
18 |
19 | // If the finally block is
20 | // if (autoclosable != null) {
21 | // close(exception, autoclosable)
22 | // }
23 | //
24 | // or
25 | //
26 | // close(exception, autoclosable)
27 | //
28 | // we can lift the autocloseable into the try.
29 | protected abstract ResourceMatch findResourceFinally(Op04StructuredStatement finallyBlock);
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/opgraph/op4rewriters/transformers/UnusedAnonymousBlockFlattener.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.transformers;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredScope;
4 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
5 | import org.benf.cfr.reader.bytecode.analysis.structured.statement.Block;
6 |
7 | public class UnusedAnonymousBlockFlattener implements StructuredStatementTransformer {
8 | @Override
9 | public StructuredStatement transform(StructuredStatement in, StructuredScope scope) {
10 | if (in instanceof Block) {
11 | ((Block)in).flattenOthersIn();
12 | }
13 | in.transformStructuredChildren(this, scope);
14 | return in;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/StatementContainer.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.InstrIndex;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.BlockIdentifier;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.SSAIdentifiers;
6 |
7 | import java.util.Set;
8 |
9 | public interface StatementContainer {
10 | T getStatement();
11 |
12 | T getTargetStatement(int idx);
13 |
14 | String getLabel();
15 |
16 | InstrIndex getIndex();
17 |
18 | void nopOut();
19 |
20 | void replaceStatement(T newTarget);
21 |
22 | void nopOutConditional();
23 |
24 | SSAIdentifiers getSSAIdentifiers();
25 |
26 | Set getBlockIdentifiers();
27 |
28 | BlockIdentifier getBlockStarted();
29 |
30 | Set getBlocksEnded();
31 |
32 | void copyBlockInformationFrom(StatementContainer other);
33 |
34 | void copyBytecodeInformationFrom(StatementContainer other);
35 | }
36 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/AbstractAssignmentExpression.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
5 | import org.benf.cfr.reader.bytecode.analysis.types.discovery.InferredJavaType;
6 |
7 | public abstract class AbstractAssignmentExpression extends AbstractExpression {
8 |
9 | public AbstractAssignmentExpression(BytecodeLoc loc, InferredJavaType inferredJavaType) {
10 | super(loc, inferredJavaType);
11 | }
12 |
13 | public abstract boolean isSelfMutatingOp1(LValue lValue, ArithOp arithOp);
14 |
15 | public abstract ArithmeticPostMutationOperation getPostMutation();
16 |
17 | public abstract ArithmeticPreMutationOperation getPreMutation();
18 |
19 | public abstract LValue getUpdatedLValue();
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/AbstractMutatingAssignmentExpression.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.types.RawJavaType;
5 | import org.benf.cfr.reader.bytecode.analysis.types.discovery.InferredJavaType;
6 | import org.benf.cfr.reader.entities.exceptions.ExceptionCheck;
7 |
8 | public abstract class AbstractMutatingAssignmentExpression extends AbstractAssignmentExpression {
9 | AbstractMutatingAssignmentExpression(BytecodeLoc loc, InferredJavaType inferredJavaType) {
10 | super(loc, inferredJavaType);
11 | }
12 |
13 | @Override
14 | public boolean canThrow(ExceptionCheck caught) {
15 | return !(getInferredJavaType().getJavaTypeInstance() instanceof RawJavaType);
16 | }
17 |
18 | @Override
19 | public boolean isValidStatement() {
20 | return true;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/AbstractNewArray.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.misc.Precedence;
6 | import org.benf.cfr.reader.bytecode.analysis.types.discovery.InferredJavaType;
7 |
8 | public abstract class AbstractNewArray extends AbstractExpression {
9 | AbstractNewArray(BytecodeLoc loc, InferredJavaType inferredJavaType) {
10 | super(loc, inferredJavaType);
11 | }
12 |
13 | @Override
14 | public Precedence getPrecedence() {
15 | return Precedence.PAREN_SUB_MEMBER;
16 | }
17 |
18 | public abstract int getNumDims();
19 |
20 | public abstract int getNumSizedDims();
21 |
22 | public abstract Expression getDimSize(int dim);
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/BoolOp.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.misc.Precedence;
4 | import org.benf.cfr.reader.util.ConfusedCFRException;
5 |
6 | public enum BoolOp {
7 | OR("||", Precedence.LOG_OR),
8 | AND("&&", Precedence.LOG_AND);
9 |
10 | private final String showAs;
11 | private final Precedence precedence;
12 |
13 | BoolOp(String showAs, Precedence precedence) {
14 | this.showAs = showAs;
15 | this.precedence = precedence;
16 | }
17 |
18 | public String getShowAs() {
19 | return showAs;
20 | }
21 |
22 | public Precedence getPrecedence() {
23 | return precedence;
24 | }
25 |
26 | public BoolOp getDemorgan() {
27 | switch (this) {
28 | case OR:
29 | return AND;
30 | case AND:
31 | return OR;
32 | default:
33 | throw new ConfusedCFRException("Unknown op.");
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/ConditionalExpression.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.misc.Precedence;
6 |
7 | import java.util.Set;
8 |
9 | public interface ConditionalExpression extends Expression {
10 | ConditionalExpression getNegated();
11 |
12 | int getSize(Precedence outerPrecedence);
13 |
14 | ConditionalExpression getDemorganApplied(boolean amNegating);
15 |
16 | /*
17 | * Normalise tree layout so ((a || b) || c) --> (a || (b || c)).
18 | * This is useful so any patterns can know what they're matching against.
19 | */
20 | ConditionalExpression getRightDeep();
21 |
22 | Set getLoopLValues();
23 |
24 | ConditionalExpression optimiseForType();
25 |
26 | ConditionalExpression simplify();
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/LambdaExpressionCommon.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | public interface LambdaExpressionCommon {
4 | }
5 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/LiteralHex.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.literal.TypedLiteral;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | /*
7 | * It's debatable whether we should have this, or make it a temporary state of the dumper, such
8 | * that we dump literals immediately under a bitwise operation as hex.
9 | *
10 | * Currently, have gone for this, as the maintenance to force a reset if we have
11 | * 0xff | (0xf + foo(12, 23, 14))
12 | * means we would need to undo any dumper state not just on the way back up, but also when we left
13 | * literals immediately inside the tree. This feels like it's a lot more work than it's worth.
14 | *
15 | * Doing things this way also means that if we eventually expose this class, we can allow a UI to tweak
16 | * this node... ;)
17 | */
18 | public class LiteralHex extends Literal {
19 |
20 | public LiteralHex(TypedLiteral value) {
21 | super(value);
22 | }
23 |
24 | @Override
25 | public Dumper dumpInner(Dumper d) {
26 | return value.dumpWithHint(d, TypedLiteral.FormatHint.Hex);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/misc/Precedence.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression.misc;
2 |
3 | public enum Precedence {
4 | HIGHEST(true),
5 | PAREN_SUB_MEMBER(true),
6 | LAMBDA(true),
7 | UNARY_POST(false),
8 | UNARY_OTHER(false),
9 | MUL_DIV_MOD(true),
10 | ADD_SUB(true),
11 | BITWISE_SHIFT(true),
12 | REL_CMP_INSTANCEOF(true),
13 | REL_EQ(true),
14 | BIT_AND(true),
15 | BIT_XOR(true),
16 | BIT_OR(true),
17 | LOG_AND(true, true),
18 | LOG_OR(true, true),
19 | CONDITIONAL(false),
20 | ASSIGNMENT(false),
21 | WEAKEST(true);
22 |
23 | private final boolean isLtoR;
24 | private final boolean commute;
25 |
26 | Precedence(boolean ltoR) {
27 | this.isLtoR = ltoR;
28 | this.commute = false;
29 | }
30 |
31 | Precedence(boolean ltoR, boolean commute) {
32 | this.isLtoR = ltoR;
33 | this.commute = commute;
34 | }
35 |
36 | public boolean isLtoR() {
37 | return isLtoR;
38 | }
39 |
40 | public boolean isCommutative() {
41 | return commute;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/rewriteinterface/BoxingProcessor.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression.rewriteinterface;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.PrimitiveBoxingRewriter;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.StatementContainer;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.ExpressionRewriter;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.ExpressionRewriterFlags;
7 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.SSAIdentifiers;
8 |
9 | public interface BoxingProcessor {
10 | // return true if boxing finished.
11 | boolean rewriteBoxing(PrimitiveBoxingRewriter boxingRewriter);
12 |
13 | void applyNonArgExpressionRewriter(ExpressionRewriter expressionRewriter, SSAIdentifiers ssaIdentifiers, StatementContainer statementContainer, ExpressionRewriterFlags flags);
14 | }
15 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/expression/rewriteinterface/FunctionProcessor.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.expression.rewriteinterface;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.VarArgsRewriter;
4 |
5 | public interface FunctionProcessor {
6 | // This feels like it should be refactored into a generalised visitor interface
7 | void rewriteVarArgs(VarArgsRewriter varArgsRewriter);
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/rewriters/AbstractExpressionVisitor.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.ArithmeticOperation;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.Literal;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.TernaryExpression;
7 |
8 | public class AbstractExpressionVisitor implements ExpressionVisitor {
9 | @Override
10 | public T visit(Expression e) {
11 | return null;
12 | }
13 |
14 | @Override
15 | public T visit(Literal l) {
16 | return null;
17 | }
18 |
19 | @Override
20 | public T visit(TernaryExpression e) {
21 | return null;
22 | }
23 |
24 | @Override
25 | public T visit(ArithmeticOperation e) {
26 | return null;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/rewriters/DeepCloneable.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.rewriters;
2 |
3 | public interface DeepCloneable {
4 | X deepClone(CloneHelper cloneHelper);
5 |
6 | // Outer deep clone exists to cause visitor action, as we've lost generic information at the
7 | // call site.
8 | X outerDeepClone(CloneHelper cloneHelper);
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/rewriters/ExpressionRewriterFlags.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.rewriters;
2 |
3 | public enum ExpressionRewriterFlags {
4 | RVALUE,
5 | LVALUE,
6 | LANDRVALUE
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/rewriters/ExpressionRewriterHelper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.StatementContainer;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.SSAIdentifiers;
6 |
7 | import java.util.List;
8 |
9 | public class ExpressionRewriterHelper {
10 | public static void applyForwards(List list, ExpressionRewriter expressionRewriter, SSAIdentifiers ssaIdentifiers, StatementContainer statementContainer, ExpressionRewriterFlags flags) {
11 | for (int x = 0; x < list.size(); ++x) {
12 | list.set(x, expressionRewriter.rewriteExpression(list.get(x), ssaIdentifiers, statementContainer, flags));
13 | }
14 | }
15 |
16 | public static void applyBackwards(List list, ExpressionRewriter expressionRewriter, SSAIdentifiers ssaIdentifiers, StatementContainer statementContainer, ExpressionRewriterFlags flags) {
17 | for (int x = list.size()-1; x >= 0; --x) {
18 | list.set(x, expressionRewriter.rewriteExpression(list.get(x), ssaIdentifiers, statementContainer, flags));
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/rewriters/ExpressionVisitor.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.rewriters;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.ArithmeticOperation;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.Literal;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.TernaryExpression;
7 |
8 | public interface ExpressionVisitor {
9 | T visit(Expression e);
10 |
11 | T visit(Literal l);
12 |
13 | T visit(TernaryExpression e);
14 |
15 | T visit(ArithmeticOperation e);
16 | }
17 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/statement/AbstractAssignment.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.statement;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.AbstractAssignmentExpression;
7 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.ArithOp;
8 |
9 | public abstract class AbstractAssignment extends AbstractStatement {
10 |
11 | public AbstractAssignment(BytecodeLoc loc) {
12 | super(loc);
13 | }
14 |
15 | public abstract boolean isSelfMutatingOperation();
16 |
17 | public abstract boolean isSelfMutatingOp1(LValue lValue, ArithOp arithOp);
18 |
19 | public abstract Expression getPostMutation();
20 |
21 | public abstract Expression getPreMutation();
22 |
23 | public abstract AbstractAssignmentExpression getInliningExpression();
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/statement/JumpingStatement.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.statement;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.Statement;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.JumpType;
6 |
7 | public abstract class JumpingStatement extends AbstractStatement {
8 | public JumpingStatement(BytecodeLoc loc) {
9 | super(loc);
10 | }
11 |
12 | public abstract Statement getJumpTarget();
13 |
14 | public abstract JumpType getJumpType();
15 |
16 | public abstract void setJumpType(JumpType jumpType);
17 |
18 | public abstract boolean isConditional();
19 | }
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/statement/MonitorStatement.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.statement;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 |
5 | public abstract class MonitorStatement extends AbstractStatement {
6 | public MonitorStatement(BytecodeLoc loc) {
7 | super(loc);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/statement/ReturnStatement.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.statement;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.CloneHelper;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.rewriters.DeepCloneable;
6 |
7 | public abstract class ReturnStatement extends AbstractStatement {
8 |
9 | public ReturnStatement(BytecodeLoc loc) {
10 | super(loc);
11 | }
12 |
13 | @Override
14 | public boolean fallsToNext() {
15 | return false;
16 | }
17 |
18 | @Override
19 | public ReturnStatement outerDeepClone(CloneHelper cloneHelper) {
20 | throw new UnsupportedOperationException();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/BlockIdentifierFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | public class BlockIdentifierFactory {
4 | int idx = 0;
5 |
6 | public BlockIdentifier getNextBlockIdentifier(BlockType blockType) {
7 | return new BlockIdentifier(idx++, blockType);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/BlockType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | public enum BlockType {
4 | WHILELOOP(true, true),
5 | DOLOOP(true, true),
6 | UNCONDITIONALDOLOOP(true, true),
7 | FORLOOP(true, true),
8 | TRYBLOCK(false, false),
9 | SIMPLE_IF_TAKEN(false, false),
10 | SIMPLE_IF_ELSE(false, false),
11 | CATCHBLOCK(false, false),
12 | SWITCH(true, false),
13 | CASE(false, false),
14 | ANONYMOUS(true, false),
15 | MONITOR(false, false);
16 |
17 | private final boolean breakable;
18 | private final boolean isloop;
19 |
20 | BlockType(boolean breakable, boolean isloop) {
21 | this.breakable = breakable;
22 | this.isloop = isloop;
23 | }
24 |
25 | public boolean isBreakable() {
26 | return breakable;
27 | }
28 |
29 | public boolean isLoop() { return isloop; }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/ComparableUnderEC.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | public interface ComparableUnderEC {
4 | boolean equivalentUnder(Object o, EquivalenceConstraint constraint);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/EquivalenceConstraint.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import java.util.Collection;
4 |
5 | public interface EquivalenceConstraint {
6 | boolean equivalent(Object o1, Object o2);
7 |
8 | boolean equivalent(Collection o1, Collection o2);
9 |
10 | boolean equivalent(ComparableUnderEC o1, ComparableUnderEC o2);
11 | }
12 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/JumpType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | public enum JumpType {
4 | NONE("none", false),
5 | GOTO("goto", true),
6 | GOTO_OUT_OF_IF("goto_out_of_if", false),
7 | GOTO_OUT_OF_TRY("goto_out_of_try", false),
8 | BREAK("break", false),
9 | BREAK_ANONYMOUS("break anon", false),
10 | CONTINUE("continue", false),
11 | END_BLOCK("// endblock", false);
12 |
13 |
14 | private final String description;
15 | private final boolean isUnknown;
16 |
17 | JumpType(String description, boolean isUnknown) {
18 | this.description = description;
19 | this.isUnknown = isUnknown;
20 | }
21 |
22 | public boolean isUnknown() {
23 | return isUnknown;
24 | }
25 |
26 | @Override
27 | public String toString() {
28 | return description;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/LValueAssignmentCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.StatementContainer;
6 | import org.benf.cfr.reader.bytecode.analysis.parse.lvalue.LocalVariable;
7 | import org.benf.cfr.reader.bytecode.analysis.parse.lvalue.StackSSALabel;
8 |
9 | public interface LValueAssignmentCollector {
10 | // TODO : Should these be StackSSALabels? Seems they should be lvalues.
11 | void collect(StackSSALabel lValue, StatementContainer statementContainer, Expression value);
12 |
13 | void collectMultiUse(StackSSALabel lValue, StatementContainer statementContainer, Expression value);
14 |
15 | void collectMutatedLValue(LValue lValue, StatementContainer statementContainer, Expression value);
16 |
17 | void collectLocalVariableAssignment(LocalVariable localVariable, StatementContainer statementContainer, Expression value);
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/LValueUsageCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
4 |
5 | public interface LValueUsageCollector {
6 | void collect(LValue lValue, ReadWrite rw);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/LValueUsageCollectorSimple.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
4 | import org.benf.cfr.reader.util.collections.SetFactory;
5 |
6 | import java.util.Collection;
7 | import java.util.Set;
8 |
9 | public class LValueUsageCollectorSimple implements LValueUsageCollector {
10 | private final Set used = SetFactory.newSet();
11 |
12 | @Override
13 | public void collect(LValue lValue, ReadWrite rw) {
14 | used.add(lValue);
15 | }
16 |
17 | public Collection getUsedLValues() {
18 | return used;
19 | }
20 |
21 | public boolean isUsed(LValue lValue) {
22 | return used.contains(lValue);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/LValueUsageCollectorSimpleRW.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
4 | import org.benf.cfr.reader.util.collections.SetFactory;
5 |
6 | import java.util.Set;
7 |
8 | public class LValueUsageCollectorSimpleRW implements LValueUsageCollector {
9 | private final Set read = SetFactory.newSet();
10 | private final Set write = SetFactory.newSet();
11 |
12 | @Override
13 | public void collect(LValue lValue, ReadWrite rw) {
14 | switch (rw) {
15 | case READ:
16 | read.add(lValue);
17 | break;
18 | case READ_WRITE:
19 | read.add(lValue);
20 | case WRITE:
21 | write.add(lValue);
22 | break;
23 | }
24 | }
25 |
26 | public Set getRead() {
27 | return read;
28 | }
29 |
30 | public Set getWritten() {
31 | return write;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/ReadWrite.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | public enum ReadWrite {
4 | READ,
5 | WRITE,
6 | READ_WRITE
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/SSAIdentifierFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import org.benf.cfr.reader.util.collections.MapFactory;
4 | import org.benf.cfr.reader.util.functors.UnaryFunction;
5 |
6 | import java.util.Map;
7 |
8 | public class SSAIdentifierFactory {
9 | private final Map nextIdentFor = MapFactory.newLazyMap(
10 | MapFactory.newOrderedMap(),
11 | new UnaryFunction() {
12 | @Override
13 | public Integer invoke(KEYTYPE ignore) {
14 | return 0;
15 | }
16 | });
17 |
18 | private final UnaryFunction typeComparisonFunction;
19 |
20 | public SSAIdentifierFactory(UnaryFunction typeComparisonFunction) {
21 | this.typeComparisonFunction = typeComparisonFunction;
22 | }
23 |
24 | public SSAIdent getIdent(KEYTYPE lValue) {
25 | int val = nextIdentFor.get(lValue);
26 | nextIdentFor.put(lValue, val + 1);
27 | return new SSAIdent(val, typeComparisonFunction == null ? null : typeComparisonFunction.invoke(lValue));
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/SSAIdentifierUtils.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.LValue;
4 |
5 | import java.util.Collection;
6 |
7 | public class SSAIdentifierUtils {
8 | public static boolean isMovableUnder(Collection lValues, LValue lValueMove, SSAIdentifiers atTarget, SSAIdentifiers atSource) {
9 | for (LValue lValue : lValues) {
10 | if (!atTarget.isValidReplacement(lValue, atSource)) return false;
11 | }
12 | SSAIdent afterSrc = atSource.getSSAIdentOnExit(lValueMove);
13 | if (afterSrc == null) return false;
14 | SSAIdent beforeTarget = atTarget.getSSAIdentOnEntry(lValueMove);
15 | if (beforeTarget == null) return false;
16 | if (beforeTarget.isSuperSet(afterSrc)) return true;
17 | // weird, but I suppose legitimate.
18 | SSAIdent afterTarget = atTarget.getSSAIdentOnExit(lValueMove);
19 | if (beforeTarget.equals(afterSrc) && afterTarget.equals(afterSrc)) return true;
20 | return false;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/utils/scope/ScopeDiscoverInfoCache.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.utils.scope;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
4 | import org.benf.cfr.reader.util.collections.MapFactory;
5 |
6 | import java.util.Map;
7 |
8 | public class ScopeDiscoverInfoCache {
9 | private final Map tests = MapFactory.newIdentityMap();
10 |
11 | public Boolean get(StructuredStatement structuredStatement) {
12 | return tests.get(structuredStatement);
13 | }
14 |
15 | public void put(StructuredStatement structuredStatement, Boolean b) {
16 | tests.put(structuredStatement, b);
17 | }
18 |
19 | boolean anyFound() {
20 | for (Boolean value : tests.values()) {
21 | if (value) return true;
22 | }
23 | return false;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/wildcard/OptionalMatch.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.wildcard;
2 |
3 | import org.benf.cfr.reader.util.Optional;
4 |
5 | public class OptionalMatch {
6 | final Optional expected; // may be missing.
7 | T matched;
8 |
9 | OptionalMatch(Optional expected) {
10 | this.expected = expected;
11 | reset();
12 | }
13 |
14 | public boolean match(T other) {
15 | if (matched != null) return matched.equals(other);
16 | matched = other;
17 | return true;
18 | }
19 |
20 | public void reset() {
21 | if (expected.isSet()) {
22 | matched = expected.getValue();
23 | } else {
24 | matched = null;
25 | }
26 | }
27 |
28 | public T getMatch() {
29 | return matched;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/parse/wildcard/Wildcard.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.parse.wildcard;
2 |
3 | public interface Wildcard {
4 | X getMatch();
5 |
6 | void resetMatch();
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/stack/StackDelta.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.stack;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
4 |
5 | public interface StackDelta {
6 | boolean isNoOp();
7 |
8 | StackTypes getConsumed();
9 |
10 | StackTypes getProduced();
11 |
12 | long getChange();
13 | }
14 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/stack/StackDeltaImpl.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.stack;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
4 | import org.benf.cfr.reader.util.ConfusedCFRException;
5 |
6 | public class StackDeltaImpl implements StackDelta {
7 | private final StackTypes consumed;
8 | private final StackTypes produced;
9 |
10 | public StackDeltaImpl(StackTypes consumed, StackTypes produced) {
11 | if (consumed == null || produced == null) {
12 | throw new ConfusedCFRException("Must not have null stackTypes");
13 | }
14 | this.consumed = consumed;
15 | this.produced = produced;
16 | }
17 |
18 | @Override
19 | public boolean isNoOp() {
20 | return consumed.isEmpty() && produced.isEmpty();
21 | }
22 |
23 | @Override
24 | public StackTypes getConsumed() {
25 | return consumed;
26 | }
27 |
28 | @Override
29 | public StackTypes getProduced() {
30 | return produced;
31 | }
32 |
33 | @Override
34 | public long getChange() {
35 | return produced.size() - consumed.size();
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | return "Consumes " + consumed + ", Produces " + produced;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/stack/StackEntryHolder.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.stack;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
4 | import org.benf.cfr.reader.util.DecompilerComment;
5 |
6 | import java.util.Set;
7 |
8 | public class StackEntryHolder {
9 | private StackEntry stackEntry;
10 |
11 | StackEntryHolder(StackType stackType) {
12 | stackEntry = new StackEntry(stackType);
13 | }
14 |
15 | public void mergeWith(StackEntryHolder other, Set comments) {
16 | stackEntry.mergeWith(other.stackEntry, comments);
17 | other.stackEntry = stackEntry;
18 | }
19 |
20 | @Override
21 | public String toString() {
22 | return stackEntry.toString();
23 | }
24 |
25 | public StackEntry getStackEntry() {
26 | return stackEntry;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/structured/statement/AbstractStructuredContinue.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.structured.statement;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.BlockIdentifier;
5 |
6 | public abstract class AbstractStructuredContinue extends AbstractStructuredStatement {
7 | public AbstractStructuredContinue(BytecodeLoc loc) {
8 | super(loc);
9 | }
10 |
11 | public abstract BlockIdentifier getContinueTgt();
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/structured/statement/UnstructuredGoto.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.structured.statement;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.state.TypeUsageCollector;
5 | import org.benf.cfr.reader.util.output.Dumper;
6 |
7 | public class UnstructuredGoto extends AbstractUnStructuredStatement {
8 |
9 | public UnstructuredGoto(BytecodeLoc loc) {
10 | super(loc);
11 | }
12 |
13 | @Override
14 | public BytecodeLoc getCombinedLoc() {
15 | return getLoc();
16 | }
17 |
18 | @Override
19 | public Dumper dump(Dumper dumper) {
20 | return dumper.print("** GOTO " + getContainer().getTargetLabel(0)).newln();
21 | }
22 |
23 | @Override
24 | public void collectTypeUsages(TypeUsageCollector collector) {
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/structured/statement/placeholder/ElseBlock.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.structured.statement.placeholder;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil.MatchIterator;
4 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil.MatchResultCollector;
5 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
6 |
7 | public class ElseBlock extends AbstractPlaceholder {
8 | @Override
9 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
10 | if (matchIterator.getCurrent() instanceof ElseBlock) {
11 | matchIterator.advance();
12 | return true;
13 | }
14 | return false;
15 | }
16 |
17 | @Override
18 | public boolean supportsContinueBreak() {
19 | return false;
20 | }
21 |
22 | @Override
23 | public boolean supportsBreak() {
24 | return false;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/structured/statement/placeholder/EndBlock.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.structured.statement.placeholder;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil.MatchIterator;
4 | import org.benf.cfr.reader.bytecode.analysis.opgraph.op4rewriters.matchutil.MatchResultCollector;
5 | import org.benf.cfr.reader.bytecode.analysis.structured.StructuredStatement;
6 | import org.benf.cfr.reader.bytecode.analysis.structured.statement.Block;
7 |
8 | public class EndBlock extends AbstractPlaceholder {
9 |
10 | private final Block block;
11 |
12 | public EndBlock(Block block) {
13 | this.block = block;
14 | }
15 |
16 | @Override
17 | public boolean match(MatchIterator matchIterator, MatchResultCollector matchResultCollector) {
18 | StructuredStatement current = matchIterator.getCurrent();
19 | if (current instanceof EndBlock) {
20 | EndBlock other = (EndBlock) current;
21 | if (block == null || block.equals(other.block)) {
22 | matchIterator.advance();
23 | return true;
24 | }
25 | }
26 | return false;
27 | }
28 |
29 | @Override
30 | public boolean supportsContinueBreak() {
31 | return false;
32 | }
33 |
34 | @Override
35 | public boolean supportsBreak() {
36 | return false;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/ClassNameUtils.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.Pair;
4 |
5 | public class ClassNameUtils {
6 | public static String convertFromPath(String from) {
7 | return from.replace('/', '.');
8 | }
9 |
10 |
11 | public static String convertToPath(String from) {
12 | return from.replace('.', '/');
13 | }
14 |
15 | public static Pair getPackageAndClassNames(JavaTypeInstance type) {
16 | return getPackageAndClassNames(type.getRawName());
17 | }
18 |
19 | public static Pair getPackageAndClassNames(String rawName) {
20 | String full = ClassNameUtils.convertFromPath(rawName);
21 | int idx = full.lastIndexOf('.');
22 | if (idx == -1) return Pair.make("", rawName);
23 | return Pair.make(full.substring(0, idx), full.substring(idx + 1));
24 | }
25 |
26 | public static String getTypeFixPrefix(JavaTypeInstance typ) {
27 | String rawName = typ.getRawName();
28 | rawName = rawName.replace("[]", "_arr").replaceAll("[*?<>. ]","_");
29 | return rawName + "_";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/DynamicInvokeType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | public enum DynamicInvokeType {
4 | UNKNOWN("?"),
5 | BOOTSTRAP("bootstrap"), // bootstrap - for groovy.
6 | METAFACTORY_1("metaFactory"),
7 | METAFACTORY_2("metafactory"),
8 | ALTMETAFACTORY_1("altMetaFactory"),
9 | ALTMETAFACTORY_2("altMetafactory");
10 |
11 | private final String constName;
12 |
13 | DynamicInvokeType(String constName) {
14 | this.constName = constName;
15 | }
16 |
17 | public String getConstName() {
18 | return constName;
19 | }
20 |
21 | public static DynamicInvokeType lookup(String name) {
22 | if (name.equals(METAFACTORY_1.constName)) return METAFACTORY_1;
23 | if (name.equals(METAFACTORY_2.constName)) return METAFACTORY_2;
24 | if (name.equals(ALTMETAFACTORY_1.constName)) return ALTMETAFACTORY_1;
25 | if (name.equals(ALTMETAFACTORY_2.constName)) return ALTMETAFACTORY_2;
26 | if (name.equals(BOOTSTRAP.constName)) return BOOTSTRAP;
27 | return UNKNOWN;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/InnerClassInfoUtils.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | public class InnerClassInfoUtils {
4 | public static JavaRefTypeInstance getTransitiveOuterClass(JavaRefTypeInstance type) {
5 | while (type.getInnerClassHereInfo().isInnerClass()) {
6 | type = type.getInnerClassHereInfo().getOuterClass();
7 | }
8 | return type;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/JavaGenericBaseInstance.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 |
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | public interface JavaGenericBaseInstance extends JavaTypeInstance {
9 | JavaTypeInstance getBoundInstance(GenericTypeBinder genericTypeBinder);
10 |
11 | boolean tryFindBinding(JavaTypeInstance other, GenericTypeBinder target);
12 |
13 | boolean hasUnbound();
14 |
15 | boolean hasL01Wildcard();
16 |
17 | JavaTypeInstance getWithoutL01Wildcard();
18 |
19 | boolean hasForeignUnbound(ConstantPool cp, int depth, boolean noWildcard, Map externals);
20 |
21 | List getGenericTypes();
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/MiscAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | import org.benf.cfr.reader.entities.annotations.AnnotationTableEntry;
4 | import org.benf.cfr.reader.entities.attributes.AttributeMap;
5 | import org.benf.cfr.reader.entities.attributes.AttributeRuntimeInvisibleAnnotations;
6 | import org.benf.cfr.reader.entities.attributes.AttributeRuntimeVisibleAnnotations;
7 | import org.benf.cfr.reader.util.collections.ListFactory;
8 |
9 | import java.util.List;
10 |
11 | public class MiscAnnotations {
12 | public static List BasicAnnotations(AttributeMap attributeMap) {
13 | AttributeRuntimeVisibleAnnotations a1 = attributeMap.getByName(AttributeRuntimeVisibleAnnotations.ATTRIBUTE_NAME);
14 | AttributeRuntimeInvisibleAnnotations a2 = attributeMap.getByName(AttributeRuntimeInvisibleAnnotations.ATTRIBUTE_NAME);
15 | List e1 = a1 == null ? null : a1.getEntryList();
16 | List e2 = a2 == null ? null : a2.getEntryList();
17 | return ListFactory.combinedOptimistic(e1,e2);
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/StackType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | /**
4 | * See table 3.3 in JVM spec.
5 | */
6 | public enum StackType {
7 | INT("int", 1, true),
8 | FLOAT("float", 1, true),
9 | REF("reference", 1, false),
10 | RETURNADDRESS("returnaddress", 1, false),
11 | RETURNADDRESSORREF("returnaddress or ref", 1, false), // Special, for astore.
12 | LONG("long", 2, true),
13 | DOUBLE("double", 2, true),
14 | VOID("void", 0, false); // not real, but useful.
15 |
16 | private final int computationCategory;
17 | private final StackTypes asList;
18 | private final boolean closed;
19 | private final String name;
20 |
21 | StackType(String name, int computationCategory, boolean closed) {
22 | this.name = name;
23 | this.computationCategory = computationCategory;
24 | this.asList = new StackTypes(this);
25 | this.closed = closed;
26 | }
27 |
28 | public int getComputationCategory() {
29 | return computationCategory;
30 | }
31 |
32 | public StackTypes asList() {
33 | return asList;
34 | }
35 |
36 | public boolean isClosed() {
37 | return closed;
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return name;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/StackTypes.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | /**
8 | * Really List but for legibility, shortened.
9 | */
10 | public class StackTypes extends ArrayList {
11 | public static final StackTypes EMPTY = new StackTypes();
12 |
13 | public StackTypes(StackType... stackTypes) {
14 | super(Arrays.asList(stackTypes));
15 | }
16 |
17 | public StackTypes(List stackTypes) {
18 | super(stackTypes);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/WildcardType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types;
2 |
3 | public enum WildcardType {
4 | NONE(""),
5 | SUPER("super"),
6 | EXTENDS("extends");
7 |
8 | private final String name;
9 |
10 | WildcardType(String name) {
11 | this.name = name;
12 | }
13 |
14 |
15 | @Override
16 | public String toString() {
17 | return name;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/annotated/JavaAnnotatedTypeInstance.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types.annotated;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaAnnotatedTypeIterator;
4 | import org.benf.cfr.reader.util.output.Dumpable;
5 |
6 | public interface JavaAnnotatedTypeInstance extends Dumpable {
7 | JavaAnnotatedTypeIterator pathIterator();
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/types/discovery/CastAction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.types.discovery;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.loc.BytecodeLoc;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
5 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.CastExpression;
6 | import org.benf.cfr.reader.bytecode.analysis.types.RawJavaType;
7 |
8 | public enum CastAction {
9 | None {
10 | public Expression performCastAction(Expression orig, InferredJavaType tgtType) {
11 | return orig;
12 | }
13 | },
14 | InsertExplicit {
15 | public Expression performCastAction(Expression orig, InferredJavaType tgtType) {
16 | if (tgtType.getJavaTypeInstance() == RawJavaType.BOOLEAN) return orig;
17 | return new CastExpression(BytecodeLoc.NONE, tgtType, orig);
18 | }
19 | };
20 |
21 | public abstract Expression performCastAction(Expression orig, InferredJavaType tgtType);
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/variables/Ident.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.variables;
2 |
3 | public class Ident {
4 | private final int stackpos;
5 | private final int idx;
6 |
7 | public Ident(int stackpos, int idx) {
8 | this.stackpos = stackpos;
9 | this.idx = idx;
10 | }
11 |
12 | @Override
13 | public String toString() {
14 | if (idx == 0) return "" + stackpos;
15 | return "" + stackpos + "_" + idx;
16 | }
17 |
18 | @Override
19 | public boolean equals(Object o) {
20 | if (this == o) return true;
21 | if (o == null || getClass() != o.getClass()) return false;
22 |
23 | Ident ident = (Ident) o;
24 |
25 | if (idx != ident.idx) return false;
26 | if (stackpos != ident.stackpos) return false;
27 |
28 | return true;
29 | }
30 |
31 | public int getIdx() {
32 | return idx;
33 | }
34 |
35 | @Override
36 | public int hashCode() {
37 | int result = stackpos;
38 | result = 31 * result + idx;
39 | return result;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/variables/NamedVariable.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.variables;
2 |
3 | import org.benf.cfr.reader.util.output.Dumpable;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public interface NamedVariable extends Dumpable {
7 | void forceName(String name);
8 |
9 | String getStringName();
10 |
11 | boolean isGoodName();
12 |
13 | @Override
14 | Dumper dump(Dumper d);
15 |
16 | Dumper dump(Dumper d, boolean defines);
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/variables/Slot.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.variables;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 |
5 | public class Slot {
6 | private final JavaTypeInstance javaTypeInstance;
7 | private final int idx;
8 |
9 | public Slot(JavaTypeInstance javaTypeInstance, int idx) {
10 | this.javaTypeInstance = javaTypeInstance;
11 | this.idx = idx;
12 | }
13 |
14 | @Override
15 | public boolean equals(Object o) {
16 | if (this == o) return true;
17 | if (o == null || getClass() != o.getClass()) return false;
18 |
19 | Slot slot = (Slot) o;
20 |
21 | if (idx != slot.idx) return false;
22 |
23 | return true;
24 | }
25 |
26 | public int getIdx() {
27 | return idx;
28 | }
29 |
30 | public JavaTypeInstance getJavaTypeInstance() {
31 | return javaTypeInstance;
32 | }
33 |
34 | @Override
35 | public String toString() {
36 | return "S{" +
37 | idx +
38 | '}';
39 | }
40 |
41 | @Override
42 | public int hashCode() {
43 | return idx;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/variables/VariableNamer.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.variables;
2 |
3 | import java.util.List;
4 |
5 | public interface VariableNamer {
6 | NamedVariable getName(int originalRawOffset, Ident ident, long stackPosition, boolean clashed);
7 |
8 | List getNamedVariables();
9 |
10 | void mutatingRenameUnClash(NamedVariable toRename);
11 |
12 | void forceName(Ident ident, long stackPosition, String name);
13 | }
14 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/analysis/variables/VariableNamerFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.analysis.variables;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.entities.attributes.AttributeLocalVariableTable;
5 |
6 | public class VariableNamerFactory {
7 | public static VariableNamer getNamer(AttributeLocalVariableTable source, ConstantPool cp) {
8 | if (source == null) return new VariableNamerDefault();
9 | return new VariableNamerHinted(source.getLocalVariableEntryList(), cp);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/DecodedSwitch.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import java.util.List;
4 |
5 | public interface DecodedSwitch {
6 |
7 | List getJumpTargets();
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/DecodedSwitchEntry.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.util.StringUtils;
4 |
5 | import java.util.List;
6 |
7 | public class DecodedSwitchEntry {
8 | private final List value;
9 | // TODO : Not useful past 0p01->Op02 stage. Create a different interface.
10 | private final int bytecodeTarget;
11 |
12 | public DecodedSwitchEntry(List value, int bytecodeTarget) {
13 | this.bytecodeTarget = bytecodeTarget;
14 | this.value = value;
15 | }
16 |
17 | public List getValue() {
18 | return value;
19 | }
20 |
21 | int getBytecodeTarget() {
22 | return bytecodeTarget;
23 | }
24 |
25 | @Override
26 | public String toString() {
27 | StringBuilder sb = new StringBuilder();
28 | boolean first = true;
29 | sb.append("case ");
30 | for (Integer val : value) {
31 | first = StringUtils.comma(first, sb);
32 | sb.append(val == null ? "default" : val);
33 | }
34 | sb.append(" -> ").append(bytecodeTarget);
35 | return sb.toString();
36 | }
37 |
38 | public boolean hasDefault() {
39 | return value.contains(null);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
6 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
7 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
8 | import org.benf.cfr.reader.entities.Method;
9 | import org.benf.cfr.reader.util.bytestream.ByteData;
10 |
11 | public interface OperationFactory {
12 | /*
13 | * When an operation is being decoded, it may need to know about the method / class it's in
14 | * (eg invokedynamic);
15 | */
16 | StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
17 | StackSim stackSim, Method method);
18 |
19 | Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset);
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryCPEntry.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
6 | import org.benf.cfr.reader.util.bytestream.ByteData;
7 |
8 | public class OperationFactoryCPEntry extends OperationFactoryDefault {
9 | private static final int LENGTH_OF_FIELD_INDEX = 1;
10 |
11 | @Override
12 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
13 | byte[] args = bd.getBytesAt(LENGTH_OF_FIELD_INDEX, 1);
14 | ConstantPoolEntry[] cpEntries = new ConstantPoolEntry[]{cp.getEntry(bd.getU1At(1))};
15 | return new Op01WithProcessedDataAndByteJumps(instr, args, null, offset, cpEntries);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryCPEntryW.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
6 | import org.benf.cfr.reader.util.bytestream.ByteData;
7 |
8 | public class OperationFactoryCPEntryW extends OperationFactoryDefault {
9 | private static final int LENGTH_OF_FIELD_INDEX = 2;
10 |
11 | @Override
12 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
13 | byte[] args = bd.getBytesAt(LENGTH_OF_FIELD_INDEX, 1);
14 | ConstantPoolEntry[] cpEntries = new ConstantPoolEntry[]{cp.getEntry(bd.getU2At(1))};
15 | return new Op01WithProcessedDataAndByteJumps(instr, args, null, offset, cpEntries);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryConditionalJump.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 |
7 | public class OperationFactoryConditionalJump extends OperationFactoryDefault {
8 |
9 | private static final long OFFSET_OF_TARGET = 1;
10 |
11 | @Override
12 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
13 | byte[] args = bd.getBytesAt(instr.getRawLength(), 1);
14 |
15 | short targetOffset = bd.getS2At(OFFSET_OF_TARGET);
16 |
17 | int[] targetOffsets = new int[2]; // next instr is either successor, or targetOffset.
18 | targetOffsets[1] = targetOffset;
19 | targetOffsets[0] = instr.getRawLength() + 1;
20 |
21 | return new Op01WithProcessedDataAndByteJumps(instr, args, targetOffsets, offset);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryDup.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
6 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
7 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
9 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
10 | import org.benf.cfr.reader.entities.Method;
11 | import org.benf.cfr.reader.util.bytestream.ByteData;
12 |
13 | public class OperationFactoryDup extends OperationFactoryDupBase {
14 |
15 | @Override
16 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
17 | StackSim stackSim, Method method) {
18 | StackTypes popped = getStackTypes(stackSim, 0);
19 | StackTypes pushed = getStackTypes(stackSim, 0, 0);
20 | return new StackDeltaImpl(popped, pushed);
21 | }
22 |
23 | @Override
24 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
25 | return new Op01WithProcessedDataAndByteJumps(instr, null, null, offset);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryDupBase.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | public abstract class OperationFactoryDupBase extends OperationFactoryDefault {
4 | }
5 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryDupX1.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
6 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
7 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
9 | import org.benf.cfr.reader.entities.Method;
10 | import org.benf.cfr.reader.util.bytestream.ByteData;
11 |
12 | public class OperationFactoryDupX1 extends OperationFactoryDupBase {
13 |
14 | @Override
15 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
16 | StackSim stackSim, Method method) {
17 | checkCat(stackSim, 0, 1);
18 | checkCat(stackSim, 1, 1);
19 | return new StackDeltaImpl(
20 | getStackTypes(stackSim, 0, 1),
21 | getStackTypes(stackSim, 0, 1, 0)
22 | );
23 | }
24 |
25 | @Override
26 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
27 | return new Op01WithProcessedDataAndByteJumps(instr, null, null, offset);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryGetField.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
6 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
7 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntryFieldRef;
9 | import org.benf.cfr.reader.entities.Method;
10 | import org.benf.cfr.reader.util.ConfusedCFRException;
11 |
12 | public class OperationFactoryGetField extends OperationFactoryCPEntryW {
13 |
14 | @Override
15 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
16 | StackSim stackSim, Method method) {
17 | ConstantPoolEntryFieldRef fieldRef = (ConstantPoolEntryFieldRef) cpEntries[0];
18 | if (fieldRef == null) throw new ConfusedCFRException("Expecting fieldRef");
19 | StackType stackType = fieldRef.getStackType();
20 | return new StackDeltaImpl(StackType.REF.asList(), stackType.asList());
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryGetStatic.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
6 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
7 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
9 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntryFieldRef;
10 | import org.benf.cfr.reader.entities.Method;
11 | import org.benf.cfr.reader.util.ConfusedCFRException;
12 |
13 | public class OperationFactoryGetStatic extends OperationFactoryCPEntryW {
14 |
15 | @Override
16 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
17 | StackSim stackSim, Method method) {
18 | ConstantPoolEntryFieldRef fieldRef = (ConstantPoolEntryFieldRef) cpEntries[0];
19 | if (fieldRef == null) throw new ConfusedCFRException("Expecting fieldRef");
20 | StackType stackType = fieldRef.getStackType();
21 | return new StackDeltaImpl(StackTypes.EMPTY, stackType.asList());
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryGoto.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 |
7 | public class OperationFactoryGoto extends OperationFactoryDefault {
8 |
9 | private static final long OFFSET_OF_TARGET = 1;
10 |
11 |
12 | @Override
13 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
14 | byte[] args = bd.getBytesAt(instr.getRawLength(), 1);
15 |
16 | short targetOffset = bd.getS2At(OFFSET_OF_TARGET);
17 |
18 | int[] targetOffsets = new int[1];
19 | targetOffsets[0] = targetOffset;
20 |
21 | return new Op01WithProcessedDataAndByteJumps(instr, args, targetOffsets, offset);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryGotoW.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 |
7 | public class OperationFactoryGotoW extends OperationFactoryDefault {
8 |
9 | private static final long OFFSET_OF_TARGET = 1;
10 |
11 | @Override
12 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
13 | byte[] args = bd.getBytesAt(instr.getRawLength(), 1);
14 |
15 | int targetOffset = bd.getS4At(OFFSET_OF_TARGET);
16 |
17 | int[] targetOffsets = new int[1];
18 | targetOffsets[0] = targetOffset;
19 |
20 | return new Op01WithProcessedDataAndByteJumps(instr, args, targetOffsets, offset);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryLDC2W.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | public class OperationFactoryLDC2W extends OperationFactoryLDCW {
4 | @Override
5 | protected int getRequiredComputationCategory() {
6 | return 2;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryLDCW.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
6 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
7 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
9 | import org.benf.cfr.reader.entities.Method;
10 | import org.benf.cfr.reader.util.ConfusedCFRException;
11 |
12 | public class OperationFactoryLDCW extends OperationFactoryCPEntryW {
13 |
14 | @Override
15 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
16 | StackSim stackSim, Method method) {
17 | StackType stackType = OperationFactoryLDC.getStackType(cpEntries[0]);
18 | int requiredComputationCategory = getRequiredComputationCategory();
19 | if (stackType.getComputationCategory() != requiredComputationCategory) {
20 | throw new ConfusedCFRException("Got a literal, but expected a different category");
21 | }
22 |
23 | return new StackDeltaImpl(StackTypes.EMPTY, stackType.asList());
24 | }
25 |
26 | protected int getRequiredComputationCategory() {
27 | return 1;
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryNew.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
6 | import org.benf.cfr.reader.util.bytestream.ByteData;
7 |
8 | public class OperationFactoryNew extends OperationFactoryDefault {
9 | private static final int LENGTH_OF_CLASS_INDEX = 2;
10 |
11 | @Override
12 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
13 | byte[] args = bd.getBytesAt(LENGTH_OF_CLASS_INDEX, 1);
14 | ConstantPoolEntry[] cpEntries = new ConstantPoolEntry[]{cp.getEntry(bd.getU2At(1))};
15 | return new Op01WithProcessedDataAndByteJumps(instr, args, null, offset, cpEntries);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryPutField.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
6 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
7 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
9 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntryFieldRef;
10 | import org.benf.cfr.reader.entities.Method;
11 | import org.benf.cfr.reader.util.ConfusedCFRException;
12 |
13 | public class OperationFactoryPutField extends OperationFactoryCPEntryW {
14 |
15 | @Override
16 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
17 | StackSim stackSim, Method method) {
18 | ConstantPoolEntryFieldRef fieldRef = (ConstantPoolEntryFieldRef) cpEntries[0];
19 | if (fieldRef == null) throw new ConfusedCFRException("Expecting fieldRef");
20 | StackType stackType = fieldRef.getStackType();
21 | return new StackDeltaImpl(new StackTypes(StackType.REF, stackType), StackTypes.EMPTY);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryPutStatic.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
6 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
7 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
9 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntryFieldRef;
10 | import org.benf.cfr.reader.entities.Method;
11 | import org.benf.cfr.reader.util.ConfusedCFRException;
12 |
13 | public class OperationFactoryPutStatic extends OperationFactoryCPEntryW {
14 |
15 | @Override
16 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
17 | StackSim stackSim, Method method) {
18 | ConstantPoolEntryFieldRef fieldRef = (ConstantPoolEntryFieldRef) cpEntries[0];
19 | if (fieldRef == null) throw new ConfusedCFRException("Expecting fieldRef");
20 | StackType stackType = fieldRef.getStackType();
21 | return new StackDeltaImpl(stackType.asList(), StackTypes.EMPTY);
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryReturn.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 |
7 | public class OperationFactoryReturn extends OperationFactoryDefault {
8 |
9 | @Override
10 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
11 | byte[] args = instr.getRawLength() == 0 ? null : bd.getBytesAt(instr.getRawLength(), 1);
12 | int[] targetOffsets = new int[0]; // There are no targets.
13 | return new Op01WithProcessedDataAndByteJumps(instr, args, targetOffsets, offset);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactorySwap.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDelta;
5 | import org.benf.cfr.reader.bytecode.analysis.stack.StackDeltaImpl;
6 | import org.benf.cfr.reader.bytecode.analysis.stack.StackSim;
7 | import org.benf.cfr.reader.bytecode.analysis.types.StackTypes;
8 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
9 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
10 | import org.benf.cfr.reader.entities.Method;
11 | import org.benf.cfr.reader.util.bytestream.ByteData;
12 |
13 | public class OperationFactorySwap extends OperationFactoryDefault {
14 |
15 | @Override
16 | public StackDelta getStackDelta(JVMInstr instr, byte[] data, ConstantPoolEntry[] cpEntries,
17 | StackSim stackSim, Method method) {
18 | StackTypes popped = getStackTypes(stackSim, 0, 1);
19 | StackTypes pushed = getStackTypes(stackSim, 1, 0);
20 | return new StackDeltaImpl(popped, pushed);
21 | }
22 |
23 | @Override
24 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
25 | return new Op01WithProcessedDataAndByteJumps(instr, null, null, offset);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/bytecode/opcode/OperationFactoryThrow.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.bytecode.opcode;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.opgraph.Op01WithProcessedDataAndByteJumps;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 |
7 | public class OperationFactoryThrow extends OperationFactoryDefault {
8 |
9 | @Override
10 | public Op01WithProcessedDataAndByteJumps createOperation(JVMInstr instr, ByteData bd, ConstantPool cp, int offset) {
11 | byte[] args = instr.getRawLength() == 0 ? null : bd.getBytesAt(instr.getRawLength(), 1);
12 | int[] targetOffsets = new int[0]; // There are no targets.
13 | return new Op01WithProcessedDataAndByteJumps(instr, args, targetOffsets, offset);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/AbstractConstantPoolEntry.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.entities.constantpool.ConstantPoolEntry;
5 |
6 | public abstract class AbstractConstantPoolEntry implements ConstantPoolEntry {
7 | private final ConstantPool cp;
8 |
9 | protected AbstractConstantPoolEntry(ConstantPool cp) {
10 | this.cp = cp;
11 | }
12 |
13 | protected ConstantPool getCp() {
14 | if (!cp.isLoaded()) {
15 | throw new IllegalStateException("Attempt to use constant pool before it's fully loaded.");
16 | }
17 | return cp;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/annotations/AnnotationTableTypeEntry.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.annotations;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.attributes.TypeAnnotationEntryKind;
5 | import org.benf.cfr.reader.entities.attributes.TypeAnnotationEntryValue;
6 | import org.benf.cfr.reader.entities.attributes.TypeAnnotationTargetInfo;
7 | import org.benf.cfr.reader.entities.attributes.TypePath;
8 |
9 | import java.util.Map;
10 |
11 | public class AnnotationTableTypeEntry extends AnnotationTableEntry {
12 | private final TypeAnnotationEntryValue value;
13 | private final T targetInfo;
14 | private final TypePath typePath;
15 |
16 | public AnnotationTableTypeEntry(TypeAnnotationEntryValue value, T targetInfo, TypePath typePath, JavaTypeInstance type, Map elementValueMap) {
17 | super(type, elementValueMap);
18 | this.value = value;
19 | this.targetInfo = targetInfo;
20 | this.typePath = typePath;
21 | }
22 |
23 | public TypePath getTypePath() {
24 | return typePath;
25 | }
26 |
27 | public TypeAnnotationEntryValue getValue() { return value; }
28 |
29 | public TypeAnnotationEntryKind getKind() {
30 | return value.getKind();
31 | }
32 |
33 | public T getTargetInfo() {
34 | return targetInfo;
35 | }
36 | }
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/annotations/ElementValue.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.annotations;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.util.TypeUsageCollectable;
5 | import org.benf.cfr.reader.util.output.Dumpable;
6 |
7 | public interface ElementValue extends Dumpable, TypeUsageCollectable {
8 | ElementValue withTypeHint(JavaTypeInstance hint);
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/annotations/ElementValueAnnotation.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.annotations;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.state.TypeUsageCollector;
5 | import org.benf.cfr.reader.util.output.Dumper;
6 |
7 | public class ElementValueAnnotation implements ElementValue {
8 | private final AnnotationTableEntry annotationTableEntry;
9 |
10 | public ElementValueAnnotation(AnnotationTableEntry annotationTableEntry) {
11 | this.annotationTableEntry = annotationTableEntry;
12 | }
13 |
14 | @Override
15 | public Dumper dump(Dumper d) {
16 | return annotationTableEntry.dump(d);
17 | }
18 |
19 | @Override
20 | public void collectTypeUsages(TypeUsageCollector collector) {
21 | annotationTableEntry.collectTypeUsages(collector);
22 | }
23 |
24 | @Override
25 | public ElementValue withTypeHint(JavaTypeInstance hint) {
26 | return this;
27 | }
28 |
29 | @Override
30 | public boolean equals(Object obj) {
31 | if (obj == this) {
32 | return true;
33 | }
34 | else if (obj instanceof ElementValueAnnotation) {
35 | ElementValueAnnotation other = (ElementValueAnnotation) obj;
36 | return annotationTableEntry.equals(other.annotationTableEntry);
37 | }
38 | else {
39 | return false;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/annotations/ElementValueClass.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.annotations;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.state.TypeUsageCollector;
5 | import org.benf.cfr.reader.util.output.Dumper;
6 |
7 | public class ElementValueClass implements ElementValue {
8 | private final JavaTypeInstance classType;
9 |
10 | public ElementValueClass(JavaTypeInstance classType) {
11 | this.classType = classType;
12 | }
13 |
14 | @Override
15 | public Dumper dump(Dumper d) {
16 | return d.dump(classType).print(".class");
17 | }
18 |
19 | @Override
20 | public void collectTypeUsages(TypeUsageCollector collector) {
21 | collector.collect(classType);
22 | }
23 |
24 | @Override
25 | public ElementValue withTypeHint(JavaTypeInstance hint) {
26 | return this;
27 | }
28 |
29 | @Override
30 | public boolean equals(Object obj) {
31 | if (obj == this) {
32 | return true;
33 | }
34 | else if (obj instanceof ElementValueClass) {
35 | ElementValueClass other = (ElementValueClass) obj;
36 | return classType.equals(other.classType);
37 | }
38 | else {
39 | return false;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/annotations/ElementValueEnum.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.annotations;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.state.TypeUsageCollector;
5 | import org.benf.cfr.reader.util.output.Dumper;
6 |
7 | public class ElementValueEnum implements ElementValue {
8 | private final JavaTypeInstance type;
9 | private final String valueName;
10 |
11 | public ElementValueEnum(JavaTypeInstance type, String valueName) {
12 | this.type = type;
13 | this.valueName = valueName;
14 | }
15 |
16 | @Override
17 | public Dumper dump(Dumper d) {
18 | return d.dump(type).print('.').print(valueName);
19 | }
20 |
21 | @Override
22 | public void collectTypeUsages(TypeUsageCollector collector) {
23 | collector.collect(type);
24 | }
25 |
26 | @Override
27 | public ElementValue withTypeHint(JavaTypeInstance hint) {
28 | return this;
29 | }
30 |
31 | @Override
32 | public boolean equals(Object obj) {
33 | if (obj == this) {
34 | return true;
35 | }
36 | else if (obj instanceof ElementValueEnum) {
37 | ElementValueEnum other = (ElementValueEnum) obj;
38 | return type.equals(other.type) && valueName.equals(other.valueName);
39 | }
40 | else {
41 | return false;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/Attribute.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.state.TypeUsageCollector;
4 | import org.benf.cfr.reader.util.KnowsRawName;
5 | import org.benf.cfr.reader.util.KnowsRawSize;
6 | import org.benf.cfr.reader.util.TypeUsageCollectable;
7 | import org.benf.cfr.reader.util.output.Dumpable;
8 | import org.benf.cfr.reader.util.output.Dumper;
9 |
10 | public abstract class Attribute implements KnowsRawSize, KnowsRawName, Dumpable, TypeUsageCollectable {
11 |
12 | @Override
13 | public abstract Dumper dump(Dumper d);
14 |
15 | @Override
16 | public void collectTypeUsages(TypeUsageCollector collector) {
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeDeprecated.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeDeprecated extends Attribute {
7 | public static final String ATTRIBUTE_NAME = "Deprecated";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeDeprecated(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d.print("Deprecated");
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return "Deprecated";
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeLocalVariableTypeTable.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeLocalVariableTypeTable extends Attribute {
7 | public final static String ATTRIBUTE_NAME = "LocalVariableTypeTable";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeLocalVariableTypeTable(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d;
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeModuleClassMain.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeModuleClassMain extends Attribute {
7 | public static final String ATTRIBUTE_NAME = "ModuleClassMain";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeModuleClassMain(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d.print(ATTRIBUTE_NAME);
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return ATTRIBUTE_NAME;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeModulePackages.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeModulePackages extends Attribute {
7 | public static final String ATTRIBUTE_NAME = "ModulePackages";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeModulePackages(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d.print(ATTRIBUTE_NAME);
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return ATTRIBUTE_NAME;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeRuntimeInvisibleAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 |
6 | public class AttributeRuntimeInvisibleAnnotations extends AttributeAnnotations {
7 | public static final String ATTRIBUTE_NAME = "RuntimeInvisibleAnnotations";
8 |
9 | public AttributeRuntimeInvisibleAnnotations(ByteData raw, ConstantPool cp) {
10 | super(raw, cp);
11 | }
12 |
13 | @Override
14 | public String getRawName() {
15 | return ATTRIBUTE_NAME;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeRuntimeInvisibleParameterAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 |
6 | public class AttributeRuntimeInvisibleParameterAnnotations extends AttributeParameterAnnotations {
7 | public static final String ATTRIBUTE_NAME = "RuntimeInvisibleParameterAnnotations";
8 |
9 | public AttributeRuntimeInvisibleParameterAnnotations(ByteData raw, ConstantPool cp) {
10 | super(raw, cp);
11 | }
12 |
13 | @Override
14 | public String getRawName() {
15 | return ATTRIBUTE_NAME;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeRuntimeInvisibleTypeAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 |
6 | public class AttributeRuntimeInvisibleTypeAnnotations extends AttributeTypeAnnotations {
7 | public static final String ATTRIBUTE_NAME = "RuntimeInvisibleTypeAnnotations";
8 |
9 | public AttributeRuntimeInvisibleTypeAnnotations(ByteData raw, ConstantPool cp) {
10 | super(raw, cp);
11 | }
12 |
13 | @Override
14 | public String getRawName() {
15 | return ATTRIBUTE_NAME;
16 | }
17 |
18 | @Override
19 | public String toString() {
20 | return ATTRIBUTE_NAME;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeRuntimeVisibleAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 |
6 | public class AttributeRuntimeVisibleAnnotations extends AttributeAnnotations {
7 | public static final String ATTRIBUTE_NAME = "RuntimeVisibleAnnotations";
8 |
9 | public AttributeRuntimeVisibleAnnotations(ByteData raw, ConstantPool cp) {
10 | super(raw, cp);
11 | }
12 |
13 | @Override
14 | public String getRawName() {
15 | return ATTRIBUTE_NAME;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeRuntimeVisibleParameterAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 |
6 | public class AttributeRuntimeVisibleParameterAnnotations extends AttributeParameterAnnotations {
7 | public static final String ATTRIBUTE_NAME = "RuntimeVisibleParameterAnnotations";
8 |
9 | public AttributeRuntimeVisibleParameterAnnotations(ByteData raw, ConstantPool cp) {
10 | super(raw, cp);
11 | }
12 |
13 | @Override
14 | public String getRawName() {
15 | return ATTRIBUTE_NAME;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeRuntimeVisibleTypeAnnotations.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.entities.constantpool.ConstantPool;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 |
6 | public class AttributeRuntimeVisibleTypeAnnotations extends AttributeTypeAnnotations {
7 | public static final String ATTRIBUTE_NAME = "RuntimeVisibleTypeAnnotations";
8 |
9 | public AttributeRuntimeVisibleTypeAnnotations(ByteData raw, ConstantPool cp) {
10 | super(raw, cp);
11 | }
12 |
13 | @Override
14 | public String getRawName() {
15 | return ATTRIBUTE_NAME;
16 | }
17 |
18 | @Override
19 | public String toString() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeScala.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeScala extends Attribute {
7 | public final static String ATTRIBUTE_NAME = "Scala";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeScala(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d;
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeScalaSig.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeScalaSig extends Attribute {
7 | public final static String ATTRIBUTE_NAME = "ScalaSig";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeScalaSig(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d;
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeSourceFile.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeSourceFile extends Attribute {
7 | public static final String ATTRIBUTE_NAME = "SourceFile";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeSourceFile(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d.print(ATTRIBUTE_NAME);
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return ATTRIBUTE_NAME;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeSynthetic.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeSynthetic extends Attribute {
7 | public final static String ATTRIBUTE_NAME = "Synthetic";
8 |
9 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
10 | private static final long OFFSET_OF_REMAINDER = 6;
11 |
12 | private final int length;
13 |
14 | public AttributeSynthetic(ByteData raw) {
15 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return ATTRIBUTE_NAME;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d;
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/AttributeUnknown.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.util.bytestream.ByteData;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | public class AttributeUnknown extends Attribute {
7 | private static final long OFFSET_OF_ATTRIBUTE_LENGTH = 2;
8 | private static final long OFFSET_OF_REMAINDER = 6;
9 |
10 | private final int length;
11 | private final String name;
12 |
13 | public AttributeUnknown(ByteData raw, String name) {
14 | this.length = raw.getS4At(OFFSET_OF_ATTRIBUTE_LENGTH);
15 | this.name = name;
16 | }
17 |
18 | @Override
19 | public String getRawName() {
20 | return name;
21 | }
22 |
23 | @Override
24 | public Dumper dump(Dumper d) {
25 | return d.print("Unknown Attribute : " + name);
26 | }
27 |
28 | @Override
29 | public long getRawByteLength() {
30 | return OFFSET_OF_REMAINDER + length;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return "Unknown Attribute : " + name;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/BadAttributeException.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | public class BadAttributeException extends RuntimeException {
4 | }
5 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/LocalVariableEntry.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | public class LocalVariableEntry {
4 | private final int startPc;
5 | private final int length;
6 | private final int nameIndex;
7 | private final int descriptorIndex;
8 | private final int index;
9 |
10 | public LocalVariableEntry(int startPc, int length, int nameIndex, int descriptorIndex, int index) {
11 | this.startPc = startPc;
12 | this.length = length;
13 | this.nameIndex = nameIndex;
14 | this.descriptorIndex = descriptorIndex;
15 | this.index = index;
16 | }
17 |
18 | public int getStartPc() {
19 | return startPc;
20 | }
21 |
22 | public int getEndPc() {
23 | return startPc + length;
24 | }
25 |
26 | public int getLength() {
27 | return length;
28 | }
29 |
30 | public int getNameIndex() {
31 | return nameIndex;
32 | }
33 |
34 | public int getDescriptorIndex() {
35 | return descriptorIndex;
36 | }
37 |
38 | public int getIndex() {
39 | return index;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypeAnnotationEntryKind.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | public enum TypeAnnotationEntryKind {
4 | type_parameter_target,
5 | supertype_target,
6 | type_parameter_bound_target,
7 | empty_target,
8 | method_formal_parameter_target,
9 | throws_target,
10 | localvar_target,
11 | catch_target,
12 | offset_target,
13 | type_argument_target
14 | }
15 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypeAnnotationLocation.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | public enum TypeAnnotationLocation {
4 | ClassFile,
5 | method_info,
6 | field_info,
7 | Code
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePath.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import java.util.List;
4 |
5 | public class TypePath {
6 | /*
7 | If the value of the type_path_kind item is 0, 1, or 2, then the value of the type_argument_index item is 0.
8 |
9 | If the value of the type_path_kind item is 3, then the value of the type_argument_index item specifies which
10 | type argument of a parameterized type is annotated, where 0 indicates the first type argument of a parameterized type.
11 | */
12 | public final List segments;
13 |
14 | public TypePath(List segments) {
15 | this.segments = segments;
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePathAccessor.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | public interface TypePathAccessor {
4 | }
5 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePathPart.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaAnnotatedTypeIterator;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public interface TypePathPart {
7 | JavaAnnotatedTypeIterator apply(JavaAnnotatedTypeIterator it, DecompilerComments comments);
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePathPartArray.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaAnnotatedTypeIterator;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public class TypePathPartArray implements TypePathPart {
7 | public static final TypePathPartArray INSTANCE = new TypePathPartArray();
8 |
9 | private TypePathPartArray() {
10 | }
11 |
12 | @Override
13 | public JavaAnnotatedTypeIterator apply(JavaAnnotatedTypeIterator it, DecompilerComments comments) {
14 | return it.moveArray(comments);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePathPartBound.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaAnnotatedTypeIterator;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public class TypePathPartBound implements TypePathPart {
7 | public static final TypePathPartBound INSTANCE = new TypePathPartBound();
8 |
9 | private TypePathPartBound() {
10 | }
11 |
12 | @Override
13 | public JavaAnnotatedTypeIterator apply(JavaAnnotatedTypeIterator it, DecompilerComments comments) {
14 | return it.moveBound(comments);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePathPartNested.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaAnnotatedTypeIterator;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public class TypePathPartNested implements TypePathPart {
7 | public static final TypePathPartNested INSTANCE = new TypePathPartNested();
8 |
9 | private TypePathPartNested() {
10 | }
11 |
12 | @Override
13 | public JavaAnnotatedTypeIterator apply(JavaAnnotatedTypeIterator it, DecompilerComments comments) {
14 | return it.moveNested(comments);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/attributes/TypePathPartParameterized.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.attributes;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaAnnotatedTypeIterator;
4 | import org.benf.cfr.reader.util.DecompilerComments;
5 |
6 | public class TypePathPartParameterized implements TypePathPart {
7 | private final int index;
8 |
9 | public TypePathPartParameterized(int index) {
10 | this.index = index;
11 | }
12 |
13 | @Override
14 | public JavaAnnotatedTypeIterator apply(JavaAnnotatedTypeIterator it, DecompilerComments comments) {
15 | return it.moveParameterized(index, comments);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/bootstrap/MethodHandleBehaviour.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.bootstrap;
2 |
3 | public enum MethodHandleBehaviour {
4 | GET_FIELD,
5 | GET_STATIC,
6 | PUT_FIELD,
7 | PUT_STATIC,
8 | INVOKE_VIRTUAL,
9 | INVOKE_STATIC,
10 | INVOKE_SPECIAL,
11 | NEW_INVOKE_SPECIAL,
12 | INVOKE_INTERFACE;
13 |
14 | public static MethodHandleBehaviour decode(byte value) {
15 | switch (value) {
16 | case 1:
17 | return GET_FIELD;
18 | case 2:
19 | return GET_STATIC;
20 | case 3:
21 | return PUT_FIELD;
22 | case 4:
23 | return PUT_STATIC;
24 | case 5:
25 | return INVOKE_VIRTUAL;
26 | case 6:
27 | return INVOKE_STATIC;
28 | case 7:
29 | return INVOKE_SPECIAL;
30 | case 8:
31 | return NEW_INVOKE_SPECIAL;
32 | case 9:
33 | return INVOKE_INTERFACE;
34 | default:
35 | throw new IllegalArgumentException("Unknown method handle behaviour " + value);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/classfilehelpers/ClassFileDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.classfilehelpers;
2 |
3 | import org.benf.cfr.reader.entities.ClassFile;
4 | import org.benf.cfr.reader.state.TypeUsageCollector;
5 | import org.benf.cfr.reader.util.TypeUsageCollectable;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public interface ClassFileDumper extends TypeUsageCollectable {
9 | enum InnerClassDumpType {
10 | NOT(false),
11 | INNER_CLASS(true),
12 | INLINE_CLASS(true);
13 |
14 | final boolean isInnerClass;
15 |
16 | InnerClassDumpType(boolean isInnerClass) {
17 | this.isInnerClass = isInnerClass;
18 | }
19 |
20 | public boolean isInnerClass() {
21 | return isInnerClass;
22 | }
23 | }
24 |
25 | Dumper dump(ClassFile classFile, InnerClassDumpType innerClass, Dumper d);
26 |
27 | /*
28 | * Some dumpers may need to request additional types -
29 | */
30 | void collectTypeUsages(TypeUsageCollector collector);
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryDouble.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
4 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public class ConstantPoolEntryDouble extends AbstractConstantPoolEntry implements ConstantPoolEntryLiteral {
9 | private final double value;
10 |
11 | public ConstantPoolEntryDouble(ConstantPool cp, ByteData data) {
12 | super(cp);
13 | this.value = data.getDoubleAt(1);
14 | }
15 |
16 | @Override
17 | public long getRawByteLength() {
18 | return 9;
19 | }
20 |
21 | @Override
22 | public void dump(Dumper d) {
23 | d.print("CONSTANT_Double " + value);
24 | }
25 |
26 | public double getValue() {
27 | return value;
28 | }
29 |
30 | @Override
31 | public StackType getStackType() {
32 | return StackType.DOUBLE;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryFloat.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
4 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public class ConstantPoolEntryFloat extends AbstractConstantPoolEntry implements ConstantPoolEntryLiteral {
9 | private final float value;
10 |
11 | public ConstantPoolEntryFloat(ConstantPool cp, ByteData data) {
12 | super(cp);
13 | this.value = data.getFloatAt(1);
14 | }
15 |
16 | @Override
17 | public long getRawByteLength() {
18 | return 5;
19 | }
20 |
21 | @Override
22 | public void dump(Dumper d) {
23 | d.print("CONSTANT_Float");
24 | }
25 |
26 | @Override
27 | public StackType getStackType() {
28 | return StackType.FLOAT;
29 | }
30 |
31 | public float getValue() {
32 | return value;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryInteger.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
4 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public class ConstantPoolEntryInteger extends AbstractConstantPoolEntry implements ConstantPoolEntryLiteral {
9 | private static final long OFFSET_OF_BYTES = 1;
10 |
11 | private final int value;
12 |
13 | public ConstantPoolEntryInteger(ConstantPool cp, ByteData data) {
14 | super(cp);
15 | this.value = data.getS4At(OFFSET_OF_BYTES);
16 | }
17 |
18 | @Override
19 | public long getRawByteLength() {
20 | return 5;
21 | }
22 |
23 | @Override
24 | public void dump(Dumper d) {
25 | d.print("CONSTANT_Integer value=" + value);
26 | }
27 |
28 | public int getValue() {
29 | return value;
30 | }
31 |
32 | @Override
33 | public StackType getStackType() {
34 | return StackType.INT;
35 | }
36 |
37 | @Override
38 | public String toString() {
39 | return ("CONSTANT_Integer value=" + value);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryLiteral.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
4 |
5 | public interface ConstantPoolEntryLiteral {
6 | StackType getStackType();
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryLong.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
4 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public class ConstantPoolEntryLong extends AbstractConstantPoolEntry implements ConstantPoolEntryLiteral {
9 | private final long value;
10 |
11 | public ConstantPoolEntryLong(ConstantPool cp, ByteData data) {
12 | super(cp);
13 | this.value = data.getLongAt(1);
14 | }
15 |
16 | @Override
17 | public long getRawByteLength() {
18 | return 9;
19 | }
20 |
21 | @Override
22 | public void dump(Dumper d) {
23 | d.print("CONSTANT_Long " + value);
24 | }
25 |
26 | @Override
27 | public String toString() {
28 | return "CONSTANT_Long[" + value + "]";
29 | }
30 |
31 | public long getValue() {
32 | return value;
33 | }
34 |
35 | @Override
36 | public StackType getStackType() {
37 | return StackType.LONG;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryMethodType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public class ConstantPoolEntryMethodType extends AbstractConstantPoolEntry {
9 | private static final long OFFSET_OF_DESCRIPTOR_INDEX = 1;
10 |
11 | private final int descriptorIndex;
12 |
13 | public ConstantPoolEntryMethodType(ConstantPool cp, ByteData data) {
14 | super(cp);
15 | this.descriptorIndex = data.getU2At(OFFSET_OF_DESCRIPTOR_INDEX);
16 | }
17 |
18 | public ConstantPool getCp() {
19 | return super.getCp();
20 | }
21 |
22 | @Override
23 | public long getRawByteLength() {
24 | return 3;
25 | }
26 |
27 | @Override
28 | public void dump(Dumper d) {
29 | d.print(this.toString());
30 | }
31 |
32 | public ConstantPoolEntryUTF8 getDescriptor() {
33 | return getCp().getUTF8Entry(descriptorIndex);
34 | }
35 |
36 | @Override
37 | public String toString() {
38 | return "MethodType value=" + descriptorIndex;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryModuleInfo.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
4 | import org.benf.cfr.reader.util.bytestream.ByteData;
5 | import org.benf.cfr.reader.util.output.Dumper;
6 |
7 | public class ConstantPoolEntryModuleInfo extends AbstractConstantPoolEntry {
8 | private static final long OFFSET_OF_NAME_INDEX = 1;
9 |
10 | private final int nameIndex;
11 |
12 | ConstantPoolEntryModuleInfo(ConstantPool cp, ByteData data) {
13 | super(cp);
14 | this.nameIndex = data.getU2At(OFFSET_OF_NAME_INDEX);
15 | }
16 |
17 | public ConstantPool getCp() {
18 | return super.getCp();
19 | }
20 |
21 | @Override
22 | public long getRawByteLength() {
23 | return 3;
24 | }
25 |
26 | @Override
27 | public void dump(Dumper d) {
28 | d.print(this.toString());
29 | }
30 |
31 | public ConstantPoolEntryUTF8 getName() {
32 | return getCp().getUTF8Entry(nameIndex);
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "NameIndex value=" + nameIndex;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryPackageInfo.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.ClassNameUtils;
4 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.output.Dumper;
7 |
8 | public class ConstantPoolEntryPackageInfo extends AbstractConstantPoolEntry {
9 | private static final long OFFSET_OF_NAME_INDEX = 1;
10 |
11 | private final int nameIndex;
12 |
13 | ConstantPoolEntryPackageInfo(ConstantPool cp, ByteData data) {
14 | super(cp);
15 | this.nameIndex = data.getU2At(OFFSET_OF_NAME_INDEX);
16 | }
17 |
18 | public ConstantPool getCp() {
19 | return super.getCp();
20 | }
21 |
22 | @Override
23 | public long getRawByteLength() {
24 | return 3;
25 | }
26 |
27 | @Override
28 | public void dump(Dumper d) {
29 | d.print(this.toString());
30 | }
31 |
32 | public String getPackageName() {
33 | return ClassNameUtils.convertFromPath(getCp().getUTF8Entry(nameIndex).getValue());
34 | }
35 |
36 | public ConstantPoolEntryUTF8 getName() {
37 | return getCp().getUTF8Entry(nameIndex);
38 | }
39 |
40 | @Override
41 | public String toString() {
42 | return "NameIndex value=" + nameIndex;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/constantpool/ConstantPoolEntryString.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.constantpool;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.utils.QuotingUtils;
4 | import org.benf.cfr.reader.bytecode.analysis.types.StackType;
5 | import org.benf.cfr.reader.entities.AbstractConstantPoolEntry;
6 | import org.benf.cfr.reader.util.bytestream.ByteData;
7 | import org.benf.cfr.reader.util.output.Dumper;
8 |
9 | public class ConstantPoolEntryString extends AbstractConstantPoolEntry implements ConstantPoolEntryLiteral {
10 | private static final long OFFSET_OF_STRING_INDEX = 1;
11 |
12 | private final long stringIndex;
13 | private transient String string;
14 |
15 | public ConstantPoolEntryString(ConstantPool cp, ByteData data) {
16 | super(cp);
17 | this.stringIndex = data.getU2At(OFFSET_OF_STRING_INDEX);
18 | }
19 |
20 | @Override
21 | public long getRawByteLength() {
22 | return 3;
23 | }
24 |
25 | @Override
26 | public void dump(Dumper d) {
27 | d.print("String " + getValue());
28 | }
29 |
30 | public String getValue() {
31 | if (string == null) {
32 | string = QuotingUtils.enquoteString(getCp().getUTF8Entry((int) stringIndex).getValue());
33 | }
34 | return string;
35 | }
36 |
37 | @Override
38 | public StackType getStackType() {
39 | return StackType.REF;
40 | }
41 | }
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/exceptions/ExceptionCheck.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.exceptions;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.AbstractMemberFunctionInvokation;
5 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
6 |
7 | import java.util.Set;
8 |
9 | public interface ExceptionCheck {
10 | boolean checkAgainst(Set extends JavaTypeInstance> thrown);
11 |
12 | // Might this throw in a way which means it can't be moved into the exception block?
13 | boolean checkAgainst(AbstractMemberFunctionInvokation functionInvokation);
14 |
15 | boolean checkAgainstException(Expression expression);
16 |
17 | boolean mightCatchUnchecked();
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/exceptions/ExceptionCheckSimple.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.exceptions;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.Expression;
4 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.AbstractMemberFunctionInvokation;
5 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
6 |
7 | import java.util.Set;
8 |
9 | public class ExceptionCheckSimple implements ExceptionCheck {
10 | public static final ExceptionCheck INSTANCE = new ExceptionCheckSimple();
11 |
12 | private ExceptionCheckSimple() {
13 | }
14 |
15 | @Override
16 | public boolean checkAgainst(Set extends JavaTypeInstance> thrown) {
17 | return true;
18 | }
19 |
20 | @Override
21 | public boolean checkAgainst(AbstractMemberFunctionInvokation functionInvokation) {
22 | return true;
23 | }
24 |
25 | @Override
26 | public boolean checkAgainstException(Expression expression) {
27 | return true;
28 | }
29 |
30 | @Override
31 | public boolean mightCatchUnchecked() {
32 | return true;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entities/innerclass/InnerClassAttributeInfo.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entities.innerclass;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.AccessFlag;
5 | import org.benf.cfr.reader.util.annotation.Nullable;
6 |
7 | import java.util.Set;
8 |
9 | public class InnerClassAttributeInfo {
10 | private final
11 | @Nullable
12 | JavaTypeInstance innerClassInfo;
13 | private final
14 | @Nullable
15 | JavaTypeInstance outerClassInfo;
16 | private final
17 | @Nullable
18 | String innerName;
19 | private final Set accessFlags;
20 |
21 | public InnerClassAttributeInfo(JavaTypeInstance innerClassInfo, JavaTypeInstance outerClassInfo, String innerName, Set accessFlags) {
22 | this.innerClassInfo = innerClassInfo;
23 | this.outerClassInfo = outerClassInfo;
24 | this.innerName = innerName;
25 | this.accessFlags = accessFlags;
26 | }
27 |
28 | public JavaTypeInstance getInnerClassInfo() {
29 | return innerClassInfo;
30 | }
31 |
32 | private JavaTypeInstance getOuterClassInfo() {
33 | return outerClassInfo;
34 | }
35 |
36 | private String getInnerName() {
37 | return innerName;
38 | }
39 |
40 | public Set getAccessFlags() {
41 | return accessFlags;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/entityfactories/ContiguousEntityFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.entityfactories;
2 |
3 | import org.benf.cfr.reader.util.KnowsRawSize;
4 | import org.benf.cfr.reader.util.functors.UnaryFunction;
5 | import org.benf.cfr.reader.util.bytestream.ByteData;
6 | import org.benf.cfr.reader.util.bytestream.OffsettingByteData;
7 |
8 | import java.util.List;
9 |
10 | public class ContiguousEntityFactory {
11 |
12 | public static long build(final ByteData raw, int count, List tgt, UnaryFunction func)
13 | {
14 | OffsettingByteData data = raw.getOffsettingOffsetData(0);
15 | for (int x=0;x long buildSized(final ByteData raw, int count, int itemLength, List tgt, UnaryFunction func)
25 | {
26 | OffsettingByteData data = raw.getOffsettingOffsetData(0);
27 | for (short x=0;x argTypes;
12 |
13 | public MethodMapping(String rename, String name, JavaTypeInstance res, List argTypes) {
14 | this.name = name;
15 | this.rename = rename;
16 | this.res = res;
17 | this.argTypes = argTypes;
18 | }
19 |
20 | public String getName() {
21 | return name;
22 | }
23 |
24 | public String getRename() {
25 | return rename;
26 | }
27 |
28 | public JavaTypeInstance getResultType() {
29 | return res;
30 | }
31 |
32 | public List getArgTypes() {
33 | return argTypes;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/mapping/ObfuscationMapping.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.mapping;
2 |
3 | import org.benf.cfr.reader.state.ObfuscationRewriter;
4 | import org.benf.cfr.reader.state.ObfuscationTypeMap;
5 |
6 | public interface ObfuscationMapping extends ObfuscationRewriter, ObfuscationTypeMap {
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Created with IntelliJ IDEA.
3 | * User: lee
4 | * Date: 14/12/16
5 | * Time: 07:33
6 | */
7 | package org.benf.cfr.reader;
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/AbstractTypeUsageCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.util.TypeUsageCollectable;
5 |
6 | import java.util.Collection;
7 |
8 | public abstract class AbstractTypeUsageCollector implements TypeUsageCollector {
9 | @Override
10 | public void collect(Collection extends JavaTypeInstance> types) {
11 | if (types == null) return;
12 | for (JavaTypeInstance type : types) collect(type);
13 | }
14 |
15 | @Override
16 | public void collectFrom(TypeUsageCollectable collectable) {
17 | if (collectable != null) collectable.collectTypeUsages(this);
18 | }
19 |
20 | @Override
21 | public void collectFromT(TypeUsageCollectable collectable) {
22 | collectFrom(collectable);
23 | }
24 |
25 | @Override
26 | public void collectFrom(Collection extends TypeUsageCollectable> collectables) {
27 | if (collectables != null) {
28 | for (TypeUsageCollectable collectable : collectables) {
29 | if (collectable != null) collectable.collectTypeUsages(this);
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/ClassNameFunction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import java.util.Map;
4 |
5 | public interface ClassNameFunction {
6 | Map apply(Map names);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/DetectedStaticImport.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 |
5 | public class DetectedStaticImport {
6 | final JavaTypeInstance clazz;
7 | final String name;
8 |
9 | public JavaTypeInstance getClazz() {
10 | return clazz;
11 | }
12 |
13 | public String getName() {
14 | return name;
15 | }
16 |
17 | DetectedStaticImport(JavaTypeInstance clazz, String name) {
18 | this.clazz = clazz;
19 | this.name = name;
20 | }
21 |
22 | @Override
23 | public boolean equals(Object o) {
24 | if (this == o) return true;
25 | if (o == null || getClass() != o.getClass()) return false;
26 |
27 | DetectedStaticImport that = (DetectedStaticImport) o;
28 |
29 | if (!clazz.equals(that.clazz)) return false;
30 | if (!name.equals(that.name)) return false;
31 |
32 | return true;
33 | }
34 |
35 | @Override
36 | public int hashCode() {
37 | int result = clazz.hashCode();
38 | result = 31 * result + name.hashCode();
39 | return result;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/JarContentImpl.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.apiunreleased.JarContent;
4 | import org.benf.cfr.reader.util.AnalysisType;
5 |
6 | import java.util.Collection;
7 | import java.util.Map;
8 |
9 | public class JarContentImpl implements JarContent {
10 | private final Collection classFiles;
11 | private final Map manifestEntries;
12 | private final AnalysisType analysisType;
13 |
14 | JarContentImpl(Collection classFiles, Map manifestEntries, AnalysisType analysisType) {
15 | this.classFiles = classFiles;
16 | this.manifestEntries = manifestEntries;
17 | this.analysisType = analysisType;
18 | }
19 |
20 | @Override
21 | public Collection getClassFiles() {
22 | return classFiles;
23 | }
24 |
25 | @Override
26 | public Map getManifestEntries() {
27 | return manifestEntries;
28 | }
29 |
30 | @Override
31 | public AnalysisType getAnalysisType() {
32 | return analysisType;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/ObfuscationRewriter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.util.output.Dumper;
5 |
6 | import java.util.List;
7 |
8 | public interface ObfuscationRewriter {
9 | Dumper wrap(Dumper d);
10 |
11 | JavaTypeInstance get(JavaTypeInstance t);
12 |
13 | List get(List types);
14 | }
15 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/ObfuscationTypeMap.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.innerclass.InnerClassAttributeInfo;
5 | import org.benf.cfr.reader.util.functors.UnaryFunction;
6 |
7 | import java.util.List;
8 |
9 | public interface ObfuscationTypeMap {
10 | boolean providesInnerClassInfo();
11 |
12 | JavaTypeInstance get(JavaTypeInstance type);
13 |
14 | UnaryFunction getter();
15 |
16 | List getInnerClassInfo(JavaTypeInstance classType);
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/OverloadMethodSetCache.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.MethodPrototype;
4 | import org.benf.cfr.reader.entities.ClassFile;
5 | import org.benf.cfr.reader.entities.classfilehelpers.OverloadMethodSet;
6 | import org.benf.cfr.reader.util.collections.MapFactory;
7 | import org.benf.cfr.reader.util.functors.UnaryFunction;
8 |
9 | import java.util.Map;
10 |
11 | // The cost of retaining all overload information may become large. Keeping it centrally allows us to flush it if in low
12 | // memory mode.
13 | public class OverloadMethodSetCache {
14 | private final Map> content = MapFactory.newLazyMap(new UnaryFunction>() {
15 | @Override
16 | public Map invoke(ClassFile arg) {
17 | return MapFactory.newIdentityMap();
18 | }
19 | });
20 |
21 | public OverloadMethodSet get(ClassFile classFile, MethodPrototype methodPrototype) {
22 | return content.get(classFile).get(methodPrototype);
23 | }
24 |
25 | public void set(ClassFile classFile, MethodPrototype methodPrototype, OverloadMethodSet overloadMethodSet) {
26 | content.get(classFile).put(methodPrototype, overloadMethodSet);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/TypeUsageCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaRefTypeInstance;
4 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
5 | import org.benf.cfr.reader.util.TypeUsageCollectable;
6 |
7 | import java.util.Collection;
8 |
9 | public interface TypeUsageCollector {
10 | void collectRefType(JavaRefTypeInstance type);
11 |
12 | void collect(JavaTypeInstance type);
13 |
14 | void collect(Collection extends JavaTypeInstance> types);
15 |
16 | // Explicitly named helper to allow J8's less lenient bridging.
17 | void collectFromT(TypeUsageCollectable collectable);
18 |
19 | void collectFrom(TypeUsageCollectable collectable);
20 |
21 | void collectFrom(Collection extends TypeUsageCollectable> collectables);
22 |
23 | TypeUsageInformation getTypeUsageInformation();
24 |
25 | boolean isStatementRecursive();
26 | }
27 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/state/TypeUsageInformation.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.state;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaRefTypeInstance;
4 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
5 | import org.benf.cfr.reader.util.output.IllegalIdentifierDump;
6 | import org.benf.cfr.reader.util.output.TypeContext;
7 |
8 | import java.util.Set;
9 |
10 | public interface TypeUsageInformation {
11 | JavaRefTypeInstance getAnalysisType();
12 |
13 | Set getShortenedClassTypes();
14 |
15 | Set getUsedClassTypes();
16 |
17 | Set getUsedInnerClassTypes();
18 |
19 | boolean hasLocalInstance(JavaRefTypeInstance type);
20 |
21 | String getName(JavaTypeInstance type, TypeContext typeContext);
22 |
23 | boolean isNameClash(JavaTypeInstance type, String name, TypeContext typeContext);
24 |
25 | String generateInnerClassShortName(JavaRefTypeInstance clazz);
26 |
27 | String generateOverriddenName(JavaRefTypeInstance clazz);
28 |
29 | IllegalIdentifierDump getIid();
30 |
31 | boolean isStaticImport(JavaTypeInstance clazz, String fixedName);
32 |
33 | Set getDetectedStaticImports();
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/AnalysisType.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public enum AnalysisType {
4 | DETECT,
5 | JAR,
6 | WAR,
7 | CLASS
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/BoolPair.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | /**
4 | * very simple enum to help switching on an XOR style decision.
5 | */
6 | public enum BoolPair {
7 | NEITHER(0),
8 | FIRST(1),
9 | SECOND(1),
10 | BOTH(2);
11 |
12 | private final int count;
13 |
14 | BoolPair(int count) {
15 | this.count = count;
16 | }
17 |
18 | public static BoolPair get(boolean a, boolean b) {
19 | if (a) {
20 | if (b) return BOTH;
21 | return FIRST;
22 | }
23 | if (b) return SECOND;
24 | return NEITHER;
25 | }
26 |
27 | public int getCount() {
28 | return count;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/CannotLoadClassException.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public class CannotLoadClassException extends RuntimeException {
4 | public CannotLoadClassException(String s, Throwable throwable) {
5 | super(s, throwable);
6 | }
7 |
8 | @Override
9 | public String toString() {
10 | return super.toString() + ((super.getCause() == null) ? "" : (" - " + super.getCause().toString()));
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/CannotPerformDecode.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public class CannotPerformDecode extends ConfusedCFRException {
4 | public CannotPerformDecode(String s) {
5 | super(s);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/ConfusedCFRException.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public class ConfusedCFRException extends RuntimeException {
4 | public ConfusedCFRException(String s)
5 | {
6 | super(s);
7 | }
8 | public ConfusedCFRException(Exception e)
9 | {
10 | super(e);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/DecompilerCommentSource.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | import java.util.List;
4 |
5 | public interface DecompilerCommentSource {
6 | List getComments();
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/KnowsRawName.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public interface KnowsRawName {
4 | String getRawName();
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/KnowsRawSize.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public interface KnowsRawSize {
4 | long getRawByteLength();
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/MalformedPrototypeException.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public class MalformedPrototypeException extends RuntimeException{
4 | public MalformedPrototypeException(String message, Throwable cause) {
5 | super(message, cause);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/MiscConstants.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | import java.util.regex.Pattern;
4 |
5 | public interface MiscConstants {
6 | String CFR_HEADER_BRA = "Decompiled with CFR";
7 |
8 | String INIT_METHOD = "";
9 | String STATIC_INIT_METHOD = "";
10 | String DOT_THIS = ".this";
11 | String THIS = "this";
12 | String CLASS = "class";
13 | String NEW = "new";
14 | String EQUALS = "equals";
15 | String HASHCODE = "hashCode";
16 | String TOSTRING = "toString";
17 | String PACKAGE_INFO = "package-info";
18 |
19 | String UNBOUND_GENERIC = "?";
20 | char INNER_CLASS_SEP_CHAR = '$';
21 | String INNER_CLASS_SEP_STR = "$";
22 |
23 | String DESERIALISE_LAMBDA_METHOD = "$deserializeLambda$";
24 | String SCALA_SERIAL_VERSION = "serialVersionUID";
25 | String GET_CLASS_NAME = "getClass";
26 | String REQUIRE_NON_NULL = "requireNonNull";
27 |
28 | String MANIFEST_PATH = "META-INF/MANIFEST.MF";
29 | String MULTI_RELEASE_KEY = "Multi-Release";
30 | String MANIFEST_CLASS_PATH = "Class-Path";
31 | String MULTI_RELEASE_PREFIX = "META-INF/versions/";
32 | String WAR_PREFIX = "WEB-INF/classes/";
33 | Pattern MULTI_RELEASE_PATH_PATTERN = Pattern.compile("^" + MULTI_RELEASE_PREFIX + "(\\d+)/(.*)$");
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/Optional.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | import org.benf.cfr.reader.util.functors.UnaryProcedure;
4 |
5 | public class Optional {
6 | private final T value;
7 | private final boolean set;
8 | private static final Optional Empty = new Optional();
9 |
10 | private Optional(T val) {
11 | value = val;
12 | set = true;
13 | }
14 |
15 | private Optional() {
16 | set = false;
17 | value = null;
18 | }
19 |
20 | public boolean isSet() {
21 | return set;
22 | }
23 |
24 | public T getValue() {
25 | return value;
26 | }
27 |
28 | public void then(UnaryProcedure func) {
29 | func.call(value);
30 | }
31 |
32 | public static Optional of(T value) {
33 | return new Optional(value);
34 | }
35 |
36 | public static Optional empty() {
37 | //noinspection unchecked
38 | return (Optional)Optional.Empty;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/Troolean.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | /**
4 | * very simple enum to help switching on an XOR style decision.
5 | */
6 | public enum Troolean {
7 | NEITHER,
8 | TRUE,
9 | FALSE;
10 |
11 | public static Troolean get(Boolean a) {
12 | if (a == null) return NEITHER;
13 | return a ? TRUE : FALSE;
14 | }
15 |
16 | public boolean boolValue(boolean ifNeither) {
17 | switch (this) {
18 | case TRUE:
19 | return true;
20 | case FALSE:
21 | return false;
22 | default:
23 | return ifNeither;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/TypeUsageCollectable.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | import org.benf.cfr.reader.state.TypeUsageCollector;
4 |
5 | public interface TypeUsageCollectable {
6 | void collectTypeUsages(TypeUsageCollector collector);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/UnverifiableJumpException.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util;
2 |
3 | public class UnverifiableJumpException extends RuntimeException {
4 |
5 | public UnverifiableJumpException()
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/annotation/Nullable.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.annotation;
2 |
3 | public @interface Nullable {
4 | }
5 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/bytestream/BaseByteData.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.bytestream;
2 |
3 | public class BaseByteData extends AbstractBackedByteData {
4 | public BaseByteData(byte[] data) {
5 | super(data);
6 | }
7 |
8 | @Override
9 | public ByteData getOffsetData(long offset) {
10 | return new OffsetBackedByteData(d, offset);
11 | }
12 |
13 | @Override
14 | public OffsettingByteData getOffsettingOffsetData(long offset) {
15 | return new OffsettingBackedByteData(d, offset);
16 | }
17 |
18 | @Override
19 | int getRealOffset(int offset) {
20 | return offset;
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/bytestream/ByteData.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.bytestream;
2 |
3 | public interface ByteData {
4 | byte getS1At(long offset);
5 |
6 | short getU1At(long offset);
7 |
8 | short getS2At(long offset);
9 |
10 | int getU2At(long offset);
11 |
12 | int getS4At(long offset);
13 |
14 | double getDoubleAt(long o);
15 |
16 | float getFloatAt(long o);
17 |
18 | long getLongAt(long o);
19 |
20 | byte[] getBytesAt(int count, long offset);
21 |
22 | ByteData getOffsetData(long offset);
23 |
24 | OffsettingByteData getOffsettingOffsetData(long offset);
25 | }
26 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/bytestream/OffsetBackedByteData.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.bytestream;
2 |
3 | public class OffsetBackedByteData extends AbstractBackedByteData {
4 | private final int offset;
5 |
6 | OffsetBackedByteData(byte[] data, long offset) {
7 | super(data);
8 | this.offset = (int) offset;
9 | }
10 |
11 | @Override
12 | public ByteData getOffsetData(long offset) {
13 | return new OffsetBackedByteData(d, this.offset + offset);
14 | }
15 |
16 | @Override
17 | public OffsettingByteData getOffsettingOffsetData(long offset) {
18 | return new OffsettingBackedByteData(d, this.offset + offset);
19 | }
20 |
21 | @Override
22 | int getRealOffset(int o) {
23 | return o + offset;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/bytestream/OffsettingBackedByteData.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.bytestream;
2 |
3 | public class OffsettingBackedByteData extends AbstractBackedByteData implements OffsettingByteData {
4 | private final int originalOffset;
5 | private int mutableOffset;
6 |
7 | OffsettingBackedByteData(byte[] data, long offset) {
8 | super(data);
9 | this.originalOffset = (int) offset;
10 | this.mutableOffset = 0;
11 | }
12 |
13 | @Override
14 | public void advance(long offset) {
15 | mutableOffset += offset;
16 | }
17 |
18 | @Override
19 | public long getOffset() {
20 | return mutableOffset;
21 | }
22 |
23 | @Override
24 | public ByteData getOffsetData(long offset) {
25 | return new OffsetBackedByteData(d, originalOffset + mutableOffset + offset);
26 | }
27 |
28 | @Override
29 | public OffsettingByteData getOffsettingOffsetData(long offset) {
30 | return new OffsettingBackedByteData(d, originalOffset + mutableOffset + offset);
31 | }
32 |
33 | @Override
34 | int getRealOffset(int offset) {
35 | return originalOffset + mutableOffset + offset;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/bytestream/OffsettingByteData.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.bytestream;
2 |
3 | public interface OffsettingByteData extends ByteData {
4 | void advance(long offset);
5 | long getOffset();
6 | }
7 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/collections/CollectionUtils.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.collections;
2 |
3 | import java.util.Collection;
4 | import java.util.Set;
5 |
6 | public class CollectionUtils {
7 | public static String join(Collection> in, String sep) {
8 | StringBuilder sb = new StringBuilder();
9 | boolean first = true;
10 | for (Object o : in) {
11 | if (first) {
12 | first = false;
13 | } else {
14 | sb.append(sep);
15 | }
16 | sb.append(o.toString());
17 | }
18 | return sb.toString();
19 | }
20 |
21 | public static String joinPostFix(Collection> in, String sep) {
22 | StringBuilder sb = new StringBuilder();
23 | for (Object o : in) {
24 | sb.append(o.toString());
25 | sb.append(sep);
26 | }
27 | return sb.toString();
28 | }
29 |
30 | public static X getSingle(Collection extends X> a) {
31 | return a.iterator().next();
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/collections/LazyExceptionRetainingMap.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.collections;
2 |
3 | import org.benf.cfr.reader.util.functors.UnaryFunction;
4 |
5 | import java.util.Map;
6 |
7 | public class LazyExceptionRetainingMap extends LazyMap {
8 | private final Map exceptionMap = MapFactory.newMap();
9 |
10 | LazyExceptionRetainingMap(Map inner, UnaryFunction factory) {
11 | super(inner, factory);
12 | }
13 |
14 | @Override
15 | public Y get(Object o) {
16 | RuntimeException exception = exceptionMap.get(o);
17 | if (exception == null) {
18 | try {
19 | return super.get(o);
20 | } catch (RuntimeException e) {
21 | exception = e;
22 | //noinspection unchecked
23 | exceptionMap.put((X) o, e);
24 | }
25 | }
26 | throw exception;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/collections/StackFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.collections;
2 |
3 | import java.util.Stack;
4 |
5 | public class StackFactory {
6 | public static Stack newStack() {
7 | return new Stack();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/BinaryFunction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface BinaryFunction {
4 | Z invoke(X arg, Y arg2);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/BinaryPredicate.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface BinaryPredicate {
4 | boolean test(X a, Y b);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/BinaryProcedure.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface BinaryProcedure {
4 | void call(X arg1, Y arg2);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/NonaryFunction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface NonaryFunction {
4 | T invoke();
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/Predicate.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface Predicate {
4 | boolean test(X in);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/TrinaryFunction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface TrinaryFunction {
4 | R invoke(X arg1, Y arg2, Z arg3);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/UnaryFunction.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface UnaryFunction {
4 | Y invoke(X arg);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/functors/UnaryProcedure.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.functors;
2 |
3 | public interface UnaryProcedure {
4 | void call(T arg);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/getopt/BadParametersException.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.getopt;
2 |
3 | public class BadParametersException extends IllegalArgumentException {
4 | private final PermittedOptionProvider.ArgumentParam, ?> option;
5 |
6 | BadParametersException(String s, PermittedOptionProvider.ArgumentParam, ?> option) {
7 | super(s);
8 | this.option = option;
9 | }
10 |
11 | @Override
12 | public String toString() {
13 | String sb = "While processing argument '" + option.getName() + "':\n" +
14 | super.getMessage() + "\n" +
15 | "Valid argument range: " + option.getFn().getRangeDescription() + "\n";
16 | return sb;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/getopt/GetOptSinkFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.getopt;
2 |
3 | import java.util.Map;
4 |
5 | public interface GetOptSinkFactory extends PermittedOptionProvider {
6 | T create(Map opts);
7 | }
8 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/getopt/OptionDecoder.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.getopt;
2 |
3 | public interface OptionDecoder extends OptionDecoderParam {
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/getopt/OptionDecoderParam.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.getopt;
2 |
3 | import org.benf.cfr.reader.util.functors.TrinaryFunction;
4 |
5 | public interface OptionDecoderParam extends TrinaryFunction {
6 | String getRangeDescription();
7 |
8 | String getDefaultValue();
9 | }
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/getopt/Options.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.getopt;
2 |
3 | public interface Options {
4 |
5 | boolean optionIsSet(PermittedOptionProvider.ArgumentParam, ?> option);
6 |
7 | T getOption(PermittedOptionProvider.ArgumentParam option);
8 |
9 | T getOption(PermittedOptionProvider.ArgumentParam option, A arg);
10 | }
11 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/graph/GraphVisitor.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.graph;
2 |
3 | import java.util.Collection;
4 |
5 | public interface GraphVisitor {
6 |
7 | void enqueue(T next);
8 |
9 | void enqueue(Collection extends T> next);
10 |
11 | void process();
12 |
13 | void abort();
14 |
15 | boolean wasAborted();
16 |
17 | Collection getVisitedNodes();
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/graph/GraphVisitorFIFO.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.graph;
2 |
3 | import org.benf.cfr.reader.util.functors.BinaryProcedure;
4 |
5 | public class GraphVisitorFIFO extends AbstractGraphVisitorFI {
6 | public GraphVisitorFIFO(T first, BinaryProcedure> callee) {
7 | super(first, callee);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/BlockCommentState.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | enum BlockCommentState {
4 | InLine,
5 | In,
6 | Not
7 | }
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/BytecodeDumpConsumer.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.entities.Method;
4 |
5 | import java.util.Collection;
6 | import java.util.NavigableMap;
7 | import java.util.TreeMap;
8 |
9 | public interface BytecodeDumpConsumer {
10 | interface Item {
11 | Method getMethod();
12 | /** return a map of BYTECODE LOCATION IN METHOD to LINE NUMBER.
13 | * Note that this is ordered by BYTECODE LOCATION.
14 | **/
15 | NavigableMap getBytecodeLocs();
16 | }
17 |
18 | void accept(Collection- items);
19 | }
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/Dumpable.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | public interface Dumpable {
4 | Dumper dump(Dumper d);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/DumpableWithPrecedence.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.parse.expression.misc.Precedence;
4 | import org.benf.cfr.reader.util.Troolean;
5 |
6 | public interface DumpableWithPrecedence extends Dumpable {
7 |
8 | Precedence getPrecedence();
9 |
10 | Dumper dumpWithOuterPrecedence(Dumper d, Precedence outerPrecedence, Troolean isLhs);
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/DumperFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.state.TypeUsageInformation;
5 |
6 | public interface DumperFactory {
7 |
8 | Dumper getNewTopLevelDumper(JavaTypeInstance classType, SummaryDumper summaryDumper, TypeUsageInformation typeUsageInformation, IllegalIdentifierDump illegalIdentifierDump);
9 |
10 | // If we support line numbers, we'll be wrapped around the top level dumper.
11 | Dumper wrapLineNoDumper(Dumper dumper);
12 |
13 | ProgressDumper getProgressDumper();
14 |
15 | SummaryDumper getSummaryDumper();
16 |
17 | ExceptionDumper getExceptionDumper();
18 |
19 | DumperFactory getFactoryWithPrefix(String prefix, int version);
20 | }
21 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/ExceptionDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | public interface ExceptionDumper {
4 | void noteException(String path, String comment, Exception e);
5 | }
6 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/LogFormatter.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import java.util.logging.Formatter;
4 | import java.util.logging.LogRecord;
5 |
6 | public class LogFormatter extends Formatter {
7 | @Override
8 | public String format(LogRecord logRecord) {
9 | return logRecord.getMessage() + "\n";
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/LoggerFactory.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import java.util.logging.*;
4 |
5 | /**
6 | * Small wrapper around the bog standard java logger.
7 | */
8 | public class LoggerFactory {
9 |
10 | private static Handler handler = getHandler();
11 | private static Level level = Level.WARNING;
12 |
13 | private static Handler getHandler() {
14 | Handler handler = new ConsoleHandler();
15 | Formatter formatter = new LogFormatter();
16 | handler.setFormatter(formatter);
17 | return handler;
18 | }
19 |
20 | public static
Logger create(Class clazz) {
21 | Logger logger = Logger.getLogger(clazz.getName());
22 | logger.setUseParentHandlers(false);
23 | logger.addHandler(handler);
24 | logger.setLevel(level);
25 | return logger;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/MethodErrorCollector.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.Method;
5 |
6 | public interface MethodErrorCollector {
7 | void addSummaryError(Method method, String s);
8 |
9 | static class SummaryDumperMethodErrorCollector implements MethodErrorCollector {
10 | private final JavaTypeInstance type;
11 | private final SummaryDumper summaryDumper;
12 |
13 | public SummaryDumperMethodErrorCollector(JavaTypeInstance type, SummaryDumper summaryDumper) {
14 | this.type = type;
15 | this.summaryDumper = summaryDumper;
16 | }
17 |
18 | @Override
19 | public void addSummaryError(Method method, String s) {
20 | summaryDumper.notifyError(type, method, s);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/MovableDumperContext.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | class MovableDumperContext {
4 | BlockCommentState inBlockComment = BlockCommentState.Not;
5 | boolean atStart = true;
6 | boolean pendingCR = false;
7 | int indent;
8 | int outputCount = 0;
9 | int currentLine = 1; // lines are 1 based. Sigh.
10 | }
11 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/NopSummaryDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.Method;
5 |
6 | public class NopSummaryDumper implements SummaryDumper {
7 |
8 | @Override
9 | public void notify(String message) {
10 | }
11 |
12 | @Override
13 | public void notifyError(JavaTypeInstance controllingType, Method method, String error) {
14 | }
15 |
16 | @Override
17 | public void close() {
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/ProgressDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 |
5 | public interface ProgressDumper {
6 | void analysingType(JavaTypeInstance type);
7 | void analysingPath(String path);
8 | }
9 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/ProgressDumperNop.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 |
5 | public class ProgressDumperNop implements ProgressDumper {
6 | public static final ProgressDumper INSTANCE = new ProgressDumperNop();
7 |
8 | private ProgressDumperNop() {}
9 |
10 | @Override
11 | public void analysingType(JavaTypeInstance type) {
12 | }
13 |
14 | @Override
15 | public void analysingPath(String path) {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/ProgressDumperStdErr.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.util.getopt.OptionsImpl;
5 |
6 | public class ProgressDumperStdErr implements ProgressDumper {
7 |
8 | @Override
9 | public void analysingType(JavaTypeInstance type) {
10 | System.err.println("Processing " + type.getRawName());
11 | }
12 |
13 | @Override
14 | public void analysingPath(String path) {
15 | System.err.println("Processing " + path + " (use " + OptionsImpl.SILENT.getName() + " to silence)");
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/SinkSummaryDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.api.OutputSinkFactory;
4 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
5 | import org.benf.cfr.reader.entities.Method;
6 |
7 | public class SinkSummaryDumper implements SummaryDumper {
8 | private final OutputSinkFactory.Sink sink;
9 |
10 | private transient JavaTypeInstance lastControllingType = null;
11 | private transient Method lastMethod = null;
12 |
13 | SinkSummaryDumper(OutputSinkFactory.Sink sink) {
14 | this.sink = sink;
15 | }
16 |
17 | @Override
18 | public void notify(String message) {
19 | sink.write(message + "\n");
20 | }
21 |
22 | @Override
23 | public void notifyError(JavaTypeInstance controllingType, Method method, String error) {
24 | if (lastControllingType != controllingType) {
25 | lastControllingType = controllingType;
26 | lastMethod = null;
27 | sink.write("\n\n" + controllingType.getRawName() + "\n----------------------------\n\n");
28 | }
29 | if (method != lastMethod) {
30 | sink.write(method.getMethodPrototype().toString() + "\n");
31 | lastMethod = method;
32 | }
33 | sink.write(" " + error + "\n");
34 | }
35 |
36 | @Override
37 | public void close() {
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/StdErrExceptionDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.util.CannotLoadClassException;
4 |
5 | public class StdErrExceptionDumper implements ExceptionDumper {
6 | @Override
7 | public void noteException(String path, String comment, Exception e) {
8 | if (comment != null) {
9 | System.err.println(comment);
10 | }
11 | if (e instanceof CannotLoadClassException) {
12 | System.err.println("Can't load the class specified:");
13 | System.err.println(e.toString());
14 | } else {
15 | System.err.println(e.toString());
16 | for (Object x : e.getStackTrace()) {
17 | System.err.println(x);
18 | }
19 | }
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/SummaryDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.entities.Method;
5 |
6 | public interface SummaryDumper {
7 | void notify(String message);
8 |
9 | void notifyError(JavaTypeInstance controllingType, Method method, String error);
10 |
11 | void close();
12 | }
13 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/TypeContext.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | public enum TypeContext {
4 | None, // Nothing worth noting.
5 | Static;
6 | }
7 |
--------------------------------------------------------------------------------
/src/org/benf/cfr/reader/util/output/TypeOverridingDumper.java:
--------------------------------------------------------------------------------
1 | package org.benf.cfr.reader.util.output;
2 |
3 | import org.benf.cfr.reader.bytecode.analysis.types.JavaTypeInstance;
4 | import org.benf.cfr.reader.state.TypeUsageInformation;
5 |
6 | public class TypeOverridingDumper extends DelegatingDumper {
7 | private final TypeUsageInformation typeUsageInformation;
8 |
9 | TypeOverridingDumper(Dumper delegate, TypeUsageInformation typeUsageInformation) {
10 | super(delegate);
11 | this.typeUsageInformation = typeUsageInformation;
12 | }
13 |
14 | @Override
15 | public TypeUsageInformation getTypeUsageInformation() {
16 | return typeUsageInformation;
17 | }
18 |
19 | @Override
20 | public Dumper dump(JavaTypeInstance javaTypeInstance) {
21 | return dump(javaTypeInstance, TypeContext.None);
22 | }
23 |
24 | @Override
25 | public Dumper dump(JavaTypeInstance javaTypeInstance, TypeContext typeContext) {
26 | javaTypeInstance.dumpInto(this, typeUsageInformation, typeContext);
27 | return this;
28 | }
29 |
30 | @Override
31 | public Dumper withTypeUsageInformation(TypeUsageInformation innerclassTypeUsageInformation) {
32 | return new TypeOverridingDumper(delegate, innerclassTypeUsageInformation);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------