📄 ctypeexpression.vb
字号:
' ' Visual Basic.Net Compiler' Copyright (C) 2004 - 2007 Rolf Bjarne Kvinge, RKvinge@novell.com' ' This library is free software; you can redistribute it and/or' modify it under the terms of the GNU Lesser General Public' License as published by the Free Software Foundation; either' version 2.1 of the License, or (at your option) any later version.' ' This library 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' Lesser General Public License for more details.' ' You should have received a copy of the GNU Lesser General Public' License along with this library; if not, write to the Free Software' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA' Public Class CTypeExpression Inherits ConversionExpression Private m_DestinationType As TypeName Private m_ResolvedDestinationType As Type Private m_IsStringToCharArray As Boolean Public Overrides Function ResolveTypeReferences() As Boolean Dim result As Boolean = True If m_DestinationType IsNot Nothing Then result = m_DestinationType.ResolveTypeReferences AndAlso result m_ResolvedDestinationType = m_DestinationType.ResolvedType Helper.Assert(m_ResolvedDestinationType.IsByRef = False) End If result = MyBase.ResolveTypeReferences() AndAlso result Return result End Function Sub New(ByVal Parent As ParsedObject) MyBase.New(Parent) End Sub Sub New(ByVal Parent As ParsedObject, ByVal Expression As Expression, ByVal DestinationType As Type) MyBase.New(Parent, Expression) m_ResolvedDestinationType = DestinationType Helper.Assert(m_ResolvedDestinationType.IsByRef = False, "Can't create TypeConversion to byref type (trying to convert from " & Expression.ExpressionType.FullName & " to " & DestinationType.FullName) End Sub Shadows Sub Init(ByVal Expression As Expression, ByVal DestinationType As TypeName) MyBase.Init(Expression) m_DestinationType = DestinationType End Sub Shadows Sub Init(ByVal Expression As Expression, ByVal DestinationType As Type) MyBase.Init(Expression) m_ResolvedDestinationType = DestinationType End Sub Protected Overrides Function GenerateCodeInternal(ByVal Info As EmitInfo) As Boolean Dim result As Boolean = True Dim expType As Type = Me.ExpressionType Dim expTypeCode As TypeCode = Helper.GetTypeCode(Compiler, expType) Select Case expTypeCode Case TypeCode.Boolean CBoolExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Byte CByteExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Char CCharExpression.GenerateCode(Me.Expression, Info) Case TypeCode.DateTime CDateExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Decimal CDecExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Double CDblExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Int16 CShortExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Int32 CIntExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Int64 CLngExpression.GenerateCode(Me.Expression, Info) Case TypeCode.SByte CSByteExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Single CSngExpression.GenerateCode(Me.Expression, Info) Case TypeCode.String CStrExpression.GenerateCode(Me.Expression, Info) Case TypeCode.UInt16 CUShortExpression.GenerateCode(Me.Expression, Info) Case TypeCode.UInt32 CUIntExpression.GenerateCode(Me.Expression, Info) Case TypeCode.UInt64 CULngExpression.GenerateCode(Me.Expression, Info) Case TypeCode.Object If Helper.CompareType(expType, Compiler.TypeCache.System_Object) Then CObjExpression.GenerateCode(Me.Expression, Info) Else result = GenerateCTypeCode(Info, expType, Me.Expression.ExpressionType) End If Case Else Throw New InternalException(Me) End Select Return result End Function Public Shared Function GenerateUserDefinedConversionCode(ByVal Info As EmitInfo, ByVal Expression As Expression, ByVal DestinationType As Type) As Boolean Dim result As Boolean = True Dim exptype As Type = Expression.ExpressionType Dim ops As Generic.List(Of MethodInfo) ops = Helper.GetWideningConversionOperators(Info.Compiler, exptype, DestinationType) If ops.Count = 0 Then ops = Helper.GetNarrowingConversionOperators(Info.Compiler, exptype, DestinationType) Helper.AddWarning("narrowing operator") End If If ops.Count = 0 Then Helper.AddError("Cannot convert from '" & exptype.Name & "' to '" & DestinationType.Name & "'") result = False ElseIf ops.Count > 1 Then Helper.AddError("Cannot convert from '" & exptype.Name & "' to '" & DestinationType.Name & "'") result = False Else Emitter.EmitCall(Info, ops(0)) End If Return result End Function Private Function EmitStringToCharArray(ByVal Info As EmitInfo) As Boolean Dim result As Boolean = True result = Expression.GenerateCode(Info.Clone(Compiler.TypeCache.System_String)) AndAlso result Emitter.EmitCall(Info, Info.Compiler.TypeCache.MS_VB_CS_Conversions__ToCharArrayRankOne_String) Return result End Function Private Function GenerateCTypeCode(ByVal Info As EmitInfo, ByVal DestinationType As Type, ByVal SourceType As Type) As Boolean Dim result As Boolean = True If m_IsStringToCharArray Then Return EmitStringToCharArray(Info) AndAlso result End If result = Expression.Classification.GenerateCode(Info.Clone(DestinationType)) AndAlso result If Helper.CompareType(Compiler.TypeCache.Nothing, SourceType) Then 'There is nothing to do here ElseIf SourceType.IsGenericParameter Then If DestinationType.IsGenericParameter Then Helper.NotImplemented() ElseIf DestinationType.IsArray Then Helper.NotImplemented() ElseIf DestinationType.IsClass Then DestinationType = Helper.GetTypeOrTypeBuilder(DestinationType) If Helper.IsTypeConvertibleToAny(Helper.GetGenericParameterConstraints(SourceType), DestinationType) Then 'Emitter.EmitUnbox_Any(Info, DestinationType) Emitter.EmitBox(Info, SourceType) Emitter.EmitCastClass(Info, SourceType, DestinationType) Else Helper.AddError() End If ElseIf DestinationType.IsValueType Then Helper.NotImplemented() ElseIf DestinationType.IsInterface Then Emitter.EmitBox(Info, SourceType) Emitter.EmitCastClass(Info, SourceType, DestinationType) Else Throw New InternalException(Me) End If ElseIf SourceType.IsArray Then If DestinationType.IsInterface Then If Helper.DoesTypeImplementInterface(Compiler, SourceType, DestinationType) Then Emitter.EmitCastClass(Info, SourceType, DestinationType) Else Info.Compiler.Report.ShowMessage(Messages.VBNC30311, SourceType.Name, DestinationType.Name) result = False End If ElseIf Helper.CompareType(DestinationType, Compiler.TypeCache.System_Array) Then Emitter.EmitCastClass(Info, SourceType, DestinationType) ElseIf DestinationType.IsArray = False Then Info.Compiler.Report.ShowMessage(Messages.VBNC30311, SourceType.Name, DestinationType.Name) result = False ElseIf SourceType.GetArrayRank <> DestinationType.GetArrayRank Then Info.Compiler.Report.ShowMessage(Messages.VBNC30311, SourceType.Name, DestinationType.Name) result = False Else Dim SourceElementType As Type = SourceType.GetElementType Dim DestinationElementType As Type = DestinationType.GetElementType 'For any two reference types A and B, if A is a derived type of B or implements B, 'a conversion exists from an array of type A to a compatible array of type B. 'A compatible array is an array of the same rank and type. 'This relationship is known as array covariance. 'Array covariance in particular means that an element of an array whose element type is B 'may actually be an element of an array whose element type is A, 'provided that both A and B are reference types and that B is a base type of A or is implemented by A.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -