Odnajdowanie kodu za pomocą modelu kodu (Visual C#)

Dodatki Visual Studio zostały zaniechane w programie Visual Studio 2013.Dodatki należy uaktualniać do pakietu rozszerzenia VSPackage.Aby uzyskać więcej informacji na temat uaktualniania, zobacz Często zadawane pytania: konwertowanie dodatków na rozszerzenia pakietu VSPackage.

Visual Studio Model kodu oferuje klientom automatyzacji możliwość odkrycia definicji kodów w projekcie i zmodyfikowania tych elementów kodu.Po dokonaniu modyfikacji w edytorze kodu model kodu automatycznie aktualizuje wszystkie obiekty.Na przykład, jeśli odwołujesz się do obiektu klasy, a użytkownik później dodaje nową funkcję, jest ona wyświetlana wśród elementów członkowskich.Model kodu umożliwia klientom automatyzacji uniknięcie wykonania parser dla Visual Studio języków, aby odkryć definicje wysokiego szczebla w projekcie, takich jak klasy, interfejsy, struktury, metody, właściwości i tak dalej.

Visual Studio Model rdzenia kodu unika obszarów kod języka, więc, na przykład nie podaje modelu obiektu dla instrukcji w funkcjach ani nie podaje pełnych szczegółów dotyczących parametrów.W przypadku parametrów, model kodu udostępnia tylko typ i nazwę parametru i nie dostarcza żadnych informacji na temat czy jest to parametr danych wejściowych, wyjściowych, opcjonalny i tak dalej.Visual C++ zapewnia to rozszerzoną wersję modelu kodu rdzenia, która jest skierowany głównie do Visual C++ projektów.Aby uzyskać informacje na ten temat, zobacz Model kodu Visual C++.

Badanie i edycja kodu z modelem kodu

Model kodu jest przede wszystkim tekstowy, ponieważ program lub kod w projekcie są przechowywane w plikach tekstowych.Znajdź kod projektu przy użyciu modelu projektu do odwiedzenia każdego elementu projektu, a następnie sprawdź, czy element projektu zawiera kod, za pomocą FileCodeModel.Jeśli elementy projektu zawierają elementy kodu, elementy te mogą zwracać obiekty z edytora, a model kodu może wykorzystać model automatyzacji edytora tekstu do modyfikowania kodu lub wykonać analizy składniowe.Za pomocą modelu obiektów edytora, można żądać element kodu zawierający punkt wstawiania edytora lub obiekt TextPoint na poziomie funkcji lub klasy.

Punkt wejścia podstawowy, Visual Studio jest modelem kodu core CodeModel obiektu.Kolekcja ogólna CodeElements jest używana w kilku miejscach w modelu kodu.Znajduje się na CodeElements poziomie i na poziomie klasy lub interfejsu, który zwraca elementy członkowskie z tych obiektów.Każdy element kolekcji CodeElements jest obiektem CodeElement2, a każdy obiekt CodeElement2 posiada właściwość Kind, która identyfikuje jego typ, czy jest to klasa, interfejs, strukturę, funkcję, właściwość, zmienną i tak dalej.

Modele kodu specyficznego dla języka

Visual C++ oferuje rozszerzenie modelu rdzenia kodu do obiektu docelowego Visual C++-określonego kodu.Na przykład jeśli Language wskazuje, że dany element kodu jest obiektu modelu kodu Visual C++ i Kind = vsCMElementClass, wówczas można wybrać QueryInterface (QI) dla CodeClass z modelu kodu Visual Studio lub QI dla VCCodeClass z modelu kodu określonego języka Visual C++.Aby uzyskać więcej informacji o modelu kodu specyficznego dla Visual C++, zobacz Porady: manipulowanie kodem za pomocą modelu kodu Visual C++ (Visual C#) i Model kodu Visual C++.

Uwagi dotyczące Model kodu programu Visual Studio

  • Tylko Visual C++ wykonuje kod modelu implementacji języka modelowania implementacji języka Microsoft.

  • W przypadku niektórych języków nie należy implementować, cały Visual Studio kod modelu.Tematy pomocy zwracają uwagę na wyjątki, jeśli takie istnieją.Większość różnic między implementacjami modelu kodu istnieje ze względu na różnice funkcjonalne między językami.Na przykład, nie można dodać funkcji do obiektów CodeNamespace w Visual Basic lub Visual C# ponieważ tylko Visual C++ cechuje się definicjami funkcji najwyższego poziomu.

Opis

Ten dodatek poprowadzi przez elementy kodu Visual Studio pliku.Aby uruchomić przykład, musi mieć kod plik otwarty w Visual Studio Edytor kodu.Aby uzyskać więcej informacji na temat sposobu uruchamiania przykładów, zobacz Porady: kompilowanie i uruchamianie kodu modelu obiektów automatyzacji — przykłady.

Kod

// Add-in code.
using System.Windows.Forms;
public void OnConnection(object application,
 Extensibility.ext_ConnectMode connectMode, object addInInst, ref
 System.Array custom)
{
    _applicationObject = (_DTE2)application;
    _addInInstance = (AddIn)addInInst;
    // Pass the applicationObject member variable to the code example.
    OutlineCode((DTE2)_applicationObject); 
}

public void OutlineCode( DTE2 dte ) 
{ 
    FileCodeModel fileCM = 
      dte.ActiveDocument.ProjectItem.FileCodeModel; 
    CodeElements elts = null; 
    elts = fileCM.CodeElements; 
    CodeElement elt = null; 
    int i = 0; 
    MessageBox.Show( "about to walk top-level code elements ..."); 
    for ( i=1; i<=fileCM.CodeElements.Count; i++ ) 
    { 
        elt = elts.Item( i ); 
        CollapseElt( elt, elts, i ); 
    } 
} 

public void CollapseElt( CodeElement elt, CodeElements elts, long loc ) 
{ 
    EditPoint epStart = null; 
    EditPoint epEnd = null; 
    epStart = elt.StartPoint.CreateEditPoint(); 
    // Do this because we move it later.
    epEnd = elt.EndPoint.CreateEditPoint(); 
    epStart.EndOfLine(); 
    if ( ( ( elt.IsCodeType ) & ( elt.Kind !=
      vsCMElement.vsCMElementDelegate ) ) ) 
    { 
        MessageBox.Show( "got type but not a delegate, 
          named : " + elt.Name); 
        CodeType ct = null; 
        ct = ( ( EnvDTE.CodeType )( elt ) ); 
        CodeElements mems = null; 
        mems = ct.Members; 
        int i = 0; 
        for ( i=1; i<=ct.Members.Count; i++ ) 
        { 
            CollapseElt( mems.Item( i ), mems, i ); 
        } 
    } 
    else if ( ( elt.Kind == vsCMElement.vsCMElementNamespace ) ) 
    { 
        MessageBox.Show( "got a namespace, named: " + elt.Name); 
        CodeNamespace cns = null; 
        cns = ( ( EnvDTE.CodeNamespace )( elt ) ); 
        MessageBox.Show( "set cns = elt, named: " + cns.Name); 

        CodeElements mems_vb = null; 
        mems_vb = cns.Members; 
        MessageBox.Show( "got cns.members"); 
        int i = 0; 

        for ( i=1; i<=cns.Members.Count; i++ ) 
        { 
            CollapseElt( mems_vb.Item( i ), mems_vb, i ); 
        } 
    } 
}

Można zmieniać wartości elementów modelu kodu

Przypisane wartości elementów modelu kodu, takich jak klasy, struktury, funkcje, atrybuty, delegaci i tak dalej, mogą ulec zmianie po wprowadzeniu niektórych rodzajów edycji.W związku z tym, nie można zakładać, że wartości pozostaną niezmienne.

Na przykład, jeśli przypiszesz element modelu kodu do zmiennej lokalnej, a następnie ustawisz wartość właściwości dla tej zmiennej lokalnej, zmienna lokalna może nie zawierać prawidłowego elementu modelu kodu, przy późniejszym odwołaniu.W rzeczywistości może nawet zawierać inny element modelu kodu.

Rozważ klasę zawierająca funkcję o nazwie „MyFunction”, która jest przypisana do zmiennej CodeFunction, a następnie właściwość NameCodeFunction jest ustawiona na wartość „YourFunction”. Po przypisaniu zmiennej zadania, nie jest już zagwarantowane, że zmienna lokalna reprezentuje tę samą CodeFunction.Następnie dostęp do wartości właściwości może zwracać E_FAIL w wyniku.

Zalecane podejście radzenia sobie z tą sytuacją, to jasne ponowne przypisanie zmiennej lokalnej z do poprawnego elementu modelu kodu przed uzyskaniem dostępu do jego wartości właściwości.Poniższy kod przedstawia przykład sposobu wykonania. (Kod jest w formie dodatku).

Opis

Ten dodatek przedstawia właściwy sposób dostępu do wartości dla CodeElements, aby pobrać poprawną wartość.Aby uzyskać więcej informacji na temat sposobu uruchamiania przykładów, zobacz Porady: kompilowanie i uruchamianie kodu modelu obiektów automatyzacji — przykłady.

Kod

[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);
    }
}

[!UWAGA]

Ustawianie właściwości elementów podrzędnych elementu modelu kodu nie przedstawia tego zachowania.Tylko te właściwości, które mają bezpośredni wpływ na CodeElement — takie jak nazwa elementu, typ funkcji, podpis metody itd — wykazują to zachowanie nie-deterministyczne.

Ponadto, ten przykład działa tylko wtedy, gdy nowa nazwa CodeElement jest unikatowa wśród elementów równorzędnych.To dlatego, Item właściwość zwraca pierwsze dopasowanie, która nie działa dla przeciążonej metody/właściwości, częściowe klasy lub obszary nazw o tej samej nazwie.

Zobacz też

Zadania

Porady: kompilowanie przykładowego kodu dla rozszerzalności modelu kodu Visual C++

Porady: tworzenie dodatku

Wskazówki: tworzenie kreatora

Porady: manipulowanie kodem za pomocą modelu kodu Visual C++ (Visual C#)

Porady: manipulowanie kodem za pomocą modelu kodu Visual C++ (Visual Basic)

Koncepcje

Odnajdowanie kodu za pomocą modelu kodu (Visual Basic)

Model kodu Visual C++

Wykres modelu obiektów automatyzacji

Inne zasoby

Tworzenie i kontrolowanie okien środowiska

Tworzenie dodatków i kreatorów

Odwołanie do automatyzacji i rozszerzalności