QL语言参考-4模块
模块(Modules)
模块通过将相关类型、谓词和其他模块组合在一起,提供了一种组织 QL 代码的方法。
定义模块
定义模块的方法有很多种ーー这里有一个最简单的例子,声明一个名为 Example 的显式模块,其中包含一个类 OneTwoThree:
module Example {
class OneTwoThree extends int {
OneTwoThree() {
this = 1 or this = 2 or this = 3
}
}
}
模块的名称可以是任何以大写或小写字母开头的标识符。
. ql
或.qll
文件还隐式定义模块
您还可以对模块进行注释。有关更多信息,请参阅“注释概述.”
注意:只能注释显式模块。文件模块不能被注释。
模块的种类
文件模块
每个查询文件(.ql
)和库文件(.qll
)隐式定义了一个模块。模块具有与文件相同的名称,但是文件名中的任何空格都将替换为下划线(_)。文件的内容构成了模块的主体。
图书馆单元
每个查询文件(.ql
)和库文件(.qll
)隐式定义了一个模块。模块具有与文件相同的名称,但是文件名中的任何空格都将替换为下划线(_)。文件的内容构成了模块的主体。
例如,考虑下面的QL库
OneTwoThreeLib.qll
class OneTwoThree extends int {
OneTwoThree() {
this = 1 or this = 2 or this = 3
}
}
这个文件定义了一个名为 OneTwoThreeLib 的库模块。
查询模块
一个查询模块被.ql
定义,它可以包含下面模块主体中列出的任何元素。
查询模块与其他模块稍有不同:
- 无法导入查询模块
- 查询模块的命名空间中必须至少有一个查询。这通常是一个 select 子句,但也可以是一个查询谓词。
OneTwoQuery.ql
import OneTwoThreeLib
from OneTwoThree ott
where ott = 1 or ott = 2
select ott
这个文件定义了一个名为 OneTwoQuery
的查询模块。这个模块的主体由一个 import 语句和一个 select 子句组成。
显式模块
您还可以在另一个模块中定义模块。这是一个显式的模块定义。
定义了一个显式模块,关键字模块后跟模块名称,然后模块体用括号括起来。除了选择子句之外,它可以包含下面“模块主体”中列出的任何元素。
例如,您可以将下面的 QL 代码片段添加到上面定义的库文件 OneTwoThreeLib.qll
中:
...
module M {
class OneTwo extends OneTwoThree {
OneTwo() {
this = 1 or this = 2
}
}
}
这个模块的主体定义了类 OneTwo。
模组主体
模块的主体是模块定义中的代码,例如显式模块 m 中的类 OneTwo。
一般来说,模块的主体可以包含以下结构:
- Import statements 导入语句
- Predicates 谓词
- Types 类型 ( (包括用户定义的classes)
- Aliases 别名
- Explicit modules 显式模块
- Select clauses 选择子句 (只在query module可用)
导入模块
在模块中存储代码的主要好处是可以在其他模块中重用它。若要访问外部模块的内容,可以使用 import 语句导入该模块。
当您导入模块时,除了私有名称之外,这会将其命名空间中的所有名称带入当前模块的命名空间。
导入语句
Import 语句用于导入模块,它们的格式如下:
import <module_expression1> as <name>
import <module_expression2>
Import 语句通常列在模块的开头。每个导入语句导入一个模块。可以通过包含多个导入语句来导入多个模块(每个要导入的模块有一个导入语句)。Import 语句也可以用 private 注释。
可以使用 as 关键字以不同的名称导入模块,例如将 import javascript as js
.
<module_expression>
本身可以是模块名称、选择或限定引用
有关如何查找 import
语句的信息,请参见 QL 语言规范中的“模块解析”。