From e503aeedf74dbb39449df6bf3b548e5fd3ef6a53 Mon Sep 17 00:00:00 2001 From: dengshiwei Date: Wed, 23 Sep 2020 07:24:49 +0800 Subject: [PATCH] add IsNullInterpreter.kt --- README.md | 9 ++++- ...0\221\345\220\216\345\205\274\345\256\271" | 11 ++++++ .../asm_example/part8/CyclomaticComplexity.kt | 27 +++++++++++++ .../part9/AnnotationNodeAdapter.kt | 39 +++++++++++++++++++ .../part9/SignatureVisitorAdapter.java | 7 ++++ 5 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 "asm_example/src/main/java/com/andoter/asm_example/part10/\346\240\221 API \345\220\221\345\220\216\345\205\274\345\256\271" create mode 100644 asm_example/src/main/java/com/andoter/asm_example/part8/CyclomaticComplexity.kt create mode 100644 asm_example/src/main/java/com/andoter/asm_example/part9/AnnotationNodeAdapter.kt create mode 100644 asm_example/src/main/java/com/andoter/asm_example/part9/SignatureVisitorAdapter.java diff --git a/README.md b/README.md index 03f8370..10614d1 100644 --- a/README.md +++ b/README.md @@ -88,4 +88,11 @@ ASM 4 教程中的示例代码 - [8.2.2 基本数据流校验器](asm_example/src/main/java/com/andoter/asm_example/part8/BasicVerifierAdapter.kt) - [8.2.3 简单数据流校验器](asm_example/src/main/java/com/andoter/asm_example/part8/RemoveUnusedCastTransformer.kt) - [RemoveUnusedCastAdapter](asm_example/src/main/java/com/andoter/asm_example/part8/RemoveUnusedCastAdapter.kt) - - [8.2.4 自定义数据流分析](asm_example/src/main/java/com/andoter/asm_example/part8/IsNullInterpreter.kt) \ No newline at end of file + - [8.2.4 自定义数据流分析](asm_example/src/main/java/com/andoter/asm_example/part8/IsNullInterpreter.kt) + - [8.2.5 控制流分析](asm_example/src/main/java/com/andoter/asm_example/part8/CyclomaticComplexity.kt) + +### [第 9 章](asm_example/src/main/java/com/andoter/asm_example/part9) +- [9.1 泛型](asm_example/src/main/java/com/andoter/asm_example/part9/SignatureVisitorAdapter.java) +- [9.2 注解](asm_example/src/main/java/com/andoter/asm_example/part9/AnnotationNodeAdapter.kt) + +### [第 10 章](asm_example/src/main/java/com/andoter/asm_example/part10) \ No newline at end of file diff --git "a/asm_example/src/main/java/com/andoter/asm_example/part10/\346\240\221 API \345\220\221\345\220\216\345\205\274\345\256\271" "b/asm_example/src/main/java/com/andoter/asm_example/part10/\346\240\221 API \345\220\221\345\220\216\345\205\274\345\256\271" new file mode 100644 index 0000000..0a5781e --- /dev/null +++ "b/asm_example/src/main/java/com/andoter/asm_example/part10/\346\240\221 API \345\220\221\345\220\216\345\205\274\345\256\271" @@ -0,0 +1,11 @@ +### 10.2 规则 +首先,如果使用树 API 编写一个类生成器,那就不需要遵循什么规则(和核心 API 一样)。可以用任意构造器创建 ClassNode 和其他元素,可以使用这些类的任意方法。 +另一方面,如果要用树 API 编写类分析器或类适配器,也就是说,如果使用 ClassNode 或其他直接或间接地通过 ClassReader.accept()填充的类似类,或者如果重写这些类中的 +一个,则必须遵循下面给出的规则。 + +#### 规则 1 +要用 ASM 版本 X 的树 API 编写类分析器或适配器,则使用以这一确切版本为参数的构造器创建 ClassNode(而不是使用没有参数的默认构造器)。 + +#### 规则 2 +要用 ASM 版本 X 的树 API 编写一个类分析器或适配器,使用别人创建的 ClassNode,在以任何方式使用这个 ClassNode 之前,都要以这个确切版本号为参数,调用 +它的 check()方法。 \ No newline at end of file diff --git a/asm_example/src/main/java/com/andoter/asm_example/part8/CyclomaticComplexity.kt b/asm_example/src/main/java/com/andoter/asm_example/part8/CyclomaticComplexity.kt new file mode 100644 index 0000000..53f9e57 --- /dev/null +++ b/asm_example/src/main/java/com/andoter/asm_example/part8/CyclomaticComplexity.kt @@ -0,0 +1,27 @@ +package com.andoter.asm_example.part8 + +import org.objectweb.asm.tree.MethodNode +import org.objectweb.asm.tree.analysis.* +import java.util.* + + +class CyclomaticComplexity { + + fun getCyclomaticComplexity(owner: String, mn: MethodNode) { + val analyzer = object :Analyzer(BasicInterpreter()) { + override fun newFrame(numLocals: Int, numStack: Int): Frame { + return Node(numLocals, numStack) + } + + override fun newControlFlowEdge(insnIndex: Int, successorIndex: Int) { + val node = frames[insnIndex] as Node + node.successors.plus(frames[successorIndex] as Node) + super.newControlFlowEdge(insnIndex, successorIndex) + } + } + } +} + +class Node(numLocals: Int, numStack: Int) : Frame(numLocals, numStack) { + var successors: Set> = mutableSetOf() +} \ No newline at end of file diff --git a/asm_example/src/main/java/com/andoter/asm_example/part9/AnnotationNodeAdapter.kt b/asm_example/src/main/java/com/andoter/asm_example/part9/AnnotationNodeAdapter.kt new file mode 100644 index 0000000..9ef1355 --- /dev/null +++ b/asm_example/src/main/java/com/andoter/asm_example/part9/AnnotationNodeAdapter.kt @@ -0,0 +1,39 @@ +package com.andoter.asm_example.part9 + +import com.andoter.asm_example.utils.ADLog +import org.objectweb.asm.AnnotationVisitor +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.AnnotationNode + +/** + * 在树 API 中提供了对应的 AnnotationNode 类用于处理注解,该类继承 AnnotationVisitor + */ + +@Test("Adapter") +class AnnotationNodeAdapter { + +} + +annotation class Test(val value: String) + +fun main() { + val classReader = ClassReader("com.andoter.asm_example.part9.AnnotationNodeAdapter") + classReader.accept(object :ClassVisitor(Opcodes.ASM7){ + override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor { + return object :AnnotationNode(Opcodes.ASM6, descriptor) { + override fun visit(name: String?, value: Any?) { + super.visit(name, value) + ADLog.info("visit, name = $name, value = $value") + } + + override fun visitEnd() { + ADLog.info("visitEnd") + super.visitEnd() + } + } + } + }, ClassReader.SKIP_DEBUG) + +} \ No newline at end of file diff --git a/asm_example/src/main/java/com/andoter/asm_example/part9/SignatureVisitorAdapter.java b/asm_example/src/main/java/com/andoter/asm_example/part9/SignatureVisitorAdapter.java new file mode 100644 index 0000000..02afec5 --- /dev/null +++ b/asm_example/src/main/java/com/andoter/asm_example/part9/SignatureVisitorAdapter.java @@ -0,0 +1,7 @@ +package com.andoter.asm_example.part9; + +/** + * 在树 API 中没有提供与 SignatureVisitor 对应的 SignatureNode + */ +class SignatureVisitorAdapter { +}