Вот макрос, который отлично работает для кода C #.
Когда я тестировал его в проекте VB .Net, он не работал для типов в ссылках на сборки.Похоже, модель кода проекта для VB.Net исключает внешние типы.
Я все равно включаю код здесь.Может быть, кто-то еще знает, как это сделать для VB
Сначала нам нужна функция, которая находит текущий контекст
Private Function FindCodeElement(ByVal caretPosition As TextPoint, ByVal elems As CodeElements) As CodeElement
If elems Is Nothing Then Return Nothing
Return elems.Cast(Of CodeElement) _
.Where(Function(x) x.StartPoint.LessThan(caretPosition) AndAlso _
x.EndPoint.GreaterThan(caretPosition)) _
.Select(Function(x) If(FindCodeElement(caretPosition, GetMembers(x)), x)) _
.FirstOrDefault()
End Function
Нам также нужна функция, которая создает все имена кандидатов на основеиспользование / import операторов
Private Sub FindAllCandidates(ByVal elem As Object, ByVal className As String)
If TypeOf elem Is CodeFunction Then
FindAllCandidates(CType(elem, CodeFunction).Parent, className)
ElseIf TypeOf elem Is CodeClass Then
mCandidates.Add(CType(elem, CodeClass).FullName & "." & className)
FindAllCandidates(CType(elem, CodeClass).Parent, className)
ElseIf TypeOf elem Is CodeStruct Then
mCandidates.Add(CType(elem, CodeStruct).FullName & "." & className)
FindAllCandidates(CType(elem, CodeStruct).Parent, className)
ElseIf TypeOf elem Is CodeNamespace Then
mCandidates.Add(CType(elem, CodeNamespace).FullName & "." & className)
For Each ns As String In CType(elem, CodeNamespace).Members.OfType(Of CodeImport) _
.Select(Function(x) x.Namespace)
mCandidates.Add(ns & "." & className)
Next
FindAllCandidates(CType(elem, CodeNamespace).Parent, className)
ElseIf TypeOf elem Is FileCodeModel Then
For Each ns As String In CType(elem, FileCodeModel).CodeElements.OfType(Of CodeImport) _
.Select(Function(x) x.Namespace)
mCandidates.Add(ns & "." & className)
Next
End If
End Sub
А затем функция, которая зацикливает все доступные элементы для поиска одного из кандидатов
Private Function FindClassInCodeElements(ByVal elems As CodeElements) As CodeElement
If elems Is Nothing Then Return Nothing
For Each elem As CodeElement In elems
If IsClassType(elem) Then
If mCandidates.Contains(elem.FullName) Then Return elem
ElseIf TypeOf elem Is CodeNamespace Then
For Each candidate As String In mCandidates
If candidate.StartsWith(elem.FullName) Then
Dim found As CodeElement = FindClassInCodeElements(GetMembers(elem))
If found IsNot Nothing Then Return found
Exit For
End If
Next
End If
Next
Return Nothing
End Function
Две маленькие вспомогательные функции
Private Function IsClassType(ByVal elem As CodeElement) As Boolean
Return TypeOf elem Is CodeClass OrElse TypeOf elem Is CodeStruct OrElse TypeOf elem Is CodeInterface
End Function
Private Function GetMembers(ByVal elem As CodeElement) As CodeElements
If TypeOf elem Is CodeClass Then
Return CType(elem, CodeClass).Members
ElseIf TypeOf elem Is CodeNamespace Then
Return CType(elem, CodeNamespace).Members
ElseIf TypeOf elem Is CodeStruct Then
Return CType(elem, CodeStruct).Members
ElseIf TypeOf elem Is CodeInterface Then
Return CType(elem, CodeInterface).Members
End If
Return Nothing
End Function
И тогда мы можем написать основную функцию, которую вы можете изменить в зависимости от того, как вы хотите ее использовать.
Dim mCandidates As New HashSet(Of String)
Sub ExpandFullNameOfSelection()
Dim selection As EnvDTE.TextSelection = CType(DTE.ActiveDocument.Selection(), EnvDTE.TextSelection)
' Assume type is selected
Dim className As String = selection.Text
' Find current context
Dim currentFunction As CodeElement = FindCodeElement(selection.ActivePoint, DTE.ActiveDocument.ProjectItem.FileCodeModel.CodeElements)
mCandidates.Clear()
FindAllCandidates(currentFunction, className)
Dim classType As CodeElement = DTE.Solution.Projects.Cast(Of Project) _
.Where(Function(x) x.CodeModel IsNot Nothing) _
.Select(Function(x) FindClassInCodeElements(x.CodeModel.CodeElements)) _
.FirstOrDefault(Function(x) x IsNot Nothing)
If classType IsNot Nothing Then
selection.Text = classType.FullName ' replace with full name
End If
End Function