invocationorindexexpression.vb

来自「大名鼎鼎的mono是.NET平台的跨平台(支持linux」· VB 代码 · 共 549 行 · 第 1/2 页

VB
549
字号
            Case ExpressionClassification.Classifications.Variable                'This is an index expression.                '                An index expression results in an array element or reclassifies a property group into a property access. An index expression consists of, in order, an expression, an opening parenthesis, an index argument list, and a closing parenthesis. The target of the index expression must be classified as either a property group or a value. An index expression is processed as follows:                '	If the target expression is classified as a value and if its type is not an array type, Object, or System.Array, the type must have a default property. The index is performed on a property group that represents all of the default properties of the type. Although it is not valid to declare a parameterless default property in Visual Basic, other languages may allow declaring such a property. Consequently, indexing a property with no arguments is allowed.                '	If the expression results in a value of an array type, the number of arguments in the argument list must be the same as the rank of the array type and may not include named arguments. If any of the indexes are invalid at run time, a System.IndexOutOfRangeException exception is thrown. Each expression must be implicitly convertible to type Integer. The result of the index expression is the variable at the specified index and is classified as a variable.                '	If the expression is classified as a property group, overload resolution is used to determine whether one of the properties is applicable to the index argument list. If the property group only contains one property that has a Get accessor and if that accessor takes no arguments, then the property group is interpreted as an index expression with an empty argument list. The result is used as the target of the current index expression. If no properties are applicable, then a compile-time error occurs. Otherwise, the expression results in a property access with the associated instance expression (if any) of the property group.                '	If the expression is classified as a late-bound property group or as a value whose type is Object or System.Array, the processing of the index expression is deferred until run time and the indexing is late-bound. The expression results in a late-bound property access typed as Object. The associated instance expression is either the target expression, if it is a value, or the associated instance expression of the property group. At run time the expression is processed as follows:                '	If the expression is classified as a late-bound property group, the expression may result in a method group, a property group, or a value (if the member is an instance or shared variable). If the result is a method group or property group, overload resolution is applied to the group to determine the correct method for the argument list. If overload resolution fails, a System.Reflection.AmbiguousMatchException exception is thrown. Then the result is processed either as a property access or as an invocation and the result is returned. If the invocation is of a subroutine, the result is Nothing.                '	If the run-time type of the target expression is an array type or System.Array, the result of the index expression is the value of the variable at the specified index.                 '	Otherwise, the run-time type of the expression must have a default property and the index is performed on the property group that represents all of the default properties on the type. If the type has no default property, then a System.MissingMemberException exception is thrown.                Dim varexp As VariableClassification = m_Expression.Classification.AsVariableClassification                Dim expType As Type = varexp.Type                If expType.IsByRef Then                    m_Expression = m_Expression.DereferenceByRef                    expType = m_Expression.ExpressionType                End If                result = ResolveIndexInvocation(Info.Compiler, expType) AndAlso result            Case Else                Helper.AddError("Some error...")        End Select        If result = False Then Return result        If m_ExpressionType Is Nothing Then            m_ExpressionType = Classification.GetType(True)        End If        Helper.Assert(m_ExpressionType IsNot Nothing)        Return result    End Function    Private Function ResolveIndexInvocation(ByVal Compiler As Compiler, ByVal VariableType As Type) As Boolean        Dim result As Boolean = True        Dim defaultProperties As Generic.List(Of PropertyInfo) = Nothing        If VariableType.IsArray Then            result = ResolveArrayInvocation(VariableType) AndAlso result        ElseIf Helper.IsDelegate(Compiler, VariableType) Then            'This is an invocation expression (the classification can be reclassified as value and the expression is a delegate expression)            result = ResolveDelegateInvocation(Compiler, VariableType)        ElseIf Helper.HasDefaultProperty(Compiler, VariableType, defaultProperties) Then            Dim propGroup As New PropertyGroupClassification(Me, m_Expression, defaultProperties)            Dim finalArguments As Generic.List(Of Argument) = Nothing            result = propGroup.ResolveGroup(m_ArgumentList, finalarguments)            If result Then                m_ArgumentList.ReplaceAndVerifyArguments(finalArguments, propGroup.ResolvedProperty)            End If            Classification = propGroup        ElseIf Helper.CompareType(VariableType, Compiler.TypeCache.System_Object) Then            Dim lbaClass As New LateBoundAccessClassification(Me, m_Expression, Nothing, Nothing)            lbaClass.Arguments = m_ArgumentList            Classification = lbaClass        Else            result = False            Helper.NotImplemented()        End If        Return result    End Function    Private Function ResolveArrayInvocation(ByVal ArrayType As Type) As Boolean        Dim result As Boolean = True        Helper.Assert(ArrayType.IsArray)        If m_ArgumentList.HasNamedArguments Then            Helper.AddError("Array invocation cannot have named arguments.")            Return False        End If        If ArrayType.GetArrayRank <> m_ArgumentList.Count Then            Helper.AddError("Array dimensions are not correct.")            Return False        End If        Dim isStrictOn As Boolean = Location.File(Compiler).IsOptionStrictOn        For i As Integer = 0 To m_ArgumentList.Count - 1            Dim arg As Argument = m_ArgumentList(i)            Dim argtype As Type = arg.Expression.ExpressionType            If Compiler.TypeResolution.IsImplicitlyConvertible(Compiler, argtype, Compiler.TypeCache.System_Int32) = False Then                If isStrictOn Then                    Helper.AddError("Array argument must be implicitly convertible to Integer.")                    Return False                End If                Dim exp As Expression                exp = Helper.CreateTypeConversion(Me, m_ArgumentList(i).Expression, Compiler.TypeCache.System_Int32, result)                If result = False Then Return result                m_ArgumentList(i).Expression = exp            End If        Next        m_ExpressionType = ArrayType.GetElementType        Classification = New VariableClassification(Me, Me.m_Expression, m_ArgumentList)        Return result    End Function    Private Function ResolveDelegateInvocation(ByVal Compiler As Compiler, ByVal DelegateType As Type) As Boolean        Dim result As Boolean = True        Dim invokeMethod As MethodInfo        Dim params() As ParameterInfo        Dim argTypes As Generic.List(Of Type)        Dim paramTypes() As Type        invokeMethod = Helper.GetInvokeMethod(Compiler, DelegateType)        params = Helper.GetParameters(Compiler, invokeMethod)        paramTypes = Helper.GetTypes(params)        argTypes = m_ArgumentList.GetTypes        If argTypes.Count <> paramTypes.Length Then Return False        For i As Integer = 0 To argTypes.Count - 1            If Compiler.TypeResolution.IsImplicitlyConvertible(Compiler, argTypes(i), paramTypes(i)) = False Then                Helper.AddError("Cannot convert implicitly from '" & argTypes(i).Name & "' to '" & paramTypes(i).Name & "'")                Return False            End If        Next        m_InvocationMethod = invokeMethod        If invokeMethod.ReturnType IsNot Nothing Then            Classification = New ValueClassification(Me, invokeMethod.ReturnType)        Else            Classification = New VoidClassification(Me)        End If        Return result    End Function    Private Function ResolvePropertyGroupInvocation() As Boolean        Dim result As Boolean = True        Dim finalArguments As Generic.List(Of Argument) = Nothing        Dim tmpResult As Boolean        tmpResult = m_Expression.Classification.AsPropertyGroup.ResolveGroup(m_ArgumentList, finalArguments)        If tmpResult = False Then            tmpResult = ResolveReclassifyToValueThenIndex()            Helper.StopIfDebugging(tmpResult = False)            Return tmpResult        Else            result = m_ArgumentList.ReplaceAndVerifyArguments(finalArguments, m_Expression.Classification.AsPropertyGroup.ResolvedProperty) AndAlso result        End If        Classification = New PropertyAccessClassification(m_Expression.Classification.AsPropertyGroup)        Return result    End Function    Private Function ResolveReclassifyToValueThenIndex() As Boolean        Dim result As Boolean = True        Dim tmpExp As Expression        Dim oldExp As Expression        tmpExp = m_Expression.ReclassifyToValueExpression        result = tmpExp.ResolveExpression(ResolveInfo.Default(Parent.Compiler)) AndAlso result        If result = False Then            Helper.AddError()            Return False        End If        oldExp = m_Expression        m_Expression = tmpExp        result = ResolveIndexInvocation(Compiler, m_Expression.ExpressionType) AndAlso result        Helper.StopIfDebugging(result = False)        Return result    End Function    Private Function ResolveMethodInvocation() As Boolean        Dim result As Boolean = True        Dim mgc As MethodGroupClassification = m_Expression.Classification.AsMethodGroupClassification        'If the method group only contains one method and that method takes no arguments and is a function,         'then the method group is interpreted as an invocation expression         'with an empty argument list and the result is used as the target of an index expression.        Dim reclassifyToIndex As Boolean        If mgc.Group.Count = 1 AndAlso m_ArgumentList.Count > 0 Then            Dim method As MethodInfo = TryCast(mgc.Group(0), MethodInfo)            reclassifyToIndex = method IsNot Nothing            reclassifyToIndex = reclassifyToIndex AndAlso method.ReturnType IsNot Nothing            reclassifyToIndex = reclassifyToIndex AndAlso Helper.CompareType(method.ReturnType, Compiler.TypeCache.System_Void) = False            reclassifyToIndex = reclassifyToIndex AndAlso Helper.GetParameters(Compiler, method).Length = 0        End If        If reclassifyToIndex Then            Return ResolveReclassifyToValueThenIndex()        Else            Dim finalArguments As Generic.List(Of Argument) = Nothing            result = mgc.ResolveGroup(m_ArgumentList, finalArguments)            If result Then                If mgc.IsLateBound = False Then                    m_ArgumentList.ReplaceAndVerifyArguments(finalArguments, mgc.ResolvedMethod)                End If            Else                mgc.ResolveGroup(m_ArgumentList, finalArguments, , True)                Return False            End If        End If        Helper.StopIfDebugging(result = False)        If mgc.IsLateBound Then            Dim lba As LateBoundAccessClassification = New LateBoundAccessClassification(Me, mgc.InstanceExpression, Nothing, mgc.Resolver.MethodName)            lba.LateBoundType = mgc.Resolver.MethodDeclaringType            lba.Arguments = m_ArgumentList            Classification = lba        ElseIf mgc.ResolvedMethodInfo IsNot Nothing Then            Dim methodInfo As MethodInfo = mgc.ResolvedMethodInfo            If Compiler.CommandLine.NoVBRuntimeRef AndAlso methodInfo.DeclaringType.Module Is Compiler.ModuleBuilder AndAlso methodInfo.IsStatic AndAlso Helper.CompareNameOrdinal(methodInfo.Name, "AscW") Then                Dim methodParameters() As ParameterInfo = Helper.GetParameters(Compiler, methodInfo)                If methodParameters.Length <> 0 AndAlso Helper.CompareType(methodParameters(0).ParameterType, Compiler.TypeCache.System_Char) Then                    m_AscWExpression = ArgumentList(0).Expression                    m_ExpressionType = Compiler.TypeCache.System_Int32                    Classification = New ValueClassification(Me, m_ExpressionType)                    Return result                End If            End If            If methodInfo.ReturnType Is Nothing Then                Classification = New VoidClassification(Me)            Else                Classification = New ValueClassification(Me, methodInfo.ReturnType)            End If        ElseIf mgc.ResolvedConstructor IsNot Nothing Then            Classification = New VoidClassification(Me)        Else            Throw New InternalException(Me)        End If        Return result    End Function    ''' <summary>    ''' Returns the list of arguments for this expression.    ''' Might be nothing.    ''' </summary>    ''' <value></value>    ''' <remarks></remarks>    ReadOnly Property ArgumentList() As ArgumentList        Get            Return m_ArgumentList        End Get    End Property#If DEBUG Then    Public Overrides Sub Dump(ByVal Dumper As IndentedTextWriter)        m_Expression.Dump(Dumper)        If m_ArgumentList IsNot Nothing Then            Dumper.Write("(")            Compiler.Dumper.Dump(m_ArgumentList)            Dumper.Write(")")        End If    End Sub#End IfEnd Class

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?