Sdílet prostřednictvím


Zjišťování kódu pomocí modelu kódu (Visual C#)

Doplňky Visual Studio jsou ve verzi aplikace Visual Studio 2013 zastaralé.Měli byste upgradovat doplňky na rozšíření VSPackage.Další informace o upgradu viz Nejčastější dotazy: Převádění doplňků na rozšíření VSPackage.

Model kódu Visual Studio nabízí klientům automatizace možnost vyhledat definice kódu v projektu a měnit tyto prvky kódu.Model kódu automaticky aktualizuje všechny odkazované objekty při provádění změn v editoru kódu.Například pokud odkazujete na objekt třídy a uživatel později přidá novou funkci, je uvedena mezi členy.Model kódu umožňuje klientům automatizace vyhnout se implementaci analyzátoru pro jazyky Visual Studio pro zjištění definic nejvyšší úrovně v projektu, jako jsou třídy, rozhraní, struktury, metody, vlastnosti a tak dále.

Základní kódový model Visual Studio se vyhýbá oblastem kód specifickým pro jazyk, takže, například, neposkytuje objektový model pro příkazy ve funkcích ani uvádí úplné informace o parametrech.Parametry modelu kódu poskytují pouze typ a název parametru a žádné informace, o tom, zda je parametr vstup, výstup, volitelný a podobně.Visual C++ nabízí rozšířenou verzi základního modelu jádra, která je zaměřena na projekty Visual C++.Informace najdete v tématu Model kódu Visual C++.

Přezkoumání a úprava kódu pomocí modelu kódu

Model kódu je především textový v tom ohledu, že program nebo kód v projektu jsou uloženy v textových souborech.Kód projektu naleznete, když použijete model projektu k návštěvě každé položky projektu a potom zkontrolujete, zda položka projektu obsahuje kód pomocí FileCodeModel.Pokud položka projektu obsahuje prvky kódu, tyto prvky mohou vrátit objekty z editoru a model kódu může použít model automatizace editoru textu ke změně kódu nebo provedení lokalizované analýzy.Pomocí editoru objektového modelu můžete vyžádat prvek kódu obsahující kurzor editoru nebo objekt TextPoint na úrovni třídy nebo funkce.

Primární vstupní bod do základního kódového modelu aplikace Visual Studio je objekt CodeModel.Obecná kolekce CodeElements se používá na několika místech v modelu kódu.Existuje jedna na úrovni CodeElements a na úrovni třídy nebo rozhraní, která vrací členy těchto objektů.Každý prvek kolekce CodeElements je objekt CodeElement2 a každý objekt CodeElement2 má vlastnost Kind, která identifikuje jeho typ, a to podle třídy, rozhraní, struktury, funkce, vlastnosti, proměnné a tak dále.

Modely kódu specifické pro jazyk

Visual C++ poskytuje rozšíření základního kódového modelu na cílový kód, který je specifický pro Visual C++.Například pokud Language označuje, že daný prvek kódu je objekt modelu kódu Visual C++, a Kind = vsCMElementClass, pak můžete vybrat QueryInterface (QI) pro CodeClass z modelu kódu Visual Studio nebo QI pro VCCodeClass z modelu kódu specifického pro jazyk Visual C++.Další informace o modelu konkrétního kódu Visual C++ naleznete v tématech Postupy: Manipulace s kódem pomocí modelu kódu Visual C++ (Visual C#) a Model kódu Visual C++.

Poznámky k modelu kódu Visual Studio

  • Pouze implementace kódového modelu Visual C++ provádí modelování specifické pro jazyk jazykových implementací Microsoft.

  • Některé jazyky nemají implementováno celou Visual Studio modelu kódu.Témata nápovědy upozorňují na výjimky, pokud existují.Většina rozdílů mezi implementacemi modelu kódu je způsobena funkčními rozdíly mezi jazyky.Nelze například přidat funkce do objektů CodeNamespace v Visual Basic nebo Visual C#, protože pouze Visual C++ obsahuje definice funkcí na nejvyšší úrovni.

Description

Tento doplněk provede prvky kódu Visual Studio souboru.Chcete-li spustit příklad, musí mít kód soubor je otevřen v Visual Studio editor kódu.Další informace o spuštění těchto příkladů naleznete v tématu Postupy: Kompilace a spuštění příkladů kódu objektu automatizace.

Kód

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

Hodnoty prvků modelu kódu lze změnit

Přiřazené hodnoty prvků kódového modelu jako třídy, struktury, funkce, atributy, delegáty a tak dále se mohou po provedení určitých typů úprav změnit.V důsledku toho nelze předpokládat, že hodnoty zůstanou statické.

Pokud například přiřadíte prvek modelu kódu lokální proměnné, a pak nastavíte hodnotu vlastnosti pro tuto místní proměnnou, místní proměnná nesmí obsahovat prvek modelu platného kódu, když na ni později odkazujete.Ve skutečnosti může dokonce obsahovat jiný prvek modelu kódu.

Zvažte třídu obsahující funkci s názvem "MáFunkce", která je přiřazena k proměnné CodeFunction a pak vlastnost Name funkce CodeFunction je nastavena na hodnotu "YourFunction". Po přiřazení této proměnné již není zaručeno, že místní proměnná představuje stejné CodeFunction.Následný přístup k hodnotě vlastnosti může vrátit E_FAIL jako výsledek.

Doporučený postup pro řešení této situace je explicitně přiřadit místní proměnnou ke správnému prvku kódového modelu před přístupem k jeho hodnotám vlastností.Následuje příklad, jak to provést. (Kód je ve formě doplňku).

Description

Tento doplněk ukazuje správný způsob, jak získat přístup k hodnotám pro CodeElements tak, aby se načetla správná hodnota.Další informace o spuštění těchto příkladů naleznete v tématu Postupy: Kompilace a spuštění příkladů kódu objektu automatizace.

Kód

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

[!POZNÁMKA]

Nastavování vlastností podřízených prvků prvku modelu kódu toto chování neprojevuje.Pouze vlastnosti, které mají bezprostřední vliv na CodeElement – například název prvku, typ funkce, podpis metody, atd. – projevují toto nedeterministické chování.

Tento příklad funguje pouze tehdy, pokud nový název CodeElement je jedinečný mezi prvky na stejné úrovni.Důvodem je, že vlastnost Item vrací první shodu, což nefunguje pro přetížené metody/vlastnosti, částečné třídy ani obory názvů se stejným názvem.

Viz také

Úkoly

Postupy: Kompilace ukázkového kódu pro rozšíření modelu kódu Visual C++

Postupy: Vytvoření doplňku

Návod: Vytvoření průvodce

Postupy: Manipulace s kódem pomocí modelu kódu Visual C++ (Visual C#)

Postupy: Manipulace s kódem pomocí modelu kódu Visual C++ (Visual Basic)

Koncepty

Zjišťování kódu pomocí modelu kódu (Visual Basic)

Model kódu Visual C++

Graf modelu objektů automatizace

Další zdroje

Vytváření a řízení oken prostředí

Vytváření doplňků a průvodců

Referenční dokumentace automatizace a rozšíření