2013-04-08 1 views
9

나는 libclang으로 코드 완성을하는 법을 이해하려고 노력하고있다. 나는 "컴파일러를 뛰어 넘는 사고"를 보았고 c-index-test를 살펴본 결과 간단한 샘플 프로그램을 발견했다. herelibclang이 의미있는 완료 결과를 반환하지 않는 이유는 무엇입니까?

나는이 프로그램을 컴파일하고이 샘플 파일에서 실행했다.

struct List { 
    int Data; 
    struct List *Next; 
}; 

int sumListNode(struct List *Node) { 
    int result = 0; 
    for (; Node; Node = Node->Next) 
     result = result + Node-> 
} 

void test() { 
    sumLi 
} 

내가 노드 - 후 첫 불완전 공간>에서 프로그램을 가리키면, 그것은 몇 가지 C 키워드를 내뿜으며,하지만 비디오와 같은 다음 또는 데이터 뱉어하지 않습니다 비디오에서 하나의 유사 그것이해야한다고 말한다.

sumLi 다음에 공백을 가리키면 동일한 C 키워드가 인쇄됩니다. sumLi에 's'가있는 열을 가리키면 sumListNode를 인쇄 할 수 있지만 그 다음에는 다른 키워드와 동일한 우선 순위 값을 지정하여 실제로 모든 것을 인쇄합니다. 커서 아래에있는 것을 읽고 현명한 추측을하기보다는 그곳에 놓을 수 있습니다. 나는 끝 부분 대신 단편의 시작 부분에 커서를 놓으면 어쨌든 도움이 될 것으로 기대하면서 빨대를 쥐고있었습니다.

libclang이 나에게 줄 수있는 데이터의 유형과 doxygen에서 작동하는 방법 및 c-index-test에서 파고 들기위한 방법을 많이 배웠습니다. 관련 데이터를 제공하므로 작업 할 항목이 있습니다.

답변

9

먼저 오류가 발생하면 코드에서 clang이 손실 될 수 있으므로 번역 단위로 CXDiagnostic 출력을 인쇄해야합니다 (언급 한 매우 간단한 경우는 거의 없습니다).

둘째, libclang은 익숙하지 않은 다른 방법으로 라인 및 컬럼 번호를 정의합니다 (즉, 텍스트 편집기에서 줄/줄 정보를 얻는 경우 col에 1을 더해야 할 수도 있습니다 번호는 clang의 정의와 일치해야 함).

셋째로, clang 컴파일러를 사용하여 컴파일 옵션 및 행/열 정보의 유효성을 테스트 할 수 있습니다. 이렇게하면 libclang 기반 코드로 인한 불확실성을 제거 할 수 있습니다. 예 : 다음 명령 줄을 사용

clang++ -cc1 -fsyntax-only -code-completion-at FILENAME:LINE:COL CLANG_ARGS 
또한

clang_codeCompleteAt이 토큰의 시작 부분에만 호출을 의미하고 가능한 모든 토큰의 목록을 생성되어 있습니다, 클라이언트는 필터링을 담당하고있는 잠재적 인 부분 토큰이 이미 텍스트 편집기에 입력 된 결과. 문서에서

(강조는 광산) :

가 번역 단위에서 주어진 위치에서 코드 완성 기능을 수행합니다.

이 함수는 소스 코드 내의 특정 파일, 행 및 열에서 코드 완성을 수행하여 완성 컨텍스트를 기반으로 잠재적 코드 조각을 제안하는 결과를 제공합니다. 코드 완성을위한 기본 모델은 Clang이 완전한 소스 파일을 구문 분석하여 코드 완성이 요청 된 위치까지 구문 검사를 수행한다는 것입니다. 이 시점에서 특수한 코드 완성 토큰이 파서에 전달되어 파서는이 토큰을 인식하고 C/Objective-C/C++ 문법의 현재 위치 및 의미 분석 상태에 따라 제공 할 완료를 결정합니다. 이러한 완료는 새로운 CXCodeCompleteResults 구조를 통해 반환됩니다.

코드 완성 자체는 사용자가 구두점 문자 또는 공백 문자을 입력 할 때 클라이언트에 의해 트리거 될 것입니다.이 시점에서 코드 완성 위치는 커서와 일치합니다. 예를 들어 p가 포인터이면 "-"다음에 ">"다음에 코드 완성이 트리거 될 수 있습니다. 코드 완성 위치가 ">"인 경우 완료 결과는 예를 들어 "p"가 가리키는 구조체의 멤버를 제공합니다. 클라이언트는 현재 입력 된 토큰의 시작 부분에 커서를 놓은 다음 토큰 내용에 따라 결과를 필터링합니다.. 예를 들어, p-> get 표현식을 코드 완성하면 클라이언트는이 코드 완성 후크에 ">"직후에 위치를 제공해야합니다 (예 : "g"를 가리킴). 그런 다음 클라이언트는 현재 토큰 텍스트 ("get")를 기반으로 결과를 필터링 할 수 있으며 "get"로 시작하는 결과 만 표시합니다. 이 인터페이스의 목적은 상대적으로 높은 대기 시간의 코드 완성 결과 획득과 문자 당 기준의 결과 필터링을 분리하는 것입니다. 대기 시간은 더 짧아야합니다.

수정 된 제 복용 예 :

int main (int argc, char **argv) { 
    int i = sumLi 
    // ^
} 

코드 완료가 표시된 위치에서 호출되어야한다 (즉, 토큰의 시작 부분). 연타는 예를 들어 포함한 결과의 긴 목록 줄 수 :

  • argc
  • sumListNode(<# struct List *Node #>)

그것은에 따라이 목록을 필터링 할 당신까지 다음이다가 부분적으로 토큰 sumLi을 입력을하고 계속 관련 완료 만 : sumListNode.

trunk/utils/clang-completion-mode.el

+0

감사합니다 : 당신이 elisp 이해한다면

는 그 소리의 근원은이 두 가지 수준의 구현의 좋은 예입니다 이맥스에 대한 자동 완성 기능 라이브러리를 포함! 그것은 내 문제를 거의 해결했다. 내 텍스트 편집기에서 노드 -> (여기) 열 33입니다 말한다. 그러나 clang 자체를 실행하면 거기에 아무것도 열 27에 대한 오류를 넣습니다. 마치 한 열로 탭을 계산합니다. 두 번째 예제의 경우, 예상되는 'sumListNodes'대신 많은 키워드를 인쇄합니다. 그들 사이에 공간이 없으면 Clang의 제안은 컴파일되지 않습니다. 나는 단지 전체 칼럼을 가로 질러 그것을 시도했다. 나는 실제적인 가능성을 분류하는 것이 나에게 맞는 것 같아요? – John

+0

죄송하지만, test.c를 편집하여 그 시점에서 정수 값이 예상되고 구조체 List가 범위에서 선언되도록 추가해야합니다. clang이 이해할 수있는 실제 세계가 있는지 확인하기 만하면됩니다. 그것은 아직도 내가 기대하고 있었던 것을 아주주지 않았다. 예를 들어 int i = sumLilong은 컴파일되지 않지만 sumListNodes와 동일한 우선 순위를 갖는 제안으로 'long'을 제공합니다. – John

+0

나는 그 질문에 대답하려고 내 대답을 편집했다. – Francesco

관련 문제