代码完成如何工作?

时间:2009-08-02 22:55:37

标签: algorithm autocomplete code-completion

许多编辑器和IDE都有代码完成。其中一些非常“聪明”,其他人则不是。我对更智能的类型感兴趣。例如,我已经看到IDE只提供一个函数,如果它是a)在当前范围内可用b)它的返回值是有效的。 (例如在“5 + foo [tab]”之后,它只提供返回可以添加到正确类型的整数或变量名称的函数。)我还看到它们将更常用或更长的选项放在前面列表。

我意识到你需要解析代码。但通常在编辑当前代码时无效,其中存在语法错误。当它不完整并包含错误时,你如何解析?

还有时间限制。如果需要几秒钟来完成列表,则完成是无用的。有时,完成算法会处理数千个类。

有什么好的算法和数据结构?

3 个答案:

答案 0 :(得分:57)

答案 1 :(得分:14)

我不能确切地说出任何特定实现使用的算法,但我可以做一些有根据的猜测。对于这个问题,trie是一个非常有用的数据结构:IDE可以在项目中的所有符号的内存中维护一个大的trie,每个节点都有一些额外的元数据。

当你输入一个角色时,它沿着特里的路径走下去。特定trie节点的所有后代都是可能的完成。然后IDE只需要在当前上下文中对那些有意义的那些进行过滤,但它只需要计算在tab-completion弹出窗口中可以显示的数量。

更高级的制表符完成需要更复杂的特里。例如,Visual Assist X有一个功能,您只需要键入CamelCase符号的大写字母 - 例如,如果您键入SFN,它会在其选项卡完成窗口中显示符号SomeFunctionName。 / p>

计算trie(或其他数据结构)确实需要解析所有代码以获取项目中所有符号的列表。 Visual Studio将其存储在IntelliSense数据库中,这是一个存储在项目旁边的.ncb文件,因此每次关闭并重新打开项目时都不需要重新解析所有内容。第一次打开一个大型项目(比如一个刚刚同步的源代码控制)时,VS会花时间解析所有内容并生成数据库。

我不知道它如何处理增量变化。正如你所说,当你编写代码时,它在90%的时间内都是无效的语法,并且每当你闲置时重新编译所有内容都会对你的CPU造成巨大的负担,但收效甚微,特别是当你修改包含的头文件时大量的源文件。

我怀疑它是(a)只在实际构建项目时(或者可能在你关闭/打开它时)进行重新分析,或者(b)它进行某种本地解析,它只解析你周围的代码我只是以某种有限的方式编辑,只是为了得到相关符号的名称。由于C ++具有如此非常复杂的语法,如果你使用大量的模板元编程等,它可能在黑暗的角落表现得很奇怪。

答案 2 :(得分:1)

以下链接将帮助您进一步..

语法突出显示:Fast Colored TextBox for Syntax Highlighting