1 | #Region "Microsoft.VisualBasic::d8b6f46f12dc7bc47dcaa346d479d398, Microsoft.VisualBasic.Core\CommandLine\InteropService\CLIAbstractor.vb" |
2 | |
3 | ' Author: |
4 | ' |
5 | ' asuka (amethyst.asuka@gcmodeller.org) |
6 | ' xie (genetics@smrucc.org) |
7 | ' xieguigang (xie.guigang@live.com) |
8 | ' |
9 | ' Copyright (c) 2018 GPL3 Licensed |
10 | ' |
11 | ' |
12 | ' GNU GENERAL PUBLIC LICENSE (GPL3) |
13 | ' |
14 | ' |
15 | ' This program is free software: you can redistribute it and/or modify |
16 | ' it under the terms of the GNU General Public License as published by |
17 | ' the Free Software Foundation, either version 3 of the License, or |
18 | ' (at your option) any later version. |
19 | ' |
20 | ' This program is distributed in the hope that it will be useful, |
21 | ' but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | ' GNU General Public License for more details. |
24 | ' |
25 | ' You should have received a copy of the GNU General Public License |
26 | ' along with this program. If not, see <http://www.gnu.org/licenses/>. |
27 | |
28 | |
29 | |
30 | ' /********************************************************************************/ |
31 | |
32 | ' Summaries: |
33 | |
34 | ' Module CLIAbstractor |
35 | ' |
36 | ' Function: CLICaller, CLIUsage |
37 | ' |
38 | ' |
39 | ' /********************************************************************************/ |
40 | |
41 | #End Region |
42 | |
43 | Imports System.Reflection |
44 | Imports System.Runtime.CompilerServices |
45 | Imports System.Text |
46 | Imports Microsoft.VisualBasic.Language |
47 | Imports Microsoft.VisualBasic.Scripting.Runtime |
48 | |
49 | Namespace CommandLine.InteropService |
50 | |
51 | ''' <summary> |
52 | ''' 将函数的定义抽象为一个命令行,从而能够提供更好的命令行编写服务 |
53 | ''' </summary> |
54 | Public Module CLIAbstractor |
55 | |
56 | ''' <summary> |
57 | ''' Abstract the function declare as a CLI usage declare. This tool not support the generic function method. |
58 | ''' (不支持泛型函数) |
59 | ''' </summary> |
60 | ''' <param name="api"></param> |
61 | ''' <param name="prefix$"></param> |
62 | ''' <returns></returns> |
63 | Public Function CLIUsage(api As MethodInfo, Optional prefix$ = "/") As String |
64 | Dim isGeneric = (Not api.GetGenericArguments.IsNullOrEmpty) Or die($"Function abstract tool not working on a generic method: {api.DeclaringType.FullName}::{api.Name}!") |
65 | Dim name$ = prefix & api.Name |
66 | Dim args As New List(Of ParameterInfo)(api.GetParameters) |
67 | Dim optionalArguments = args.Where(Function(param) param.IsOptional).ToArray |
68 | Dim requiredArguments = args - optionalArguments |
69 | Dim usage As New StringBuilder |
70 | Dim required$ = requiredArguments _ |
71 | .Select(Function(param) |
72 | Return $"{prefix}{param.Name} <value:={param.Name}>" |
73 | End Function) _ |
74 | .JoinBy(" ") |
75 | Dim optionals = optionalArguments _ |
76 | .Select(Function(param) |
77 | If param.ParameterType Is GetType(Boolean) Then |
78 | Return $"{prefix}{param.Name}" |
79 | Else |
80 | Dim default$ = $"<default={CStrSafe(param.DefaultValue)}>" |
81 | Return $"{prefix}{param.Name} {[default]}" |
82 | End If |
83 | End Function) _ |
84 | .JoinBy(" ") |
85 | |
86 | Call usage.Append(name & " ") |
87 | Call usage.Append(required) |
88 | Call usage.Append(" ") |
89 | Call usage.Append($"[{optionals}]") |
90 | |
91 | Return usage.ToString.Trim |
92 | End Function |
93 | |
94 | <Extension> Public Function CLICaller(api As MethodInfo, args As CommandLine) As Integer |
95 | Dim paramValues As List(Of Object) |
96 | Dim names As Dictionary(Of String, String) |
97 | Dim parameters = api.GetParameters |
98 | |
99 | If parameters.Length = 1 AndAlso parameters(Scan0).ParameterType Is GetType(CommandLine) Then |
100 | Return DirectCast(api.Invoke(Nothing, {args}), Integer) |
101 | Else |
102 | paramValues = New List(Of Object) |
103 | End If |
104 | |
105 | names = args _ |
106 | .Keys _ |
107 | .ToDictionary(Function(k) |
108 | Return k.Trim("/"c, "-"c).Trim.ToLower |
109 | End Function) |
110 | |
111 | For Each param As ParameterInfo In api.GetParameters |
112 | Dim name$ = param.Name.ToLower |
113 | |
114 | If param.ParameterType Is GetType(Boolean) Then |
115 | paramValues += names.ContainsKey(name) |
116 | Else |
117 | paramValues += Scripting.CTypeDynamic( |
118 | args(names(name)), |
119 | param.ParameterType |
120 | ) |
121 | End If |
122 | Next |
123 | |
124 | Dim result% = DirectCast(api.Invoke(Nothing, paramValues.ToArray), Integer) |
125 | Return result |
126 | End Function |
127 | End Module |
128 | End Namespace |