mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Rust: move body skipping logic to code generation
This commit is contained in:
@@ -114,7 +114,9 @@ fn node_src_to_schema_class(
|
|||||||
let (ty, child) = match &f.ty {
|
let (ty, child) = match &f.ty {
|
||||||
FieldType::String => ("optional[string]".to_string(), false),
|
FieldType::String => ("optional[string]".to_string(), false),
|
||||||
FieldType::Predicate => ("predicate".to_string(), false),
|
FieldType::Predicate => ("predicate".to_string(), false),
|
||||||
FieldType::Optional(ty) => (format!("optional[\"{}\"]", class_name(ty)), true),
|
FieldType::Optional(ty) | FieldType::Body(ty) => {
|
||||||
|
(format!("optional[\"{}\"]", class_name(ty)), true)
|
||||||
|
}
|
||||||
FieldType::List(ty) => (format!("list[\"{}\"]", class_name(ty)), true),
|
FieldType::List(ty) => (format!("list[\"{}\"]", class_name(ty)), true),
|
||||||
};
|
};
|
||||||
SchemaField {
|
SchemaField {
|
||||||
@@ -169,6 +171,7 @@ enum FieldType {
|
|||||||
String,
|
String,
|
||||||
Predicate,
|
Predicate,
|
||||||
Optional(String),
|
Optional(String),
|
||||||
|
Body(String),
|
||||||
List(String),
|
List(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,158 +180,93 @@ struct FieldInfo {
|
|||||||
ty: FieldType,
|
ty: FieldType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FieldInfo {
|
||||||
|
pub fn optional(name: &str, ty: &str) -> FieldInfo {
|
||||||
|
FieldInfo {
|
||||||
|
name: name.to_string(),
|
||||||
|
ty: FieldType::Optional(ty.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn body(name: &str, ty: &str) -> FieldInfo {
|
||||||
|
FieldInfo {
|
||||||
|
name: name.to_string(),
|
||||||
|
ty: FieldType::Body(ty.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string(name: &str) -> FieldInfo {
|
||||||
|
FieldInfo {
|
||||||
|
name: name.to_string(),
|
||||||
|
ty: FieldType::String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn predicate(name: &str) -> FieldInfo {
|
||||||
|
FieldInfo {
|
||||||
|
name: name.to_string(),
|
||||||
|
ty: FieldType::Predicate,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn list(name: &str, ty: &str) -> FieldInfo {
|
||||||
|
FieldInfo {
|
||||||
|
name: name.to_string(),
|
||||||
|
ty: FieldType::List(ty.to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_additional_fields(node: &AstNodeSrc) -> Vec<FieldInfo> {
|
fn get_additional_fields(node: &AstNodeSrc) -> Vec<FieldInfo> {
|
||||||
match node.name.as_str() {
|
match node.name.as_str() {
|
||||||
"Name" | "NameRef" | "Lifetime" => vec![FieldInfo {
|
"Name" | "NameRef" | "Lifetime" => vec![FieldInfo::string("text")],
|
||||||
name: "text".to_string(),
|
"Abi" => vec![FieldInfo::string("abi_string")],
|
||||||
ty: FieldType::String,
|
"Literal" => vec![FieldInfo::string("text_value")],
|
||||||
}],
|
"PrefixExpr" => vec![FieldInfo::string("operator_name")],
|
||||||
"Abi" => vec![FieldInfo {
|
|
||||||
name: "abi_string".to_string(),
|
|
||||||
ty: FieldType::String,
|
|
||||||
}],
|
|
||||||
"Literal" => vec![FieldInfo {
|
|
||||||
name: "text_value".to_string(),
|
|
||||||
ty: FieldType::String,
|
|
||||||
}],
|
|
||||||
"PrefixExpr" => vec![FieldInfo {
|
|
||||||
name: "operator_name".to_string(),
|
|
||||||
ty: FieldType::String,
|
|
||||||
}],
|
|
||||||
"BinExpr" => vec![
|
"BinExpr" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("lhs", "Expr"),
|
||||||
name: "lhs".to_string(),
|
FieldInfo::optional("rhs", "Expr"),
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
FieldInfo::string("operator_name"),
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "rhs".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "operator_name".to_string(),
|
|
||||||
ty: FieldType::String,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"IfExpr" => vec![
|
"IfExpr" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("then_branch", "BlockExpr"),
|
||||||
name: "then_branch".to_string(),
|
FieldInfo::optional("else_branch", "ElseBranch"),
|
||||||
ty: FieldType::Optional("BlockExpr".to_string()),
|
FieldInfo::optional("condition", "Expr"),
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "else_branch".to_string(),
|
|
||||||
ty: FieldType::Optional("ElseBranch".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "condition".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"RangeExpr" => vec![
|
"RangeExpr" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("start", "Expr"),
|
||||||
name: "start".to_string(),
|
FieldInfo::optional("end", "Expr"),
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
FieldInfo::string("operator_name"),
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "end".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "operator_name".to_string(),
|
|
||||||
ty: FieldType::String,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"RangePat" => vec![
|
"RangePat" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("start", "Pat"),
|
||||||
name: "start".to_string(),
|
FieldInfo::optional("end", "Pat"),
|
||||||
ty: FieldType::Optional("Pat".to_string()),
|
FieldInfo::string("operator_name"),
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "end".to_string(),
|
|
||||||
ty: FieldType::Optional("Pat".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "operator_name".to_string(),
|
|
||||||
ty: FieldType::String,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"IndexExpr" => vec![
|
"IndexExpr" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("index", "Expr"),
|
||||||
name: "index".to_string(),
|
FieldInfo::optional("base", "Expr"),
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "base".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"Impl" => vec![
|
"Impl" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("trait_", "Type"),
|
||||||
name: "trait_".to_string(),
|
FieldInfo::optional("self_ty", "Type"),
|
||||||
ty: FieldType::Optional("Type".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "self_ty".to_string(),
|
|
||||||
ty: FieldType::Optional("Type".to_string()),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"ForExpr" => vec![FieldInfo {
|
"ForExpr" => vec![FieldInfo::optional("iterable", "Expr")],
|
||||||
name: "iterable".to_string(),
|
"WhileExpr" => vec![FieldInfo::optional("condition", "Expr")],
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
"MatchGuard" => vec![FieldInfo::optional("condition", "Expr")],
|
||||||
}],
|
|
||||||
"WhileExpr" => vec![FieldInfo {
|
|
||||||
name: "condition".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
}],
|
|
||||||
"MatchGuard" => vec![FieldInfo {
|
|
||||||
name: "condition".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
}],
|
|
||||||
"MacroDef" => vec![
|
"MacroDef" => vec![
|
||||||
FieldInfo {
|
FieldInfo::optional("args", "TokenTree"),
|
||||||
name: "args".to_string(),
|
FieldInfo::optional("body", "TokenTree"),
|
||||||
ty: FieldType::Optional("TokenTree".to_string()),
|
|
||||||
},
|
|
||||||
FieldInfo {
|
|
||||||
name: "body".to_string(),
|
|
||||||
ty: FieldType::Optional("TokenTree".to_string()),
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
"FormatArgsExpr" => vec![FieldInfo {
|
"FormatArgsExpr" => vec![FieldInfo::list("args", "FormatArgsArg")],
|
||||||
name: "args".to_string(),
|
"ArgList" => vec![FieldInfo::list("args", "Expr")],
|
||||||
ty: FieldType::List("FormatArgsArg".to_string()),
|
"Fn" => vec![FieldInfo::body("body", "BlockExpr")],
|
||||||
}],
|
"Const" => vec![FieldInfo::body("body", "Expr")],
|
||||||
"ArgList" => vec![FieldInfo {
|
"Static" => vec![FieldInfo::body("body", "Expr")],
|
||||||
name: "args".to_string(),
|
"ClosureExpr" => vec![FieldInfo::optional("body", "Expr")],
|
||||||
ty: FieldType::List("Expr".to_string()),
|
"ArrayExpr" => vec![FieldInfo::predicate("is_semicolon")],
|
||||||
}],
|
"SelfParam" => vec![FieldInfo::predicate("is_amp")],
|
||||||
"Fn" => vec![FieldInfo {
|
"UseTree" => vec![FieldInfo::predicate("is_star")],
|
||||||
name: "body".to_string(),
|
|
||||||
ty: FieldType::Optional("BlockExpr".to_string()),
|
|
||||||
}],
|
|
||||||
"Const" => vec![FieldInfo {
|
|
||||||
name: "body".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
}],
|
|
||||||
"Static" => vec![FieldInfo {
|
|
||||||
name: "body".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
}],
|
|
||||||
"ClosureExpr" => vec![FieldInfo {
|
|
||||||
name: "body".to_string(),
|
|
||||||
ty: FieldType::Optional("Expr".to_string()),
|
|
||||||
}],
|
|
||||||
"ArrayExpr" => vec![FieldInfo {
|
|
||||||
name: "is_semicolon".to_string(),
|
|
||||||
ty: FieldType::Predicate,
|
|
||||||
}],
|
|
||||||
"SelfParam" => vec![FieldInfo {
|
|
||||||
name: "is_amp".to_string(),
|
|
||||||
ty: FieldType::Predicate,
|
|
||||||
}],
|
|
||||||
"UseTree" => vec![FieldInfo {
|
|
||||||
name: "is_star".to_string(),
|
|
||||||
ty: FieldType::Predicate,
|
|
||||||
}],
|
|
||||||
_ => vec![],
|
_ => vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -356,6 +294,10 @@ fn get_fields(node: &AstNodeSrc) -> Vec<FieldInfo> {
|
|||||||
("ArrayExpr", "expr") // The ArrayExpr type also has an 'exprs' field
|
("ArrayExpr", "expr") // The ArrayExpr type also has an 'exprs' field
|
||||||
| ("PathSegment", "ty" | "path_type") // these are broken, handling them manually
|
| ("PathSegment", "ty" | "path_type") // these are broken, handling them manually
|
||||||
=> continue,
|
=> continue,
|
||||||
|
("Param", "pat") => {
|
||||||
|
result.push(FieldInfo::body("pat", "Pat"));
|
||||||
|
continue;
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
let ty = match field {
|
let ty = match field {
|
||||||
@@ -374,54 +316,26 @@ fn get_fields(node: &AstNodeSrc) -> Vec<FieldInfo> {
|
|||||||
}
|
}
|
||||||
for trait_ in &node.traits {
|
for trait_ in &node.traits {
|
||||||
match trait_.as_str() {
|
match trait_.as_str() {
|
||||||
"HasAttrs" => result.push(FieldInfo {
|
"HasAttrs" => result.push(FieldInfo::list("attrs", "Attr")),
|
||||||
name: "attrs".to_owned(),
|
"HasName" => result.push(FieldInfo::optional("name", "Name")),
|
||||||
ty: FieldType::List("Attr".to_owned()),
|
"HasVisibility" => result.push(FieldInfo::optional("visibility", "Visibility")),
|
||||||
}),
|
|
||||||
"HasName" => result.push(FieldInfo {
|
|
||||||
name: "name".to_owned(),
|
|
||||||
ty: FieldType::Optional("Name".to_owned()),
|
|
||||||
}),
|
|
||||||
"HasVisibility" => result.push(FieldInfo {
|
|
||||||
name: "visibility".to_owned(),
|
|
||||||
ty: FieldType::Optional("Visibility".to_owned()),
|
|
||||||
}),
|
|
||||||
"HasGenericParams" => {
|
"HasGenericParams" => {
|
||||||
result.push(FieldInfo {
|
result.push(FieldInfo::optional(
|
||||||
name: "generic_param_list".to_owned(),
|
"generic_param_list",
|
||||||
ty: FieldType::Optional("GenericParamList".to_owned()),
|
"GenericParamList",
|
||||||
});
|
));
|
||||||
result.push(FieldInfo {
|
result.push(FieldInfo::optional("where_clause", "WhereClause"))
|
||||||
name: "where_clause".to_owned(),
|
|
||||||
ty: FieldType::Optional("WhereClause".to_owned()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
"HasGenericArgs" => result.push(FieldInfo {
|
"HasGenericArgs" => {
|
||||||
name: "generic_arg_list".to_owned(),
|
result.push(FieldInfo::optional("generic_arg_list", "GenericArgList"))
|
||||||
ty: FieldType::Optional("GenericArgList".to_owned()),
|
}
|
||||||
}),
|
"HasTypeBounds" => result.push(FieldInfo::optional("type_bound_list", "TypeBoundList")),
|
||||||
"HasTypeBounds" => result.push(FieldInfo {
|
"HasModuleItem" => result.push(FieldInfo::list("items", "Item")),
|
||||||
name: "type_bound_list".to_owned(),
|
|
||||||
ty: FieldType::Optional("TypeBoundList".to_owned()),
|
|
||||||
}),
|
|
||||||
"HasModuleItem" => result.push(FieldInfo {
|
|
||||||
name: "items".to_owned(),
|
|
||||||
ty: FieldType::List("Item".to_owned()),
|
|
||||||
}),
|
|
||||||
"HasLoopBody" => {
|
"HasLoopBody" => {
|
||||||
result.push(FieldInfo {
|
result.push(FieldInfo::optional("label", "Label"));
|
||||||
name: "label".to_owned(),
|
result.push(FieldInfo::optional("loop_body", "BlockExpr"))
|
||||||
ty: FieldType::Optional("Label".to_owned()),
|
|
||||||
});
|
|
||||||
result.push(FieldInfo {
|
|
||||||
name: "loop_body".to_owned(),
|
|
||||||
ty: FieldType::Optional("BlockExpr".to_owned()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
"HasArgList" => result.push(FieldInfo {
|
"HasArgList" => result.push(FieldInfo::optional("arg_list", "ArgList")),
|
||||||
name: "arg_list".to_owned(),
|
|
||||||
ty: FieldType::Optional("ArgList".to_owned()),
|
|
||||||
}),
|
|
||||||
"HasDocComments" => {}
|
"HasDocComments" => {}
|
||||||
|
|
||||||
_ => panic!("Unknown trait {}", trait_),
|
_ => panic!("Unknown trait {}", trait_),
|
||||||
@@ -455,6 +369,7 @@ struct ExtractorNodeFieldInfo {
|
|||||||
predicate: bool,
|
predicate: bool,
|
||||||
optional: bool,
|
optional: bool,
|
||||||
list: bool,
|
list: bool,
|
||||||
|
body: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
@@ -518,6 +433,13 @@ fn field_info_to_extractor_info(name: &str, field: &FieldInfo) -> ExtractorNodeF
|
|||||||
optional: true,
|
optional: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
FieldType::Body(ty) => ExtractorNodeFieldInfo {
|
||||||
|
name,
|
||||||
|
method: field.name.clone(),
|
||||||
|
snake_case_ty: to_lower_snake_case(ty),
|
||||||
|
body: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
FieldType::List(ty) => ExtractorNodeFieldInfo {
|
FieldType::List(ty) => ExtractorNodeFieldInfo {
|
||||||
name,
|
name,
|
||||||
method: field.name.clone(),
|
method: field.name.clone(),
|
||||||
|
|||||||
@@ -34,23 +34,27 @@ impl Translator<'_> {
|
|||||||
{{#nodes}}
|
{{#nodes}}
|
||||||
|
|
||||||
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
|
pub(crate) fn emit_{{snake_case_name}}(&mut self, node: &ast::{{ast_name}}) -> Option<Label<generated::{{name}}>> {
|
||||||
if self.should_be_excluded(node) { return None; }
|
|
||||||
{{#has_attrs}}
|
{{#has_attrs}}
|
||||||
if self.should_be_excluded_attrs(node) { return None; }
|
if self.should_be_excluded(node) { return None; }
|
||||||
{{/has_attrs}}
|
{{/has_attrs}}
|
||||||
{{#fields}}
|
{{#fields}}
|
||||||
{{#predicate}}
|
let {{name}} =
|
||||||
let {{name}} = node.{{method}}().is_some();
|
{{#predicate}}
|
||||||
{{/predicate}}
|
node.{{method}}().is_some()
|
||||||
{{#string}}
|
{{/predicate}}
|
||||||
let {{name}} = node.try_get_text();
|
{{#string}}
|
||||||
{{/string}}
|
node.try_get_text()
|
||||||
{{#list}}
|
{{/string}}
|
||||||
let {{name}} = node.{{method}}().filter_map(|x| self.emit_{{snake_case_ty}}(&x)).collect();
|
{{#list}}
|
||||||
{{/list}}
|
node.{{method}}().filter_map(|x| self.emit_{{snake_case_ty}}(&x)).collect()
|
||||||
{{#optional}}
|
{{/list}}
|
||||||
let {{name}} = node.{{method}}().and_then(|x| self.emit_{{snake_case_ty}}(&x));
|
{{#optional}}
|
||||||
{{/optional}}
|
node.{{method}}().and_then(|x| self.emit_{{snake_case_ty}}(&x))
|
||||||
|
{{/optional}}
|
||||||
|
{{#body}}
|
||||||
|
if self.should_skip_bodies() { None } else { node.{{method}}().and_then(|x| self.emit_{{snake_case_ty}}(&x)) }
|
||||||
|
{{/body}}
|
||||||
|
;
|
||||||
{{/fields}}
|
{{/fields}}
|
||||||
let label = self.trap.emit(generated::{{name}} {
|
let label = self.trap.emit(generated::{{name}} {
|
||||||
id: TrapId::Star,
|
id: TrapId::Star,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use ra_ap_ide_db::RootDatabase;
|
|||||||
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
|
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
|
||||||
use ra_ap_parser::SyntaxKind;
|
use ra_ap_parser::SyntaxKind;
|
||||||
use ra_ap_span::TextSize;
|
use ra_ap_span::TextSize;
|
||||||
use ra_ap_syntax::ast::{Const, Fn, HasName, Param, Static};
|
use ra_ap_syntax::ast::HasName;
|
||||||
use ra_ap_syntax::{
|
use ra_ap_syntax::{
|
||||||
AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxNode, SyntaxToken, TextRange,
|
AstNode, NodeOrToken, SyntaxElementChildren, SyntaxError, SyntaxNode, SyntaxToken, TextRange,
|
||||||
ast,
|
ast,
|
||||||
@@ -627,7 +627,7 @@ impl<'a> Translator<'a> {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn should_be_excluded_attrs(&self, item: &impl ast::HasAttrs) -> bool {
|
pub(crate) fn should_be_excluded(&self, item: &impl ast::HasAttrs) -> bool {
|
||||||
self.semantics.is_some_and(|sema| {
|
self.semantics.is_some_and(|sema| {
|
||||||
item.attrs().any(|attr| {
|
item.attrs().any(|attr| {
|
||||||
attr.as_simple_call().is_some_and(|(name, tokens)| {
|
attr.as_simple_call().is_some_and(|(name, tokens)| {
|
||||||
@@ -637,43 +637,8 @@ impl<'a> Translator<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn should_be_excluded(&self, item: &impl ast::AstNode) -> bool {
|
pub(crate) fn should_skip_bodies(&self) -> bool {
|
||||||
if self.source_kind == SourceKind::Library {
|
self.source_kind == SourceKind::Library
|
||||||
let syntax = item.syntax();
|
|
||||||
if syntax
|
|
||||||
.parent()
|
|
||||||
.and_then(Fn::cast)
|
|
||||||
.and_then(|x| x.body())
|
|
||||||
.is_some_and(|body| body.syntax() == syntax)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if syntax
|
|
||||||
.parent()
|
|
||||||
.and_then(Const::cast)
|
|
||||||
.and_then(|x| x.body())
|
|
||||||
.is_some_and(|body| body.syntax() == syntax)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if syntax
|
|
||||||
.parent()
|
|
||||||
.and_then(Static::cast)
|
|
||||||
.and_then(|x| x.body())
|
|
||||||
.is_some_and(|body| body.syntax() == syntax)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if syntax
|
|
||||||
.parent()
|
|
||||||
.and_then(Param::cast)
|
|
||||||
.and_then(|x| x.pat())
|
|
||||||
.is_some_and(|pat| pat.syntax() == syntax)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn extract_types_from_path_segment(
|
pub(crate) fn extract_types_from_path_segment(
|
||||||
|
|||||||
486
rust/extractor/src/translate/generated.rs
generated
486
rust/extractor/src/translate/generated.rs
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user