2013-04-08 50 views
9

我想了解如何使用libclang完成代碼完成。我看過「思考超越編譯器」,我已經看過c-index-test,並且我找到了一個簡單的示例程序here爲什麼不是libclang返回有意義的完成結果?

我編譯了該程序,並將其運行在此示例文件上,類似於一個視頻:

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

首先,您應該嘗試打印翻譯單元輸出的任何CXDiagnostic,因爲任何錯誤都可能導致clang在代碼中丟失(在您提到的非常簡單的情況下,這種情況不太可能發生)。其次,請注意,libclang以與您習慣的方式不同的方式定義了行號和列號(例如,如果您從文本編輯器獲取行/列信息,則可能必須將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」指向的結構的成員。 客戶端負責將光標置於當前鍵入的令牌的開頭,然後根據令牌的內容對結果進行過濾。例如,當表達式p-> get的代碼完成時,客戶端應該在「>」之後提供位置(例如,指向「g」)到這個代碼完成鉤子。然後,客戶端可以根據當前標記文本(「get」)過濾結果,僅顯示以「get」開頭的結果。 這個接口的目的是將相對高延遲的代碼完成結果從每個字符的結果過濾中分離出來,這個結果必須有較低的延遲。

以你的經修改的第二示例:

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

代碼完成應當在標記的位置被調用(即,在令牌的開始)。然後鏘可以給結果,包括例如一個長長的清單:

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

然後由你來篩選基於此列表中的部分輸入sumLi令牌和保持只有相關的完成:sumListNode

如果你瞭解的elisp,鐺的來源包含的Emacs自動完成庫,它是這兩個級別實現的一個很好的例子:

trunk/utils/clang-completion-mode.el

+0

謝謝!這幾乎解決了我的問題。我的文本編輯器說,Node - >(這裏)是第33列。然而,運行clang本身會在第27列顯示沒有任何內容的錯誤。看起來它會將製表符視爲單個列。對於第二個例子,它仍然打印出很多關鍵字,而不是僅僅是預期的'sumListNodes'。他們之間沒有空間,Clang的建議就不會編譯。我試過整個專欄中的那一個,只是爲了確定。我想這是爲了理清實際的可能性嗎? – John 2013-04-08 16:54:11

+0

糟糕,我應該補充一點,我編輯了test.c,以便在這一點上可以預期一個整數值,並且在範圍內聲明一個struct List。只是爲了確定clang能夠理解的真實世界背景。它仍然沒有給我很多我期待的。例如,int i = sumLilong將不會編譯,但它將「long」作爲與sumListNodes同等優先級的建議。 – John 2013-04-08 16:57:16

+0

我編輯了我的答案,嘗試回答這些問題。 – Francesco 2013-04-09 06:41:14

相關問題