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 + -
显示快捷键?