Skip to content

Commit

Permalink
explicit module tracking instead of via definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
amitu committed Dec 2, 2024
1 parent 95f3886 commit c63f588
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 58 deletions.
16 changes: 0 additions & 16 deletions fastn-resolved/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ pub type Map<T> = std::collections::BTreeMap<String, T>;

#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum Definition {
/// every module is a "thing" and can be referred to etc., so we need to keep track of them
Module {
package: String,
module: Option<String>,
},
Record(fastn_resolved::Record),
OrType(fastn_resolved::OrType),
OrTypeWithVariant {
Expand Down Expand Up @@ -68,14 +63,6 @@ impl Definition {
fastn_resolved::Definition::Function(f) => f.name.to_string(),
fastn_resolved::Definition::WebComponent(w) => w.name.to_string(),
fastn_resolved::Definition::Export { to, .. } => to.to_string(),
Definition::Module {
package,
module: None,
} => package.clone(),
Definition::Module {
package,
module: Some(module),
} => format!("{}/{}", package, module),
}
}

Expand All @@ -89,9 +76,6 @@ impl Definition {
Definition::OrTypeWithVariant { variant, .. } => variant.line_number(),
Definition::WebComponent(w) => w.line_number,
Definition::Export { line_number, .. } => *line_number,
// module is not defined on any given line, unless it is defined using the future
// module proposal, till now we return 0
Definition::Module { .. } => 0,
}
}

Expand Down
20 changes: 17 additions & 3 deletions v0.5/fastn-compiler/src/compiler.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
const ITERATION_THRESHOLD: usize = 100;

// foo.ftd
// -- import: foo as f (f => foo)
//
// -- import: bar (bar => Module<bar>, x => Symbol<bar.y>) (bar => bar, x => bar.y)
// exposing: y as x
//
pub(crate) struct Compiler {
symbols: Box<dyn fastn_compiler::SymbolStore>,
pub(crate) definitions_used: std::collections::HashSet<fastn_unresolved::Symbol>,
pub(crate) arena: fastn_unresolved::Arena,
pub(crate) definitions: std::collections::HashMap<String, fastn_unresolved::URD>,
/// we keep track of every module found (or not found), if not in dict we don't know
/// if module exists, if in dict bool tells if it exists.
pub(crate) modules: std::collections::HashMap<fastn_unresolved::Module, bool>,
/// checkout resolve_document for why this is an Option
content: Option<Vec<fastn_unresolved::URCI>>,
pub(crate) document: fastn_unresolved::Document,
Expand Down Expand Up @@ -33,6 +41,7 @@ impl Compiler {
symbols,
arena,
definitions: std::collections::HashMap::new(),
modules: std::collections::HashMap::new(),
content,
document,
auto_imports,
Expand Down Expand Up @@ -94,7 +103,7 @@ impl Compiler {
match definition.as_mut() {
Some(fastn_unresolved::UR::UnResolved(definition)) => {
let mut o = Default::default();
definition.resolve(&self.definitions, &mut self.arena, &mut o);
definition.resolve(&self.definitions, &self.modules, &mut self.arena, &mut o);
r.need_more_symbols.extend(o.stuck_on);
self.document.merge(o.errors, o.warnings, o.comments);
}
Expand Down Expand Up @@ -139,7 +148,12 @@ impl Compiler {
match ci {
fastn_unresolved::UR::UnResolved(mut c) => {
let mut needed = Default::default();
c.resolve(&self.definitions, &mut self.arena, &mut needed);
c.resolve(
&self.definitions,
&self.modules,
&mut self.arena,
&mut needed,
);
stuck_on_symbols.extend(needed.stuck_on);
self.document
.merge(needed.errors, needed.warnings, needed.comments);
Expand Down
3 changes: 2 additions & 1 deletion v0.5/fastn-core/src/config/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ fn desugar_auto_imports(
_auto_imports: &[fastn_core::config::AutoImport],
) -> fastn_unresolved::AliasesID {
let id = arena.new_aliases();
let ftd = fastn_unresolved::SoM::Module(fastn_unresolved::Module::new("ftd", None, arena));
let aliases = arena.aliases.get_mut(id).unwrap();
aliases.insert("ftd".to_string(), "ftd".to_string());
aliases.insert("ftd".to_string(), ftd);
id
}
4 changes: 3 additions & 1 deletion v0.5/fastn-section/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,16 @@ pub struct Identifier {
#[derive(Debug, Clone, PartialEq)]
pub enum IdentifierReference {
// foo
Local(fastn_section::Span),
Local(fastn_section::Span), // -- foo:
// bar.foo: module = bar, name: foo
Imported {
// -- foo.bar: (foo/bar#bar)
module: fastn_section::Span,
name: fastn_section::Span,
},
// bar#foo: component using the absolute path.
Absolute {
// -- foo#bar:
package: fastn_section::Span,
module: fastn_section::Span,
name: fastn_section::Span,
Expand Down
10 changes: 7 additions & 3 deletions v0.5/fastn-unresolved/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub type URCI = fastn_unresolved::UR<
fastn_resolved::ComponentInvocation,
>;
pub type URIS = fastn_unresolved::UR<fastn_section::IdentifierReference, fastn_unresolved::Symbol>;
pub type Aliases = std::collections::HashMap<String, String>;
pub type Aliases = std::collections::HashMap<String, fastn_unresolved::SoM>;
pub type AliasesID = id_arena::Id<Aliases>;

#[derive(Default)]
Expand Down Expand Up @@ -49,6 +49,11 @@ pub struct Module {
package_len: std::num::NonZeroU16,
}

pub enum SoM {
Symbol(Symbol),
Module(Module),
}

#[derive(Debug, Clone)]
pub struct Document {
pub aliases: AliasesID,
Expand Down Expand Up @@ -79,8 +84,6 @@ pub struct Definition {

#[derive(Debug, Clone)]
pub enum InnerDefinition {
SymbolAlias(fastn_unresolved::Symbol),
ModuleAlias(fastn_unresolved::Module),
Component {
arguments: Vec<UR<Argument, fastn_resolved::Argument>>,
body: Vec<URCI>,
Expand Down Expand Up @@ -168,6 +171,7 @@ pub enum UR<U, R> {

#[derive(Debug, Clone, PartialEq)]
pub struct ComponentInvocation {
pub aliases: AliasesID,
/// this contains a symbol that is the module where this component invocation happened.
///
/// all local symbols are resolved with respect to the module.
Expand Down
1 change: 1 addition & 0 deletions v0.5/fastn-unresolved/src/parser/component_invocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub(super) fn component_invocation(

document.content.push(
fastn_unresolved::ComponentInvocation {
aliases: document.aliases,
module: document.module.clone(),
name: fastn_unresolved::UR::UnResolved(section.init.name.clone()),
caption: section.caption.into(),
Expand Down
12 changes: 10 additions & 2 deletions v0.5/fastn-unresolved/src/resolver/component_invocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ impl fastn_unresolved::ComponentInvocation {
pub fn resolve(
&mut self,
definitions: &std::collections::HashMap<String, fastn_unresolved::URD>,
modules: &std::collections::HashMap<fastn_unresolved::Module, bool>,
arena: &mut fastn_unresolved::Arena,
output: &mut fastn_unresolved::resolver::Output,
) {
// -- foo: (foo has children)
// -- bar:
// -- end: foo

// we resolve children first (so we can do early returns after this for loop)
for c in self.children.iter_mut() {
if let fastn_unresolved::UR::UnResolved(ref mut c) = c {
c.resolve(definitions, arena, output);
c.resolve(definitions, modules, arena, output);
}
}

fastn_unresolved::resolver::symbol::resolve(
fastn_unresolved::resolver::symbol(
self.aliases,
&self.module,
&mut self.name,
definitions,
modules,
arena,
output,
&[], // TODO
Expand Down
1 change: 1 addition & 0 deletions v0.5/fastn-unresolved/src/resolver/definition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ impl fastn_unresolved::Definition {
pub fn resolve(
&mut self,
_definitions: &std::collections::HashMap<String, fastn_unresolved::URD>,
_modules: &std::collections::HashMap<fastn_unresolved::Module, bool>,
_arena: &mut fastn_unresolved::Arena,
_output: &mut fastn_unresolved::resolver::Output,
) {
Expand Down
2 changes: 2 additions & 0 deletions v0.5/fastn-unresolved/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod component_invocation;
mod definition;
mod symbol;

use symbol::symbol;

#[derive(Debug, Default)]
pub struct Output {
pub stuck_on: std::collections::HashSet<fastn_unresolved::Symbol>,
Expand Down
67 changes: 39 additions & 28 deletions v0.5/fastn-unresolved/src/resolver/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
/// e.g., inside a function we can have block containing blocks, and each block may have defined
/// some variables, each such nested block is passed as locals,
/// with the innermost block as the last entry.
pub fn resolve(
pub fn symbol(
aid: fastn_unresolved::AliasesID,
// foo.ftd (current_module = foo, package = foo, module = "")
current_module: &fastn_unresolved::Module,
// parent: Option<fastn_unresolved::Symbol>,
Expand All @@ -14,8 +15,9 @@ pub fn resolve(
// S3_name="bar#x"
name: &mut fastn_unresolved::URIS,
definitions: &std::collections::HashMap<String, fastn_unresolved::URD>,
modules: &std::collections::HashMap<fastn_unresolved::Module, bool>,
arena: &mut fastn_unresolved::Arena,
output: &mut fastn_unresolved::resolver::Output,
_output: &mut fastn_unresolved::resolver::Output,
_locals: &[Vec<fastn_unresolved::UR<fastn_unresolved::Argument, fastn_resolved::Argument>>],
) {
let inner_name = if let fastn_unresolved::UR::UnResolved(name) = name {
Expand All @@ -38,6 +40,19 @@ pub fn resolve(
// if it is in error state, or not found state, we resolve ourselves as them.
fastn_unresolved::Symbol::new(package.str(), Some(module.str()), name.str(), arena)
}
fastn_section::IdentifierReference::Local(name) => {
// we combine the name with current_module to create the target symbol.
// but what if the name is an alias?
// we resolve the alias first.
match arena.aliases.get(aid).and_then(|v| v.get(name.str())) {
Some(fastn_unresolved::SoM::Symbol(s)) => s.clone(),
Some(fastn_unresolved::SoM::Module(_)) => {
// report an error, resolve always resolves
todo!()
}
None => current_module.symbol(name.str(), arena),
}
}
fastn_section::IdentifierReference::Imported {
module,
name: dotted_name,
Expand All @@ -50,38 +65,34 @@ pub fn resolve(
// module from the module alias.
// we combine the target module with the name, "x" to get the target symbol.
match definitions.get(target_symbol.str(arena)) {
Some(fastn_unresolved::UR::Resolved(fastn_resolved::Definition::Module {
package,
module,
..
})) => {
// what we stored in resolved place, no further action is required.
*name = fastn_unresolved::UR::Resolved(fastn_unresolved::Symbol::new(
package,
module.as_deref(),
dotted_name.str(),
arena,
));
return;
}
Some(fastn_unresolved::UR::UnResolved(_)) => {
output.stuck_on.insert(target_symbol);
return;
}
Some(fastn_unresolved::UR::NotFound) => {
*name = fastn_unresolved::UR::Invalid(fastn_section::Error::InvalidIdentifier);
return;
}
// Some(fastn_unresolved::UR::Resolved(fastn_resolved::Definition::Module {
// package,
// module,
// ..
// })) => {
// // what we stored in resolved place, no further action is required.
// *name = fastn_unresolved::UR::Resolved(fastn_unresolved::Symbol::new(
// package,
// module.as_deref(),
// dotted_name.str(),
// arena,
// ));
// return;
// }
// Some(fastn_unresolved::UR::UnResolved(_)) => {
// output.stuck_on.insert(target_symbol);
// return;
// }
// Some(fastn_unresolved::UR::NotFound) => {
// *name = fastn_unresolved::UR::Invalid(fastn_section::Error::InvalidIdentifier);
// return;
// }
_ => {
// we have
todo!()
}
}
}
fastn_section::IdentifierReference::Local(name) => {
// we combine name with current_module to create target symbol.
current_module.symbol(name.str(), arena)
}
};

*name = fastn_unresolved::UR::Resolved(target_symbol);
Expand Down
6 changes: 2 additions & 4 deletions v0.5/fastn-unresolved/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,8 @@ impl fastn_unresolved::Symbol {
}

pub fn base<'a>(&self, arena: &'a fastn_unresolved::Arena) -> &'a str {
&self.str(
arena[..self.package_len.get() as usize
+ self.module_len.map(|v| v.get() + 1).unwrap_or(0) as usize],
)
&self.str(arena)[..self.package_len.get() as usize
+ self.module_len.map(|v| v.get() + 1).unwrap_or(0) as usize]
}

pub fn string(&self, arena: &fastn_unresolved::Arena) -> String {
Expand Down

0 comments on commit c63f588

Please sign in to comment.