📄 methodresolver.vb
字号:
ReadOnly Property ParamArrayParameter() As ParameterInfo
Get
If m_IsParamArray = False Then Return Nothing
Return m_DefinedParameters(m_DefinedParameters.Length - 1)
End Get
End Property
Sub ExpandParamArray()
If DefinedParameters.Length = 0 Then Return
If Helper.IsParamArrayParameter(Compiler, DefinedParameters(DefinedParameters.Length - 1)) = False Then Return
Dim candidate As New MemberCandidate(Resolver, m_Member)
candidate.m_IsParamArray = True
Resolver.Candidates.Add(candidate)
End Sub
Function DefineApplicability() As Boolean
Dim matchedParameters As Generic.List(Of ParameterInfo)
Dim exactArguments As Generic.List(Of Argument)
Dim method As MethodBase = TryCast(Member, MethodBase)
Dim prop As PropertyInfo = TryCast(Member, PropertyInfo)
Dim isLastParamArray As Boolean
Dim paramArrayExpression As ArrayCreationExpression = Nothing
Dim inputParametersCount As Integer = InputParameters.Length
isLastParamArray = m_IsParamArray
'(if there are more arguments than parameters and the last parameter is not a
'paramarray parameter the method should not be applicable)
If Arguments.Count > InputParameters.Length Then
If InputParameters.Length < 1 Then
'LogResolutionMessage(Parent.Compiler, "N/A: 1")
Return False
End If
If isLastParamArray = False Then
'LogResolutionMessage(Parent.Compiler, "N/A: 2")
Return False
End If
End If
matchedParameters = New Generic.List(Of ParameterInfo)
exactArguments = New Generic.List(Of Argument)(Helper.CreateArray(Of Argument)(Nothing, inputParametersCount))
ReDim m_TypesInInvokedOrder(Math.Max(Arguments.Count - 1, inputParametersCount - 1))
If isLastParamArray Then
Dim paramArrayArg As New PositionalArgument(Parent)
Helper.Assert(paramArrayExpression Is Nothing)
paramArrayExpression = New ArrayCreationExpression(paramArrayArg)
paramArrayExpression.Init(ParamArrayParameter.ParameterType, New Expression() {})
paramArrayArg.Init(ParamArrayParameter.Position, paramArrayExpression)
exactArguments(inputParametersCount - 1) = paramArrayArg
m_TypesInInvokedOrder(inputParametersCount - 1) = ParamArrayParameter.ParameterType
End If
Dim firstNamedArgument As Integer = Arguments.Count + 1
For i As Integer = 0 To Arguments.Count - 1
'First, match each positional argument in order to the list of method parameters.
'If there are more positional arguments than parameters and the last parameter
'is not a paramarray, the method is not applicable. Otherwise, the paramarray parameter
'is expanded with parameters of the paramarray element type to match the number
'of positional arguments. If a positional argument is omitted, the method is not applicable.
If Arguments(i).IsNamedArgument Then
firstNamedArgument = i
Exit For '(No more positional arguments)
End If
If inputParametersCount - 1 < i Then
'(more positional arguments than parameters)
If isLastParamArray = False Then '(last parameter is not a paramarray)
'LogResolutionMessage(Parent.Compiler, "N/A: 3")
Return False
End If
'Add the additional expressions to the param array creation expression.
Helper.Assert(paramArrayExpression.ArrayElementInitalizer.Initializers.Count = 1)
For j As Integer = i To Arguments.Count - 1
'A paramarray element has to be specified.
If Arguments(j).Expression Is Nothing Then
'LogResolutionMessage(Parent.Compiler, "N/A: 4")
Return False
End If
paramArrayExpression.ArrayElementInitalizer.AddInitializer(Arguments(j).Expression)
Helper.Assert(m_TypesInInvokedOrder(j) Is Nothing)
m_TypesInInvokedOrder(j) = ParamArrayParameter.ParameterType.GetElementType
Next
Exit For
Else
matchedParameters.Add(InputParameters(i))
'Helper.Assert(m_TypesInInvokedOrder(i) Is Nothing)
m_TypesInInvokedOrder(i) = InputParameters(i).ParameterType
'Get the default value of the parameter if the specified argument has no expression.
Dim arg As Argument = Nothing
If Arguments(i).Expression Is Nothing Then
If InputParameters(i).IsOptional = False Then
Helper.Assert(False)
Else
Dim exp As Expression
Dim pArg As New PositionalArgument(Parent)
exp = Helper.GetOptionalValueExpression(pArg, InputParameters(i))
pArg.Init(InputParameters(i).Position, exp)
arg = pArg
End If
Else
arg = Arguments(i)
End If
If isLastParamArray = False Then exactArguments(i) = arg
If isLastParamArray AndAlso inputParametersCount - 1 = i Then
Helper.Assert(paramArrayExpression.ArrayElementInitalizer.Initializers.Count = 0)
paramArrayExpression.ArrayElementInitalizer.AddInitializer(arg.Expression)
'Helper.Assert(m_TypesInInvokedOrder(i) Is Nothing)
m_TypesInInvokedOrder(i) = ParamArrayParameter.ParameterType.GetElementType
Else
If isLastParamArray Then exactArguments(i) = arg
End If
End If
'??? If a positional argument is omitted, the method is not applicable.
Next
For i As Integer = firstNamedArgument To Arguments.Count - 1
Helper.Assert(Arguments(i).IsNamedArgument)
'Next, match each named argument to a parameter with the given name.
'If one of the named arguments fails to match, matches a paramarray parameter,
'or matches an argument already matched with another positional or named argument,
'the method is not applicable.
Dim namedArgument As NamedArgument = DirectCast(Arguments(i), NamedArgument)
Dim matched As Boolean = False
For j As Integer = 0 To inputParametersCount - 1
'Next, match each named argument to a parameter with the given name.
If NameResolution.CompareName(InputParameters(i).Name, namedArgument.Name) Then
If matchedParameters.Contains(InputParameters(i)) Then
'If one of the named arguments (...) matches an argument already matched with
'another positional or named argument, the method is not applicable
'LogResolutionMessage(Parent.Compiler, "N/A: 5")
Return False
ElseIf Helper.IsParamArrayParameter(Parent.Compiler, InputParameters(i)) Then
'If one of the named arguments (...) matches a paramarray parameter,
'(...) the method is not applicable.
'LogResolutionMessage(Parent.Compiler, "N/A: 6")
Return False
Else
matchedParameters.Add(InputParameters(i))
exactArguments(j) = Arguments(i)
Helper.Assert(m_TypesInInvokedOrder(j) Is Nothing)
m_TypesInInvokedOrder(j) = InputParameters(i).ParameterType
matched = True
Exit For
End If
End If
Next
'If one of the named arguments fails to match (...) the method is not applicable
If matched = False Then
'LogResolutionMessage(Parent.Compiler, "N/A: 7")
Return False
End If
Next
'Next, if parameters that have not been matched are not optional,
'the method is not applicable. If optional parameters remain, the default value
'specified in the optional parameter declaration is matched to the parameter.
'If an Object parameter does not specify a default value, then the expression
'System.Reflection.Missing.Value is used. If an optional Integer parameter
'has the Microsoft.VisualBasic.CompilerServices.OptionCompareAttribute attribute,
'then the literal 1 is supplied for text comparisons and the literal 0 otherwise.
For i As Integer = 0 To inputParametersCount - 1
If matchedParameters.Contains(InputParameters(i)) = False Then
'if parameters that have not been matched are not optional, the method is not applicable
If isLastParamArray = False AndAlso Helper.IsParamArrayParameter(Compiler, InputParameters(i)) Then
Return False
End If
If InputParameters(i).IsOptional = False AndAlso InputParameters(i) Is ParamArrayParameter = False Then
'LogResolutionMessage(Parent.Compiler, "N/A: 8")
Return False
End If
Dim exp As Expression
Dim arg As New PositionalArgument(Parent)
exp = Helper.GetOptionalValueExpression(arg, InputParameters(i))
arg.Init(InputParameters(i).Position, exp)
If isLastParamArray = False Then
Helper.Assert(m_TypesInInvokedOrder(i) Is Nothing)
m_TypesInInvokedOrder(i) = InputParameters(i).ParameterType
exactArguments(i) = arg
End If
If Helper.IsParamArrayParameter(Parent.Compiler, InputParameters(i)) = False Then
'he arraycreation has already been created and added to the exactArguments(1).
If isLastParamArray Then exactArguments(i) = arg
End If
End If
Next
'Finally, if type arguments have been specified, they are matched against
'the type parameter list. If the two lists do not have the same number of elements,
'the method is not applicable, unless the type argument list is empty. If the
'type argument list is empty, type inferencing is used to try and infer
'the type argument list. If type inferencing fails, the method is not applicable.
'Otherwise, the type arguments are filled in the place of the
'type parameters in the signature.
Dim genericTypeArgumentCount As Integer
Dim genericTypeArguments As Type()
If method IsNot Nothing AndAlso method.IsGenericMethod Then
genericTypeArguments = method.GetGenericArguments()
genericTypeArgumentCount = genericTypeArguments.Length
ElseIf prop IsNot Nothing Then
'property cannot be generic.
End If
If genericTypeArgumentCount > 0 AndAlso (TypeArguments Is Nothing OrElse TypeArguments.List.Count = 0) Then
'If the Then type argument list is empty, type inferencing is used to try and infer
'the type argument list.
Helper.NotImplementedYet("Type argument inference")
ElseIf TypeArguments IsNot Nothing AndAlso TypeArguments.List.Count > 0 Then
'If the two lists do not have the same number of elements, the method is not applicable
If TypeArguments.List.Count <> genericTypeArgumentCount Then
'LogResolutionMessage(Parent.Compiler, "N/A: 9")
Return False
End If
Helper.NotImplemented("Type argument matching")
End If
m_ExactArguments = exactArguments
Helper.AssertNotNothing(m_TypesInInvokedOrder)
If ResolveUnresolvedExpressions() = False Then
Helper.ErrorRecoveryNotImplemented()
End If
Return True 'Method is applicable!!
End Function
Function ResolveUnresolvedExpressions() As Boolean
Dim result As Boolean = True
For i As Integer = 0 To m_ExactArguments.Count - 1
Dim exp As Expression
Dim expType As Type
exp = m_ExactArguments(0).Expression
expType = exp.ExpressionType
If Helper.CompareType(expType, Compiler.TypeCache.DelegateUnresolvedType) = False Then Continue For
Dim aoe As AddressOfExpression
aoe = TryCast(exp, AddressOfExpression)
If aoe IsNot Nothing Then
Dim exp2 As Expression
exp2 = exp.ReclassifyMethodPointerToValueExpression(DefinedParameters(i).ParameterType)
result = exp2.ResolveExpression(ResolveInfo.Default(Compiler)) AndAlso result
If result Then m_ExactArguments(0).Expression = exp2
End If
Next
Return result
End Function
Sub SelectOutputArguments()
If IsParamArrayCandidate Then
Dim ace As ArrayCreationExpression
ace = ParamArrayExpression ' TryCast(OutputArguments.Item(OutputArguments.Count - 1).Expression, ArrayCreationExpression)
If ace IsNot Nothing AndAlso ace.IsResolved = False AndAlso Helper.IsParamArrayParameter(Compiler, InputParameters(InputParameters.Length - 1)) Then
If ace.ResolveExpression(ResolveInfo.Default(Compiler)) = False Then
Helper.ErrorRecoveryNotImplemented()
End If
End If
End If
End Sub
End Class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -