typemanager.vb
来自「大名鼎鼎的mono是.NET平台的跨平台(支持linux」· VB 代码 · 共 729 行 · 第 1/2 页
VB
729 行
' ' Visual Basic.Net Compiler' Copyright (C) 2004 - 2007 Rolf Bjarne Kvinge, RKvinge@novell.com' ' This library is free software; you can redistribute it and/or' modify it under the terms of the GNU Lesser General Public' License as published by the Free Software Foundation; either' version 2.1 of the License, or (at your option) any later version.' ' This library is distributed in the hope that it will be useful,' but WITHOUT ANY WARRANTY; without even the implied warranty of' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU' Lesser General Public License for more details.' ' You should have received a copy of the GNU Lesser General Public' License along with this library; if not, write to the Free Software' Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA' #If DEBUG Then#Const EXTENDEDDEBUG = 0#End If''' <summary>''' A helper class containing all information about the referenced assemblies,''' loaded types, etc.''' </summary>''' <remarks></remarks>Public Class TypeManager#If ENABLECECIL Then Private m_CecilAssemblies As New Generic.List(Of Mono.Cecil.AssemblyDefinition) Private m_CecilTypes As New CecilTypeList Private m_CecilModuleTypes As New CecilTypeList Private m_CecilTypesByNamespace As New CecilNamespaceDictionary Private m_CecilModulesByNamespace As New CecilNamespaceDictionary#End If ''' <summary> ''' All the referenced assemblies ''' </summary> ''' <remarks></remarks> Private m_Assemblies As New Generic.List(Of System.Reflection.Assembly) ''' <summary> ''' All the types available. ''' </summary> ''' <remarks></remarks> Private m_Types As New TypeList ''' <summary> ''' All the types indexed by namespace. ''' </summary> ''' <remarks></remarks> Private m_TypesByNamespace As New NamespaceDictionary Private m_TypesByNamespaceAndName As New Generic.Dictionary(Of String, Generic.List(Of MemberInfo)) Private m_TypesByName As New Generic.Dictionary(Of String, Generic.List(Of Type))(NameResolution.StringComparer) Private m_TypesByFullName As New Generic.Dictionary(Of String, Generic.List(Of Type))(NameResolution.StringComparer) ''' <summary> ''' All the modules indexed by namespace. ''' </summary> ''' <remarks></remarks> Private m_ModulesByNamespace As New NamespaceDictionary ''' <summary> ''' All the namespaces available. ''' </summary> ''' <remarks></remarks> Private m_Namespaces As New Namespaces ''' <summary> ''' All the types that are modules. ''' </summary> ''' <remarks></remarks> Private m_ModuleTypes As New TypeList Private m_Compiler As Compiler Private Shared m_GenericTypeCache As New Generic.Dictionary(Of String, GenericTypeDescriptor)(vbnc.NameResolution.StringComparer) Private Shared m_TypeDescriptorsOfTypes As New Generic.Dictionary(Of Type, TypeDescriptor)(New TypeComparer) Private Shared m_TypeDescriptorsOfTypes2 As New Generic.Dictionary(Of Integer, TypeDescriptor) Private Shared m_MemberDescriptorsOfMembers As New Generic.Dictionary(Of Integer, MemberInfo) Private Shared m_MemberDescriptorsOfMembers2 As New Generic.Dictionary(Of MemberInfo, MemberInfo)(New MemberComparer) Public MemberCache As New Generic.Dictionary(Of Type, MemberCache)(New TypeComparer) Function IsTypeNamed(ByVal Type As Type, ByVal Name As String) As Boolean If TypeOf Type Is TypeDescriptor Then Return NameResolution.CompareName(Type.Name, Name) Dim types As Generic.List(Of Type) = Nothing If m_TypesByName.TryGetValue(Name, types) = False Then Return False Return types.Contains(Type) End Function Function IsTypeFullnamed(ByVal Type As Type, ByVal FullName As String) As Boolean If TypeOf Type Is TypeDescriptor Then Return NameResolution.CompareName(Type.FullName, FullName) Dim types As Generic.List(Of Type) = Nothing If m_TypesByFullName.TryGetValue(FullName, types) = False Then Return False Return types.Contains(Type) End Function ReadOnly Property TypesByName() As Generic.Dictionary(Of String, Generic.List(Of Type)) Get Return m_TypesByName End Get End Property Function GetCache(ByVal Type As Type) As MemberCache If MemberCache.ContainsKey(Type) Then Return MemberCache(Type) Else Return New MemberCache(Compiler, Type) End If End Function Function ContainsCache(ByVal Type As Type) As Boolean Return MemberCache.ContainsKey(Type) End Function ''' <summary> ''' All the referenced assemblies ''' </summary> ''' <remarks></remarks> ReadOnly Property Assemblies() As Generic.List(Of System.Reflection.Assembly) Get Return m_Assemblies End Get End Property#If ENABLECECIL Then ReadOnly Property CecilAssemblies() As Generic.List(Of Mono.Cecil.AssemblyDefinition) Get Return m_CecilAssemblies End Get End Property ReadOnly Property CecilTypes() As CecilTypeList Get Return m_CecilTypes End Get End Property#End If ''' <summary> ''' All the non-nested types available. ''' </summary> ''' <remarks></remarks> ReadOnly Property Types() As TypeList Get Return m_Types End Get End Property ''' <summary> ''' All the non-nested types indexed by namespace. ''' </summary> ''' <remarks></remarks> ReadOnly Property TypesByNamespace() As NamespaceDictionary Get Return m_TypesByNamespace End Get End Property Function GetTypesByNamespaceAndName(ByVal [Namespace] As String, ByVal Name As String) As Generic.List(Of MemberInfo) Dim result As Generic.List(Of MemberInfo) Dim key As String = String.Concat([Namespace], "?", Name) If m_TypesByNamespaceAndName.ContainsKey(key) Then result = m_TypesByNamespaceAndName(key) Else result = New Generic.List(Of MemberInfo) Helper.FilterByName(TypesByNamespace([Namespace]), Name, result) m_TypesByNamespaceAndName.Add(key, result) End If Return result End Function ''' <summary> ''' All the namespaces available. ''' </summary> ''' <remarks></remarks> ReadOnly Property Namespaces() As Namespaces Get Return m_Namespaces End Get End Property ''' <summary> ''' All the non-nested types that are modules. ''' </summary> ''' <remarks></remarks> ReadOnly Property ModuleTypes() As TypeList Get Return m_ModuleTypes End Get End Property ReadOnly Property Compiler() As Compiler Get Return m_Compiler End Get End Property Sub New(ByVal Compiler As Compiler) MyBase.New() m_Compiler = Compiler End Sub ''' <summary> ''' Searches for the type with the specified name. ''' </summary> ''' <param name="Name">The type's name to search for. Not case-sensitive.</param> ''' <param name="OnlyCreatedTypes">Specifes whether to search in all types, or only in types compiled now.</param> ''' <returns></returns> ''' <remarks></remarks> Overloads Function [GetType](ByVal Name As String, ByVal OnlyCreatedTypes As Boolean) As Generic.List(Of Type) Dim result As New Generic.List(Of Type) result.AddRange(Me.GetType(Name, Types, OnlyCreatedTypes)) Return result End Function Overloads Function [GetType](ByVal Name As String, ByVal InList As IEnumerable, ByVal OnlyCreatedTypes As Boolean) As Generic.List(Of Type) Dim result As New Generic.List(Of Type) For Each tp As Type In InList Dim tpD As TypeDescriptor = TryCast(tp, TypeDescriptor) If OnlyCreatedTypes AndAlso tpD Is Nothing Then Continue For If IsTypeNamed(tp, Name) OrElse IsTypeFullnamed(tp, Name) Then#If EXTENDEDDEBUG Then Compiler.Report.WriteLine("Found type: " & tp.Name)#End If result.Add(tp) Else#If EXTENDEDDEBUG Then Compiler.Report.WriteLine("Discarded type: " & tp.Name)#End If End If result.AddRange(Me.GetType(Name, tp.GetNestedTypes(BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic), OnlyCreatedTypes)) Next Return result End Function ''' <summary> ''' Loads all the referenced assemblies. ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Private Function LoadReferencedAssemblies() As Boolean Dim result As Boolean = True Dim refAssembly As Reflection.Assembly For Each strFile As String In Compiler.CommandLine.References refAssembly = LoadAssembly(strFile) If refAssembly Is Nothing Then Compiler.Report.ShowMessage(Messages.VBNC2017, strFile) Return False Else If Assemblies.Contains(refAssembly) = False Then If Compiler.CommandLine.Verbose Then Compiler.Report.WriteLine("Loaded '" & refAssembly.Location & "' (" & refAssembly.FullName & ")") End If Assemblies.Add(refAssembly)#If ENABLECECIL Then m_CecilAssemblies.Add(Mono.Cecil.AssemblyFactory.GetAssembly(refAssembly.Location))#End If End If End If Next Compiler.TypeCache.Init()#If ENABLECECIL Then Compiler.CecilTypeCache.Init()#End If Return result End Function ''' <summary> ''' Loads all the types (referenced and compiled) and all the namespaces as well. ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Function LoadReferenced() As Boolean Dim result As Boolean = True result = LoadReferencedAssemblies() AndAlso result If result = False Then Return result Dim loadVB As Boolean loadVB = Compiler.CommandLine.NoVBRuntimeRef = False If Not loadVB Then For Each ass As Assembly In Assemblies If NameResolution.CompareNameOrdinal(ass.GetName().Name, "Microsoft.VisualBasic") Then loadVB = True Exit For End If Next End If If loadVB Then Compiler.TypeCache.InitInternalVB()#If ENABLECECIL Then Compiler.CecilTypeCache.InitInternalVB()#End If End If result = LoadReferencedTypes() AndAlso result#If EXTENDEDDEBUG Then Compiler.Report.WriteLine(String.Format("{0} assemblies were loaded.", Assemblies.Count.ToString)) If Compiler.CommandLine.Verbose Then For i As Integer = 0 To Assemblies.Count - 1 Compiler.Report.WriteLine("#" & (i + 1).ToString & ": " & Assemblies(i).FullName & " (location: " & Assemblies(i).Location & ")") Next End If Compiler.Report.WriteLine(String.Format("{0} namespaces were loaded.", Namespaces.Count)) If Compiler.CommandLine.Verbose Then Dim ns As String() = Namespaces.NamespacesAsString For i As Integer = 0 To ns.Length - 1 Compiler.Report.WriteLine("#" & (i + 1).ToString & ": " & ns(i)) Next End If Compiler.Report.WriteLine(String.Format("{0} types were loaded.", Types.Count)) If Compiler.CommandLine.Verbose Then For i As Integer = 0 To Types.Count - 1 'Compiler.Report.WriteLine("#" & (i + 1).ToString & ": " & Types(i).FullName) Next End If#End If Return result End Function ''' <summary> ''' Tries to load the specified file as an assembly. ''' </summary> ''' <param name="Filename"></param> ''' <returns></returns> ''' <remarks></remarks> Private Function LoadAssembly(ByVal Filename As String) As Reflection.Assembly Dim refAss As Reflection.Assembly ' Try If IO.File.Exists(Filename) Then refAss = Reflection.Assembly.LoadFrom(Filename) 'If Compiler.CommandLine.Verbose Then Compiler.Report.WriteLine("Loaded '" & Filename & "'") Return refAss End If If IO.File.Exists(IO.Path.Combine(IO.Path.GetDirectoryName(Reflection.Assembly.GetExecutingAssembly.Location), Filename)) Then Filename = IO.Path.Combine(IO.Path.GetDirectoryName(Reflection.Assembly.GetExecutingAssembly.Location), Filename) refAss = Reflection.Assembly.LoadFrom(Filename) 'If Compiler.CommandLine.Verbose Then Compiler.Report.WriteLine("Loaded '" & Filename & "'") Return refAss End If ' Catch ex As IO.FileNotFoundException For Each strPath As String In Compiler.CommandLine.LibPath Dim strFullPath As String = IO.Path.Combine(strPath, Filename) Try If IO.File.Exists(strFullPath) Then refAss = Reflection.Assembly.LoadFrom(strFullPath) 'If Compiler.CommandLine.Verbose Then Compiler.Report.WriteLine("Loaded '" & strFullPath & "'") Return refAss End If Catch ex2 As Exception 'Do nothing, just keep on trying End Try
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?