📄 methodresolver.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
'
''' <summary>
''' A helper class to do method resolution
''' </summary>
''' <remarks></remarks>
Public Class MethodResolver
Public Shared LOGMETHODRESOLUTION As Boolean = False
Private m_Parent As ParsedObject
Private m_Candidates As Generic.List(Of MemberCandidate)
Private m_InitialCandidates As MemberCandidate()
Private m_Name As String
Private m_Arguments As ArgumentList
Private m_TypeArguments As TypeArgumentList
Private m_Caller As TypeDeclaration
Private m_ArgumentsTypesAsString As String
Private m_ResolvedCandidate As MemberCandidate
Private m_ShowErrors As Boolean
Private m_Resolved As Boolean
Private m_IsLateBound As Boolean
ReadOnly Property IsLateBound() As Boolean
Get
Return m_IsLateBound
End Get
End Property
Property ShowErrors() As Boolean
Get
Return m_ShowErrors
End Get
Set(ByVal value As Boolean)
m_ShowErrors = value
End Set
End Property
ReadOnly Property Candidates() As Generic.List(Of MemberCandidate)
Get
Return m_Candidates
End Get
End Property
ReadOnly Property ArgumentsTypesAsString() As String
Get
If m_ArgumentsTypesAsString Is Nothing Then
m_ArgumentsTypesAsString = "(" & m_Arguments.AsString & ")"
End If
Return m_ArgumentsTypesAsString
End Get
End Property
ReadOnly Property Caller() As TypeDeclaration
Get
Return m_Caller
End Get
End Property
ReadOnly Property Parent() As ParsedObject
Get
Return m_Parent
End Get
End Property
ReadOnly Property MethodName() As String
Get
Return m_Name
End Get
End Property
ReadOnly Property MethodDeclaringType() As Type
Get
Return m_InitialCandidates(0).Member.DeclaringType
End Get
End Property
Sub Init(ByVal InitialGroup As Generic.List(Of MemberInfo), ByVal Arguments As ArgumentList, ByVal TypeArguments As TypeArgumentList)
m_Candidates = New Generic.List(Of MemberCandidate)(InitialGroup.Count)
For i As Integer = 0 To InitialGroup.Count - 1
Dim member As MemberInfo = InitialGroup(i)
m_Candidates.Add(New MemberCandidate(Me, member))
Next
m_InitialCandidates = m_Candidates.ToArray()
m_Arguments = Arguments
m_TypeArguments = TypeArguments
m_Caller = Parent.FindTypeParent()
m_Name = InitialGroup(0).Name
End Sub
Sub New(ByVal Parent As ParsedObject)
m_Parent = Parent
End Sub
ReadOnly Property Compiler() As Compiler
Get
Return m_Parent.Compiler
End Get
End Property
ReadOnly Property Arguments() As ArgumentList
Get
Return m_Arguments
End Get
End Property
ReadOnly Property TypeArguments() As TypeArgumentList
Get
Return m_TypeArguments
End Get
End Property
ReadOnly Property CandidatesLeft() As Integer
Get
Dim result As Integer
For Each member As MemberCandidate In m_Candidates
If member IsNot Nothing Then result += 1
Next
Return result
End Get
End Property
Public Function Resolve() As Boolean
Dim result As Boolean = True
If m_Resolved AndAlso ShowErrors = False Then Helper.StopIfDebugging()
Log("")
Log("Resolving method {0} with arguments {1}", ArgumentsTypesAsString)
result = ResolveInternal()
If result Then
Helper.Assert(CandidatesLeft = 1 OrElse IsLateBound)
If IsLateBound Then
m_ResolvedCandidate = Nothing
Else
For Each member As MemberCandidate In m_Candidates
If member IsNot Nothing Then
m_ResolvedCandidate = member
m_ResolvedCandidate.SelectOutputArguments()
Exit For
End If
Next
End If
End If
m_Resolved = True
Return result
End Function
Private Function ResolveInternal() As Boolean
Log("There are " & CandidatesLeft & " candidates left.")
m_IsLateBound = False
If ShowErrors AndAlso CandidatesLeft = 0 Then
Helper.AddError("No candidates: " & Parent.Location.ToString(Compiler))
End If
RemoveInaccessible()
Log("After removing inaccessible candidates, there are " & CandidatesLeft & " candidates left.")
If ShowErrors AndAlso CandidatesLeft = 0 Then
If m_InitialCandidates.Length = 1 Then
Return Compiler.Report.ShowMessage(Messages.VBNC30390, Parent.Location, m_InitialCandidates(0).Member.DeclaringType.Name, m_InitialCandidates(0).Member.Name, Helper.GetMethodAccessibilityString(Helper.GetMethodAttributes(m_InitialCandidates(0).Member)))
Else
Return Compiler.Report.ShowMessage(Messages.VBNC30517, Parent.Location, m_InitialCandidates(0).Member.Name)
End If
End If
ExpandParamArrays()
Log("After expanding paramarrays, there are " & CandidatesLeft & " candidates left.")
If ShowErrors AndAlso CandidatesLeft = 0 Then
Throw New InternalException("Expanding paramarrays resulted in fewer candidates: " & Parent.Location.ToString(Compiler))
End If
RemoveInapplicable()
Log("After removing inapplicable candidates, there are " & CandidatesLeft & " candidates left.")
If ShowErrors AndAlso CandidatesLeft = 0 Then
If m_InitialCandidates.Length = 1 Then
Return Compiler.Report.ShowMessage(Messages.VBNC30057, Parent.Location, m_InitialCandidates(0).ToString())
Else
Return Compiler.Report.ShowMessage(Messages.VBNC30516, Parent.Location, MethodName)
End If
End If
If CandidatesLeft <= 1 Then Return CandidatesLeft = 1
RemoveNarrowingExceptObject()
Log("After removing narrowing (except object) candidates, there are " & CandidatesLeft & " candidates left.")
If ShowErrors AndAlso CandidatesLeft = 0 Then
Helper.AddError("No non-narrowing (except object): " & Parent.Location.ToString(Compiler))
End If
If CandidatesLeft <= 1 Then Return CandidatesLeft = 1
RemoveNarrowing()
Log("After removing narrowing candidates, there are " & CandidatesLeft & " candidates left.")
If CandidatesLeft = 1 Then
Return True
ElseIf CandidatesLeft = 0 Then
If Caller.Location.File(Compiler).IsOptionStrictOn = False Then
m_IsLateBound = True
Return True
End If
End If
If ShowErrors AndAlso CandidatesLeft = 0 Then
Helper.AddError("No non-narrowing: " & Parent.Location.ToString(Compiler))
End If
SelectMostApplicable()
Log("After selecting the most applicable candidates, there are " & CandidatesLeft & " candidates left.")
If ShowErrors AndAlso CandidatesLeft = 0 Then
Helper.AddError("No most applicable: " & Parent.Location.ToString(Compiler))
End If
Return CandidatesLeft = 1
End Function
Sub RemoveInaccessible()
For i As Integer = 0 To m_Candidates.Count - 1
Dim candidate As MemberCandidate = m_Candidates(i)
If candidate Is Nothing Then Continue For
If candidate.IsAccessible = False Then
Log("NOT ACCESSIBLE: Method call to '{0}{1}' with arguments '{2}'", Helper.ToString(candidate.DefinedParametersTypes), ArgumentsTypesAsString)
m_Candidates(i) = Nothing
Else
Log("ACCESSIBLE : Method call to '{0}{1}' with arguments '{2}'", Helper.ToString(candidate.DefinedParametersTypes), ArgumentsTypesAsString)
End If
Next
End Sub
Sub ExpandParamArrays()
For i As Integer = 0 To m_Candidates.Count - 1
Dim candidate As MemberCandidate = m_Candidates(i)
If candidate Is Nothing Then Continue For
candidate.ExpandParamArray()
Next
End Sub
Sub RemoveInapplicable()
For i As Integer = 0 To m_Candidates.Count - 1
Dim candidate As MemberCandidate = m_Candidates(i)
If candidate Is Nothing Then Continue For
If candidate.IsApplicable = False Then
Log("NOT APPLICABLE: Method call to '{0}{1}' with arguments '{2}'", Helper.ToString(candidate.DefinedParametersTypes), ArgumentsTypesAsString)
m_Candidates(i) = Nothing
Else
Log("APPLICABLE : Method call to '{0}{1}' with arguments '{2}'", Helper.ToString(candidate.DefinedParametersTypes), ArgumentsTypesAsString)
End If
Next
End Sub
Sub RemoveNarrowingExceptObject()
For i As Integer = 0 To m_Candidates.Count - 1
Dim candidate As MemberCandidate = m_Candidates(i)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -