다음을 통해 공유


코드 모델을 사용하여 코드 검색(Visual C#)

Visual Studio 코드 모델을 사용하면 자동화 클라이언트에서는 프로젝트에서 코드 정의를 검색하고 해당 코드 요소를 수정할 수 있습니다. 코드 편집기에서 내용을 수정하면 코드 모델은 참조된 모든 개체를 자동으로 업데이트합니다. 예를 들어, 클래스 개체를 참조하고 나중에 사용자가 새 함수를 추가하면 그 함수가 멤버 중에 표시됩니다. 코드 모델을 사용하면 자동화 클라이언트가 클래스, 인터페이스, 구조체, 메서드, 속성과 같은 상위 수준의 정의를 프로젝트에서 검색하기 위해 Visual Studio 언어에 대한 파서를 구현할 필요가 없습니다.

Visual Studio 핵심 코드 모델에는 코드의 언어 관련 영역이 포함되지 않으므로 함수의 문에 대한 개체 모델을 제공하지 않으며 매개 변수에 대한 세부 사항도 제공하지 않습니다. 매개 변수의 경우 코드 모델에서는 매개 변수의 형식과 이름만 표시되며, 매개 변수가 입력 매개 변수인지, 출력 매개 변수인지, 선택적 매개 변수인지 등에 대한 정보는 제공되지 않습니다. Visual C++에서는 Visual C++ 프로젝트를 대상으로 하는 핵심 코드 모델의 확장된 버전을 제공합니다. 자세한 내용은 Visual C++ 코드 모델을 참조하십시오.

코드 모델로 코드 검사 및 편집

코드 모델은 프로젝트의 프로그램이나 코드가 텍스트 파일로 저장된다는 점에서 기본적으로 텍스트 기반 형식을 갖습니다. 프로젝트 모델로 프로젝트 코드를 찾아 각 프로젝트 항목을 연 다음 FileCodeModel을 사용하여 프로젝트 항목에 코드가 포함되어 있는지 여부를 확인할 수 있습니다. 프로젝트 항목에 코드 요소가 포함되어 있으면 해당 요소들은 편집기에 있는 개체를 반환할 수 있으며 코드 모델은 텍스트 편집기 자동화 모델을 사용하여 코드를 수정하거나 지역화된 구문 분석을 수행할 수 있습니다. 편집기 개체 모델을 사용하면 함수 또는 클래스 수준에서 편집기의 삽입 지점이나 TextPoint 개체를 포함하는 코드 요소를 요청할 수 있습니다.

Visual Studio 핵심 코드 모델에 대한 주 진입점은 CodeModel 개체입니다. 일반 CodeElements 컬렉션은 코드 모델의 여러 위치에서 사용되며, CodeElements 수준 및 이러한 개체의 멤버를 반환하는 클래스 또는 인터페이스 수준에 하나가 있습니다. CodeElements 컬렉션의 각 요소는 CodeElement2 개체로, 각 CodeElement2 개체에는 해당 개체의 형식, 즉 해당 개체가 클래스, 인터페이스, 구조체, 함수, 속성, 변수 등인지 여부를 식별하는 Kind 속성이 있습니다.

언어 관련 코드 모델

Visual C++에서는 Visual C++ 관련 코드를 대상으로 하는 핵심 코드 모델에 대한 확장을 제공합니다. 예를 들어 Language에서 지정된 코드 요소가 Visual C++ 코드 모델 개체이고 Kind = vsCMElementClass임을 나타내는 경우 Visual Studio 코드 모델에서 CodeClass에 대해 QI(QueryInterface)를 선택하거나 Visual C++ 언어 관련 코드 모델에서 VCCodeClass에 대해 QI를 선택할 수 있습니다. Visual C++ 관련 코드 모델에 대한 자세한 내용은 방법: Visual C++ 코드 모델을 사용하여 코드 조작(Visual C#)Visual C++ 코드 모델을 참조하십시오.

Visual Studio 코드 모델에 대한 참고 사항

  • Visual C++ 코드 모델 구현으로만 Microsoft 언어 구현의 언어 관련 모델링을 수행합니다.

  • 언어에 따라서는 Visual Studio 코드 모델의 일부가 구현되지 않습니다. 예외가 발생하면 관련 도움말 항목이 표시됩니다. 코드 모델 구현 간의 차이는 대부분 언어 간의 기능상 차이로 인해 발생합니다. 예를 들어, Visual Basic 또는 Visual C#에서는 CodeNamespace 개체에 함수를 추가할 수 없습니다. 최상위 함수 정의 기능은 Visual C++에만 있기 때문입니다.

설명

이 추가 기능은 Visual Studio 파일에 있는 코드 요소를 순환하면서 작업을 수행합니다. 예제를 실행하려면 Visual Studio 코드 편집기에서 코드 파일을 열어야 합니다. 예제를 실행하는 방법에 대한 자세한 내용은 방법: 자동화 개체 모델 코드의 예제 컴파일 및 실행을 참조하십시오.

코드

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

코드 모델 요소 값이 변경될 수 있음

클래스, 구조체, 함수, 특성, 대리자 등의 코드 모델 요소에 할당된 값이 특정 편집 작업을 수행한 후에 변경될 수 있습니다. 즉, 값이 그대로 남아 있지 않을 수 있습니다.

예를 들어, 코드 모델 요소를 지역 변수에 할당하고 이 변수의 속성 값을 설정한 경우 나중에 참조하면 지역 변수에 올바른 코드 모델 요소가 들어 있지 않을 수 있습니다 . 실제로 다른 코드 모델 요소가 들어 있을 수도 있습니다.

CodeFunction 변수에 할당된 "MyFunction"이라는 함수를 포함하는 클래스에서 CodeFunction의 Name 속성이 "YourFunction"이라는 값으로 설정된 경우, 이 변수 할당 이후에 더 이상 해당 지역 변수가 동일한 CodeFunction을 나타내지 않을 수 있습니다. 나중에 속성 값에 액세스하면 결과 값으로 E_FAIL이 반환될 수 있습니다.

이 문제를 해결하려면 지역 변수의 속성 값에 액세스하기 전에 지역 변수를 올바른 코드 모델 요소로 명시적으로 다시 할당하는 것이 좋습니다. 다음 코드 예제에서는 이 작업을 수행하는 방법을 보여 줍니다. 이 코드는 추가 기능의 형식으로 제공됩니다.

설명

이 추가 기능에서는 속성 값을 검색하기 위해 CodeElements의 값에 액세스하는 방법을 보여 줍니다. 이 예제를 실행하는 방법에 대한 자세한 내용은 방법: 자동화 개체 모델 코드의 예제 컴파일 및 실행을 참조하십시오.

코드

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

참고

코드 모델 요소의 자식 요소 속성을 설정하는 경우 이러한 동작이 나타나지 않습니다. 요소 이름, 함수 형식, 메서드 시그니처 등과 같이 CodeElement에 직접 영향을 미치는 속성에서만 이러한 명확하지 않은 결과가 나타납니다.

또한 CodeElement의 새 이름이 해당 형제 요소 간에 고유할 경우에만 이 예제를 사용할 수 있습니다. Item 속성은 첫번째로 일치하는 항목을 반환하기 때문에 동일한 이름을 가진 오버로드된 메서드/속성, partial 클래스 또는 네임스페이스에서는 이 예제를 사용할 수 없습니다.

참고 항목

작업

방법: Visual C++ 코드 모델 확장성에 대한 예제 코드 컴파일

방법: 추가 기능 만들기

연습: 마법사 만들기

방법: Visual C++ 코드 모델을 사용하여 코드 조작(Visual C#)

방법: Visual C++ 코드 모델을 사용하여 코드 조작(Visual Basic)

개념

코드 모델을 사용하여 코드 검색(Visual Basic)

Visual C++ 코드 모델

자동화 개체 모델 차트

기타 리소스

환경 창 만들기 및 제어

추가 기능 및 마법사 만들기

자동화 및 확장성 참조