Skip to content

Commit cee2ed0

Browse files
author
Paolo Tranquilli
committed
Rust: extract some resolved paths
1 parent 2b37c6c commit cee2ed0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+700
-221
lines changed

rust/extractor/src/generated/.generated.list

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/extractor/src/generated/top.rs

Lines changed: 117 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/extractor/src/translate/base.rs

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ use crate::generated::{self};
44
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
55
use crate::trap::{Label, TrapClass};
66
use codeql_extractor::trap::{self};
7+
use itertools::Either;
78
use log::Level;
89
use ra_ap_base_db::salsa::InternKey;
910
use ra_ap_base_db::CrateOrigin;
1011
use ra_ap_hir::db::ExpandDatabase;
11-
use ra_ap_hir::{Adt, ItemContainer, Module, Semantics, Type};
12+
use ra_ap_hir::{Adt, Crate, ItemContainer, Module, ModuleDef, PathResolution, Semantics, Type};
1213
use ra_ap_hir_def::type_ref::Mutability;
1314
use ra_ap_hir_def::ModuleId;
1415
use ra_ap_hir_expand::ExpandTo;
@@ -46,6 +47,12 @@ macro_rules! emit_detached {
4647
$self.extract_canonical_origin(&$node, $label.into());
4748
};
4849
// TODO canonical origin of other items
50+
(Path, $self:ident, $node:ident, $label:ident) => {
51+
$self.extract_canonical_destination(&$node, $label);
52+
};
53+
(MethodCallExpr, $self:ident, $node:ident, $label:ident) => {
54+
$self.extract_method_canonical_destination(&$node, $label);
55+
};
4956
($($_:tt)*) => {};
5057
}
5158

@@ -276,13 +283,13 @@ impl<'a> Translator<'a> {
276283
} else {
277284
let range = self.text_range_for_node(mcall);
278285
self.emit_parse_error(mcall, &SyntaxError::new(
279-
format!(
280-
"macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected",
281-
mcall.path().map(|p| p.to_string()).unwrap_or_default(),
282-
kind, expand_to
283-
),
284-
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
285-
));
286+
format!(
287+
"macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected",
288+
mcall.path().map(|p| p.to_string()).unwrap_or_default(),
289+
kind, expand_to
290+
),
291+
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
292+
));
286293
}
287294
} else {
288295
let range = self.text_range_for_node(mcall);
@@ -380,10 +387,34 @@ impl<'a> Translator<'a> {
380387
Some(format!("{prefix}::{name}"))
381388
}
382389

390+
fn canonical_path_from_module_def(&self, item: ModuleDef) -> Option<String> {
391+
match item {
392+
ModuleDef::Module(it) => self.canonical_path_from_hir(it),
393+
ModuleDef::Function(it) => self.canonical_path_from_hir(it),
394+
ModuleDef::Adt(Adt::Enum(it)) => self.canonical_path_from_hir(it),
395+
ModuleDef::Adt(Adt::Struct(it)) => self.canonical_path_from_hir(it),
396+
ModuleDef::Adt(Adt::Union(it)) => self.canonical_path_from_hir(it),
397+
ModuleDef::Trait(it) => self.canonical_path_from_hir(it),
398+
ModuleDef::Static(_) => None,
399+
ModuleDef::TraitAlias(_) => None,
400+
ModuleDef::TypeAlias(_) => None,
401+
ModuleDef::BuiltinType(_) => None,
402+
ModuleDef::Macro(_) => None,
403+
ModuleDef::Variant(_) => None,
404+
ModuleDef::Const(_) => None,
405+
}
406+
}
407+
383408
fn origin_from_hir<T: AstNode>(&self, item: impl AddressableHir<T>) -> String {
384409
// if we have a Hir entity, it means we have semantics
385410
let sema = self.semantics.as_ref().unwrap();
386-
match item.module(sema).krate().origin(sema.db) {
411+
self.origin_from_crate(item.module(sema).krate())
412+
}
413+
414+
fn origin_from_crate(&self, item: Crate) -> String {
415+
// if we have a Hir entity, it means we have semantics
416+
let sema = self.semantics.as_ref().unwrap();
417+
match item.origin(sema.db) {
387418
CrateOrigin::Rustc { name } => format!("rustc:{}", name),
388419
CrateOrigin::Local { repo, name } => format!(
389420
"repo:{}:{}",
@@ -397,6 +428,24 @@ impl<'a> Translator<'a> {
397428
}
398429
}
399430

431+
fn origin_from_module_def(&self, item: ModuleDef) -> Option<String> {
432+
match item {
433+
ModuleDef::Module(it) => Some(self.origin_from_hir(it)),
434+
ModuleDef::Function(it) => Some(self.origin_from_hir(it)),
435+
ModuleDef::Adt(Adt::Enum(it)) => Some(self.origin_from_hir(it)),
436+
ModuleDef::Adt(Adt::Struct(it)) => Some(self.origin_from_hir(it)),
437+
ModuleDef::Adt(Adt::Union(it)) => Some(self.origin_from_hir(it)),
438+
ModuleDef::Trait(it) => Some(self.origin_from_hir(it)),
439+
ModuleDef::Static(_) => None,
440+
ModuleDef::TraitAlias(_) => None,
441+
ModuleDef::TypeAlias(_) => None,
442+
ModuleDef::BuiltinType(_) => None,
443+
ModuleDef::Macro(_) => None,
444+
ModuleDef::Variant(_) => None,
445+
ModuleDef::Const(_) => None,
446+
}
447+
}
448+
400449
pub(crate) fn extract_canonical_origin<T: AddressableAst + HasName>(
401450
&mut self,
402451
item: &T,
@@ -412,4 +461,50 @@ impl<'a> Translator<'a> {
412461
Some(())
413462
})();
414463
}
464+
465+
pub(crate) fn extract_canonical_destination(
466+
&mut self,
467+
item: &ast::Path,
468+
label: Label<generated::Path>,
469+
) {
470+
(|| {
471+
let sema = self.semantics.as_ref()?;
472+
let resolution = sema.resolve_path(item)?;
473+
let PathResolution::Def(def) = resolution else {
474+
return None;
475+
};
476+
let origin = self.origin_from_module_def(def)?;
477+
let path = self.canonical_path_from_module_def(def)?;
478+
generated::Resolvable::emit_resolved_crate_origin(
479+
label.into(),
480+
origin,
481+
&mut self.trap.writer,
482+
);
483+
generated::Resolvable::emit_resolved_path(label.into(), path, &mut self.trap.writer);
484+
Some(())
485+
})();
486+
}
487+
488+
pub(crate) fn extract_method_canonical_destination(
489+
&mut self,
490+
item: &ast::MethodCallExpr,
491+
label: Label<generated::MethodCallExpr>,
492+
) {
493+
(|| {
494+
let sema = self.semantics.as_ref()?;
495+
let resolved = sema.resolve_method_call_fallback(item)?;
496+
let Either::Left(function) = resolved else {
497+
return None;
498+
};
499+
let origin = self.origin_from_hir(function);
500+
let path = self.canonical_path_from_hir(function)?;
501+
generated::Resolvable::emit_resolved_crate_origin(
502+
label.into(),
503+
origin,
504+
&mut self.trap.writer,
505+
);
506+
generated::Resolvable::emit_resolved_path(label.into(), path, &mut self.trap.writer);
507+
Some(())
508+
})();
509+
}
415510
}

0 commit comments

Comments
 (0)