Skip to content

Commit

Permalink
Rust: extract some resolved paths
Browse files Browse the repository at this point in the history
  • Loading branch information
Paolo Tranquilli committed Oct 31, 2024
1 parent 2b37c6c commit cee2ed0
Show file tree
Hide file tree
Showing 41 changed files with 700 additions and 221 deletions.
2 changes: 1 addition & 1 deletion rust/extractor/src/generated/.generated.list

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

171 changes: 117 additions & 54 deletions rust/extractor/src/generated/top.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

113 changes: 104 additions & 9 deletions rust/extractor/src/translate/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use crate::generated::{self};
use crate::trap::{DiagnosticSeverity, TrapFile, TrapId};
use crate::trap::{Label, TrapClass};
use codeql_extractor::trap::{self};
use itertools::Either;
use log::Level;
use ra_ap_base_db::salsa::InternKey;
use ra_ap_base_db::CrateOrigin;
use ra_ap_hir::db::ExpandDatabase;
use ra_ap_hir::{Adt, ItemContainer, Module, Semantics, Type};
use ra_ap_hir::{Adt, Crate, ItemContainer, Module, ModuleDef, PathResolution, Semantics, Type};
use ra_ap_hir_def::type_ref::Mutability;
use ra_ap_hir_def::ModuleId;
use ra_ap_hir_expand::ExpandTo;
Expand Down Expand Up @@ -46,6 +47,12 @@ macro_rules! emit_detached {
$self.extract_canonical_origin(&$node, $label.into());
};
// TODO canonical origin of other items
(Path, $self:ident, $node:ident, $label:ident) => {
$self.extract_canonical_destination(&$node, $label);
};
(MethodCallExpr, $self:ident, $node:ident, $label:ident) => {
$self.extract_method_canonical_destination(&$node, $label);
};
($($_:tt)*) => {};
}

Expand Down Expand Up @@ -276,13 +283,13 @@ impl<'a> Translator<'a> {
} else {
let range = self.text_range_for_node(mcall);
self.emit_parse_error(mcall, &SyntaxError::new(
format!(
"macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected",
mcall.path().map(|p| p.to_string()).unwrap_or_default(),
kind, expand_to
),
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
));
format!(
"macro expansion failed: the macro '{}' expands to {:?} but a {:?} was expected",
mcall.path().map(|p| p.to_string()).unwrap_or_default(),
kind, expand_to
),
range.unwrap_or_else(|| TextRange::empty(TextSize::from(0))),
));
}
} else {
let range = self.text_range_for_node(mcall);
Expand Down Expand Up @@ -380,10 +387,34 @@ impl<'a> Translator<'a> {
Some(format!("{prefix}::{name}"))
}

fn canonical_path_from_module_def(&self, item: ModuleDef) -> Option<String> {
match item {
ModuleDef::Module(it) => self.canonical_path_from_hir(it),
ModuleDef::Function(it) => self.canonical_path_from_hir(it),
ModuleDef::Adt(Adt::Enum(it)) => self.canonical_path_from_hir(it),
ModuleDef::Adt(Adt::Struct(it)) => self.canonical_path_from_hir(it),
ModuleDef::Adt(Adt::Union(it)) => self.canonical_path_from_hir(it),
ModuleDef::Trait(it) => self.canonical_path_from_hir(it),
ModuleDef::Static(_) => None,
ModuleDef::TraitAlias(_) => None,
ModuleDef::TypeAlias(_) => None,
ModuleDef::BuiltinType(_) => None,
ModuleDef::Macro(_) => None,
ModuleDef::Variant(_) => None,
ModuleDef::Const(_) => None,
}
}

fn origin_from_hir<T: AstNode>(&self, item: impl AddressableHir<T>) -> String {
// if we have a Hir entity, it means we have semantics
let sema = self.semantics.as_ref().unwrap();
match item.module(sema).krate().origin(sema.db) {
self.origin_from_crate(item.module(sema).krate())
}

fn origin_from_crate(&self, item: Crate) -> String {
// if we have a Hir entity, it means we have semantics
let sema = self.semantics.as_ref().unwrap();
match item.origin(sema.db) {
CrateOrigin::Rustc { name } => format!("rustc:{}", name),
CrateOrigin::Local { repo, name } => format!(
"repo:{}:{}",
Expand All @@ -397,6 +428,24 @@ impl<'a> Translator<'a> {
}
}

fn origin_from_module_def(&self, item: ModuleDef) -> Option<String> {
match item {
ModuleDef::Module(it) => Some(self.origin_from_hir(it)),
ModuleDef::Function(it) => Some(self.origin_from_hir(it)),
ModuleDef::Adt(Adt::Enum(it)) => Some(self.origin_from_hir(it)),
ModuleDef::Adt(Adt::Struct(it)) => Some(self.origin_from_hir(it)),
ModuleDef::Adt(Adt::Union(it)) => Some(self.origin_from_hir(it)),
ModuleDef::Trait(it) => Some(self.origin_from_hir(it)),
ModuleDef::Static(_) => None,
ModuleDef::TraitAlias(_) => None,
ModuleDef::TypeAlias(_) => None,
ModuleDef::BuiltinType(_) => None,
ModuleDef::Macro(_) => None,
ModuleDef::Variant(_) => None,
ModuleDef::Const(_) => None,
}
}

pub(crate) fn extract_canonical_origin<T: AddressableAst + HasName>(
&mut self,
item: &T,
Expand All @@ -412,4 +461,50 @@ impl<'a> Translator<'a> {
Some(())
})();
}

pub(crate) fn extract_canonical_destination(
&mut self,
item: &ast::Path,
label: Label<generated::Path>,
) {
(|| {
let sema = self.semantics.as_ref()?;
let resolution = sema.resolve_path(item)?;
let PathResolution::Def(def) = resolution else {
return None;
};
let origin = self.origin_from_module_def(def)?;
let path = self.canonical_path_from_module_def(def)?;
generated::Resolvable::emit_resolved_crate_origin(
label.into(),
origin,
&mut self.trap.writer,
);
generated::Resolvable::emit_resolved_path(label.into(), path, &mut self.trap.writer);
Some(())
})();
}

pub(crate) fn extract_method_canonical_destination(
&mut self,
item: &ast::MethodCallExpr,
label: Label<generated::MethodCallExpr>,
) {
(|| {
let sema = self.semantics.as_ref()?;
let resolved = sema.resolve_method_call_fallback(item)?;
let Either::Left(function) = resolved else {
return None;
};
let origin = self.origin_from_hir(function);
let path = self.canonical_path_from_hir(function)?;
generated::Resolvable::emit_resolved_crate_origin(
label.into(),
origin,
&mut self.trap.writer,
);
generated::Resolvable::emit_resolved_path(label.into(), path, &mut self.trap.writer);
Some(())
})();
}
}
Loading

0 comments on commit cee2ed0

Please sign in to comment.