mirror of
https://github.com/github/codeql.git
synced 2026-02-07 18:51:06 +01:00
Merge pull request #31 from github/autogenerate-qldoc
Autogenerate QLDoc for `TreeSitter.qll`
This commit is contained in:
@@ -17,6 +17,7 @@ impl<'a> fmt::Display for TopLevel<'a> {
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Class<'a> {
|
||||
pub qldoc: Option<String>,
|
||||
pub name: &'a str,
|
||||
pub is_abstract: bool,
|
||||
pub supertypes: BTreeSet<Type<'a>>,
|
||||
@@ -26,6 +27,9 @@ pub struct Class<'a> {
|
||||
|
||||
impl<'a> fmt::Display for Class<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(qldoc) = &self.qldoc {
|
||||
write!(f, "/** {} */", qldoc)?;
|
||||
}
|
||||
if self.is_abstract {
|
||||
write!(f, "abstract ")?;
|
||||
}
|
||||
@@ -43,6 +47,7 @@ impl<'a> fmt::Display for Class<'a> {
|
||||
f,
|
||||
" {}\n",
|
||||
Predicate {
|
||||
qldoc: None,
|
||||
name: self.name.clone(),
|
||||
overridden: false,
|
||||
return_type: None,
|
||||
@@ -176,6 +181,7 @@ impl<'a> fmt::Display for Expression<'a> {
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Predicate<'a> {
|
||||
pub qldoc: Option<String>,
|
||||
pub name: &'a str,
|
||||
pub overridden: bool,
|
||||
pub return_type: Option<Type<'a>>,
|
||||
@@ -185,6 +191,9 @@ pub struct Predicate<'a> {
|
||||
|
||||
impl<'a> fmt::Display for Predicate<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if let Some(qldoc) = &self.qldoc {
|
||||
write!(f, "/** {} */", qldoc)?;
|
||||
}
|
||||
if self.overridden {
|
||||
write!(f, "override ")?;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ pub fn write(language: &Language, classes: &[ql::TopLevel]) -> std::io::Result<(
|
||||
fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
// Default implementation of `toString` calls `this.getAPrimaryQlClass()`
|
||||
let to_string = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
"Gets a string representation of this element.",
|
||||
)),
|
||||
name: "toString",
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::String),
|
||||
@@ -42,11 +45,20 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
)),
|
||||
),
|
||||
};
|
||||
let get_location =
|
||||
create_none_predicate("getLocation", false, Some(ql::Type::Normal("Location")));
|
||||
let get_a_field_or_child =
|
||||
create_none_predicate("getAFieldOrChild", false, Some(ql::Type::Normal("AstNode")));
|
||||
let get_location = create_none_predicate(
|
||||
Some(String::from("Gets the location of this element.")),
|
||||
"getLocation",
|
||||
false,
|
||||
Some(ql::Type::Normal("Location")),
|
||||
);
|
||||
let get_a_field_or_child = create_none_predicate(
|
||||
Some(String::from("Gets a field or child node of this node.")),
|
||||
"getAFieldOrChild",
|
||||
false,
|
||||
Some(ql::Type::Normal("AstNode")),
|
||||
);
|
||||
let get_parent = ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the parent of this element.")),
|
||||
name: "getParent",
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::Normal("AstNode")),
|
||||
@@ -61,6 +73,9 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
),
|
||||
};
|
||||
let get_parent_index = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
"Gets the index of this node among the children of its parent.",
|
||||
)),
|
||||
name: "getParentIndex",
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::Int),
|
||||
@@ -75,6 +90,9 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
),
|
||||
};
|
||||
let get_a_primary_ql_class = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
"Gets the name of the primary QL class for this element.",
|
||||
)),
|
||||
name: "getAPrimaryQlClass",
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::String),
|
||||
@@ -85,6 +103,7 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
),
|
||||
};
|
||||
ql::Class {
|
||||
qldoc: Some(String::from("The base class for all AST nodes")),
|
||||
name: "AstNode",
|
||||
is_abstract: false,
|
||||
supertypes: vec![ql::Type::AtType("ast_node")].into_iter().collect(),
|
||||
@@ -103,6 +122,7 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
|
||||
fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
let tokeninfo_arity = 6;
|
||||
let get_value = ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the value of this token.")),
|
||||
name: "getValue",
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::String),
|
||||
@@ -110,6 +130,7 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
body: create_get_field_expr_for_column_storage("result", "tokeninfo", 3, tokeninfo_arity),
|
||||
};
|
||||
let get_location = ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the location of this token.")),
|
||||
name: "getLocation",
|
||||
overridden: true,
|
||||
return_type: Some(ql::Type::Normal("Location")),
|
||||
@@ -117,6 +138,9 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
body: create_get_field_expr_for_column_storage("result", "tokeninfo", 4, tokeninfo_arity),
|
||||
};
|
||||
let to_string = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
"Gets a string representation of this element.",
|
||||
)),
|
||||
name: "toString",
|
||||
overridden: true,
|
||||
return_type: Some(ql::Type::String),
|
||||
@@ -127,6 +151,7 @@ fn create_token_class<'a>() -> ql::Class<'a> {
|
||||
),
|
||||
};
|
||||
ql::Class {
|
||||
qldoc: Some(String::from("A token.")),
|
||||
name: "Token",
|
||||
is_abstract: false,
|
||||
supertypes: vec![ql::Type::AtType("token"), ql::Type::Normal("AstNode")]
|
||||
@@ -148,6 +173,7 @@ fn create_reserved_word_class<'a>() -> ql::Class<'a> {
|
||||
let class_name = "ReservedWord";
|
||||
let get_a_primary_ql_class = create_get_a_primary_ql_class(&class_name);
|
||||
ql::Class {
|
||||
qldoc: Some(String::from("A reserved word.")),
|
||||
name: class_name,
|
||||
is_abstract: false,
|
||||
supertypes: vec![ql::Type::AtType(db_name), ql::Type::Normal("Token")]
|
||||
@@ -160,11 +186,13 @@ fn create_reserved_word_class<'a>() -> ql::Class<'a> {
|
||||
|
||||
/// Creates a predicate whose body is `none()`.
|
||||
fn create_none_predicate<'a>(
|
||||
qldoc: Option<String>,
|
||||
name: &'a str,
|
||||
overridden: bool,
|
||||
return_type: Option<ql::Type<'a>>,
|
||||
) -> ql::Predicate<'a> {
|
||||
ql::Predicate {
|
||||
qldoc: qldoc,
|
||||
name: name,
|
||||
overridden,
|
||||
return_type,
|
||||
@@ -177,6 +205,9 @@ fn create_none_predicate<'a>(
|
||||
/// name.
|
||||
fn create_get_a_primary_ql_class<'a>(class_name: &'a str) -> ql::Predicate<'a> {
|
||||
ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
"Gets the name of the primary QL class for this element.",
|
||||
)),
|
||||
name: "getAPrimaryQlClass",
|
||||
overridden: true,
|
||||
return_type: Some(ql::Type::String),
|
||||
@@ -196,6 +227,7 @@ fn create_get_a_primary_ql_class<'a>(class_name: &'a str) -> ql::Predicate<'a> {
|
||||
/// `arity` - the total number of columns in the table
|
||||
fn create_get_location_predicate<'a>(def_table: &'a str, arity: usize) -> ql::Predicate<'a> {
|
||||
ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the location of this element.")),
|
||||
name: "getLocation",
|
||||
overridden: true,
|
||||
return_type: Some(ql::Type::Normal("Location")),
|
||||
@@ -220,6 +252,7 @@ fn create_get_location_predicate<'a>(def_table: &'a str, arity: usize) -> ql::Pr
|
||||
/// `def_table` - the name of the table that defines the entity and its text.
|
||||
fn create_get_text_predicate<'a>(def_table: &'a str) -> ql::Predicate<'a> {
|
||||
ql::Predicate {
|
||||
qldoc: Some(String::from("Gets the text content of this element.")),
|
||||
name: "getText",
|
||||
overridden: false,
|
||||
return_type: Some(ql::Type::String),
|
||||
@@ -419,6 +452,10 @@ fn create_field_getters<'a>(
|
||||
};
|
||||
(
|
||||
ql::Predicate {
|
||||
qldoc: field
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|name| format!("Gets the node corresponding to the field `{}`.", name)),
|
||||
name: &field.getter_name,
|
||||
overridden: false,
|
||||
return_type,
|
||||
@@ -456,6 +493,7 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
|
||||
supertypes.insert(ql::Type::AtType(&node.dbscheme_name));
|
||||
supertypes.insert(ql::Type::Normal("Token"));
|
||||
classes.push(ql::TopLevel::Class(ql::Class {
|
||||
qldoc: Some(format!("A class representing `{}` tokens.", type_name.kind)),
|
||||
name: &node.ql_class_name,
|
||||
is_abstract: false,
|
||||
supertypes,
|
||||
@@ -468,6 +506,7 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
|
||||
// It's a tree-sitter supertype node, so we're wrapping a dbscheme
|
||||
// union type.
|
||||
classes.push(ql::TopLevel::Class(ql::Class {
|
||||
qldoc: None,
|
||||
name: &node.ql_class_name,
|
||||
is_abstract: false,
|
||||
supertypes: vec![
|
||||
@@ -501,6 +540,7 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
|
||||
|
||||
let main_class_name = &node.ql_class_name;
|
||||
let mut main_class = ql::Class {
|
||||
qldoc: Some(format!("A class representing `{}` nodes.", type_name.kind)),
|
||||
name: &main_class_name,
|
||||
is_abstract: false,
|
||||
supertypes: vec![
|
||||
@@ -543,6 +583,7 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
|
||||
}
|
||||
|
||||
main_class.predicates.push(ql::Predicate {
|
||||
qldoc: Some(String::from("Gets a field or child node of this node.")),
|
||||
name: "getAFieldOrChild",
|
||||
overridden: true,
|
||||
return_type: Some(ql::Type::Normal("AstNode")),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user