⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 methodresolver.vb

📁 大名鼎鼎的mono是.NET平台的跨平台(支持linux
💻 VB
📖 第 1 页 / 共 3 页
字号:
    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 + -