Skip to content

Commit

Permalink
Merge 6cf7938 into 656a7d6
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite authored Aug 21, 2024
2 parents 656a7d6 + 6cf7938 commit 857d16e
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 72 deletions.
3 changes: 0 additions & 3 deletions compiler/noirc_frontend/src/elaborator/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ impl<'context> Elaborator<'context> {
resolver.resolve(self.def_maps, path.clone(), &mut Some(&mut references))?;

for (referenced, segment) in references.iter().zip(path.segments) {
let Some(referenced) = referenced else {
continue;
};
self.interner.add_reference(
*referenced,
Location::new(segment.ident.span(), self.file),
Expand Down
18 changes: 11 additions & 7 deletions compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use crate::hir::Context;

use crate::macros_api::{MacroError, MacroProcessor};
use crate::node_interner::{
FuncId, GlobalId, NodeInterner, ReferenceId, StructId, TraitId, TraitImplId, TypeAliasId,
FuncId, GlobalId, ModuleAttributes, NodeInterner, ReferenceId, StructId, TraitId, TraitImplId,
TypeAliasId,
};

use crate::ast::{
Expand Down Expand Up @@ -269,11 +270,17 @@ impl DefCollector {
macro_processors,
));

let dep_def_root =
context.def_map(&dep.crate_id).expect("ice: def map was just created").root;
let dep_def_map =
context.def_map(&dep.crate_id).expect("ice: def map was just created");

let dep_def_root = dep_def_map.root;
let module_id = ModuleId { krate: dep.crate_id, local_id: dep_def_root };
// Add this crate as a dependency by linking it's root module
def_map.extern_prelude.insert(dep.as_name(), module_id);

let location = dep_def_map[dep_def_root].location;
let attriutes = ModuleAttributes { name: dep.as_name(), location, parent: None };
context.def_interner.add_module_attributes(module_id, attriutes);
}

// At this point, all dependencies are resolved and type checked.
Expand Down Expand Up @@ -309,7 +316,7 @@ impl DefCollector {
for collected_import in std::mem::take(&mut def_collector.imports) {
let module_id = collected_import.module_id;
let resolved_import = if context.def_interner.lsp_mode {
let mut references: Vec<Option<ReferenceId>> = Vec::new();
let mut references: Vec<ReferenceId> = Vec::new();
let resolved_import = resolve_import(
crate_id,
&collected_import,
Expand All @@ -322,9 +329,6 @@ impl DefCollector {

for (referenced, segment) in references.iter().zip(&collected_import.path.segments)
{
let Some(referenced) = referenced else {
continue;
};
context.def_interner.add_reference(
*referenced,
Location::new(segment.ident.span(), file_id),
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ impl<'a> ModCollector<'a> {
ModuleAttributes {
name: mod_name.0.contents.clone(),
location: mod_location,
parent: self.module_id,
parent: Some(self.module_id),
},
);

Expand Down
19 changes: 9 additions & 10 deletions compiler/noirc_frontend/src/hir/resolution/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub fn resolve_import(
crate_id: CrateId,
import_directive: &ImportDirective,
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> Result<ResolvedImport, PathResolutionError> {
let module_scope = import_directive.module_id;
let NamespaceResolution {
Expand Down Expand Up @@ -131,7 +131,7 @@ fn resolve_path_to_ns(
crate_id: CrateId,
importing_crate: CrateId,
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> NamespaceResolutionResult {
let import_path = &import_directive.path.segments;
let def_map = &def_maps[&crate_id];
Expand Down Expand Up @@ -221,7 +221,7 @@ fn resolve_path_from_crate_root(

import_path: &[PathSegment],
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> NamespaceResolutionResult {
resolve_name_in_module(
crate_id,
Expand All @@ -239,7 +239,7 @@ fn resolve_name_in_module(
import_path: &[PathSegment],
starting_mod: LocalModuleId,
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> NamespaceResolutionResult {
let def_map = &def_maps[&krate];
let mut current_mod_id = ModuleId { krate, local_id: starting_mod };
Expand Down Expand Up @@ -275,22 +275,22 @@ fn resolve_name_in_module(
current_mod_id = match typ {
ModuleDefId::ModuleId(id) => {
if let Some(path_references) = path_references {
path_references.push(Some(ReferenceId::Module(id)));
path_references.push(ReferenceId::Module(id));
}
id
}
ModuleDefId::FunctionId(_) => panic!("functions cannot be in the type namespace"),
// TODO: If impls are ever implemented, types can be used in a path
ModuleDefId::TypeId(id) => {
if let Some(path_references) = path_references {
path_references.push(Some(ReferenceId::Struct(id)));
path_references.push(ReferenceId::Struct(id));
}
id.module_id()
}
ModuleDefId::TypeAliasId(_) => panic!("type aliases cannot be used in type namespace"),
ModuleDefId::TraitId(id) => {
if let Some(path_references) = path_references {
path_references.push(Some(ReferenceId::Trait(id)));
path_references.push(ReferenceId::Trait(id));
}
id.0
}
Expand Down Expand Up @@ -337,7 +337,7 @@ fn resolve_external_dep(
current_def_map: &CrateDefMap,
directive: &ImportDirective,
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
importing_crate: CrateId,
) -> NamespaceResolutionResult {
// Use extern_prelude to get the dep
Expand All @@ -355,9 +355,8 @@ fn resolve_external_dep(
// See `singleton_import.nr` test case for a check that such cases are handled elsewhere.
let path_without_crate_name = &path[1..];

// Given that we skipped the first segment, record that it doesn't refer to any module or type.
if let Some(path_references) = path_references {
path_references.push(None);
path_references.push(ReferenceId::Module(*dep_module));
}

let path = Path {
Expand Down
6 changes: 3 additions & 3 deletions compiler/noirc_frontend/src/hir/resolution/path_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub trait PathResolver {
&self,
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path: Path,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> PathResolutionResult;

fn local_module_id(&self) -> LocalModuleId;
Expand All @@ -39,7 +39,7 @@ impl PathResolver for StandardPathResolver {
&self,
def_maps: &BTreeMap<CrateId, CrateDefMap>,
path: Path,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> PathResolutionResult {
resolve_path(def_maps, self.module_id, path, path_references)
}
Expand All @@ -59,7 +59,7 @@ pub fn resolve_path(
def_maps: &BTreeMap<CrateId, CrateDefMap>,
module_id: ModuleId,
path: Path,
path_references: &mut Option<&mut Vec<Option<ReferenceId>>>,
path_references: &mut Option<&mut Vec<ReferenceId>>,
) -> PathResolutionResult {
// lets package up the path into an ImportDirective and resolve it using that
let import =
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const IMPL_SEARCH_RECURSION_LIMIT: u32 = 10;
pub struct ModuleAttributes {
pub name: String,
pub location: Location,
pub parent: LocalModuleId,
pub parent: Option<LocalModuleId>,
}

type StructAttributes = Vec<SecondaryAttribute>;
Expand Down Expand Up @@ -1035,7 +1035,7 @@ impl NodeInterner {
}

pub fn try_module_parent(&self, module_id: &ModuleId) -> Option<LocalModuleId> {
self.try_module_attributes(module_id).map(|attrs| attrs.parent)
self.try_module_attributes(module_id).and_then(|attrs| attrs.parent)
}

pub fn global_attributes(&self, global_id: &GlobalId) -> &[SecondaryAttribute] {
Expand Down
34 changes: 12 additions & 22 deletions tooling/lsp/src/requests/completion/auto_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use lsp_types::{Position, Range, TextEdit};
use noirc_frontend::{
ast::ItemVisibility,
graph::{CrateId, Dependency},
graph::CrateId,
hir::def_map::{CrateDefMap, ModuleId},
macros_api::{ModuleDefId, NodeInterner},
node_interner::ReferenceId,
Expand Down Expand Up @@ -47,7 +47,6 @@ impl<'a> NodeFinder<'a> {
&self.module_id,
current_module_parent_id,
self.interner,
self.dependencies,
);
} else {
let Some(parent_module) = get_parent_module(self.interner, *module_def_id)
Expand All @@ -74,7 +73,6 @@ impl<'a> NodeFinder<'a> {
&self.module_id,
current_module_parent_id,
self.interner,
self.dependencies,
);
}

Expand Down Expand Up @@ -149,7 +147,6 @@ fn module_id_path(
current_module_id: &ModuleId,
current_module_parent_id: Option<ModuleId>,
interner: &NodeInterner,
dependencies: &[Dependency],
) -> String {
if Some(target_module_id) == current_module_parent_id {
return "super".to_string();
Expand All @@ -163,8 +160,12 @@ fn module_id_path(

let mut current_attributes = module_attributes;
loop {
let Some(parent_local_id) = current_attributes.parent else {
break;
};

let parent_module_id =
&ModuleId { krate: target_module_id.krate, local_id: current_attributes.parent };
&ModuleId { krate: target_module_id.krate, local_id: parent_local_id };

if current_module_id == parent_module_id {
is_relative = true;
Expand All @@ -186,24 +187,13 @@ fn module_id_path(
}
}

let crate_id = target_module_id.krate;
let crate_name = if is_relative {
None
} else {
match crate_id {
CrateId::Root(_) => Some("crate".to_string()),
CrateId::Stdlib(_) => Some("std".to_string()),
CrateId::Crate(_) => dependencies
.iter()
.find(|dep| dep.crate_id == crate_id)
.map(|dep| dep.name.to_string()),
CrateId::Dummy => unreachable!("ICE: A dummy CrateId should not be accessible"),
if !is_relative {
// We don't record module attriubtes for the root module,
// so we handle that case separately
if let CrateId::Root(_) = target_module_id.krate {
segments.push("crate");
}
};

if let Some(crate_name) = &crate_name {
segments.push(crate_name);
};
}

segments.reverse();
segments.join("::")
Expand Down
18 changes: 18 additions & 0 deletions tooling/lsp/src/requests/completion/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1638,4 +1638,22 @@ mod completion_tests {
})
);
}

#[test]
async fn test_auto_import_from_std() {
let src = r#"
fn main() {
compute_merkle_roo>|<
}
"#;
let items = get_completions(src).await;
assert_eq!(items.len(), 1);

let item = &items[0];
assert_eq!(item.label, "compute_merkle_root(…)");
assert_eq!(
item.label_details.as_ref().unwrap().detail,
Some("(use std::merkle::compute_merkle_root)".to_string()),
);
}
}
14 changes: 14 additions & 0 deletions tooling/lsp/src/requests/goto_definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,18 @@ mod goto_definition_tests {
)
.await;
}

#[test]
async fn goto_crate() {
expect_goto(
"go_to_definition",
Position { line: 29, character: 6 }, // "dependency" in "use dependency::something"
"dependency/src/lib.nr",
Range {
start: Position { line: 0, character: 0 },
end: Position { line: 0, character: 0 },
},
)
.await;
}
}
Loading

0 comments on commit 857d16e

Please sign in to comment.