From 3a045ef4e5a13ad90701d1e6e3db0275dcb62e1c Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 28 May 2021 21:06:51 +0000 Subject: [PATCH 1/2] Autogenerate QLDoc for `TreeSitter.qll` --- generator/src/ql.rs | 9 + generator/src/ql_gen.rs | 24 +- ql/src/codeql_ql/ast/internal/TreeSitter.qll | 383 +++++++++++++++++++ 3 files changed, 414 insertions(+), 2 deletions(-) diff --git a/generator/src/ql.rs b/generator/src/ql.rs index b41ac8235b9..b1b2f7529d2 100644 --- a/generator/src/ql.rs +++ b/generator/src/ql.rs @@ -17,6 +17,7 @@ impl<'a> fmt::Display for TopLevel<'a> { #[derive(Clone, Eq, PartialEq, Hash)] pub struct Class<'a> { + pub qldoc: Option, pub name: &'a str, pub is_abstract: bool, pub supertypes: BTreeSet>, @@ -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, pub name: &'a str, pub overridden: bool, pub return_type: Option>, @@ -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 ")?; } diff --git a/generator/src/ql_gen.rs b/generator/src/ql_gen.rs index 3c911e52cb8..f0427c96e16 100644 --- a/generator/src/ql_gen.rs +++ b/generator/src/ql_gen.rs @@ -29,6 +29,7 @@ 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), @@ -43,10 +44,11 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> { ), }; let get_location = - create_none_predicate("getLocation", false, Some(ql::Type::Normal("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("getAFieldOrChild", false, Some(ql::Type::Normal("AstNode"))); + 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 +63,7 @@ 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 +78,7 @@ 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 +89,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 +108,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 +116,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 +124,7 @@ 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 +135,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 +157,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 +170,13 @@ fn create_reserved_word_class<'a>() -> ql::Class<'a> { /// Creates a predicate whose body is `none()`. fn create_none_predicate<'a>( + qldoc: Option, name: &'a str, overridden: bool, return_type: Option>, ) -> ql::Predicate<'a> { ql::Predicate { + qldoc: qldoc, name: name, overridden, return_type, @@ -177,6 +189,7 @@ 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 +209,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 +234,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 +434,7 @@ 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 +472,7 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec(nodes: &'a node_types::NodeTypeMap) -> Vec(nodes: &'a node_types::NodeTypeMap) -> Vec(nodes: &'a node_types::NodeTypeMap) -> Vec Date: Sat, 29 May 2021 08:09:35 +0000 Subject: [PATCH 2/2] Autoformat --- generator/src/ql_gen.rs | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/generator/src/ql_gen.rs b/generator/src/ql_gen.rs index f0427c96e16..a5c64f16714 100644 --- a/generator/src/ql_gen.rs +++ b/generator/src/ql_gen.rs @@ -29,7 +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.")), + qldoc: Some(String::from( + "Gets a string representation of this element.", + )), name: "toString", overridden: false, return_type: Some(ql::Type::String), @@ -43,10 +45,18 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> { )), ), }; - 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_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", @@ -63,7 +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.")), + 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), @@ -78,7 +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.")), + 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), @@ -124,7 +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.")), + qldoc: Some(String::from( + "Gets a string representation of this element.", + )), name: "toString", overridden: true, return_type: Some(ql::Type::String), @@ -189,7 +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.")), + 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), @@ -434,7 +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)), + qldoc: field + .name + .as_ref() + .map(|name| format!("Gets the node corresponding to the field `{}`.", name)), name: &field.getter_name, overridden: false, return_type,