reproto 0.0.7__py3-none-any.whl → 0.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- .git/COMMIT_EDITMSG +11 -26
- .git/FETCH_HEAD +2 -0
- .git/index +0 -0
- .git/logs/HEAD +6 -0
- .git/logs/refs/heads/iyue +6 -0
- .git/logs/refs/remotes/gitlab/iyue +6 -0
- .git/logs/refs/remotes/origin/iyue +6 -0
- .git/objects/15/eb3f02479e633439ec83c143e703f8448043a1 +0 -0
- .git/objects/26/1f67f3b731b32f6d77de9dd7be2d61e2a14ace +0 -0
- .git/objects/29/4708b82b343e04e7a6685f5cd1287f3d17f7a9 +0 -0
- .git/objects/2c/fcddd7eebeb4eee0562dc384a79366bc7b04bb +0 -0
- .git/objects/2e/2c1c42f5ac5d665cc672d3792078b756d9ab0e +0 -0
- .git/objects/34/192f0df5f5b694c881d086019eda349608d222 +0 -0
- .git/objects/35/8bace20b731ff1bbb256d2a0158dfc84720978 +0 -0
- .git/objects/3e/d953d5ed2c66722045f5e39d068696a0853b4f +0 -0
- .git/objects/44/4af3a0d68ba81976f67c7b638c9b0db4640709 +0 -0
- .git/objects/4b/43f5f577e1cdc35f8e06d178d8f5c892034061 +0 -0
- .git/objects/4c/16984be6ef7b24d01604821e9728cb579acd69 +0 -0
- .git/objects/4d/6d457bfabc4af842e5ddc2d56eb059d5dfdc9d +0 -0
- .git/objects/55/6723fdd4f525eed41c52fa80defca3f0c81c47 +0 -0
- .git/objects/56/79064a3138031d3a92d60aa629b82009fd0d1d +0 -0
- .git/objects/58/0d8f872aa869e42ba608f64888b1349f8b3ff4 +0 -0
- .git/objects/5a/11f9d70791e06a0570e01d3dcbbae39cde55db +0 -0
- .git/objects/5c/715dcb05e32db7a7a3b030f07524bdd8a56849 +0 -0
- .git/objects/5d/e2e9d536c2c0b78e8f9b3b61daa531a55332dc +0 -0
- .git/objects/65/a4f0ada7519f8b1e6a7c7e287541b8effde9fd +0 -0
- .git/objects/66/7291e131d4769e7d028346a0cc7a0c05d500e5 +0 -0
- .git/objects/67/f54a4a3ede6749acc7c718ad97a86634215b5e +0 -0
- .git/objects/70/ded03ee69f30850c938a8129be308cb30772d9 +0 -0
- .git/objects/78/3e7e252c20e73e33615c703174766036546ff6 +3 -0
- .git/objects/8d/44142ae2d6dbb59d4ebed8587bccd051e5766b +0 -0
- .git/objects/8d/4a5767bef0c342f1660526f9671c0944922c40 +0 -0
- .git/objects/94/ce01b61b90d1fb21d2d339fbeb22e821b6f413 +0 -0
- .git/objects/95/295a15779ebefd563ec777c3d3cced7e8d0209 +0 -0
- .git/objects/97/71dd4958faa94d3db229c129f6af35b508905a +0 -0
- .git/objects/9e/9978522bc8ca79133d7c11ef8ca3fe3c7eed0a +0 -0
- .git/objects/9f/b57064e0c53ed80af8507acaab718a1e80184e +0 -0
- .git/objects/b3/28dc445ee33220db9359370fc0089a77174101 +0 -0
- .git/objects/b3/d2b3037bede44e7e4d18dc99419f8c712c9c62 +0 -0
- .git/objects/c3/93db4841dbbb8acf54e9af12b6705c9f5ecde9 +0 -0
- .git/objects/c3/c8594874dd9ff9c21662fd06cac9b5baadbba0 +0 -0
- .git/objects/c9/a6ca8f8efee4a5632e9a655ced29f1b708f35e +0 -0
- .git/objects/c9/cdef9ab627b874ffe6455a47583a75bf16496d +0 -0
- .git/objects/db/beedb30613f79ae3ff67df1428cf8ade223711 +0 -0
- .git/objects/df/f8f64cee2b97df7d86f73207c5e690f98f0208 +0 -0
- .git/objects/eb/528f06c622d54e411e9e05b3a200b4ac624a90 +0 -0
- .git/objects/fc/e15b9dbffd9f37b1f2d46944ee2d0394df6565 +2 -0
- .git/objects/fd/267d9de63212db235135fa6834f62572224fc6 +0 -0
- .git/refs/heads/iyue +1 -1
- .git/refs/remotes/gitlab/iyue +1 -1
- .git/refs/remotes/origin/iyue +1 -1
- .gitignore +4 -1
- ARCHITECTURE.md +146 -48
- README.md +145 -24
- core/bytecode_parser.py +2 -5
- core/info_decoder.py +9 -83
- core/reconstructor.py +122 -200
- generation/proto_generator.py +19 -68
- parsing/java_parser.py +219 -46
- pyproject.toml +1 -1
- reproto-0.0.9.dist-info/METADATA +295 -0
- reproto-0.0.9.dist-info/RECORD +132 -0
- utils/file_cache.py +165 -0
- utils/type_index.py +341 -0
- utils/type_utils.py +414 -0
- reproto-0.0.7.dist-info/METADATA +0 -174
- reproto-0.0.7.dist-info/RECORD +0 -87
- {reproto-0.0.7.dist-info → reproto-0.0.9.dist-info}/WHEEL +0 -0
- {reproto-0.0.7.dist-info → reproto-0.0.9.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,132 @@
|
|
1
|
+
.git/COMMIT_EDITMSG,sha256=f7YiPfJff1yNgjPRfmD8mYTljSiz5aQvEIfwH3TqtCc,683
|
2
|
+
.git/FETCH_HEAD,sha256=1W_vttZCTHf9DXnCOhWjilD3kVx9WT2Xu85YBetV3ok,191
|
3
|
+
.git/HEAD,sha256=ly8yuQLWQE8njkYAapHLPJ1xVg6_fMgQjCoHqKvFIdw,21
|
4
|
+
.git/config,sha256=9ZAySfDWBdI-K9eOXyrEQOhiX68AiaP0Z4CLzH07H10,399
|
5
|
+
.git/description,sha256=hatsFj1DoX6pz3eIMIvKFGbxsKjRzJLibpv2PaQGKu4,73
|
6
|
+
.git/hooks/applypatch-msg.sample,sha256=AiNJeguLAzqlijpSG4YphpOGz3qw4vEBlj0yiqYhk_c,478
|
7
|
+
.git/hooks/commit-msg.sample,sha256=H3TV6SkpebVz69WXQdRsuT_zkazdCD00C5Q3B1PZJDc,896
|
8
|
+
.git/hooks/fsmonitor-watchman.sample,sha256=4FSZZOk4l7UZvY4zPAN-Uf_w-IuhPghqMxWSv4AfodA,4726
|
9
|
+
.git/hooks/post-update.sample,sha256=gXZa8trvMjBh3LxeYfwWSBy3SzusmtihdLGGUjWG9sU,189
|
10
|
+
.git/hooks/pre-applypatch.sample,sha256=4VxbRp6j4KaVvqbyyCvPjmKCEHSTnd2Ft34AB_8WVHU,424
|
11
|
+
.git/hooks/pre-commit.sample,sha256=Vxhbe58FI516tS2wRfW4nrMTSNeyF36rIU9euHLhlxs,1649
|
12
|
+
.git/hooks/pre-merge-commit.sample,sha256=04JacDN5QOu9ClwHKYThMkWSDN-ImL0iXI0npt_Jy1M,416
|
13
|
+
.git/hooks/pre-push.sample,sha256=7M6cfgTT9d2ditqBdT3R1UmpY0smdwBCtY3aACF9CGo,1374
|
14
|
+
.git/hooks/pre-rebase.sample,sha256=T-vOhneQBSM4B29OZsxH77FIedGAl9HWHIJhhZ6qp7M,4898
|
15
|
+
.git/hooks/pre-receive.sample,sha256=pMPSuce7P9jRRBwxvU7nGlldZrRPz0ndsxAlIyAWmYk,544
|
16
|
+
.git/hooks/prepare-commit-msg.sample,sha256=6d3KpBif3dJe2X_Ix4nsp7bKFjkLI5KuMnbwyOGqRhk,1492
|
17
|
+
.git/hooks/push-to-checkout.sample,sha256=pT0HQXmLKHxt16-mSu5HPzBeZdP0lGO7nXQI7DsSv18,2783
|
18
|
+
.git/hooks/sendemail-validate.sample,sha256=ROv8kj3FRmvACWAvDs8Ge5xlRZq_6IaN3Em3jmztepI,2308
|
19
|
+
.git/hooks/update.sample,sha256=jV8vqD4QPPCLV-qmdSHfkZT0XL28s32lKtWGCXoU0QY,3650
|
20
|
+
.git/index,sha256=H3N6fAu_qEXal8X0k_4Zioz9AUDGeBtlnCGJsmnn-Ak,2255
|
21
|
+
.git/info/exclude,sha256=ZnH-g7egfIky7okWTR8nk7IxgFjri5jcXAbuClo7DsE,240
|
22
|
+
.git/logs/HEAD,sha256=Zy6alEsv_L04s2VP7Gxm3YDVCLNe5MtHabDIeCZlGj4,1827
|
23
|
+
.git/logs/refs/heads/iyue,sha256=Zy6alEsv_L04s2VP7Gxm3YDVCLNe5MtHabDIeCZlGj4,1827
|
24
|
+
.git/logs/refs/remotes/gitlab/iyue,sha256=s-5DlIRcdV81dLF6FzRwj1JDOnGI0myIxAfKWE88otw,1224
|
25
|
+
.git/logs/refs/remotes/origin/HEAD,sha256=4vCPTgC0N80jhmkFXNUlYvHtGllYJkQTGZEn6LlqZgs,163
|
26
|
+
.git/logs/refs/remotes/origin/iyue,sha256=6kHIydv6sCMdRdbla-7hwUsIRfmU2VIM2ScTZtgwopk,1224
|
27
|
+
.git/objects/09/a92517fe9eeb33d2fd7c979e01d163665f7abc,sha256=wyFL5jJ16f0xCpL1MB5EiJvs2opieE0hMEmyDpUV3ps,9356
|
28
|
+
.git/objects/14/d323d58fb90c209a730c17e23fd82a6c735fc1,sha256=rTCuhPM5LYusLIMDv7CLC557SlRFvvbBzgr4jwrjMVg,426
|
29
|
+
.git/objects/15/eb3f02479e633439ec83c143e703f8448043a1,sha256=duJXtvq_NNhYKG7WdejXgoMlyHIaCUG5jv9SJpU_orc,14711
|
30
|
+
.git/objects/18/89a4fb55eb3abdc528ce87f0cea039278c06fd,sha256=Uz8TPtDNnPWR5pfsIx7tMDCDFBdWLIkaPcnYPIJ12oM,2880
|
31
|
+
.git/objects/20/cf56ec106bcd66420dd000279f983571b918b6,sha256=0dwZwG7CpR7yYYNvgYDxHLPj2P7eRLK7fTW_En419pk,166
|
32
|
+
.git/objects/21/55b64d52922c88527c102d62f23e5c2abbae79,sha256=6LLW2HrSfqqVwvO59yc-EcUp6MHw6zfHwu8TB775dII,13853
|
33
|
+
.git/objects/23/bfbca38e177bcbb423dd782c35b19d127a5ab0,sha256=hYW2b3t3bVGNh4pqyyA7DMlyF4LfNZco5NwedWMwwuI,3700
|
34
|
+
.git/objects/26/1f67f3b731b32f6d77de9dd7be2d61e2a14ace,sha256=mcasCBpCulVy2N-X_d2hg8567PdhZRof4ea5nYoelJM,96
|
35
|
+
.git/objects/29/4708b82b343e04e7a6685f5cd1287f3d17f7a9,sha256=YE3F4zucGeMHEw7bTEvQc0uJEUUCfEgw-mZTWupuNhA,96
|
36
|
+
.git/objects/2c/fcddd7eebeb4eee0562dc384a79366bc7b04bb,sha256=FHxE2giqoo-1IB9Q8i_XQUypGvQbRlRnTK0sbsNDcJE,96
|
37
|
+
.git/objects/2e/2c1c42f5ac5d665cc672d3792078b756d9ab0e,sha256=5LG3jHGORJeswNw0lz5dc6QSsxztyMstbRDADhZDnZY,166
|
38
|
+
.git/objects/33/181441ab38eded005db356da89b54c7d29f452,sha256=iIM6a2aGs_TGZjxHKnkYYyZj_hA77nAF7r2lMOtN1VA,2021
|
39
|
+
.git/objects/33/52dfa8f5d9eb46cc98ea7ccecf02e4d9df95f7,sha256=KNAvQNdSalt8CxCZVVb8e6KBC4zqVtusT5MriFLPbIQ,4409
|
40
|
+
.git/objects/34/192f0df5f5b694c881d086019eda349608d222,sha256=zcWIY4oDFz6n17MRjbwFrN1o-HEY0--gqK96dohmZfE,4901
|
41
|
+
.git/objects/35/8bace20b731ff1bbb256d2a0158dfc84720978,sha256=hEPGT0bRzT1GlXErWRWJ7ogflTWj3SutlHRKCBH1TII,426
|
42
|
+
.git/objects/3c/6f0120229cc2cd8123efbeb7f186eb0a485f29,sha256=iyh7Xt-m7vou3slm58k8xSl3Cn2yYXTuv5WziSWHrW0,802
|
43
|
+
.git/objects/3e/d953d5ed2c66722045f5e39d068696a0853b4f,sha256=GelU4l-EVo8Y5rXSksIEnewIasEr9N54pTJcgrY3VVk,166
|
44
|
+
.git/objects/40/84f4567d983a977c49598b7d886e46b13ff50b,sha256=R3w6EvxpJRcVuJvbCslrGDK07kcOjECGGosj5tO-JBo,426
|
45
|
+
.git/objects/44/4af3a0d68ba81976f67c7b638c9b0db4640709,sha256=s__MvPzT4Ndsip8kgkfMh-Y0oZ28tv2kVqaz_ExQKvU,166
|
46
|
+
.git/objects/48/369b05749e384be9be58e5f943f3a0040d0f37,sha256=KP9dXx-XniZuIEXESlrL_MWWi55zGiFr7xtmp3oD67o,8551
|
47
|
+
.git/objects/4b/43f5f577e1cdc35f8e06d178d8f5c892034061,sha256=eawBjiWutNeKjIzvNonVMMKUVsz_-jn3Uew_NsKQJ-I,1150
|
48
|
+
.git/objects/4c/16984be6ef7b24d01604821e9728cb579acd69,sha256=sy5h3rBsk0JcPlpA7L0WhJESaYjNZnTvrB1F1CRPSJQ,167
|
49
|
+
.git/objects/4d/6d457bfabc4af842e5ddc2d56eb059d5dfdc9d,sha256=HLQ8aGvln8ZuhdINhhbr_aTt2BttkJOY8k6LhciAMLE,672
|
50
|
+
.git/objects/55/6723fdd4f525eed41c52fa80defca3f0c81c47,sha256=vwGNz5lxU_wrrRWVPU64TccYo4Vo4uUGC3-GwVIs1xs,4520
|
51
|
+
.git/objects/56/79064a3138031d3a92d60aa629b82009fd0d1d,sha256=4pQvc0ulzTZ9RQEVr5yy37dV-uhP1VU58UyKcCugHHw,426
|
52
|
+
.git/objects/58/0d8f872aa869e42ba608f64888b1349f8b3ff4,sha256=sag83Y6gsy8I31WmM2lVeBM-AYKgo5su3H97fuDOj14,13984
|
53
|
+
.git/objects/5a/11f9d70791e06a0570e01d3dcbbae39cde55db,sha256=wjd8hb5D03icknLFsPqMas6xAFfG30_Wg-PJJH03ezg,13722
|
54
|
+
.git/objects/5c/715dcb05e32db7a7a3b030f07524bdd8a56849,sha256=wLXhy_1PP8n3Gd6NsvY1eFlK1pjkIjW35im_BD-0yMU,426
|
55
|
+
.git/objects/5d/e2e9d536c2c0b78e8f9b3b61daa531a55332dc,sha256=Wiyz9xFF5A95FEnxZULmV9TSJf0-erTb_qIhLFIvmag,6558
|
56
|
+
.git/objects/65/a4f0ada7519f8b1e6a7c7e287541b8effde9fd,sha256=jSGkVjAMcm2nrF6w_0U7lmzoBgwIJaf4P8POOlABxEQ,188
|
57
|
+
.git/objects/66/7291e131d4769e7d028346a0cc7a0c05d500e5,sha256=3D6kzCQW7DkYuwARYA74Tlfzeaiaob9ux4YE6hYohas,4026
|
58
|
+
.git/objects/67/f54a4a3ede6749acc7c718ad97a86634215b5e,sha256=n0_tiP-u_DP9uhXCryaz98mNJYcUX8RYiS48FvxIxCA,744
|
59
|
+
.git/objects/70/ded03ee69f30850c938a8129be308cb30772d9,sha256=d_DDP1Jj_KnSDtbZRKOomzOvV9ySvlaiapwSEXhO0DE,1012
|
60
|
+
.git/objects/76/311aa8e59d780763e0d66787067cc5d9613a67,sha256=J9Xy8ESXbWUbC_4sA0KumGVKm09tzlqA8C5oJ63a_b4,2167
|
61
|
+
.git/objects/78/3e7e252c20e73e33615c703174766036546ff6,sha256=cQ-PXyvzEYjb2Lr24anO9aGui5IxBxZCYXL6zZRc0xc,810
|
62
|
+
.git/objects/7c/00eec7ae9ef5f94fc337e5c8f9793a2a48810d,sha256=Ju-Yuy5EARcIThU4vkHrZuHQWu3MjXSZYGtBDTWR18c,96
|
63
|
+
.git/objects/8c/809c42c7ae13007fd885ee7bcffae7acf2c520,sha256=HYoU3_cZUGur3rWrgRvzHRAv0JfrXgc34R8UeGbC5Bc,14180
|
64
|
+
.git/objects/8d/44142ae2d6dbb59d4ebed8587bccd051e5766b,sha256=l1G5ZzQBQW8Lxd3WvGLRcY6quM6dBL4zdNT5ovjv3Dc,802
|
65
|
+
.git/objects/8d/4a5767bef0c342f1660526f9671c0944922c40,sha256=kP0nfEnyNmuEJ4wLQabhPPx60OIa5Dxqn7R9Ni89CqY,1900
|
66
|
+
.git/objects/94/ce01b61b90d1fb21d2d339fbeb22e821b6f413,sha256=oSSA97T7TGnstzHDjUrdwzwZO4d1qIUyjo6lz_EbNbM,122
|
67
|
+
.git/objects/95/295a15779ebefd563ec777c3d3cced7e8d0209,sha256=IIN8_K0K-3LAkUI4Ra3DS8yUsfpsqteSDGhgvRpSfZ4,426
|
68
|
+
.git/objects/97/56fe0931216a7c40cbf250e1ab8a6dfd589f13,sha256=Su7Q-bXO0K9QKEGC249NVuUS62xmQs5TgWfEmdbauaI,97
|
69
|
+
.git/objects/97/71dd4958faa94d3db229c129f6af35b508905a,sha256=Tc_ZkUqvJ4rk0QG5Bvwkp4DkMM9DlsmjdMIyDaO1S2k,756
|
70
|
+
.git/objects/9a/e313cdf64cd82416c1238eb493e6396f799f12,sha256=9bPRhebwMVqtGqJUxfVq-TEUxceuOdSvicWe1H8F7Ks,876
|
71
|
+
.git/objects/9e/9978522bc8ca79133d7c11ef8ca3fe3c7eed0a,sha256=FkHx7Pp6DCZ5e4bRo2RjRU875YBgl9tEw7Z_9Rii8cE,13109
|
72
|
+
.git/objects/9f/b57064e0c53ed80af8507acaab718a1e80184e,sha256=DGx0Ie-bppvghrmiV5w7mn24c6YlvHvYLIQsm-_jzsQ,635
|
73
|
+
.git/objects/a3/cedc28e563a1845a7860161b39b0fe58d5f0d3,sha256=Vee0H8dhSj4ERNDSAnRU6vebs0tbY1-lgYr1Nz5X7bc,122
|
74
|
+
.git/objects/a5/b7e4e1b63bfb65288f6553687aaabcfb4d51b1,sha256=9tl9xb48EdvQk9GIg6mEzXSwqUgD6yEVZx-sVxaQVKw,1064
|
75
|
+
.git/objects/b3/28dc445ee33220db9359370fc0089a77174101,sha256=cipG_34_tKM5VPfYW2wRCmBYOqlmTBIUjakeph9sfl4,3652
|
76
|
+
.git/objects/b3/d2b3037bede44e7e4d18dc99419f8c712c9c62,sha256=OIWo7wvTTKYZkYkxcZrOtnvfqgGlPezaE6sglITaF_Y,1156
|
77
|
+
.git/objects/c3/93db4841dbbb8acf54e9af12b6705c9f5ecde9,sha256=g36XyKIObniMsMBcIzsoG7f82SzOgn_Bdx-V9Rezjbg,3864
|
78
|
+
.git/objects/c3/c8594874dd9ff9c21662fd06cac9b5baadbba0,sha256=5YUWDZ-BMZvyOJksaoiKeZC0N-eRcOJemLb_jNUHcC4,14309
|
79
|
+
.git/objects/c9/a6ca8f8efee4a5632e9a655ced29f1b708f35e,sha256=IOmxZbePi1cWHt2HzdDNtWy0SYR2XvigDkGK2fyNbWU,4957
|
80
|
+
.git/objects/c9/cdef9ab627b874ffe6455a47583a75bf16496d,sha256=7y908SUa7dmWJyNXDKS_tOdrcfmI6OjZc7zvtL38M5Y,428
|
81
|
+
.git/objects/cd/2d6c229438c6b1c694b9392a85888d89ef49c1,sha256=IW9iGk3Eb-i_Ht64HQcltVp27ziQHz5IP6k5p57YFtY,122
|
82
|
+
.git/objects/d0/9c84ad2142a187bf26a1714b7041b62e404c8f,sha256=twhhaZbfU_mgu5LIlt9ZeGjp_PT_gri_9H231H5nrNc,2172
|
83
|
+
.git/objects/d9/6d7456245232b3e159dcf691f11e51224c557a,sha256=3w45hxiT2rn6ljSdgo36fHMMWZt30r5C1FPvbnjq9tc,597
|
84
|
+
.git/objects/db/beedb30613f79ae3ff67df1428cf8ade223711,sha256=tTGayiwSvdy-uBiXQKRhNnToZ_dc1BmeXZ2mltuRfxY,3812
|
85
|
+
.git/objects/df/f8f64cee2b97df7d86f73207c5e690f98f0208,sha256=eRT2hUSKxaIPfQVnE9NaRGxbAvBVCSreSOGzVGtd7As,213
|
86
|
+
.git/objects/e8/1433b6ad92206cdadbee1f474b4f99383314cb,sha256=mRMdmx6wCs6b-63QL72Iutm2AUVCOIYs7J5XbAsLluc,426
|
87
|
+
.git/objects/e8/2f42ea26b8bf4f0bc92c0648ac8f190f14226d,sha256=xtbEwloZnqXdNdViAevzyprosfPQ1P--xAu6URGlaYI,155
|
88
|
+
.git/objects/e9/a15996cb55ac72aeb6611d26e8d22246589943,sha256=sTn6X3xMp3_WYpj1CmP2hDqviX86aJHTCzzi_ZTpBKw,4643
|
89
|
+
.git/objects/eb/528f06c622d54e411e9e05b3a200b4ac624a90,sha256=i9b0c6j5KYuoPAR_-5923QJwBZM2_aq2Y-CElPjRT0M,4596
|
90
|
+
.git/objects/ed/fb5bbf938de738d1f658f80e23c675bb8b3fae,sha256=MOYiuXKTxnd9YcqU3-HUVUq2g9fPU1-AKZOQ-3xsWCk,4237
|
91
|
+
.git/objects/ef/4844af55f7f64b8dd24b81b5a8322a8c80208e,sha256=hO8yllVMOtIE4HeOvwKSqQUByH6lvaA4L-RYrSU4vlg,167
|
92
|
+
.git/objects/f2/2bfffda9fb6a7f37bed04b7c40c9466ef09454,sha256=goQNyEV3NqzS28mMXuus1SWzwb8yXnvEPef14Ugzh5Q,750
|
93
|
+
.git/objects/f5/18c69a6e1bf3052b79da01502b2837ea58f0f4,sha256=r98SFbCvw7yeAYTjzkw-2VMhOVbpm79FLZQiC5A1-pw,123
|
94
|
+
.git/objects/f7/25a430eb3364460ba854dbc8809edc21dc6c70,sha256=LdyMmAWGLWbn5G5fC7eAPi4NFOboKcJ6iJJdxENSUCk,2505
|
95
|
+
.git/objects/fc/e15b9dbffd9f37b1f2d46944ee2d0394df6565,sha256=81qdzKkVZ5C_1oej2Mm0q2RLifilVFolIs95mrUfpg4,163
|
96
|
+
.git/objects/fd/267d9de63212db235135fa6834f62572224fc6,sha256=vzhjdZvcXQ8Fgja_XwvbBkuLuRhzSYf_3mckDyZEoso,426
|
97
|
+
.git/objects/pack/pack-289f7bb06603881c49190e6036de6390223baf77.idx,sha256=KRv1SBEe9bYL9d5V301LwPOBqFs3tMnB0dl4PriMMIw,2416
|
98
|
+
.git/objects/pack/pack-289f7bb06603881c49190e6036de6390223baf77.pack,sha256=R4oMXhr-NcPAUBXStCbAaUvGUDW_SBECmPIbiB9Gy48,42003
|
99
|
+
.git/objects/pack/pack-289f7bb06603881c49190e6036de6390223baf77.rev,sha256=22_3sqyTNB5IbwAK5oCqNz0UxDDqoZ5jcF7p_44Lalo,244
|
100
|
+
.git/packed-refs,sha256=4H0m4wd6q98wZkBk7WfvVeTBuuxQdTE65XxsswYP-oQ,112
|
101
|
+
.git/refs/heads/iyue,sha256=eBmizaWpaeQ5r12COERLFcpVj3j7zd_ks0CYMmwWY_A,41
|
102
|
+
.git/refs/remotes/gitlab/iyue,sha256=eBmizaWpaeQ5r12COERLFcpVj3j7zd_ks0CYMmwWY_A,41
|
103
|
+
.git/refs/remotes/origin/HEAD,sha256=G8pFPTbCqnJ2IkCzz9J-STqOXWU6TrlXfpt1wx5bUWE,30
|
104
|
+
.git/refs/remotes/origin/iyue,sha256=eBmizaWpaeQ5r12COERLFcpVj3j7zd_ks0CYMmwWY_A,41
|
105
|
+
.gitignore,sha256=7KBWk3hOUkvfJh1A-RNk5jHepGKp71qPlktu8nyEptI,2085
|
106
|
+
.python-version,sha256=NxOs_9lT1XG8y-FjlRru-YinX5RcBJt_ulPwgDESZ_o,7
|
107
|
+
ARCHITECTURE.md,sha256=HiUhP4wGzy4lD01MpHjOgAhuAUwpNsEac3tZaE65kos,12047
|
108
|
+
README.md,sha256=khO65a7VGeyjyUxxXpu1W_EosoPLzJyWCol6jDVzw9k,8484
|
109
|
+
core/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
|
110
|
+
core/bytecode_parser.py,sha256=bv01quLoLeKHjswLU86g4w3MeZR9uh7WIJsnV2sGE2g,11399
|
111
|
+
core/info_decoder.py,sha256=xHLAVJfGsziNPO52-1DOr3TBqbab-sbkx0g7NAzjSwc,49807
|
112
|
+
core/reconstructor.py,sha256=rnsIVwktSBbVywAdL1fHAK8JkoaW9dmCzhMYb5mKAqQ,48686
|
113
|
+
generation/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
|
114
|
+
generation/proto_generator.py,sha256=yTU8yXEZ6F0L2eOZXl0iTsgBBxkRl1feWVozrKMTvko,15734
|
115
|
+
main.py,sha256=3G649-aTByEjMS4tb1A9wcO9NVUxXVSvdwGTq9hXxBI,7081
|
116
|
+
models/__init__.py,sha256=WScv63rvEl65y5CWjpb6__hvjNvjpCkl6lz1Z2u0IYc,811
|
117
|
+
models/message_definition.py,sha256=AszUZnNPSBn9SMXne5ORDBiGZz1W2pcYmU8ftGC3Mks,4873
|
118
|
+
parsing/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
|
119
|
+
parsing/enum_parser.py,sha256=4BjMk1NIYgt2FDZUjTZyOvFfC1uJp_MBZipVdk1tqes,6175
|
120
|
+
parsing/java_parser.py,sha256=C8-D_nww1C8dlnCmO6Apz9XsF0LfvsTTWIMPjN52Zyw,21756
|
121
|
+
pyproject.toml,sha256=qJOeZq3nba897lkksyVBYDKCCOrQIWOz7WHfLaOxwlE,1378
|
122
|
+
requirements.txt,sha256=cQGj3IS6Kj88jbwj_jeKkokMnG-fEezWve91mfW4CJs,96
|
123
|
+
utils/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
|
124
|
+
utils/file_cache.py,sha256=eOBkfrumWg0EU1EfLESnRN1kcidi_MocxV_EWP8lEhQ,5207
|
125
|
+
utils/file_utils.py,sha256=N1Ei7hmyeOkIyZJFEXyNbtTrfeVF2hP-U8evXAVW2MA,4085
|
126
|
+
utils/logger.py,sha256=473DfzFVXzdGpiRTJGY6bBd-V5G80_P07gQqcvDChpQ,2447
|
127
|
+
utils/type_index.py,sha256=So8FYyGtR0ff-ZhVHjXUdhXiXQEujlcCEJlj7OPQMsg,12128
|
128
|
+
utils/type_utils.py,sha256=M3eB7GavxQYAVFOf3E1pO1vK9VD6_lKrutnSH1tx_Gs,14695
|
129
|
+
reproto-0.0.9.dist-info/METADATA,sha256=VT-RHjMen_58RxfPvOkmtyUFoFUJb_tlri-XjA_NULI,9433
|
130
|
+
reproto-0.0.9.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
131
|
+
reproto-0.0.9.dist-info/entry_points.txt,sha256=6Oro9lK_2DXDgHiB3andNuIE78wxfooqacqp8yY1C-g,37
|
132
|
+
reproto-0.0.9.dist-info/RECORD,,
|
utils/file_cache.py
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
"""
|
2
|
+
文件内容缓存系统
|
3
|
+
|
4
|
+
用于缓存Java源码文件内容,避免重复的文件I/O操作
|
5
|
+
这是解决reproto性能瓶颈的核心优化组件
|
6
|
+
|
7
|
+
Author: AI Assistant
|
8
|
+
"""
|
9
|
+
|
10
|
+
from pathlib import Path
|
11
|
+
from typing import Optional, Dict
|
12
|
+
import threading
|
13
|
+
from utils.logger import get_logger
|
14
|
+
|
15
|
+
|
16
|
+
class FileContentCache:
|
17
|
+
"""
|
18
|
+
文件内容缓存系统
|
19
|
+
|
20
|
+
提供线程安全的文件内容缓存,显著减少重复的文件I/O操作
|
21
|
+
特别适用于需要多次读取同一Java文件的场景
|
22
|
+
"""
|
23
|
+
|
24
|
+
def __init__(self):
|
25
|
+
"""初始化缓存系统"""
|
26
|
+
self._cache: Dict[str, str] = {}
|
27
|
+
self._stats = {
|
28
|
+
'hits': 0,
|
29
|
+
'misses': 0,
|
30
|
+
'errors': 0
|
31
|
+
}
|
32
|
+
self._lock = threading.RLock() # 使用可重入锁
|
33
|
+
self.logger = get_logger("file_cache")
|
34
|
+
|
35
|
+
def get_content(self, file_path: Path) -> Optional[str]:
|
36
|
+
"""
|
37
|
+
获取文件内容,优先从缓存读取
|
38
|
+
|
39
|
+
Args:
|
40
|
+
file_path: 文件路径
|
41
|
+
|
42
|
+
Returns:
|
43
|
+
文件内容字符串,如果读取失败则返回None
|
44
|
+
"""
|
45
|
+
cache_key = str(file_path.resolve())
|
46
|
+
|
47
|
+
with self._lock:
|
48
|
+
# 检查缓存
|
49
|
+
if cache_key in self._cache:
|
50
|
+
self._stats['hits'] += 1
|
51
|
+
return self._cache[cache_key]
|
52
|
+
|
53
|
+
# 缓存未命中,读取文件
|
54
|
+
try:
|
55
|
+
if not file_path.exists():
|
56
|
+
self._stats['errors'] += 1
|
57
|
+
return None
|
58
|
+
|
59
|
+
content = file_path.read_text(encoding='utf-8')
|
60
|
+
self._cache[cache_key] = content
|
61
|
+
self._stats['misses'] += 1
|
62
|
+
|
63
|
+
# 定期输出缓存统计
|
64
|
+
total_requests = self._stats['hits'] + self._stats['misses']
|
65
|
+
if total_requests % 50 == 0 and total_requests > 0:
|
66
|
+
hit_rate = self._stats['hits'] / total_requests * 100
|
67
|
+
self.logger.debug(f"📊 缓存统计: {total_requests} 次请求, 命中率 {hit_rate:.1f}%")
|
68
|
+
|
69
|
+
return content
|
70
|
+
|
71
|
+
except Exception as e:
|
72
|
+
self._stats['errors'] += 1
|
73
|
+
self.logger.warning(f"⚠️ 读取文件失败 {file_path}: {e}")
|
74
|
+
return None
|
75
|
+
|
76
|
+
def preload_files(self, file_paths: list[Path]) -> int:
|
77
|
+
"""
|
78
|
+
预加载文件列表到缓存
|
79
|
+
|
80
|
+
Args:
|
81
|
+
file_paths: 要预加载的文件路径列表
|
82
|
+
|
83
|
+
Returns:
|
84
|
+
成功预加载的文件数量
|
85
|
+
"""
|
86
|
+
loaded_count = 0
|
87
|
+
|
88
|
+
for file_path in file_paths:
|
89
|
+
if self.get_content(file_path) is not None:
|
90
|
+
loaded_count += 1
|
91
|
+
|
92
|
+
self.logger.info(f"📁 预加载完成: {loaded_count}/{len(file_paths)} 个文件")
|
93
|
+
return loaded_count
|
94
|
+
|
95
|
+
def clear_cache(self):
|
96
|
+
"""清空缓存"""
|
97
|
+
with self._lock:
|
98
|
+
self._cache.clear()
|
99
|
+
self.logger.info("🗑️ 缓存已清空")
|
100
|
+
|
101
|
+
def get_stats(self) -> dict:
|
102
|
+
"""
|
103
|
+
获取缓存统计信息
|
104
|
+
|
105
|
+
Returns:
|
106
|
+
包含缓存统计的字典
|
107
|
+
"""
|
108
|
+
with self._lock:
|
109
|
+
total_requests = self._stats['hits'] + self._stats['misses']
|
110
|
+
hit_rate = (self._stats['hits'] / total_requests * 100) if total_requests > 0 else 0
|
111
|
+
|
112
|
+
return {
|
113
|
+
'total_requests': total_requests,
|
114
|
+
'cache_hits': self._stats['hits'],
|
115
|
+
'cache_misses': self._stats['misses'],
|
116
|
+
'hit_rate_percent': hit_rate,
|
117
|
+
'errors': self._stats['errors'],
|
118
|
+
'cached_files': len(self._cache)
|
119
|
+
}
|
120
|
+
|
121
|
+
def print_stats(self):
|
122
|
+
"""打印缓存统计信息"""
|
123
|
+
stats = self.get_stats()
|
124
|
+
|
125
|
+
self.logger.info("📊 文件缓存统计:")
|
126
|
+
self.logger.info(f" 总请求数: {stats['total_requests']}")
|
127
|
+
self.logger.info(f" 缓存命中: {stats['cache_hits']}")
|
128
|
+
self.logger.info(f" 缓存未命中: {stats['cache_misses']}")
|
129
|
+
self.logger.info(f" 命中率: {stats['hit_rate_percent']:.1f}%")
|
130
|
+
self.logger.info(f" 错误数: {stats['errors']}")
|
131
|
+
self.logger.info(f" 已缓存文件: {stats['cached_files']}")
|
132
|
+
|
133
|
+
# 计算性能提升
|
134
|
+
if stats['cache_hits'] > 0:
|
135
|
+
io_saved = stats['cache_hits']
|
136
|
+
self.logger.info(f" 🚀 节省I/O操作: {io_saved} 次")
|
137
|
+
|
138
|
+
|
139
|
+
# 全局缓存实例
|
140
|
+
_global_cache = None
|
141
|
+
_cache_lock = threading.Lock()
|
142
|
+
|
143
|
+
|
144
|
+
def get_file_cache() -> FileContentCache:
|
145
|
+
"""
|
146
|
+
获取全局文件缓存实例(单例模式)
|
147
|
+
|
148
|
+
Returns:
|
149
|
+
FileContentCache实例
|
150
|
+
"""
|
151
|
+
global _global_cache
|
152
|
+
|
153
|
+
if _global_cache is None:
|
154
|
+
with _cache_lock:
|
155
|
+
if _global_cache is None:
|
156
|
+
_global_cache = FileContentCache()
|
157
|
+
|
158
|
+
return _global_cache
|
159
|
+
|
160
|
+
|
161
|
+
def clear_global_cache():
|
162
|
+
"""清空全局缓存"""
|
163
|
+
global _global_cache
|
164
|
+
if _global_cache is not None:
|
165
|
+
_global_cache.clear_cache()
|
utils/type_index.py
ADDED
@@ -0,0 +1,341 @@
|
|
1
|
+
"""
|
2
|
+
类型匹配索引系统
|
3
|
+
|
4
|
+
用于快速查找Java类型,避免重复的目录扫描操作
|
5
|
+
这是解决reproto性能瓶颈的第二个核心优化组件
|
6
|
+
|
7
|
+
Author: AI Assistant
|
8
|
+
"""
|
9
|
+
|
10
|
+
from pathlib import Path
|
11
|
+
from typing import Dict, List, Optional, Set
|
12
|
+
import threading
|
13
|
+
from utils.logger import get_logger
|
14
|
+
|
15
|
+
|
16
|
+
class TypeMatchingIndex:
|
17
|
+
"""
|
18
|
+
类型匹配索引系统
|
19
|
+
|
20
|
+
构建从类型名到完整类名的多级索引,支持:
|
21
|
+
- 精确匹配(完整类名)
|
22
|
+
- 简单名匹配(类名)
|
23
|
+
- 后缀匹配(如 IdData -> ContactIdData)
|
24
|
+
- 包名相似度匹配
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(self, sources_dir: Path):
|
28
|
+
"""
|
29
|
+
初始化索引系统
|
30
|
+
|
31
|
+
Args:
|
32
|
+
sources_dir: Java源码根目录
|
33
|
+
"""
|
34
|
+
self.sources_dir = sources_dir
|
35
|
+
self.logger = get_logger("type_index")
|
36
|
+
|
37
|
+
# 多级索引结构
|
38
|
+
self._exact_index: Dict[str, str] = {} # 完整类名 -> 完整类名
|
39
|
+
self._simple_index: Dict[str, List[str]] = {} # 简单类名 -> [完整类名列表]
|
40
|
+
self._suffix_index: Dict[str, List[str]] = {} # 后缀 -> [完整类名列表]
|
41
|
+
self._package_index: Dict[str, List[str]] = {} # 包名 -> [完整类名列表]
|
42
|
+
|
43
|
+
# 基础类型集合(快速过滤)
|
44
|
+
self._basic_types: Set[str] = {
|
45
|
+
'int', 'long', 'float', 'double', 'boolean', 'byte', 'short', 'char',
|
46
|
+
'String', 'Object', 'Integer', 'Long', 'Float', 'Double', 'Boolean',
|
47
|
+
'Byte', 'Short', 'Character', 'List', 'Map', 'Set', 'Collection'
|
48
|
+
}
|
49
|
+
|
50
|
+
# 索引统计
|
51
|
+
self._stats = {
|
52
|
+
'total_classes': 0,
|
53
|
+
'index_hits': 0,
|
54
|
+
'index_misses': 0,
|
55
|
+
'basic_type_skips': 0
|
56
|
+
}
|
57
|
+
|
58
|
+
self._lock = threading.RLock()
|
59
|
+
self._is_built = False
|
60
|
+
|
61
|
+
def build_index(self) -> None:
|
62
|
+
"""构建所有索引"""
|
63
|
+
if self._is_built:
|
64
|
+
return
|
65
|
+
|
66
|
+
with self._lock:
|
67
|
+
if self._is_built:
|
68
|
+
return
|
69
|
+
|
70
|
+
self.logger.info("🏗️ 开始构建类型索引...")
|
71
|
+
|
72
|
+
# 扫描所有Java文件
|
73
|
+
java_files = list(self.sources_dir.rglob("*.java"))
|
74
|
+
self.logger.info(f"📁 发现 {len(java_files)} 个Java文件")
|
75
|
+
|
76
|
+
for java_file in java_files:
|
77
|
+
self._index_single_file(java_file)
|
78
|
+
|
79
|
+
self._stats['total_classes'] = len(self._exact_index)
|
80
|
+
self._is_built = True
|
81
|
+
|
82
|
+
self.logger.info(f"✅ 索引构建完成: {self._stats['total_classes']} 个类")
|
83
|
+
self._print_index_stats()
|
84
|
+
|
85
|
+
def _index_single_file(self, java_file: Path) -> None:
|
86
|
+
"""
|
87
|
+
为单个Java文件建立索引
|
88
|
+
|
89
|
+
Args:
|
90
|
+
java_file: Java文件路径
|
91
|
+
"""
|
92
|
+
try:
|
93
|
+
# 获取类名和包名
|
94
|
+
class_name = java_file.stem
|
95
|
+
relative_path = java_file.relative_to(self.sources_dir)
|
96
|
+
package_parts = relative_path.parts[:-1] # 排除文件名
|
97
|
+
|
98
|
+
if package_parts:
|
99
|
+
package_name = '.'.join(package_parts)
|
100
|
+
full_class_name = f"{package_name}.{class_name}"
|
101
|
+
else:
|
102
|
+
package_name = ""
|
103
|
+
full_class_name = class_name
|
104
|
+
|
105
|
+
# 1. 精确索引:完整类名
|
106
|
+
self._exact_index[full_class_name] = full_class_name
|
107
|
+
|
108
|
+
# 2. 简单名索引
|
109
|
+
if class_name not in self._simple_index:
|
110
|
+
self._simple_index[class_name] = []
|
111
|
+
self._simple_index[class_name].append(full_class_name)
|
112
|
+
|
113
|
+
# 3. 后缀索引(用于匹配如 IdData -> ContactIdData)
|
114
|
+
if len(class_name) > 4:
|
115
|
+
for suffix_len in [4, 6, 8]: # 多种后缀长度
|
116
|
+
if len(class_name) >= suffix_len:
|
117
|
+
suffix = class_name[-suffix_len:]
|
118
|
+
if suffix not in self._suffix_index:
|
119
|
+
self._suffix_index[suffix] = []
|
120
|
+
self._suffix_index[suffix].append(full_class_name)
|
121
|
+
|
122
|
+
# 4. 包名索引
|
123
|
+
if package_name:
|
124
|
+
if package_name not in self._package_index:
|
125
|
+
self._package_index[package_name] = []
|
126
|
+
self._package_index[package_name].append(full_class_name)
|
127
|
+
|
128
|
+
except Exception as e:
|
129
|
+
self.logger.warning(f"⚠️ 索引文件失败 {java_file}: {e}")
|
130
|
+
|
131
|
+
def find_best_match(self, type_name: str, current_package: str = "") -> Optional[str]:
|
132
|
+
"""
|
133
|
+
查找类型名的最佳匹配
|
134
|
+
|
135
|
+
Args:
|
136
|
+
type_name: 要查找的类型名
|
137
|
+
current_package: 当前包名(用于相似度计算)
|
138
|
+
|
139
|
+
Returns:
|
140
|
+
最佳匹配的完整类名,如果没有找到则返回None
|
141
|
+
"""
|
142
|
+
if not self._is_built:
|
143
|
+
self.build_index()
|
144
|
+
|
145
|
+
# 快速过滤基础类型
|
146
|
+
if type_name in self._basic_types:
|
147
|
+
self._stats['basic_type_skips'] += 1
|
148
|
+
return None
|
149
|
+
|
150
|
+
with self._lock:
|
151
|
+
# 1. 精确匹配
|
152
|
+
if type_name in self._exact_index:
|
153
|
+
self._stats['index_hits'] += 1
|
154
|
+
return self._exact_index[type_name]
|
155
|
+
|
156
|
+
# 2. 简单名匹配
|
157
|
+
if type_name in self._simple_index:
|
158
|
+
candidates = self._simple_index[type_name]
|
159
|
+
if len(candidates) == 1:
|
160
|
+
self._stats['index_hits'] += 1
|
161
|
+
return candidates[0]
|
162
|
+
else:
|
163
|
+
# 多个候选,选择包名最相似的
|
164
|
+
best_match = self._select_best_by_package(candidates, current_package)
|
165
|
+
if best_match:
|
166
|
+
self._stats['index_hits'] += 1
|
167
|
+
return best_match
|
168
|
+
|
169
|
+
# 3. 后缀匹配
|
170
|
+
for suffix_len in [4, 6, 8]:
|
171
|
+
if len(type_name) >= suffix_len:
|
172
|
+
suffix = type_name[-suffix_len:]
|
173
|
+
if suffix in self._suffix_index:
|
174
|
+
candidates = self._suffix_index[suffix]
|
175
|
+
# 过滤:确保候选类名以type_name结尾
|
176
|
+
filtered_candidates = [
|
177
|
+
c for c in candidates
|
178
|
+
if c.split('.')[-1].endswith(type_name)
|
179
|
+
]
|
180
|
+
if filtered_candidates:
|
181
|
+
best_match = self._select_best_by_package(filtered_candidates, current_package)
|
182
|
+
if best_match:
|
183
|
+
self._stats['index_hits'] += 1
|
184
|
+
return best_match
|
185
|
+
|
186
|
+
# 4. 未找到匹配
|
187
|
+
self._stats['index_misses'] += 1
|
188
|
+
return None
|
189
|
+
|
190
|
+
def _select_best_by_package(self, candidates: List[str], current_package: str) -> Optional[str]:
|
191
|
+
"""
|
192
|
+
根据包名相似度选择最佳候选
|
193
|
+
|
194
|
+
Args:
|
195
|
+
candidates: 候选类名列表
|
196
|
+
current_package: 当前包名
|
197
|
+
|
198
|
+
Returns:
|
199
|
+
最佳匹配的类名
|
200
|
+
"""
|
201
|
+
if not candidates:
|
202
|
+
return None
|
203
|
+
|
204
|
+
if len(candidates) == 1:
|
205
|
+
return candidates[0]
|
206
|
+
|
207
|
+
if not current_package:
|
208
|
+
return candidates[0] # 无包名信息时返回第一个
|
209
|
+
|
210
|
+
# 计算包名相似度
|
211
|
+
best_candidate = None
|
212
|
+
best_similarity = -1
|
213
|
+
|
214
|
+
for candidate in candidates:
|
215
|
+
candidate_package = '.'.join(candidate.split('.')[:-1])
|
216
|
+
similarity = self._calculate_package_similarity(candidate_package, current_package)
|
217
|
+
|
218
|
+
if similarity > best_similarity:
|
219
|
+
best_similarity = similarity
|
220
|
+
best_candidate = candidate
|
221
|
+
|
222
|
+
return best_candidate
|
223
|
+
|
224
|
+
def _calculate_package_similarity(self, package1: str, package2: str) -> float:
|
225
|
+
"""
|
226
|
+
计算两个包名的相似度
|
227
|
+
|
228
|
+
Args:
|
229
|
+
package1: 第一个包名
|
230
|
+
package2: 第二个包名
|
231
|
+
|
232
|
+
Returns:
|
233
|
+
相似度分数(0-1)
|
234
|
+
"""
|
235
|
+
if not package1 or not package2:
|
236
|
+
return 0.0
|
237
|
+
|
238
|
+
parts1 = package1.split('.')
|
239
|
+
parts2 = package2.split('.')
|
240
|
+
|
241
|
+
# 计算公共前缀长度
|
242
|
+
common_prefix = 0
|
243
|
+
for i in range(min(len(parts1), len(parts2))):
|
244
|
+
if parts1[i] == parts2[i]:
|
245
|
+
common_prefix += 1
|
246
|
+
else:
|
247
|
+
break
|
248
|
+
|
249
|
+
# 相似度 = 公共前缀长度 / 最大包深度
|
250
|
+
max_depth = max(len(parts1), len(parts2))
|
251
|
+
return common_prefix / max_depth if max_depth > 0 else 0.0
|
252
|
+
|
253
|
+
def get_classes_in_package(self, package_name: str) -> List[str]:
|
254
|
+
"""
|
255
|
+
获取指定包中的所有类
|
256
|
+
|
257
|
+
Args:
|
258
|
+
package_name: 包名
|
259
|
+
|
260
|
+
Returns:
|
261
|
+
类名列表
|
262
|
+
"""
|
263
|
+
if not self._is_built:
|
264
|
+
self.build_index()
|
265
|
+
|
266
|
+
return self._package_index.get(package_name, [])
|
267
|
+
|
268
|
+
def get_stats(self) -> dict:
|
269
|
+
"""
|
270
|
+
获取索引统计信息
|
271
|
+
|
272
|
+
Returns:
|
273
|
+
包含索引统计的字典
|
274
|
+
"""
|
275
|
+
with self._lock:
|
276
|
+
total_requests = self._stats['index_hits'] + self._stats['index_misses']
|
277
|
+
hit_rate = (self._stats['index_hits'] / total_requests * 100) if total_requests > 0 else 0
|
278
|
+
|
279
|
+
return {
|
280
|
+
'total_classes': self._stats['total_classes'],
|
281
|
+
'total_requests': total_requests,
|
282
|
+
'index_hits': self._stats['index_hits'],
|
283
|
+
'index_misses': self._stats['index_misses'],
|
284
|
+
'hit_rate_percent': hit_rate,
|
285
|
+
'basic_type_skips': self._stats['basic_type_skips'],
|
286
|
+
'is_built': self._is_built
|
287
|
+
}
|
288
|
+
|
289
|
+
def _print_index_stats(self):
|
290
|
+
"""打印索引构建统计"""
|
291
|
+
self.logger.info("📊 索引统计:")
|
292
|
+
self.logger.info(f" 精确索引: {len(self._exact_index)} 个类")
|
293
|
+
self.logger.info(f" 简单名索引: {len(self._simple_index)} 个条目")
|
294
|
+
self.logger.info(f" 后缀索引: {len(self._suffix_index)} 个条目")
|
295
|
+
self.logger.info(f" 包名索引: {len(self._package_index)} 个包")
|
296
|
+
|
297
|
+
def print_stats(self):
|
298
|
+
"""打印使用统计信息"""
|
299
|
+
stats = self.get_stats()
|
300
|
+
|
301
|
+
self.logger.info("📊 类型索引统计:")
|
302
|
+
self.logger.info(f" 总类数: {stats['total_classes']}")
|
303
|
+
self.logger.info(f" 查询请求: {stats['total_requests']}")
|
304
|
+
self.logger.info(f" 索引命中: {stats['index_hits']}")
|
305
|
+
self.logger.info(f" 索引未命中: {stats['index_misses']}")
|
306
|
+
self.logger.info(f" 命中率: {stats['hit_rate_percent']:.1f}%")
|
307
|
+
self.logger.info(f" 基础类型跳过: {stats['basic_type_skips']}")
|
308
|
+
|
309
|
+
|
310
|
+
# 全局索引实例
|
311
|
+
_global_index = None
|
312
|
+
_index_lock = threading.Lock()
|
313
|
+
|
314
|
+
|
315
|
+
def get_type_index(sources_dir: Path = None) -> TypeMatchingIndex:
|
316
|
+
"""
|
317
|
+
获取全局类型索引实例(单例模式)
|
318
|
+
|
319
|
+
Args:
|
320
|
+
sources_dir: 源码目录(仅在首次调用时需要)
|
321
|
+
|
322
|
+
Returns:
|
323
|
+
TypeMatchingIndex实例
|
324
|
+
"""
|
325
|
+
global _global_index
|
326
|
+
|
327
|
+
if _global_index is None:
|
328
|
+
with _index_lock:
|
329
|
+
if _global_index is None:
|
330
|
+
if sources_dir is None:
|
331
|
+
raise ValueError("首次调用 get_type_index 时必须提供 sources_dir 参数")
|
332
|
+
_global_index = TypeMatchingIndex(sources_dir)
|
333
|
+
_global_index.build_index()
|
334
|
+
|
335
|
+
return _global_index
|
336
|
+
|
337
|
+
|
338
|
+
def clear_global_index():
|
339
|
+
"""清空全局索引"""
|
340
|
+
global _global_index
|
341
|
+
_global_index = None
|