Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::ast::{
use crate::hir::def_collector::errors::DefCollectorErrorKind;
use crate::macros_api::StructId;
use crate::node_interner::{ExprId, QuotedTypeId};
use crate::token::{Attributes, Token, Tokens};
use crate::token::{Attributes, FunctionAttribute, Token, Tokens};
use crate::{Kind, Type};
use acvm::{acir::AcirField, FieldElement};
use iter_extended::vecmap;
Expand Down Expand Up @@ -478,6 +478,20 @@ pub struct FunctionDefinition {
pub return_visibility: Visibility,
}

impl FunctionDefinition {
pub fn is_private(&self) -> bool {
self.visibility == ItemVisibility::Private
}

pub fn is_test(&self) -> bool {
if let Some(attribute) = &self.attributes.function {
matches!(attribute, FunctionAttribute::Test(..))
} else {
false
}
}
}

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Param {
pub visibility: Visibility,
Expand Down
12 changes: 11 additions & 1 deletion compiler/noirc_frontend/src/elaborator/comptime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ use crate::{
hir_def::expr::HirIdent,
lexer::Lexer,
macros_api::{
Expression, ExpressionKind, HirExpression, NodeInterner, SecondaryAttribute, StructId,
Expression, ExpressionKind, HirExpression, ModuleDefId, NodeInterner, SecondaryAttribute,
StructId,
},
node_interner::{DefinitionKind, DependencyId, FuncId, TraitId},
parser::{self, TopLevelStatement},
Expand Down Expand Up @@ -267,6 +268,15 @@ impl<'context> Elaborator<'context> {
let id = self.interner.push_empty_fn();
let module = self.module_id();
self.interner.push_function(id, &function.def, module, location);

if self.is_in_lsp_mode() && !function.def.is_test() && !function.def.is_private() {
self.interner.register_name_for_auto_import(
function.def.name.0.contents.clone(),
ModuleDefId::FunctionId(id),
function.def.visibility,
);
}

let functions = vec![(self.local_module, id, function)];
generated_items.functions.push(UnresolvedFunctions {
file_id: self.file,
Expand Down
22 changes: 22 additions & 0 deletions compiler/noirc_frontend/src/elaborator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,16 @@ impl<'context> Elaborator<'context> {
self.current_item = Some(DependencyId::Global(global_id));
let let_stmt = global.stmt_def;

let name = if self.is_in_lsp_mode() {
if let Pattern::Identifier(ident) = &let_stmt.pattern {
Some(ident.to_string())
} else {
None
}
} else {
None
};

if !self.in_contract()
&& let_stmt.attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Abi(_)))
{
Expand All @@ -1322,6 +1332,14 @@ impl<'context> Elaborator<'context> {
self.interner
.add_definition_location(ReferenceId::Global(global_id), Some(self.module_id()));

if let Some(name) = name {
self.interner.register_name_for_auto_import(
name,
ModuleDefId::GlobalId(global_id),
ItemVisibility::Public,
);
}

self.local_module = old_module;
self.file = old_file;
self.current_item = old_item;
Expand Down Expand Up @@ -1463,4 +1481,8 @@ impl<'context> Elaborator<'context> {
_ => true,
})
}

fn is_in_lsp_mode(&self) -> bool {
self.interner.is_in_lsp_mode()
}
}
79 changes: 61 additions & 18 deletions compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::ast::{
NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, Pattern, TraitImplItem, TraitItem,
TypeImpl,
};
use crate::macros_api::NodeInterner;
use crate::macros_api::{ModuleDefId, NodeInterner};
use crate::node_interner::{ModuleAttributes, ReferenceId};
use crate::{
graph::CrateId,
Expand Down Expand Up @@ -232,6 +232,17 @@ impl<'a> ModCollector<'a> {
let location = Location::new(function.span(), self.file_id);
context.def_interner.push_function(func_id, &function.def, module, location);

if context.def_interner.is_in_lsp_mode()
&& !function.def.is_test()
&& !function.def.is_private()
{
context.def_interner.register_name_for_auto_import(
function.def.name.0.contents.clone(),
ModuleDefId::FunctionId(func_id),
function.def.visibility,
);
}

// Now link this func_id to a crate level map with the noir function and the module id
// Encountering a NoirFunction, we retrieve it's module_data to get the namespace
// Once we have lowered it to a HirFunction, we retrieve it's Id from the DefInterner
Expand Down Expand Up @@ -307,8 +318,8 @@ impl<'a> ModCollector<'a> {
};

// Add the struct to scope so its path can be looked up later
let result =
self.def_collector.def_map.modules[self.module_id.0].declare_struct(name, id);
let result = self.def_collector.def_map.modules[self.module_id.0]
.declare_struct(name.clone(), id);

if let Err((first_def, second_def)) = result {
let error = DefCollectorErrorKind::Duplicate {
Expand All @@ -322,10 +333,18 @@ impl<'a> ModCollector<'a> {
// And store the TypeId -> StructType mapping somewhere it is reachable
self.def_collector.items.types.insert(id, unresolved);

context.def_interner.add_definition_location(
ReferenceId::Struct(id),
Some(ModuleId { krate, local_id: self.module_id }),
);
if context.def_interner.is_in_lsp_mode() {
context.def_interner.add_definition_location(
ReferenceId::Struct(id),
Some(ModuleId { krate, local_id: self.module_id }),
);

context.def_interner.register_name_for_auto_import(
name.to_string(),
ModuleDefId::TypeId(id),
ItemVisibility::Public,
);
}
}
definition_errors
}
Expand Down Expand Up @@ -383,7 +402,7 @@ impl<'a> ModCollector<'a> {

// Add the type alias to scope so its path can be looked up later
let result = self.def_collector.def_map.modules[self.module_id.0]
.declare_type_alias(name, type_alias_id);
.declare_type_alias(name.clone(), type_alias_id);

if let Err((first_def, second_def)) = result {
let err = DefCollectorErrorKind::Duplicate {
Expand All @@ -396,10 +415,18 @@ impl<'a> ModCollector<'a> {

self.def_collector.items.type_aliases.insert(type_alias_id, unresolved);

context.def_interner.add_definition_location(
ReferenceId::Alias(type_alias_id),
Some(ModuleId { krate, local_id: self.module_id }),
);
if context.def_interner.is_in_lsp_mode() {
context.def_interner.add_definition_location(
ReferenceId::Alias(type_alias_id),
Some(ModuleId { krate, local_id: self.module_id }),
);

context.def_interner.register_name_for_auto_import(
name.to_string(),
ModuleDefId::TypeAliasId(type_alias_id),
ItemVisibility::Public,
);
}
}
errors
}
Expand Down Expand Up @@ -432,8 +459,8 @@ impl<'a> ModCollector<'a> {
};

// Add the trait to scope so its path can be looked up later
let result =
self.def_collector.def_map.modules[self.module_id.0].declare_trait(name, trait_id);
let result = self.def_collector.def_map.modules[self.module_id.0]
.declare_trait(name.clone(), trait_id);

if let Err((first_def, second_def)) = result {
let error = DefCollectorErrorKind::Duplicate {
Expand Down Expand Up @@ -567,10 +594,18 @@ impl<'a> ModCollector<'a> {
};
context.def_interner.push_empty_trait(trait_id, &unresolved, resolved_generics);

context.def_interner.add_definition_location(
ReferenceId::Trait(trait_id),
Some(ModuleId { krate, local_id: self.module_id }),
);
if context.def_interner.is_in_lsp_mode() {
context.def_interner.add_definition_location(
ReferenceId::Trait(trait_id),
Some(ModuleId { krate, local_id: self.module_id }),
);

context.def_interner.register_name_for_auto_import(
name.to_string(),
ModuleDefId::TraitId(trait_id),
ItemVisibility::Public,
);
}

self.def_collector.items.traits.insert(trait_id, unresolved);
}
Expand Down Expand Up @@ -766,6 +801,14 @@ impl<'a> ModCollector<'a> {
parent: self.module_id,
},
);

if context.def_interner.is_in_lsp_mode() {
context.def_interner.register_name_for_auto_import(
mod_name.0.contents.clone(),
ModuleDefId::ModuleId(mod_id),
ItemVisibility::Public,
);
}
}

Ok(mod_id)
Expand Down
2 changes: 1 addition & 1 deletion compiler/noirc_frontend/src/hir/def_map/module_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::node_interner::{FuncId, GlobalId, StructId, TraitId, TypeAliasId};
use super::ModuleId;

/// A generic ID that references either a module, function, type, interface or global
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum ModuleDefId {
ModuleId(ModuleId),
FunctionId(FuncId),
Expand Down
22 changes: 20 additions & 2 deletions compiler/noirc_frontend/src/locations.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use fm::FileId;
use noirc_errors::Location;
use rangemap::RangeMap;
use rustc_hash::FxHashMap;
use rustc_hash::FxHashMap as HashMap;

use crate::{
ast::ItemVisibility,
hir::def_map::{ModuleDefId, ModuleId},
macros_api::{NodeInterner, StructId},
node_interner::{DefinitionId, FuncId, GlobalId, ReferenceId, TraitId, TypeAliasId},
Expand All @@ -12,7 +13,7 @@ use petgraph::prelude::NodeIndex as PetGraphIndex;

#[derive(Debug, Default)]
pub(crate) struct LocationIndices {
map_file_to_range: FxHashMap<FileId, RangeMap<u32, PetGraphIndex>>,
map_file_to_range: HashMap<FileId, RangeMap<u32, PetGraphIndex>>,
}

impl LocationIndices {
Expand Down Expand Up @@ -275,4 +276,21 @@ impl NodeInterner {
.neighbors_directed(reference_index, petgraph::Direction::Outgoing)
.next()
}

pub(crate) fn register_name_for_auto_import(
&mut self,
name: String,
module_def_id: ModuleDefId,
visibility: ItemVisibility,
) {
if !self.lsp_mode {
return;
}

self.auto_import_names.entry(name).or_default().push((module_def_id, visibility));
}

pub fn get_auto_import_names(&self) -> &HashMap<String, Vec<(ModuleDefId, ItemVisibility)>> {
&self.auto_import_names
}
}
8 changes: 8 additions & 0 deletions compiler/noirc_frontend/src/node_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::hir::comptime;
use crate::hir::def_collector::dc_crate::CompilationError;
use crate::hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait, UnresolvedTypeAlias};
use crate::hir::def_map::{LocalModuleId, ModuleId};
use crate::macros_api::ModuleDefId;
use crate::macros_api::UnaryOp;
use crate::QuotedType;

Expand Down Expand Up @@ -231,6 +232,11 @@ pub struct NodeInterner {
// (ReferenceId::Reference and ReferenceId::Local aren't included here)
pub(crate) reference_modules: HashMap<ReferenceId, ModuleId>,

// All names (and their definitions) that can be offered for auto_import.
// These include top-level functions, global variables and types, but excludes
// impl and trait-impl methods.
pub(crate) auto_import_names: HashMap<String, Vec<(ModuleDefId, ItemVisibility)>>,

/// Each value currently in scope in the comptime interpreter.
/// Each element of the Vec represents a scope with every scope together making
/// up all currently visible definitions. The first scope is always the global scope.
Expand Down Expand Up @@ -602,6 +608,7 @@ impl Default for NodeInterner {
reference_graph: petgraph::graph::DiGraph::new(),
reference_graph_indices: HashMap::default(),
reference_modules: HashMap::default(),
auto_import_names: HashMap::default(),
comptime_scopes: vec![HashMap::default()],
}
}
Expand Down Expand Up @@ -910,6 +917,7 @@ impl NodeInterner {
// This needs to be done after pushing the definition since it will reference the
// location that was stored
self.add_definition_location(ReferenceId::Function(id), Some(module));

definition_id
}

Expand Down
Loading