Skip to content

Commit 571305e

Browse files
committed
Rust: extract impl, dyn, and traits
1 parent 05ba858 commit 571305e

File tree

1 file changed

+105
-25
lines changed

1 file changed

+105
-25
lines changed

rust/extractor/src/main.rs

Lines changed: 105 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use ra_ap_cfg::CfgAtom;
1010
use ra_ap_hir::db::{DefDatabase, HirDatabase};
1111
use ra_ap_hir::{DefMap, ModPath, ModuleDefId, Semantics, TypeRef, Variant};
1212
use ra_ap_hir_def::data::adt::VariantData;
13-
use ra_ap_hir_def::LocalModuleId;
13+
use ra_ap_hir_def::data::FunctionData;
14+
use ra_ap_hir_def::{AssocItemId, LocalModuleId};
1415
use ra_ap_ide_db::line_index::{LineCol, LineIndex};
1516
use ra_ap_ide_db::RootDatabase;
1617
use ra_ap_project_model::{CargoConfig, ProjectManifest};
@@ -40,6 +41,36 @@ struct Extractor<'a> {
4041
steps: Vec<ExtractionStep>,
4142
}
4243

44+
fn emit_hir_type_bound(
45+
trap: &mut TrapFile,
46+
type_bound: &ra_ap_hir_def::type_ref::TypeBound,
47+
) -> Option<trap::Label<generated::TypeBoundType>> {
48+
match type_bound {
49+
ra_ap_hir_def::type_ref::TypeBound::Path(path, _) => Some(
50+
trap.emit(generated::TraitTypeBound {
51+
id: trap::TrapId::Star,
52+
path: emit_hir_path(path),
53+
})
54+
.into(),
55+
),
56+
ra_ap_hir_def::type_ref::TypeBound::ForLifetime(names, path) => Some(
57+
trap.emit(generated::ForLifetimeTypeBound {
58+
id: trap::TrapId::Star,
59+
path: emit_hir_path(path),
60+
names: names.into_iter().map(|x| x.as_str().to_owned()).collect(),
61+
})
62+
.into(),
63+
),
64+
ra_ap_hir_def::type_ref::TypeBound::Lifetime(lifetime_ref) => Some(
65+
trap.emit(generated::LifetimeTypeBound {
66+
id: trap::TrapId::Star,
67+
name: lifetime_ref.name.as_str().to_owned(),
68+
})
69+
.into(),
70+
),
71+
ra_ap_hir_def::type_ref::TypeBound::Error => None,
72+
}
73+
}
4374
fn emit_hir_path(path: &ra_ap_hir_def::path::Path) -> Vec<String> {
4475
path.segments()
4576
.iter()
@@ -71,6 +102,27 @@ fn emit_hir_fn(
71102
has_varargs: false,
72103
})
73104
}
105+
fn emit_hir_fn_data(
106+
trap: &mut TrapFile,
107+
function: &FunctionData,
108+
) -> trap::Label<generated::FunctionType> {
109+
let params: Vec<_> = function.params.iter().map(|x| x.as_ref()).collect();
110+
let (self_type, params) = if function.has_self_param() {
111+
(Some(params[0]), &params[1..])
112+
} else {
113+
(None, &params[..])
114+
};
115+
let ret_type = function.ret_type.as_ref();
116+
emit_hir_fn(
117+
trap,
118+
self_type,
119+
params,
120+
ret_type,
121+
function.is_async(),
122+
function.is_const(),
123+
function.is_unsafe(),
124+
)
125+
}
74126
fn emit_hir_typeref(trap: &mut TrapFile, ty: &TypeRef) -> trap::Label<generated::Type> {
75127
match ty {
76128
TypeRef::Never => trap
@@ -109,7 +161,7 @@ fn emit_hir_typeref(trap: &mut TrapFile, ty: &TypeRef) -> trap::Label<generated:
109161
}
110162
TypeRef::Reference(type_ref, lifetime_ref, mutability) => {
111163
let type_ = emit_hir_typeref(trap, type_ref);
112-
let lifetime = lifetime_ref.as_ref().map(|x|x.name.as_str().to_owned());
164+
let lifetime = lifetime_ref.as_ref().map(|x| x.name.as_str().to_owned());
113165
trap.emit(generated::ReferenceType {
114166
id: trap::TrapId::Star,
115167
is_mut: mutability.is_mut(),
@@ -157,10 +209,33 @@ fn emit_hir_typeref(trap: &mut TrapFile, ty: &TypeRef) -> trap::Label<generated:
157209
})
158210
.into()
159211
}
160-
TypeRef::ImplTrait(_) | // TODO handle impl
161-
TypeRef::DynTrait(_) | // TODO handle dyn
162-
TypeRef::Macro(_) |
163-
TypeRef::Error => trap.emit(generated::ErrorType { id: trap::TrapId::Star, }) .into(),
212+
TypeRef::ImplTrait(type_bounds) => {
213+
let type_bounds = type_bounds
214+
.iter()
215+
.flat_map(|t| emit_hir_type_bound(trap, t))
216+
.collect();
217+
trap.emit(generated::ImplTraitType {
218+
id: trap::TrapId::Star,
219+
type_bounds,
220+
})
221+
.into()
222+
}
223+
TypeRef::DynTrait(type_bounds) => {
224+
let type_bounds = type_bounds
225+
.iter()
226+
.flat_map(|t| emit_hir_type_bound(trap, t))
227+
.collect();
228+
trap.emit(generated::DynTraitType {
229+
id: trap::TrapId::Star,
230+
type_bounds,
231+
})
232+
.into()
233+
}
234+
TypeRef::Macro(_) | TypeRef::Error => trap
235+
.emit(generated::ErrorType {
236+
id: trap::TrapId::Star,
237+
})
238+
.into(),
164239
}
165240
}
166241

@@ -415,25 +490,7 @@ impl<'a> Extractor<'a> {
415490
match value {
416491
ModuleDefId::FunctionId(function) => {
417492
let function = db.function_data(function);
418-
let params: Vec<_> =
419-
function.params.iter().map(|x| x.as_ref()).collect();
420-
let (self_type, params) = if function.has_self_param() {
421-
(Some(params[0]), &params[1..])
422-
} else {
423-
(None, &params[..])
424-
};
425-
let ret_type = function.ret_type.as_ref();
426-
let type_ = emit_hir_fn(
427-
trap,
428-
self_type,
429-
params,
430-
ret_type,
431-
function.is_async(),
432-
function.is_const(),
433-
function.is_unsafe(),
434-
)
435-
.into();
436-
493+
let type_ = emit_hir_fn_data(trap, &function).into();
437494
values.push(trap.emit(generated::ValueItem {
438495
id: trap::TrapId::Star,
439496
name: name.as_str().to_owned(),
@@ -571,6 +628,29 @@ impl<'a> Extractor<'a> {
571628
}
572629
}
573630
}
631+
if let ModuleDefId::TraitId(trait_id) = type_id {
632+
let data = db.trait_data(trait_id);
633+
let mut method_names = Vec::new();
634+
let mut method_types = Vec::new();
635+
for (name, item) in &data.items {
636+
if let AssocItemId::FunctionId(function) = item {
637+
method_names.push(name.as_str().to_owned());
638+
let function = db.function_data(*function);
639+
let method_type = emit_hir_fn_data(trap, &function);
640+
method_types.push(method_type);
641+
};
642+
}
643+
644+
types.push(
645+
trap.emit(generated::TraitItem {
646+
id: trap::TrapId::Star,
647+
name: name.as_str().to_owned(),
648+
method_names,
649+
method_types,
650+
})
651+
.into(),
652+
);
653+
}
574654
}
575655
}
576656
let label = trap.emit(generated::CrateModule {

0 commit comments

Comments
 (0)