├── .gitignore ├── LICENSE ├── README.md ├── _svrs_address.txt ├── coverage.cov ├── go.mod ├── goc.log ├── iancoleman └── orderedmap.go ├── index.html ├── main.go ├── unitauto-go ├── unitauto-go_profile_listen_addr └── unitauto ├── method_util.go ├── server.go └── test └── test_util.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe~ 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, built with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Dependency directories (remove the comment below to include it) 14 | # vendor/ 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright ©2023 TommyLemon(https://github.com/TommyLemon) 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unitauto-go 2 | UnitAuto Go 库,可通过 GitHub 仓库等远程依赖。
3 | UnitAuto Go Library for remote dependencies with GitHub repo, etc. 4 | 5 | image 6 | 7 | 同步纯函数:
8 | Sync pure function:
9 | https://github.com/TommyLemon/unitauto-go/blob/main/unitauto/test/test_util.go#L25-L27 10 | image 11 | 12 | struct 成员函数:
13 | strcut member function:
14 | https://github.com/TommyLemon/unitauto-go/blob/main/unitauto/test/test_util.go#L88-L90 15 | image 16 | image 17 | 18 | 协程异步函数:
19 | goroutine function:
20 | https://github.com/TommyLemon/unitauto-go/blob/main/unitauto/test/test_util.go#L33-L45 21 | image 22 | 23 | 异步回调函数:
24 | async callback function:
25 | https://github.com/TommyLemon/unitauto-go/blob/main/unitauto/test/test_util.go#L72-L81 26 | image 27 | 28 |
29 | 30 | 代码覆盖率统计:
31 | Code coverage:
32 | https://github.com/qiniu/goc/issues/349 33 | image 34 | image 35 | 36 |
37 | 38 | **Demo:** https://github.com/TommyLemon/unitauto-go-demo 39 | 40 |
41 | 42 | #### 1. 在 go.mod 中添加 GitHub 仓库 43 | #### 1. Add the GitHub repository to go.mod 44 | ```go 45 | require ( 46 | github.com/TommyLemon/unitauto-go v1.0.0 47 | ) 48 | ``` 49 |
50 | 51 | #### 2. 执行 go get 命令 52 | #### 2. Run go get command 53 | ```sh 54 | go get github.com/TommyLemon/unitauto-go@v1.0.0 55 | ``` 56 |
57 | 58 | #### 3. 启动单元测试服务 59 | #### 3. Start unit testing server 60 | https://github.com/TommyLemon/unitauto-go/blob/main/main.go#L7-L12 61 | ```go 62 | func main() { 63 | unitauto.Start(8082) 64 | } 65 | ``` 66 | 67 |
68 | 69 | #### 4. 参考主项目文档来测试 70 | #### 4. Test by following the main repo 71 | 72 | https://github.com/TommyLemon/UnitAuto 73 | 74 | 由于 Go 的反射限制,目前做不到像 Java, Kotlin 版几乎绝对零代码,还需要注册 func 和 struct 的实例,
75 | 不过注册代码可以通过 UnitAuto-Admin 前端管理网页设置项 \[查看、同步方法文档] 来生成,复制粘贴到被测项目中:
76 | Due to the limitation of Go, it's not almost absolutely coding free like Java and Kotlin,
77 | and you need to write few code to register the funcs and structs to be tested.
78 | However, the code can be generated by clicking the setting item [View/Sync doc] of UnitAuto-Admin,
79 | then you can copy and pasted the "ginCode" into the project under test instead of coding:
80 | 81 | https://github.com/TommyLemon/unitauto-go/blob/main/main.go 82 | image 83 | image 84 | 85 |
86 | 87 | ### 5. 关于作者 88 | ### 5. Author 89 | [https://github.com/TommyLemon](https://github.com/TommyLemon)
90 | 91 | 92 | 如果有什么问题或建议可以 [去 APIAuto 提 issue](https://github.com/TommyLemon/APIAuto/issues),交流技术,分享经验。
93 | 如果你解决了某些 bug,或者新增了一些功能,欢迎 [提 PR 贡献代码](https://github.com/Tencent/APIJSON/blob/master/CONTRIBUTING.md),感激不尽。 94 |
95 | If you have any questions or suggestions, you can [create an issue](https://github.com/TommyLemon/APIAuto/issues).
96 | If you can added a feature or fixed a bug, please [create a pull request](https://github.com/TommyLemon/unitauto-go/pulls), thank you~ 97 | 98 | 99 | ### 6. 其它项目 100 | ### 6. Link 101 | 创作不易、坚持更难,右上角点 ⭐ Star 支持下吧,谢谢 ^\_^
102 | Please ⭐ Star the repos that you like ^\_^
103 | 104 | [UnitAuto](https://github.com/TommyLemon/UnitAuto) 机器学习零代码单元测试平台,零代码、全方位、自动化 测试 方法/函数 的正确性、可用性和性能 105 | 106 | [unitauto-go-demo](https://github.com/TommyLemon/unitauto-go-demo) UnitAuto Go Demo,提供用来做单元测试的业务函数 107 | 108 | [unitauto-py](https://github.com/TommyLemon/unitauto-py) UnitAuto Python 库,可通过 pip 仓库等远程依赖 109 | 110 | [APIJSON](https://github.com/Tencent/APIJSON) 🚀 腾讯零代码、全功能、强安全 ORM 库 🏆 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构 111 | 112 | [apijson-go](https://github.com/glennliao/apijson-go) Go 版 APIJSON, 基于Go(>=1.18) + GoFrame2, 支持查询、单表增删改、权限管理等 113 | 114 | [APIAuto](https://github.com/TommyLemon/APIAuto) 敏捷开发最强大易用的 HTTP 接口工具,机器学习零代码测试、生成代码与静态检查、生成文档与光标悬浮注释,集 文档、测试、Mock、调试、管理 于一体的一站式体验 115 | 116 | [SQLAuto](https://github.com/TommyLemon/SQLAuto) 智能零代码自动化测试 SQL 语句执行结果的数据库工具,任意增删改查、任意 SQL 模板变量、一键批量生成参数组合、快速构造大量测试数据 117 | 118 | [UIGO](https://github.com/TommyLemon/UIGO) 📱 零代码快准稳 UI 智能录制回放平台 🚀 自动兼容任意宽高比分辨率屏幕,自动精准等待网络请求,录制回放快、准、稳! 119 | -------------------------------------------------------------------------------- /_svrs_address.txt: -------------------------------------------------------------------------------- 1 | unitauto-go&http://127.0.0.1:51675 2 | -------------------------------------------------------------------------------- /coverage.cov: -------------------------------------------------------------------------------- 1 | mode: count 2 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:14.30,16.2 1 0 3 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:18.37,20.2 1 0 4 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:27.37,27.60 1 0 5 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:28.37,28.88 1 0 6 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:29.37,29.82 1 0 7 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:37.24,43.2 5 0 8 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:45.45,47.2 1 0 9 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:49.58,50.21 1 0 10 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:50.21,52.3 1 0 11 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:53.2,54.20 2 0 12 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:57.57,58.21 1 0 13 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:58.21,60.3 1 0 14 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:61.2,62.13 2 0 15 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:62.13,64.3 1 0 16 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:65.2,65.23 1 0 17 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:68.41,71.9 2 0 18 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:71.9,73.3 1 0 19 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:75.2,75.27 1 0 20 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:75.27,76.15 1 0 21 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:76.15,78.9 2 0 22 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:82.2,82.23 1 0 23 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:85.38,87.2 1 0 24 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:90.61,92.2 1 0 25 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:95.65,97.29 2 0 26 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:97.29,99.3 1 0 27 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:101.2,103.29 2 0 28 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:103.29,105.3 1 0 29 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:108.52,109.21 1 0 30 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:109.21,111.3 1 0 31 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:112.2,113.16 2 0 32 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:113.16,115.3 1 0 33 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:116.2,117.38 2 0 34 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:117.38,119.3 1 0 35 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:120.2,121.33 2 0 36 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:124.63,126.6 2 0 37 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:126.6,128.17 2 0 38 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:128.17,130.4 1 0 39 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:131.3,131.58 1 0 40 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:131.58,133.4 1 0 41 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:134.3,135.18 2 0 42 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:135.18,137.29 1 0 43 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:137.29,138.17 1 0 44 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:138.17,140.11 2 0 45 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:143.4,143.31 1 0 46 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:144.9,147.4 2 0 47 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:149.3,150.17 2 0 48 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:150.17,152.4 1 0 49 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:153.3,153.42 1 0 50 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:153.42,154.17 1 0 51 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:155.13,156.65 1 0 52 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:156.65,162.58 2 0 53 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:162.58,164.7 1 0 54 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:165.6,165.28 1 0 55 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:166.11,166.60 1 0 56 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:166.60,172.58 2 0 57 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:172.58,174.7 1 0 58 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:175.6,175.28 1 0 59 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:176.11,176.70 1 0 60 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:176.70,178.6 1 0 61 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:179.13,180.56 1 0 62 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:180.56,181.66 1 0 63 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:181.66,183.7 1 0 64 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:184.11,184.81 1 0 65 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:184.81,186.6 1 0 66 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:192.77,193.28 1 0 67 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:193.28,195.17 2 0 68 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:195.17,197.4 1 0 69 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:198.3,198.42 1 0 70 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:198.42,199.17 1 0 71 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:200.13,201.23 1 0 72 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:201.23,202.61 1 0 73 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:202.61,208.59 2 0 74 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:208.59,210.8 1 0 75 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:211.7,211.24 1 0 76 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:212.12,212.56 1 0 77 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:212.56,218.59 2 0 78 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:218.59,220.8 1 0 79 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:221.7,221.24 1 0 80 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:222.12,222.71 1 0 81 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:222.71,224.7 1 0 82 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:225.11,225.70 1 0 83 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:225.70,227.6 1 0 84 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:228.13,229.23 1 0 85 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:229.23,230.52 1 0 86 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:230.52,231.65 1 0 87 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:231.65,233.8 1 0 88 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:234.12,234.80 1 0 89 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:234.80,236.7 1 0 90 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:237.11,237.79 1 0 91 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:237.79,239.6 1 0 92 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:240.13,241.15 1 0 93 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:247.51,252.27 5 0 94 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:252.27,253.12 1 0 95 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:253.12,255.4 1 0 96 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:257.3,257.43 1 0 97 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:257.43,259.4 1 0 98 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:260.3,262.53 2 0 99 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:262.53,264.4 1 0 100 | github.com/TommyLemon/unitauto-go/iancoleman/orderedmap.go:266.2,267.25 2 0 101 | github.com/TommyLemon/unitauto-go/main.go:7.13,12.2 2 1 102 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:93.100,95.2 1 0 103 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:97.107,98.80 1 0 104 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:98.80,100.3 1 0 105 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:100.8,102.3 1 0 106 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:105.136,107.33 2 0 107 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:107.33,109.3 1 0 108 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:111.2,112.24 2 0 109 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:112.24,114.3 1 0 110 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:115.2,115.16 1 0 111 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:119.106,121.2 1 0 112 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:123.135,125.2 1 0 113 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:215.47,216.14 1 19 114 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:216.14,218.3 1 0 115 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:219.2,220.14 2 19 116 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:220.14,222.3 1 18 117 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:223.2,223.18 1 1 118 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:226.45,227.14 1 0 119 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:227.14,229.3 1 0 120 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:230.2,231.14 2 0 121 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:231.14,233.3 1 0 122 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:235.2,235.18 1 0 123 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:236.13,237.24 1 0 124 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:238.13,239.24 1 0 125 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:240.15,241.26 1 0 126 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:242.15,243.26 1 0 127 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:245.2,245.16 1 0 128 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:248.49,249.14 1 0 129 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:249.14,251.3 1 0 130 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:252.2,253.14 2 0 131 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:253.14,255.3 1 0 132 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:257.2,257.18 1 0 133 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:258.11,259.24 1 0 134 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:260.13,261.26 1 0 135 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:262.15,263.28 1 0 136 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:264.15,265.28 1 0 137 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:267.2,267.18 1 0 138 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:270.49,271.14 1 6 139 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:271.14,273.3 1 0 140 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:274.2,275.14 2 6 141 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:275.14,277.3 1 6 142 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:278.2,278.18 1 0 143 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:279.11,280.24 1 0 144 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:281.13,282.26 1 0 145 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:283.15,284.28 1 0 146 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:285.15,286.28 1 0 147 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:288.2,288.18 1 0 148 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:291.48,292.14 1 37 149 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:292.14,294.3 1 0 150 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:295.2,296.14 2 37 151 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:296.14,298.3 1 11 152 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:299.2,299.22 1 26 153 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:302.56,303.14 1 6 154 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:303.14,305.3 1 0 155 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:306.2,307.14 2 6 156 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:307.14,309.3 1 5 157 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:310.2,310.27 1 1 158 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:313.47,314.14 1 20 159 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:314.14,316.3 1 0 160 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:317.2,318.14 2 20 161 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:318.14,320.3 1 14 162 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:321.2,321.18 1 6 163 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:322.24,324.44 2 1 164 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:324.44,326.4 1 1 165 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:327.3,327.12 1 1 166 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:335.2,335.18 1 5 167 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:338.61,339.14 1 0 168 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:339.14,341.3 1 0 169 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:342.2,343.14 2 0 170 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:343.14,345.3 1 0 171 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:346.2,346.29 1 0 172 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:349.70,351.14 2 0 173 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:351.14,353.3 1 0 174 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:354.2,355.14 2 0 175 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:355.14,357.3 1 0 176 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:359.2,359.39 1 0 177 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:359.39,361.3 1 0 178 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:362.2,362.11 1 0 179 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:365.63,368.74 3 0 180 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:368.74,370.3 1 0 181 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:372.2,374.32 2 0 182 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:374.32,376.3 1 0 183 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:378.2,378.11 1 0 184 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:381.60,383.33 2 0 185 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:383.33,385.3 1 0 186 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:386.2,386.18 1 0 187 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:389.52,390.14 1 0 188 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:390.14,392.3 1 0 189 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:393.2,394.14 2 0 190 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:394.14,396.3 1 0 191 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:398.2,398.22 1 0 192 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:401.53,402.47 1 0 193 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:402.47,404.3 1 0 194 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:404.8,407.3 2 0 195 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:424.52,427.16 2 0 196 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:427.16,429.3 1 0 197 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:431.2,440.24 8 0 198 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:440.24,443.44 3 0 199 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:443.44,445.19 2 0 200 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:445.19,448.34 2 0 201 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:448.34,451.21 3 0 202 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:451.21,453.7 1 0 203 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:459.2,460.17 2 0 204 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:460.17,462.3 1 0 205 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:464.2,465.24 2 0 206 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:465.24,467.3 1 0 207 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:470.2,470.15 1 0 208 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:474.90,475.47 1 0 209 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:475.47,477.3 1 0 210 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:477.8,479.3 1 0 211 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:546.83,547.15 1 6 212 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:547.15,548.35 1 6 213 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:548.35,550.4 1 0 214 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:553.2,553.16 1 6 215 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:553.16,555.3 1 0 216 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:557.2,570.19 12 6 217 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:570.19,571.24 1 0 218 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:571.24,575.4 3 0 219 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:577.3,577.20 1 0 220 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:580.2,580.48 1 6 221 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:580.48,584.3 3 0 222 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:586.2,587.18 2 6 223 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:587.18,589.3 1 0 224 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:589.8,589.20 1 6 225 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:589.20,590.24 1 0 226 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:590.24,592.4 1 0 227 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:592.9,594.4 1 0 228 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:595.3,595.18 1 0 229 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:598.2,600.48 3 6 230 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:600.48,601.17 1 0 231 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:601.17,603.4 1 0 232 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:604.3,605.13 2 0 233 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:608.2,608.18 1 6 234 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:608.18,617.17 7 1 235 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:617.17,619.4 1 0 236 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:620.3,620.21 1 1 237 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:623.2,625.73 3 6 238 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:625.73,626.29 1 0 239 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:626.29,628.4 1 0 240 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:628.9,630.62 2 0 241 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:630.62,631.164 1 0 242 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:631.164,633.6 1 0 243 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:637.2,639.16 2 6 244 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:639.16,640.37 1 6 245 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:640.37,642.4 1 0 246 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:645.2,645.16 1 6 247 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:645.16,648.3 2 0 248 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:650.2,650.17 1 6 249 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:650.17,652.13 2 0 250 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:652.13,657.4 3 0 251 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:660.2,661.37 2 6 252 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:661.37,663.3 1 1 253 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:668.2,668.112 1 5 254 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:672.55,675.145 2 6 255 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:675.145,677.18 2 6 256 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:677.18,678.23 1 6 257 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:679.24,681.25 2 6 258 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:681.25,683.6 1 22 259 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:687.3,688.22 2 6 260 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:688.22,690.4 1 1 261 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:692.3,692.22 1 6 262 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:692.22,694.18 2 6 263 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:694.18,696.5 1 0 264 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:699.3,699.13 1 6 265 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:702.2,702.16 1 6 266 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:702.16,705.3 2 0 267 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:706.2,706.12 1 6 268 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:709.133,712.16 3 0 269 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:712.16,714.3 1 0 270 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:716.2,727.21 7 0 271 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:727.21,728.52 1 0 272 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:728.52,730.4 1 0 273 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:736.31,743.2 1 1 274 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:745.33,747.2 1 11 275 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:748.35,750.2 1 10 276 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:752.33,754.2 1 11 277 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:755.33,757.2 1 4 278 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:758.33,760.2 1 11 279 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:762.69,763.16 1 19 280 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:763.16,765.3 1 0 281 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:766.2,768.26 3 19 282 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:768.26,770.3 1 13 283 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:772.2,773.25 2 6 284 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:773.25,777.65 4 10 285 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:777.65,779.4 1 1 286 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:779.9,779.40 1 9 287 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:779.40,784.18 5 3 288 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:784.18,787.5 2 1 289 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:789.4,789.46 1 3 290 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:790.9,790.38 1 6 291 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:790.38,794.26 4 6 292 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:794.26,796.5 1 6 293 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:797.4,800.26 4 6 294 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:801.9,801.44 1 0 295 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:801.44,805.26 4 0 296 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:805.26,807.5 1 0 297 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:808.4,811.26 4 0 298 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:812.9,815.18 3 0 299 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:815.18,817.5 1 0 300 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:817.10,819.5 1 0 301 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:821.4,822.26 2 0 302 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:826.2,826.19 1 6 303 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:826.19,828.3 1 0 304 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:829.2,829.12 1 6 305 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:836.72,838.23 2 6 306 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:838.23,840.3 1 0 307 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:840.8,842.37 2 6 308 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:842.37,844.4 1 6 309 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:847.2,847.16 1 6 310 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:847.16,850.71 3 6 311 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:850.71,852.4 1 6 312 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:855.2,856.16 2 0 313 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:856.16,858.3 1 0 314 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:907.2,907.15 1 0 315 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:910.102,911.46 1 0 316 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:911.46,913.3 1 0 317 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:914.2,914.11 1 0 318 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:914.11,916.15 2 0 319 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:916.15,918.4 1 0 320 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:921.2,923.16 3 0 321 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:923.16,925.3 1 0 322 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:926.2,926.17 1 0 323 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:934.53,935.19 1 1 324 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:935.19,937.3 1 0 325 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:938.2,939.16 2 1 326 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:939.16,941.17 2 1 327 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:941.17,943.4 1 1 328 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:970.2,970.19 1 0 329 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:980.103,981.16 1 0 330 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:981.16,983.3 1 0 331 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:985.2,985.24 1 0 332 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:985.24,987.3 1 0 333 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:989.2,989.30 1 0 334 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:989.30,991.3 1 0 335 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:993.2,993.21 1 0 336 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:993.21,996.22 2 0 337 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:996.22,998.4 1 0 338 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1000.3,1000.31 1 0 339 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1003.2,1003.22 1 0 340 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1014.145,1018.22 1 6 341 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1018.22,1020.3 1 0 342 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1022.2,1029.22 5 6 343 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1029.22,1031.17 2 5 344 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1031.17,1033.4 1 0 345 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1036.2,1039.49 3 6 346 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1039.49,1041.3 1 2 347 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1041.8,1041.30 1 4 348 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1041.30,1043.3 1 4 349 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1043.8,1045.3 1 0 350 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1047.2,1047.39 1 6 351 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1047.39,1049.3 1 0 352 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1051.2,1053.121 2 6 353 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1053.121,1059.22 4 6 354 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1059.22,1061.4 1 0 355 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1063.3,1066.33 3 6 356 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1066.33,1068.36 2 5 357 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1068.36,1070.5 1 5 358 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1071.4,1071.19 1 5 359 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1071.19,1073.5 1 0 360 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1073.10,1073.27 1 5 361 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1073.27,1075.5 1 5 362 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1078.3,1082.21 4 6 363 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1082.21,1085.36 2 5 364 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1085.36,1089.5 3 9 365 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1091.4,1091.45 1 5 366 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1094.3,1096.22 2 6 367 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1096.22,1098.18 2 6 368 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1098.18,1100.5 1 0 369 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1103.3,1103.13 1 6 370 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1106.2,1113.20 5 6 371 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1113.20,1114.35 1 5 372 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1114.35,1119.51 3 9 373 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1119.51,1124.16 3 1 374 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1124.16,1126.6 1 1 375 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1127.5,1127.43 1 1 376 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1127.43,1128.49 1 0 377 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1128.49,1129.24 1 0 378 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1130.27,1133.20 3 0 379 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1133.20,1135.9 1 0 380 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1136.8,1136.47 1 0 381 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1136.47,1137.17 1 0 382 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1139.8,1140.15 2 0 383 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1140.15,1142.9 1 0 384 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1145.7,1145.18 1 0 385 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1145.18,1146.13 1 0 386 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1150.6,1150.57 1 0 387 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1150.57,1151.23 1 0 388 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1152.26,1153.33 1 0 389 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1154.15,1166.18 10 0 390 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1166.18,1167.44 1 0 391 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1167.44,1169.26 2 0 392 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1169.26,1172.16 3 0 393 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1177.8,1178.17 2 0 394 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1178.17,1180.52 2 0 395 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1180.52,1181.27 1 0 396 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1182.30,1185.23 3 0 397 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1185.23,1187.12 1 0 398 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1188.11,1188.50 1 0 399 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1188.50,1189.20 1 0 400 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1191.11,1194.103 3 0 401 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1194.103,1201.21 5 0 402 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1201.21,1202.29 1 0 403 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1202.29,1204.14 1 0 404 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1204.19,1205.53 1 0 405 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1205.53,1207.15 1 0 406 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1209.13,1209.35 1 0 407 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1211.12,1212.22 2 0 408 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1212.22,1214.13 1 0 409 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1216.12,1218.19 2 0 410 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1218.19,1220.13 1 0 411 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1221.12,1221.22 1 0 412 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1226.9,1229.36 3 0 413 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1230.14,1232.9 1 0 414 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1234.12,1237.7 2 0 415 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1238.6,1238.14 1 0 416 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1241.5,1242.32 2 1 417 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1242.32,1243.57 1 0 418 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1243.57,1246.7 1 0 419 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1246.12,1248.7 1 0 420 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1249.6,1249.14 1 0 421 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1252.5,1254.36 3 1 422 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1254.36,1256.20 2 2 423 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1256.20,1258.7 1 0 424 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1261.5,1265.12 5 1 425 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1265.12,1267.6 1 1 426 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1269.5,1270.30 2 1 427 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1270.30,1272.6 1 0 428 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1273.5,1274.37 2 1 429 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1274.37,1276.20 2 1 430 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1276.20,1278.7 1 0 431 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1281.5,1282.118 2 1 432 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1282.118,1286.27 3 1 433 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1286.27,1290.21 4 2 434 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1290.21,1292.8 1 2 435 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1292.13,1292.30 1 0 436 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1292.30,1294.8 1 0 437 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1294.13,1294.33 1 0 438 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1294.33,1296.8 1 0 439 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1296.13,1296.35 1 0 440 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1296.35,1298.8 1 0 441 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1298.13,1298.34 1 0 442 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1298.34,1300.8 1 0 443 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1302.7,1305.8 1 2 444 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1308.6,1309.19 2 1 445 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1309.19,1311.7 1 1 446 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1313.6,1322.29 5 1 447 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1322.29,1325.7 2 1 448 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1327.6,1327.17 1 1 449 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1327.18,1329.7 0 0 450 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1329.12,1329.60 1 1 451 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1329.60,1333.18 4 0 452 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1333.18,1335.8 1 0 453 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1336.7,1336.32 1 0 454 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1336.32,1337.61 1 0 455 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1337.61,1339.9 1 0 456 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1339.14,1341.9 1 0 457 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1343.12,1344.57 1 1 458 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1344.57,1346.8 1 0 459 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1346.13,1348.8 1 1 460 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1351.6,1351.13 1 1 461 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1351.13,1353.21 2 1 462 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1353.21,1356.8 2 0 463 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1359.6,1359.15 1 1 464 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1362.10,1363.56 1 8 465 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1363.56,1365.6 1 8 466 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1365.11,1367.6 1 0 467 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1372.2,1380.27 6 6 468 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1380.27,1381.24 1 5 469 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1381.24,1383.12 2 0 470 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1386.3,1387.19 2 5 471 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1387.19,1389.4 1 3 472 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1389.9,1389.28 1 2 473 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1389.28,1391.4 1 1 474 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1391.9,1391.29 1 1 475 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1391.29,1393.4 1 0 476 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1393.9,1393.31 1 1 477 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1393.31,1395.4 1 1 478 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1395.9,1395.32 1 0 479 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1395.32,1397.4 1 0 480 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1397.9,1399.4 1 0 481 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1402.2,1402.13 1 6 482 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1402.13,1404.3 1 5 483 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1404.8,1404.19 1 1 484 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1404.19,1406.3 1 0 485 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1408.2,1408.12 1 6 486 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1408.12,1409.22 1 5 487 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1409.22,1412.18 3 5 488 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1412.18,1414.5 1 0 489 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1416.3,1416.18 1 5 490 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1419.2,1419.17 1 1 491 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1434.154,1435.44 1 0 492 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1435.44,1437.3 1 0 493 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1439.2,1440.16 2 0 494 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1440.16,1442.3 1 0 495 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1444.2,1456.16 10 0 496 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1456.16,1460.3 3 0 497 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1462.2,1465.27 3 0 498 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1465.27,1469.42 3 0 499 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1469.42,1471.18 2 0 500 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1471.18,1472.13 1 0 501 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1475.4,1481.17 5 0 502 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1481.17,1483.5 1 0 503 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1484.4,1484.42 1 0 504 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1484.42,1486.5 1 0 505 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1487.4,1491.19 4 0 506 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1491.19,1494.5 2 0 507 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1496.4,1496.18 1 0 508 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1496.18,1499.5 2 0 509 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1500.4,1503.24 3 0 510 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1503.24,1505.5 1 0 511 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1507.4,1510.63 3 0 512 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1510.63,1511.13 1 0 513 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1514.4,1518.17 3 0 514 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1518.17,1520.5 1 0 515 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1522.4,1534.76 10 0 516 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1534.76,1547.5 4 0 517 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1549.4,1549.57 1 0 518 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1549.57,1551.23 2 0 519 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1551.23,1553.29 2 0 520 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1553.29,1555.7 1 0 521 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1556.6,1556.39 1 0 522 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1559.5,1559.22 1 0 523 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1559.22,1563.27 2 0 524 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1563.27,1565.7 1 0 525 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1567.6,1567.16 1 0 526 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1567.16,1569.64 2 0 527 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1569.64,1570.16 1 0 528 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1573.7,1574.85 2 0 529 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1577.10,1578.40 1 0 530 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1578.40,1585.41 3 0 531 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1585.41,1587.25 2 0 532 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1587.25,1589.8 1 0 533 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1591.7,1591.24 1 0 534 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1591.24,1595.29 2 0 535 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1595.29,1597.9 1 0 536 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1599.8,1600.65 2 0 537 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1600.65,1601.17 1 0 538 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1604.8,1605.86 2 0 539 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1611.4,1611.18 1 0 540 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1611.18,1613.5 1 0 541 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1615.4,1615.27 1 0 542 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1615.27,1617.5 1 0 543 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1619.4,1619.23 1 0 544 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1619.23,1621.5 1 0 545 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1623.4,1623.26 1 0 546 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1623.26,1625.5 1 0 547 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1627.4,1627.38 1 0 548 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1627.38,1629.5 1 0 549 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1631.4,1631.30 1 0 550 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1634.3,1634.27 1 0 551 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1634.27,1636.4 1 0 552 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1639.2,1641.16 2 0 553 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1641.16,1645.3 3 0 554 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1647.2,1647.44 1 0 555 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1647.44,1656.3 1 0 556 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1658.2,1660.22 2 0 557 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1663.40,1665.2 1 0 558 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1667.40,1669.2 1 0 559 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1671.127,1672.26 1 6 560 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1672.26,1674.3 1 0 561 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1675.2,1675.33 1 6 562 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1675.33,1677.3 1 0 563 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1678.2,1678.67 1 6 564 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1678.67,1680.3 1 0 565 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1682.2,1682.39 1 6 566 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1682.39,1689.17 5 10 567 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1689.17,1691.4 1 0 568 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1693.3,1693.19 1 10 569 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1693.19,1694.75 1 0 570 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1694.75,1696.5 1 0 571 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1699.3,1699.65 1 10 572 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1699.65,1720.22 1 3 573 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1720.22,1721.50 1 1 574 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1721.50,1723.6 1 0 575 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1727.3,1728.18 2 10 576 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1731.2,1731.12 1 6 577 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1734.57,1735.51 1 0 578 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1735.51,1737.3 1 0 579 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1739.2,1744.32 5 0 580 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1744.32,1750.32 5 0 581 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1750.32,1752.4 1 0 582 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1754.3,1756.18 3 0 583 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1756.18,1758.4 1 0 584 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1759.3,1760.18 2 0 585 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1760.18,1762.4 1 0 586 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1763.3,1763.36 1 0 587 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1763.36,1765.4 1 0 588 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1767.3,1773.36 6 0 589 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1773.36,1776.21 3 0 590 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1776.21,1778.5 1 0 591 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1779.4,1785.18 4 0 592 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1785.18,1788.5 2 0 593 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1791.3,1794.37 4 0 594 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1794.37,1797.21 3 0 595 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1797.21,1799.5 1 0 596 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1800.4,1806.18 4 0 597 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1806.18,1809.5 2 0 598 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1812.3,1816.27 5 0 599 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1817.8,1819.19 2 0 600 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1820.22,1821.43 1 0 601 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1824.11,1825.44 1 0 602 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1827.3,1829.43 3 0 603 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1829.43,1831.4 1 0 604 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1834.3,1835.34 2 0 605 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1835.34,1837.4 1 0 606 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1839.3,1840.35 2 0 607 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1840.35,1842.4 1 0 608 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1844.3,1850.43 7 0 609 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1859.2,1859.28 1 0 610 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1859.28,1861.35 2 0 611 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1861.35,1863.4 1 0 612 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1865.3,1865.40 1 0 613 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1868.2,1868.12 1 0 614 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1871.75,1874.14 2 0 615 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1874.14,1876.3 1 0 616 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1878.2,1878.16 1 0 617 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1878.16,1880.3 1 0 618 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1882.2,1885.99 3 0 619 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1885.99,1887.3 1 0 620 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1888.2,1888.62 1 0 621 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1888.62,1890.3 1 0 622 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1892.2,1894.46 2 0 623 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1894.46,1896.3 1 0 624 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1898.2,1899.140 2 0 625 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1899.140,1901.3 1 0 626 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1903.2,1903.50 1 0 627 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1903.50,1906.20 3 0 628 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1906.20,1908.4 1 0 629 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1909.3,1909.19 1 0 630 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1913.2,1913.22 1 0 631 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1913.22,1915.3 1 0 632 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1917.2,1918.120 1 0 633 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1918.120,1919.15 1 0 634 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1919.15,1921.4 1 0 635 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1922.3,1922.28 1 0 636 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1925.2,1925.74 1 0 637 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1925.74,1926.15 1 0 638 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1926.15,1928.4 1 0 639 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1929.3,1929.31 1 0 640 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1931.2,1931.100 1 0 641 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1931.100,1932.15 1 0 642 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1932.15,1934.4 1 0 643 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1935.3,1935.33 1 0 644 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1938.2,1938.15 1 0 645 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1938.15,1940.3 1 0 646 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1942.2,1942.52 1 0 647 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1942.52,1945.26 3 0 648 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1945.26,1947.4 1 0 649 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1948.3,1948.13 1 0 650 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1951.2,1953.25 2 0 651 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1953.25,1955.26 2 0 652 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1955.26,1958.4 2 0 653 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1959.3,1959.13 1 0 654 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1962.2,1962.26 1 0 655 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1962.26,1965.37 3 0 656 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1965.37,1969.4 3 0 657 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1971.3,1971.18 1 0 658 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1971.18,1974.4 2 0 659 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1974.9,1974.26 1 0 660 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1974.26,1977.4 2 0 661 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1979.3,1980.13 2 0 662 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1983.2,1983.28 1 0 663 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1983.28,1984.39 1 0 664 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1984.39,1989.94 4 0 665 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1989.94,1991.13 2 0 666 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1994.4,1994.48 1 0 667 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1994.48,1996.13 2 0 668 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1999.4,1999.58 1 0 669 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:1999.58,2000.13 1 0 670 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2003.4,2003.52 1 0 671 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2006.3,2006.13 1 0 672 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2009.2,2009.31 1 0 673 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2009.31,2010.40 1 0 674 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2010.40,2015.35 4 0 675 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2015.35,2016.14 1 0 676 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2016.14,2018.6 1 0 677 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2019.5,2019.34 1 0 678 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2022.4,2024.36 3 0 679 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2024.36,2028.5 3 0 680 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2030.4,2031.19 2 0 681 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2031.19,2034.5 2 0 682 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2034.10,2034.27 1 0 683 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2034.27,2037.5 2 0 684 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2038.4,2040.19 2 0 685 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2043.3,2043.13 1 0 686 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2046.2,2046.12 1 0 687 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2054.60,2056.32 2 1 688 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2056.32,2059.17 3 0 689 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2059.17,2061.4 1 0 690 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2064.2,2064.16 1 1 691 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2064.16,2066.3 1 1 692 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2067.2,2067.29 1 1 693 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2075.54,2078.54 3 10 694 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2078.54,2080.3 1 8 695 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2080.8,2081.23 1 2 696 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2082.14,2083.33 1 0 697 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2086.3,2086.48 1 2 698 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2086.48,2088.4 1 2 699 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2088.9,2092.4 3 0 700 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2095.2,2095.10 1 10 701 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2098.44,2101.2 2 10 702 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2103.46,2108.2 4 6 703 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2110.53,2115.2 4 0 704 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2117.47,2118.38 1 0 705 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2118.38,2120.35 2 0 706 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2120.35,2122.4 1 0 707 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2123.3,2123.15 1 0 708 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2125.2,2125.12 1 0 709 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2128.47,2129.16 1 5 710 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2129.16,2131.3 1 0 711 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2132.2,2132.29 1 5 712 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2134.35,2135.19 1 5 713 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2135.19,2137.3 1 0 714 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2144.2,2144.30 1 5 715 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2144.30,2145.15 1 253 716 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2145.15,2146.12 1 7 717 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2149.3,2150.15 2 246 718 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2150.15,2151.12 1 0 719 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2153.3,2153.25 1 246 720 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2153.25,2155.4 1 5 721 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2158.2,2160.6 3 0 722 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2160.6,2162.16 2 0 723 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2162.16,2163.9 1 0 724 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2165.3,2166.23 2 0 725 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2169.2,2169.41 1 0 726 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2169.41,2171.3 1 0 727 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2173.2,2173.21 1 0 728 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2176.55,2178.28 2 0 729 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2178.28,2180.17 2 0 730 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2180.17,2182.4 1 0 731 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2184.3,2184.13 1 0 732 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2186.2,2186.16 1 0 733 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2189.78,2190.38 1 13 734 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2190.38,2192.3 1 1 735 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2193.2,2193.39 1 12 736 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2193.39,2195.3 1 0 737 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2197.2,2198.70 2 12 738 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2198.70,2200.3 1 0 739 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2200.8,2200.93 1 12 740 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2200.93,2202.3 1 0 741 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2203.2,2203.67 1 12 742 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2203.67,2204.43 1 3 743 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2204.44,2206.4 0 0 744 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2206.9,2208.4 1 3 745 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2209.8,2212.37 2 9 746 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2212.37,2214.4 1 0 747 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2215.3,2215.41 1 9 748 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2215.41,2218.4 1 0 749 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2219.3,2219.71 1 9 750 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2219.71,2221.4 1 0 751 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2221.9,2221.94 1 9 752 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2221.94,2223.4 1 0 753 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2224.3,2224.26 1 9 754 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2224.26,2225.33 1 0 755 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2225.33,2227.5 1 0 756 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2229.4,2229.19 1 0 757 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2232.3,2234.18 3 9 758 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2234.18,2236.4 1 0 759 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2238.3,2239.15 2 9 760 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2239.15,2241.4 1 9 761 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2241.9,2243.19 2 0 762 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2243.19,2246.5 2 0 763 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2248.4,2248.16 1 0 764 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2248.16,2250.5 1 0 765 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2250.10,2252.5 1 0 766 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2255.3,2255.17 1 9 767 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2255.17,2259.17 3 0 768 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2259.17,2260.65 1 0 769 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2260.65,2262.6 1 0 770 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2263.10,2264.86 1 0 771 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2264.86,2266.6 1 0 772 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2269.4,2269.18 1 0 773 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2269.18,2271.5 1 0 774 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2319.2,2319.31 1 12 775 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2319.31,2321.3 1 0 776 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2323.2,2323.17 1 12 777 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2327.40,2327.41 0 0 778 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2354.51,2355.49 1 10 779 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2355.49,2357.3 1 0 780 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2359.2,2360.25 2 10 781 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2360.25,2362.3 1 8 782 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2364.2,2370.38 2 2 783 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2370.38,2371.65 1 1 784 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2371.65,2373.4 1 0 785 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2373.9,2375.4 1 1 786 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2378.2,2378.29 1 2 787 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2378.29,2383.46 4 0 788 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2383.46,2385.4 1 0 789 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2385.9,2387.4 1 0 790 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2390.2,2390.29 1 2 791 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2390.29,2395.47 4 0 792 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2395.47,2397.4 1 0 793 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2397.9,2399.4 1 0 794 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2402.2,2403.29 2 2 795 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2403.29,2408.47 4 0 796 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2408.47,2410.4 1 0 797 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2410.9,2413.4 2 0 798 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2416.2,2416.13 1 2 799 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2417.17,2421.25 1 0 800 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2422.16,2423.33 1 1 801 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2424.18,2425.35 1 0 802 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2426.18,2427.35 1 0 803 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2428.20,2429.37 1 0 804 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2430.20,2431.28 1 0 805 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2432.19,2433.30 1 0 806 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2434.27,2435.32 1 0 807 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2436.33,2438.39 2 0 808 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2438.39,2440.4 1 0 809 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2441.3,2441.16 1 0 810 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2442.20,2443.26 1 0 811 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2444.21,2446.33 2 0 812 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2446.33,2447.49 1 0 813 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2447.49,2449.5 1 0 814 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2449.10,2451.5 1 0 815 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2453.3,2453.16 1 0 816 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2454.20,2456.33 2 0 817 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2456.33,2457.48 1 0 818 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2457.48,2459.5 1 0 819 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2459.10,2461.5 1 0 820 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2463.3,2463.16 1 0 821 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2464.22,2466.33 2 0 822 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2466.33,2467.48 1 0 823 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2467.48,2469.5 1 0 824 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2469.10,2471.5 1 0 825 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2473.3,2473.16 1 0 826 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2474.22,2476.33 2 0 827 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2476.33,2477.48 1 0 828 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2477.48,2479.5 1 0 829 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2479.10,2481.5 1 0 830 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2483.3,2483.16 1 0 831 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2484.24,2486.33 2 0 832 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2486.33,2487.48 1 0 833 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2487.48,2489.5 1 0 834 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2489.10,2491.5 1 0 835 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2493.3,2493.16 1 0 836 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2494.24,2496.33 2 0 837 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2496.33,2497.48 1 0 838 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2497.48,2499.5 1 0 839 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2499.10,2501.5 1 0 840 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2503.3,2503.16 1 0 841 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2504.23,2506.33 2 0 842 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2506.33,2507.51 1 0 843 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2507.51,2509.5 1 0 844 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2509.10,2511.5 1 0 845 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2513.3,2513.16 1 0 846 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2514.31,2516.33 2 0 847 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2516.33,2517.59 1 0 848 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2517.59,2519.5 1 0 849 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2519.10,2521.5 1 0 850 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2523.3,2523.16 1 0 851 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2524.37,2526.33 2 0 852 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2526.33,2527.65 1 0 853 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2527.65,2529.5 1 0 854 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2529.10,2531.5 1 0 855 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2533.3,2533.16 1 0 856 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2534.52,2536.37 2 0 857 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2536.37,2539.24 3 0 858 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2539.24,2541.5 1 0 859 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2542.4,2543.27 2 0 860 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2546.3,2546.31 1 0 861 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2546.31,2552.17 3 0 862 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2552.17,2554.5 1 0 863 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2555.4,2555.25 1 0 864 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2555.25,2561.16 3 0 865 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2561.16,2563.6 1 0 866 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2564.5,2565.33 2 0 867 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2565.33,2567.6 1 0 868 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2568.5,2568.35 1 0 869 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2568.35,2570.14 2 0 870 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2578.5,2579.34 2 0 871 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2579.34,2596.26 2 0 872 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2596.26,2598.7 1 0 873 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2599.6,2599.28 1 0 874 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2599.28,2605.7 1 0 875 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2606.6,2606.19 1 0 876 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2611.3,2611.20 1 0 877 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2612.10,2643.17 2 1 878 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2643.17,2646.15 3 1 879 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2646.15,2648.5 1 1 880 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2649.4,2650.18 2 0 881 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2650.18,2653.5 1 0 882 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2653.11,2656.5 0 0 883 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2657.4,2658.18 2 0 884 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2658.18,2660.5 1 0 885 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2663.3,2663.48 1 0 886 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2707.100,2713.16 2 0 887 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2713.16,2715.3 1 0 888 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2722.2,2723.33 2 0 889 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2723.33,2725.3 1 0 890 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2726.2,2726.20 1 0 891 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2736.146,2740.24 3 0 892 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2740.24,2742.3 1 0 893 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2743.2,2743.16 1 0 894 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2743.16,2745.3 1 0 895 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2747.2,2749.45 3 0 896 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2749.45,2750.14 1 0 897 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2750.14,2752.4 1 0 898 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2752.9,2754.4 1 0 899 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2757.2,2761.16 4 0 900 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2761.16,2763.3 1 0 901 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2764.2,2764.16 1 0 902 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2764.16,2767.3 2 0 903 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2769.2,2771.18 2 0 904 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2771.18,2773.42 2 0 905 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2773.42,2783.40 7 0 906 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2783.40,2786.66 1 0 907 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2786.66,2788.19 2 0 908 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2788.19,2790.25 2 0 909 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2790.25,2791.13 1 0 910 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2797.4,2797.18 1 0 911 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2797.18,2798.46 1 0 912 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2798.46,2803.43 3 0 913 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2803.43,2804.15 1 0 914 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2807.6,2807.37 1 0 915 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2815.2,2815.17 1 0 916 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2823.40,2825.13 1 27 917 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2825.13,2827.3 1 8 918 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2829.2,2829.10 1 19 919 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2829.10,2831.3 1 19 920 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2832.2,2832.20 1 19 921 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2839.28,2841.2 1 19 922 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2843.39,2845.32 2 0 923 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2845.32,2847.3 1 0 924 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2848.2,2848.16 1 0 925 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2855.57,2856.15 1 0 926 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2856.15,2858.3 1 0 927 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2859.2,2861.56 2 0 928 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2861.56,2863.3 1 0 929 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2864.2,2864.15 1 0 930 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2871.48,2872.15 1 0 931 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2872.15,2874.3 1 0 932 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2875.2,2877.58 2 0 933 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2877.58,2879.3 1 0 934 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2880.2,2880.17 1 0 935 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2882.50,2883.16 1 6 936 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2883.16,2885.3 1 0 937 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2887.2,2887.50 1 6 938 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2887.50,2889.3 1 0 939 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2889.8,2891.3 1 6 940 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2902.50,2907.2 4 4 941 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2924.24,2925.2 0 0 942 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2926.26,2927.2 0 0 943 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2944.49,2946.2 1 0 944 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2948.52,2950.2 1 0 945 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2952.67,2953.27 1 0 946 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2953.27,2955.3 1 0 947 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2956.2,2956.31 1 0 948 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2964.77,2965.27 1 0 949 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2965.27,2967.3 1 0 950 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2968.2,2968.35 1 0 951 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2972.74,2980.2 1 0 952 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2982.114,2998.24 5 0 953 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:2998.24,3003.30 1 0 954 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3004.23,3007.43 3 0 955 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3008.11,3009.24 1 0 956 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3014.2,3016.18 3 0 957 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3016.18,3018.3 1 0 958 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3020.2,3021.17 2 0 959 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3021.17,3022.34 1 0 960 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3022.34,3025.16 3 0 961 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3025.16,3027.5 1 0 962 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3029.4,3029.40 1 0 963 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3032.3,3032.47 1 0 964 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3036.2,3037.34 2 0 965 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3037.34,3039.3 1 0 966 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3041.2,3043.39 3 0 967 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3043.39,3045.3 1 0 968 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3045.8,3047.3 1 0 969 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3049.2,3055.30 5 0 970 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3055.30,3057.3 1 0 971 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3059.2,3060.12 2 0 972 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3060.12,3062.3 1 0 973 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3065.2,3070.21 4 0 974 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3070.21,3072.17 2 0 975 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3072.17,3074.4 1 0 976 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3077.2,3078.16 2 0 977 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3078.16,3080.3 1 0 978 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3082.2,3084.16 2 0 979 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3084.16,3086.20 2 0 980 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3086.20,3087.20 1 0 981 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3087.20,3089.5 1 0 982 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3089.10,3091.5 1 0 983 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3094.3,3094.106 1 0 984 | github.com/TommyLemon/unitauto-go/unitauto/method_util.go:3097.2,3097.19 1 0 985 | github.com/TommyLemon/unitauto-go/unitauto/server.go:22.13,78.99 50 2 986 | github.com/TommyLemon/unitauto-go/unitauto/server.go:78.99,79.13 1 1 987 | github.com/TommyLemon/unitauto-go/unitauto/server.go:79.13,80.53 1 1 988 | github.com/TommyLemon/unitauto-go/unitauto/server.go:80.53,83.5 2 0 989 | github.com/TommyLemon/unitauto-go/unitauto/server.go:84.4,84.54 1 1 990 | github.com/TommyLemon/unitauto-go/unitauto/server.go:84.54,87.5 2 1 991 | github.com/TommyLemon/unitauto-go/unitauto/server.go:88.4,88.53 1 0 992 | github.com/TommyLemon/unitauto-go/unitauto/server.go:88.53,91.5 2 0 993 | github.com/TommyLemon/unitauto-go/unitauto/server.go:92.4,92.54 1 0 994 | github.com/TommyLemon/unitauto-go/unitauto/server.go:92.54,95.5 2 0 995 | github.com/TommyLemon/unitauto-go/unitauto/server.go:96.4,96.56 1 0 996 | github.com/TommyLemon/unitauto-go/unitauto/server.go:96.56,99.5 2 0 997 | github.com/TommyLemon/unitauto-go/unitauto/server.go:100.4,100.57 1 0 998 | github.com/TommyLemon/unitauto-go/unitauto/server.go:100.57,103.5 2 0 999 | github.com/TommyLemon/unitauto-go/unitauto/server.go:104.4,104.61 1 0 1000 | github.com/TommyLemon/unitauto-go/unitauto/server.go:104.61,107.5 2 0 1001 | github.com/TommyLemon/unitauto-go/unitauto/server.go:108.4,108.62 1 0 1002 | github.com/TommyLemon/unitauto-go/unitauto/server.go:108.62,111.5 2 0 1003 | github.com/TommyLemon/unitauto-go/unitauto/server.go:112.4,112.49 1 0 1004 | github.com/TommyLemon/unitauto-go/unitauto/server.go:112.49,116.5 3 0 1005 | github.com/TommyLemon/unitauto-go/unitauto/server.go:117.4,117.50 1 0 1006 | github.com/TommyLemon/unitauto-go/unitauto/server.go:117.50,121.5 3 0 1007 | github.com/TommyLemon/unitauto-go/unitauto/server.go:124.3,124.48 1 0 1008 | github.com/TommyLemon/unitauto-go/unitauto/server.go:142.36,148.2 2 0 1009 | github.com/TommyLemon/unitauto-go/unitauto/server.go:149.37,155.2 2 0 1010 | github.com/TommyLemon/unitauto-go/unitauto/server.go:157.22,158.14 1 1 1011 | github.com/TommyLemon/unitauto-go/unitauto/server.go:158.14,160.3 1 1 1012 | github.com/TommyLemon/unitauto-go/unitauto/server.go:161.2,163.12 2 1 1013 | github.com/TommyLemon/unitauto-go/unitauto/server.go:163.12,165.3 1 1 1014 | github.com/TommyLemon/unitauto-go/unitauto/server.go:167.2,170.16 4 1 1015 | github.com/TommyLemon/unitauto-go/unitauto/server.go:170.16,172.3 1 0 1016 | github.com/TommyLemon/unitauto-go/unitauto/server.go:176.53,177.36 1 0 1017 | github.com/TommyLemon/unitauto-go/unitauto/server.go:177.36,182.3 3 0 1018 | github.com/TommyLemon/unitauto-go/unitauto/server.go:184.2,184.33 1 0 1019 | github.com/TommyLemon/unitauto-go/unitauto/server.go:184.33,187.3 2 0 1020 | github.com/TommyLemon/unitauto-go/unitauto/server.go:189.2,191.53 2 0 1021 | github.com/TommyLemon/unitauto-go/unitauto/server.go:191.53,195.3 3 0 1022 | github.com/TommyLemon/unitauto-go/unitauto/server.go:195.8,202.35 5 0 1023 | github.com/TommyLemon/unitauto-go/unitauto/server.go:202.35,204.4 1 0 1024 | github.com/TommyLemon/unitauto-go/unitauto/server.go:204.9,204.44 1 0 1025 | github.com/TommyLemon/unitauto-go/unitauto/server.go:204.44,217.128 2 0 1026 | github.com/TommyLemon/unitauto-go/unitauto/server.go:217.128,218.26 1 0 1027 | github.com/TommyLemon/unitauto-go/unitauto/server.go:218.26,220.6 1 0 1028 | github.com/TommyLemon/unitauto-go/unitauto/server.go:221.5,223.56 2 0 1029 | github.com/TommyLemon/unitauto-go/unitauto/server.go:223.56,226.6 1 0 1030 | github.com/TommyLemon/unitauto-go/unitauto/server.go:226.11,227.15 1 0 1031 | github.com/TommyLemon/unitauto-go/unitauto/server.go:227.15,229.7 1 0 1032 | github.com/TommyLemon/unitauto-go/unitauto/server.go:231.6,232.21 2 0 1033 | github.com/TommyLemon/unitauto-go/unitauto/server.go:232.21,234.7 1 0 1034 | github.com/TommyLemon/unitauto-go/unitauto/server.go:234.12,236.7 1 0 1035 | github.com/TommyLemon/unitauto-go/unitauto/server.go:240.5,243.15 2 0 1036 | github.com/TommyLemon/unitauto-go/unitauto/server.go:244.19,246.9 1 0 1037 | github.com/TommyLemon/unitauto-go/unitauto/server.go:246.9,247.27 1 0 1038 | github.com/TommyLemon/unitauto-go/unitauto/server.go:247.27,248.12 1 0 1039 | github.com/TommyLemon/unitauto-go/unitauto/server.go:250.6,250.48 1 0 1040 | github.com/TommyLemon/unitauto-go/unitauto/server.go:253.5,253.11 1 0 1041 | github.com/TommyLemon/unitauto-go/unitauto/server.go:254.10,256.5 1 0 1042 | github.com/TommyLemon/unitauto-go/unitauto/server.go:257.9,259.4 1 0 1043 | github.com/TommyLemon/unitauto-go/unitauto/server.go:261.3,261.24 1 0 1044 | github.com/TommyLemon/unitauto-go/unitauto/server.go:261.24,263.4 1 0 1045 | github.com/TommyLemon/unitauto-go/unitauto/server.go:264.3,266.57 2 0 1046 | github.com/TommyLemon/unitauto-go/unitauto/server.go:266.57,268.4 1 0 1047 | github.com/TommyLemon/unitauto-go/unitauto/server.go:268.9,270.18 2 0 1048 | github.com/TommyLemon/unitauto-go/unitauto/server.go:270.18,272.5 1 0 1049 | github.com/TommyLemon/unitauto-go/unitauto/server.go:272.10,274.5 1 0 1050 | github.com/TommyLemon/unitauto-go/unitauto/server.go:278.3,278.21 1 0 1051 | github.com/TommyLemon/unitauto-go/unitauto/server.go:283.51,285.21 2 0 1052 | github.com/TommyLemon/unitauto-go/unitauto/server.go:285.21,287.3 1 0 1053 | github.com/TommyLemon/unitauto-go/unitauto/server.go:289.2,290.20 2 0 1054 | github.com/TommyLemon/unitauto-go/unitauto/server.go:290.20,292.3 1 0 1055 | github.com/TommyLemon/unitauto-go/unitauto/server.go:293.2,293.19 1 0 1056 | github.com/TommyLemon/unitauto-go/unitauto/server.go:293.19,295.3 1 0 1057 | github.com/TommyLemon/unitauto-go/unitauto/server.go:297.2,301.57 5 0 1058 | github.com/TommyLemon/unitauto-go/unitauto/server.go:306.13,316.93 2 1 1059 | github.com/TommyLemon/unitauto-go/unitauto/server.go:316.93,320.3 3 1 1060 | github.com/TommyLemon/unitauto-go/unitauto/server.go:322.2,336.93 1 1 1061 | github.com/TommyLemon/unitauto-go/unitauto/server.go:336.93,340.3 3 1 1062 | github.com/TommyLemon/unitauto-go/unitauto/server.go:342.2,347.93 1 1 1063 | github.com/TommyLemon/unitauto-go/unitauto/server.go:347.93,351.3 3 1 1064 | github.com/TommyLemon/unitauto-go/unitauto/server.go:353.2,367.93 1 1 1065 | github.com/TommyLemon/unitauto-go/unitauto/server.go:367.93,371.3 3 1 1066 | github.com/TommyLemon/unitauto-go/unitauto/server.go:373.2,381.93 1 1 1067 | github.com/TommyLemon/unitauto-go/unitauto/server.go:381.93,385.3 3 1 1068 | github.com/TommyLemon/unitauto-go/unitauto/server.go:387.2,409.93 1 1 1069 | github.com/TommyLemon/unitauto-go/unitauto/server.go:409.93,413.3 3 1 1070 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:9.29,11.2 1 1 1071 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:13.28,15.2 1 0 1072 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:17.36,19.2 1 1 1073 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:21.45,23.2 1 0 1074 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:25.35,27.2 1 0 1075 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:29.153,31.2 1 1 1076 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:33.70,34.12 1 1 1077 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:34.12,37.12 3 1 1078 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:37.12,39.4 1 1 1079 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:39.9,41.4 1 0 1080 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:42.3,42.48 1 1 1081 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:44.2,44.14 1 1 1082 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:56.46,59.2 1 0 1083 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:60.47,63.2 1 0 1084 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:65.38,67.2 1 0 1085 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:68.39,70.2 1 0 1086 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:72.54,73.12 1 0 1087 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:73.12,75.15 2 0 1088 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:75.15,77.4 1 0 1089 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:77.9,79.4 1 0 1090 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:88.31,90.2 1 1 1091 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:92.36,94.2 1 0 1092 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:96.33,98.2 1 0 1093 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:100.40,102.2 1 1 1094 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:104.35,106.2 1 3 1095 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:108.36,109.20 1 0 1096 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:109.20,111.3 1 0 1097 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:112.2,112.19 1 0 1098 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:112.19,114.3 1 0 1099 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:115.2,115.10 1 0 1100 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:118.17,123.2 1 0 1101 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:134.46,136.2 1 0 1102 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:147.47,150.2 2 0 1103 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:152.53,154.2 1 0 1104 | github.com/TommyLemon/unitauto-go/unitauto/test/test_util.go:156.42,159.2 2 0 1105 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TommyLemon/unitauto-go 2 | 3 | go 1.18 4 | 5 | //require github.com/iancoleman/orderedmap v0.2.0 -------------------------------------------------------------------------------- /goc.log: -------------------------------------------------------------------------------- 1 | [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. 2 | 3 | [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. 4 | - using env: export GIN_MODE=release 5 | - using code: gin.SetMode(gin.ReleaseMode) 6 | 7 | [GIN-debug] GET /static --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (3 handlers) 8 | [GIN-debug] HEAD /static --> github.com/gin-gonic/gin.(*RouterGroup).StaticFile.func1 (3 handlers) 9 | [GIN-debug] POST /v1/cover/register --> github.com/qiniu/goc/pkg/cover.(*server).registerService-fm (3 handlers) 10 | [GIN-debug] GET /v1/cover/profile --> github.com/qiniu/goc/pkg/cover.(*server).profile-fm (3 handlers) 11 | [GIN-debug] POST /v1/cover/profile --> github.com/qiniu/goc/pkg/cover.(*server).profile-fm (3 handlers) 12 | [GIN-debug] POST /v1/cover/clear --> github.com/qiniu/goc/pkg/cover.(*server).clear-fm (3 handlers) 13 | [GIN-debug] POST /v1/cover/init --> github.com/qiniu/goc/pkg/cover.(*server).initSystem-fm (3 handlers) 14 | [GIN-debug] GET /v1/cover/list --> github.com/qiniu/goc/pkg/cover.(*server).listServices-fm (3 handlers) 15 | [GIN-debug] POST /v1/cover/remove --> github.com/qiniu/goc/pkg/cover.(*server).removeServices-fm (3 handlers) 16 | [GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value. 17 | Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details. 18 | [GIN-debug] Listening and serving HTTP on :7777 19 | [GIN] 2023/08/19 - 20:57:27 | 200 | 17.876833ms | 127.0.0.1 | POST "/v1/cover/profile" 20 | -------------------------------------------------------------------------------- /iancoleman/orderedmap.go: -------------------------------------------------------------------------------- 1 | package orderedmap 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "sort" 7 | ) 8 | 9 | type Pair struct { 10 | key string 11 | value interface{} 12 | } 13 | 14 | func (kv *Pair) Key() string { 15 | return kv.key 16 | } 17 | 18 | func (kv *Pair) Value() interface{} { 19 | return kv.value 20 | } 21 | 22 | type ByPair struct { 23 | Pairs []*Pair 24 | LessFunc func(a *Pair, j *Pair) bool 25 | } 26 | 27 | func (a ByPair) Len() int { return len(a.Pairs) } 28 | func (a ByPair) Swap(i, j int) { a.Pairs[i], a.Pairs[j] = a.Pairs[j], a.Pairs[i] } 29 | func (a ByPair) Less(i, j int) bool { return a.LessFunc(a.Pairs[i], a.Pairs[j]) } 30 | 31 | type OrderedMap struct { 32 | keys []string 33 | values map[string]interface{} 34 | escapeHTML bool 35 | } 36 | 37 | func New() *OrderedMap { 38 | o := OrderedMap{} 39 | o.keys = []string{} 40 | o.values = map[string]interface{}{} 41 | o.escapeHTML = true 42 | return &o 43 | } 44 | 45 | func (o *OrderedMap) SetEscapeHTML(on bool) { 46 | o.escapeHTML = on 47 | } 48 | 49 | func (o *OrderedMap) Get(key string) (interface{}, bool) { 50 | if o.values == nil { 51 | return nil, false 52 | } 53 | val, exists := o.values[key] 54 | return val, exists 55 | } 56 | 57 | func (o *OrderedMap) Set(key string, value interface{}) { 58 | if o.values == nil { 59 | o.values = map[string]interface{}{} 60 | } 61 | _, exists := o.values[key] 62 | if !exists { 63 | o.keys = append(o.keys, key) 64 | } 65 | o.values[key] = value 66 | } 67 | 68 | func (o *OrderedMap) Delete(key string) { 69 | // check key is in use 70 | _, ok := o.values[key] 71 | if !ok { 72 | return 73 | } 74 | // remove from keys 75 | for i, k := range o.keys { 76 | if k == key { 77 | o.keys = append(o.keys[:i], o.keys[i+1:]...) 78 | break 79 | } 80 | } 81 | // remove from values 82 | delete(o.values, key) 83 | } 84 | 85 | func (o *OrderedMap) Keys() []string { 86 | return o.keys 87 | } 88 | 89 | // SortKeys Sort the map keys using your sort func 90 | func (o *OrderedMap) SortKeys(sortFunc func(keys []string)) { 91 | sortFunc(o.keys) 92 | } 93 | 94 | // Sort Sort the map using your sort func 95 | func (o *OrderedMap) Sort(lessFunc func(a *Pair, b *Pair) bool) { 96 | pairs := make([]*Pair, len(o.keys)) 97 | for i, key := range o.keys { 98 | pairs[i] = &Pair{key, o.values[key]} 99 | } 100 | 101 | sort.Sort(ByPair{pairs, lessFunc}) 102 | 103 | for i, pair := range pairs { 104 | o.keys[i] = pair.key 105 | } 106 | } 107 | 108 | func (o *OrderedMap) UnmarshalJSON(b []byte) error { 109 | if o.values == nil { 110 | o.values = map[string]interface{}{} 111 | } 112 | err := json.Unmarshal(b, &o.values) 113 | if err != nil { 114 | return err 115 | } 116 | dec := json.NewDecoder(bytes.NewReader(b)) 117 | if _, err = dec.Token(); err != nil { // skip '{' 118 | return err 119 | } 120 | o.keys = make([]string, 0, len(o.values)) 121 | return decodeOrderedMap(dec, o) 122 | } 123 | 124 | func decodeOrderedMap(dec *json.Decoder, o *OrderedMap) error { 125 | hasKey := make(map[string]bool, len(o.values)) 126 | for { 127 | token, err := dec.Token() 128 | if err != nil { 129 | return err 130 | } 131 | if delim, ok := token.(json.Delim); ok && delim == '}' { 132 | return nil 133 | } 134 | key := token.(string) 135 | if hasKey[key] { 136 | // duplicate key 137 | for j, k := range o.keys { 138 | if k == key { 139 | copy(o.keys[j:], o.keys[j+1:]) 140 | break 141 | } 142 | } 143 | o.keys[len(o.keys)-1] = key 144 | } else { 145 | hasKey[key] = true 146 | o.keys = append(o.keys, key) 147 | } 148 | 149 | token, err = dec.Token() 150 | if err != nil { 151 | return err 152 | } 153 | if delim, ok := token.(json.Delim); ok { 154 | switch delim { 155 | case '{': 156 | if values, ok := o.values[key].(map[string]interface{}); ok { 157 | newMap := OrderedMap{ 158 | keys: make([]string, 0, len(values)), 159 | values: values, 160 | escapeHTML: o.escapeHTML, 161 | } 162 | if err = decodeOrderedMap(dec, &newMap); err != nil { 163 | return err 164 | } 165 | o.values[key] = newMap 166 | } else if oldMap, ok := o.values[key].(OrderedMap); ok { 167 | newMap := OrderedMap{ 168 | keys: make([]string, 0, len(oldMap.values)), 169 | values: oldMap.values, 170 | escapeHTML: o.escapeHTML, 171 | } 172 | if err = decodeOrderedMap(dec, &newMap); err != nil { 173 | return err 174 | } 175 | o.values[key] = newMap 176 | } else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil { 177 | return err 178 | } 179 | case '[': 180 | if values, ok := o.values[key].([]interface{}); ok { 181 | if err = decodeSlice(dec, values, o.escapeHTML); err != nil { 182 | return err 183 | } 184 | } else if err = decodeSlice(dec, []interface{}{}, o.escapeHTML); err != nil { 185 | return err 186 | } 187 | } 188 | } 189 | } 190 | } 191 | 192 | func decodeSlice(dec *json.Decoder, s []interface{}, escapeHTML bool) error { 193 | for index := 0; ; index++ { 194 | token, err := dec.Token() 195 | if err != nil { 196 | return err 197 | } 198 | if delim, ok := token.(json.Delim); ok { 199 | switch delim { 200 | case '{': 201 | if index < len(s) { 202 | if values, ok := s[index].(map[string]interface{}); ok { 203 | newMap := OrderedMap{ 204 | keys: make([]string, 0, len(values)), 205 | values: values, 206 | escapeHTML: escapeHTML, 207 | } 208 | if err = decodeOrderedMap(dec, &newMap); err != nil { 209 | return err 210 | } 211 | s[index] = newMap 212 | } else if oldMap, ok := s[index].(OrderedMap); ok { 213 | newMap := OrderedMap{ 214 | keys: make([]string, 0, len(oldMap.values)), 215 | values: oldMap.values, 216 | escapeHTML: escapeHTML, 217 | } 218 | if err = decodeOrderedMap(dec, &newMap); err != nil { 219 | return err 220 | } 221 | s[index] = newMap 222 | } else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil { 223 | return err 224 | } 225 | } else if err = decodeOrderedMap(dec, &OrderedMap{}); err != nil { 226 | return err 227 | } 228 | case '[': 229 | if index < len(s) { 230 | if values, ok := s[index].([]interface{}); ok { 231 | if err = decodeSlice(dec, values, escapeHTML); err != nil { 232 | return err 233 | } 234 | } else if err = decodeSlice(dec, []interface{}{}, escapeHTML); err != nil { 235 | return err 236 | } 237 | } else if err = decodeSlice(dec, []interface{}{}, escapeHTML); err != nil { 238 | return err 239 | } 240 | case ']': 241 | return nil 242 | } 243 | } 244 | } 245 | } 246 | 247 | func (o OrderedMap) MarshalJSON() ([]byte, error) { 248 | var buf bytes.Buffer 249 | buf.WriteByte('{') 250 | encoder := json.NewEncoder(&buf) 251 | encoder.SetEscapeHTML(o.escapeHTML) 252 | for i, k := range o.keys { 253 | if i > 0 { 254 | buf.WriteByte(',') 255 | } 256 | // add key 257 | if err := encoder.Encode(k); err != nil { 258 | return nil, err 259 | } 260 | buf.WriteByte(':') 261 | // add value 262 | if err := encoder.Encode(o.values[k]); err != nil { 263 | return nil, err 264 | } 265 | } 266 | buf.WriteByte('}') 267 | return buf.Bytes(), nil 268 | } 269 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Go Coverage Report 7 | 52 | 53 | 54 |
55 | 60 |
61 | not tracked 62 | 63 | no coverage 64 | low coverage 65 | * 66 | * 67 | * 68 | * 69 | * 70 | * 71 | * 72 | * 73 | high coverage 74 | 75 |
76 |
77 |
78 | 79 |
80 | 81 | 108 | 109 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/TommyLemon/unitauto-go/unitauto" 5 | ) 6 | 7 | func main() { 8 | // TODO 改成你项目的 module 路径 unitauto.DEFAULT_MODULE_PATH = "github.com/TommyLemon/unitauto-go" 9 | 10 | unitauto.Test() 11 | unitauto.Start(8082) 12 | } 13 | -------------------------------------------------------------------------------- /unitauto-go: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TommyLemon/unitauto-go/5a1548b93d126a95318d556c4938423b1646f0a0/unitauto-go -------------------------------------------------------------------------------- /unitauto-go_profile_listen_addr: -------------------------------------------------------------------------------- 1 | 192.168.100.4:51675 -------------------------------------------------------------------------------- /unitauto/method_util.go: -------------------------------------------------------------------------------- 1 | /*Copyright ©2019 TommyLemon(https://github.com/TommyLemon/UnitAuto) 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License") 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License.*/ 14 | 15 | package unitauto 16 | 17 | import ( 18 | "container/list" 19 | "encoding/json" 20 | "errors" 21 | "fmt" 22 | orderedmap "github.com/TommyLemon/unitauto-go/iancoleman" 23 | "go/importer" 24 | "go/token" 25 | "go/types" 26 | "math/rand" 27 | "reflect" 28 | "regexp" 29 | "strconv" 30 | "strings" 31 | "time" 32 | ) 33 | 34 | /**方法/函数的工具类 35 | * @author Lemon 36 | */ 37 | var TAG = "MethodUtil" 38 | var DEFAULT_MODULE_PATH = "github.com/TommyLemon/unitauto-go" 39 | 40 | //type Listener[T any] interface { 41 | // Complete(data T, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error 42 | //} 43 | 44 | type Listener[T any] func(data T, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error 45 | 46 | type SimpleComplete func(data any) error 47 | type Complete func(data any, method reflect.Method, proxy InterfaceProxy, extras ...any) error 48 | type Callback func(data any, method reflect.Method, proxy InterfaceProxy, extras ...any) error 49 | 50 | var KEY_CODE = "code" 51 | var KEY_MSG = "msg" 52 | 53 | var CODE_SUCCESS = 200 54 | var CODE_SERVER_ERROR = 500 55 | var MSG_SUCCESS = "success" 56 | 57 | var KEY_LANGUAGE = "language" 58 | var KEY_REUSE = "reuse" 59 | var KEY_UI = "ui" 60 | var KEY_TIME = "@time" 61 | var KEY_TIMEOUT = "timeout" 62 | var KEY_PACKAGE = "package" 63 | var KEY_THIS = "this" 64 | var KEY_CLASS = "class" 65 | var KEY_CONSTRUCTOR = "constructor" 66 | var KEY_TYPE = "type" 67 | var KEY_AT_TYPE = "@type" 68 | var KEY_VALUE = "value" 69 | var KEY_WARN = "warn" 70 | var KEY_STATIC = "static" 71 | var KEY_NAME = "name" 72 | var KEY_METHOD = "method" 73 | var KEY_MOCK = "mock" 74 | var KEY_QUERY = "query" 75 | var KEY_RETURN = "return" 76 | var KEY_TIME_DETAIL = "time:start|duration|end" 77 | var KEY_CLASS_ARGS = "classArgs" 78 | var KEY_METHOD_ARGS = "methodArgs" 79 | var KEY_ARGS = "args" 80 | var KEY_CALLBACK = "callback" 81 | var KEY_GLOBAL = "global" 82 | 83 | var KEY_CALL_LIST = "call()[]" 84 | var KEY_CALL_MAP = "call(){}" 85 | var KEY_PACKAGE_TOTAL = "packageTotal" 86 | var KEY_CLASS_TOTAL = "classTotal" 87 | var KEY_METHOD_TOTAL = "methodTotal" 88 | var KEY_PACKAGE_LIST = "packageList" 89 | var KEY_CLASS_LIST = "classList" 90 | var KEY_METHOD_LIST = "methodList" 91 | 92 | // GetInstance 不能在 static 代码块赋值,否则 MethodUtil 子类中 static 代码块对它赋值的代码不会执行! 93 | var GetInstance = func(typ reflect.Type, value any, classArgs []Argument, reuse bool) (any, error) { 94 | return GetInvokeInstance(typ, value, classArgs, reuse) 95 | } 96 | 97 | var LoadStruct = func(packageOrFileName string, className string, ignoreError bool) (reflect.Type, error) { 98 | if s, err := FindClass(packageOrFileName, className, ignoreError); err != nil { 99 | return nil, err 100 | } else { 101 | return reflect.TypeOf(reflect.ValueOf(s)), nil 102 | } 103 | } 104 | 105 | var LoadStructList = func(packageOrFileName string, className string, ignoreError bool, limit int, offset int) ([]reflect.Type, error) { 106 | var lst, err = FindClassList(packageOrFileName, className, ignoreError, limit, offset, true) 107 | if err != nil || len(lst) <= 0 { 108 | return nil, err 109 | } 110 | 111 | var nl = make([]reflect.Type, len(lst)) 112 | for i, s := range lst { 113 | nl[i] = reflect.TypeOf(reflect.ValueOf(s)) // reflect.TypeOf(s) 114 | } 115 | return nl, nil 116 | } 117 | 118 | // LoadClass 不能在 static 代码块赋值,否则 MethodUtil 子类中 static 代码块对它赋值的代码不会执行! 119 | var LoadClass = func(packageOrFileName string, className string, ignoreError bool) (types.Object, error) { 120 | return FindClass(packageOrFileName, className, ignoreError) 121 | } 122 | 123 | var LoadClassList = func(packageOrFileName string, className string, ignoreError bool, limit int, offset int) ([]types.Object, error) { 124 | return FindClassList(packageOrFileName, className, ignoreError, limit, offset, false) 125 | } 126 | 127 | var PRIMITIVE_CLASS_MAP = map[string]any{ 128 | "any": (any)(nil), 129 | "interface{}": (interface{})(nil), 130 | "bool": false, 131 | "byte": byte(0), 132 | "int": int(0), 133 | "int8": int8(0), 134 | "int16": int16(0), 135 | "int32": int32(0), 136 | "int64": int64(0), 137 | "uint": uint(0), 138 | "uint8": uint8(0), 139 | "uint16": uint16(0), 140 | "uint32": uint32(0), 141 | "uint64": uint64(0), 142 | "float32": float32(0), 143 | "float64": float64(0), 144 | "string": "", 145 | } 146 | 147 | var BASE_CLASS_MAP = map[string]any{ 148 | "any": (any)(nil), 149 | "interface{}": (interface{})(nil), 150 | "bool": false, 151 | "byte": byte(0), 152 | "int": int(0), 153 | "int8": int8(0), 154 | "int16": int16(0), 155 | "int32": int32(0), 156 | "int64": int64(0), 157 | "uint": uint(0), 158 | "uint8": uint8(0), 159 | "uint16": uint16(0), 160 | "uint32": uint32(0), 161 | "uint64": uint64(0), 162 | "float32": float32(0), 163 | "float64": float64(0), 164 | "string": "", 165 | } 166 | var CLASS_MAP = map[string]any{ 167 | "any": (any)(nil), 168 | "interface{}": (interface{})(nil), 169 | "bool": false, 170 | "byte": byte(0), 171 | "int": int(0), 172 | "int8": int8(0), 173 | "int16": int16(0), 174 | "int32": int32(0), 175 | "int64": int64(0), 176 | "uint": uint(0), 177 | "uint8": uint8(0), 178 | "uint16": uint16(0), 179 | "uint32": uint32(0), 180 | "uint64": uint64(0), 181 | "float32": float32(0), 182 | "float64": float64(0), 183 | "string": "", 184 | "[]bool": []bool{}, 185 | "[]byte": []byte{}, 186 | "[]int": []int{}, 187 | "[]int8": []int8{}, 188 | "[]int16": []int16{}, 189 | "[]int32": []int32{}, 190 | "[]int64": []int64{}, 191 | "[]uint": []uint{}, 192 | "[]uint8": []uint8{}, 193 | "[]uint16": []uint16{}, 194 | "[]uint32": []uint32{}, 195 | "[]uint64": []uint64{}, 196 | "[]float32": []float32{}, 197 | "[]float64": []float64{}, 198 | "[]string": []string{}, 199 | "[]any": []any{}, 200 | "map": map[any]any{}, 201 | "map[any]any": map[any]any{}, 202 | "map[string]any": map[string]any{}, 203 | "map[string]string": map[string]string{}, 204 | "Array": types.Array{}, 205 | "*Array": &types.Array{}, 206 | "List": list.List{}, 207 | "*List": &list.List{}, 208 | "Map": types.Map{}, 209 | "*Map": &types.Map{}, 210 | } 211 | 212 | var DEFAULT_TYPE_VALUE_MAP = map[reflect.Type]any{} 213 | var INSTANCE_MAP = map[reflect.Type]any{} 214 | 215 | func GetBool(m map[string]any, k string) bool { 216 | if m == nil { 217 | return false 218 | } 219 | v := m[k] 220 | if v == nil { 221 | return false 222 | } 223 | return v == true 224 | } 225 | 226 | func GetInt(m map[string]any, k string) int { 227 | if m == nil { 228 | return 0 229 | } 230 | v := m[k] 231 | if v == nil { 232 | return 0 233 | } 234 | 235 | switch v.(type) { 236 | case int32: 237 | return int(v.(int32)) 238 | case int64: 239 | return int(v.(int64)) 240 | case float32: 241 | return int(v.(float32)) 242 | case float64: 243 | return int(v.(float64)) 244 | } 245 | return v.(int) 246 | } 247 | 248 | func GetInt32(m map[string]any, k string) int32 { 249 | if m == nil { 250 | return 0 251 | } 252 | v := m[k] 253 | if v == nil { 254 | return 0 255 | } 256 | 257 | switch v.(type) { 258 | case int: 259 | return int32(v.(int)) 260 | case int64: 261 | return int32(v.(int64)) 262 | case float32: 263 | return int32(v.(float32)) 264 | case float64: 265 | return int32(v.(float64)) 266 | } 267 | return v.(int32) 268 | } 269 | 270 | func GetInt64(m map[string]any, k string) int64 { 271 | if m == nil { 272 | return 0 273 | } 274 | v := m[k] 275 | if v == nil { 276 | return 0 277 | } 278 | switch v.(type) { 279 | case int: 280 | return int64(v.(int)) 281 | case int32: 282 | return int64(v.(int32)) 283 | case float32: 284 | return int64(v.(float32)) 285 | case float64: 286 | return int64(v.(float64)) 287 | } 288 | return v.(int64) 289 | } 290 | 291 | func GetStr(m map[string]any, k string) string { 292 | if m == nil { 293 | return "" 294 | } 295 | v := m[k] 296 | if v == nil { 297 | return "" 298 | } 299 | return fmt.Sprint(v) 300 | } 301 | 302 | func GetMap(m map[string]any, k string) map[string]any { 303 | if m == nil { 304 | return nil 305 | } 306 | v := m[k] 307 | if v == nil { 308 | return nil 309 | } 310 | return v.(map[string]any) 311 | } 312 | 313 | func GetArr(m map[string]any, k string) []any { 314 | if m == nil { 315 | return nil 316 | } 317 | v := m[k] 318 | if v == nil { 319 | return nil 320 | } 321 | switch v.(type) { 322 | case []map[string]any: 323 | var m2 = make([]any, len(v.([]map[string]any))) 324 | for i2, v2 := range v.([]map[string]any) { 325 | m2[i2] = v2 326 | } 327 | return m2 328 | //case []map[string]interface{}: 329 | // var m2 = make([]interface{, len(v.([]map[string]interface{))) 330 | // for i2, v2 := range v.([]map[string]interface{) { 331 | // m2[i2] = v2 332 | // } 333 | // return m2 334 | } 335 | return v.([]any) 336 | } 337 | 338 | func GetMapArr(m map[string]any, k string) []map[string]any { 339 | if m == nil { 340 | return nil 341 | } 342 | v := m[k] 343 | if v == nil { 344 | return nil 345 | } 346 | return v.([]map[string]any) 347 | } 348 | 349 | func GetJSONObject(m map[string]any, k string) orderedmap.OrderedMap { 350 | o := orderedmap.New() 351 | if m == nil { 352 | return *o 353 | } 354 | v := m[k] 355 | if v == nil { 356 | return *o 357 | } 358 | 359 | for k, v := range v.(map[string]any) { 360 | o.Set(k, v) 361 | } 362 | return *o 363 | } 364 | 365 | func GetJSONList(m orderedmap.OrderedMap, k string) list.List { 366 | l := list.New() 367 | v, exists := m.Get(k) 368 | if exists == false || v == nil || reflect.TypeOf(v).String() != "[]any" { 369 | return *l 370 | } 371 | 372 | arr := v.([]any) 373 | 374 | for i := 0; i < len(arr); i++ { 375 | l.PushBack(arr[i]) 376 | } 377 | 378 | return *l 379 | } 380 | 381 | func GetJSONArray(m orderedmap.OrderedMap, k string) []any { 382 | v, exists := m.Get(k) 383 | if exists == false || v == nil { 384 | return nil 385 | } 386 | return v.([]any) 387 | } 388 | 389 | func GetList(m map[string]any, k string) list.List { 390 | if m == nil { 391 | return *list.New() 392 | } 393 | v := m[k] 394 | if v == nil { 395 | return *list.New() 396 | } 397 | 398 | return v.(list.List) 399 | } 400 | 401 | func ListMethodByStr(request string) map[string]any { 402 | if req, err := ParseMap(request); err == nil { 403 | return ListMethod(req) 404 | } else { 405 | fmt.Println(err.Error()) 406 | return NewErrorResult(err) 407 | } 408 | } 409 | 410 | /* 411 | *获取方法列表 412 | - @param request : 413 | { 414 | "mock": true, 415 | "query": 0, // 0-数据,1-总数,2-全部 416 | "package": "apijson.demo.server", 417 | "class": "DemoFunction", 418 | "method": "plus", 419 | "types": ["Integer", "String", "com.alibaba.fastjson.JSONObject"] 420 | //不返回的话,这个接口没意义 "return": true, //返回 class list,方便调试 421 | } 422 | - @return 423 | */ 424 | func ListMethod(req map[string]any) map[string]any { 425 | var result map[string]any 426 | 427 | if req == nil { 428 | req = map[string]any{} 429 | } 430 | 431 | var query = GetInt(req, KEY_QUERY) 432 | var mock = GetBool(req, KEY_MOCK) 433 | var pkgName = GetStr(req, KEY_PACKAGE) 434 | var clsName = GetStr(req, KEY_CLASS) 435 | var methodName = GetStr(req, KEY_METHOD) 436 | 437 | var allMethod = IsEmpty(methodName, true) 438 | 439 | var argTypes []reflect.Type = nil 440 | if allMethod == false { 441 | var methodArgTypes = req["types"] 442 | var t = reflect.TypeOf(methodArgTypes).String() 443 | if t == "[]any" || t == "[]interface {}" { 444 | var ts = methodArgTypes.([]any) 445 | if len(ts) > 0 { 446 | argTypes = make([]reflect.Type, len(ts)) 447 | 448 | for i := 0; i < len(ts); i++ { 449 | var err2 error 450 | argTypes[i], err2 = getType(ts[i].(string), nil, true) 451 | if err2 != nil { 452 | return NewErrorResult(err2) 453 | } 454 | } 455 | } 456 | } 457 | } 458 | 459 | var obj, err2 = getMethodListGroupByClass(pkgName, clsName, methodName, argTypes, query, mock) 460 | if err2 != nil { 461 | return NewErrorResult(err2) 462 | } 463 | 464 | result = NewSuccessResult() 465 | for k, v := range obj { 466 | result[k] = v 467 | } 468 | // result.putAll(obj) //序列化 Class 只能拿到 name result.put("Class[]", ParseArr(ToJSONString(classlist))) 469 | 470 | return result 471 | } 472 | 473 | // InvokeMethodByStr 执行方法 474 | var InvokeMethodByStr = func(request string, instance any, listener Listener[any]) error { 475 | if obj, err := ParseMap(request); err != nil { 476 | return err 477 | } else { 478 | return InvokeMethod(obj, instance, listener) 479 | } 480 | } 481 | 482 | /* 483 | InvokeMethod 执行方法 484 | - @param req : 485 | { 486 | "timeout": 0, //超时时间 487 | "package": "unitauto.test", //被测方法所在的包名 488 | "class": "Test", //被测方法所在的 Struct/Func/Method 名 489 | "constructor": "New", //如果有自定义的构造方法,不能用默认构造方法,可以自定义获取实例的方法,传参仍用 classArgs 490 | "classArgs": [ //构造方法的参数值,可以和 methodArgs 结构一样。这里用了简化形式,只传值不传类型,注意简化形式只能在所有值完全符合构造方法的类型定义时才可用 491 | nil, 492 | nil, 493 | 0, 494 | nil 495 | ], 496 | "this": { //当前类示例,和 constructor & classArgs 二选一 497 | "type": "unitauto.test.Test", //不可缺省,且必须全称,指针引用则在最前面加 *,例如 *unitauto.test.Test 498 | "value": { //Test 的示例值,会根据 type 来转为 Java 类型,这里执行等价于 json.Unmarshal(value, &unitauto.test.Test{}) 499 | "Id": 1, 500 | "Name": "Tommy" 501 | } 502 | }, 503 | "method": "Compare", //被测 Func/Method 名 504 | "methodArgs": [ //被测 Func/Method 的参数值 505 | { 506 | "typ": "int", //bool, float64, string, []interface{} 都可缺省,自动根据 value 来判断 507 | "value": 1 508 | }, 509 | { 510 | "typ": "string", //可缺省,自动根据 value 来判断 511 | "value": "APIJSON" 512 | }, 513 | { 514 | "type": "map[string]interface{}", //可缺省,已缓存到 CLASS_MAP 515 | "value": {} 516 | }, 517 | { 518 | "typ": "[]int", //不可缺省,且必须全称 519 | "value": [1, 2, 3] 520 | }, 521 | { 522 | "type": "[]apijson.demo.server.model.User", //不可缺省,且必须全称 523 | "value": [ 524 | { //apijson.demo.server.model.User 525 | "id": 1, 526 | "name": "Tommy" 527 | }, 528 | { //apijson.demo.server.model.User 529 | "id": 2, 530 | "name": "Lemon" 531 | } 532 | ] 533 | }, 534 | { 535 | "type": "android.content.Context", //不可缺省,且必须全称 536 | "reuse": true //复用实例池 INSTANCE_MAP 里的 537 | } 538 | } 539 | } 540 | ] 541 | } 542 | - @param instance 默认从 CLASS_MAP 取值,取不到则自动 new 543 | - @return 544 | - @error 545 | */ 546 | func InvokeMethod(req map[string]any, instance any, listener Listener[any]) error { 547 | defer func() { 548 | if err := recover(); err != nil { 549 | completeWithError("", "", "", 0, errors.New(fmt.Sprint(err)), listener) 550 | } 551 | }() 552 | 553 | if req == nil { 554 | req = map[string]any{} 555 | } 556 | 557 | var pkgName = GetStr(req, KEY_PACKAGE) 558 | var clsName = GetStr(req, KEY_CLASS) 559 | var cttName = GetStr(req, KEY_CONSTRUCTOR) 560 | var methodName = GetStr(req, KEY_METHOD) 561 | 562 | var startTime = time.Now().UnixMilli() 563 | // 客户端才用 var ui = req.getBooleanValue(KEY_UI) 564 | var static_ = GetBool(req, KEY_STATIC) 565 | var timeout = GetInt64(req, KEY_TIMEOUT) 566 | var this_ = GetMap(req, KEY_THIS) 567 | var clsArgs = GetArgList(req, KEY_CLASS_ARGS) 568 | var methodArgs = GetArgList(req, KEY_METHOD_ARGS) 569 | var args = GetArgList(req, KEY_ARGS) 570 | if len(args) > 0 { 571 | if methodArgs != nil { 572 | err := errors.New(KEY_ARGS + " 和 " + KEY_METHOD_ARGS + " 不能同时传!") 573 | completeWithError(pkgName, clsName, methodName, startTime, err, listener) 574 | return err 575 | } 576 | 577 | methodArgs = args 578 | } 579 | 580 | if IsEmpty(cttName, true) && len(clsArgs) > 0 { 581 | err := errors.New("Go 没有构造函数,不允许单独传 " + KEY_CLASS_ARGS + " ,必须配合 " + KEY_CONSTRUCTOR + " 一起用!") 582 | completeWithError(pkgName, clsName, methodName, startTime, err, listener) 583 | return err 584 | } 585 | 586 | var cn = clsName 587 | if len(cn) <= 0 { 588 | cn = methodName 589 | } else if static_ { 590 | if len(pkgName) <= 0 { 591 | pkgName = cn 592 | } else { 593 | pkgName += "." + cn 594 | } 595 | cn = methodName 596 | } 597 | 598 | var cls, err = GetInvokeClass(pkgName, cn) 599 | fmt.Println("cls = ", cls) 600 | if err != nil || (cls == nil && this_ != nil) { 601 | if err == nil { 602 | err = errors.New("找不到 " + pkgName + "." + cn + " 对应的类!") 603 | } 604 | completeWithError(pkgName, clsName, methodName, startTime, err, listener) 605 | return err 606 | } 607 | 608 | if this_ != nil { 609 | var obj = map[string]any{} 610 | obj[KEY_METHOD_ARGS] = []map[string]any{this_} 611 | var mArgs = GetArgList(obj, KEY_METHOD_ARGS) 612 | 613 | var types = []reflect.Type{nil} 614 | var args = []any{nil} 615 | 616 | err = initTypesAndValues(mArgs, types, args, true, true) 617 | if err != nil { 618 | return err 619 | } 620 | instance = args[0] 621 | } 622 | 623 | var typ = reflect.TypeOf(cls) 624 | fmt.Println("typ = ", typ) 625 | if typ.Kind() == reflect.Struct && instance == nil && static_ == false { 626 | if IsEmpty(cttName, true) { 627 | instance, err = GetInstance(typ, cls, clsArgs, GetBool(req, KEY_REUSE)) 628 | } else { 629 | var cc any 630 | if cc, err = GetInvokeClass(pkgName, cttName); err == nil { 631 | instance, err = getInvokeResult(reflect.ValueOf(cc), typ, cttName, clsArgs, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 632 | return nil 633 | }) 634 | } 635 | } 636 | } 637 | fmt.Println("instance = ", instance) 638 | 639 | if err == nil { 640 | if timeout < 0 || timeout > 60000 { 641 | err = errors.New("参数 " + KEY_TIMEOUT + " 的值不合法!只能在 [0, 60000] 范围内!") 642 | } 643 | } 644 | 645 | if err != nil { 646 | completeWithError(pkgName, clsName, methodName, startTime, err, listener) 647 | return err 648 | } 649 | 650 | if timeout > 0 { 651 | timer := time.NewTimer(time.Duration(timeout) * time.Millisecond) 652 | go func() { 653 | <-timer.C 654 | timer.Stop() 655 | completeWithError(pkgName, clsName, methodName, startTime, errors.New("处理超时,应该在期望时间 "+fmt.Sprint(timeout)+"ms 内!"), listener) 656 | //panic("处理超时,应该在期望时间 " + fmt.Sprint(timeout) + "ms 内!") 657 | }() 658 | } 659 | 660 | var fv = reflect.ValueOf(instance) 661 | if instance != nil && fv.IsValid() { 662 | return InvokeReflectMethod(fv, instance, pkgName, clsName, methodName, methodArgs, listener) 663 | } 664 | //switch cls.(type) { 665 | //case *types.Func: 666 | // return InvokeReflectMethod(reflect.Indirect(cls), instance, pkgName, clsName, methodName, methodArgs, listener) 667 | //} 668 | return InvokeReflectMethod(reflect.ValueOf(cls), instance, pkgName, clsName, methodName, methodArgs, listener) 669 | } 670 | 671 | var InvokeReflectMethod = func(typ reflect.Value, instance any, pkgName string, clsName string, methodName string, 672 | methodArgs []Argument, listener Listener[any]) error { 673 | 674 | var startTime = time.Now().UnixMilli() 675 | _, err := getInvokeResult(typ, nil, methodName, methodArgs, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 676 | var result = NewSuccessResult() 677 | if data != nil { 678 | switch data.(type) { 679 | case map[string]any: 680 | var m = data.(map[string]any) 681 | for k, v := range m { 682 | result[k] = v 683 | } 684 | } 685 | } 686 | 687 | result[KEY_LANGUAGE] = "Go" 688 | if instance != nil { 689 | result[KEY_THIS] = parseJson(reflect.TypeOf(instance), instance) //TODO InterfaceProxy proxy 改成泛型 I instance ? 690 | } 691 | 692 | if listener != nil { 693 | err := listener(result, nil, nil) 694 | if err != nil { 695 | return err 696 | } 697 | } 698 | 699 | return nil 700 | }) 701 | 702 | if err != nil { 703 | completeWithError(pkgName, clsName, methodName, startTime, err, listener) 704 | return err 705 | } 706 | return nil 707 | } 708 | 709 | var completeWithError = func(pkgName string, clsName string, methodName string, startTime int64, err error, listener Listener[any]) { 710 | var endTime = time.Now().UnixMilli() 711 | fmt.Println(err) 712 | if err == nil { 713 | err = errors.New("unknown error") 714 | } 715 | 716 | var duration = endTime - startTime 717 | var throwName = reflect.TypeOf(err).String() // e.getClass().getTypeName( 718 | fmt.Println("getInvokeResult " + pkgName + "." + clsName + "." + methodName + " throw " + throwName + 719 | "! endTime = " + fmt.Sprint(endTime) + " duration = " + fmt.Sprint(duration) + ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n") 720 | 721 | var result = NewErrorResult(err) 722 | result[KEY_TIME_DETAIL] = fmt.Sprint(startTime) + "|" + fmt.Sprint(duration) + "|" + fmt.Sprint(endTime) 723 | result["throw"] = throwName 724 | //result["cause"] = e.getCause() 725 | //result["trace"= = e.getStackTrace() 726 | 727 | if listener != nil { 728 | if err := listener(result, nil, nil); err != nil { 729 | fmt.Println(err.Error()) 730 | } 731 | } 732 | } 733 | 734 | var PATTERN_NAME, _ = regexp.Compile("^[0-9a-zA-Z_]+$") 735 | 736 | func IsName(name string) bool { 737 | return PATTERN_NAME.MatchString(name) 738 | //if b, err := regexp.MatchString("^[0-9a-zA-Z_]+$", name); err == nil { 739 | // return b 740 | //} else { 741 | // return false 742 | //} 743 | } 744 | 745 | func IsIntType(typ string) bool { 746 | return typ == "int" || typ == "int32" || typ == "int64" 747 | } 748 | func IsFloatType(typ string) bool { 749 | return typ == "float" || typ == "float32" || typ == "float64" 750 | } 751 | 752 | func IsNumType(typ string) bool { 753 | return IsIntType(typ) || IsFloatType(typ) 754 | } 755 | func IsMapType(typ string) bool { 756 | return strings.HasPrefix(typ, "map[") 757 | } 758 | func IsArrType(typ string) bool { 759 | return strings.HasPrefix(typ, "[]") 760 | } 761 | 762 | var GetArgList = func(req map[string]any, arrKey string) []Argument { 763 | if req == nil { 764 | return nil 765 | } 766 | var arr = GetArr(req, arrKey) 767 | var l = len(arr) 768 | if arr == nil || l <= 0 { 769 | return nil 770 | } 771 | 772 | var lst = []Argument{} 773 | for i := 0; i < l; i++ { 774 | var item = arr[i] 775 | var t = reflect.TypeOf(item) 776 | var ts = t.String() 777 | if t.Kind() == reflect.Bool || IsNumType(ts) || IsArrType(ts) { 778 | lst = append(lst, NewArgument("", item)) 779 | } else if t.Kind() == reflect.String { 780 | var str = item.(string) 781 | var index = strings.Index(str, ":") 782 | var typ = "" 783 | var value = str 784 | if index >= 0 { 785 | typ = str[0:index] 786 | value = str[index+1:] 787 | } 788 | 789 | lst = append(lst, NewArgument(typ, value)) 790 | } else if t == TYPE_MAP_STRING_ANY { 791 | var m = item.(map[string]any) 792 | var agt = Argument{} 793 | agt.Type = GetStr(m, KEY_AT_TYPE) 794 | if len(agt.Type) <= 0 { 795 | agt.Type = GetStr(m, KEY_TYPE) 796 | } 797 | agt.Value = m[KEY_VALUE] 798 | agt.Reuse = GetBool(m, KEY_REUSE) 799 | agt.Global = GetBool(m, KEY_GLOBAL) 800 | lst = append(lst, agt) 801 | } else if t == TYPE_MAP_STRING_INTERFACE { 802 | var m = item.(map[string]interface{}) 803 | var agt = Argument{} 804 | agt.Type = GetStr(m, KEY_AT_TYPE) 805 | if len(agt.Type) <= 0 { 806 | agt.Type = GetStr(m, KEY_TYPE) 807 | } 808 | agt.Value = m[KEY_VALUE] 809 | agt.Reuse = GetBool(m, KEY_REUSE) 810 | agt.Global = GetBool(m, KEY_GLOBAL) 811 | lst = append(lst, agt) 812 | } else { 813 | var agt = Argument{} 814 | tp, err := getType("", item, true) 815 | if err == nil { 816 | agt.Type = tp.String() 817 | } else { 818 | agt.Type = "any" 819 | } 820 | 821 | agt.Value = item 822 | lst = append(lst, agt) 823 | } 824 | } 825 | 826 | if len(lst) <= 0 { 827 | return nil 828 | } 829 | return lst 830 | } 831 | 832 | /** GetInvokeClass 获取类 833 | * @param pkgName 包名 834 | * @param clsName 类名 835 | */ 836 | var GetInvokeClass = func(pkgName string, clsName string) (any, error) { 837 | var cls any 838 | if len(clsName) <= 0 { 839 | cls = CLASS_MAP[pkgName] 840 | } else { 841 | cls = CLASS_MAP[clsName] 842 | if cls == nil && len(pkgName) > 0 { 843 | cls = CLASS_MAP[pkgName+"."+clsName] 844 | } 845 | } 846 | 847 | if cls != nil { 848 | var v = reflect.ValueOf(cls) 849 | var k = v.Kind() 850 | if k == reflect.Struct || k == reflect.Func || k == reflect.Pointer { 851 | return cls, nil 852 | } 853 | } 854 | 855 | o, err := LoadClass(pkgName, clsName, false) 856 | if err != nil { 857 | return nil, err 858 | } 859 | 860 | //var t = o.Type() 861 | //switch t.(type) { 862 | //case *types.Signature: 863 | // return runtime.FuncForPC(reflect.ValueOf(o).Pointer()), nil 864 | // //var sgt = t.(*types.Signature) 865 | // // 866 | // //var ps = sgt.Params() 867 | // //var inTypes = make([]reflect.Type, ps.Len()) 868 | // //for i := 0; i < ps.Len(); i++ { 869 | // // var s = strings.Trim(ps.At(i).String(), " ") 870 | // // if strings.HasPrefix(s, "var ") { 871 | // // s = strings.Trim(s[len("var "):], " ") 872 | // // } 873 | // // var ind = strings.Index(s, " ") 874 | // // if ind >= 0 { 875 | // // s = strings.Trim(s[ind+1:], " ") 876 | // // } 877 | // // 878 | // // inTypes[i], err = getType(s, nil, true) 879 | // // if err != nil { 880 | // // return nil, err 881 | // // } 882 | // //} 883 | // // 884 | // //var rs = sgt.Results() 885 | // //var outTypes = make([]reflect.Type, rs.Len()) 886 | // //for i := 0; i < rs.Len(); i++ { 887 | // // var s = strings.Trim(rs.At(i).String(), " ") 888 | // // if strings.HasPrefix(s, "var ") { 889 | // // s = strings.Trim(s[len("var "):], " ") 890 | // // } 891 | // // var ind = strings.Index(s, " ") 892 | // // if ind >= 0 { 893 | // // s = strings.Trim(s[ind+1:], " ") 894 | // // } 895 | // // 896 | // // outTypes[i], err = getType(s, nil, true) 897 | // // if err != nil { 898 | // // return nil, err 899 | // // } 900 | // //} 901 | // // 902 | // //runtime.FuncForPC() 903 | // // 904 | // //return reflect.FuncOf(inTypes, outTypes, false), nil 905 | //} 906 | 907 | return o, err 908 | } 909 | 910 | var GetInstanceValue = func(typ reflect.Type, val any, reuse bool, proxy InterfaceProxy) (any, bool) { 911 | if val != nil && typ == reflect.TypeOf(val) { 912 | return val, true 913 | } 914 | if reuse { 915 | var v = INSTANCE_MAP[typ] //必须精确对应值,否则去除缓存的和需要的很可能不符 916 | if v != nil { 917 | return v, true 918 | } 919 | } 920 | 921 | var v = reflect.Zero(typ) // .New(typ) 922 | var toVal, err = Convert(val, v) 923 | if err == nil { 924 | return toVal, true 925 | } 926 | return v, false 927 | 928 | //if v.CanConvert(typ) { 929 | // return v.Convert(typ), false 930 | //} 931 | //return v.Elem(), false 932 | } 933 | 934 | func Convert[T any](rawVal any, toVal T) (T, error) { 935 | if rawVal == nil { 936 | return toVal, nil 937 | } 938 | var bytes, err = json.Marshal(rawVal) 939 | if err == nil { 940 | err = json.Unmarshal(bytes, &toVal) 941 | if err == nil { 942 | return toVal, nil 943 | } 944 | } 945 | 946 | //switch rawVal.(type) { 947 | //case map[string]any: 948 | // var ok = true 949 | // var ret = reflect.ValueOf(toVal) 950 | // for k, v := range rawVal.(map[string]any) { 951 | // var f = ret.FieldByName(k) 952 | // fmt.Println("f = ", f) 953 | // if !f.IsValid() { // || !f.CanSet() { 954 | // continue 955 | // } 956 | // 957 | // if v2, err := cast(v, f.Type()); err != nil { 958 | // ok = false 959 | // break 960 | // } else { 961 | // f.Set(reflect.ValueOf(v2)) 962 | // } 963 | // } 964 | // 965 | // if ok { 966 | // return ret, nil 967 | // } 968 | //} 969 | 970 | return toVal, err 971 | } 972 | 973 | /** GetInvokeInstance 获取实例 974 | * @param typ 975 | * @param classArgs 976 | * @param reuse 977 | * @return 978 | * @error 979 | */ 980 | func GetInvokeInstance(typ reflect.Type, instance any, classArgs []Argument, reuse bool) (any, error) { 981 | if typ == nil { 982 | return nil, errors.New("typ == nil") 983 | } 984 | 985 | if len(classArgs) > 0 { 986 | return nil, errors.New("Go 没有构造函数,不允许单独传 " + KEY_CLASS_ARGS + " ,必须配合 " + KEY_CONSTRUCTOR + " 一起用!") 987 | } 988 | 989 | if reuse && instance == nil { //必须精确对应值,否则去除缓存的和需要的很可能不符 990 | instance = INSTANCE_MAP[typ] 991 | } 992 | 993 | if instance == nil { 994 | instance, _ = GetInstanceValue(typ, nil, reuse, InterfaceProxy{}) // new(typ) 995 | 996 | if instance == nil { //通过默认方法 997 | return nil, errors.New("找不到 " + typ.String() + " 以及 classArgs 对应的构造方法!") 998 | } 999 | 1000 | INSTANCE_MAP[typ] = instance 1001 | } 1002 | 1003 | return instance, nil 1004 | } 1005 | 1006 | /** getInvokeResult 执行方法并返回结果 1007 | * @param instance 1008 | * @param methodName 1009 | * @param methodArgs 1010 | * @param listener 如果确定是同步的,则传 nil 1011 | * @return 同步可能 return nil,异步一定 return nil 1012 | * @error 1013 | */ 1014 | func getInvokeResult(typ reflect.Value, returnType reflect.Type, methodName string, methodArgs []Argument, listener Listener[any]) (any, error) { 1015 | //if typ == nil { 1016 | // return nil, errors.New("typ == nil") 1017 | //} 1018 | if methodName == "" { 1019 | return nil, errors.New("methodName == nil") 1020 | } 1021 | 1022 | var size = len(methodArgs) 1023 | var IsEmpty = size <= 0 1024 | 1025 | //method argument, types and values 1026 | var types = make([]reflect.Type, size) 1027 | var args = make([]any, size) 1028 | 1029 | if IsEmpty == false { 1030 | err := initTypesAndValues(methodArgs, types, args, true, false) 1031 | if err != nil { 1032 | return nil, err 1033 | } 1034 | } 1035 | 1036 | var k = typ.Kind() 1037 | var method reflect.Value 1038 | 1039 | if k == reflect.Struct || k == reflect.Pointer { 1040 | method = typ.MethodByName(methodName) 1041 | } else if k == reflect.Func { 1042 | method = typ 1043 | } else { 1044 | return nil, errors.New("typ 不合法, 必须为 Struct, Func 中的一种!") 1045 | } 1046 | 1047 | if method.IsNil() || method.IsZero() { 1048 | return nil, errors.New("methodName == " + methodName + " not found in " + fmt.Sprint(typ)) 1049 | } 1050 | 1051 | var startTime = time.Now().UnixMilli() // 必须在 onItemComplete 前初始化,但又得在后面重新赋值以获得最准确的时间 1052 | 1053 | var onItemComplete Listener[any] = func(data any, method_ *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 1054 | var endTime = time.Now().UnixMilli() 1055 | var duration = endTime - startTime 1056 | 1057 | fmt.Println("getInvokeResult " + reflect.ValueOf(method).String() + " endTime = " + fmt.Sprint(endTime) + " duration = " + fmt.Sprint(duration) + ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n") 1058 | 1059 | if listener == nil { 1060 | return nil 1061 | } 1062 | 1063 | var result = map[string]any{} 1064 | var t = method.Type() // nil 1065 | 1066 | if t != nil && t.NumOut() > 0 { 1067 | var ts = make([]string, t.NumOut()) 1068 | for i := 0; i < t.NumOut(); i++ { 1069 | ts[i] = trimReflectType(t.Out(i)) 1070 | } 1071 | if len(ts) > 1 { 1072 | result[KEY_TYPE] = ts 1073 | } else if len(ts) == 1 { 1074 | result[KEY_TYPE] = ts[0] 1075 | } 1076 | } 1077 | 1078 | fmt.Println("data = ", data) 1079 | result[KEY_RETURN] = data 1080 | 1081 | var finalMethodArgs []any = nil 1082 | if len(types) > 0 { 1083 | finalMethodArgs = []any{} 1084 | 1085 | for i := 0; i < len(types); i++ { 1086 | var t = types[i] 1087 | var v = args[i] 1088 | finalMethodArgs = append(finalMethodArgs, parseJSON(t.String(), v)) 1089 | } 1090 | 1091 | result[KEY_METHOD_ARGS] = finalMethodArgs 1092 | } 1093 | 1094 | result[KEY_TIME_DETAIL] = fmt.Sprint(startTime) + "|" + fmt.Sprint(duration) + "|" + fmt.Sprint(endTime) 1095 | 1096 | if listener != nil { 1097 | err := listener(result, nil, nil) 1098 | if err != nil { 1099 | return err 1100 | } 1101 | } 1102 | 1103 | return nil 1104 | } 1105 | 1106 | var isSync = true 1107 | var err error = nil 1108 | 1109 | pl := make([]reflect.Value, len(args)) 1110 | 1111 | var res any = nil 1112 | 1113 | if len(types) > 0 { 1114 | for i := 0; i < len(types); i++ { //当其中有 interface 且用 KEY_CALLBACK 标记了内部至少一个方法,则认为是触发异步回调的方法 1115 | 1116 | var key = methodArgs[i].Type 1117 | var value = methodArgs[i].Value 1118 | 1119 | if reflect.TypeOf(value).Kind() == reflect.Map { 1120 | 1121 | //判断是否符合 "fun(arg0,arg1...)": { "callback": true } 格式 1122 | var start = -1 1123 | var end = strings.LastIndex(key, ")") 1124 | if end > 2 { 1125 | start = strings.Index(key, "(") 1126 | } 1127 | if start < 1 || !IsName(key[0:start]) { 1128 | for ck, cv := range value.(map[string]any) { 1129 | switch cv.(type) { 1130 | case map[string]any: 1131 | var start2 = -1 1132 | var end2 = strings.LastIndex(ck, ")") 1133 | if end2 > 2 { 1134 | start2 = strings.Index(ck, "(") 1135 | } 1136 | if start2 < 1 || !IsName(ck[0:start2]) { 1137 | continue 1138 | } 1139 | var fcc = GetBool(cv.(map[string]any), KEY_CALLBACK) 1140 | if fcc { 1141 | isSync = false 1142 | } 1143 | } 1144 | 1145 | if !isSync { 1146 | break 1147 | } 1148 | } 1149 | 1150 | if v, err2 := cast(args[i], types[i]); err2 == nil { 1151 | switch v.(type) { 1152 | case reflect.Value: 1153 | pl[i] = v.(reflect.Value) 1154 | default: 1155 | var ip = InterfaceProxy{} 1156 | var tt = reflect.TypeOf(ip) 1157 | fmt.Println("tt = ", tt) 1158 | 1159 | var rt = reflect.TypeOf(v) 1160 | var rv = reflect.ValueOf(v) 1161 | fmt.Println("rt = ", rt) 1162 | fmt.Println("rv = ", rv) 1163 | fmt.Println("rv.Type() = ", rv.Type()) 1164 | 1165 | var ipf, exist = rt.FieldByName("InterfaceProxy") 1166 | if !exist { 1167 | for j := 0; j < rt.NumField(); j++ { 1168 | var f = rt.Field(j) 1169 | if f.Type == tt { 1170 | ipf = f 1171 | exist = true 1172 | break 1173 | } 1174 | } 1175 | } 1176 | 1177 | fmt.Println("ipf = ", ipf) 1178 | if exist { 1179 | var lm = map[string]Listener[any]{} 1180 | for ck, cv := range value.(map[string]any) { 1181 | switch cv.(type) { 1182 | case map[string]any: 1183 | var start2 = -1 1184 | var end2 = strings.LastIndex(ck, ")") 1185 | if end2 > 2 { 1186 | start2 = strings.Index(ck, "(") 1187 | } 1188 | if start2 < 1 || !IsName(ck[0:start2]) { 1189 | continue 1190 | } 1191 | var fcc = GetBool(cv.(map[string]any), KEY_CALLBACK) 1192 | var callbackIndex = i 1193 | 1194 | lm[ck] = func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 1195 | var fcm = value.(map[string]any) 1196 | 1197 | var cm = GetMap(fcm, KEY_CALL_MAP) 1198 | var cl = GetArr(fcm, KEY_CALL_LIST) 1199 | 1200 | var cm2, exist = proxy.Get(KEY_CALL_MAP) 1201 | if exist { 1202 | if len(cm) <= 0 { 1203 | cm = cm2.(map[string]any) 1204 | } else { 1205 | for k, v := range cm2.(map[string]any) { 1206 | cm[k] = v 1207 | } 1208 | } 1209 | fcm[KEY_CALL_MAP] = cm 1210 | } 1211 | var cl2, exist3 = proxy.Get(KEY_CALL_LIST) 1212 | if exist3 { 1213 | fcm[KEY_CALL_LIST] = append(cl, cl2.([]any)...) 1214 | } 1215 | 1216 | args[callbackIndex] = fcm 1217 | 1218 | if fcc { 1219 | return onItemComplete(data, method, proxy, extras) 1220 | } 1221 | return nil 1222 | } 1223 | } 1224 | } 1225 | 1226 | ip.CallbackMap = lm 1227 | 1228 | var fv, _ = GetInstanceValue(types[i], v, false, ip) 1229 | pl[i] = reflect.ValueOf(fv) 1230 | } else { 1231 | pl[i] = rv 1232 | } 1233 | } 1234 | } else { 1235 | fmt.Println(err2.Error()) 1236 | pl[i] = reflect.Zero(types[i]) 1237 | } 1238 | continue 1239 | } 1240 | 1241 | t := reflect.TypeOf(value) 1242 | if t.Kind() != reflect.Map { 1243 | if v, err2 := cast(args[i], types[i]); err2 == nil { 1244 | //pl[i] = reflect.ValueOf(v) 1245 | pl[i] = v.(reflect.Value) // reflect.ValueOf(v) 1246 | } else { 1247 | fmt.Println(err2.Error()) 1248 | } 1249 | continue 1250 | } 1251 | 1252 | var inTypeStrs = strings.Split(key[start+1:end], ",") 1253 | var inTypes = make([]reflect.Type, len(inTypeStrs)) 1254 | for j, its := range inTypeStrs { 1255 | inTypes[j], err = getType(its, nil, true) 1256 | if err != nil { 1257 | return nil, err 1258 | } 1259 | } 1260 | 1261 | var fcm = value.(map[string]any) 1262 | var fct = GetStr(fcm, KEY_TYPE) 1263 | var fcr = fcm[KEY_RETURN] 1264 | var fcc = GetBool(fcm, KEY_CALLBACK) 1265 | if fcc { 1266 | isSync = false 1267 | } 1268 | 1269 | var outTypeStrs = strings.Split(key[end+1:], ",") 1270 | if len(outTypeStrs) <= 0 { 1271 | outTypeStrs = strings.Split(fct, ",") 1272 | } 1273 | var outTypes = make([]reflect.Type, len(outTypeStrs)) 1274 | for j, its := range outTypeStrs { 1275 | outTypes[j], err = getType(its, nil, true) 1276 | if err != nil { 1277 | return nil, err 1278 | } 1279 | } 1280 | 1281 | var callbackIndex = i 1282 | pl[i] = reflect.MakeFunc(reflect.FuncOf(inTypes, outTypes, false), func(as []reflect.Value) (rs []reflect.Value) { 1283 | var callTime = time.Now().UnixMilli() 1284 | 1285 | var calledArgs = make([]map[string]any, len(as)) 1286 | for j, a := range as { 1287 | fmt.Println("as[", j, "] = ", a) 1288 | var vt = a.Type() 1289 | var vv any 1290 | if a.CanInt() { 1291 | vv = a.Int() 1292 | } else if a.CanFloat() { 1293 | vv = a.Float() 1294 | } else if vt == TYPE_BOOL { 1295 | vv = a.Bool() 1296 | } else if vt == TYPE_STRING { 1297 | vv = a.String() 1298 | } else if a.CanConvert(vt) { 1299 | vv = a.Convert(vt) 1300 | } 1301 | 1302 | calledArgs[j] = map[string]any{ 1303 | KEY_TYPE: vt.String(), 1304 | KEY_VALUE: vv, 1305 | } 1306 | } 1307 | 1308 | var cm = GetArr(fcm, KEY_CALL_MAP) 1309 | if cm == nil { 1310 | cm = []any{} 1311 | } 1312 | 1313 | var callInfo = map[string]any{ 1314 | KEY_TIME: callTime, 1315 | KEY_METHOD_ARGS: calledArgs, 1316 | } 1317 | fcm[KEY_CALL_MAP] = append(cm, callInfo) 1318 | 1319 | args[callbackIndex] = fcm 1320 | 1321 | var rl = len(rs) 1322 | if rl != len(outTypes) { 1323 | rs = make([]reflect.Value, len(outTypes)) 1324 | rl = len(rs) 1325 | } 1326 | 1327 | if rl <= 0 { 1328 | // do nothing 1329 | } else if reflect.TypeOf(fcr).Kind() == reflect.Array { 1330 | var arr = fcr.([]any) 1331 | var al = len(arr) 1332 | var min = al 1333 | if al > rl { 1334 | min = rl 1335 | } 1336 | for j := 0; j < min; j++ { 1337 | if v, err3 := cast(arr[j], outTypes[j]); err3 != nil { 1338 | rs[j] = reflect.Zero(outTypes[j]) 1339 | } else { 1340 | rs[j] = reflect.ValueOf(v) 1341 | } 1342 | } 1343 | } else { 1344 | if v, err3 := cast(fcr, outTypes[0]); err3 != nil { 1345 | rs[0] = reflect.Zero(outTypes[0]) 1346 | } else { 1347 | rs[0] = reflect.ValueOf(v) 1348 | } 1349 | } 1350 | 1351 | if fcc { 1352 | err = onItemComplete(res, nil, nil) 1353 | if err != nil { 1354 | fmt.Println(err.Error()) 1355 | callInfo[KEY_WARN] = err.Error() 1356 | } 1357 | } 1358 | 1359 | return rs 1360 | }) 1361 | 1362 | } else { 1363 | if v, err2 := cast(args[i], types[i]); err2 == nil { 1364 | pl[i] = reflect.ValueOf(v) 1365 | } else { 1366 | fmt.Println(err2.Error()) 1367 | } 1368 | } 1369 | } 1370 | } 1371 | 1372 | startTime = time.Now().UnixMilli() // 排除前面初始化参数的最准确时间 1373 | fmt.Println("getInvokeResult " + method.String() + " startTime = " + fmt.Sprint(startTime) + 1374 | "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n\n ") 1375 | 1376 | var vals = method.Call(pl) 1377 | 1378 | var vl = len(vals) 1379 | var vs = make([]any, vl) 1380 | for i, val := range vals { 1381 | if returnType != nil { 1382 | vs[i] = val.Convert(returnType) 1383 | continue 1384 | } 1385 | if val.CanInterface() { 1386 | vs[i] = val.Interface() 1387 | continue 1388 | } 1389 | 1390 | //k := val.Kind() 1391 | //switch k { 1392 | //case reflect.Bool: 1393 | // vs[i] = val.Bool() // bool(p) // *(*bool)(p) 1394 | //case reflect.Uint: 1395 | // vs[i] = uint(val.Pointer()) 1396 | //case reflect.Uint8: 1397 | // vs[i] = uint8(val.Pointer()) 1398 | //case reflect.Uint16: 1399 | // vs[i] = uint16(val.Pointer()) 1400 | //case reflect.Uint32: 1401 | // vs[i] = uint32(val.Pointer()) 1402 | //case reflect.Uint64: 1403 | // vs[i] = uint64(val.Pointer()) 1404 | //case reflect.Uintptr: 1405 | // vs[i] = val.Pointer() 1406 | //case reflect.Int: 1407 | // vs[i] = int(val.Pointer()) 1408 | //case reflect.Int8: 1409 | // vs[i] = int8(val.Pointer()) 1410 | //case reflect.Int16: 1411 | // vs[i] = int16(val.Pointer()) 1412 | //case reflect.Int32: 1413 | // vs[i] = int32(val.Pointer()) 1414 | //case reflect.Int64: 1415 | // vs[i] = int64(val.Pointer()) 1416 | //case reflect.String: 1417 | // vs[i] = val.String() 1418 | //default: 1419 | var vt = val.Type() 1420 | if val.CanInt() { 1421 | vs[i] = val.Int() 1422 | } else if val.CanUint() { 1423 | vs[i] = val.Uint() 1424 | } else if val.CanFloat() { 1425 | vs[i] = val.Float() 1426 | } else if vt == TYPE_BOOL { 1427 | vs[i] = val.Bool() 1428 | } else if vt == TYPE_STRING { 1429 | vs[i] = val.String() 1430 | } else if vt == TYPE_ERROR || vt.String() == "error" { 1431 | //fn := val.MethodByName("Error") 1432 | //if fn.IsNil() || fn.IsZero() || ! fn.IsValid() { 1433 | vs[i] = fmt.Sprint(val) 1434 | //} else { 1435 | // vs[i] = fmt.Sprint(fn.Call([]reflect.Value{})) 1436 | //} 1437 | } else if val.CanConvert(vt) { 1438 | vs[i] = val.Convert(vt) 1439 | } else if val.IsZero() { 1440 | vs[i] = reflect.Zero(vt) // nil 1441 | } else if val.CanInterface() && val.IsNil() { 1442 | vs[i] = nil 1443 | } else { 1444 | vs[i] = reflect.Indirect(val) 1445 | } 1446 | //} 1447 | 1448 | } 1449 | 1450 | if vl == 1 { 1451 | res = vs[0] 1452 | } else if vl > 1 { 1453 | res = vs 1454 | } 1455 | 1456 | if isSync { 1457 | if listener != nil { 1458 | fmt.Println(res) 1459 | err = onItemComplete(res, nil, nil) 1460 | if err != nil { 1461 | return nil, err 1462 | } 1463 | } 1464 | return res, nil 1465 | } 1466 | 1467 | return nil, nil 1468 | } 1469 | 1470 | var PATTERN_UPPER_CASE, _ = regexp.Compile("^[A-Z]+$") 1471 | 1472 | /** getMethodListGroupByClass 获取用 Class 分组的 Method 二级嵌套列表 1473 | * @param pkgName 1474 | * @param clsName 1475 | * @param methodName 1476 | * @param argTypes 1477 | * @param query 1478 | * @param mock 1479 | * @return 1480 | * @error 1481 | */ 1482 | func getMethodListGroupByClass(pkgName string, clsName string, methodName string, argTypes []reflect.Type, query int, mock bool) (map[string]any, error) { 1483 | if query != 0 && query != 1 && query != 2 { 1484 | return nil, errors.New("query 取值只能是 [0, 1, 2] 中的一个! 0-数据,1-总数,2-全部") 1485 | } 1486 | 1487 | var allClassList, err = LoadClassList(pkgName, clsName, true, 0, 0) 1488 | if err != nil { 1489 | return nil, err 1490 | } 1491 | 1492 | var queryData = query != 1 1493 | var queryTotal = query != 0 1494 | var allMethod = IsEmpty(methodName, true) 1495 | 1496 | var packageTotal = 0 1497 | var classTotal = 0 1498 | var methodTotal = 0 1499 | 1500 | var packageMap map[string]any 1501 | var packageList []map[string]any 1502 | 1503 | var countObj = map[string]any{} 1504 | if queryTotal { 1505 | countObj[KEY_PACKAGE_TOTAL] = packageTotal 1506 | countObj[KEY_CLASS_TOTAL] = classTotal 1507 | countObj[KEY_METHOD_TOTAL] = methodTotal 1508 | } 1509 | 1510 | var codeStr = "" 1511 | var insCodeStr = "" 1512 | 1513 | if len(allClassList) > 0 { 1514 | packageMap = map[string]any{} 1515 | packageList = []map[string]any{} 1516 | 1517 | for i := 0; i < len(allClassList); i++ { 1518 | var cls = allClassList[i] 1519 | if cls == nil { // reflect.Value{}) { 1520 | continue 1521 | } 1522 | 1523 | classTotal++ 1524 | 1525 | var methodCount = 0 1526 | var pkg = cls.Pkg().String() // .Type().PkgPath() 1527 | var start = strings.Index(pkg, "(") 1528 | //var end = strings.LastIndex(pkg, ")") 1529 | if start > 1 { 1530 | pkg = pkg[:start] 1531 | } 1532 | if strings.HasPrefix(pkg, "package ") { 1533 | pkg = pkg[len("package "):] 1534 | } 1535 | pkg = strings.TrimSpace(pkg) 1536 | 1537 | var pkgObj = GetMap(packageMap, pkg) 1538 | var pkgNotExist = pkgObj == nil 1539 | if pkgNotExist { 1540 | pkgObj = map[string]any{} 1541 | packageMap[pkg] = pkgObj 1542 | } 1543 | 1544 | if queryTotal { 1545 | var clsCount = GetInt(pkgObj, KEY_CLASS_TOTAL) 1546 | pkgObj[KEY_CLASS_TOTAL] = clsCount + 1 1547 | } 1548 | pkgObj[KEY_PACKAGE] = pkg 1549 | 1550 | var classList = GetMapArr(pkgObj, KEY_CLASS_LIST) 1551 | if classList == nil { 1552 | classList = []map[string]any{} 1553 | } 1554 | 1555 | var clsObj = map[string]any{} 1556 | 1557 | var cn = cls.Name() // fmt.Sprint(cls) // cls.String() 1558 | if len(cn) < 1 || !PATTERN_UPPER_CASE.MatchString(cn[0:1]) { 1559 | continue 1560 | } 1561 | 1562 | clsObj[KEY_CLASS] = cn 1563 | //clsObj[KEY_TYPE] = trimType(cls.getGenericSuperclass()) 1564 | 1565 | var methodList []map[string]any 1566 | if queryData { 1567 | methodList = []map[string]any{} 1568 | } 1569 | 1570 | fmt.Println("cls = ", cls) 1571 | var v = reflect.ValueOf(cls) 1572 | fmt.Println("v = ", v) 1573 | var t = cls.Type() // v.Type() // reflect.TypeOf(cls) 1574 | fmt.Println("t = ", t) 1575 | var k = v.Kind() 1576 | fmt.Println("k = ", k) 1577 | 1578 | var ts = fmt.Sprint(cls) 1579 | 1580 | var isFunc = k == reflect.Func || strings.HasPrefix(ts, "func(") || strings.HasPrefix(ts, "func ") 1581 | 1582 | if !isFunc && (k == reflect.Struct || strings.Contains(ts, " struct{")) { // (k == reflect.Pointer && t.Underlying() != &types.Interface{})) { 1583 | var path = pkg + "." + cn 1584 | codeStr += "\n " + `unitauto.CLASS_MAP["` + path + `"] = ` + path + "{};" 1585 | codeStr += "\n " + `unitauto.CLASS_MAP["*` + path + `"] = &` + path + "{};" 1586 | insCodeStr += ` 1587 | if typ.AssignableTo(reflect.TypeOf(` + path + `{})) { 1588 | toV, err := unitauto.Convert[` + path + `](val, ` + path + `{}); 1589 | return toV, err == nil; 1590 | }; 1591 | if typ.AssignableTo(reflect.TypeOf(&` + path + `{})) { 1592 | toV, err := unitauto.Convert[*` + path + `](val, &` + path + `{}); 1593 | return toV, err == nil; 1594 | };` 1595 | } 1596 | 1597 | if (allMethod == false && argTypes != nil) || isFunc { 1598 | var mObj = parseMethodObject(ts, mock) 1599 | if len(mObj) <= 0 { 1600 | var m = v 1601 | if k == reflect.Struct { 1602 | m = v.MethodByName(methodName) 1603 | } 1604 | mObj = parseMethodObject(m, mock) 1605 | } 1606 | 1607 | if len(mObj) > 0 { 1608 | //mObj["name"] = fmt.Sprint(m) // m.String() 1609 | methodCount = 1 1610 | 1611 | if methodList != nil { 1612 | methodList = append(methodList, mObj) 1613 | } 1614 | 1615 | if isFunc { 1616 | var n = GetStr(mObj, "name") 1617 | if len(n) < 1 || !PATTERN_UPPER_CASE.MatchString(n[0:1]) { 1618 | continue 1619 | } 1620 | 1621 | var path = pkg + "." + n 1622 | codeStr += "\n " + `unitauto.CLASS_MAP["` + path + `"] = ` + path + ";" 1623 | } 1624 | } 1625 | } else { 1626 | for j := 0; j < v.NumMethod(); j++ { 1627 | var m = v.Method(j) 1628 | var name = m.Type().Name() // m.String() 1629 | //if len(name) < 2 { 1630 | // continue 1631 | //} 1632 | 1633 | if allMethod || name == methodName { 1634 | var mObj = parseMethodObject(fmt.Sprint(m), mock) 1635 | if len(mObj) <= 0 { 1636 | mObj = parseMethodObject(m, mock) 1637 | } 1638 | 1639 | if len(mObj) > 0 { 1640 | //mObj["name"] = fmt.Sprint(m) // m.String() 1641 | methodCount++ 1642 | 1643 | if methodList != nil { 1644 | methodList = append(methodList, mObj) 1645 | } 1646 | 1647 | var n = GetStr(mObj, "name") 1648 | if len(n) < 1 || !PATTERN_UPPER_CASE.MatchString(n[0:1]) { 1649 | continue 1650 | } 1651 | 1652 | var path = pkg + "." + n 1653 | codeStr += "\n " + `unitauto.CLASS_MAP["` + path + `"] = ` + path + ";" 1654 | } 1655 | } 1656 | } 1657 | } 1658 | 1659 | if queryTotal { 1660 | clsObj[KEY_METHOD_TOTAL] = methodCount //太多不需要的信息,导致后端返回慢、前端卡 UI clsObj["Method[]", ParseArr(methods)) 1661 | } 1662 | 1663 | if len(methodList) > 0 { 1664 | clsObj[KEY_METHOD_LIST] = methodList //太多不需要的信息,导致后端返回慢、前端卡 UI clsObj["Method[]", ParseArr(methods)) 1665 | } 1666 | 1667 | if len(clsObj) > 0 { 1668 | classList = append(classList, clsObj) 1669 | } 1670 | 1671 | if len(classList) > 0 { 1672 | pkgObj[KEY_CLASS_LIST] = classList 1673 | } 1674 | 1675 | if pkgNotExist && len(pkgObj) > 0 { 1676 | packageList = append(packageList, pkgObj) 1677 | } 1678 | 1679 | methodTotal += methodCount 1680 | } 1681 | 1682 | if len(packageList) > 0 { 1683 | countObj[KEY_PACKAGE_LIST] = packageList 1684 | } 1685 | } 1686 | 1687 | packageTotal = len(packageMap) 1688 | 1689 | if query != 0 { 1690 | countObj[KEY_PACKAGE_TOTAL] = packageTotal 1691 | countObj[KEY_CLASS_TOTAL] = classTotal 1692 | countObj[KEY_METHOD_TOTAL] = methodTotal 1693 | } 1694 | 1695 | if len(strings.TrimSpace(insCodeStr)) > 1 { 1696 | codeStr += ` 1697 | 1698 | var GetInstanceVal = unitauto.GetInstanceValue; 1699 | unitauto.GetInstanceValue = func(typ reflect.Type, val any, reuse bool, proxy unitauto.InterfaceProxy) (any, bool) { 1700 | ` + insCodeStr + ` 1701 | 1702 | return GetInstanceVal(typ, val, reuse, proxy); 1703 | }` 1704 | } 1705 | 1706 | countObj["ginCode"] = codeStr 1707 | 1708 | return countObj, nil 1709 | } 1710 | 1711 | func dot2Separator(name string) string { 1712 | return strings.ReplaceAll(name, ".", "/") 1713 | } 1714 | 1715 | func separator2dot(name string) string { 1716 | return strings.ReplaceAll(name, "/", ".") 1717 | } 1718 | 1719 | func initTypesAndValues(methodArgs []Argument, types []reflect.Type, args []any, defaultType bool, castValue2Type bool) error { 1720 | if len(methodArgs) <= 0 { 1721 | return nil 1722 | } 1723 | if types == nil || args == nil { 1724 | return errors.New("types == nil || args == nil") 1725 | } 1726 | if len(types) != len(methodArgs) || len(args) != len(methodArgs) { 1727 | return errors.New("len(types) != len(methodArgs) || len(args) != len(methodArgs)") 1728 | } 1729 | 1730 | for i := 0; i < len(methodArgs); i++ { 1731 | var argObj = methodArgs[i] 1732 | 1733 | var typeName = argObj.Type 1734 | var value = argObj.Value 1735 | 1736 | var typ, err = getType(typeName, value, defaultType) 1737 | if err != nil { 1738 | return err 1739 | } 1740 | 1741 | if value == nil { 1742 | if value, err = GetInstance(typ, value, nil, argObj.Reuse); err != nil { 1743 | fmt.Println(err.Error()) 1744 | } 1745 | } 1746 | 1747 | if value != nil && typ != nil && reflect.TypeOf(value) != typ { 1748 | //try { //解决只有 interface getter 方法才有对应字段返回 1749 | // if (typ.isArray() || Collection.class.isAssignableFrom(typ) || GenericArrayType.class.isAssignableFrom(typ)) { 1750 | // if (typ.getComponentType() != nil && typ.getComponentType().isInterface()) { // @interface 也必须代理&& typ.getComponentType().isAnnotation() == false) { 1751 | // List implList = ParseArr(ToJSONString(value), reflect.TypeOf(InterfaceProxy{})) 1752 | // value = implList 1753 | // } 1754 | // } 1755 | // // @interface 也必须代理 1756 | // // else if (typ.isAnnotation()) { 1757 | // // } 1758 | // else if (typ.isInterface()) { 1759 | // var proxy = ParseObject(ToJSONString(value), reflect.TypeOf(InterfaceProxy{})) 1760 | // proxy.SetType(typ) 1761 | // value = proxy 1762 | // } 1763 | //} 1764 | //catch (err error) { 1765 | // fmt.Println(err.Error()) 1766 | //} 1767 | 1768 | if castValue2Type { 1769 | if value, err = cast(value, typ); err != nil { 1770 | fmt.Println(err.Error()) 1771 | } 1772 | } 1773 | } 1774 | 1775 | types[i] = typ 1776 | args[i] = value 1777 | } 1778 | 1779 | return nil 1780 | } 1781 | 1782 | func parseMethodObject(m any, mock bool) map[string]any { 1783 | if (m == nil || m == "" || m == reflect.Value{}) { 1784 | return nil 1785 | } 1786 | 1787 | var types []reflect.Type 1788 | var returnTypes []reflect.Type 1789 | var obj = map[string]any{} 1790 | 1791 | var t = reflect.TypeOf(m) 1792 | if t.Kind() == reflect.String { 1793 | var s = m.(string) 1794 | var isStatic = strings.Contains(strings.TrimSpace(s), ")(") 1795 | 1796 | var start = strings.Index(s, "(") 1797 | var end = strings.LastIndex(s, ")") 1798 | if start < 0 || start >= end { 1799 | return nil 1800 | } 1801 | 1802 | var n = strings.TrimSpace(s[0:start]) 1803 | var dotInd = strings.LastIndex(n, ".") 1804 | if dotInd >= 0 { 1805 | n = n[dotInd+1:] 1806 | } 1807 | dotInd = strings.LastIndex(n, "/") 1808 | if dotInd >= 0 { 1809 | n = n[dotInd+1:] 1810 | } 1811 | if strings.HasPrefix(n, "func ") { 1812 | n = n[len("func "):] 1813 | } 1814 | 1815 | obj["name"] = n 1816 | 1817 | var inStrs = strings.Split(s[start+1:end], ",") 1818 | types = make([]reflect.Type, len(inStrs)) 1819 | var inTypes = make([]string, len(inStrs)) 1820 | var err error 1821 | for i := 0; i < len(inStrs); i++ { 1822 | var as = strings.Trim(inStrs[i], " ") 1823 | var blankInd = strings.Index(as, " ") 1824 | if blankInd >= 0 { 1825 | as = as[blankInd+1:] 1826 | } 1827 | as = strings.TrimSpace(as) 1828 | //if strings.HasPrefix(as, "...") { 1829 | // 1830 | //} 1831 | inTypes[i] = as 1832 | types[i], err = getType(as, nil, true) 1833 | if err != nil { 1834 | fmt.Println(err.Error()) 1835 | return nil 1836 | } 1837 | } 1838 | 1839 | var outStrs = strings.Split(s[end+1:], ",") 1840 | returnTypes = make([]reflect.Type, len(outStrs)) 1841 | var outTypes = make([]string, len(outStrs)) 1842 | for i := 0; i < len(outStrs); i++ { 1843 | var as = strings.Trim(outStrs[i], " ") 1844 | var blankInd = strings.Index(as, " ") 1845 | if blankInd >= 0 { 1846 | as = as[blankInd+1:] 1847 | } 1848 | as = strings.TrimSpace(as) 1849 | //if strings.HasPrefix(as, "...") { 1850 | // 1851 | //} 1852 | outTypes[i] = as 1853 | returnTypes[i], err = getType(as, nil, true) 1854 | if err != nil { 1855 | fmt.Println(err.Error()) 1856 | return nil 1857 | } 1858 | } 1859 | 1860 | obj["parameterTypeList"] = inTypes 1861 | obj["genericParameterTypeList"] = inTypes //不能用泛型,会导致解析崩溃 m.getGenericParameterTypes())) 1862 | obj["returnType"] = outTypes //不能用泛型,会导致解析崩溃m.getGenericReturnType())) 1863 | obj["genericReturnType"] = outTypes //不能用泛型,会导致解析崩溃m.getGenericReturnType())) 1864 | obj["static"] = isStatic 1865 | } else { 1866 | var v reflect.Value 1867 | switch m.(type) { 1868 | case reflect.Value: 1869 | v = reflect.Indirect(m.(reflect.Value)) 1870 | //case *reflect.Value: 1871 | // var = reflect.Indirect(m.(*reflect.Value)) 1872 | default: 1873 | v = reflect.Indirect(reflect.ValueOf(m)) 1874 | } 1875 | obj["name"] = fmt.Sprint(v) // v.Name 1876 | t = v.Type() 1877 | if t != nil && t.Kind() != reflect.Func { 1878 | return nil 1879 | } 1880 | 1881 | //var t = m.Type() // reflect.TypeOf(m) 1882 | types = make([]reflect.Type, t.NumIn()) 1883 | for i := 0; i < t.NumIn(); i++ { 1884 | types[i] = t.In(i) 1885 | } 1886 | 1887 | returnTypes = make([]reflect.Type, t.NumOut()) 1888 | for i := 0; i < t.NumOut(); i++ { 1889 | returnTypes[i] = t.Out(i) 1890 | } 1891 | 1892 | var inTypes = trimTypes(types) 1893 | var outTypes = trimTypes(returnTypes) 1894 | obj["parameterTypeList"] = inTypes //不能用泛型,会导致解析崩溃 m.getGenericParameterTypes())) 1895 | obj["genericParameterTypeList"] = inTypes // trimTypes(genericTypes) //不能用泛型,会导致解析崩溃 m.getGenericParameterTypes())) 1896 | obj["returnType"] = outTypes //不能用泛型,会导致解析崩溃m.getGenericReturnType())) 1897 | obj["genericReturnType"] = outTypes //不能用泛型,会导致解析崩溃m.getGenericReturnType())) 1898 | obj["static"] = t.Kind() == reflect.Func 1899 | } 1900 | 1901 | //var genericTypes = m.getGenericParameterTypes() 1902 | 1903 | //obj["static"] = Modifier.isStatic(m.getModifiers()) 1904 | //obj["exceptionTypeList"] = trimTypes(m.getExceptionTypes()) //不能用泛型,会导致解析崩溃m.getGenericExceptionTypes())) 1905 | //obj["genericExceptionTypeList"] = trimTypes(m.getGenericExceptionTypes()) //不能用泛型,会导致解析崩溃m.getGenericExceptionTypes())) 1906 | 1907 | if mock && len(types) > 0 { // genericTypes != nil && genericTypes.length > 0) { 1908 | var vs = make([]any, len(types)) 1909 | for i := 0; i < len(types); i++ { 1910 | vs[i] = mockValue(types[i], types[i], 3) //FIXME 这里应该用 ParameterTypes 还是 GenericParameterTypes ? 1911 | } 1912 | 1913 | obj["parameterDefaultValueList"] = vs 1914 | } 1915 | 1916 | return obj 1917 | } 1918 | 1919 | func mockValue(typ reflect.Type, genericType reflect.Type, depth int) any { 1920 | //避免缓存穿透 1921 | var v = DEFAULT_TYPE_VALUE_MAP[typ] 1922 | if v != nil { 1923 | return v 1924 | } 1925 | 1926 | if typ == nil { 1927 | return nil 1928 | } 1929 | 1930 | var kind = typ.Kind() 1931 | var typStr = typ.String() 1932 | 1933 | if kind == reflect.Invalid || kind == reflect.Chan || typStr == "any" || typStr == "interface{}" { 1934 | return nil 1935 | } 1936 | if kind == reflect.Pointer || kind == reflect.UnsafePointer { 1937 | return nil 1938 | } 1939 | 1940 | var r = rand.Float64() 1941 | 1942 | if kind == reflect.Bool || typStr == "bool" { 1943 | return r >= 0.5 1944 | } 1945 | 1946 | var sign = -1.0 1947 | if r > 0.1 || kind == reflect.Uint || kind == reflect.Uint8 || kind == reflect.Uint16 || kind == reflect.Uint32 || kind == reflect.Uint64 { 1948 | sign = 1 1949 | } 1950 | 1951 | if kind == reflect.String || typStr == "string" { 1952 | var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 1953 | b := make([]rune, int32(100*r)) 1954 | for i := range b { 1955 | b[i] = letters[rand.Intn(len(letters))] 1956 | } 1957 | return string(b) 1958 | } 1959 | 1960 | //常规业务不会用 int 之外的整型,一般是驱动、算法之类的才会用 1961 | if typStr == "byte" { 1962 | return byte(128 * r) 1963 | } 1964 | 1965 | if kind == reflect.Int || kind == reflect.Int8 || kind == reflect.Int16 || kind == reflect.Int32 || 1966 | kind == reflect.Uint || kind == reflect.Uint8 || kind == reflect.Uint16 || kind == reflect.Uint32 || typStr == "int" { 1967 | if sign < 0 { 1968 | return int(sign * 2 * r) 1969 | } 1970 | return int(sign * 10 * r) 1971 | } 1972 | 1973 | if kind == reflect.Int64 || kind == reflect.Uint64 || typStr == "int64" { 1974 | if sign < 0 { 1975 | return int64(sign * 10 * r) 1976 | } 1977 | return int64(sign * 100 * r) 1978 | } 1979 | if kind == reflect.Float32 || kind == reflect.Float64 || typStr == "int32" || typStr == "float64" { 1980 | if sign < 0 { 1981 | return float64(sign * 10 * r) 1982 | } 1983 | return float64(sign * 100 * r) 1984 | } 1985 | 1986 | if depth < 0 { 1987 | return nil 1988 | } 1989 | 1990 | if kind == reflect.Array || kind == reflect.Slice { 1991 | var l = int(r * 10) 1992 | var arr = make([]any, l) 1993 | for j := 0; j < l; j++ { 1994 | arr[j] = mockValue(TYPE_INT, TYPE_INT, depth-1) 1995 | } 1996 | return arr 1997 | } 1998 | 1999 | var obj = map[string]any{} 2000 | 2001 | if kind == reflect.Map { 2002 | var l = int(r * 10) 2003 | for j := 0; j < l; j++ { 2004 | var k = mockValue(TYPE_STRING, TYPE_STRING, depth-1) 2005 | obj[fmt.Sprint(k)] = mockValue(TYPE_INT, TYPE_INT, depth-1) 2006 | } 2007 | return obj 2008 | } 2009 | 2010 | if kind == reflect.Func { 2011 | var ts = make([]string, typ.NumOut()) 2012 | var rs = make([]any, typ.NumOut()) 2013 | for j := 0; j < typ.NumOut(); j++ { 2014 | var rt = typ.Out(j) 2015 | ts[j] = trimReflectType(rt) 2016 | rs[j] = mockValue(rt, rt, depth-1) 2017 | } 2018 | 2019 | if len(ts) > 1 { 2020 | obj[KEY_TYPE] = ts 2021 | obj[KEY_RETURN] = rs 2022 | } else if len(ts) == 1 { 2023 | obj[KEY_TYPE] = ts[0] 2024 | obj[KEY_RETURN] = rs[0] 2025 | } 2026 | 2027 | obj[KEY_CALLBACK] = true 2028 | return obj 2029 | } 2030 | 2031 | if kind == reflect.Struct { 2032 | for i := 0; i < typ.NumField(); i++ { 2033 | var f = typ.Field(i) 2034 | var t = f.Type 2035 | var k = t.Kind() 2036 | 2037 | if k == reflect.Struct || k == reflect.Interface || k == reflect.Map || k == reflect.Func { 2038 | obj[f.Name] = mockValue(f.Type, f.Type, depth-1) 2039 | continue 2040 | } 2041 | 2042 | if k == reflect.Array || k == reflect.Slice { 2043 | obj[f.Name] = mockValue(f.Type, f.Type, depth-1) 2044 | continue 2045 | } 2046 | 2047 | if k == reflect.Pointer || k == reflect.UnsafePointer { 2048 | continue 2049 | } 2050 | 2051 | obj[f.Name] = mockValue(f.Type, f.Type, depth-1) 2052 | } 2053 | 2054 | return obj 2055 | } 2056 | 2057 | if kind == reflect.Interface { 2058 | for i := 0; i < typ.NumMethod(); i++ { 2059 | var m = typ.Method(i) 2060 | var t = m.Type 2061 | 2062 | var n = m.Name + "(" 2063 | for j := 0; j < t.NumIn(); j++ { 2064 | if j > 0 { 2065 | n += "," 2066 | } 2067 | n += trimReflectType(t.In(j)) 2068 | } 2069 | 2070 | var ts = make([]string, t.NumOut()) 2071 | var rs = make([]any, t.NumOut()) 2072 | for j := 0; j < t.NumOut(); j++ { 2073 | var rt = t.Out(j) 2074 | ts[j] = trimReflectType(rt) 2075 | rs[j] = mockValue(rt, rt, depth-1) 2076 | } 2077 | 2078 | var om = map[string]any{} 2079 | if len(ts) > 1 { 2080 | om[KEY_TYPE] = ts 2081 | om[KEY_RETURN] = rs 2082 | } else if len(ts) == 1 { 2083 | om[KEY_TYPE] = ts[0] 2084 | om[KEY_RETURN] = rs[0] 2085 | } 2086 | om[KEY_CALLBACK] = true 2087 | 2088 | obj[n+")"] = om 2089 | } 2090 | 2091 | return obj 2092 | } 2093 | 2094 | return nil 2095 | } 2096 | 2097 | /**转为 var {"typ": t, "value": v } 2098 | * @param typ 2099 | * @param value 2100 | * @return 2101 | */ 2102 | func parseJson(typ reflect.Type, value any) map[string]any { 2103 | var ts = "any" 2104 | if typ == nil && value != nil { 2105 | var err error 2106 | typ, err = getType("", value, true) 2107 | if err != nil { 2108 | fmt.Println(err.Error()) 2109 | } 2110 | } 2111 | 2112 | if typ != nil { 2113 | ts = typ.String() 2114 | } 2115 | return parseJSON(ts, value) 2116 | } 2117 | 2118 | /**转为 var {"typ": t, "value": v } 2119 | * @param typ 2120 | * @param value 2121 | * @return 2122 | */ 2123 | func parseJSON(typ string, value any) map[string]any { 2124 | var o = map[string]any{} 2125 | o[KEY_TYPE] = typ 2126 | if value == nil || isBooleanOrNumberOrString(value) { 2127 | o[KEY_VALUE] = value 2128 | } else { 2129 | switch value.(type) { 2130 | case error: 2131 | value = value.(error).Error() 2132 | } 2133 | 2134 | if _, err := json.Marshal(value); err == nil { 2135 | o[KEY_VALUE] = value 2136 | } else { 2137 | fmt.Println(err.Error()) 2138 | o[KEY_VALUE] = fmt.Sprint(value) 2139 | o[KEY_WARN] = err.Error() 2140 | } 2141 | } 2142 | 2143 | return o 2144 | } 2145 | 2146 | func isBooleanOrNumberOrString(a any) bool { 2147 | typ := reflect.TypeOf(a).String() 2148 | return typ == "bool" || typ == "int" || typ == "int32" || typ == "int64" || typ == "float32" || typ == "float64" || typ == "string" 2149 | } 2150 | 2151 | var NewSuccessResult = func() map[string]any { 2152 | result := map[string]any{} 2153 | result[KEY_CODE] = CODE_SUCCESS 2154 | result[KEY_MSG] = MSG_SUCCESS 2155 | return result 2156 | } 2157 | 2158 | var NewErrorResult = func(err error) map[string]any { 2159 | result := map[string]any{} 2160 | result[KEY_CODE] = CODE_SERVER_ERROR 2161 | result[KEY_MSG] = err.Error() 2162 | return result 2163 | } 2164 | 2165 | func trimTypes(types []reflect.Type) []string { 2166 | if len(types) > 0 && len(types) > 0 { 2167 | var names = make([]string, len(types)) 2168 | for i := 0; i < len(types); i++ { 2169 | names[i] = trimReflectType(types[i]) 2170 | } 2171 | return names 2172 | } 2173 | return nil 2174 | } 2175 | 2176 | func trimReflectType(typ reflect.Type) string { 2177 | if typ == nil { 2178 | return "" 2179 | } 2180 | return trimType(typ.Name()) 2181 | } 2182 | func trimType(name string) string { 2183 | if name == "nil" { 2184 | return "" 2185 | } 2186 | 2187 | //var ts = CLASS_MAP[name] 2188 | //if len(ts) > 0 { 2189 | // return ts 2190 | //} 2191 | 2192 | for k, v := range CLASS_MAP { 2193 | if v == nil { 2194 | continue 2195 | } 2196 | 2197 | var t = reflect.TypeOf(v) 2198 | if t == nil { 2199 | continue 2200 | } 2201 | if name == t.String() { 2202 | return k 2203 | } 2204 | } 2205 | 2206 | var child = "" 2207 | var index = -1 2208 | for { 2209 | index = strings.Index(name, "[") 2210 | if index < 0 { 2211 | break 2212 | } 2213 | child += "[" + trimType(name[index+1:strings.LastIndex(name, "]")]) + "]" 2214 | name = name[0:index] 2215 | } 2216 | 2217 | if strings.HasPrefix(name, "builtin.") { 2218 | name = name[len("builtin."):] 2219 | } 2220 | 2221 | return name + child 2222 | } 2223 | 2224 | func getTypes(types []string) ([]reflect.Type, error) { 2225 | var ts = make([]reflect.Type, len(types)) 2226 | for j, str := range types { 2227 | var rt, err = getType(str, nil, true) 2228 | if err != nil { 2229 | return nil, err 2230 | } 2231 | 2232 | ts[j] = rt 2233 | } 2234 | return ts, nil 2235 | } 2236 | 2237 | func getType(name string, value any, defaultType bool) (reflect.Type, error) { 2238 | if strings.HasPrefix(name, "func(") { 2239 | return TYPE_FUNC, nil 2240 | } 2241 | if strings.HasPrefix(name, "method") { 2242 | return TYPE_METHOD, nil 2243 | } 2244 | 2245 | var typ reflect.Type = nil // FIXME 太奇怪了,居然 name = "any" 然后 name == "any" 返回 false 2246 | if strings.HasPrefix(name, "any") && strings.HasSuffix(name, "any") { 2247 | name = "" 2248 | } else if strings.HasPrefix(name, "interface{}") && strings.HasSuffix(name, "interface{}") { 2249 | name = "" 2250 | } 2251 | if IsEmpty(name, true) || name == "any" || name == "interface{}" { //根据值来自动判断 2252 | if value == nil || defaultType == false { 2253 | //nothing 2254 | } else { 2255 | typ = reflect.TypeOf(value) 2256 | } 2257 | } else { 2258 | var index = strings.Index(name, "[") 2259 | // TODO var child = "" 2260 | if strings.HasPrefix(name, "...") { 2261 | name = name[len("..."):] 2262 | } 2263 | if index > 0 && IsName(name[0:index]) { 2264 | //child = name[index + 1 : strings.LastIndex(name, "]")] 2265 | name = name[0:index] 2266 | } 2267 | if strings.HasPrefix(name, "any") && strings.HasSuffix(name, "any") { 2268 | name = "" 2269 | } else if strings.HasPrefix(name, "interface{}") && strings.HasSuffix(name, "interface{}") { 2270 | name = "" 2271 | } 2272 | if IsEmpty(name, true) { 2273 | if typ == nil && defaultType { 2274 | typ = reflect.TypeOf(nil) 2275 | } 2276 | 2277 | return typ, nil 2278 | } 2279 | 2280 | var n = strings.TrimSpace(name) 2281 | var dotInd = strings.LastIndex(n, "/") 2282 | if dotInd >= 0 { 2283 | n = n[dotInd+1:] 2284 | } 2285 | 2286 | var v = CLASS_MAP[n] 2287 | if v != nil { 2288 | typ = reflect.TypeOf(v) 2289 | } else { 2290 | dotInd = strings.LastIndex(n, ".") 2291 | if dotInd >= 0 { 2292 | n = n[dotInd+1:] 2293 | v = CLASS_MAP[n] 2294 | } 2295 | 2296 | if v != nil { 2297 | typ = reflect.TypeOf(v) 2298 | } else { 2299 | typ = reflect.TypeOf(CLASS_MAP[name]) 2300 | } 2301 | } 2302 | 2303 | if typ == nil { 2304 | index = strings.LastIndex(name, ".") 2305 | 2306 | var err error 2307 | if index < 0 { 2308 | if typ, err = LoadStruct("", name, defaultType); err != nil { 2309 | return nil, err 2310 | } 2311 | } else { 2312 | if typ, err = LoadStruct(name[0:index], name[index+1:], defaultType); err != nil { 2313 | return nil, err 2314 | } 2315 | } 2316 | 2317 | if typ != nil { 2318 | CLASS_MAP[name] = typ 2319 | } 2320 | //} else if (value != nil && IsEmpty(child, true) == false && "interface{}" != child && "any" != child && 2321 | // Collection.class.isAssignableFrom(typ)) { 2322 | // try { 2323 | // // 传参进来必须是 Collection,不是就抛异常 value = cast(value, typ) 2324 | // var c = value.(list.List) 2325 | // if (c != nil && c.IsEmpty() == false) { 2326 | // var nc 2327 | // 2328 | // if (Queue.class.isAssignableFrom(typ) || AbstractSequentialList.class.isAssignableFrom(typ)) { // LinkedList 2329 | // nc = new LinkedList<>() 2330 | // } 2331 | // else if (Vector.class.isAssignableFrom(typ)) { // Stack 2332 | // nc = new Stack<>() 2333 | // } 2334 | // else if (List.class.isAssignableFrom(typ)) { // 写在最前,和 else 重合,但大部分情况下性能更好 // ArrayList 2335 | // nc = new ArrayList<>(c.size()) 2336 | // } 2337 | // else if (SortedSet.class.isAssignableFrom(typ)) { // TreeSet 2338 | // nc = new TreeSet<>() 2339 | // } 2340 | // else if (Set.class.isAssignableFrom(typ)) { // HashSet, LinkedHashSet 2341 | // nc = new LinkedHashSet<>(c.size()) 2342 | // } 2343 | // else { // List, ArrayList 2344 | // nc = new ArrayList<>(c.size()) 2345 | // } 2346 | // 2347 | // for (var o : c) { 2348 | // if (o != nil) { 2349 | // var ct = getType(child, o, true) 2350 | // o = cast(o, ct) 2351 | // } 2352 | // nc.add(o) 2353 | // } 2354 | // 2355 | // // 改变不了外部的 value 值 value = nc 2356 | // c.clear() 2357 | // c.addAll(nc) 2358 | // } 2359 | // } 2360 | // catch (err error) { 2361 | // fmt.Println(err.Error()) 2362 | // } 2363 | 2364 | } 2365 | } 2366 | 2367 | if typ == nil && defaultType { 2368 | typ = reflect.TypeOf(nil) 2369 | } 2370 | 2371 | return typ, nil 2372 | } 2373 | 2374 | var TYPE_INTERFACE_PROXY = reflect.TypeOf(InterfaceProxy{}) 2375 | var TYPE_FUNC = reflect.TypeOf(func() {}) 2376 | var TYPE_METHOD = reflect.TypeOf(reflect.Method{}) 2377 | var TYPE_ANY = reflect.TypeOf((any)(nil)) 2378 | var TYPE_INTERFACE = TYPE_ANY 2379 | var TYPE_BOOL = reflect.TypeOf(false) 2380 | var TYPE_BYTE = reflect.TypeOf(byte(0)) 2381 | var TYPE_INT = reflect.TypeOf(int(0)) 2382 | var TYPE_INT8 = reflect.TypeOf(int8(0)) 2383 | var TYPE_INT16 = reflect.TypeOf(int16(0)) 2384 | var TYPE_INT32 = reflect.TypeOf(int32(0)) 2385 | var TYPE_INT64 = reflect.TypeOf(int64(0)) 2386 | var TYPE_UINT = reflect.TypeOf(uint(0)) 2387 | var TYPE_UINT8 = reflect.TypeOf(uint8(0)) 2388 | var TYPE_UINT16 = reflect.TypeOf(uint16(0)) 2389 | var TYPE_UINT32 = reflect.TypeOf(uint32(0)) 2390 | var TYPE_UINT64 = reflect.TypeOf(uint64(0)) 2391 | var TYPE_FLOAT32 = reflect.TypeOf(float32(0.0)) 2392 | var TYPE_FLOAT64 = reflect.TypeOf(float64(0.0)) 2393 | var TYPE_STRING = reflect.TypeOf("") 2394 | var TYPE_ERROR = reflect.TypeOf(errors.New("")) 2395 | var TYPE_MAP_ANY_ANY = reflect.TypeOf(map[any]any{}) 2396 | var TYPE_MAP_STRING_ANY = reflect.TypeOf(map[string]any{}) 2397 | var TYPE_MAP_INTERFACE_INTERFACE = reflect.TypeOf(map[interface{}]interface{}{}) 2398 | var TYPE_MAP_STRING_INTERFACE = reflect.TypeOf(map[string]interface{}{}) 2399 | var TYPE_ARR_ANY = reflect.TypeOf([]any{}) 2400 | var TYPE_ARR_INTERFACE = reflect.TypeOf([]interface{}{}) 2401 | var TYPE_ARR_BOOL = reflect.TypeOf([]bool{}) 2402 | var TYPE_ARR_BYTE = reflect.TypeOf([]byte{}) 2403 | var TYPE_ARR_INT = reflect.TypeOf([]int{}) 2404 | var TYPE_ARR_INT8 = reflect.TypeOf([]int8{}) 2405 | var TYPE_ARR_INT16 = reflect.TypeOf([]int16{}) 2406 | var TYPE_ARR_INT32 = reflect.TypeOf([]int32{}) 2407 | var TYPE_ARR_INT64 = reflect.TypeOf([]int64{}) 2408 | var TYPE_ARR_UINT = reflect.TypeOf([]uint{}) 2409 | var TYPE_ARR_UINT8 = reflect.TypeOf([]uint8{}) 2410 | var TYPE_ARR_UINT16 = reflect.TypeOf([]uint16{}) 2411 | var TYPE_ARR_UINT32 = reflect.TypeOf([]uint32{}) 2412 | var TYPE_ARR_UINT64 = reflect.TypeOf([]uint64{}) 2413 | var TYPE_ARR_FLOAT32 = reflect.TypeOf([]float32{}) 2414 | var TYPE_ARR_FLOAT64 = reflect.TypeOf([]float64{}) 2415 | var TYPE_ARR_STRING = reflect.TypeOf([]string{}) 2416 | var TYPE_ARR_MAP_STRING_ANY = reflect.TypeOf([]map[string]any{}) 2417 | var TYPE_ARR_MAP_STRING_INTERFACE = reflect.TypeOf([]map[string]interface{}{}) 2418 | 2419 | func cast(obj any, typ reflect.Type) (any, error) { 2420 | if typ == nil || typ == TYPE_ANY || obj == nil { 2421 | return obj, nil 2422 | } 2423 | 2424 | var t = reflect.TypeOf(obj) 2425 | if t.AssignableTo(typ) { 2426 | return obj, nil 2427 | } 2428 | 2429 | var isStr = t.Kind() == reflect.String 2430 | 2431 | //if obj == nil && typ != nil { 2432 | // return reflect.Zero(typ) 2433 | //} 2434 | 2435 | if isStr && IsNumType(typ.String()) { 2436 | if v, err := strconv.ParseFloat(obj.(string), 64); err != nil { 2437 | return nil, err 2438 | } else { 2439 | obj = v 2440 | } 2441 | } 2442 | 2443 | if IsMapType(typ.String()) { 2444 | var b, err = json.Marshal(obj) 2445 | if err != nil { 2446 | var s = fmt.Sprintf("%q\n", obj) 2447 | b = []byte(s) 2448 | } 2449 | 2450 | var m = map[string]any{} 2451 | if err := json.Unmarshal(b, m); err != nil { 2452 | return nil, err 2453 | } else { 2454 | obj = m 2455 | } 2456 | } 2457 | 2458 | if IsMapType(typ.String()) { 2459 | var s = fmt.Sprint(obj) 2460 | 2461 | var b = []byte(s) 2462 | var m = map[string]any{} 2463 | if err := json.Unmarshal(b, &m); err != nil { 2464 | return nil, err 2465 | } else { 2466 | obj = m 2467 | } 2468 | } 2469 | 2470 | var al = 0 2471 | if IsArrType(typ.String()) { 2472 | //rt := reflect.TypeOf(obj) 2473 | //if IsArrType(rt.String()) { 2474 | // 这里没法用 len 函数 al = len(obj) 2475 | //} 2476 | 2477 | var b, err = json.Marshal(obj) 2478 | if err != nil { 2479 | var s = fmt.Sprintf("%q\n", obj) 2480 | b = []byte(s) 2481 | } 2482 | 2483 | var a []any 2484 | if err := json.Unmarshal(b, &a); err != nil { 2485 | return nil, err 2486 | } else { 2487 | obj = a 2488 | al = len(a) 2489 | } 2490 | } 2491 | 2492 | switch typ { 2493 | case TYPE_BOOL: 2494 | //if obj == nil { 2495 | // return false 2496 | //} 2497 | return obj.(bool), nil 2498 | case TYPE_BYTE: 2499 | return byte(obj.(float64)), nil 2500 | case TYPE_INT: 2501 | return int(obj.(float64)), nil 2502 | case TYPE_INT8: 2503 | return int8(obj.(float64)), nil 2504 | case TYPE_INT16: 2505 | return int16(obj.(float64)), nil 2506 | case TYPE_INT32: 2507 | return int32(obj.(float64)), nil 2508 | case TYPE_INT64: 2509 | return int64(obj.(float64)), nil 2510 | case TYPE_UINT: 2511 | return uint(obj.(float64)), nil 2512 | case TYPE_UINT8: 2513 | return uint8(obj.(float64)), nil 2514 | case TYPE_UINT16: 2515 | return uint16(obj.(float64)), nil 2516 | case TYPE_UINT32: 2517 | return uint32(obj.(float64)), nil 2518 | case TYPE_UINT64: 2519 | return uint64(obj.(float64)), nil 2520 | case TYPE_FLOAT32: 2521 | return float32(obj.(float64)), nil 2522 | case TYPE_FLOAT64: 2523 | return obj.(float64), nil 2524 | case TYPE_STRING: 2525 | return fmt.Sprint(obj), nil 2526 | case TYPE_MAP_STRING_ANY: 2527 | return obj.(map[any]any), nil 2528 | case TYPE_MAP_STRING_INTERFACE: 2529 | var m = map[any]interface{}{} 2530 | for k, v := range obj.(map[any]any) { 2531 | m[k] = v 2532 | } 2533 | return m, nil 2534 | case TYPE_ARR_ANY: 2535 | return obj.([]any), nil 2536 | case TYPE_ARR_BOOL: 2537 | var a = make([]bool, al) 2538 | for i, v := range obj.([]any) { 2539 | if v2, err := cast(v, TYPE_BOOL); err != nil { 2540 | return nil, err 2541 | } else { 2542 | a[i] = v2.(bool) 2543 | } 2544 | } 2545 | return a, nil 2546 | case TYPE_ARR_BYTE: 2547 | var a = make([]byte, al) 2548 | for i, v := range obj.([]any) { 2549 | if v2, err := cast(v, TYPE_BYTE); err != nil { 2550 | return nil, err 2551 | } else { 2552 | a[i] = v2.(byte) 2553 | } 2554 | } 2555 | return a, nil 2556 | case TYPE_ARR_INT: 2557 | var a = make([]int, al) 2558 | for i, v := range obj.([]any) { 2559 | if v2, err := cast(v, TYPE_INT); err != nil { 2560 | return nil, err 2561 | } else { 2562 | a[i] = v2.(int) 2563 | } 2564 | } 2565 | return a, nil 2566 | case TYPE_ARR_INT8: 2567 | var a = make([]int8, al) 2568 | for i, v := range obj.([]any) { 2569 | if v2, err := cast(v, TYPE_INT8); err != nil { 2570 | return nil, err 2571 | } else { 2572 | a[i] = v2.(int8) 2573 | } 2574 | } 2575 | return a, nil 2576 | case TYPE_ARR_INT16: 2577 | var a = make([]int16, al) 2578 | for i, v := range obj.([]any) { 2579 | if v2, err := cast(v, TYPE_INT16); err != nil { 2580 | return nil, err 2581 | } else { 2582 | a[i] = v2.(int16) 2583 | } 2584 | } 2585 | return a, nil 2586 | case TYPE_ARR_INT32: 2587 | var a = make([]int32, al) 2588 | for i, v := range obj.([]any) { 2589 | if v2, err := cast(v, TYPE_INT32); err != nil { 2590 | return nil, err 2591 | } else { 2592 | a[i] = v2.(int32) 2593 | } 2594 | } 2595 | return a, nil 2596 | case TYPE_ARR_INT64: 2597 | var a = make([]int64, al) 2598 | for i, v := range obj.([]any) { 2599 | if v2, err := cast(v, TYPE_INT64); err != nil { 2600 | return nil, err 2601 | } else { 2602 | a[i] = v2.(int64) 2603 | } 2604 | } 2605 | return a, nil 2606 | case TYPE_ARR_UINT: 2607 | var a = make([]uint, al) 2608 | for i, v := range obj.([]any) { 2609 | if v2, err := cast(v, TYPE_UINT); err != nil { 2610 | return nil, err 2611 | } else { 2612 | a[i] = v2.(uint) 2613 | } 2614 | } 2615 | return a, nil 2616 | case TYPE_ARR_UINT8: 2617 | var a = make([]uint8, al) 2618 | for i, v := range obj.([]any) { 2619 | if v2, err := cast(v, TYPE_UINT8); err != nil { 2620 | return nil, err 2621 | } else { 2622 | a[i] = v2.(uint8) 2623 | } 2624 | } 2625 | return a, nil 2626 | case TYPE_ARR_UINT16: 2627 | var a = make([]uint16, al) 2628 | for i, v := range obj.([]any) { 2629 | if v2, err := cast(v, TYPE_UINT16); err != nil { 2630 | return nil, err 2631 | } else { 2632 | a[i] = v2.(uint16) 2633 | } 2634 | } 2635 | return a, nil 2636 | case TYPE_ARR_UINT32: 2637 | var a = make([]uint32, al) 2638 | for i, v := range obj.([]any) { 2639 | if v2, err := cast(v, TYPE_UINT32); err != nil { 2640 | return nil, err 2641 | } else { 2642 | a[i] = v2.(uint32) 2643 | } 2644 | } 2645 | return a, nil 2646 | case TYPE_ARR_UINT64: 2647 | var a = make([]uint64, al) 2648 | for i, v := range obj.([]any) { 2649 | if v2, err := cast(v, TYPE_UINT64); err != nil { 2650 | return nil, err 2651 | } else { 2652 | a[i] = v2.(uint64) 2653 | } 2654 | } 2655 | return a, nil 2656 | case TYPE_ARR_FLOAT32: 2657 | var a = make([]float32, al) 2658 | for i, v := range obj.([]any) { 2659 | if v2, err := cast(v, TYPE_FLOAT32); err != nil { 2660 | return nil, err 2661 | } else { 2662 | a[i] = v2.(float32) 2663 | } 2664 | } 2665 | return a, nil 2666 | case TYPE_ARR_FLOAT64: 2667 | var a = make([]float64, al) 2668 | for i, v := range obj.([]any) { 2669 | if v2, err := cast(v, TYPE_FLOAT64); err != nil { 2670 | return nil, err 2671 | } else { 2672 | a[i] = v2.(float64) 2673 | } 2674 | } 2675 | return a, nil 2676 | case TYPE_ARR_STRING: 2677 | var a = make([]string, al) 2678 | for i, v := range obj.([]any) { 2679 | if v2, err := cast(v, TYPE_STRING); err != nil { 2680 | return nil, err 2681 | } else { 2682 | a[i] = v2.(string) 2683 | } 2684 | } 2685 | return a, nil 2686 | case TYPE_ARR_MAP_STRING_ANY: 2687 | var a = make([]map[string]any, al) 2688 | for i, v := range obj.([]any) { 2689 | if v2, err := cast(v, TYPE_MAP_STRING_ANY); err != nil { 2690 | return nil, err 2691 | } else { 2692 | a[i] = v2.(map[string]any) 2693 | } 2694 | } 2695 | return a, nil 2696 | case TYPE_ARR_MAP_STRING_INTERFACE: 2697 | var a = make([]map[string]interface{}, al) 2698 | for i, v := range obj.([]any) { 2699 | if v2, err := cast(v, TYPE_MAP_STRING_INTERFACE); err != nil { 2700 | return nil, err 2701 | } else { 2702 | a[i] = v2.(map[string]interface{}) 2703 | } 2704 | } 2705 | return a, nil 2706 | case TYPE_FUNC, TYPE_METHOD, TYPE_INTERFACE_PROXY: 2707 | var proxy = InterfaceProxy{} 2708 | if t == TYPE_MAP_STRING_INTERFACE { 2709 | var m = obj.(map[string]interface{}) 2710 | var m2 = map[string]any{} 2711 | for k, v := range m { 2712 | m2[k] = v 2713 | } 2714 | obj = m2 2715 | t = TYPE_MAP_STRING_ANY 2716 | } 2717 | 2718 | if t == TYPE_MAP_STRING_ANY { 2719 | var m = obj.(map[string]any) 2720 | //var cbm = map[string]Listener[any] {} 2721 | 2722 | //var ft = GetStr(m, KEY_TYPE) 2723 | var fv = GetMap(m, KEY_VALUE) 2724 | if fv == nil { 2725 | fv = m 2726 | } 2727 | for k, v := range fv { 2728 | //proxy.Set(k, v) 2729 | 2730 | // FIXME 下面有 PutCallback 2731 | var end = strings.LastIndex(k, ")") 2732 | var start = -1 2733 | if end > 2 { 2734 | start = strings.Index(k, "(") 2735 | } 2736 | var name = "" 2737 | if start > 0 && start < end { 2738 | name = k[0:start] 2739 | } 2740 | if start < 1 || !IsName(name) { 2741 | proxy.Set(k, v) 2742 | continue 2743 | } 2744 | 2745 | //var inTypes, err2 = getTypes(strings.Split(k[index+1:len(k)-1], ",")) 2746 | //if err2 != nil { 2747 | // return nil, err2 2748 | //} 2749 | 2750 | var vt = reflect.TypeOf(v) 2751 | if vt == TYPE_MAP_STRING_ANY { 2752 | //var fcm = v.(map[string]any) 2753 | //var fct = GetStr(fcm, KEY_TYPE) 2754 | //var fcr = fcm[KEY_RETURN] 2755 | //var fcc = GetBool(fcm, KEY_CALLBACK) 2756 | 2757 | //var outTypes, err3 = getTypes(strings.Split(fct, ",")) 2758 | //if err3 != nil { 2759 | // return nil, err3 2760 | //} 2761 | 2762 | var f = CLASS_MAP[k] // reflect.FuncOf(inTypes, outTypes, false) 2763 | //var f = reflect.New(typ).Elem() 2764 | //var f = reflect.MakeFunc(reflect.FuncOf(inTypes, outTypes, false), func(args []reflect.Value) (results []reflect.Value) { 2765 | // fmt.Println(args) 2766 | // return []reflect.Value{reflect.ValueOf(fcr)} 2767 | //}) 2768 | if typ == TYPE_FUNC { 2769 | return f, nil 2770 | } 2771 | if typ == TYPE_METHOD { 2772 | return reflect.Method{ 2773 | Name: name, 2774 | Type: TYPE_INTERFACE_PROXY, 2775 | Func: reflect.ValueOf(f), 2776 | }, nil 2777 | } 2778 | return f, nil 2779 | } 2780 | 2781 | } 2782 | } 2783 | return proxy, nil 2784 | default: 2785 | //switch obj.(type) { 2786 | //case map[string]any: 2787 | // var ret = reflect.ValueOf(GetInstanceValue(typ, false)) 2788 | // fmt.Println("ret = ", ret) 2789 | // if !ret.IsValid() { 2790 | // //var ret = reflect.New(typ) // 2791 | // ret = reflect.Zero(typ) // .Convert(typ) 2792 | // } 2793 | // var ok = true 2794 | // for k, v := range obj.(map[string]any) { 2795 | // var f = ret.FieldByName(k) 2796 | // fmt.Println("f = ", f) 2797 | // if !f.IsValid() { // || !f.CanSet() { 2798 | // continue 2799 | // } 2800 | // 2801 | // if v2, err := cast(v, f.Type()); err != nil { 2802 | // ok = false 2803 | // break 2804 | // } else { 2805 | // f.Set(reflect.ValueOf(v2)) 2806 | // } 2807 | // } 2808 | // 2809 | // if ok { 2810 | // return ret, nil 2811 | // } 2812 | //} 2813 | 2814 | var bytes, err = json.Marshal(obj) 2815 | if err == nil { 2816 | fmt.Println("string(bytes) = ", string(bytes)) 2817 | var ret, isFinal = GetInstanceValue(typ, obj, false, InterfaceProxy{}) 2818 | if isFinal { 2819 | return ret, nil 2820 | } 2821 | fmt.Println("ret = ", ret) 2822 | if ret == nil { 2823 | //var ret = reflect.New(typ) // 2824 | ret = reflect.Zero(typ) // .Convert(typ) 2825 | } else { 2826 | //var t = reflect.TypeOf(ret) 2827 | //ret = reflect.ValueOf(ret).Convert(t) 2828 | } 2829 | err = json.Unmarshal(bytes, &ret) // err = json.Unmarshal([]byte(string(bytes)), &ret) 2830 | if err == nil { 2831 | return ret, nil // reflect.Indirect(ret).Convert(typ), nil 2832 | } 2833 | } 2834 | 2835 | return reflect.ValueOf(obj).Convert(typ), nil 2836 | } 2837 | 2838 | //if (Collection.class.isAssignableFrom(typ)) { 2839 | // var c = obj 2840 | // 2841 | // var nc any 2842 | // if (Queue.class.isAssignableFrom(typ) || AbstractSequentialList.class.isAssignableFrom(typ)) { // LinkedList 2843 | // nc = new LinkedList<>() 2844 | // } 2845 | // else if (Vector.class.isAssignableFrom(typ)) { // Stack 2846 | // nc = new Stack<>() 2847 | // } 2848 | // else if (List.class.isAssignableFrom(typ)) { // 写在最前,和 else 重合,但大部分情况下性能更好 // ArrayList 2849 | // nc = new ArrayList<>(c.size()) 2850 | // } 2851 | // else if (SortedSet.class.isAssignableFrom(typ)) { // TreeSet 2852 | // nc = new TreeSet<>() 2853 | // } 2854 | // else if (Set.class.isAssignableFrom(typ)) { // HashSet, LinkedHashSet 2855 | // nc = new LinkedHashSet<>(c.size()) 2856 | // } 2857 | // else { // List, ArrayList 2858 | // nc = new ArrayList<>(c.size()) 2859 | // } 2860 | // 2861 | // for i, o := range c { 2862 | // nc.add(o) 2863 | // } 2864 | // 2865 | // return nc 2866 | //} 2867 | 2868 | //return TypeUtils.cast(obj, typ, config) 2869 | } 2870 | 2871 | /** FindClass 提供直接调用的方法 2872 | * @param packageOrFileName 2873 | * @param className 2874 | * @param ignoreError 2875 | * @return 2876 | * @throws ClassNotFoundException 2877 | * @throws IOException 2878 | */ 2879 | func FindClass(packageOrFileName string, className string, ignoreError bool) (types.Object, error) { 2880 | //if len(className) <= 0 { 2881 | // return nil, nil 2882 | //} 2883 | 2884 | var index = strings.Index(className, "[") 2885 | if index >= 0 { 2886 | className = className[0:index] 2887 | } 2888 | //这个方法保证在 jar 包里能正常执行 2889 | //var typ = Class.forName(IsEmpty(packageOrFileName, true) ? className : packageOrFileName.replaceAll("/", ".") + "." + className) 2890 | //if (typ != nil) { 2891 | // return typ, nil 2892 | //} 2893 | 2894 | var lst, err = LoadClassList(packageOrFileName, className, ignoreError, 1, 0) 2895 | if err != nil || len(lst) <= 0 { 2896 | return nil, err 2897 | } 2898 | return lst[0], nil 2899 | } 2900 | 2901 | /** FindClassList 2902 | * @param packageOrFileName 2903 | * @param className 2904 | * @param ignoreError 2905 | * @return 2906 | * @throws ClassNotFoundException 2907 | */ 2908 | func FindClassList(packageOrFileName string, className string, ignoreError bool, limit int, offset int, onlyStruct bool) ([]types.Object, error) { 2909 | var lst = []types.Object{} // []reflect.Value{} 2910 | 2911 | var index = -1 2912 | if len(className) > 0 { 2913 | index = strings.Index(className, "[") 2914 | } 2915 | if index >= 0 { 2916 | className = className[0:index] 2917 | } 2918 | 2919 | packageOrFileName = dot2Separator(packageOrFileName) 2920 | var nl = len(packageOrFileName) 2921 | if nl < 1 || packageOrFileName[0:1] == "/" { 2922 | if nl <= 1 { 2923 | packageOrFileName = DEFAULT_MODULE_PATH 2924 | } else { 2925 | packageOrFileName = DEFAULT_MODULE_PATH + packageOrFileName 2926 | } 2927 | } 2928 | 2929 | var allPackage = IsEmpty(packageOrFileName, true) 2930 | var allName = IsEmpty(className, true) 2931 | 2932 | var pkg, err = importer.Default().Import(packageOrFileName) 2933 | if err != nil { 2934 | pkg, err = importer.ForCompiler(token.NewFileSet(), "source", nil).Import(packageOrFileName) 2935 | } 2936 | if err != nil { 2937 | fmt.Println("error:", err) 2938 | return nil, err 2939 | } 2940 | 2941 | var scope = pkg.Scope() 2942 | 2943 | if scope != nil { 2944 | var count = 0 2945 | for _, declName := range scope.Names() { 2946 | var o = scope.Lookup(declName) 2947 | 2948 | fmt.Println(o) 2949 | var v = reflect.ValueOf(o) 2950 | 2951 | fmt.Println(v) 2952 | 2953 | t := reflect.TypeOf(v) // v.Type().String() 2954 | k := t.Kind() 2955 | if allName || className == declName { 2956 | 2957 | //if t == "Struct" || (t == "Func" && !onlyStruct) { // 2958 | if k == reflect.Struct || (k == reflect.Func && !onlyStruct) { 2959 | lst = append(lst, o) // .Convert(t)) // v.Elem()) 2960 | if limit > 0 { 2961 | count++ 2962 | if count >= limit { 2963 | break 2964 | } 2965 | } 2966 | } 2967 | } 2968 | 2969 | if allPackage { 2970 | for i := 0; i < scope.NumChildren(); i++ { 2971 | childScope := scope.Child(i) 2972 | 2973 | //进一步寻找 2974 | childList, err := FindClassList(childScope.String(), className, ignoreError, limit-count, 0, onlyStruct) 2975 | if err != nil || len(childList) <= 0 { 2976 | continue 2977 | } 2978 | 2979 | lst = append(lst, childList...) 2980 | } 2981 | 2982 | } 2983 | 2984 | } 2985 | } 2986 | 2987 | return lst, nil 2988 | } 2989 | 2990 | /** IsEmpty 判断字符是否为空 2991 | * @param s 2992 | * @param trim 2993 | * @return 2994 | */ 2995 | func IsEmpty(s string, trim bool) bool { 2996 | // Log.i(TAG, "IsEmpty s = " + s) 2997 | if s == "" { 2998 | return true 2999 | } 3000 | 3001 | if trim { 3002 | s = Trim(s) 3003 | } 3004 | return len(s) <= 0 3005 | } 3006 | 3007 | /** Trim 判断字符是否为空 3008 | * @param s 3009 | * @return 3010 | */ 3011 | func Trim(s string) string { 3012 | return strings.Trim(s, "128") 3013 | } 3014 | 3015 | func ArrToString(arr []string) string { 3016 | s := "[" 3017 | for i := 0; i < len(arr); i++ { 3018 | s += fmt.Sprint(arr[i]) 3019 | } 3020 | return s + "]" 3021 | } 3022 | 3023 | /** ParseMap 把 JSON 字符串转 Struct 3024 | * @param json 3025 | * @return 3026 | */ 3027 | var ParseMap = func(str string) (map[string]any, error) { 3028 | if str == "" { 3029 | return nil, nil 3030 | } 3031 | m := map[string]any{} 3032 | 3033 | if err := json.Unmarshal([]byte(str), &m); err != nil { 3034 | return nil, err 3035 | } 3036 | return m, nil 3037 | } 3038 | 3039 | /** ParseArr 把 JSON 字符串转 Array 3040 | * @param json 3041 | * @return 3042 | */ 3043 | var ParseArr = func(str string) ([]any, error) { 3044 | if str == "" { 3045 | return nil, nil 3046 | } 3047 | arr := []any{} 3048 | 3049 | if err := json.Unmarshal([]byte(str), &arr); err != nil { 3050 | return nil, err 3051 | } 3052 | return arr, nil 3053 | } 3054 | var ToJSONString = func(str any) (string, error) { 3055 | if str == nil { 3056 | return "", nil 3057 | } 3058 | 3059 | if bytes, err := json.Marshal(&str); err != nil { 3060 | return "", err 3061 | } else { 3062 | return string(bytes), nil 3063 | } 3064 | } 3065 | 3066 | // 参数,包括类型和值 3067 | type Argument struct { 3068 | Reuse bool 3069 | Type string 3070 | Value any 3071 | Global bool 3072 | } 3073 | 3074 | func NewArgument(typ string, value any) Argument { 3075 | arg := Argument{} 3076 | arg.Type = typ 3077 | arg.Value = value 3078 | return arg 3079 | } 3080 | 3081 | /** 3082 | * 将 interface 转成 JSONObject,便于返回时查看 3083 | * TODO 应该在 ParseMap(json, typ) 时代理 typ 内所有的 interface 3084 | */ 3085 | type InterfaceProxy struct { 3086 | _ noCopy // 如果 Proxy 内没有任何成员变量被修改值,则不需要 3087 | orderedmap.OrderedMap 3088 | //OrderedMap map[string]any 3089 | //reflect.Value 3090 | Type reflect.Type 3091 | CallbackMap map[string]Listener[any] // orderedmap.OrderedMap // 3092 | } 3093 | 3094 | type noCopy struct{} 3095 | 3096 | func (*noCopy) Lock() { 3097 | } 3098 | func (*noCopy) Unlock() { 3099 | } 3100 | 3101 | //func (ip *InterfaceProxy) Get(key string) (any, bool) { 3102 | // if ip.OrderedMap == nil { 3103 | // return nil, false 3104 | // } 3105 | // var v = ip.OrderedMap[key] 3106 | // return v, true 3107 | //} 3108 | // 3109 | //func (ip *InterfaceProxy) Set(key string, val any) { 3110 | // if ip.OrderedMap == nil { 3111 | // ip.OrderedMap = map[string]any{} 3112 | // } 3113 | // ip.OrderedMap[key] = val 3114 | //} 3115 | 3116 | func (ip InterfaceProxy) GetType() reflect.Type { 3117 | return ip.Type 3118 | } 3119 | 3120 | func (ip InterfaceProxy) SetType(typ reflect.Type) { 3121 | ip.Type = typ 3122 | } 3123 | 3124 | func (ip InterfaceProxy) GetCallback(method string) Listener[any] { 3125 | if ip.CallbackMap == nil { 3126 | return nil 3127 | } 3128 | return ip.CallbackMap[method] 3129 | //var l, b = ip.CallbackMap.Get(method) 3130 | //if b { 3131 | // return l.(Listener[any]) 3132 | //} 3133 | //return nil 3134 | } 3135 | 3136 | func (ip InterfaceProxy) PutCallback(method string, callback Listener[any]) { 3137 | if ip.CallbackMap == nil { 3138 | ip.CallbackMap = map[string]Listener[any]{} 3139 | } 3140 | ip.CallbackMap[method] = callback 3141 | //ip.CallbackMap.Set(method, callback) 3142 | } 3143 | 3144 | func (ip *InterfaceProxy) Invoke(method string, args []any) (any, error) { 3145 | //mv := reflect.TypeOf(method) 3146 | //var types = make([]reflect.Type, mv.NumIn()) 3147 | //for i := 0; i < mv.NumIn(); i++ { 3148 | // types[i] = mv.In(i) 3149 | //} 3150 | 3151 | return ip.OnInvoke(method, nil, args, true) 3152 | } 3153 | 3154 | func (ip *InterfaceProxy) OnInvoke(method string, types []reflect.Type, args []any, callSuper bool) (any, error) { 3155 | //if method == nil { 3156 | // return nil, nil 3157 | //} 3158 | 3159 | //var name = method.String() // method.Name 3160 | //if name == "" { 3161 | // return nil, nil 3162 | //} 3163 | 3164 | //var key = name + "(" + strings.Join(trimTypes(types), ",") + ")" // 带修饰符,太长 method.toGenericString() 3165 | var key = method // .String() 3166 | var handlerValue, exists = ip.Get(key) 3167 | 3168 | typeStr := "" 3169 | var value any = nil // callSuper ? super.invoke(proxy, method, args) : nil 3170 | if callSuper == false { //TODO default 方法如何执行里面的代码块?可能需要参考热更新,把方法动态加进去 3171 | //FIXME value = method.Func.Call(args) 3172 | //if value == nil || len(value.([]reflect.Value)) <= 0 { //正常情况不会进这个分支,因为 interface 中 static 方法不允许用实例来调用 3173 | // 3174 | //} else { 3175 | switch handlerValue.(type) { 3176 | case map[string]any: 3177 | var handler = handlerValue.(map[string]any) 3178 | value = handler[KEY_RETURN] //TODO 可能根据传参而返回不同值 3179 | typeStr = fmt.Sprint(handler[KEY_TYPE]) 3180 | default: 3181 | value = handlerValue 3182 | } 3183 | //} 3184 | } 3185 | 3186 | var methodObj = map[string]any{} //只需要简要信息 var methodObj = parseMethodObject(method) 3187 | methodObj[KEY_TIME] = time.Now().UnixMilli() 3188 | if value != nil { 3189 | methodObj[KEY_RETURN] = value 3190 | } 3191 | 3192 | var finalMethodArgs = make([]any, len(args)) // list.New() 3193 | if args != nil { 3194 | for i := 0; i < len(args); i++ { 3195 | var v = args[i] 3196 | var t = "any" 3197 | if v != nil { // !v.IsZero() { 3198 | t = reflect.TypeOf(v).String() 3199 | } 3200 | 3201 | finalMethodArgs[i] = parseJSON(t, v) 3202 | } 3203 | 3204 | methodObj[KEY_METHOD_ARGS] = finalMethodArgs 3205 | } 3206 | 3207 | //方法调用记录列表分组对象,按方法分组,且每组是按调用顺序排列的数组,同一个方法可能被调用多次 3208 | cm, exists := ip.Get(KEY_CALL_MAP) 3209 | if exists == false || cm == nil { 3210 | cm = map[string]any{} 3211 | } 3212 | 3213 | callMap := cm.(map[string]any) 3214 | var cl = callMap[key] 3215 | if cl == nil || len(cl.([]any)) <= 0 { 3216 | cl = []any{methodObj} 3217 | } else { 3218 | cl = append(cl.([]any), methodObj) 3219 | } 3220 | 3221 | callMap[key] = cl //倒序,因为要最上方显示最终状态 3222 | ip.Set(KEY_CALL_MAP, callMap) 3223 | 3224 | //方法调用记录列表,按调用顺序排列的数组,同一个方法可能被调用多次 3225 | var methodObj2 = map[string]any{} 3226 | methodObj2[KEY_METHOD] = key 3227 | for k, v := range methodObj { 3228 | methodObj2[k] = v 3229 | } 3230 | 3231 | var lst, exist = ip.Get(KEY_CALL_LIST) 3232 | if !exist { 3233 | lst = []any{} 3234 | } 3235 | 3236 | //var lst = GetArr(ip.OrderedMap, KEY_CALL_LIST) // var lst = GetJSONList(ip.OrderedMap, KEY_CALL_LIST) 3237 | lst = append(lst.([]any), methodObj2) //lst.PushBack(methodObj2) //顺序,因为要直观看到调用过程 3238 | ip.Set(KEY_CALL_LIST, lst) 3239 | 3240 | //是否被设置为 HTTP 回调方法 3241 | var listener = ip.GetCallback(key) 3242 | if listener != nil { //提前判断 && handler.getBooleanValue(KEY_CALLBACK)) { 3243 | err := listener(value, nil, ip) 3244 | if err != nil { 3245 | return nil, err 3246 | } 3247 | } 3248 | 3249 | typ, err := getType(typeStr, value, true) 3250 | if err != nil { 3251 | return nil, errors.New(key + " 中 " + KEY_RETURN + " 值无法转为 " + typeStr + "! " + err.Error()) 3252 | } 3253 | 3254 | value, err = cast(value, typ) 3255 | 3256 | if err != nil { 3257 | fmt.Println(err.Error()) 3258 | if typeStr == "" { 3259 | if value != nil { 3260 | typeStr = "any" 3261 | } else { 3262 | typeStr = reflect.TypeOf(value).String() 3263 | } 3264 | } 3265 | 3266 | return nil, errors.New(key + " 中 " + KEY_RETURN + " 值无法转为 " + typeStr + "! " + err.Error()) 3267 | } 3268 | 3269 | return value, nil 3270 | } 3271 | -------------------------------------------------------------------------------- /unitauto/server.go: -------------------------------------------------------------------------------- 1 | package unitauto 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "github.com/TommyLemon/unitauto-go/unitauto/test" 8 | "io/ioutil" 9 | "log" 10 | "net/http" 11 | "reflect" 12 | "regexp" 13 | "time" 14 | ) 15 | 16 | var Debug = true // 改为 false 不打日志 17 | var Port = 8082 18 | var Addr = ":" + fmt.Sprint(Port) 19 | var IsInit = true // 你的项目不需要这些默认测试配置,可以改为 false,然后在项目中配置需要的 20 | 21 | // Init 初始化默认的测试配置 22 | func Init() { 23 | // 如果没有改,则以下注册时需要传完整的路径,例如 github.com/TommyLemon/unitauto-go/unitauto.test.Hello 24 | 25 | // Struct/Func 需要注册,可通过调用 POST /method/list 接口来生成以下代码,然后复制 ginCode 代码到自己项目中 26 | CLASS_MAP["fmt.Sprint"] = fmt.Sprint 27 | CLASS_MAP["fmt.Print"] = fmt.Print 28 | CLASS_MAP["fmt.Errorf"] = fmt.Errorf 29 | CLASS_MAP["time.Unix"] = time.Unix 30 | CLASS_MAP["regexp.MatchString"] = regexp.MatchString 31 | CLASS_MAP["unitauto.ParseArr"] = ParseArr 32 | 33 | CLASS_MAP["unitauto.test.Hello"] = test.Hello 34 | CLASS_MAP["unitauto.test.Add"] = test.Add 35 | CLASS_MAP["unitauto.test.Minus"] = test.Minus 36 | CLASS_MAP["unitauto.test.Multiply"] = test.Multiply 37 | CLASS_MAP["unitauto.test.Divide"] = test.Divide 38 | CLASS_MAP["unitauto.test.Len"] = test.Len 39 | CLASS_MAP["unitauto.test.Index"] = test.Index 40 | CLASS_MAP["unitauto.test.GetByIndex"] = test.GetByIndex[any] 41 | CLASS_MAP["unitauto.test.GetByIndex[int]"] = test.GetByIndex[int] 42 | CLASS_MAP["unitauto.test.GetByIndex[float64]"] = test.GetByIndex[float64] 43 | CLASS_MAP["unitauto.test.GetByIndex[string]"] = test.GetByIndex[string] 44 | CLASS_MAP["unitauto.test.SetByIndex"] = test.SetByIndex[any] 45 | CLASS_MAP["unitauto.test.SetByIndex[int]"] = test.SetByIndex[int] 46 | CLASS_MAP["unitauto.test.SetByIndex[float64]"] = test.SetByIndex[float64] 47 | CLASS_MAP["unitauto.test.SetByIndex[string]"] = test.SetByIndex[string] 48 | CLASS_MAP["unitauto.test.ComputeAsync"] = test.ComputeAsync 49 | CLASS_MAP["unitauto.test.New"] = test.New 50 | CLASS_MAP["unitauto.test.Compare"] = test.Compare 51 | CLASS_MAP["unitauto.test.TestInterfaceCallback"] = test.TestInterfaceCallback 52 | CLASS_MAP["unitauto.test.Test"] = test.Test{} 53 | CLASS_MAP["*unitauto.test.Test"] = &test.Test{} 54 | CLASS_MAP["unitauto.test.User"] = test.User{} 55 | CLASS_MAP["*unitauto.test.User"] = &test.User{} 56 | CLASS_MAP["unitauto.test.Comment"] = test.Comment{} 57 | CLASS_MAP["*unitauto.test.Comment"] = &test.Comment{} 58 | CLASS_MAP["unitauto.test.Callback"] = Proxy{} // new(test.Callback) 59 | CLASS_MAP["*unitauto.test.Callback"] = &Proxy{} // new(test.Callback) 60 | CLASS_MAP["unitauto.test.CallbackImpl"] = test.CallbackImpl{} 61 | CLASS_MAP["*unitauto.test.CallbackImpl"] = &test.CallbackImpl{} 62 | CLASS_MAP["test.Hello"] = test.Hello 63 | CLASS_MAP["test.Add"] = test.Add 64 | CLASS_MAP["test.Minus"] = test.Minus 65 | CLASS_MAP["test.Multiply"] = test.Multiply 66 | CLASS_MAP["test.Divide"] = test.Divide 67 | CLASS_MAP["test.Len"] = test.Len 68 | CLASS_MAP["test.Index"] = test.Index 69 | CLASS_MAP["test.GetByIndex"] = test.GetByIndex[any] 70 | CLASS_MAP["test.GetByIndex[int]"] = test.GetByIndex[int] 71 | CLASS_MAP["test.GetByIndex[float64]"] = test.GetByIndex[float64] 72 | CLASS_MAP["test.GetByIndex[string]"] = test.GetByIndex[string] 73 | CLASS_MAP["test.SetByIndex"] = test.SetByIndex[any] 74 | CLASS_MAP["test.SetByIndex[int]"] = test.SetByIndex[int] 75 | CLASS_MAP["test.SetByIndex[float64]"] = test.SetByIndex[float64] 76 | CLASS_MAP["test.SetByIndex[string]"] = test.SetByIndex[string] 77 | CLASS_MAP["test.TestGeneric"] = test.TestGeneric[float64, float64] 78 | CLASS_MAP["test.TestGeneric[int,int]"] = test.TestGeneric[int, int] 79 | CLASS_MAP["test.TestGeneric[int,float64]"] = test.TestGeneric[int, float64] 80 | CLASS_MAP["test.ComputeAsync"] = test.ComputeAsync 81 | CLASS_MAP["test.New"] = test.New 82 | CLASS_MAP["test.Compare"] = test.Compare 83 | CLASS_MAP["test.TestInterfaceCallback"] = test.TestInterfaceCallback 84 | CLASS_MAP["test.Test"] = test.Test{} 85 | CLASS_MAP["*test.Test"] = &test.Test{} 86 | CLASS_MAP["test.User"] = test.User{} 87 | CLASS_MAP["*test.User"] = &test.User{} 88 | CLASS_MAP["test.Comment"] = test.Comment{} 89 | CLASS_MAP["*test.Comment"] = &test.Comment{} 90 | CLASS_MAP["test.Callback"] = Proxy{} // new(test.Callback) 91 | CLASS_MAP["*test.Callback"] = &Proxy{} // new(test.Callback) 92 | CLASS_MAP["test.CallbackImpl"] = test.CallbackImpl{} 93 | CLASS_MAP["*test.CallbackImpl"] = &test.CallbackImpl{} 94 | CLASS_MAP["main.Proxy"] = Proxy{} 95 | CLASS_MAP["*main.Proxy"] = &Proxy{} 96 | 97 | // Struct 实例需要转换 98 | var GetInstanceVal = GetInstanceValue 99 | GetInstanceValue = func(typ reflect.Type, val any, reuse bool, proxy InterfaceProxy) (any, bool) { 100 | if !reuse { 101 | if typ.AssignableTo(reflect.TypeOf(test.Test{})) { 102 | toV, err := Convert[test.Test](val, test.Test{}) 103 | return toV, err == nil 104 | } 105 | if typ.AssignableTo(reflect.TypeOf(&test.Test{})) { 106 | toV, err := Convert[*test.Test](val, &test.Test{}) 107 | return toV, err == nil 108 | } 109 | if typ.AssignableTo(reflect.TypeOf(test.User{})) { 110 | toV, err := Convert[test.User](val, test.User{}) 111 | return toV, err == nil 112 | } 113 | if typ.AssignableTo(reflect.TypeOf(&test.User{})) { 114 | toV, err := Convert[*test.User](val, &test.User{}) 115 | return toV, err == nil 116 | } 117 | if typ.AssignableTo(reflect.TypeOf(test.Comment{})) { 118 | toV, err := Convert[test.Comment](val, test.Comment{}) 119 | return toV, err == nil 120 | } 121 | if typ.AssignableTo(reflect.TypeOf(&test.Comment{})) { 122 | toV, err := Convert[*test.Comment](val, &test.Comment{}) 123 | return toV, err == nil 124 | } 125 | if typ.AssignableTo(reflect.TypeOf(test.CallbackImpl{})) { // || typ.AssignableTo(reflect.Indirect(reflect.ValueOf(new(test.Callback))).Type()) { 126 | toV, err := Convert[test.CallbackImpl](val, test.CallbackImpl{}) 127 | return toV, err == nil 128 | } 129 | if typ.AssignableTo(reflect.TypeOf(&test.CallbackImpl{})) { 130 | toV, err := Convert[*test.CallbackImpl](val, &test.CallbackImpl{}) 131 | return toV, err == nil 132 | } 133 | if typ.AssignableTo(reflect.TypeOf(Proxy{})) { 134 | toV, err := Convert[Proxy](val, Proxy{}) 135 | toV.InterfaceProxy = proxy // 组合 InterfaceProxy 的需要给它赋值 136 | return toV, err == nil 137 | } 138 | if typ.AssignableTo(reflect.TypeOf(&Proxy{})) { 139 | toV, err := Convert[*Proxy](val, &Proxy{}) 140 | toV.InterfaceProxy = proxy // 组合 InterfaceProxy 的需要给它赋值 141 | return toV, err == nil 142 | } 143 | //TODO 加上其它的 144 | } 145 | return GetInstanceVal(typ, val, reuse, proxy) 146 | } 147 | 148 | // 取消注释来提升性能 149 | //for _, v := range CLASS_MAP { 150 | // INSTANCE_MAP[reflect.TypeOf(v)] = v 151 | //} 152 | } 153 | 154 | // interface{ func } 需要通过以下方式来注册和模拟 155 | 156 | type Proxy struct { 157 | _ noCopy // 如果 Proxy 内没有任何成员变量被修改值,则不需要 158 | InterfaceProxy 159 | } 160 | 161 | // 如果已经定义了 struct 和 method,也可以直接在现有的 method 中调用 InterfaceProxy.Invoke 162 | 163 | func (p Proxy) OnSuccess(data any) { 164 | fmt.Println("OnSuccess data = ", data) 165 | //p.Invoke(reflect.ValueOf(Proxy.OnSuccess), []reflect.Value{reflect.ValueOf(data)}) 166 | 167 | // 必须调用 168 | p.Invoke("OnSuccess(any)", []any{data}) 169 | } 170 | func (p Proxy) OnFailure(err error) { 171 | fmt.Println("OnFailure err = ", err) 172 | //p.Invoke(reflect.ValueOf(Proxy.OnFailure), []reflect.Value{reflect.ValueOf(err)}) 173 | 174 | // 必须调用 175 | p.Invoke("OnFailure(error)", []any{err}) 176 | } 177 | 178 | func Start(port int) { 179 | if port > 0 { 180 | Port = port 181 | } 182 | Addr = ":" + fmt.Sprint(Port) 183 | 184 | if IsInit { 185 | Init() 186 | } 187 | 188 | http.HandleFunc("/method/list", Handle) 189 | http.HandleFunc("/method/invoke", Handle) 190 | err := http.ListenAndServe(Addr, nil) 191 | if err != nil { 192 | log.Fatal(err) 193 | } 194 | } 195 | 196 | // Handle 处理网络请求 197 | func Handle(w http.ResponseWriter, r *http.Request) { 198 | if r.Method == http.MethodOptions { 199 | //logger.Infof("%v", r.Header) 200 | Cors(w, r) 201 | w.WriteHeader(http.StatusOK) 202 | return 203 | } 204 | 205 | if r.Method != http.MethodPost { 206 | w.WriteHeader(http.StatusNotFound) 207 | return 208 | } 209 | 210 | Cors(w, r) 211 | 212 | if data, err := ioutil.ReadAll(r.Body); err != nil { 213 | fmt.Errorf("请求参数有问题: " + err.Error()) 214 | w.WriteHeader(http.StatusBadRequest) 215 | return 216 | } else { 217 | var reqStr = string(data) 218 | fmt.Printf("request: %s", reqStr) 219 | 220 | //var done = false 221 | var called = false 222 | var respMap map[string]any 223 | if r.URL.Path == "/method/list" { 224 | respMap = ListMethodByStr(reqStr) 225 | } else if r.URL.Path == "/method/invoke" { 226 | w.Header().Set("Content-Length", "-1") 227 | 228 | //timer := time.NewTimer(time.Minute) 229 | //go func(t *time.Timer) { 230 | // called = true 231 | // timer.Stop() 232 | // w.WriteHeader(http.StatusInternalServerError) 233 | //}(timer) 234 | 235 | // 没用,只能阻塞,持续不断地发消息 236 | //ticker := time.NewTicker(time.Millisecond) 237 | 238 | if err := InvokeMethodByStr(reqStr, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 239 | if called || r.Close { 240 | return nil 241 | } 242 | called = true 243 | 244 | if respBody, err := json.Marshal(data); err != nil { 245 | //done = true 246 | w.WriteHeader(http.StatusInternalServerError) 247 | } else { 248 | if Debug { 249 | fmt.Println("respBody = ", string(respBody)) 250 | } 251 | //done = true 252 | _, err2 := w.Write(respBody) 253 | if err2 != nil { 254 | w.WriteHeader(http.StatusInternalServerError) 255 | } else { 256 | w.WriteHeader(http.StatusOK) 257 | } 258 | } 259 | 260 | //done = true 261 | r.Context().Done() 262 | 263 | //ticker.Stop() 264 | return nil 265 | }); err == nil { 266 | //go func(t *time.Ticker) { 267 | for { // FIXME 用 done 判断导致报错 concurrent modify map;用 called 有时返回空对象,尤其是高并发时 268 | if called || r.Close { // done || r.Close { 269 | break 270 | } 271 | w.Header().Set("Connection", "Keep-Alive") 272 | } 273 | //}(ticker) 274 | return 275 | } else { 276 | respMap = NewErrorResult(err) 277 | } 278 | } else { 279 | respMap = NewErrorResult(errors.New("URL 错误,只支持 /method/list 和 /method/invoke")) 280 | } 281 | 282 | if called || r.Close { 283 | return 284 | } 285 | called = true 286 | 287 | if respBody, err := json.Marshal(respMap); err != nil { 288 | w.WriteHeader(http.StatusInternalServerError) 289 | } else { 290 | _, err = w.Write(respBody) 291 | if err != nil { 292 | w.WriteHeader(http.StatusInternalServerError) 293 | } else { 294 | w.WriteHeader(http.StatusOK) 295 | } 296 | } 297 | 298 | //done = true 299 | r.Context().Done() 300 | } 301 | } 302 | 303 | // Cors 解决前端网页跨域问题 304 | func Cors(w http.ResponseWriter, r *http.Request) { 305 | var hosts = r.Header["Origin"] 306 | if len(hosts) <= 0 { 307 | hosts = r.Header["origin"] 308 | } 309 | 310 | var host = "" 311 | if len(hosts) > 0 { 312 | host = hosts[0] 313 | } 314 | if len(host) < 5 { 315 | host = "http://apijson.cn" 316 | } 317 | 318 | w.Header().Set("Content-Type", "application/json;charset=UTF-8") 319 | w.Header().Set("Access-Control-Allow-Origin", host) 320 | w.Header().Set("Access-Control-Allow-Credentials", "true") 321 | w.Header().Set("Access-Control-Allow-Headers", "content-type") 322 | w.Header().Set("Access-Control-Request-Method", "POST") 323 | //w.Header().Set("Content-Length", "-1") 324 | //w.Header().Set("Transfer-Encoding", "chunked") 325 | } 326 | 327 | func Test() { 328 | Init() 329 | 330 | _ = InvokeMethod(map[string]any{ 331 | KEY_PACKAGE: "unitauto.test", 332 | KEY_CLASS: "Hello", 333 | KEY_METHOD: "Hello", 334 | KEY_METHOD_ARGS: []any{ 335 | "UnitAuto", 336 | }, 337 | }, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 338 | str, _ := ToJSONString(data) 339 | println("\nunitauto.test.Hello(UnitAuto) = \n" + str) 340 | return nil 341 | }) 342 | 343 | _ = InvokeMethod(map[string]any{ 344 | KEY_PACKAGE: "test", 345 | KEY_CLASS: "Minus", 346 | KEY_METHOD: "Minus", 347 | KEY_METHOD_ARGS: []any{ 348 | map[string]any{ 349 | KEY_TYPE: "int64", 350 | KEY_VALUE: int64(2), 351 | }, 352 | map[string]any{ 353 | KEY_TYPE: "int64", 354 | KEY_VALUE: int64(3), 355 | }, 356 | }, 357 | }, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 358 | str, _ := ToJSONString(data) 359 | println("\ntest.Minus(2, 3) = \n" + str) 360 | return nil 361 | }) 362 | 363 | _ = InvokeMethod(map[string]any{ 364 | KEY_PACKAGE: "*test", 365 | KEY_CLASS: "Test", 366 | KEY_CONSTRUCTOR: "New", 367 | KEY_METHOD: "GetId", 368 | }, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 369 | str, _ := ToJSONString(data) 370 | println("\nunitauto.test.Test.GetId() = \n" + str) 371 | return nil 372 | }) 373 | 374 | _ = InvokeMethod(map[string]any{ 375 | KEY_PACKAGE: "*unitauto.test", 376 | KEY_CLASS: "Test", 377 | KEY_THIS: map[string]any{ 378 | KEY_TYPE: "*unitauto.test.Test", 379 | KEY_VALUE: map[string]any{ 380 | "Id": 1, 381 | "Name": "UnitAuto", 382 | }, 383 | }, 384 | KEY_METHOD: "SetName", 385 | KEY_METHOD_ARGS: []any{ 386 | "UnitAuto@Go", 387 | }, 388 | }, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 389 | str, _ := ToJSONString(data) 390 | println("\nunitauto.test.Test.SetName() = \n" + str) 391 | return nil 392 | }) 393 | 394 | _ = InvokeMethod(map[string]any{ 395 | KEY_PACKAGE: "test", 396 | KEY_CLASS: "TestGeneric[int,float64]", 397 | KEY_METHOD: "TestGeneric", 398 | KEY_METHOD_ARGS: []any{ 399 | "int:10", 400 | float64(2), 401 | }, 402 | }, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 403 | str, _ := ToJSONString(data) 404 | println("\ntest.Test.TestGeneric() = \n" + str) 405 | return nil 406 | }) 407 | 408 | _ = InvokeMethod(map[string]any{ 409 | KEY_PACKAGE: "unitauto.test", 410 | KEY_CLASS: "ComputeAsync", 411 | KEY_METHOD: "ComputeAsync", 412 | KEY_METHOD_ARGS: []any{ 413 | map[string]any{ 414 | KEY_TYPE: "int", 415 | KEY_VALUE: 2, 416 | }, 417 | map[string]any{ 418 | KEY_TYPE: "int", 419 | KEY_VALUE: 8, 420 | }, 421 | map[string]any{ 422 | KEY_TYPE: "func(int,int)int", 423 | KEY_VALUE: map[string]any{ 424 | KEY_TYPE: "int", 425 | KEY_RETURN: 5, 426 | KEY_CALLBACK: true, 427 | }, 428 | }, 429 | }, 430 | }, nil, func(data any, method *reflect.Method, proxy *InterfaceProxy, extras ...any) error { 431 | str, _ := ToJSONString(data) 432 | println("\nunitauto.test.ComputeAsync(2, 8, listener) = \n" + str) 433 | return nil 434 | }) 435 | 436 | } 437 | -------------------------------------------------------------------------------- /unitauto/test/test_util.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "time" 7 | ) 8 | 9 | func Hello(s string) string { 10 | return "Hello, " + s + " !" 11 | } 12 | 13 | func Add(a int, b int) int { 14 | return a + b 15 | } 16 | 17 | func Minus(a int64, b int64) int64 { 18 | return a - b 19 | } 20 | 21 | func Multiply(a float32, b float32) float64 { 22 | return float64(a * b) 23 | } 24 | 25 | func Divide(a int, b int) float64 { 26 | return float64(a) / float64(b) 27 | } 28 | 29 | func Len(arr []int) int { 30 | if arr == nil { 31 | return 0 32 | } 33 | return len(arr) 34 | } 35 | 36 | func Index(arr []any, item any) int { 37 | l := len(arr) 38 | if l <= 0 { 39 | return -1 40 | } 41 | 42 | for i := 0; i < l; i++ { 43 | if arr[i] == item { 44 | return i 45 | } 46 | } 47 | 48 | return -1 49 | } 50 | 51 | func GetByIndex[T any](arr []T, index int) *T { 52 | l := len(arr) 53 | if l <= 0 || l <= index { 54 | return nil 55 | } 56 | 57 | return &arr[index] 58 | } 59 | 60 | func SetByIndex[T any](arr []T, index int, item T) { 61 | l := len(arr) 62 | if l <= 0 || l <= index { 63 | return 64 | } 65 | 66 | arr[index] = item 67 | } 68 | 69 | func TestGeneric[T int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64, R int | float64](a T, b R) float64 { 70 | return float64(a) + float64(b) 71 | } 72 | 73 | func ComputeAsync(a int, b int, callback func(a int, b int) int) int { 74 | go func() { 75 | time.Sleep(time.Second * 3) // 模拟耗时 3s 76 | var result any 77 | if a < b { 78 | result = callback(a, b) 79 | } else { 80 | result = callback(b, a) 81 | } 82 | fmt.Println("ComputeAsync result = ", result) 83 | }() 84 | return a + b 85 | } 86 | 87 | type Callback interface { 88 | OnSuccess(data any) 89 | OnFailure(err error) 90 | } 91 | 92 | type CallbackImpl struct { 93 | //unitauto.InterfaceProxy 94 | } 95 | 96 | func (test CallbackImpl) OnSuccess(data any) { 97 | fmt.Println("OnSuccess data = ", data) 98 | //test.Invoke("OnSuccess(any)", []any{data}) 99 | } 100 | func (test CallbackImpl) OnFailure(err error) { 101 | fmt.Println("OnFailure err = ", err) 102 | //test.Invoke("OnFailure(err)", []any{err}) 103 | } 104 | 105 | func (test Test) OnSuccess(data any) { 106 | fmt.Println("OnSuccess data = ", data) 107 | } 108 | func (test Test) OnFailure(err error) { 109 | fmt.Println("OnFailure err = ", err) 110 | } 111 | 112 | func TestInterfaceCallback(a int, callback Callback) { 113 | go func() { 114 | time.Sleep(time.Second * 2) // 模拟耗时 2s 115 | if a%2 == 0 { 116 | callback.OnSuccess(a + 1) 117 | } else { 118 | callback.OnFailure(errors.New("a%2 != 0")) 119 | } 120 | }() 121 | } 122 | 123 | type Test struct { 124 | Id int 125 | Name string 126 | } 127 | 128 | func (test *Test) GetId() int { 129 | return test.Id 130 | } 131 | 132 | func (test *Test) GetName() string { 133 | return test.Name 134 | } 135 | 136 | func (test *Test) SetId(id int) { 137 | test.Id = id 138 | } 139 | 140 | func (test *Test) SetName(name string) { 141 | test.Name = name 142 | } 143 | 144 | func (test *Test) String() string { 145 | return "{id: " + fmt.Sprint(test.Id) + ", name: " + test.Name + "}" 146 | } 147 | 148 | func Compare(t1 Test, t2 Test) int { 149 | if t1.Id == t2.Id { 150 | return 0 151 | } 152 | if t1.Id < t2.Id { 153 | return -1 154 | } 155 | return 1 156 | } 157 | 158 | func New() Test { 159 | return Test{ 160 | Id: 1, 161 | Name: "Test", 162 | } 163 | } 164 | 165 | type User struct { 166 | Id int 167 | Name string 168 | Sex int 169 | Certified bool 170 | Balance float64 171 | Date int64 172 | } 173 | 174 | func (user *User) AddBalance(amount float64) { 175 | user.Balance += amount 176 | } 177 | 178 | type Comment struct { 179 | Id int 180 | ToId int 181 | Content string 182 | UserId int 183 | Date int64 184 | User User 185 | } 186 | 187 | func (comment *Comment) Reply(c Comment) bool { 188 | comment.ToId = c.Id 189 | return true 190 | } 191 | 192 | func (comment Comment) GetPublisher(c Comment) User { 193 | return comment.User 194 | } 195 | 196 | func ReplyTo(c Comment, c2 Comment) bool { 197 | c.ToId = c2.Id 198 | return true 199 | } 200 | --------------------------------------------------------------------------------