智能感知和自动完成如何工作?

How do intellisense and autocompletions work?

我一直在想:自动完成是如何工作的?

示例: 在 PhpStorm 中,每当我使用 class 并键入 -> 时,它都会向我显示该 class 的所有属性和方法。它还自动完成命名空间,甚至是 jQuery.

等库中的函数

它 运行 是文件的某种正则表达式,还是以某种方式解析它们?

这里是 PhpStorm 开发人员。我想了解一些基础知识,以防对那些想要实现自己的插件的人有所帮助。

首先,必须使用 lexer. Then AST (an abstract syntax tree) and PSI (a program structure interface) are built using a parser 将代码分解为标记。 PhpStorm 有自己的词法分析器和解析器实现。这就是简单 class.

的 PSI 树的样子

当您在编辑器中键入内容或显式调用完成操作 (Ctrl+Space) 时,一些 completion contributors 被调用。它们旨在 return 基于光标位置的建议列表。

让我们考虑在字段引用中调用完成的情况。

PhpStorm 知道在当前位置可以建议所有 class 成员。它开始获取 class 引用(在我们的例子中是 $class 变量)并确定其类型。如果变量 resolves 到 class 其类型是 class' FQN(完全限定名称)。

要获取 class 的方法和字段,需要其 PSI 元素。特殊索引用于将 FQN 映射到适当的 PhpClass 树元素。索引最初是在第一次打开项目时构建的,并针对每个修改过的文件进行更新。

PhpStorm 从 PSI 元素(包括父元素)中收集所有成员,然后从其特征中收集。它们根据当前上下文(例如访问范围)和已键入的名称部分 (f) 进行过滤。

建议显示在一个列表中,该列表按元素名称的匹配程度、类型、位置等排序。键入时列表会重新排列。

当您按 Enter 插入元素时,PhpStorm 会调用另一个处理程序。它知道如何将元素正确地插入到代码中。例如,它可以为方法添加括号或导入 class 引用。在我们的例子中,放置方括号并在它们后面放置一个光标就足够了,因为该方法没有参数。

基本上就是这样。值得一提的是,IntelliJ IDEA 平台允许插件为上述每个步骤提供一个实现。因此可以针对某些特定的框架或语言改进或扩展完成。