📄 hierarchy.java
字号:
SignatureConverter.convertMethodSignature(inv,cpg)); } short opcode = inv.getOpcode(); if (methodChooser != ANY_METHOD) { methodChooser = new CompoundMethodChooser(new JavaClassAndMethodChooser[]{ methodChooser, opcode == Constants.INVOKESTATIC ? STATIC_METHOD : INSTANCE_METHOD }); } // Find the method if (opcode == Constants.INVOKESPECIAL) { // Non-virtual dispatch result = findExactMethod(inv, cpg, methodChooser); } else { String className = inv.getClassName(cpg); String methodName = inv.getName(cpg); String methodSig = inv.getSignature(cpg); if (DEBUG_METHOD_LOOKUP) { System.out.println("[Class name is " + className + "]"); System.out.println("[Method name is " + methodName + "]"); System.out.println("[Method signature is " + methodSig + "]"); } if (className.startsWith("[")) { // Java 1.5 allows array classes to appear as the class name className= "java.lang.Object"; } if (opcode == Constants.INVOKEVIRTUAL || opcode == Constants.INVOKESTATIC) { if (DEBUG_METHOD_LOOKUP) { System.out.println("[invokevirtual or invokestatic]"); } // Dispatch where the class hierarchy is searched // Check superclasses result = findMethod(Repository.lookupClass(className), methodName, methodSig, methodChooser); if (result == null) { if (DEBUG_METHOD_LOOKUP) { System.out.println("[not in class, checking superclasses...]"); } JavaClass[] superClassList = Repository.getSuperClasses(className); result = findMethod(superClassList, methodName, methodSig, methodChooser); } } else { // Check superinterfaces result = findMethod(Repository.lookupClass(className), methodName, methodSig, methodChooser); if (result == null) { JavaClass[] interfaceList = Repository.getInterfaces(className); result = findMethod(interfaceList, methodName, methodSig, methodChooser); } } } return result; } /** * Find the declared exceptions for the method called * by given instruction. * * @param inv the InvokeInstruction * @param cpg the ConstantPoolGen used by the class the InvokeInstruction belongs to * @return array of ObjectTypes of thrown exceptions, or null * if we can't find the list of declared exceptions */ public static ObjectType[] findDeclaredExceptions(InvokeInstruction inv, ConstantPoolGen cpg) throws ClassNotFoundException { JavaClassAndMethod method = findInvocationLeastUpperBound(inv, cpg); if (method == null) return null; ExceptionTable exTable = method.getMethod().getExceptionTable(); if (exTable == null) return new ObjectType[0]; String[] exNameList = exTable.getExceptionNames(); ObjectType[] result = new ObjectType[exNameList.length]; for (int i = 0; i < exNameList.length; ++i) { result[i] = ObjectTypeFactory.getInstance(exNameList[i]); } return result; } /** * Find a method in given class. * * @param javaClass the class * @param methodName the name of the method * @param methodSig the signature of the method * @return the JavaClassAndMethod, or null if no such method exists in the class */ public static @CheckForNull JavaClassAndMethod findMethod(JavaClass javaClass, String methodName, String methodSig) { return findMethod(javaClass, methodName, methodSig, ANY_METHOD); } /** * Find a method in given class. * * @param javaClass the class * @param methodName the name of the method * @param methodSig the signature of the method * @param chooser JavaClassAndMethodChooser to use to select a matching method * (assuming class, name, and signature already match) * @return the JavaClassAndMethod, or null if no such method exists in the class */ public static @CheckForNull JavaClassAndMethod findMethod( JavaClass javaClass, String methodName, String methodSig, JavaClassAndMethodChooser chooser) { if (DEBUG_METHOD_LOOKUP) { System.out.println("Check " + javaClass.getClassName()); } Method[] methodList = javaClass.getMethods(); for (Method method : methodList) if (method.getName().equals(methodName) && method.getSignature().equals(methodSig)) { JavaClassAndMethod m = new JavaClassAndMethod(javaClass, method); if (chooser.choose(m)) { if (DEBUG_METHOD_LOOKUP) { System.out.println("\t==> FOUND: " + method); } return m; } } if (DEBUG_METHOD_LOOKUP) { System.out.println("\t==> NOT FOUND"); } return null; } /** * Find a method in given class. * * @param javaClass the class * @param methodName the name of the method * @param methodSig the signature of the method * @return the JavaClassAndMethod, or null if no such method exists in the class */ public static @CheckForNull JavaClassAndMethod findConcreteMethod( JavaClass javaClass, String methodName, String methodSig) { if (DEBUG_METHOD_LOOKUP) { System.out.println("Check " + javaClass.getClassName()); } Method[] methodList = javaClass.getMethods(); for (Method method : methodList) if (method.getName().equals(methodName) && method.getSignature().equals(methodSig) && accessFlagsAreConcrete(method.getAccessFlags())) { JavaClassAndMethod m = new JavaClassAndMethod(javaClass, method); return m; } if (DEBUG_METHOD_LOOKUP) { System.out.println("\t==> NOT FOUND"); } return null; } /** * Find a method in given class. * * @param javaClass the class * @param methodName the name of the method * @param methodSig the signature of the method * @param chooser the JavaClassAndMethodChooser to use to screen possible candidates * @return the XMethod, or null if no such method exists in the class */ public static @CheckForNull XMethod findXMethod(JavaClass javaClass, String methodName, String methodSig, JavaClassAndMethodChooser chooser) { JavaClassAndMethod result = findMethod(javaClass, methodName, methodSig, chooser); return result == null ? null : XFactory.createXMethod(result.getJavaClass(), result.getMethod()); } /** * JavaClassAndMethodChooser which accepts any method. */ public static final JavaClassAndMethodChooser ANY_METHOD = new JavaClassAndMethodChooser() { public boolean choose(JavaClassAndMethod javaClassAndMethod) { return true; } }; // FIXME: perhaps native methods should be concrete. public static boolean accessFlagsAreConcrete(int accessFlags) { return (accessFlags & Constants.ACC_ABSTRACT) == 0 && (accessFlags & Constants.ACC_NATIVE) == 0; } /** * JavaClassAndMethodChooser which accepts only concrete (not abstract or native) methods. */ public static final JavaClassAndMethodChooser CONCRETE_METHOD = new JavaClassAndMethodChooser() { public boolean choose(JavaClassAndMethod javaClassAndMethod) { Method method = javaClassAndMethod.getMethod(); int accessFlags = method.getAccessFlags(); return accessFlagsAreConcrete(accessFlags); } }; /** * JavaClassAndMethodChooser which accepts only static methods. */ public static final JavaClassAndMethodChooser STATIC_METHOD = new JavaClassAndMethodChooser() { public boolean choose(JavaClassAndMethod javaClassAndMethod) { return javaClassAndMethod.getMethod().isStatic(); } }; /** * JavaClassAndMethodChooser which accepts only instance methods. */ public static final JavaClassAndMethodChooser INSTANCE_METHOD = new JavaClassAndMethodChooser() { public boolean choose(JavaClassAndMethod javaClassAndMethod) { return !javaClassAndMethod.getMethod().isStatic(); } }; /** * Find a method in given list of classes, * searching the classes in order. * * @param classList list of classes in which to search * @param methodName the name of the method * @param methodSig the signature of the method * @return the JavaClassAndMethod, or null if no such method exists in the class */ public static JavaClassAndMethod findMethod(JavaClass[] classList, String methodName, String methodSig) { return findMethod(classList, methodName, methodSig, ANY_METHOD); } /** * Find a method in given list of classes, * searching the classes in order. * * @param classList list of classes in which to search * @param methodName the name of the method * @param methodSig the signature of the method * @param chooser JavaClassAndMethodChooser to select which methods are considered; * it must return true for a method to be returned * @return the JavaClassAndMethod, or null if no such method exists in the class */ public static JavaClassAndMethod findMethod(JavaClass[] classList, String methodName, String methodSig, JavaClassAndMethodChooser chooser) { JavaClassAndMethod m = null; for (JavaClass cls : classList) { if ((m = findMethod(cls, methodName, methodSig, chooser)) != null) break; } return m; } /** * Find XMethod for method in given list of classes, * searching the classes in order. * * @param classList list of classes in which to search * @param methodName the name of the method * @param methodSig the signature of the method * @return the XMethod, or null if no such method exists in the class */ public static XMethod findXMethod(JavaClass[] classList, String methodName, String methodSig) { return findXMethod(classList, methodName, methodSig, ANY_METHOD); } /** * Find XMethod for method in given list of classes, * searching the classes in order. * * @param classList list of classes in which to search * @param methodName the name of the method * @param methodSig the signature of the method * @param chooser JavaClassAndMethodChooser to select which methods are considered; * it must return true for a method to be returned * @return the XMethod, or null if no such method exists in the class */ public static XMethod findXMethod(JavaClass[] classList, String methodName, String methodSig, JavaClassAndMethodChooser chooser) { for (JavaClass cls : classList) { JavaClassAndMethod m; if ((m = findMethod(cls, methodName, methodSig)) != null && chooser.choose(m)) { return XFactory.createXMethod(cls, m.getMethod()); } } return null; } /** * Resolve possible method call targets. * This works for both static and instance method calls. * * @param invokeInstruction the InvokeInstruction * @param typeFrame the TypeFrame containing the types of stack values * @param cpg the ConstantPoolGen * @return Set of methods which might be called * @throws DataflowAnalysisException * @throws ClassNotFoundException */ public static Set<JavaClassAndMethod> resolveMethodCallTargets( InvokeInstruction invokeInstruction,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -