From c63f58852c23d9941d9ec3c0e976c70008c3461d Mon Sep 17 00:00:00 2001 From: Amit Upadhyay Date: Mon, 2 Dec 2024 13:05:44 +0530 Subject: [PATCH] explicit module tracking instead of via definitions --- fastn-resolved/src/lib.rs | 16 ----- v0.5/fastn-compiler/src/compiler.rs | 20 +++++- v0.5/fastn-core/src/config/read.rs | 3 +- v0.5/fastn-section/src/lib.rs | 4 +- v0.5/fastn-unresolved/src/lib.rs | 10 ++- .../src/parser/component_invocation.rs | 1 + .../src/resolver/component_invocation.rs | 12 +++- .../src/resolver/definition.rs | 1 + v0.5/fastn-unresolved/src/resolver/mod.rs | 2 + v0.5/fastn-unresolved/src/resolver/symbol.rs | 67 +++++++++++-------- v0.5/fastn-unresolved/src/utils.rs | 6 +- 11 files changed, 84 insertions(+), 58 deletions(-) diff --git a/fastn-resolved/src/lib.rs b/fastn-resolved/src/lib.rs index 3b1fb7ffa..ce523b882 100644 --- a/fastn-resolved/src/lib.rs +++ b/fastn-resolved/src/lib.rs @@ -34,11 +34,6 @@ pub type Map = std::collections::BTreeMap; #[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, - }, Record(fastn_resolved::Record), OrType(fastn_resolved::OrType), OrTypeWithVariant { @@ -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), } } @@ -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, } } diff --git a/v0.5/fastn-compiler/src/compiler.rs b/v0.5/fastn-compiler/src/compiler.rs index 43140cf35..78d3e764a 100644 --- a/v0.5/fastn-compiler/src/compiler.rs +++ b/v0.5/fastn-compiler/src/compiler.rs @@ -1,10 +1,18 @@ const ITERATION_THRESHOLD: usize = 100; - +// foo.ftd +// -- import: foo as f (f => foo) +// +// -- import: bar (bar => Module, x => Symbol) (bar => bar, x => bar.y) +// exposing: y as x +// pub(crate) struct Compiler { symbols: Box, pub(crate) definitions_used: std::collections::HashSet, pub(crate) arena: fastn_unresolved::Arena, pub(crate) definitions: std::collections::HashMap, + /// 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, /// checkout resolve_document for why this is an Option content: Option>, pub(crate) document: fastn_unresolved::Document, @@ -33,6 +41,7 @@ impl Compiler { symbols, arena, definitions: std::collections::HashMap::new(), + modules: std::collections::HashMap::new(), content, document, auto_imports, @@ -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); } @@ -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); diff --git a/v0.5/fastn-core/src/config/read.rs b/v0.5/fastn-core/src/config/read.rs index c018fb4fd..47e08bf56 100644 --- a/v0.5/fastn-core/src/config/read.rs +++ b/v0.5/fastn-core/src/config/read.rs @@ -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 } diff --git a/v0.5/fastn-section/src/lib.rs b/v0.5/fastn-section/src/lib.rs index 3b93edc7f..0efca6255 100644 --- a/v0.5/fastn-section/src/lib.rs +++ b/v0.5/fastn-section/src/lib.rs @@ -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, diff --git a/v0.5/fastn-unresolved/src/lib.rs b/v0.5/fastn-unresolved/src/lib.rs index b26f0b0e0..ba91802e7 100644 --- a/v0.5/fastn-unresolved/src/lib.rs +++ b/v0.5/fastn-unresolved/src/lib.rs @@ -20,7 +20,7 @@ pub type URCI = fastn_unresolved::UR< fastn_resolved::ComponentInvocation, >; pub type URIS = fastn_unresolved::UR; -pub type Aliases = std::collections::HashMap; +pub type Aliases = std::collections::HashMap; pub type AliasesID = id_arena::Id; #[derive(Default)] @@ -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, @@ -79,8 +84,6 @@ pub struct Definition { #[derive(Debug, Clone)] pub enum InnerDefinition { - SymbolAlias(fastn_unresolved::Symbol), - ModuleAlias(fastn_unresolved::Module), Component { arguments: Vec>, body: Vec, @@ -168,6 +171,7 @@ pub enum UR { #[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. diff --git a/v0.5/fastn-unresolved/src/parser/component_invocation.rs b/v0.5/fastn-unresolved/src/parser/component_invocation.rs index 178c52d3b..2d65c173e 100644 --- a/v0.5/fastn-unresolved/src/parser/component_invocation.rs +++ b/v0.5/fastn-unresolved/src/parser/component_invocation.rs @@ -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(), diff --git a/v0.5/fastn-unresolved/src/resolver/component_invocation.rs b/v0.5/fastn-unresolved/src/resolver/component_invocation.rs index 09b93f67e..41a28b762 100644 --- a/v0.5/fastn-unresolved/src/resolver/component_invocation.rs +++ b/v0.5/fastn-unresolved/src/resolver/component_invocation.rs @@ -2,19 +2,27 @@ impl fastn_unresolved::ComponentInvocation { pub fn resolve( &mut self, definitions: &std::collections::HashMap, + modules: &std::collections::HashMap, 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 diff --git a/v0.5/fastn-unresolved/src/resolver/definition.rs b/v0.5/fastn-unresolved/src/resolver/definition.rs index b8a976ba4..b3b6455a2 100644 --- a/v0.5/fastn-unresolved/src/resolver/definition.rs +++ b/v0.5/fastn-unresolved/src/resolver/definition.rs @@ -2,6 +2,7 @@ impl fastn_unresolved::Definition { pub fn resolve( &mut self, _definitions: &std::collections::HashMap, + _modules: &std::collections::HashMap, _arena: &mut fastn_unresolved::Arena, _output: &mut fastn_unresolved::resolver::Output, ) { diff --git a/v0.5/fastn-unresolved/src/resolver/mod.rs b/v0.5/fastn-unresolved/src/resolver/mod.rs index 3480a9ba7..36f442e78 100644 --- a/v0.5/fastn-unresolved/src/resolver/mod.rs +++ b/v0.5/fastn-unresolved/src/resolver/mod.rs @@ -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, diff --git a/v0.5/fastn-unresolved/src/resolver/symbol.rs b/v0.5/fastn-unresolved/src/resolver/symbol.rs index a27783016..235d3cf1c 100644 --- a/v0.5/fastn-unresolved/src/resolver/symbol.rs +++ b/v0.5/fastn-unresolved/src/resolver/symbol.rs @@ -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, @@ -14,8 +15,9 @@ pub fn resolve( // S3_name="bar#x" name: &mut fastn_unresolved::URIS, definitions: &std::collections::HashMap, + modules: &std::collections::HashMap, arena: &mut fastn_unresolved::Arena, - output: &mut fastn_unresolved::resolver::Output, + _output: &mut fastn_unresolved::resolver::Output, _locals: &[Vec>], ) { let inner_name = if let fastn_unresolved::UR::UnResolved(name) = name { @@ -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, @@ -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); diff --git a/v0.5/fastn-unresolved/src/utils.rs b/v0.5/fastn-unresolved/src/utils.rs index 1c08f0d51..dbcfd16e3 100644 --- a/v0.5/fastn-unresolved/src/utils.rs +++ b/v0.5/fastn-unresolved/src/utils.rs @@ -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 {