Skip to content

Commit 26839f5

Browse files
authored
Merge pull request github#17882 from github/redsun82/rust-resolve
Rust: extract some resolved paths
2 parents 0610c26 + e5a199b commit 26839f5

File tree

70 files changed

+788
-309
lines changed

Some content is hidden

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

70 files changed

+788
-309
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
@@ -5,11 +5,12 @@ use crate::rust_analyzer::FileSemanticInformation;
55
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
66
use crate::trap::{Label, TrapClass};
77
use codeql_extractor::trap::{self};
8+
use itertools::Either;
89
use log::Level;
910
use ra_ap_base_db::salsa::InternKey;
1011
use ra_ap_base_db::CrateOrigin;
1112
use ra_ap_hir::db::ExpandDatabase;
12-
use ra_ap_hir::{Adt, ItemContainer, Module, Semantics, Type};
13+
use ra_ap_hir::{Adt, Crate, ItemContainer, Module, ModuleDef, PathResolution, Semantics, Type};
1314
use ra_ap_hir_def::type_ref::Mutability;
1415
use ra_ap_hir_def::ModuleId;
1516
use ra_ap_hir_expand::ExpandTo;
@@ -47,6 +48,12 @@ macro_rules! emit_detached {
4748
$self.extract_canonical_origin(&$node, $label.into());
4849
};
4950
// TODO canonical origin of other items
51+
(Path, $self:ident, $node:ident, $label:ident) => {
52+
$self.extract_canonical_destination(&$node, $label);
53+
};
54+
(MethodCallExpr, $self:ident, $node:ident, $label:ident) => {
55+
$self.extract_method_canonical_destination(&$node, $label);
56+
};
5057
($($_:tt)*) => {};
5158
}
5259

@@ -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 if self.semantics.is_some() {
288295
// let's not spam warnings if we don't have semantics, we already emitted one
@@ -381,10 +388,34 @@ impl<'a> Translator<'a> {
381388
Some(format!("{prefix}::{name}"))
382389
}
383390

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

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

0 commit comments

Comments
 (0)