1'
2' Visual Basic.Net Compiler
3' Copyright (C) 2004 - 2010 Rolf Bjarne Kvinge, RKvinge@novell.com
4'
5' This library is free software; you can redistribute it and/or
6' modify it under the terms of the GNU Lesser General Public
7' License as published by the Free Software Foundation; either
8' version 2.1 of the License, or (at your option) any later version.
9'
10' This library is distributed in the hope that it will be useful,
11' but WITHOUT ANY WARRANTY; without even the implied warranty of
12' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13' Lesser General Public License for more details.
14'
15' You should have received a copy of the GNU Lesser General Public
16' License along with this library; if not, write to the Free Software
17' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18'
19
20''' <summary>
21''' Represents the location of a method. A method pointer may have
22''' an associated instance expression and an associated type argument list.
23'''
24''' Can be reclassified as a value. This reclassification can only occur in
25''' assignment stastements or as a part of interpreting a parameter list,
26''' where the target type is known. The method pointer expression is interpreted
27''' as the argument to a delegate instantiation expression of the appropiate type
28''' with the associated type argument list.
29''' </summary>
30''' <remarks></remarks>
31Public Class MethodPointerClassification
32    Inherits ExpressionClassification
33
34    Private m_TypeArguments As TypeArgumentList
35
36    Private m_MethodGroup As MethodGroupClassification
37
38    Private m_ResolvedMethod As Mono.Cecil.MethodReference
39    Private m_DelegateType As Mono.Cecil.TypeReference
40
41    Private m_Resolved As Boolean
42
43    ReadOnly Property Resolved() As Boolean
44        Get
45            Return m_Resolved
46        End Get
47    End Property
48
49    ''' <summary>
50    ''' Loads the method pointer onto the evalation stack.
51    ''' Creates a new delegate of the specified type.
52    ''' </summary>
53    ''' <param name="Info"></param>
54    ''' <returns></returns>
55    ''' <remarks></remarks>
56    Friend Overrides Function GenerateCode(ByVal Info As EmitInfo) As Boolean
57        Dim result As Boolean = True
58
59        Helper.Assert(m_ResolvedMethod IsNot Nothing)
60        Helper.Assert(m_DelegateType IsNot Nothing)
61
62        If m_MethodGroup.InstanceExpression IsNot Nothing AndAlso CecilHelper.IsStatic(m_ResolvedMethod) = False Then
63            result = m_MethodGroup.InstanceExpression.GenerateCode(Info.Clone(Parent, True, False, m_MethodGroup.InstanceExpression.ExpressionType)) AndAlso result
64            Emitter.EmitDup(Info)
65        Else
66            Emitter.EmitLoadNull(Info.Clone(Parent, True, False, Compiler.TypeCache.System_Object))
67        End If
68
69        Emitter.EmitLoadVftn(Info, m_ResolvedMethod)
70
71        Dim ctor As Mono.Cecil.MethodReference
72        Dim dT As Mono.Cecil.TypeDefinition = CecilHelper.FindDefinition(m_DelegateType)
73        ctor = CecilHelper.FindConstructor(dT.Methods, False, New Mono.Cecil.TypeReference() {Compiler.TypeCache.System_Object, Compiler.TypeCache.System_IntPtr})
74        ctor = CecilHelper.GetCorrectMember(ctor, m_DelegateType)
75        Emitter.EmitNew(Info, ctor)
76
77        Return result
78    End Function
79
80    ''' <summary>
81    '''
82    ''' </summary>
83    ''' <returns></returns>
84    ''' <remarks></remarks>
85    Function Resolve(ByVal DelegateType As Mono.Cecil.TypeReference, ByVal ShowErrors As Boolean) As Boolean
86        Dim result As Boolean = True
87
88        Helper.Assert(DelegateType IsNot Nothing)
89
90        If Helper.CompareType(DelegateType, Compiler.TypeCache.DelegateUnresolvedType) Then
91            m_DelegateType = DelegateType
92            Return True
93        End If
94
95        If Helper.IsDelegate(Compiler, DelegateType) = False Then
96            If ShowErrors Then
97                Compiler.Report.ShowMessage(Messages.VBNC30581, Me.Parent.Location, DelegateType.FullName)
98            End If
99            Return False
100        End If
101
102        Dim params As Mono.Collections.Generic.Collection(Of ParameterDefinition) = Helper.GetDelegateArguments(Compiler, DelegateType)
103        Dim paramtypes() As Mono.Cecil.TypeReference = Helper.GetParameterTypes(params)
104
105        m_ResolvedMethod = CType(Helper.ResolveGroupExact(Me.Parent, m_MethodGroup.Group, paramtypes), Mono.Cecil.MethodReference)
106        m_DelegateType = DelegateType
107
108        If m_ResolvedMethod Is Nothing Then
109            If ShowErrors Then
110                For i As Integer = 0 To m_MethodGroup.Group.Count - 1
111                    Compiler.Report.ShowMessage(Messages.VBNC30408, Me.Parent.Location, Helper.ToString(Me.Parent, m_MethodGroup.Group(i)), Helper.ToString(Me.Parent, DelegateType))
112                Next
113            End If
114            result = False
115        Else
116            If m_MethodGroup.InstanceExpression Is Nothing AndAlso CecilHelper.IsStatic(m_ResolvedMethod) = False Then
117                If ShowErrors Then
118                    Compiler.Report.ShowMessage(Messages.VBNC30469, Parent.Location)
119                End If
120                Return False
121            End If
122        End If
123
124        m_Resolved = True
125
126        Return result
127    End Function
128
129    ReadOnly Property DelegateType() As Mono.Cecil.TypeReference
130        Get
131            Return m_DelegateType
132        End Get
133    End Property
134
135    ReadOnly Property MethodGroup() As MethodGroupClassification
136        Get
137            Return m_MethodGroup
138        End Get
139    End Property
140
141    ReadOnly Property Type() As Mono.Cecil.TypeReference
142        Get
143            Return Compiler.TypeCache.System_IntPtr
144        End Get
145    End Property
146
147    ReadOnly Property InstanceExpression() As Expression
148        Get
149            Return m_MethodGroup.InstanceExpression
150        End Get
151    End Property
152
153    ReadOnly Property Method() As Mono.Cecil.MethodReference
154        Get
155            Return DirectCast(m_ResolvedMethod, Mono.Cecil.MethodReference)
156        End Get
157    End Property
158
159    Sub New(ByVal Parent As AddressOfExpression, ByVal MethodGroup As MethodGroupClassification)
160        MyBase.new(Classifications.MethodPointer, Parent)
161        Helper.Assert(MethodGroup IsNot Nothing)
162        m_MethodGroup = MethodGroup
163    End Sub
164End Class
165
166