diff --git a/generator/src/ql_gen.rs b/generator/src/ql_gen.rs index c9de7749f8b..5db3b0b2189 100644 --- a/generator/src/ql_gen.rs +++ b/generator/src/ql_gen.rs @@ -204,6 +204,24 @@ fn create_token_class() -> ql::Class { ], } } + +// Creates the `ReservedWord` class. +fn create_reserved_word_class() -> ql::Class { + let db_name = "reserved_word".to_owned(); + let class_name = dbscheme_name_to_class_name(&db_name); + let describe_ql_class = create_describe_ql_class(&class_name); + ql::Class { + name: class_name, + is_abstract: false, + supertypes: vec![ + ql::Type::Normal("Token".to_owned()), + ql::Type::AtType(db_name), + ], + characteristic_predicate: None, + predicates: vec![describe_ql_class], + } +} + /// Creates a predicate whose body is `none()`. fn create_none_predicate( name: &str, @@ -482,6 +500,7 @@ pub fn convert_nodes(nodes: &Vec) -> Vec { ql::TopLevel::Import("codeql.Locations".to_owned()), ql::TopLevel::Class(create_ast_node_class()), ql::TopLevel::Class(create_token_class()), + ql::TopLevel::Class(create_reserved_word_class()), ]; let mut token_kinds = BTreeSet::new(); for node in nodes { @@ -494,8 +513,27 @@ pub fn convert_nodes(nodes: &Vec) -> Vec { for node in nodes { match &node { - node_types::Entry::Token { .. } => { - // don't generate any QL code for tokens + node_types::Entry::Token { + type_name, + kind_id: _, + } => { + if type_name.named { + let db_name = format!("token_{}", &type_name.kind); + let db_name = node_types::escape_name(&db_name); + let class_name = + dbscheme_name_to_class_name(&node_types::escape_name(&type_name.kind)); + let describe_ql_class = create_describe_ql_class(&class_name); + classes.push(ql::TopLevel::Class(ql::Class { + name: class_name, + is_abstract: false, + supertypes: vec![ + ql::Type::Normal("Token".to_owned()), + ql::Type::AtType(db_name), + ], + characteristic_predicate: None, + predicates: vec![describe_ql_class], + })); + } } node_types::Entry::Union { type_name, diff --git a/ql/src/codeql_ruby/ast.qll b/ql/src/codeql_ruby/ast.qll index cc755954f4a..d9000565764 100644 --- a/ql/src/codeql_ruby/ast.qll +++ b/ql/src/codeql_ruby/ast.qll @@ -26,6 +26,10 @@ class Token extends @token, AstNode { override string describeQlClass() { result = "Token" } } +class ReservedWord extends Token, @reserved_word { + override string describeQlClass() { result = "ReservedWord" } +} + class UnderscoreArg extends @underscore_arg, AstNode, ArgumentListChildType, ArrayChildType, AssignmentRightType, BinaryLeftType, BinaryRightType, ElementReferenceChildType, ExceptionsChildType, IfModifierConditionType, OperatorAssignmentRightType, PairKeyType, @@ -1257,3 +1261,87 @@ class Yield extends @yield, AstNode, ArgumentListChildType, ArrayChildType, Assi override AstNode getAFieldOrChild() { yield_child(this, result) } } + +class Character extends Token, @token_character { + override string describeQlClass() { result = "Character" } +} + +class ClassVariable extends Token, @token_class_variable { + override string describeQlClass() { result = "ClassVariable" } +} + +class Comment extends Token, @token_comment { + override string describeQlClass() { result = "Comment" } +} + +class Complex extends Token, @token_complex { + override string describeQlClass() { result = "Complex" } +} + +class Constant extends Token, @token_constant { + override string describeQlClass() { result = "Constant" } +} + +class EmptyStatement extends Token, @token_empty_statement { + override string describeQlClass() { result = "EmptyStatement" } +} + +class EscapeSequence extends Token, @token_escape_sequence { + override string describeQlClass() { result = "EscapeSequence" } +} + +class False extends Token, @token_false { + override string describeQlClass() { result = "False" } +} + +class Float extends Token, @token_float { + override string describeQlClass() { result = "Float" } +} + +class GlobalVariable extends Token, @token_global_variable { + override string describeQlClass() { result = "GlobalVariable" } +} + +class HeredocBeginning extends Token, @token_heredoc_beginning { + override string describeQlClass() { result = "HeredocBeginning" } +} + +class HeredocEnd extends Token, @token_heredoc_end { + override string describeQlClass() { result = "HeredocEnd" } +} + +class Identifier extends Token, @token_identifier { + override string describeQlClass() { result = "Identifier" } +} + +class InstanceVariable extends Token, @token_instance_variable { + override string describeQlClass() { result = "InstanceVariable" } +} + +class Integer extends Token, @token_integer { + override string describeQlClass() { result = "Integer" } +} + +class Nil extends Token, @token_nil { + override string describeQlClass() { result = "Nil" } +} + +class Operator extends Token, @token_operator { + override string describeQlClass() { result = "Operator" } +} + +class Self extends Token, @token_self { + override string describeQlClass() { result = "Self" } +} + +class Super extends Token, @token_super { + override string describeQlClass() { result = "Super" } +} + +class True extends Token, @token_true { + override string describeQlClass() { result = "True" } +} + +class Uninterpreted extends Token, @token_uninterpreted { + override string describeQlClass() { result = "Uninterpreted" } +}