simplenameexpression.vb
来自「大名鼎鼎的mono是.NET平台的跨平台(支持linux」· VB 代码 · 共 907 行 · 第 1/4 页
VB
907 行
' result is exactly the same as a member access of the form M.E, where M is the standard module ' containing the matching member and E is the identifier. If the identifier matches accessible type ' members in more than one standard module, a compile-time error occurs. '--------------------------------------------------------------------------------------------------------- '* If the source file has one or more import aliases, and the identifier matches the name of one of them, ' then the identifier refers to that namespace or type. '--------------------------------------------------------------------------------------------------------- '* If the source file containing the name reference has one or more imports: '** If the identifier matches the name of an accessible type or type member in exactly one import, ' then the identifier refers to that type or type member. If the identifier matches the name of ' an accessible type or type member in more than one import, a compile-time error occurs. '** If the identifier matches the name of a namespace in exactly one import, then the identifier ' refers to that namespace. If the identifier matches the name of a namespace in more than one import, ' a compile-time error occurs. '** Otherwise, if the imports contain one or more accessible standard modules, and a member name ' lookup of the identifier produces an accessible match in exactly one standard module, then ' the result is exactly the same as a member access of the form M.E, where M is the standard ' module containing the matching member and E is the identifier. If the identifier matches ' accessible type members in more than one standard module, a compile-time error occurs. '--------------------------------------------------------------------------------------------------------- '* If the compilation environment defines one or more import aliases, and the identifier matches ' the name of one of them, then the identifier refers to that namespace or type. '--------------------------------------------------------------------------------------------------------- '* If the compilation environment defines one or more imports: '** If the identifier matches the name of an accessible type or type member in exactly one import, ' then the identifier refers to that type or type member. If the identifier matches the name ' of an accessible type or type member in more than one import, a compile-time error occurs. '** If the identifier matches the name of a namespace in exactly one import, then the identifier ' refers to that namespace. If the identifier matches the name of a namespace in more than ' one import, a compile-time error occurs. '** Otherwise, if the imports contain one or more accessible standard modules, and a member name ' lookup of the identifier produces an accessible match in exactly one standard module, then the result ' is exactly the same as a member access of the form M.E, where M is the standard module containing ' the matching member and E is the identifier. If the identifier matches accessible type members in ' more than one standard module, a compile-time error occurs. '--------------------------------------------------------------------------------------------------------- '* Otherwise, the name given by the identifier is undefined and a compile-time error occurs. '--------------------------------------------------------------------------------------------------------- 'If a simple name with a type argument list resolves to anything other than a type or method, 'a compile time error occurs. If a type argument list is supplied, only types with the same arity as 'the type argument list are considered but type members, including methods with different arities, 'are still considered. This is because type inference can be used to fill in missing type arguments. 'As a result, names with type arguments may bind differently to types and methods: '--------------------------------------------------------------------------------------------------------- If m_TypeArgumentList IsNot Nothing Then If m_TypeArgumentList.ResolveCode(Info) = False Then Return False '* Starting with the immediately enclosing block and continuing with each enclosing outer block (if any), ' if the identifier matches the name of a local variable, static variable, constant local, method type ' parameter, or parameter, then the identifier refers to the matching entity. ' - The expression is classified as a variable if it is a local variable, static variable, or parameter. ' - The expression is classified as a type if it is a method type parameter. ' - The expression is classified as a value if it is a constant local. ' * With the following exception: ' If the local variable matched is the implicit function or Get accessor return local variable, ' and the expression is part of an invocation expression, invocation statement, ' or an AddressOf expression, then no match occurs and resolution continues. Dim block As CodeBlock = Me.FindFirstParent(Of CodeBlock)() While block IsNot Nothing Dim var As IAttributableNamedDeclaration var = block.FindVariable(Name) If TypeOf var Is ConstantDeclaration Then 'The expression is classified as a value if it is a constant local (...) Classification = New ValueClassification(Me, DirectCast(var, ConstantDeclaration)) Return True ElseIf TypeOf var Is VariableDeclaration Then 'The expression is classified as a variable if it is a local variable, static variable (...) Dim varDecl As VariableDeclaration varDecl = DirectCast(var, VariableDeclaration) If varDecl.Modifiers.Is(ModifierMasks.Static) AndAlso varDecl.DeclaringMethod.IsShared = False Then Classification = New VariableClassification(Me, varDecl, CreateMeExpression) Else Classification = New VariableClassification(Me, varDecl) End If Return True ElseIf var IsNot Nothing Then Throw New InternalException(Me) End If block = block.FindFirstParent(Of CodeBlock)() End While Dim method As IMethod method = Me.FindFirstParent(Of IMethod)() If method IsNot Nothing Then If method.Signature.TypeParameters IsNot Nothing Then Dim typeparam As TypeParameter = method.Signature.TypeParameters.Parameters.Item(Name) If typeparam IsNot Nothing Then 'The expression is classified as a type if it is a method type parameter. Classification = New TypeClassification(Me, typeparam) Return True End If End If End If If method IsNot Nothing Then If method.Signature.Parameters IsNot Nothing Then Dim param As Parameter = method.Signature.Parameters.Item(Name) If param IsNot Nothing Then 'The expression is classified as a variable if it is a (...) parameter Classification = New VariableClassification(Me, param) Return True End If End If End If ' If the local variable matched is the implicit function or Get accessor return local variable, ' and the expression is part of an invocation expression, invocation statement, ' or an AddressOf expression, then no match occurs and resolution continues. If method IsNot Nothing Then If method.HasReturnValue AndAlso Info.SkipFunctionReturnVariable = False Then If NameResolution.CompareName(method.Name, Name) Then 'The expression is classified as a variable if it is a local variable, static variable (...) Classification = New VariableClassification(Me, method) Return True End If End If End If '* For each nested type containing the expression, starting from the innermost and going to the ' outermost, if a lookup of the identifier in the type produces a match with an accessible member: '** If the matching type member is a type parameter, then the result is classified as a type and ' is the matching type parameter. '** Otherwise, if the type is the immediately enclosing type and the lookup identifies a non-shared ' type member, then the result is the same as a member access of the form Me.E, where E is ' the identifier. '** Otherwise, the result is exactly the same as a member access of the form T.E, where T is the ' type containing the matching member and E is the identifier. In this case, it is an error for the ' identifier to refer to a non-shared member. Dim firstcontainer As IType = Me.FindFirstParent(Of IType)() Dim container As IType = firstcontainer While container IsNot Nothing Dim constructable As IConstructable = TryCast(container, IConstructable) If constructable IsNot Nothing AndAlso constructable.TypeParameters IsNot Nothing Then Dim typeparam As TypeParameter = constructable.TypeParameters.Parameters.Item(Name) If typeparam IsNot Nothing Then 'If the matching type member is a type parameter, then the result is classified 'as a type and is the matching type parameter. Classification = New TypeClassification(Me, typeparam) Return True End If End If Dim cache As MemberCacheEntry Dim members As Generic.List(Of MemberInfo) cache = Compiler.TypeManager.GetCache(container.TypeDescriptor).LookupFlattened(Name) If cache Is Nothing Then members = New Generic.List(Of MemberInfo) Else members = cache.Members members = Helper.FilterExternalInaccessible(Compiler, members) End If#If EXTENDEDDEBUG Then Compiler.Report.WriteLine("Found " & membersArray.Length & " members, after filtering by name it's " & members.Count & " members")#End If Helper.ApplyTypeArguments(members, m_TypeArgumentList) If members.Count > 0 Then 'Otherwise, if the type is the immediately enclosing type and the lookup identifies a non-shared 'type member, then the result is the same as a member access of the form Me.E, where E is 'the identifier. 'Otherwise, the result is exactly the same as a member access of the form T.E, where T is the 'type containing the matching member and E is the identifier. In this case, it is an error for the 'identifier to refer to a non-shared member. 'NOTE: it is not possible to determine yet if the resolved member is shared or not '(it can resolve to a method group with several methods, some shared, some not. 'So we create a classification with an instance expression, if the member is 'shared, the instance expression should not be used. Dim hasInstanceExpression As Boolean Dim hasNotInstanceExpression As Boolean For i As Integer = 0 To members.Count - 1 Dim member As MemberInfo = members(i) If member.MemberType = MemberTypes.TypeInfo OrElse member.MemberType = MemberTypes.NestedType Then hasNotInstanceExpression = True ElseIf Helper.IsShared(member) Then hasNotInstanceExpression = True Else hasInstanceExpression = True End If Next If container Is firstcontainer AndAlso hasInstanceExpression Then 'Otherwise, if the type is the immediately enclosing type and the lookup identifies a non-shared 'type member, then the result is the same as a member access of the form Me.E, where E is 'the identifier. Classification = GetMeClassification(members, firstcontainer) Return True Else 'Otherwise, the result is exactly the same as a member access of the form T.E, where T is the 'type containing the matching member and E is the identifier. In this case, it is an error for the 'identifier to refer to a non-shared member. Classification = GetTypeClassification(members, firstcontainer) Return True End If End If container = DirectCast(container, BaseObject).FindFirstParent(Of IType)() End While '* For each nested namespace, starting from the innermost and going to the outermost namespace, ' do the following: '** If the namespace contains an accessible namespace member with the given name, then the identifier ' refers to that member and, depending on the member, is classified as a namespace or a type. '** Otherwise, if the namespace contains one or more accessible standard modules, and a member name ' lookup of the identifier produces an accessible match in exactly one standard module, then the ' result is exactly the same as a member access of the form M.E, where M is the standard module ' containing the matching member and E is the identifier. If the identifier matches accessible type ' members in more than one standard module, a compile-time error occurs. Dim currentNS As String = Nothing If firstcontainer IsNot Nothing Then currentNS = firstcontainer.Namespace While currentNS IsNot Nothing Dim foundType As Type foundType = Compiler.TypeManager.GetTypesByNamespace(currentNS).Item(Name) If foundType IsNot Nothing Then Classification = New TypeClassification(Me, foundType) Return True End If If currentNS <> "" Then Dim foundNS As [Namespace] foundNS = Compiler.TypeManager.Namespaces(currentNS & "." & Name) If foundNS IsNot Nothing Then Classification = New NamespaceClassification(Me, foundNS) Return True End If
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?