CodeQL library for Java
内容提要
本文介绍CodeQL Java库,用于分析Java程序。库以QL模块实现,核心类分五类:程序元素(如类、方法)、AST节点(语句、表达式)、元数据(注解、Javadoc)、度量(如循环复杂度)和调用图。文章详述各类用途,如查询变量、类型、注解及方法调用,并强调库支持泛型、通配符等复杂类型分析,辅助代码质量检测。
延伸解读
库的模块化设计
CodeQL Java库以QL模块(.qll文件)实现,通过导入java.qll即可引入全部核心模块。这种模块化设计便于按需加载,同时保持查询的简洁性。理解这一结构有助于开发者高效组织自己的查询代码,避免重复导入。
类型系统的精细建模
库对Java类型系统进行了细致建模,区分原始类型、引用类型、泛型、通配符等。例如,ParameterizedType与GenericType分离,RawType处理遗留代码,WildcardTypeAccess支持上下界。这种精细度使得分析泛型代码成为可能,但也要求使用者熟悉这些类的区别,以免混淆。
AST与调用图分析
库提供AST节点类(Stmt、Expr)及导航谓词,便于分析语句和表达式的结构。同时,预计算的调用图信息(Call、Callable)支持分析方法调用关系,如查找未调用的方法。这些功能为代码质量检测和漏洞发现提供了基础,但需注意调用图可能不完整,结果需结合上下文解读。
Q&A
CodeQL Java库的主要作用是什么?
CodeQL Java库用于分析Java程序,它提供大量类,以面向对象形式呈现数据库中的数据,并提供抽象和谓词帮助完成常见分析任务,如查找特定元素、计算度量等。
CodeQL Java库的核心类分为哪几类?
核心类分为五类:程序元素(如类、方法)、AST节点(语句、表达式)、元数据(注解、Javadoc)、度量(如循环复杂度)和调用图。
如何使用CodeQL查询Java程序中所有int类型的变量?
可以使用如下查询:import java; from Variable v, PrimitiveType pt where pt = v.getType() and pt.hasName("int") select v。
CodeQL中如何表示泛型类型?
泛型类型由GenericType(包括GenericInterface和GenericClass)表示,类型参数由TypeVariable表示,参数化实例由ParameterizedType表示,原始类型由RawType表示,通配符由WildcardTypeAccess表示。
CodeQL中如何查找所有直接扩展Object的嵌套类?
可以使用如下查询:import java; from NestedClass nc where nc.getASupertype() instanceof TypeObject select nc。
CodeQL中如何计算方法的循环复杂度?
可以使用MetricCallable类的getCyclomaticComplexity()方法,例如:import java; from Method m, MetricCallable mc where mc = m.getMetrics() and mc.getCyclomaticComplexity() > 40 select m。
CodeQL中如何查找所有调用println方法的调用点?
可以使用如下查询:import java; from Call c, Method m where m = c.getCallee() and m.hasName("println") select c。
CodeQL中如何查找从未被调用的方法或构造函数?
可以使用如下查询:import java; from Callable c where not exists(c.getAReference()) select c。