Wei Yang

75 papers A* 22Journal 48Unranked 5
YearRankTypeTitle / Venue / Authors
2025 conf
APSIPA
Songting Liu, Deheng Ye, Wei Yang, Haoyang Li, Eng Siong Chng
2025 A* conf
SIGGRAPH Asia
Yuze He, Yanning Zhou, Wang Zhao, Jingwen Ye, Yushi Bai, Kaiwen Xiao, Yong-Jin Liu, Zhongqian Sun, Wei Yang
2025 conf
SIGGRAPH (Conference Paper Track)
Jingwen Ye, Yuze He, Yanning Zhou, Yiqin Zhu, Kaiwen Xiao, Yong-Jin Liu, Wei Yang, Xiao Han
2025 J jnl
CoRR
Deheng Ye, Fangyun Zhou, Jiacheng Lv, Jianqi Ma, Jun Zhang, Junyan Lv, Junyou Li, Minwen Deng, Mingyu Yang, Qiang Fu, Wei Yang, Wenkai Lv, Yangbin Yu, Yewen Wang, Yonghang Guan, Zhihao Hu, Zhongbin Fang, Zhongqian Sun
2024 J jnl
CoRR
Fei Shen, Hu Ye, Sibo Liu, Jun Zhang, Cong Wang, Xiao Han, Wei Yang
2024 J jnl
CoRR
Hanlin Yang, Jian Yao, Weiming Liu, Qing Wang, Hanmin Qin, Hansheng Kong, Kirk Tang, Jiechao Xiong, Chao Yu, Kai Li, Junliang Xing, Hongwu Chen, Juchao Zhuo, Qiang Fu, Wei Yang, Haobo Fu
2024 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Tiantian Zhang, Zichuan Lin, Yuxing Wang, Deheng Ye, Qiang Fu, Wei Yang, Xueqian Wang, Bin Liang, Bo Yuan, Xiu Li
2024 A* conf
ICLR
Yiming Gao, Feiyu Liu, Liang Wang, Dehua Zheng, Zhenjie Lian, Weixuan Wang, Wenjin Yang, Siqin Li, Xianliang Wang, Wenhui Chen, Jing Dai, Qiang Fu, Wei Yang, Lanxiao Huang, Wei Liu
2024 J jnl
CoRR
Yiming Gao, Feiyu Liu, Liang Wang, Zhenjie Lian, Dehua Zheng, Weixuan Wang, Wenjin Yang, Siqin Li, Xianliang Wang, Wenhui Chen, Jing Dai, Qiang Fu, Wei Yang, Lanxiao Huang, Wei Liu
2024 J jnl
CoRR
Cong Wang, Kuan Tian, Yonghang Guan, Jun Zhang, Zhiwei Jiang, Fei Shen, Xiao Han, Qing Gu, Wei Yang
2024 J jnl
CoRR
Yun Qu, Boyuan Wang, Jianzhun Shao, Yuhang Jiang, Chen Chen, Zhenbin Ye, Lin Liu, Junfeng Yang, Lin Lai, Hongyang Qin, Minwen Deng, Juchao Zhuo, Deheng Ye, Qiang Fu, Wei Yang, Guang Yang, Lanxiao Huang, Xiangyang Ji
2024 J jnl
CoRR
Mingyu Yang, Junyou Li, Zhongbin Fang, Sheng Chen, Yangbin Yu, Qiang Fu, Wei Yang, Deheng Ye
2024 J jnl
CoRR
Liangzhou Wang, Kaiwen Zhu, Fengming Zhu, Xinghu Yao, Shujie Zhang, Deheng Ye, Haobo Fu, Qiang Fu, Wei Yang
2024 J jnl
CoRR
Cong Wang, Kuan Tian, Jun Zhang, Yonghang Guan, Feng Luo, Fei Shen, Zhiwei Jiang, Qing Gu, Xiao Han, Wei Yang
2023 A* conf
NeurIPS
Ruozi Huang, Xipeng Wu, Hongsheng Yu, Zhong Fan, Haobo Fu, Qiang Fu, Wei Yang
2023 J jnl
Medical Image Anal.
Xiyue Wang, Jun Zhang, Sen Yang, Jingxi Xiang, Feng Luo, Minghui Wang, Jing Zhang, Wei Yang, Junzhou Huang, Xiao Han
2023 J jnl
CoRR
Fei Shen, Hu Ye, Jun Zhang, Cong Wang, Xiao Han, Wei Yang
2023 J jnl
Comput. Biol. Medicine
Jinxi Xiang, Xiyue Wang, Xinran Wang, Jun Zhang, Sen Yang, Wei Yang, Xiao Han, Yueping Liu
2023 A* conf
ACM Multimedia
Yue Lv, Jinxi Xiang, Jun Zhang, Wenming Yang, Xiao Han, Wei Yang
2023 J jnl
CoRR
Yue Lv, Jinxi Xiang, Jun Zhang, Wenming Yang, Xiao Han, Wei Yang
2023 J jnl
CoRR
Kuan Tian, Yonghang Guan, Jinxi Xiang, Jun Zhang, Xiao Han, Wei Yang
2023 J jnl
CoRR
Zhihui Xie, Zichuan Lin, Deheng Ye, Qiang Fu, Wei Yang, Shuai Li
2023 A* conf
NeurIPS
Yun Qu, Boyuan Wang, Jianzhun Shao, Yuhang Jiang, Chen Chen, Zhenbin Ye, Lin Liu, Yang Feng, Lin Lai, Hongyang Qin, Minwen Deng, Juchao Zhuo, Deheng Ye, Qiang Fu, Yang Guang, Wei Yang, Lanxiao Huang, Xiangyang Ji
2023 J jnl
CoRR
Hu Ye, Jun Zhang, Sibo Liu, Xiao Han, Wei Yang
2023 J jnl
CoRR
Feng Luo, Jinxi Xiang, Jun Zhang, Xiao Han, Wei Yang
2023 J jnl
Medical Image Anal.
Wenhua Zhang, Jun Zhang, Xiyue Wang, Sen Yang, Junzhou Huang, Wei Yang, Wenping Wang, Xiao Han
2023 A* conf
ICML
Weiming Liu, Haobo Fu, Qiang Fu, Wei Yang
2023 A* conf
NeurIPS
Jian Yao, Weiming Liu, Haobo Fu, Yaodong Yang, Stephen McAleer, Qiang Fu, Wei Yang
2023 J jnl
CoRR
Jian Yao, Weiming Liu, Haobo Fu, Yaodong Yang, Stephen McAleer, Qiang Fu, Wei Yang
2023 A* conf
ICLR
Shuang Wu, Jian Yao, Haobo Fu, Ye Tian, Chao Qian, Yaodong Yang, Qiang Fu, Wei Yang
2023 J jnl
CoRR
Jiate Liu, Yiqin Zhu, Kaiwen Xiao, Qiang Fu, Xiao Han, Wei Yang, Deheng Ye
2023 J jnl
Trans. Mach. Learn. Res.
Jiate Liu, Yiqin Zhu, Kaiwen Xiao, Qiang Fu, Xiao Han, Wei Yang, Deheng Ye
2023 A* conf
AAAI
Boxuan Zhao, Jun Zhang, Deheng Ye, Jian Cao, Xiao Han, Qiang Fu, Wei Yang
2023 J jnl
Medical Image Anal.
Xiyue Wang, Yuexi Du, Sen Yang, Jun Zhang, Minghui Wang, Jing Zhang, Wei Yang, Junzhou Huang, Xiao Han
2023 J jnl
CoRR
Haoxuan Pan, Deheng Ye, Xiaoming Duan, Qiang Fu, Wei Yang, Jianping He, Mingfei Sun
2023 J jnl
CoRR
Zichuan Lin, Xiapeng Wu, Mingfei Sun, Deheng Ye, Qiang Fu, Wei Yang, Wei Liu
2023 A* conf
ICLR
Yiming Gao, Feiyu Liu, Liang Wang, Zhenjie Lian, Weixuan Wang, Siqin Li, Xianliang Wang, Xianhan Zeng, Rundong Wang, Jiawei Wang, Qiang Fu, Wei Yang, Lanxiao Huang, Wei Liu
2023 J jnl
CoRR
Yiming Gao, Feiyu Liu, Liang Wang, Zhenjie Lian, Weixuan Wang, Siqin Li, Xianliang Wang, Xianhan Zeng, Rundong Wang, Jiawei Wang, Qiang Fu, Wei Yang, Lanxiao Huang, Wei Liu
2023 A* conf
ACM Multimedia
Kuan Tian, Yonghang Guan, Jinxi Xiang, Jun Zhang, Xiao Han, Wei Yang
2023 J jnl
CoRR
Kuan Tian, Yonghang Guan, Jinxi Xiang, Jun Zhang, Xiao Han, Wei Yang
2022 A* conf
ICLR
Haobo Fu, Weiming Liu, Shuang Wu, Yijia Wang, Tao Yang, Kai Li, Junliang Xing, Bin Li, Bo Ma, Qiang Fu, Wei Yang
2022 J jnl
Genom. Proteom. Bioinform.
Sen Yang, Tao Shen, Yuqi Fang, Xiyue Wang, Jun Zhang, Wei Yang, Junzhou Huang, Xiao Han
2022 J jnl
CoRR
Tiantian Zhang, Zichuan Lin, Yuxing Wang, Deheng Ye, Qiang Fu, Wei Yang, Xueqian Wang, Bin Liang, Bo Yuan, Xiu Li
2022 A* conf
ICML
Haobo Fu, Ye Tian, Hongxiang Yu, Weiming Liu, Shuang Wu, Jiechao Xiong, Ying Wen, Kai Li, Junliang Xing, Qiang Fu, Wei Yang
2022 A* conf
NeurIPS
Hua Wei, Jingxiao Chen, Xiyang Ji, Hongyang Qin, Minwen Deng, Siqin Li, Liang Wang, Weinan Zhang, Yong Yu, Liu Lin, Lanxiao Huang, Deheng Ye, Qiang Fu, Wei Yang
2022 J jnl
CoRR
Hua Wei, Jingxiao Chen, Xiyang Ji, Hongyang Qin, Minwen Deng, Siqin Li, Liang Wang, Weinan Zhang, Yong Yu, Lin Liu, Lanxiao Huang, Deheng Ye, Qiang Fu, Wei Yang
2022 A* conf
IJCAI
Zichuan Lin, Junyou Li, Jianing Shi, Deheng Ye, Qiang Fu, Wei Yang
2022 J jnl
IEEE Trans. Medical Imaging
Wenhua Zhang, Jun Zhang, Sen Yang, Xiyue Wang, Wei Yang, Junzhou Huang, Wenping Wang, Xiao Han
2022 J jnl
CoRR
Anssi Kanervisto, Stephanie Milani, Karolis Ramanauskas, Nicholay Topin, Zichuan Lin, Junyou Li, Jianing Shi, Deheng Ye, Qiang Fu, Wei Yang, Weijun Hong, Zhongyue Huang, Haicheng Chen, Guangjun Zeng, Yue Lin, Vincent Micheli, Eloi Alonso, François Fleuret, Alexander Nikulin, Yury Belousov, Oleg Svidchenko, Aleksei Shpilman
2022 A* conf
CVPR
Yonghang Guan, Jun Zhang, Kuan Tian, Sen Yang, Pei Dong, Jinxi Xiang, Wei Yang, Junzhou Huang, Yuyao Zhang, Xiao Han
2022 J jnl
CoRR
Siteng Chen, Jinxi Xiang, Xiyue Wang, Jun Zhang, Sen Yang, Junzhou Huang, Wei Yang, Junhua Zheng, Xiao Han
2022 J jnl
CoRR
Boxuan Zhao, Jun Zhang, Deheng Ye, Jian Cao, Xiao Han, Qiang Fu, Wei Yang
2022 J jnl
CoRR
Haibin Zhou, Zichuan Lin, Junyou Li, Deheng Ye, Qiang Fu, Wei Yang
2022 A* conf
NeurIPS
Xiyue Wang, Jinxi Xiang, Jun Zhang, Sen Yang, Zhongyi Yang, Ming-Hui Wang, Jing Zhang, Wei Yang, Junzhou Huang, Xiao Han
2022 J jnl
IEEE Trans. Neural Networks Learn. Syst.
Deheng Ye, Guibin Chen, Peilin Zhao, Fuhao Qiu, Bo Yuan, Wen Zhang, Sheng Chen, Mingfei Sun, Xiaoqian Li, Siqin Li, Jing Liang, Zhenjie Lian, Bei Shi, Liang Wang, Tengfei Shi, Qiang Fu, Wei Yang, Lanxiao Huang
2022 J jnl
Medical Image Anal.
Xiyue Wang, Sen Yang, Jun Zhang, Minghui Wang, Jing Zhang, Wei Yang, Junzhou Huang, Xiao Han
2021 A* conf
IJCAI
Hua Wei, Deheng Ye, Zhao Liu, Hao Wu, Bo Yuan, Qiang Fu, Wei Yang, Zhenhui Li
2021 J jnl
CoRR
Hua Wei, Deheng Ye, Zhao Liu, Hao Wu, Bo Yuan, Qiang Fu, Wei Yang, Zhenhui Li
2021 J jnl
CoRR
Xin Zhang, Zixuan Liu, Kaiwen Xiao, Tian Shen, Junzhou Huang, Wei Yang, Dimitris Samaras, Xiao Han
2021 J jnl
CoRR
Zichuan Lin, Junyou Li, Jianing Shi, Deheng Ye, Qiang Fu, Wei Yang
2021 A* conf
NeurIPS
Yiming Gao, Bei Shi, Xueying Du, Liang Wang, Guangwei Chen, Zhenjie Lian, Fuhao Qiu, Guoan Han, Weixuan Wang, Deheng Ye, Qiang Fu, Wei Yang, Lanxiao Huang
2021 J jnl
CoRR
Yiming Gao, Bei Shi, Xueying Du, Liang Wang, Guangwei Chen, Zhenjie Lian, Fuhao Qiu, Guoan Han, Weixuan Wang, Deheng Ye, Qiang Fu, Wei Yang, Lanxiao Huang
2021 A* conf
IJCAI
Menghui Zhu, Minghuan Liu, Jian Shen, Zhicheng Zhang, Sheng Chen, Weinan Zhang, Deheng Ye, Yong Yu, Qiang Fu, Wei Yang
2021 J jnl
CoRR
Menghui Zhu, Minghuan Liu, Jian Shen, Zhicheng Zhang, Sheng Chen, Weinan Zhang, Deheng Ye, Yong Yu, Qiang Fu, Wei Yang
2021 conf
NeurIPS (Competition and Demos)
Anssi Kanervisto, Stephanie Milani, Karolis Ramanauskas, Nicholay Topin, Zichuan Lin, Junyou Li, Jianing Shi, Deheng Ye, Qiang Fu, Wei Yang, Weijun Hong, Zhongyue Huang, Haicheng Chen, Guangjun Zeng, Yue Lin, Vincent Micheli, Eloi Alonso, François Fleuret, Alexander Nikulin, Yury Belousov, Oleg Svidchenko, Aleksei Shpilman
2021 conf
MICCAI (8)
Xiyue Wang, Sen Yang, Jun Zhang, Minghui Wang, Jing Zhang, Junzhou Huang, Wei Yang, Xiao Han
2021 J jnl
IEEE Trans. Games
Sheng Chen, Menghui Zhu, Deheng Ye, Weinan Zhang, Qiang Fu, Wei Yang
2020 A* conf
AAAI
Deheng Ye, Zhao Liu, Mingfei Sun, Bei Shi, Peilin Zhao, Hao Wu, Hongsheng Yu, Shaojie Yang, Xipeng Wu, Qingwei Guo, Qiaobo Chen, Yinyuting Yin, Hao Zhang, Tengfei Shi, Liang Wang, Qiang Fu, Wei Yang, Lanxiao Huang
2020 J jnl
CoRR
Deheng Ye, Guibin Chen, Peilin Zhao, Fuhao Qiu, Bo Yuan, Wen Zhang, Sheng Chen, Mingfei Sun, Xiaoqian Li, Siqin Li, Jing Liang, Zhenjie Lian, Bei Shi, Liang Wang, Tengfei Shi, Qiang Fu, Wei Yang, Lanxiao Huang
2020 A* conf
NeurIPS
Deheng Ye, Guibin Chen, Wen Zhang, Sheng Chen, Bo Yuan, Bo Liu, Jia Chen, Zhao Liu, Fuhao Qiu, Hongsheng Yu, Yinyuting Yin, Bei Shi, Liang Wang, Tengfei Shi, Qiang Fu, Wei Yang, Lanxiao Huang, Wei Liu
2020 J jnl
CoRR
Deheng Ye, Guibin Chen, Wen Zhang, Sheng Chen, Bo Yuan, Bo Liu, Jia Chen, Zhao Liu, Fuhao Qiu, Hongsheng Yu, Yinyuting Yin, Bei Shi, Liang Wang, Tengfei Shi, Qiang Fu, Wei Yang, Lanxiao Huang, Wei Liu
2020 J jnl
CoRR
Sheng Chen, Menghui Zhu, Deheng Ye, Weinan Zhang, Qiang Fu, Wei Yang
2019 conf
MICCAI (5)
Hong Shang, Zhongqian Sun, Wei Yang, Xinghui Fu, Han Zheng, Jia Chang, Junzhou Huang
2019 J jnl
CoRR
Deheng Ye, Zhao Liu, Mingfei Sun, Bei Shi, Peilin Zhao, Hao Wu, Hongsheng Yu, Shaojie Yang, Xipeng Wu, Qingwei Guo, Qiaobo Chen, Yinyuting Yin, Hao Zhang, Tengfei Shi, Liang Wang, Qiang Fu, Wei Yang, Lanxiao Huang
2018 J jnl
CoRR
Bin Wu, Qiang Fu, Jing Liang, Peng Qu, Xiaoqian Li, Liang Wang, Wei Liu, Wei Yang, Yongsheng Liu
tests/unit/test_smali_normalization.py
← Index tests/unit/test_smali_normalization.py python
"""Unit tests for smali semantic normalization.

Tests the three normalization levels (category, opcode, opcode_api),
opcode categorization, ACFG feature index mapping, and integration
with MinHash computation.
"""
import pytest

pytestmark = [pytest.mark.unit, pytest.mark.apk, pytest.mark.decompile]


class TestCategorizeOpcode:
    """Tests for opcode -> semantic category mapping."""

    def test_arithmetic(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("add-int") == "ALU"
        assert categorize_opcode("mul-long/2addr") == "ALU"
        assert categorize_opcode("neg-int") == "ALU"

    def test_data_movement(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("move-result") == "MOV"
        assert categorize_opcode("const/4") == "CONST"
        assert categorize_opcode("const-string") == "CONST"

    def test_memory_access(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("iget-object") == "LOAD"
        assert categorize_opcode("sput-wide") == "STORE"
        assert categorize_opcode("aget-byte") == "LOAD"

    def test_invocation(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("invoke-virtual") == "CALL"
        assert categorize_opcode("invoke-static") == "CALL"
        assert categorize_opcode("invoke-direct") == "CALL"

    def test_control_flow(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("if-eqz") == "BRANCH"
        assert categorize_opcode("goto") == "JMP"
        assert categorize_opcode("goto/16") == "JMP"
        assert categorize_opcode("return-void") == "RET"

    def test_comparison(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("cmp-long") == "CMP"
        assert categorize_opcode("cmpl-float") == "CMP"
        assert categorize_opcode("cmpg-double") == "CMP"

    def test_conversion(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("int-to-long") == "CONV"
        assert categorize_opcode("float-to-int") == "CONV"

    def test_object_type(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("new-instance") == "ALLOC"
        assert categorize_opcode("check-cast") == "TYPE"
        assert categorize_opcode("instance-of") == "TYPE"

    def test_exception_sync(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("throw") == "EXC"
        assert categorize_opcode("monitor-enter") == "SYNC"

    def test_unknown(self):
        from redb.extractors.decompiler.apk.smali_normalization import categorize_opcode
        assert categorize_opcode("nop") == "OTHER"


class TestNormalizeInstruction:
    """Tests for single instruction normalization at various levels."""

    def test_category_level(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        assert normalize_instruction("add-int v0, v1, v2", "category") == "ALU"
        assert normalize_instruction("invoke-virtual {p0}, Lcom/Foo;->bar()V", "category") == "CALL"
        assert normalize_instruction("return-void", "category") == "RET"

    def test_opcode_level_strips_width(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        # Width variants collapse to same base
        assert normalize_instruction("add-int v0, v1, v2", "opcode") == "add"
        assert normalize_instruction("add-long v0, v2, v4", "opcode") == "add"
        assert normalize_instruction("add-float v0, v1, v2", "opcode") == "add"
        # Addressing modes collapse too
        assert normalize_instruction("add-int/2addr v0, v1", "opcode") == "add"

    def test_opcode_api_invoke(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            "invoke-virtual {p0, v0}, Lcom/example/Foo;->bar(I)V"
        )
        assert result == "CALL Lcom/example/Foo;->bar(I)V"

    def test_opcode_api_invoke_no_ref(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        # If somehow no method ref is found, fallback to CALL
        assert normalize_instruction("invoke-virtual {v0}") == "CALL"

    def test_opcode_api_field_load(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            "iget-object v0, p0, Lcom/Foo;->mField:Ljava/lang/String;"
        )
        assert result == "LOAD Lcom/Foo;->mField:Ljava/lang/String;"

    def test_opcode_api_field_store(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            "iput-object v0, p0, Lcom/Foo;->mField:Ljava/lang/String;"
        )
        assert result == "STORE Lcom/Foo;->mField:Ljava/lang/String;"

    def test_opcode_api_androguard_field_format(self):
        """androguard uses space instead of colon in field references."""
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            "iget-object v0, p0, Lcom/Foo;->mField Ljava/lang/String;"
        )
        assert result.startswith("LOAD")
        assert "Lcom/Foo;->mField" in result

    def test_opcode_api_new_instance(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            "new-instance v0, Lcom/example/MyClass;"
        )
        assert result == "ALLOC Lcom/example/MyClass;"

    def test_opcode_api_const_string(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            'const-string v0, "hello world"'
        )
        assert result == 'CONST_STR "hello world"'

    def test_opcode_api_const_string_jumbo(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        result = normalize_instruction(
            'const-string/jumbo v0, "large string"'
        )
        assert result == 'CONST_STR "large string"'

    def test_opcode_api_fallback_to_category(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        # Non-special instructions fall back to category
        assert normalize_instruction("add-int v0, v1, v2") == "ALU"
        assert normalize_instruction("return-void") == "RET"
        assert normalize_instruction("nop") == "OTHER"

    def test_empty_input(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_instruction
        assert normalize_instruction("") == ""
        assert normalize_instruction("   ") == ""


class TestNormalizeMethodBody:
    """Tests for full method body normalization."""

    def test_filters_directives_labels_comments(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_method_body
        body = """\
.locals 2
# comment
:label_0
add-int v0, v1, v2
.line 42
invoke-virtual {p0}, Lcom/Foo;->bar()V
return-void
"""
        result = normalize_method_body(body, "category")
        assert result == ["ALU", "CALL", "RET"]

    def test_opcode_api_preserves_api_refs(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_method_body
        body = """\
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/Foo;->setX(I)V
iget-object v1, p0, Lcom/Foo;->name:Ljava/lang/String;
return-void
"""
        result = normalize_method_body(body, "opcode_api")
        assert result[0] == "CONST"
        assert result[1] == "CALL Lcom/Foo;->setX(I)V"
        assert result[2] == "LOAD Lcom/Foo;->name:Ljava/lang/String;"
        assert result[3] == "RET"

    def test_empty_body(self):
        from redb.extractors.decompiler.apk.smali_normalization import normalize_method_body
        assert normalize_method_body("") == []
        assert normalize_method_body("\n\n") == []


class TestNormalizationWithMinHash:
    """Integration tests: normalization + MinHash computation."""

    def test_minhash_returns_signature(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_minhash
        body = """\
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/Foo;->bar(I)V
iget-object v1, p0, Lcom/Foo;->name:Ljava/lang/String;
add-int v2, v0, v1
return-void
"""
        sig = compute_minhash(body)
        assert sig is not None
        assert len(sig) == 64
        assert all(0 <= v < 256 for v in sig)

    def test_minhash_register_invariance(self):
        """Same operations with different registers should produce identical signatures."""
        from redb.extractors.decompiler.apk.method_extractor import compute_minhash
        body_a = """\
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/Foo;->bar(I)V
iget-object v1, p0, Lcom/Foo;->name:Ljava/lang/String;
add-int v2, v0, v1
return-void
"""
        body_b = """\
const/4 v3, 0x0
invoke-virtual {p1, v3}, Lcom/Foo;->bar(I)V
iget-object v4, p1, Lcom/Foo;->name:Ljava/lang/String;
add-int v5, v3, v4
return-void
"""
        sig_a = compute_minhash(body_a)
        sig_b = compute_minhash(body_b)
        assert sig_a == sig_b

    def test_minhash_width_invariance(self):
        """Width variants of same operations should produce identical signatures."""
        from redb.extractors.decompiler.apk.method_extractor import compute_minhash
        body_int = """\
add-int v0, v1, v2
sub-int v3, v0, v1
mul-int v4, v0, v3
return v4
"""
        body_long = """\
add-long v0, v2, v4
sub-long v6, v0, v2
mul-long v8, v0, v6
return-wide v8
"""
        sig_int = compute_minhash(body_int)
        sig_long = compute_minhash(body_long)
        # Both normalize to ALU, ALU, ALU, RET -> identical
        assert sig_int == sig_long

    def test_minhash_different_apis_differ(self):
        """Methods calling different APIs should produce different signatures."""
        from redb.extractors.decompiler.apk.method_extractor import compute_minhash
        body_a = """\
const/4 v0, 0x0
invoke-virtual {p0, v0}, Lcom/crypto/AES;->encrypt([B)[B
invoke-virtual {v0}, Ljava/io/OutputStream;->write([B)V
return-void
"""
        body_b = """\
const/4 v0, 0x0
invoke-virtual {p0, v0}, Ljava/lang/String;->length()I
invoke-virtual {v0}, Ljava/io/PrintStream;->println(I)V
return-void
"""
        sig_a = compute_minhash(body_a)
        sig_b = compute_minhash(body_b)
        assert sig_a != sig_b

    def test_minhash_too_few_instructions(self):
        from redb.extractors.decompiler.apk.method_extractor import compute_minhash
        assert compute_minhash("return-void\nnop") is None


class TestACFGBlockFeatures:
    """Tests for per-block ACFG feature extraction via smali_cfg."""

    def test_simple_linear_method(self):
        from redb.extractors.decompiler.apk.smali_cfg import compute_cfg_metrics
        body = """\
add-int v0, v1, v2
invoke-virtual {p0}, Lcom/Foo;->bar()V
return-void
"""
        metrics = compute_cfg_metrics(body)
        assert metrics.block_count >= 1
        assert len(metrics.block_features) == metrics.block_count
        # Each feature vector has 8 elements
        for feat in metrics.block_features:
            assert len(feat) == 8

    def test_branching_method_has_multiple_blocks(self):
        from redb.extractors.decompiler.apk.smali_cfg import compute_cfg_metrics
        body = """\
const/4 v0, 0x0
if-eqz v0, :cond_0
invoke-virtual {p0}, Lcom/Foo;->a()V
goto :goto_0
:cond_0
invoke-virtual {p0}, Lcom/Foo;->b()V
:goto_0
return-void
"""
        metrics = compute_cfg_metrics(body)
        assert metrics.block_count >= 3
        assert len(metrics.block_features) == metrics.block_count

    def test_feature_vector_arithmetic_count(self):
        from redb.extractors.decompiler.apk.smali_cfg import compute_cfg_metrics
        body = """\
add-int v0, v1, v2
sub-int v3, v0, v1
mul-int v4, v0, v3
return v4
"""
        metrics = compute_cfg_metrics(body)
        assert len(metrics.block_features) == 1
        feat = metrics.block_features[0]
        # feat[0] = instr_count (4), feat[1] = arithmetic (3)
        assert feat[0] == 4
        assert feat[1] >= 3  # 3 ALU ops

    def test_feature_vector_call_count(self):
        from redb.extractors.decompiler.apk.smali_cfg import compute_cfg_metrics
        body = """\
invoke-virtual {p0}, Lcom/A;->a()V
invoke-static {v0}, Lcom/B;->b()V
return-void
"""
        metrics = compute_cfg_metrics(body)
        feat = metrics.block_features[0]
        # feat[4] = call count
        assert feat[4] == 2