diff --git a/extractor/src/extractor.rs b/extractor/src/extractor.rs index ffe69820523..a55c68830e1 100644 --- a/extractor/src/extractor.rs +++ b/extractor/src/extractor.rs @@ -2,7 +2,6 @@ use node_types::{EntryKind, Field, NodeTypeMap, Storage, TypeName}; use std::collections::BTreeMap as Map; use std::collections::BTreeSet as Set; use std::fmt; -use std::ops::Range; use std::path::Path; use tracing::{error, info, span, Level}; use tree_sitter::{Language, Node, Parser, Tree}; @@ -251,7 +250,7 @@ struct ChildNode { field_name: Option<&'static str>, label: Label, type_name: TypeName, - src_range: Range, + text: &'static str, } struct Visitor<'a> { @@ -388,7 +387,7 @@ impl Visitor<'_> { kind: node.kind().to_owned(), named: node.is_named(), }, - src_range: node.byte_range(), + text: node.kind(), }); }; } @@ -401,11 +400,7 @@ impl Visitor<'_> { child_nodes: &Vec, parent_id: Label, ) -> Option> { - enum ChildValue { - Label(Label), - Int(usize), - } - let mut map: Map<&Option, (&Field, Vec)> = Map::new(); + let mut map: Map<&Option, (&Field, Vec)> = Map::new(); for field in fields { map.insert(&field.name, (field, Vec::new())); } @@ -413,30 +408,16 @@ impl Visitor<'_> { if let Some((field, values)) = map.get_mut(&child_node.field_name.map(|x| x.to_owned())) { //TODO: handle error and missing nodes - if let node_types::FieldTypeInfo::ReservedWordInt(int_mapping) = &field.type_info { - // For this field, we look up the string value in - // `int_mapping` and emit the corresponding integer instead. - let field_text = String::from_utf8_lossy( - &self.source[child_node.src_range.start..child_node.src_range.end], - ) - .into_owned(); - match int_mapping.get(&field_text) { - Some((value, _)) => { - values.push(ChildValue::Int(*value)); - } - None => { - error!( - "{}:{}: missing integer mapping for field {}::{} with value {}", - &self.path, - node.start_position().row + 1, - node.kind(), - child_node.field_name.unwrap_or("child"), - field_text, - ); - } + if self.type_matches(&child_node.type_name, &field.type_info) { + if let node_types::FieldTypeInfo::ReservedWordInt(int_mapping) = + &field.type_info + { + // We can safely unwrap because type_matches checks the key is in the map. + let (int_value, _) = int_mapping.get(child_node.text).unwrap(); + values.push(Arg::Int(*int_value)); + } else { + values.push(Arg::Label(child_node.label)); } - } else if self.type_matches(&child_node.type_name, &field.type_info) { - values.push(ChildValue::Label(child_node.label)); } else if field.name.is_some() { error!( "{}:{}: type mismatch for field {}::{} with type {:?} != {:?}", @@ -468,10 +449,7 @@ impl Visitor<'_> { match &field.storage { Storage::Column { name: column_name } => { if child_values.len() == 1 { - args.push(match child_values.first().unwrap() { - ChildValue::Label(label) => Arg::Label(*label), - ChildValue::Int(value) => Arg::Int(*value), - }); + args.push(child_values.first().unwrap().clone()); } else { is_valid = false; error!( @@ -508,10 +486,7 @@ impl Visitor<'_> { if *has_index { args.push(Arg::Int(index)) } - args.push(match child_value { - ChildValue::Label(label) => Arg::Label(*label), - ChildValue::Int(value) => Arg::Int(*value), - }); + args.push(child_value.clone()); self.trap_writer.add_tuple(&table_name, args); } } @@ -543,7 +518,9 @@ impl Visitor<'_> { return self.type_matches_set(tp, types); } - node_types::FieldTypeInfo::ReservedWordInt(_) => panic!("???"), + node_types::FieldTypeInfo::ReservedWordInt(int_mapping) => { + return !tp.named && int_mapping.contains_key(&tp.kind) + } } false } @@ -702,7 +679,7 @@ impl fmt::Display for Index { } // Some untyped argument to a TrapEntry. -#[derive(Debug)] +#[derive(Debug, Clone)] enum Arg { Label(Label), Int(usize), diff --git a/generator/src/main.rs b/generator/src/main.rs index 48c5c87cdad..c79a2397e9a 100644 --- a/generator/src/main.rs +++ b/generator/src/main.rs @@ -54,7 +54,7 @@ fn make_field_type<'a>( name: parent_name, column: match &field.storage { node_types::Storage::Column { name } => name, - node_types::Storage::Table { name, has_index: _ } => name, + node_types::Storage::Table { name, .. } => name, }, branches, }); diff --git a/generator/src/ql_gen.rs b/generator/src/ql_gen.rs index 8ff4c91ef46..ed6567face4 100644 --- a/generator/src/ql_gen.rs +++ b/generator/src/ql_gen.rs @@ -307,8 +307,8 @@ fn create_field_getters<'a>( node_types::FieldTypeInfo::ReservedWordInt(_) => Some(ql::Type::String), }; let formal_parameters = match &field.storage { - node_types::Storage::Column { name: _ } => vec![], - node_types::Storage::Table { name: _, has_index } => { + node_types::Storage::Column { .. } => vec![], + node_types::Storage::Table { has_index, .. } => { if *has_index { vec![ql::FormalParameter { name: "i", diff --git a/node-types/src/lib.rs b/node-types/src/lib.rs index d4dd7d6aef5..b29ebed46ad 100644 --- a/node-types/src/lib.rs +++ b/node-types/src/lib.rs @@ -104,7 +104,7 @@ pub fn convert_nodes(nodes: &Vec) -> NodeTypeMap { // First, find all the token kinds for node in nodes { - if let None = &node.subtypes { + if node.subtypes.is_none() { if node.fields.as_ref().map_or(0, |x| x.len()) == 0 && node.children.is_none() { let type_name = TypeName { kind: node.kind.clone(),