Skip to content
This repository has been archived by the owner on Nov 3, 2023. It is now read-only.

Commit

Permalink
In vbnc/vbnc/source:
Browse files Browse the repository at this point in the history
2010-06-11  Rolf Bjarne Kvinge  <RKvinge@novell.com>

	* General/TypeResolution.vb: IsImplicitlyConvertible: two nullable types can
	convert between eachother if the nulled types are implicitly convertible.

	* General/TypeCache.vb:
	* General/TypeCache.Generated.vb: Regenerated.

	* General/TypeCache.in: Added Nullable.HasValue and Nullable.GetValueOrDefault.

	* General/Helper.vb: Add helper method to pretty-print types.

	* General/CecilHelper.vb: Add helper methods to check if a type is nullable
	and get the nulled type.

	* Expressions/Conversions/CTypeExpression.vb: Implement implicit conversion
	between nullable types.

In vbnc/vbnc/tests:
2010-06-11  Rolf Bjarne Kvinge  <RKvinge@novell.com>

	* tests.xml:
	* Errors/30512-4.vb:
	* Errors/30311-37.vb:
	* Errors/30311-36.vb:
	* CompileTime2/ImplicitNullableConversions1.vb:
	* CompileTime2/UserDefinedNullableConversions1.vb: Added new tests.

svn path=/trunk/mono-basic/; revision=158827
  • Loading branch information
rolfbjarne committed Jun 11, 2010
1 parent 2e3fde0 commit efa3380
Show file tree
Hide file tree
Showing 15 changed files with 319 additions and 3 deletions.
18 changes: 18 additions & 0 deletions vbnc/vbnc/source/ChangeLog
@@ -1,3 +1,21 @@
2010-06-11 Rolf Bjarne Kvinge <RKvinge@novell.com>

* General/TypeResolution.vb: IsImplicitlyConvertible: two nullable types can
convert between eachother if the nulled types are implicitly convertible.

* General/TypeCache.vb:
* General/TypeCache.Generated.vb: Regenerated.

* General/TypeCache.in: Added Nullable.HasValue and Nullable.GetValueOrDefault.

* General/Helper.vb: Add helper method to pretty-print types.

* General/CecilHelper.vb: Add helper methods to check if a type is nullable
and get the nulled type.

* Expressions/Conversions/CTypeExpression.vb: Implement implicit conversion
between nullable types.

2010-06-11 Rolf Bjarne Kvinge <RKvinge@novell.com>

* General/MethodBaseDeclaration.vb: Remove unused variable.
Expand Down
60 changes: 60 additions & 0 deletions vbnc/vbnc/source/Expressions/Conversions/CTypeExpression.vb 100644 → 100755
Expand Up @@ -245,6 +245,62 @@ Public Class CTypeExpression
Else
Throw New InternalException(Me)
End If
ElseIf CecilHelper.IsNullable(DestinationType) AndAlso CecilHelper.IsNullable(SourceType) Then
Dim nullable_src_type As GenericInstanceType
Dim nullable_dst_type As GenericInstanceType
Dim get_value As MethodReference
Dim has_value As MethodReference
Dim ctor As MethodReference
Dim localsrc, localdst As Mono.Cecil.Cil.VariableDefinition
Dim falseLabel As Label = Emitter.DefineLabel(Info)
Dim endLabel As Label = Emitter.DefineLabel(Info)
Dim vose As ValueOnStackExpression
Dim type_conversion As Expression

nullable_src_type = New GenericInstanceType(Helper.GetTypeOrTypeReference(Compiler, Compiler.TypeCache.System_Nullable1))
nullable_src_type.GenericArguments.Add(Helper.GetTypeOrTypeReference(Compiler, CecilHelper.GetNulledType(SourceType)))
has_value = New MethodReference("get_HasValue", nullable_src_type, Helper.GetTypeOrTypeReference(Compiler, Compiler.TypeCache.System_Boolean), True, False, MethodCallingConvention.Default)
get_value = New MethodReference("GetValueOrDefault", nullable_src_type, Compiler.TypeCache.System_Nullable1.GenericParameters(0), True, False, MethodCallingConvention.Default)

nullable_dst_type = New GenericInstanceType(Helper.GetTypeOrTypeReference(Compiler, Compiler.TypeCache.System_Nullable1))
nullable_dst_type.GenericArguments.Add(Helper.GetTypeOrTypeReference(Compiler, CecilHelper.GetNulledType(DestinationType)))
ctor = New MethodReference(".ctor", nullable_dst_type, Helper.GetTypeOrTypeReference(Compiler, Compiler.TypeCache.System_Void), True, False, MethodCallingConvention.Default)
ctor.Parameters.Add(New ParameterDefinition(Compiler.TypeCache.System_Nullable1.GenericParameters(0)))

'store in local
localsrc = Emitter.DeclareLocal(Info, SourceType)
Emitter.EmitStoreVariable(Info, localsrc)

'call Nullable`1.HasValue to check the condition
Emitter.EmitLoadVariableLocation(Info, localsrc)
Emitter.EmitCall(Info, has_value)
Emitter.EmitBranchIfFalse(Info, falseLabel)

localdst = Emitter.DeclareLocal(Info, DestinationType)

'true branch: we have a value, get it to create a new nullable with the right value
Emitter.EmitLoadVariableLocation(Info, localdst)
Emitter.EmitLoadVariableLocation(Info, localsrc)
Emitter.EmitCall(Info, get_value)

'convert value
vose = New ValueOnStackExpression(Me, CecilHelper.GetNulledType(SourceType))
type_conversion = Helper.CreateTypeConversion(Me, vose, CecilHelper.GetNulledType(DestinationType), result)
result = type_conversion.GenerateCode(Info) AndAlso result

Emitter.EmitCall(Info, ctor)
Emitter.EmitLoadVariable(Info, localdst)
Emitter.EmitBranch(Info, endLabel)

'false branch: no value
Emitter.MarkLabel(Info, falseLabel)
Emitter.EmitLoadVariableLocation(Info, localdst)
Emitter.EmitInitObj(Info, localdst.VariableType)
Emitter.EmitLoadVariable(Info, localdst)

'end
Emitter.MarkLabel(Info, endLabel)

ElseIf CecilHelper.IsValueType(SourceType) Then
'A value type value can be converted to one of its base reference types or an interface type that it implements through a process called boxing
If Helper.CompareType(DestinationType, Compiler.TypeCache.System_Object) Then
Expand Down Expand Up @@ -347,6 +403,10 @@ Public Class CTypeExpression
Else
m_IsStringToCharArray = True
End If
ElseIf CecilHelper.IsNullable(Me.ExpressionType) AndAlso CecilHelper.IsNullable(Me.Expression.ExpressionType) Then
If Not Compiler.TypeResolution.IsImplicitlyConvertible(Me, CecilHelper.GetNulledType(Me.Expression.ExpressionType), CecilHelper.GetNulledType(Me.ExpressionType)) Then
result = Compiler.Report.ShowMessage(Messages.VBNC30512, Me.Location, Helper.PrettyFormatType(Me.Expression.ExpressionType), Helper.PrettyFormatType(Me.ExpressionType)) AndAlso result
End If
End If
Case Else
Throw New InternalException(Me)
Expand Down
19 changes: 19 additions & 0 deletions vbnc/vbnc/source/General/CecilHelper.vb 100644 → 100755
Expand Up @@ -940,6 +940,25 @@ Public Class CecilHelper
Return Type.IsValueType
End Function

Public Shared Function IsNullable(ByVal Type As TypeReference) As Boolean
Dim git As GenericInstanceType

If Not Type.IsGenericInstance Then Return False

If Helper.CompareNameOrdinal(Type.Name, "Nullable`1") = False Then Return False

git = TryCast(Type, GenericInstanceType)
If git Is Nothing Then Return False

Return Helper.CompareType(Compiler.CurrentCompiler.TypeCache.System_Nullable1, git.ElementType)
End Function

Public Shared Function GetNulledType(ByVal Type As TypeReference) As TypeReference
'No checking done, caller must call IsNullable first
Dim git As GenericInstanceType = DirectCast(Type, GenericInstanceType)
Return git.GenericArguments()(0)
End Function

Public Shared Function IsByRef(ByVal Type As Mono.Cecil.TypeReference) As Boolean
Return TypeOf Type Is ByReferenceType
End Function
Expand Down
4 changes: 4 additions & 0 deletions vbnc/vbnc/source/General/Helper.vb
Expand Up @@ -2914,6 +2914,10 @@ Public Class Helper
Return result
End Function

Shared Function PrettyFormatType(ByVal type As TypeReference) As String
Return type.ToString()
End Function

Overloads Shared Function ToString(ByVal Types As Mono.Cecil.TypeReference()) As String
Dim result As String = ""
Dim sep As String = ""
Expand Down
6 changes: 5 additions & 1 deletion vbnc/vbnc/source/General/TypeCache.Generated.vb 100644 → 100755
@@ -1,6 +1,6 @@
'
' Visual Basic.Net Compiler
' Copyright (C) 2004 - 2007 Rolf Bjarne Kvinge, RKvinge@novell.com
' Copyright (C) 2004 - 2010 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
Expand Down Expand Up @@ -88,6 +88,8 @@ Public Partial Class CecilTypeCache
Public System_ParamArrayAttribute As Mono.Cecil.TypeDefinition
Public System_ParamArrayAttribute__ctor As Mono.Cecil.MethodDefinition
Public System_Nullable1 As Mono.Cecil.TypeDefinition
Public System_Nullable1__get_HasValue As Mono.Cecil.MethodDefinition
Public System_Nullable1__GetValueOrDefault As Mono.Cecil.MethodDefinition
Public System_Runtime_CompilerServices_RuntimeHelpers As Mono.Cecil.TypeDefinition
Public System_STAThreadAttribute As Mono.Cecil.TypeDefinition
Public System_STAThreadAttribute__ctor As Mono.Cecil.MethodDefinition
Expand Down Expand Up @@ -357,6 +359,8 @@ Public Partial Class CecilTypeCache
System_ParamArrayAttribute = [GetType](mscorlib, "System.ParamArrayAttribute")
System_ParamArrayAttribute__ctor = GetConstructor(System_ParamArrayAttribute)
System_Nullable1 = [GetType](mscorlib, "System.Nullable`1")
System_Nullable1__get_HasValue = GetMethod(System_Nullable1, "get_HasValue")
System_Nullable1__GetValueOrDefault = GetMethod(System_Nullable1, "GetValueOrDefault")
System_Runtime_CompilerServices_RuntimeHelpers = [GetType](mscorlib, "System.Runtime.CompilerServices.RuntimeHelpers")
System_STAThreadAttribute = [GetType](mscorlib, "System.STAThreadAttribute")
System_STAThreadAttribute__ctor = GetConstructor(System_STAThreadAttribute)
Expand Down
2 changes: 2 additions & 0 deletions vbnc/vbnc/source/General/TypeCache.in
Expand Up @@ -102,6 +102,8 @@ ctor System_Diagnostics_DebuggableAttribute System_Diagnostics_DebuggableAttribu
type mscorlib "System.ParamArrayAttribute"
ctor System_ParamArrayAttribute
type mscorlib "System.Nullable`1"
method System_Nullable1 "get_HasValue"
method System_Nullable1 "GetValueOrDefault"
type mscorlib "System.Runtime.CompilerServices.RuntimeHelpers"
type mscorlib "System.STAThreadAttribute"
ctor System_STAThreadAttribute
Expand Down
8 changes: 6 additions & 2 deletions vbnc/vbnc/source/General/TypeCache.vb 100644 → 100755
Expand Up @@ -425,7 +425,7 @@ End Class
' License along with this library; if not, write to the Free Software
' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
'
Partial Public Class CecilTypeCache
Public Partial Class CecilTypeCache
Public System_Boolean As Mono.Cecil.TypeDefinition
Public System_Boolean_Array As Mono.Cecil.TypeReference
Public System_Byte As Mono.Cecil.TypeDefinition
Expand Down Expand Up @@ -497,6 +497,8 @@ Partial Public Class CecilTypeCache
Public System_ParamArrayAttribute As Mono.Cecil.TypeDefinition
Public System_ParamArrayAttribute__ctor As Mono.Cecil.MethodDefinition
Public System_Nullable1 As Mono.Cecil.TypeDefinition
Public System_Nullable1__get_HasValue As Mono.Cecil.MethodDefinition
Public System_Nullable1__GetValueOrDefault As Mono.Cecil.MethodDefinition
Public System_Runtime_CompilerServices_RuntimeHelpers As Mono.Cecil.TypeDefinition
Public System_STAThreadAttribute As Mono.Cecil.TypeDefinition
Public System_STAThreadAttribute__ctor As Mono.Cecil.MethodDefinition
Expand Down Expand Up @@ -694,7 +696,7 @@ Partial Public Class CecilTypeCache
Public MS_VB_CS_Operators__CompareObjectLess_Object_Object_Boolean As Mono.Cecil.MethodDefinition
Public MS_VB_CS_Operators__CompareObjectLessEqual_Object_Object_Boolean As Mono.Cecil.MethodDefinition

Protected Overrides Sub InitInternal()
Protected Overrides Sub InitInternal ()
System_Boolean = [GetType](mscorlib, "System.Boolean")
System_Boolean_Array = GetArrayType(System_Boolean)
System_Byte = [GetType](mscorlib, "System.Byte")
Expand Down Expand Up @@ -766,6 +768,8 @@ Partial Public Class CecilTypeCache
System_ParamArrayAttribute = [GetType](mscorlib, "System.ParamArrayAttribute")
System_ParamArrayAttribute__ctor = GetConstructor(System_ParamArrayAttribute)
System_Nullable1 = [GetType](mscorlib, "System.Nullable`1")
System_Nullable1__get_HasValue = GetMethod(System_Nullable1, "get_HasValue")
System_Nullable1__GetValueOrDefault = GetMethod(System_Nullable1, "GetValueOrDefault")
System_Runtime_CompilerServices_RuntimeHelpers = [GetType](mscorlib, "System.Runtime.CompilerServices.RuntimeHelpers")
System_STAThreadAttribute = [GetType](mscorlib, "System.STAThreadAttribute")
System_STAThreadAttribute__ctor = GetConstructor(System_STAThreadAttribute)
Expand Down
4 changes: 4 additions & 0 deletions vbnc/vbnc/source/General/TypeResolution.vb 100644 → 100755
Expand Up @@ -428,6 +428,10 @@ Public Class TypeResolution
If Helper.CompareType(Compiler.TypeCache.Nothing, FromType) Then Return True
If CecilHelper.IsByRef(FromType) Then FromType = CecilHelper.GetElementType(FromType)
If CecilHelper.IsByRef(ToType) Then ToType = CecilHelper.GetElementType(ToType)
If CecilHelper.IsNullable(FromType) AndAlso CecilHelper.IsNullable(ToType) Then
FromType = CecilHelper.GetNulledType(FromType)
ToType = CecilHelper.GetNulledType(ToType)
End If
tpFrom = Helper.GetTypeCode(Compiler, FromType)
tpTo = Helper.GetTypeCode(Compiler, ToType)
If tpTo = TypeCode.Object Then
Expand Down
9 changes: 9 additions & 0 deletions vbnc/vbnc/tests/ChangeLog
@@ -1,3 +1,12 @@
2010-06-11 Rolf Bjarne Kvinge <RKvinge@novell.com>

* tests.xml:
* Errors/30512-4.vb:
* Errors/30311-37.vb:
* Errors/30311-36.vb:
* CompileTime2/ImplicitNullableConversions1.vb:
* CompileTime2/UserDefinedNullableConversions1.vb: Added new tests.

2010-06-11 Rolf Bjarne Kvinge <RKvinge@novell.com>

* tests.xml:
Expand Down
73 changes: 73 additions & 0 deletions vbnc/vbnc/tests/CompileTime2/ImplicitNullableConversions1.vb
@@ -0,0 +1,73 @@
Option Strict On
Class ImplicitNullableConversions1
Shared Function Main() As Integer
Dim b As Nullable(Of Byte)
Dim sb As Nullable(Of SByte)
Dim i16 As Nullable(Of Short)
Dim u16 As Nullable(Of UShort)
Dim i32 As Nullable(Of Integer)
Dim u32 As Nullable(Of UInteger)
Dim i64 As Nullable(Of Long)
Dim u64 As Nullable(Of ULong)
Dim s As Nullable(Of Single)
Dim f As Nullable(Of Double)
Dim d As Nullable(Of Decimal)
Dim dt As Nullable(Of Date)
Dim c As Nullable(Of Char)
Dim boo As Nullable(Of Boolean)

d = u64
d = u32
d = u16
d = b
d = i64
d = i32
d = i16
d = sb

f = d
f = s
f = u64
f = u32
f = u16
f = b
f = i64
f = i32
f = i16
f = sb

s = u64
s = u32
s = u16
s = b
s = i64
s = i32
s = i16
s = sb

u64 = u32
u64 = u16
u64 = b

u32 = u16
u32 = b

u16 = b

i64 = i32
i64 = i16
i64 = sb
i64 = u32
i64 = u16
i64 = b

i32 = i16
i32 = sb
i32 = u16
i32 = b

i16 = sb
i16 = b

End Function
End Class
25 changes: 25 additions & 0 deletions vbnc/vbnc/tests/CompileTime2/UserDefinedNullableConversions1.vb
@@ -0,0 +1,25 @@
Option Strict On
Class UserDefinedNullableConversions1
Shared Function Main() As Integer
Dim d As Nullable(Of Decimal)
Dim c As Nullable(Of Char)
Dim from As Nullable(Of From)
Dim [to] As Nullable(Of [To])

' vbc compiles char? -> decimal? using a user defined char->decimal widening operator on decimal
d = c
[to] = [from]
End Function

Structure From
Dim i As Integer
Public Shared Widening Operator CType(ByVal a As From) As [To]
Return New [To]
End Operator
End Structure

Structure [To]
Dim i As Integer
End Structure

End Class
10 changes: 10 additions & 0 deletions vbnc/vbnc/tests/Errors/30311-36.vb
@@ -0,0 +1,10 @@
Class ImplicitNullableConversions1
Shared Function Main() As Integer
Dim c As Nullable(Of Char)
Dim boo As Nullable(Of Boolean)

boo = c
End Function


End Class
9 changes: 9 additions & 0 deletions vbnc/vbnc/tests/Errors/30311-37.vb
@@ -0,0 +1,9 @@
Option Strict On
Class ImplicitNullableConversions1
Shared Function Main() As Integer
Dim f As Nullable(Of Double)
Dim c As Nullable(Of Char)
f = c
End Function

End Class

0 comments on commit efa3380

Please sign in to comment.