Skip to content

Commit

Permalink
Refactored ResolvedName to use FsNodeId to identifiy which module i…
Browse files Browse the repository at this point in the history
…t belongs to
  • Loading branch information
IsaacShelton committed Oct 6, 2024
1 parent 9492e1e commit f5f7249
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/inflow/into_inflow/peeker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ impl<S: InflowStream> InflowPeeker<S> {
pub fn new(stream: S) -> Self {
Self {
stream,
queue: VecDeque::new(),
queue: VecDeque::with_capacity(8),
}
}
}
Expand Down
27 changes: 21 additions & 6 deletions src/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,16 @@ fn lower_global(
global: &resolved::GlobalVar,
resolved_ast: &resolved::Ast,
) -> Result<(), LowerError> {
let mangled_name = if global.is_foreign {
global.name.plain().to_string()
} else {
global.name.display(resolved_ast.fs).to_string()
};

ir_module.globals.insert(
global_ref,
Global {
mangled_name: global.name.to_string(),
mangled_name,
ir_type: lower_type(&ir_module.target, &global.resolved_type, resolved_ast)?,
is_foreign: global.is_foreign,
is_thread_local: global.is_thread_local,
Expand Down Expand Up @@ -161,7 +167,7 @@ fn lower_function(
} else {
return Err(LowerErrorKind::MustReturnValueOfTypeBeforeExitingFunction {
return_type: function.return_type.to_string(),
function: function.name.to_string(),
function: function.name.display(resolved_ast.fs).to_string(),
}
.at(function.source));
}
Expand Down Expand Up @@ -194,7 +200,7 @@ fn lower_function(
} else if function.is_foreign {
function.name.plain().to_string()
} else {
function.name.to_string()
function.name.display(resolved_ast.fs).to_string()
};

let is_main = mangled_name == "main";
Expand Down Expand Up @@ -890,7 +896,10 @@ fn lower_expr(
.get(&enum_member_literal.variant_name)
.ok_or_else(|| {
LowerErrorKind::NoSuchEnumMember {
enum_name: enum_member_literal.enum_name.to_string(),
enum_name: enum_member_literal
.enum_name
.display(resolved_ast.fs)
.to_string(),
variant_name: enum_member_literal.variant_name.clone(),
}
.at(enum_member_literal.source)
Expand All @@ -907,7 +916,10 @@ fn lower_expr(
let make_error = |_| {
LowerErrorKind::CannotFit {
value: value.to_string(),
expected_type: enum_member_literal.enum_name.to_string(),
expected_type: enum_member_literal
.enum_name
.display(resolved_ast.fs)
.to_string(),
}
.at(enum_definition.source)
};
Expand Down Expand Up @@ -939,7 +951,10 @@ fn lower_expr(
}
_ => {
return Err(LowerErrorKind::EnumBackingTypeMustBeInteger {
enum_name: enum_member_literal.enum_name.to_string(),
enum_name: enum_member_literal
.enum_name
.display(resolved_ast.fs)
.to_string(),
}
.at(enum_definition.source))
}
Expand Down
49 changes: 32 additions & 17 deletions src/name.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::workspace::fs::{Fs, FsNodeId};
use std::fmt::Display;

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -56,33 +57,47 @@ impl Display for Name {
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ResolvedName {
Remote(Box<str>),
Project(Box<str>),
pub struct ResolvedName {
fs_node_id: FsNodeId,
name: Box<str>,
}

impl ResolvedName {
pub fn new(name: &Name) -> Self {
Self::Project(name.fullname().into_boxed_str())
pub fn new(fs_node_id: FsNodeId, name: &Name) -> Self {
Self {
fs_node_id,
name: name.fullname().into_boxed_str(),
}
}

pub fn new_remote(name: &Name) -> Self {
Self::Remote(name.fullname().into_boxed_str())
pub fn plain(&self) -> &str {
&*self.name
}

pub fn plain(&self) -> &str {
match self {
ResolvedName::Remote(name) => &**name,
ResolvedName::Project(name) => &**name,
}
pub fn display<'a>(&'a self, fs: &'a Fs) -> DisplayResolvedName<'a> {
DisplayResolvedName { name: self, fs }
}
}

impl Display for ResolvedName {
pub struct DisplayResolvedName<'a> {
name: &'a ResolvedName,
fs: &'a Fs,
}

impl Display for DisplayResolvedName<'_> {
#[allow(dead_code)]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ResolvedName::Remote(name) => write!(f, "<remote>/{}", name),
ResolvedName::Project(name) => write!(f, "{}", name),
}
let filename = &self.fs.get(self.name.fs_node_id).filename;
let prefix = if cfg!(target_os = "windows") { "/" } else { "" };

write!(
f,
"{}{} ::: {}",
prefix,
filename.to_string_lossy(),
self.name.plain()
)?;

Ok(())
}
}
8 changes: 6 additions & 2 deletions src/parser/parse_expr/post/member.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
let source = self.parse_token(TokenKind::Member, Some("for member expression"))?;
let member_name = self.parse_name(Some("for member name"))?;

if self.input.peek_is(TokenKind::OpenParen) || self.input.peek_is(TokenKind::OpenAngle) {
let generics = self.parse_generics()?;
let generics = self.parse_generics()?;

if !generics.is_empty()
|| self.input.peek_is(TokenKind::OpenParen)
|| self.input.peek_is(TokenKind::OpenAngle)
{
self.parse_call_with(member_name, generics, vec![subject], source)
} else {
Ok(ExprKind::Member(
Expand Down
3 changes: 2 additions & 1 deletion src/parser/parse_expr/primary/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ impl<'a, I: Inflow<Token>> Parser<'a, I> {
prefix_args: Vec<Expr>,
source: Source,
) -> Result<Expr, ParseError> {
let starting_args_len = prefix_args.len();
let mut args = prefix_args;

self.parse_token(TokenKind::OpenParen, Some("to begin call argument list"))?;
self.ignore_newlines();

while !self.input.peek_is_or_eof(TokenKind::CloseParen) {
if !args.is_empty() {
if args.len() > starting_args_len {
self.parse_token(TokenKind::Comma, Some("to separate arguments"))?;
self.ignore_newlines();
}
Expand Down
4 changes: 2 additions & 2 deletions src/resolve/expr/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ pub fn resolve_call_expr(
return Err(ResolveErrorKind::BadTypeForArgumentToFunction {
expected: preferred_type.to_string(),
got: argument.resolved_type.to_string(),
name: function.name.to_string(),
name: function.name.display(ctx.resolved_ast.fs).to_string(),
i,
}
.at(source));
Expand All @@ -94,7 +94,7 @@ pub fn resolve_call_expr(
if resolved_required_ty != return_type {
return Err(ResolveErrorKind::FunctionMustReturnType {
of: required_ty.to_string(),
function_name: function.name.to_string(),
function_name: function.name.display(ctx.resolved_ast.fs).to_string(),
}
.at(function.return_type.source));
}
Expand Down
3 changes: 2 additions & 1 deletion src/resolve/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ pub struct ResolveExprCtx<'a, 'b> {
pub resolved_function_ref: resolved::FunctionRef,
pub helper_exprs: &'b IndexMap<ResolvedName, &'a ast::HelperExpr>,
pub settings: &'b Settings,
pub public: &'b HashMap<FsNodeId, HashMap<String, Vec<resolved::FunctionRef>>>,
pub public_functions: &'b HashMap<FsNodeId, HashMap<String, Vec<resolved::FunctionRef>>>,
pub module_fs_node_id: FsNodeId,
}

impl<'a, 'b> ResolveExprCtx<'a, 'b> {
Expand Down
2 changes: 1 addition & 1 deletion src/resolve/expr/struct_literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub fn resolve_struct_literal_expr(
.is_some()
{
return Err(ResolveErrorKind::FieldSpecifiedMoreThanOnce {
struct_name: struct_name.to_string(),
struct_name: struct_name.display(ctx.resolved_ast.fs).to_string(),
field_name: field_name.to_string(),
}
.at(ast_type.source));
Expand Down
12 changes: 6 additions & 6 deletions src/resolve/expr/variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
};

pub fn resolve_variable_expr(
ctx: &mut ResolveExprCtx<'_, '_>,
ctx: &mut ResolveExprCtx,
name: &Name,
preferred_type: Option<PreferredType>,
initialized: Initialized,
Expand Down Expand Up @@ -48,7 +48,7 @@ pub fn resolve_variable_expr(
));
}

let resolved_name = ResolvedName::new(name);
let resolved_name = ResolvedName::new(ctx.module_fs_node_id, name);

if let Some((resolved_type, reference)) = ctx.global_search_ctx.find_global(&resolved_name) {
return Ok(resolve_global_variable(resolved_type, *reference, source));
Expand All @@ -64,10 +64,10 @@ pub fn resolve_variable_expr(
.imported_namespaces
.iter()
.flat_map(|namespace| {
let resolved_name = ResolvedName::new(&Name::new(
Some(namespace.to_string()),
name.basename.to_string(),
));
let resolved_name = ResolvedName::new(
ctx.module_fs_node_id,
&Name::new(Some(namespace.to_string()), name.basename.to_string()),
);

let global = ctx
.global_search_ctx
Expand Down
17 changes: 10 additions & 7 deletions src/resolve/function_search_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ use crate::{
name::{Name, ResolvedName},
resolved::{self, TypedExpr},
source_files::Source,
workspace::fs::FsNodeId,
};
use std::collections::HashMap;

#[derive(Clone, Debug)]
pub struct FunctionSearchCtx {
pub available: HashMap<ResolvedName, Vec<resolved::FunctionRef>>,
pub imported_namespaces: Vec<Box<str>>,
pub fs_node_id: FsNodeId,
}

#[derive(Clone, Debug)]
Expand All @@ -23,10 +25,11 @@ pub enum FindFunctionError {
}

impl FunctionSearchCtx {
pub fn new(imported_namespaces: Vec<Box<str>>) -> Self {
pub fn new(imported_namespaces: Vec<Box<str>>, fs_node_id: FsNodeId) -> Self {
Self {
available: Default::default(),
imported_namespaces,
fs_node_id,
}
}

Expand All @@ -37,7 +40,7 @@ impl FunctionSearchCtx {
arguments: &[TypedExpr],
source: Source,
) -> Result<FunctionRef, FindFunctionError> {
let resolved_name = ResolvedName::new(name);
let resolved_name = ResolvedName::new(self.fs_node_id, name);

let mut local_matches = self
.available
Expand Down Expand Up @@ -67,7 +70,7 @@ impl FunctionSearchCtx {
ctx.settings
.dependency_to_module
.get(dependency)
.and_then(|module_fs_node_id| ctx.public.get(module_fs_node_id))
.and_then(|module_fs_node_id| ctx.public_functions.get(module_fs_node_id))
.and_then(|public| public.get(name.basename.as_ref()))
.into_iter()
})
Expand All @@ -87,10 +90,10 @@ impl FunctionSearchCtx {
.imported_namespaces
.iter()
.filter_map(|namespace| {
self.available.get(&ResolvedName::new(&Name::new(
Some(namespace.to_string()),
name.basename.clone(),
)))
self.available.get(&ResolvedName::new(
self.fs_node_id,
&Name::new(Some(namespace.to_string()), name.basename.clone()),
))
})
.flatten()
.filter(|f| Self::fits(ctx, **f, arguments, source));
Expand Down
4 changes: 3 additions & 1 deletion src/resolve/global_search_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
name::ResolvedName,
resolved::{self, GlobalVarRef},
source_files::Source,
workspace::fs::Fs,
};
use std::collections::HashMap;

Expand All @@ -21,12 +22,13 @@ impl GlobalSearchCtx {
pub fn find_global_or_error(
&self,
name: &ResolvedName,
fs: &Fs,
source: Source,
) -> Result<(&resolved::Type, &GlobalVarRef), ResolveError> {
match self.find_global(name) {
Some(global) => Ok(global),
None => Err(ResolveErrorKind::UndeclaredVariable {
name: name.to_string(),
name: name.display(fs).to_string(),
}
.at(source)),
}
Expand Down
Loading

0 comments on commit f5f7249

Please sign in to comment.