Compartilhar via


Descobrindo código usando o modelo de código (Visual Basic)

Os suplementos do Visual Studio foram substituídos no Visual Studio 2013. Você deve atualizar seus suplementos para as extensões VSPackage. Para obter mais informações sobre atualização, consulte Perguntas frequentes: convertendo suplementos em extensões VSPackage.

O modelo de código do Visual Studio oferece aos clientes de automação a capacidade de descobrir definições de código em um projeto e de modificar esses elementos de código. O modelo de código atualiza automaticamente todos os objetos referenciados quando modificações são feitas no editor de códigos. Por exemplo, se você referencia um objeto de classe e um usuário adiciona posteriormente uma nova função, ele é listado entre os membros. O modelo de código permite que os clientes de automação evitem implementar um analisador para linguagens do Visual Studio com a finalidade de descobrir as definições de alto nível em um projeto, como classes, interfaces, estruturas, métodos, propriedades etc.

O principal modelo de código do Visual Studio evita áreas de código específicas de linguagem, portanto, ele não fornece, por exemplo, um modelo de objeto para instruções em funções, nem fornece detalhes completos sobre parâmetros. Para parâmetros, o modelo de código expõe apenas o tipo e o nome do parâmetro, e nenhuma informação é fornecida dizendo se parâmetro é entrada, saída, opcional, e assim por diante. Visual C++ oferece uma versão estendida modelo de código principal que é definido para projetos de Visual C++. Para obter informações sobre isso, consulte Modelo de código do Visual C++.

Examinando e editando código com o modelo de código

O modelo de código é basicamente baseado em texto em que o programa ou o código no projeto é armazenado em arquivos de texto. Você pode localizar um código de projeto usando o modelo de projeto para visitar cada item de projeto e verificar se o item de projeto contém o código usando FileCodeModel. Se um item de projeto contiver elementos de código, esses elementos podem retornar objetos do editor e o modelo de código pode usar o modelo de automação do editor de texto para modificar o código ou executar a análise localizada. Usando o modelo de objeto de Editor, será possível solicitar o elemento de código que contém o ponto de inserção de editor ou um objeto de TextPoint no nível de função ou classe.

O ponto de entrada primário para o modelo de código principal do Visual Studio é o objeto CodeModel. Uma coleção de CodeElements geral usada em vários locais no modelo de código. Há uma no nível CodeElements e no nível de classe ou interface que retorna os membros desses objetos. Cada elemento de uma coleção de CodeElements é um objeto de CodeElement2 , e cada objeto de CodeElement2 tem uma propriedade de Kind que identifica seu tipo, seja uma classe, estrutura, interface, função, propriedade, variável, e assim por diante.

Modelos específicos da linguagem de código

Visual C++ fornece uma extensão para o modelo de código principal para o código específico do Visual C++. Por exemplo, se Language indicar que um determinado elemento de código é um objeto de modelo de código de Visual C++ , e Kind = vsCMElementClass, então você pode escolher a QueryInterface (QI) para CodeClass no modelo de código do Visual Studio ou a QI para VCCodeClass no modelo de código específico de linguagem do Visual C++. Para mais informações sobre o modelo de código específico do Visual C++, consulte Como manipular código usando o modelo de código do Visual C++ (Visual Basic) e Modelo de código do Visual C++.

Observações para o modelo de código principal do Visual Studio

  • Somente a implementação do modelo de código do Visual C++ executa a modelagem específica à linguagem das implementações de linguagem da Microsoft.

  • Algumas implementações de linguagem não implementam o modelo inteiro do código do Visual Studio. Os tópicos da Ajuda indicam exceções quando existirem. A maioria das diferenças entre as implementações de modelo de código são funcionais devido às diferenças entre as linguagens. Por exemplo, você não pode adicionar funções a objetos de CodeNamespace no Visual Basic ou Visual C# porque somente o Visual C++ possui definições de função de nível superior.

Descrição

Esse suplemento percorre os vários elementos de código de um arquivo do Visual Studio. Para executar o exemplo, você deve ter um arquivo de código-fonte aberto no editor de códigos Visual Studio. Para obter mais informações sobre como executar os exemplos, consulte Como compilar e executar os exemplos de código do modelo de objeto Automation.

Código

' Add-in code.
Public Sub OnConnection(ByVal application As Object, ByVal _
 connectMode As ext_ConnectMode, ByVal addInInst As Object,  _
 ByRef custom As Array) Implements IDTExtensibility2.OnConnection
    _applicationObject = CType(application, DTE2)
    _addInInstance = CType(addInInst, AddIn)
    ' Pass the applicationObject member variable to the code example.
    OutlineCode(_applicationObject)
End Sub

Sub OutlineCode(ByVal dte As DTE2)
    Dim fileCM As FileCodeModel2 _
      = CType(dte.ActiveDocument.ProjectItem.FileCodeModel, _
      FileCodeModel2)
    Dim elts As CodeElements
    elts = fileCM.CodeElements
    Dim elt As CodeElement2
    Dim i As Integer
    MsgBox("About to walk top-level elements ...")
    For i = 1 To fileCM.CodeElements.Count
        elt = CType(elts.Item(i), CodeElement2)
        CollapseElt(elt, elts, i)
    Next
End Sub

Sub CollapseElt(ByVal elt As CodeElement2, ByVal elts As _
    CodeElements, ByVal loc As Long)
    Dim epStart As EditPoint2
    Dim epEnd As EditPoint2
    epStart = CType(elt.StartPoint.CreateEditPoint, EditPoint2)
    ' Do this since we move it later.
    epEnd = CType(elt.EndPoint.CreateEditPoint, EditPoint2)
    epStart.EndOfLine()
    If ((elt.IsCodeType) And (elt.Kind <> _
      vsCMElement.vsCMElementDelegate)) Then
        MsgBox("Got type but not a delegate, named : " & elt.Name)
        Dim ct As CodeType
        ct = CType(elt, CodeType)
        Dim mems As CodeElements
        mems = ct.Members
        MsgBox("Set mems = ct.members")
        Dim i As Integer
        For i = 1 To ct.Members.Count
            CollapseElt(CType(mems.Item(i), CodeElement2), mems, i)
        Next
    ElseIf (elt.Kind = vsCMElement.vsCMElementNamespace) Then
        MsgBox("Got a namespace, named: " & elt.Name)
        Dim cns As CodeNamespace
        cns = CType(elt, CodeNamespace)
        MsgBox("set cns = elt, named: " & cns.Name)

        Dim mems_vb As CodeElements
        mems_vb = cns.Members
        MsgBox("Got cns.members")
        Dim i As Integer

        For i = 1 To cns.Members.Count
            CollapseElt(CType(mems_vb.Item(i), CodeElement2),  _
              mems_vb, i)
        Next
    End If
End Sub

Os valores do elemento de modelo de código podem ser alterados

Os valores atribuídos de elementos de modelo de código, como classes, estruturas, funções, atributos, representantes e assim por diante, podem ser alterados depois de serem feitos determinados tipos de edições. Portanto, não é possível presumir que os valores permanecerão estáticos.

Se você atribuir um elemento de modelo de código a uma variável local, por exemplo, e definir um valor de propriedade para essa variável local, a variável local não poderá conter um elemento válido de modelo de código quando você referenciá-la posteriormente. De fato, ainda pode conter um elemento de modelo de código diferente.

Considere uma classe que contém uma função chamada "MyFunction", que é atribuída a uma variável de CodeFunction e a propriedade Name de CodeFunction definida para o valor "YourFunction". Depois dessa atribuição de variável, não há garantia de que sua variável local represente o mesmo CodeFunction. Posteriormente, acessar o valor da propriedade poderá retornar E_FAIL como resultado.

A abordagem recomendada para tratar essa situação é reatribuir explicitamente sua variável local ao elemento de modelo de código correto antes de acessar seus valores de propriedade. O exemplo a seguir mostra como fazer isso. (O código está na forma de um suplemento.)

Descrição

Esse suplemento demonstra a maneira correta de acessar valores para CodeElements, de modo que o valor apropriado seja recuperado. Para obter mais informações sobre como executar os exemplos, consulte Como compilar e executar os exemplos de código do modelo de objeto Automation.

Código

[Visual Basic]

Public Sub OnConnection(ByVal application As Object, ByVal _
  connectMode As ext_ConnectMode, ByVal addInInst As Object, _
  ByRef custom As Array) Implements IDTExtensibility2.OnConnection
    _applicationObject = CType(application, DTE2)
    _addInInstance = CType(addInInst, AddIn)
    ReassignValue(_applicationObject)
End Sub

Sub ReassignValue(ByVal dte As DTE2)
    ' Before running, create a new Windows application project,
    ' and then add a function to it named MyFunction.
    Try
        Dim myFCM As FileCodeModel = _
          dte.ActiveDocument.ProjectItem.FileCodeModel
        ' Change the MyFunction name in Form1 class to
        ' the name, OtherFunction.
        Dim myClass1 As CodeClass = _
          CType(myFCM.CodeElements.Item("Form1"), CodeClass2)
        Dim myFunction As CodeFunction = _
          CType(myClass1.Members.Item("MyFunction"), CodeFunction2)
        myFunction.Name = "OtherFunction"
        myFunction = CType(myClass1.Members.Item("OtherFunction"), _
          CodeFunction2)
    Catch ex As Exception
        MsgBox(ex.ToString)
    End Try
End Sub

[C#]

public void OnConnection(object application, ext_ConnectMode 
  connectMode, object addInInst, ref Array custom)
{
    _applicationObject = (DTE2)application;
    _addInInstance = (AddIn)addInInst;
    ReassignValue(_applicationObject);
}

// Before running, create a new Windows application project,
// and then add a function to it named MyFunction.
public void ReassignValue(DTE2 dte)
{
    try
    {
        FileCodeModel myFCM = 
          dte.ActiveDocument.ProjectItem.FileCodeModel;
        // Change the MyFunction name in Form1 class to
        // the name, OtherFunction.
        CodeClass myClass1 = 
          (CodeClass2)myFCM.CodeElements.Item("Form1");
        CodeFunction myFunction = 
          (CodeFunction2)myClass1.Members.Item("MyFunction");
        myFunction.Name = "OtherFunction";
        myFunction = 
          (CodeFunction2)myClass1.Members.Item("OtherFunction");
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message);
    }
}

Dica

A configuração das propriedades de elementos filho do elemento modelo de código não exibe esse comportamento.Somente as propriedades que afetam diretamente o CodeElement — como o nome do elemento, o tipo de uma função, a assinatura de um método, etc. — exibem esse comportamento não determinístico.

Além disso, esse exemplo só funcionará se o novo nome de CodeElement for exclusivo entre seus irmãos.Isso ocorre porque a propriedade Item retorna a primeira correspondência, que não funciona para métodos/propriedades sobrecarregados, classes parciais ou namespaces com o mesmo nome.

Consulte também

Tarefas

Como compilar um código de exemplo para extensibilidade do modelo de código do Visual C++

Como criar um suplemento

Instruções passo a passo: criando um assistente

Como manipular código usando o modelo de código do Visual C++ (Visual C#)

Conceitos

Descobrindo código usando o modelo de código (Visual C#)

Modelo de código do Visual C++

Gráfico do modelo de objetos automation

Modelo de código do Visual C++

Outros recursos

Criando e controlando janelas de ambiente

Criando suplementos e assistentes

Referência sobre automação e extensibilidade