mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Rust: initial extractor for expressions and patterns
This commit is contained in:
@@ -2,11 +2,16 @@ use crate::archive::Archiver;
|
||||
use crate::trap::{AsTrapKeyPart, TrapFile, TrapId};
|
||||
use crate::{generated, trap_key};
|
||||
use codeql_extractor::trap;
|
||||
use ra_ap_hir::db::DefDatabase;
|
||||
use ra_ap_hir::HasSource;
|
||||
use ra_ap_hir::TypeRef;
|
||||
use ra_ap_hir::{Crate, Module, ModuleDef};
|
||||
use ra_ap_hir_def::body::{Body, BodySourceMap};
|
||||
use ra_ap_hir_def::hir::{CaptureBy, ExprId, LabelId, MatchArm, PatId, Statement};
|
||||
use ra_ap_ide_db::line_index::LineIndex;
|
||||
use ra_ap_ide_db::{LineIndexDatabase, RootDatabase};
|
||||
use ra_ap_syntax::AstNode;
|
||||
use ra_ap_syntax::ast::RangeOp;
|
||||
use ra_ap_syntax::{AstNode, Edition};
|
||||
use ra_ap_vfs::{FileId, Vfs};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@@ -64,6 +69,77 @@ impl CrateTranslator<'_> {
|
||||
})
|
||||
}
|
||||
|
||||
fn emit_location_ast_ptr<T>(
|
||||
&mut self,
|
||||
source: ra_ap_hir::InFile<ra_ap_syntax::AstPtr<T>>,
|
||||
) -> Option<trap::Label>
|
||||
where
|
||||
T: AstNode,
|
||||
{
|
||||
source
|
||||
.file_id
|
||||
.file_id()
|
||||
.map(|f| (f.file_id(), source))
|
||||
.and_then(|(file_id, source)| self.emit_file(file_id).map(|data| (data, source)))
|
||||
.and_then(|(data, source)| {
|
||||
let range = source.value.text_range();
|
||||
let start = data.line_index.line_col(range.start());
|
||||
let end = data.line_index.line_col(range.end());
|
||||
Some(self.trap.emit_location(data.label, start, end))
|
||||
})
|
||||
}
|
||||
|
||||
fn emit_location_expr(
|
||||
&mut self,
|
||||
expr: ra_ap_hir_def::hir::ExprId,
|
||||
source_map: &BodySourceMap,
|
||||
) -> Option<trap::Label> {
|
||||
let source = source_map.expr_syntax(expr).ok()?;
|
||||
self.emit_location_ast_ptr(source)
|
||||
}
|
||||
|
||||
fn emit_location_pat(
|
||||
&mut self,
|
||||
pat_id: ra_ap_hir_def::hir::PatId,
|
||||
source_map: &BodySourceMap,
|
||||
) -> Option<trap::Label> {
|
||||
let source = source_map.pat_syntax(pat_id).ok()?;
|
||||
self.emit_location_ast_ptr(source)
|
||||
}
|
||||
|
||||
fn emit_literal_or_const_pat(
|
||||
&mut self,
|
||||
pat: &ra_ap_hir_def::hir::LiteralOrConst,
|
||||
location: Option<trap::Label>,
|
||||
body: &Body,
|
||||
source_map: &BodySourceMap,
|
||||
) -> trap::Label {
|
||||
match pat {
|
||||
ra_ap_hir_def::hir::LiteralOrConst::Literal(literal) => {
|
||||
let expr = self.trap.emit(generated::Literal {
|
||||
id: TrapId::Star,
|
||||
location: None,
|
||||
});
|
||||
self.trap.emit(generated::LitPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::LiteralOrConst::Const(inner) => {
|
||||
self.emit_pat(*inner, body, source_map)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_location_label(
|
||||
&mut self,
|
||||
label_id: ra_ap_hir_def::hir::LabelId,
|
||||
source_map: &BodySourceMap,
|
||||
) -> Option<trap::Label> {
|
||||
let source = source_map.label_syntax(label_id);
|
||||
self.emit_location_ast_ptr(source)
|
||||
}
|
||||
fn emit_location<T: HasSource>(&mut self, entity: T) -> Option<trap::Label>
|
||||
where
|
||||
T::Ast: AstNode,
|
||||
@@ -80,6 +156,671 @@ impl CrateTranslator<'_> {
|
||||
})
|
||||
}
|
||||
|
||||
fn emit_label(
|
||||
&mut self,
|
||||
label_id: LabelId,
|
||||
body: &Body,
|
||||
source_map: &BodySourceMap,
|
||||
) -> trap::Label {
|
||||
let location: Option<trap::Label> = self.emit_location_label(label_id, source_map);
|
||||
let label = &body.labels[label_id];
|
||||
self.trap.emit(generated::Label {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
name: label.name.as_str().into(),
|
||||
})
|
||||
}
|
||||
fn emit_pat(&mut self, pat_id: PatId, body: &Body, source_map: &BodySourceMap) -> trap::Label {
|
||||
let location: Option<trap::Label> = self.emit_location_pat(pat_id, source_map);
|
||||
let pat = &body.pats[pat_id];
|
||||
match pat {
|
||||
ra_ap_hir_def::hir::Pat::Missing => self.trap.emit(generated::MissingPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Pat::Wild => self.trap.emit(generated::WildPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Pat::Tuple { args, ellipsis } => {
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|pat| self.emit_pat(*pat, body, source_map))
|
||||
.collect();
|
||||
let ellipsis = ellipsis.and_then(|x| x.try_into().ok());
|
||||
self.trap.emit(generated::TuplePat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
args,
|
||||
ellipsis,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::Or(args) => {
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|pat| self.emit_pat(*pat, body, source_map))
|
||||
.collect();
|
||||
self.trap.emit(generated::OrPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
args,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::Record {
|
||||
path,
|
||||
args,
|
||||
ellipsis,
|
||||
} => self.trap.emit(generated::RecordPat {
|
||||
//TODO:
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Pat::Range { start, end } => {
|
||||
let start = start
|
||||
.as_ref()
|
||||
.map(|x| self.emit_literal_or_const_pat(x, location, body, source_map));
|
||||
let end = end
|
||||
.as_ref()
|
||||
.map(|x| self.emit_literal_or_const_pat(x, location, body, source_map));
|
||||
self.trap.emit(generated::RangePat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
start,
|
||||
end,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::Slice {
|
||||
prefix,
|
||||
slice,
|
||||
suffix,
|
||||
} => {
|
||||
let prefix = prefix
|
||||
.into_iter()
|
||||
.map(|pat| self.emit_pat(*pat, body, source_map))
|
||||
.collect();
|
||||
let slice = slice.map(|pat| self.emit_pat(pat, body, source_map));
|
||||
let suffix = suffix
|
||||
.into_iter()
|
||||
.map(|pat| self.emit_pat(*pat, body, source_map))
|
||||
.collect();
|
||||
self.trap.emit(generated::SlicePat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
prefix,
|
||||
slice,
|
||||
suffix,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::Path(path) => self.trap.emit(generated::PathPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Pat::Lit(expr) => {
|
||||
let expr = self.emit_expr(*expr, body, source_map);
|
||||
self.trap.emit(generated::LitPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::Bind { id, subpat } => {
|
||||
let subpat = subpat.map(|pat| self.emit_pat(pat, body, source_map));
|
||||
self.trap.emit(generated::BindPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
subpat,
|
||||
binding_id: body.bindings[*id].name.as_str().into(),
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::TupleStruct {
|
||||
path,
|
||||
args,
|
||||
ellipsis,
|
||||
} => self.trap.emit(generated::TupleStructPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Pat::Ref { pat, mutability } => {
|
||||
let pat = self.emit_pat(*pat, body, source_map);
|
||||
self.trap.emit(generated::RefPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
pat,
|
||||
is_mut: mutability.is_mut(),
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::Box { inner } => {
|
||||
let inner = self.emit_pat(*inner, body, source_map);
|
||||
self.trap.emit(generated::BoxPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
inner,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Pat::ConstBlock(expr) => {
|
||||
let expr = self.emit_expr(*expr, body, source_map);
|
||||
self.trap.emit(generated::ConstBlockPat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
fn emit_type_ref(
|
||||
&mut self,
|
||||
type_ref: &TypeRef, //TODO
|
||||
) -> trap::Label {
|
||||
let location: Option<trap::Label> = None; //TODO: ?
|
||||
self.trap.emit(generated::TypeRef {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
})
|
||||
}
|
||||
fn emit_match_arm(
|
||||
&mut self,
|
||||
arm: &MatchArm,
|
||||
body: &Body,
|
||||
source_map: &BodySourceMap,
|
||||
) -> trap::Label {
|
||||
let location: Option<trap::Label> = self.emit_location_pat(arm.pat, source_map);
|
||||
let pat = self.emit_pat(arm.pat, body, source_map);
|
||||
let guard = arm.guard.map(|g| self.emit_expr(g, body, source_map));
|
||||
let expr = self.emit_expr(arm.expr, body, source_map);
|
||||
self.trap.emit(generated::MatchArm {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
pat,
|
||||
guard,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
fn emit_stmt(
|
||||
&mut self,
|
||||
stmt: &Statement,
|
||||
body: &Body,
|
||||
source_map: &BodySourceMap,
|
||||
) -> trap::Label {
|
||||
match stmt {
|
||||
Statement::Let {
|
||||
pat,
|
||||
type_ref,
|
||||
initializer,
|
||||
else_branch,
|
||||
} => {
|
||||
// TODO: find a way to get the location of the entire statement
|
||||
let location = self.emit_location_pat(*pat, source_map);
|
||||
let pat = self.emit_pat(*pat, body, source_map);
|
||||
let type_ref = type_ref
|
||||
.as_ref()
|
||||
.map(|type_ref| self.emit_type_ref(type_ref));
|
||||
let initializer =
|
||||
initializer.map(|initializer| self.emit_expr(initializer, body, source_map));
|
||||
let else_ = else_branch.map(|else_| self.emit_expr(else_, body, source_map));
|
||||
|
||||
self.trap.emit(generated::IfLet {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
pat,
|
||||
type_ref,
|
||||
initializer,
|
||||
else_,
|
||||
})
|
||||
}
|
||||
Statement::Expr { expr, has_semi } => {
|
||||
let location = self.emit_location_expr(*expr, source_map);
|
||||
let expr = self.emit_expr(*expr, body, source_map);
|
||||
self.trap.emit(generated::ExprStmt {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
has_semi: *has_semi,
|
||||
})
|
||||
}
|
||||
Statement::Item => self.trap.emit(generated::ItemStmt {
|
||||
id: TrapId::Star,
|
||||
location: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
fn emit_expr(
|
||||
&mut self,
|
||||
expr_id: ExprId,
|
||||
body: &Body,
|
||||
source_map: &BodySourceMap,
|
||||
) -> trap::Label {
|
||||
let location: Option<trap::Label> = self.emit_location_expr(expr_id, source_map);
|
||||
let expr = &body[expr_id];
|
||||
match expr {
|
||||
ra_ap_hir_def::hir::Expr::Missing => self.trap.emit(generated::MissingExpr {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Expr::Path(_) => self.trap.emit(generated::Path {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Expr::If {
|
||||
condition,
|
||||
then_branch,
|
||||
else_branch,
|
||||
} => {
|
||||
let condition = self.emit_expr(*condition, &body, &source_map);
|
||||
let then = self.emit_expr(*then_branch, &body, &source_map);
|
||||
let else_ = else_branch.map(|x| self.emit_expr(x, &body, &source_map));
|
||||
self.trap.emit(generated::If {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
condition,
|
||||
then,
|
||||
else_,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Let { pat, expr } => {
|
||||
let pat = self.emit_pat(*pat, &body, &source_map);
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
self.trap.emit(generated::Let {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
pat,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Block {
|
||||
id: _,
|
||||
statements,
|
||||
tail,
|
||||
label,
|
||||
} => {
|
||||
let statements = statements
|
||||
.into_iter()
|
||||
.map(|stmt| self.emit_stmt(stmt, &body, &source_map))
|
||||
.collect();
|
||||
let tail = tail.map(|expr_id| self.emit_expr(expr_id, &body, &source_map));
|
||||
let label = label.map(|l| self.emit_label(l, &body, &source_map));
|
||||
self.trap.emit(generated::Block {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
statements,
|
||||
tail,
|
||||
label,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Async {
|
||||
id: _,
|
||||
statements,
|
||||
tail,
|
||||
} => {
|
||||
let statements = statements
|
||||
.into_iter()
|
||||
.map(|stmt| self.emit_stmt(stmt, &body, &source_map))
|
||||
.collect();
|
||||
let tail = tail.map(|expr_id| self.emit_expr(expr_id, &body, &source_map));
|
||||
self.trap.emit(generated::AsyncBlock {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
statements,
|
||||
tail,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Const(_) => self.trap.emit(generated::Const {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Expr::Unsafe {
|
||||
id: _,
|
||||
statements,
|
||||
tail,
|
||||
} => {
|
||||
let statements = statements
|
||||
.into_iter()
|
||||
.map(|stmt| self.emit_stmt(stmt, &body, &source_map))
|
||||
.collect();
|
||||
let tail = tail.map(|expr_id| self.emit_expr(expr_id, &body, &source_map));
|
||||
self.trap.emit(generated::UnsafeBlock {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
statements,
|
||||
tail,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Loop {
|
||||
body: loop_body,
|
||||
label,
|
||||
} => {
|
||||
let loop_body = self.emit_expr(*loop_body, &body, &source_map);
|
||||
let label = label.map(|l| self.emit_label(l, &body, &source_map));
|
||||
self.trap.emit(generated::Loop {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
body: loop_body,
|
||||
label,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Call {
|
||||
callee,
|
||||
args,
|
||||
is_assignee_expr,
|
||||
} => {
|
||||
let callee = self.emit_expr(*callee, &body, &source_map);
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|e| self.emit_expr(*e, &body, &source_map))
|
||||
.collect();
|
||||
self.trap.emit(generated::Call {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
callee,
|
||||
args,
|
||||
is_assignee_expr: *is_assignee_expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::MethodCall {
|
||||
receiver,
|
||||
method_name,
|
||||
args,
|
||||
generic_args, //TODO
|
||||
} => {
|
||||
let receiver = self.emit_expr(*receiver, &body, &source_map);
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|e| self.emit_expr(*e, &body, &source_map))
|
||||
.collect();
|
||||
|
||||
self.trap.emit(generated::MethodCall {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
receiver,
|
||||
method_name: method_name.as_str().into(),
|
||||
args,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Match { expr, arms } => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
let branches = arms
|
||||
.into_iter()
|
||||
.map(|e| self.emit_match_arm(e, &body, &source_map))
|
||||
.collect();
|
||||
|
||||
self.trap.emit(generated::Match {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
branches,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Continue { label } => {
|
||||
let label = label.map(|l| self.emit_label(l, &body, &source_map));
|
||||
self.trap.emit(generated::Continue {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
label,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Break { expr, label } => {
|
||||
let expr = expr.map(|e| self.emit_expr(e, &body, &source_map));
|
||||
let label = label.map(|l| self.emit_label(l, &body, &source_map));
|
||||
self.trap.emit(generated::Break {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
label,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Return { expr } => {
|
||||
let expr = expr.map(|e| self.emit_expr(e, &body, &source_map));
|
||||
self.trap.emit(generated::Return {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Become { expr } => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
self.trap.emit(generated::Become {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Yield { expr } => {
|
||||
let expr = expr.map(|e| self.emit_expr(e, &body, &source_map));
|
||||
self.trap.emit(generated::Yield {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Yeet { expr } => {
|
||||
let expr = expr.map(|e| self.emit_expr(e, &body, &source_map));
|
||||
self.trap.emit(generated::Yeet {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::RecordLit {
|
||||
path, //TODO
|
||||
fields,
|
||||
spread,
|
||||
ellipsis,
|
||||
is_assignee_expr,
|
||||
} => self.trap.emit(generated::RecordLit {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Expr::Field { expr, name } => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
self.trap.emit(generated::Field {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
name: name.as_str().into(),
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Await { expr } => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
self.trap.emit(generated::Await {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Cast { expr, type_ref } => {
|
||||
let expr: trap::Label = self.emit_expr(*expr, &body, &source_map);
|
||||
let type_ref: trap::Label = self.emit_type_ref(type_ref.as_ref());
|
||||
self.trap.emit(generated::Cast {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
type_ref,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Ref {
|
||||
expr,
|
||||
rawness,
|
||||
mutability,
|
||||
} => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
self.trap.emit(generated::Ref {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
is_mut: mutability.is_mut(),
|
||||
is_raw: rawness.is_raw(),
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Box { expr } => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
self.trap.emit(generated::Box {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::UnaryOp { expr, op } => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
let op = match op {
|
||||
ra_ap_syntax::ast::UnaryOp::Deref => "*",
|
||||
ra_ap_syntax::ast::UnaryOp::Not => "!",
|
||||
ra_ap_syntax::ast::UnaryOp::Neg => "-",
|
||||
};
|
||||
self.trap.emit(generated::UnaryOp {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
op: op.into(),
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::BinaryOp { lhs, rhs, op } => {
|
||||
let lhs = self.emit_expr(*lhs, &body, &source_map);
|
||||
let rhs = self.emit_expr(*rhs, &body, &source_map);
|
||||
let op = op.map(|op| format!("{op}"));
|
||||
self.trap.emit(generated::BinaryOp {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
lhs,
|
||||
rhs,
|
||||
op,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Range {
|
||||
lhs,
|
||||
rhs,
|
||||
range_type,
|
||||
} => {
|
||||
let lhs = lhs.map(|lhs| self.emit_expr(lhs, &body, &source_map));
|
||||
let rhs = rhs.map(|rhs| self.emit_expr(rhs, &body, &source_map));
|
||||
self.trap.emit(generated::Range {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
lhs,
|
||||
rhs,
|
||||
is_inclusive: *range_type == RangeOp::Inclusive,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Index {
|
||||
base,
|
||||
index,
|
||||
is_assignee_expr,
|
||||
} => {
|
||||
let base = self.emit_expr(*base, &body, &source_map);
|
||||
let index = self.emit_expr(*index, &body, &source_map);
|
||||
self.trap.emit(generated::Index {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
base,
|
||||
index,
|
||||
is_assignee_expr: *is_assignee_expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Closure {
|
||||
args,
|
||||
arg_types,
|
||||
ret_type,
|
||||
body: expr,
|
||||
closure_kind, //TODO:
|
||||
capture_by,
|
||||
} => {
|
||||
let expr = self.emit_expr(*expr, &body, &source_map);
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|arg| self.emit_pat(*arg, &body, &source_map))
|
||||
.collect();
|
||||
let ret_type = ret_type
|
||||
.as_ref()
|
||||
.map(|ret_type| self.emit_type_ref(ret_type));
|
||||
let arg_types = arg_types
|
||||
.into_iter()
|
||||
.map(|arg_type| {
|
||||
arg_type
|
||||
.as_ref()
|
||||
.map(|arg_type| self.emit_type_ref(arg_type))
|
||||
})
|
||||
.collect();
|
||||
self.trap.emit(generated::Closure {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
args,
|
||||
arg_types,
|
||||
body: expr,
|
||||
ret_type,
|
||||
is_move: *capture_by == CaptureBy::Value,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Tuple {
|
||||
exprs,
|
||||
is_assignee_expr,
|
||||
} => {
|
||||
let exprs = exprs
|
||||
.into_iter()
|
||||
.map(|expr| self.emit_expr(*expr, &body, &source_map))
|
||||
.collect();
|
||||
self.trap.emit(generated::Tuple {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
exprs,
|
||||
is_assignee_expr: *is_assignee_expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Array(ra_ap_hir_def::hir::Array::ElementList {
|
||||
elements,
|
||||
is_assignee_expr,
|
||||
}) => {
|
||||
let elements = elements
|
||||
.into_iter()
|
||||
.map(|expr| self.emit_expr(*expr, &body, &source_map))
|
||||
.collect();
|
||||
self.trap.emit(generated::ElementList {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
elements,
|
||||
is_assignee_expr: *is_assignee_expr,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Array(ra_ap_hir_def::hir::Array::Repeat {
|
||||
initializer,
|
||||
repeat,
|
||||
}) => {
|
||||
let initializer: trap::Label = self.emit_expr(*initializer, &body, &source_map);
|
||||
let repeat: trap::Label = self.emit_expr(*repeat, &body, &source_map);
|
||||
|
||||
self.trap.emit(generated::Repeat {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
initializer,
|
||||
repeat,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::Literal(literal) => self.trap.emit(generated::Literal {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Expr::Underscore => self.trap.emit(generated::Underscore {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
}),
|
||||
ra_ap_hir_def::hir::Expr::OffsetOf(offset) => {
|
||||
let container = self.emit_type_ref(&offset.container);
|
||||
let fields = offset.fields.iter().map(|x| x.as_str().into()).collect();
|
||||
self.trap.emit(generated::OffsetOf {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
container,
|
||||
fields,
|
||||
})
|
||||
}
|
||||
ra_ap_hir_def::hir::Expr::InlineAsm(asm) => {
|
||||
let expr = self.emit_expr(asm.e, &body, &source_map);
|
||||
self.trap.emit(generated::InlineAsm {
|
||||
id: TrapId::Star,
|
||||
location,
|
||||
expr,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_definition(
|
||||
&mut self,
|
||||
module_label: trap::Label,
|
||||
@@ -89,12 +830,15 @@ impl CrateTranslator<'_> {
|
||||
match id {
|
||||
ModuleDef::Module(_) => {}
|
||||
ModuleDef::Function(function) => {
|
||||
let def: ra_ap_hir::DefWithBody = function.into();
|
||||
let (body, source_map) = self.db.body_with_source_map(def.into());
|
||||
let txt = body.pretty_print(self.db, def.into(), Edition::Edition2021);
|
||||
println!("{}", &txt);
|
||||
|
||||
let name = function.name(self.db);
|
||||
|
||||
let location = self.emit_location(function);
|
||||
let body = self.trap.emit(generated::MissingExpr {
|
||||
id: TrapId::Star,
|
||||
location: None,
|
||||
});
|
||||
let body = self.emit_expr(body.body_expr, &body, &source_map);
|
||||
labels.push(self.trap.emit(generated::Function {
|
||||
id: trap_key![module_label, name.as_str()],
|
||||
location,
|
||||
|
||||
Reference in New Issue
Block a user