1 #Region "Microsoft.VisualBasic::062abf9170cbd65288b462d737aac04f, Microsoft.VisualBasic.Core\Extensions\CodeDOM\CodeDOMExpressions.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 CodeDOMExpressions
35     
36     '         Properties: EntryPoint
37     
38     '         Function: (+4 Overloads) [Call], [CType], [GetType], (+4 Overloads) [New], (+2 Overloads) [Return]
39     '                   (+2 Overloads) Argument, Comments, DeclareFunc, (+2 Overloads) Field, FieldRef
40     '                   GetValue, (+3 Overloads) LocalsInit, LocalVariable, (+2 Overloads) Reference, Type
41     '                   TypeRef, Value, ValueAssign
42     
43     
44     ' /********************************************************************************/
45
46 #End Region
47
48 Imports System.CodeDom
49 Imports System.Reflection
50 Imports System.Runtime.CompilerServices
51 Imports Microsoft.VisualBasic.Language
52
53 Namespace Emit.CodeDOM_VBC
54
55     Public Module CodeDOMExpressions
56
57         ''' <summary>
58         ''' Public Shared Function Main(Argvs As String()) As Integer
59         ''' </summary>
60         ''' <returns></returns>
61         Public ReadOnly Property EntryPoint As CodeDom.CodeMemberMethod
62             Get
63                 Dim Func As New CodeMemberMethod With {
64                     .Name = "Main",
65                     .ReturnType = Type(Of Integer)(),
66                     .Attributes = MemberAttributes.Public Or MemberAttributes.Static
67                 }
68
69                 Func.Parameters.Add(Argument(Of String())("Argvs"))
70
71                 Return Func
72             End Get
73         End Property
74
75         ''' <summary>
76         ''' ```
77         ''' Public Shared Function xxx() As T
78         ''' Public Shared Property XXX As T
79         ''' ```
80         ''' 
81         ''' Or declare a method in a standard Module type.
82         ''' </summary>
83         Public Const PublicShared As MemberAttributes =
84             CodeDom.MemberAttributes.Public Or
85             CodeDom.MemberAttributes.Static
86
87         ''' <summary>
88         ''' 声明一个函数
89         ''' </summary>
90         ''' <param name="name"></param>
91         ''' <param name="args"></param>
92         ''' <param name="returns"></param>
93         ''' <param name="control"></param>
94         ''' <returns></returns>
95         Public Function DeclareFunc(name As String,
96                                     args As Dictionary(Of String, Type),
97                                     returns As Type,
98                                     Optional control As CodeDom.MemberAttributes = PublicShared) As CodeDom.CodeMemberMethod
99
100             Dim Func As New CodeDom.CodeMemberMethod With {
101                 .Name = name,
102                 .ReturnType = returns.TypeRef,
103                 .Attributes = control
104             }
105
106             If Not args.IsNullOrEmpty Then
107                 For Each x In args
108                     Call Func.Parameters.Add(Argument(x.Key, x.Value))
109                 Next
110             End If
111
112             Return Func
113         End Function
114
115         ''' <summary>
116         ''' ```
117         ''' Dim Name As &lt;Type>
118         ''' ```
119         ''' 
120         ''' Declare a field in the type
121         ''' </summary>
122         ''' <param name="Name"></param>
123         ''' <param name="Type"></param>
124         ''' <returns></returns>
125         Public Function Field(Name As String, Type As Type) As CodeDom.CodeMemberField
126             Return New CodeDom.CodeMemberField(name:=Name, type:=New CodeDom.CodeTypeReference(Type))
127         End Function
128
129         ''' <summary>
130         ''' Reference of ``Me.Field``
131         ''' </summary>
132         ''' <param name="Name"></param>
133         ''' <returns></returns>
134         Public Function FieldRef(Name As StringAs CodeDom.CodeFieldReferenceExpression
135             Return New CodeDom.CodeFieldReferenceExpression(New CodeDom.CodeThisReferenceExpression, Name)
136         End Function
137
138         Public Function Field(Name As String, type As StringAs CodeDom.CodeFieldReferenceExpression
139             Return New CodeDom.CodeFieldReferenceExpression(New CodeDom.CodeTypeReferenceExpression(type), Name)
140         End Function
141
142         Public Function Comments(text As StringAs CodeDom.CodeCommentStatement
143             Return New CodeDom.CodeCommentStatement(text)
144         End Function
145
146         ''' <summary>
147         ''' Class object instance constructor
148         ''' </summary>
149         ''' <param name="Type"></param>
150         ''' <param name="parameters"></param>
151         ''' <returns></returns>
152         Public Function [New](Type As Type, parameters As CodeDom.CodeExpression()) As CodeDom.CodeObjectCreateExpression
153             Return New CodeDom.CodeObjectCreateExpression(New CodeDom.CodeTypeReference(Type), parameters)
154         End Function
155
156         Public Function [New](type As StringAs CodeDom.CodeObjectCreateExpression
157             Dim typeRef As New CodeDom.CodeTypeReference(type)
158             Return New CodeDom.CodeObjectCreateExpression(typeRef, {})
159         End Function
160
161         ''' <summary>
162         ''' Class object instance constructor.
163         ''' </summary>
164         ''' <typeparam name="T"></typeparam>
165         ''' <param name="parameters"></param>
166         ''' <returns></returns>
167         Public Function [New](Of T As Class)(parameters As Object()) As CodeDom.CodeObjectCreateExpression
168             If parameters.IsNullOrEmpty Then
169                 Return [New](GetType(T), {})
170             Else
171                 Dim args As CodePrimitiveExpression() = LinqAPI.Exec(Of CodePrimitiveExpression) <=
172                     From obj As Object
173                     In parameters
174                     Select New CodePrimitiveExpression(obj)
175
176                 Return [New](GetType(T), args)
177             End If
178         End Function
179
180         ''' <summary>
181         ''' New object
182         ''' </summary>
183         ''' <param name="typeRef"></param>
184         ''' <param name="parameters"></param>
185         ''' <returns></returns>
186         Public Function [New](typeRef As String, parameters As CodeDom.CodeExpression()) As CodeDom.CodeObjectCreateExpression
187             Dim objectType As New CodeDom.CodeTypeReference(typeRef)
188             If parameters Is Nothing Then
189                 parameters = New CodeDom.CodeExpression() {}
190             End If
191
192             Return New CodeDom.CodeObjectCreateExpression(objectType, parameters)
193         End Function
194
195         ''' <summary>
196         ''' 声明一个局部变量
197         ''' </summary>
198         ''' <param name="Name"></param>
199         ''' <param name="Type"></param>
200         ''' <param name="initExpression"></param>
201         ''' <returns></returns>
202         Public Function LocalsInit(Name As String, Type As System.Type, Optional initExpression As CodeDom.CodeExpression = NothingAs CodeDom.CodeVariableDeclarationStatement
203             Dim expr As New CodeDom.CodeVariableDeclarationStatement(New CodeDom.CodeTypeReference(Type), Name)
204             If Not initExpression Is Nothing Then
205                 expr.InitExpression = initExpression
206             End If
207             Return expr
208         End Function
209
210         Public Function LocalsInit(Name As String, Type As StringOptional initExpression As CodeDom.CodeExpression = NothingAs CodeDom.CodeVariableDeclarationStatement
211             Dim typeRef As New CodeDom.CodeTypeReference(Type)
212             Dim Expr = New CodeDom.CodeVariableDeclarationStatement(typeRef, Name)
213             If Not initExpression Is Nothing Then
214                 Expr.InitExpression = initExpression
215             End If
216             Return Expr
217         End Function
218
219         ''' <summary>
220         ''' Declare a local variable.
221         ''' </summary>
222         ''' <param name="Name"></param>
223         ''' <param name="Type"></param>
224         ''' <param name="init"></param>
225         ''' <returns></returns>
226         Public Function LocalsInit(Name As String, Type As System.Type, Optional init As Object = NothingAs CodeDom.CodeVariableDeclarationStatement
227             If Not init Is Nothing Then
228                 Return LocalsInit(Name, Type, New CodeDom.CodePrimitiveExpression(init))
229             Else
230                 Return LocalsInit(Name, Type, initExpression:=Nothing)
231             End If
232         End Function
233
234         ''' <summary>
235         ''' Ctype
236         ''' </summary>
237         ''' <param name="obj"></param>
238         ''' <param name="type"></param>
239         ''' <returns></returns>
240         ''' 
241         <Extension>
242         Public Function [CType](obj As CodeDom.CodeExpression, type As Type) As CodeDom.CodeCastExpression
243             Return New CodeDom.CodeCastExpression(New CodeDom.CodeTypeReference(type), obj)
244         End Function
245
246         ''' <summary>
247         ''' Call method
248         ''' </summary>
249         ''' <param name="Method"></param>
250         ''' <param name="Parameters"></param>
251         ''' <param name="obj"></param>
252         ''' <returns></returns>
253         <Extension>
254         Public Function [Call](Method As MethodInfo,
255                                Parameters As CodeDom.CodeExpression(),
256                                Optional obj As CodeDom.CodeExpression = NothingAs CodeDom.CodeMethodInvokeExpression
257             Return [Call](If(obj Is NothingNew CodeDom.CodeTypeReferenceExpression(Method.DeclaringType), obj), Method.Name, Parameters)
258         End Function
259
260         ''' <summary>
261         ''' Call object by method name
262         ''' </summary>
263         ''' <param name="obj"></param>
264         ''' <param name="Name"></param>
265         ''' <param name="Parameters"></param>
266         ''' <returns></returns>
267         Public Function [Call](obj As CodeDom.CodeExpression, Name As String, Parameters As CodeDom.CodeExpression()) As CodeDom.CodeMethodInvokeExpression
268             Dim MethodRef As New CodeDom.CodeMethodReferenceExpression(obj, Name)
269             Dim Expression As New CodeDom.CodeMethodInvokeExpression(MethodRef, Parameters)
270             Return Expression
271         End Function
272
273         Public Function [Call](type As Type, Name As String, Parameters As CodeDom.CodeExpression()) As CodeDom.CodeMethodInvokeExpression
274             Return [Call](New CodeDom.CodeTypeReferenceExpression(type), Name, Parameters)
275         End Function
276
277         ''' <summary>
278         ''' Call a statics function from a specific type with a known function name
279         ''' </summary>
280         ''' <param name="type"></param>
281         ''' <param name="Name"></param>
282         ''' <param name="parametersValue"></param>
283         ''' <returns></returns>
284         Public Function [Call](type As Type, Name As String, parametersValue As Object()) As CodeDom.CodeMethodInvokeExpression
285             If parametersValue.IsNullOrEmpty Then
286                 Return [Call](type, Name, Parameters:={})
287             Else
288                 Return [Call](type, Name, (From obj In parametersValue Select New CodeDom.CodePrimitiveExpression(obj)).ToArray)
289             End If
290         End Function
291
292         ''' <summary>
293         ''' Function returns
294         ''' </summary>
295         ''' <param name="variable"></param>
296         ''' <returns></returns>
297         Public Function [Return](variable As StringAs CodeDom.CodeMethodReturnStatement
298             Return New CodeDom.CodeMethodReturnStatement(New CodeDom.CodeVariableReferenceExpression(variable))
299         End Function
300
301         ''' <summary>
302         ''' Returns value in a function body
303         ''' </summary>
304         ''' <param name="expression"></param>
305         ''' <returns></returns>
306         Public Function [Return](expression As CodeDom.CodeExpression) As CodeDom.CodeMethodReturnStatement
307             Return New CodeDom.CodeMethodReturnStatement(expression)
308         End Function
309
310         ''' <summary>
311         ''' Reference to a statics field in the specific target type
312         ''' </summary>
313         ''' <param name="obj"></param>
314         ''' <param name="Name"></param>
315         ''' <returns></returns>
316         Public Function Reference(obj As Type, Name As StringAs CodeDom.CodeFieldReferenceExpression
317             Return New CodeDom.CodeFieldReferenceExpression(New CodeDom.CodeTypeReferenceExpression(obj), Name)
318         End Function
319
320         ''' <summary>
321         ''' Reference to a instance field in the specific object instance. 
322         ''' </summary>
323         ''' <param name="obj"></param>
324         ''' <param name="Name"></param>
325         ''' <returns></returns>
326         Public Function Reference(obj As CodeDom.CodeExpression, Name As StringAs CodeDom.CodeFieldReferenceExpression
327             Return New CodeDom.CodeFieldReferenceExpression(obj, Name)
328         End Function
329
330         ''' <summary>
331         ''' ``left = value``
332         ''' </summary>
333         ''' <param name="LeftAssigned"></param>
334         ''' <param name="value"></param>
335         ''' <returns></returns>
336         Public Function ValueAssign(LeftAssigned As CodeDom.CodeExpression, value As CodeDom.CodeExpression) As CodeDom.CodeAssignStatement
337             Return New CodeDom.CodeAssignStatement(LeftAssigned, value)
338         End Function
339
340         ''' <summary>
341         ''' Variable value initializer
342         ''' </summary>
343         ''' <param name="obj"></param>
344         ''' <returns></returns>
345         Public Function Value(obj As ObjectAs CodeDom.CodePrimitiveExpression
346             Return New CodeDom.CodePrimitiveExpression(obj)
347         End Function
348
349         ''' <summary>
350         ''' Reference to a local variable in a function body.(引用局部变量)
351         ''' </summary>
352         ''' <param name="Name"></param>
353         ''' <returns></returns>
354         Public Function LocalVariable(Name As StringAs CodeDom.CodeVariableReferenceExpression
355             Return New CodeDom.CodeVariableReferenceExpression(Name)
356         End Function
357
358         ''' <summary>
359         ''' Gets the element value in a array object.
360         ''' </summary>
361         ''' <param name="Array"></param>
362         ''' <param name="index"></param>
363         ''' <returns></returns>
364         Public Function GetValue(Array As CodeDom.CodeExpression, index As IntegerAs CodeDom.CodeArrayIndexerExpression
365             Dim idx = New CodeDom.CodePrimitiveExpression(index)
366             Return New CodeDom.CodeArrayIndexerExpression(Array, idx)
367         End Function
368
369         Public Function Type(Of T)() As CodeDom.CodeTypeReference
370             Dim refType As Type = GetType(T)
371             Return New CodeDom.CodeTypeReference(refType)
372         End Function
373
374         <Extension> Public Function TypeRef(type As Type) As CodeDom.CodeTypeReference
375             Return New CodeDom.CodeTypeReference(type)
376         End Function
377
378         ''' <summary>
379         ''' System.Type.GetType(TypeName)
380         ''' </summary>
381         ''' <param name="Type"></param>
382         ''' <returns></returns>
383         Public Function [GetType](Type As Type) As CodeDom.CodeMethodInvokeExpression
384             Return [Call](GetType(System.Type), NameOf(System.Type.GetType), parametersValue:={Type.FullName, TrueFalse})
385         End Function
386
387         Public Function Argument(Name As String, Type As Type) As CodeDom.CodeParameterDeclarationExpression
388             Return New CodeDom.CodeParameterDeclarationExpression(New CodeDom.CodeTypeReference(Type), Name)
389         End Function
390
391         Public Function Argument(Of T)(Name As StringAs CodeDom.CodeParameterDeclarationExpression
392             Return Argument(Name, GetType(T))
393         End Function
394
395     End Module
396 End Namespace