2020-01-02 19:08:37 +08:00
|
|
|
|
#Region "Microsoft.VisualBasic::e4aadecd84ae19dea90f2a572f5e5cfd, Microsoft.VisualBasic.Core\CommandLine\InteropService\SharedORM\Languages\VisualBasic.vb"
|
|
|
|
|
|
|
|
|
|
|
|
' Author:
|
|
|
|
|
|
'
|
|
|
|
|
|
' asuka (amethyst.asuka@gcmodeller.org)
|
|
|
|
|
|
' xie (genetics@smrucc.org)
|
|
|
|
|
|
' xieguigang (xie.guigang@live.com)
|
|
|
|
|
|
'
|
|
|
|
|
|
' Copyright (c) 2018 GPL3 Licensed
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' GNU GENERAL PUBLIC LICENSE (GPL3)
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is free software: you can redistribute it and/or modify
|
|
|
|
|
|
' it under the terms of the GNU General Public License as published by
|
|
|
|
|
|
' the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
|
' (at your option) any later version.
|
|
|
|
|
|
'
|
|
|
|
|
|
' This program is distributed in the hope that it will be useful,
|
|
|
|
|
|
' but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
|
' GNU General Public License for more details.
|
|
|
|
|
|
'
|
|
|
|
|
|
' You should have received a copy of the GNU General Public License
|
|
|
|
|
|
' along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
' /********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
' Summaries:
|
|
|
|
|
|
|
|
|
|
|
|
' Class VisualBasic
|
|
|
|
|
|
'
|
|
|
|
|
|
' Constructor: (+2 Overloads) Sub New
|
|
|
|
|
|
'
|
|
|
|
|
|
' Function: addXmlComments, ArgumentXmlDocs, createCliCalls, GetSourceCode, normAsVisualBasicName
|
|
|
|
|
|
' optionalDefaultValue, vbParameters
|
|
|
|
|
|
'
|
|
|
|
|
|
' Sub: cliCallsInternal
|
|
|
|
|
|
'
|
|
|
|
|
|
'
|
|
|
|
|
|
' /********************************************************************************/
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Imports System.Runtime.CompilerServices
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Imports System.Text
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Imports Microsoft.VisualBasic.CommandLine.Reflection
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Language
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Imports Microsoft.VisualBasic.Linq
|
2018-10-03 13:28:23 +08:00
|
|
|
|
Imports Microsoft.VisualBasic.Scripting.SymbolBuilder.VBLanguage
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Imports Microsoft.VisualBasic.Text
|
|
|
|
|
|
Imports Microsoft.VisualBasic.Text.Xml
|
|
|
|
|
|
|
|
|
|
|
|
Namespace CommandLine.InteropService.SharedORM
|
|
|
|
|
|
|
|
|
|
|
|
Public Class VisualBasic : Inherits CodeGenerator
|
|
|
|
|
|
|
|
|
|
|
|
Dim namespace$
|
|
|
|
|
|
|
2018-11-11 13:38:09 +08:00
|
|
|
|
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Public Sub New(CLI As Type, namespace$)
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Me.New(New Interpreter(type:=CLI), [namespace])
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Sub
|
|
|
|
|
|
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Sub New(App As Interpreter, Optional namespace$ = Nothing)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Call MyBase.New(App)
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Me.namespace = [namespace] Or App.Type.Name.AsDefault
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End Sub
|
|
|
|
|
|
|
|
|
|
|
|
Public Overrides Function GetSourceCode() As String
|
|
|
|
|
|
Dim vb As New StringBuilder
|
|
|
|
|
|
Dim className$ = MyBase.exe _
|
2019-03-25 18:15:46 +08:00
|
|
|
|
.NormalizePathString(alphabetOnly:=True) _
|
2018-08-02 20:14:48 +08:00
|
|
|
|
.Replace(" ", "_")
|
2018-10-23 20:37:21 +08:00
|
|
|
|
Dim rel$ = PathExtensions.RelativePath(App.Type.Assembly.Location.GetFullPath)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim info$ = App.Type.NamespaceEntry.Description
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Dim appName$ = KeywordProcessor.AutoEscapeVBKeyword(className)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Call vb.AppendLine("Imports System.Runtime.CompilerServices")
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Call vb.AppendLine("Imports " & GetType(StringBuilder).Namespace)
|
|
|
|
|
|
Call vb.AppendLine("Imports " & GetType(IIORedirectAbstract).Namespace)
|
|
|
|
|
|
Call vb.AppendLine("Imports " & GetType(InteropService).Namespace)
|
|
|
|
|
|
Call vb.AppendLine("Imports Microsoft.VisualBasic.ApplicationServices")
|
|
|
|
|
|
Call vb.AppendLine()
|
|
|
|
|
|
Call vb.AppendLine("' Microsoft VisualBasic CommandLine Code AutoGenerator")
|
|
|
|
|
|
Call vb.AppendLine("' assembly: " & rel)
|
|
|
|
|
|
Call vb.AppendLine()
|
|
|
|
|
|
Call vb.AppendLine(GetManualPage.LineTokens.Select(Function(l) "' " & l).JoinBy(vbCrLf))
|
|
|
|
|
|
Call vb.AppendLine()
|
|
|
|
|
|
Call vb.AppendLine("Namespace " & [namespace])
|
|
|
|
|
|
Call vb.AppendLine()
|
2019-08-31 11:42:06 +08:00
|
|
|
|
Call vb.AppendLine(addXmlComments(XmlEntity.EscapingXmlEntity(info)))
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Call vb.AppendLine($"Public Class {appName} : Inherits {GetType(InteropService).Name}")
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Call vb.AppendLine()
|
|
|
|
|
|
Call vb.AppendLine($" Public Const App$ = ""{exe}.exe""")
|
|
|
|
|
|
Call vb.AppendLine()
|
|
|
|
|
|
Call vb.AppendLine(" Sub New(App$)")
|
|
|
|
|
|
Call vb.AppendLine($" MyBase.{NameOf(InteropService._executableAssembly)} = App$")
|
|
|
|
|
|
Call vb.AppendLine(" End Sub")
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Call vb.AppendLine("
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' Create an internal CLI pipeline invoker from a given environment path.
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name=""directory"">A directory path that contains the target application</param>
|
|
|
|
|
|
''' <returns></returns>")
|
2018-11-11 13:38:09 +08:00
|
|
|
|
Call vb.AppendLine(" <MethodImpl(MethodImplOptions.AggressiveInlining)>")
|
|
|
|
|
|
Call vb.AppendLine($" Public Shared Function FromEnvironment(directory As String) As {appName}")
|
|
|
|
|
|
Call vb.AppendLine($" Return New {appName}(App:=directory & ""/"" & {appName}.App)")
|
|
|
|
|
|
Call vb.AppendLine(" End Function")
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-11-30 14:14:02 +08:00
|
|
|
|
For Each api As APITuple In Me.EnumeratesAPI
|
|
|
|
|
|
Call cliCallsInternal(vb, api, incompatible:=Not InCompatibleAttribute.CLRProcessCompatible(api.API))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Call vb.AppendLine("End Class")
|
|
|
|
|
|
Call vb.AppendLine("End Namespace")
|
|
|
|
|
|
|
|
|
|
|
|
Return vb.ToString
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-11-30 14:14:02 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
'''
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="description$"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
Private Shared Function addXmlComments(description$) As String
|
2018-08-02 20:14:48 +08:00
|
|
|
|
If description.StringEmpty Then
|
|
|
|
|
|
description = "'''"
|
|
|
|
|
|
Else
|
|
|
|
|
|
description = description _
|
|
|
|
|
|
.LineTokens _
|
|
|
|
|
|
.Select(Function(s) "''' " & s.Trim(" "c, ASCII.TAB)) _
|
|
|
|
|
|
.JoinBy(vbCrLf)
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Return $"
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
{description}
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
'''"
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
''' 生成一个命令行API的调用代码
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="vb"></param>
|
2019-11-30 14:14:02 +08:00
|
|
|
|
''' <param name="cli"></param>
|
2018-08-02 20:14:48 +08:00
|
|
|
|
''' <remarks>
|
|
|
|
|
|
''' </remarks>
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Private Sub cliCallsInternal(vb As StringBuilder, cli As APITuple, incompatible As Boolean)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
#Region "Code template"
|
|
|
|
|
|
|
|
|
|
|
|
' Public Function CommandName(args$,....Optional args$....) As Integer
|
|
|
|
|
|
' Dim CLI$ = "commandname arguments"
|
|
|
|
|
|
' Dim proc As IIORedirectAbstract = RunDotNetApp(CLI$)
|
|
|
|
|
|
'
|
|
|
|
|
|
' Return proc.Run()
|
|
|
|
|
|
' End Function
|
|
|
|
|
|
#End Region
|
|
|
|
|
|
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Dim api As NamedValue(Of CommandLine) = cli.CLI
|
2018-08-02 20:14:48 +08:00
|
|
|
|
' 直接使用函数原型的名字了,会比较容易辨别一些
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Dim func$ = api.Name
|
2018-08-02 20:14:48 +08:00
|
|
|
|
' Xml comment 已经是经过转义了的,所以不需要再做xml entity的转义了
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Dim xmlComments$ = addXmlComments(api.Description)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim params$()
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Dim usage As Argument() = cli.API _
|
|
|
|
|
|
.GetCustomAttributes(True) _
|
|
|
|
|
|
.Where(Function(a)
|
|
|
|
|
|
Return a.GetType Is GetType(Argument)
|
|
|
|
|
|
End Function) _
|
|
|
|
|
|
.Select(Function(use) DirectCast(use, Argument)) _
|
|
|
|
|
|
.ToArray
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
Try
|
|
|
|
|
|
If func.First <= "9" AndAlso func.First >= "0"c Then
|
|
|
|
|
|
func = "_" & func ' 有些命令行开关是以数字开头的?
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 不是以数字开头的,则尝试解决关键词的问题
|
2018-10-03 13:28:23 +08:00
|
|
|
|
func = KeywordProcessor.AutoEscapeVBKeyword(func)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
2019-11-30 14:14:02 +08:00
|
|
|
|
params = vbParameters(api.Value)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Catch ex As Exception
|
2019-11-30 14:14:02 +08:00
|
|
|
|
ex = New Exception("Check for your CLI Usage definition: " & api.Value.ToString, ex)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Throw ex
|
|
|
|
|
|
End Try
|
|
|
|
|
|
|
|
|
|
|
|
Call vb.AppendLine(xmlComments)
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Call vb.AppendLine(usage.DoCall(AddressOf ArgumentXmlDocs).JoinBy(vbCrLf))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-09-13 00:43:14 +08:00
|
|
|
|
Dim deli$
|
|
|
|
|
|
|
|
|
|
|
|
If params.Length > 4 Then
|
|
|
|
|
|
deli = ", " & vbCrLf & New String(" "c, 20 + func.Length)
|
|
|
|
|
|
Else
|
|
|
|
|
|
deli = ", "
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
2019-12-08 18:54:02 +08:00
|
|
|
|
Dim funcDeclare$ = $"Public Function {func}({params.JoinBy(deli)}) As Integer"
|
|
|
|
|
|
|
|
|
|
|
|
Call vb.AppendLine(funcDeclare)
|
2019-12-08 18:01:27 +08:00
|
|
|
|
Call vb.AppendLine($" Dim CLI As New StringBuilder(""{api.Value.Name}"")")
|
2019-12-08 18:02:46 +08:00
|
|
|
|
' 插入命令名称和参数值之间的一个必须的空格
|
|
|
|
|
|
Call vb.AppendLine(" Call CLI.Append("" "")")
|
2019-12-08 18:01:27 +08:00
|
|
|
|
Call vb.AppendLine(createCliCalls(+api))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Call vb.AppendLine()
|
|
|
|
|
|
|
|
|
|
|
|
If incompatible Then
|
|
|
|
|
|
' 这个CLI是不兼容的方法
|
|
|
|
|
|
Call vb.AppendLine($" Dim proc As {NameOf(IIORedirectAbstract)} = {NameOf(InteropService.RunProgram)}(CLI.ToString(), Nothing)")
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 兼容的
|
|
|
|
|
|
Call vb.AppendLine($" Dim proc As {NameOf(IIORedirectAbstract)} = {NameOf(InteropService.RunDotNetApp)}(CLI.ToString())")
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
Call vb.AppendLine($" Return proc.{NameOf(IIORedirectAbstract.Run)}()")
|
|
|
|
|
|
Call vb.AppendLine("End Function")
|
|
|
|
|
|
End Sub
|
|
|
|
|
|
|
2019-11-30 14:14:02 +08:00
|
|
|
|
Private Shared Function ArgumentXmlDocs(args As Argument()) As String()
|
|
|
|
|
|
Dim out As New List(Of String)
|
|
|
|
|
|
Dim param$
|
2019-12-05 21:21:53 +08:00
|
|
|
|
Dim comments$
|
2019-11-30 14:14:02 +08:00
|
|
|
|
|
|
|
|
|
|
For Each arg As Argument In args
|
2019-12-05 21:21:53 +08:00
|
|
|
|
comments = XmlEntity.EscapingXmlEntity(arg.Description) _
|
|
|
|
|
|
.Replace("\n", vbCrLf) _
|
|
|
|
|
|
.LineTokens _
|
|
|
|
|
|
.Select(Function(l) "''' " & l) _
|
|
|
|
|
|
.JoinBy(vbCrLf) _
|
|
|
|
|
|
.Trim("'"c)
|
|
|
|
|
|
param = $"''' <param name=""{VisualBasic.normAsVisualBasicName(arg.Name)}"">{comments}
|
2019-11-30 14:14:02 +08:00
|
|
|
|
''' </param>"
|
|
|
|
|
|
out += param
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return out
|
|
|
|
|
|
End Function
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 在这个函数之中会生成函数的参数列表
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="API"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
Private Shared Function vbParameters(API As CommandLine) As String()
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim out As New List(Of String)
|
|
|
|
|
|
Dim param$
|
|
|
|
|
|
|
2019-08-03 21:28:16 +08:00
|
|
|
|
If API.arguments = 1 AndAlso API.arguments(Scan0).Name.StringEmpty Then
|
2019-06-23 15:54:28 +08:00
|
|
|
|
' /command <term>
|
|
|
|
|
|
out += $"term As String"
|
|
|
|
|
|
Else
|
|
|
|
|
|
For Each arg As NamedValue(Of String) In API.ParameterList
|
2019-08-31 11:42:06 +08:00
|
|
|
|
param = $"{VisualBasic.normAsVisualBasicName(arg.Name)} As String"
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-06-23 15:54:28 +08:00
|
|
|
|
If Not arg.Description.StringEmpty Then
|
|
|
|
|
|
' 可选参数
|
2019-08-31 11:42:06 +08:00
|
|
|
|
param = $"Optional {param} = ""{optionalDefaultValue(arg.Value)}"""
|
2019-06-23 15:54:28 +08:00
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
out += param
|
|
|
|
|
|
Next
|
|
|
|
|
|
End If
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
For Each bool In API.BoolFlags
|
2019-08-31 11:42:06 +08:00
|
|
|
|
out += $"Optional {VisualBasic.normAsVisualBasicName(bool)} As Boolean = False"
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
Return out
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 必须是以``default=``来作为前缀的,否则默认使用空字符串
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="value$"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
Private Shared Function optionalDefaultValue(value$) As String
|
2018-08-02 20:14:48 +08:00
|
|
|
|
If value.First = """"c AndAlso value.Last = """"c Then
|
|
|
|
|
|
' 如果是直接使用双引号包裹而不是使用<>尖括号进行包裹,则认为双引号所包裹的值都是默认值
|
|
|
|
|
|
value = value.GetStackValue(ASCII.Quot, ASCII.Quot)
|
|
|
|
|
|
ElseIf value.First = "<"c AndAlso value.Last = ">"c Then
|
|
|
|
|
|
' 而如果是使用尖括号的时候,则判断是否存在default=表达式,不存在则是空值
|
|
|
|
|
|
value = value.GetStackValue("<", ">")
|
|
|
|
|
|
|
|
|
|
|
|
If InStr(value, "default=") > 0 Then
|
|
|
|
|
|
value = Strings.Split(value, "default=").Last.Trim(""""c)
|
|
|
|
|
|
Else
|
2019-08-31 11:42:06 +08:00
|
|
|
|
' 没有表达式前缀,则使用默认的空字符串
|
|
|
|
|
|
value = ""
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 其他情况都认为是使用空值为默认值
|
|
|
|
|
|
value = ""
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
value = value.Replace(""""c, New String(ASCII.Quot, 2))
|
|
|
|
|
|
|
|
|
|
|
|
Return value
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
2019-06-23 15:54:28 +08:00
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 创建命令行调用字符串
|
|
|
|
|
|
''' </summary>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
''' <param name="api"></param>
|
2019-06-23 15:54:28 +08:00
|
|
|
|
''' <returns></returns>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
Private Shared Function createCliCalls(api As CommandLine) As String
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Dim CLI As New StringBuilder
|
|
|
|
|
|
Dim vbcode$
|
2019-08-31 11:42:06 +08:00
|
|
|
|
' 可能在参数中存在/@set环境参数的设置的调用
|
|
|
|
|
|
Dim envir As String = Nothing
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-31 11:42:06 +08:00
|
|
|
|
If api.arguments = 1 AndAlso api.arguments(Scan0).Name.StringEmpty Then
|
2019-06-23 15:54:28 +08:00
|
|
|
|
' /command <term>
|
|
|
|
|
|
vbcode = " Call CLI.Append($""{term}"")"
|
|
|
|
|
|
CLI.AppendLine(vbcode)
|
|
|
|
|
|
Else
|
2019-08-31 11:42:06 +08:00
|
|
|
|
For Each param As NamedValue(Of String) In api.ParameterList
|
|
|
|
|
|
Dim var$ = normAsVisualBasicName(param.Name)
|
|
|
|
|
|
|
|
|
|
|
|
If param.Name.TextEquals("/@set") Then
|
|
|
|
|
|
envir = param.Name
|
|
|
|
|
|
Continue For
|
|
|
|
|
|
End If
|
2019-06-23 15:54:28 +08:00
|
|
|
|
|
|
|
|
|
|
' 注意:在这句代码的最后有一个空格,是间隔参数所必需的,不可以删除
|
|
|
|
|
|
vbcode = $" Call CLI.Append(""{param.Name} "" & """""""" & {var} & """""" "")"
|
|
|
|
|
|
|
|
|
|
|
|
If param.Description.StringEmpty Then
|
|
|
|
|
|
' 必须参数不需要进一步判断,直接添加
|
|
|
|
|
|
Call CLI.AppendLine(vbcode)
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 可选参数还需要IF判断是否存在
|
|
|
|
|
|
Call CLI.AppendLine($" If Not {var}.{NameOf(StringEmpty)} Then")
|
|
|
|
|
|
Call CLI.AppendLine(" " & vbcode)
|
|
|
|
|
|
Call CLI.AppendLine(" End If")
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
End If
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
2019-08-31 11:42:06 +08:00
|
|
|
|
For Each b In api.BoolFlags
|
|
|
|
|
|
Dim var$ = normAsVisualBasicName(b)
|
2018-08-02 20:14:48 +08:00
|
|
|
|
|
|
|
|
|
|
Call CLI.AppendLine($" If {var} Then")
|
2019-08-31 11:42:06 +08:00
|
|
|
|
' 逻辑参数后面有一个空格,是正确的生成CLI所必需的
|
|
|
|
|
|
Call CLI.AppendLine($" Call CLI.Append(""{b} "")")
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Call CLI.AppendLine(" End If")
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
2019-08-31 11:42:06 +08:00
|
|
|
|
' 在最后将/@set环境参数组装起来
|
|
|
|
|
|
If Not envir.StringEmpty Then
|
|
|
|
|
|
envir = normAsVisualBasicName(envir)
|
|
|
|
|
|
|
|
|
|
|
|
Call CLI.AppendLine($" If Not {envir}.{NameOf(StringEmpty)} Then")
|
|
|
|
|
|
Call CLI.AppendLine($" Call CLI.Append($""/@set """"""""{Microsoft.VisualBasic.App.FlagInternalPipeline}=TRUE;'{{{envir}}}'"""""""" "")")
|
|
|
|
|
|
Call CLI.AppendLine("Else")
|
|
|
|
|
|
' 没有需要组装的,直接添加调用
|
|
|
|
|
|
Call CLI.AppendLine($" Call CLI.Append(""/@set {Microsoft.VisualBasic.App.FlagInternalPipeline}=TRUE "")")
|
|
|
|
|
|
Call CLI.AppendLine(" End If")
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 没有需要组装的,直接添加调用
|
|
|
|
|
|
Call CLI.AppendLine($" Call CLI.Append(""/@set {Microsoft.VisualBasic.App.FlagInternalPipeline}=TRUE "")")
|
|
|
|
|
|
End If
|
2019-06-23 15:54:28 +08:00
|
|
|
|
|
2018-08-02 20:14:48 +08:00
|
|
|
|
Return CLI.ToString
|
|
|
|
|
|
End Function
|
|
|
|
|
|
|
|
|
|
|
|
Const SyntaxError$ = "'<' or '>' is using for the IO redirect in your terminal, unavailable for your commandline argument name!"
|
|
|
|
|
|
|
|
|
|
|
|
''' <summary>
|
|
|
|
|
|
''' 将命令行参数的名称转义为VB之中有效的对象标识符
|
|
|
|
|
|
''' </summary>
|
|
|
|
|
|
''' <param name="arg$"></param>
|
|
|
|
|
|
''' <returns></returns>
|
2019-08-31 11:42:06 +08:00
|
|
|
|
Private Shared Function normAsVisualBasicName(arg$) As String
|
2018-08-02 20:14:48 +08:00
|
|
|
|
' 在命令行的参数名称前面一般都会有/-之类的控制符前缀,在这里去掉
|
|
|
|
|
|
Dim name$ = arg.Trim("/"c, "\"c, "-"c)
|
|
|
|
|
|
Dim s As Char() = name.ToArray
|
|
|
|
|
|
Dim upper As Char() = name.ToUpper.ToArray
|
|
|
|
|
|
Dim c As Char
|
|
|
|
|
|
|
|
|
|
|
|
If s.First = "<"c OrElse s.Last = ">"c Then
|
|
|
|
|
|
Throw New SyntaxErrorException(SyntaxError)
|
|
|
|
|
|
End If
|
|
|
|
|
|
|
|
|
|
|
|
For i As Integer = 0 To s.Length - 1
|
|
|
|
|
|
c = upper(i)
|
|
|
|
|
|
|
|
|
|
|
|
If (c >= "A"c AndAlso c <= "Z"c) OrElse (c >= "0"c AndAlso c <= "9"c) OrElse (c = "_") Then
|
|
|
|
|
|
' 合法的字符,不做处理
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 非法字符串都被替换为下划线
|
|
|
|
|
|
s(i) = "_"c
|
|
|
|
|
|
End If
|
|
|
|
|
|
Next
|
|
|
|
|
|
|
|
|
|
|
|
If s.First >= "0"c AndAlso s.First <= "9"c Then
|
|
|
|
|
|
Return "_" & New String(s)
|
|
|
|
|
|
Else
|
|
|
|
|
|
' 可能会存在in, byref, class这类的名字,需要在这里转义一下
|
2018-10-03 13:28:23 +08:00
|
|
|
|
Return KeywordProcessor.AutoEscapeVBKeyword(New String(s))
|
2018-08-02 20:14:48 +08:00
|
|
|
|
End If
|
|
|
|
|
|
End Function
|
|
|
|
|
|
End Class
|
|
|
|
|
|
End Namespace
|