Basics
Program Elements
Types
下面是Type的几个子类
PrimitiveType: 表示Java中的原始类boolean、byte、char、double、float、int、long、shortQL中把
void和null也作为原始类
RefType: 表示引用类型(reference | non-primitive), 有如下子类ClassInterfaceEnumTypeArray
TopLevelType: 表示声明在一个编译单元最上层的引用类型(不太懂。。。)NestedType: 声明在另一个类型中的类型LocalClass: 声明在一个方法或构造函数中的类AnonymousClass: 匿名类
此外还有一些常用的类,顾名思义
TypeObject、TypeCloneable、TypeRuntime、TypeSerializable、TypeString、TypeSystem、TypeClass
examples:
查找所有double变量
import java
from Variable v, PrimitiveType pt
where pt = v.getType() and pt.hasName("double")
select v查找所有直接继承自Object的内部类
import java
from InnerClass ic
where ic.getASupertype() instanceof TypeObject
select icGenerics
GenericType表示泛型,分为 GenericInterface 或 GenericClass
比如java.util.Map这个接口
package java.util.;
public interface Map<K, V> {
int size();
// ...
}参数K、V用TypeVariable表示
泛型的参数化实例(如Map<String, File>)提供了一个具体类型(这里的String、File)来实例化类型参数,比
这里的参数化实例用ParameterizedType表示
通过getSourceDeclaration获取ParameterizedType对应的GenericType
通常,泛型可能会限制类型参数可以绑定到哪些类型,比如下面限制了一个从String到Number的map
class StringToNumMap<N extends Number> implements Map<String, N> {
// ...
}StringToNumberMap的参数化实例只能是Number或其子类
使用getATypeBound和getType来得到TypeVariable类型绑定
RawType用于处理泛型的原生类型,如下m1
Map m1 = new HashMap();
Map<String, String> m2 = new HashMap<String, String>();examples:
查找
java.util.Map的所有参数化实例
import java
from GenericInterface map, ParameterizedType pt
where
map.hasQualifiedName("java.util", "Map") and
pt.getSourceDeclaration() = map
select pt查找
java.util.Map的原生类型
import java
from Variable v, RawType rt
where rt = v.getType() and
rt.getSourceDeclaration().hasQualifiedName("java.util", "Map")
select v查找绑定到
java.lang.Object的所有泛型的类型变量
import java
from TypeVariable tv, TypeBound tb
where tb = tv.getATypeBound() and
tb.getType().hasQualifiedName("java.lang", "Object")
select tvVariables
Variable表示Java中的变量
FieldLocalVariableDeclParameter
AST
抽象语法树中的节点
statement(
Stmt)expression(
Expr)Expr.getAChildExpr返回子表达式Stmt.getAChild返回语句的下一条语句Expr.getParent、Stmt.getParent返回父节点
import java
from Expr e
where e.getParent() instanceof ReturnStmt
select e返回跟在return语句后面的表达式
比如 return x+y 返回 x+y
import java
from Stmt s
where s.getParent() instanceof IfStmt
select s返回所有if语句的then分支和else分支
import java
from Stmt s
where s.getParent() instanceof Method
select s返回所有方法体
可见Expr和Stmt的父节点不一定是Expr或Stmt,可以使用ExprParent 或 StmtParent表示Expr和Stmt可能的父节点
Metadata
元数据包括注解(annotation)和文档(javadoc)
对于packages, reference types, fields, methods, constructors, local variable declarations
这些都可以被注解,Annotatable是其父类,getAnAnnotation获取注解
寻找所有Callable(包括Method和Constructor)的注解
import java
from Callable c
select c.getAnAnnotation()寻找所有构造器中注解的@Deprecated
import java
from Constructor c, Annotation ann, AnnotationType anntp
where ann = c.getAnAnnotation() and
anntp = ann.getType() and
anntp.hasQualifiedName("java.lang", "Deprecated")
select ann寻找私有字段的文档
import java
from Field f, Javadoc jdoc
where f.isPrivate() and
jdoc = f.getDoc().getJavadoc()
select jdocCall graph
CodeQL根据Java代码生成的数据库包含了预计算的程序调用图
Callable包括方法和构造器,Call表示调用表达式(包括方法调用、new对象、用this或super的构造器调用)
下面找出println的调用点
import java
from Call c, Method m
where m = c.getCallee() and
m.hasName("println")
select cCallable.getAReference返回Call调用表达式的引用点
下面找出没被调用过的方法
import java
from Callable c
where not exists(c.getAReference())
select cLast updated
Was this helpful?