From e8424358fa383e94194eadb1f36f422d564fe01d Mon Sep 17 00:00:00 2001 From: Kai Schmidt Date: Mon, 24 Jun 2024 13:33:08 -0700 Subject: [PATCH] allow for a name in scopes --- site/src/editor/utils.rs | 2 +- src/ast.rs | 13 +++++++++++-- src/compile/mod.rs | 25 ++++++++++++++++--------- src/compile/modifier.rs | 2 +- src/format.rs | 7 +++++-- src/lsp.rs | 2 +- src/parse.rs | 5 ++++- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/site/src/editor/utils.rs b/site/src/editor/utils.rs index 282c06b6..b7d100dd 100644 --- a/site/src/editor/utils.rs +++ b/site/src/editor/utils.rs @@ -1025,7 +1025,7 @@ pub fn progressive_strings(input: &str) -> Vec { Item::Binding(binding) => { lines.push(vec![binding.span().as_str(&inputs, |s| s.into())]) } - Item::TestScope(items) => lines.push(vec![items.span.as_str(&inputs, |s| s.into())]), + Item::Module(items) => lines.push(vec![items.span.as_str(&inputs, |s| s.into())]), Item::Import(import) => lines.push(vec![import.span().as_str(&inputs, |s| s.into())]), } } diff --git a/src/ast.rs b/src/ast.rs index 2dcc424c..29f3ea01 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -19,8 +19,8 @@ pub enum Item { Binding(Binding), /// An import Import(Import), - /// A test scope - TestScope(Sp>), + /// A scope + Module(Sp), } /// A binding @@ -51,6 +51,15 @@ impl Binding { } } +/// A scoped module +#[derive(Debug, Clone)] +pub struct ScopedModule { + /// The name of the scope + pub name: Option>, + /// The items + pub items: Vec, +} + /// An import #[derive(Debug, Clone)] pub struct Import { diff --git a/src/compile/mod.rs b/src/compile/mod.rs index 4a78f928..7e643aad 100644 --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -173,8 +173,8 @@ pub(crate) struct Scope { #[derive(Clone, Copy, PartialEq, Eq)] enum ScopeKind { - /// A scope at the top level of a file - File, + /// A scope at the top level of a file or in a named module + Module, /// A temporary scope, probably for a macro Temp, /// A test scope between `---`s @@ -184,7 +184,7 @@ enum ScopeKind { impl Default for Scope { fn default() -> Self { Self { - kind: ScopeKind::File, + kind: ScopeKind::Module, file_path: None, comment: None, names: IndexMap::new(), @@ -493,9 +493,16 @@ code: (words.iter()).any(|w| matches!(&w.value, Word::SemanticComment(_))) } let mut lines = match item { - Item::TestScope(items) => { + Item::Module(module) => { prev_comment.take(); - self.in_scope(ScopeKind::Test, |env| env.items(items.value, true))?; + let is_test = + (module.value.name.as_ref()).map_or(true, |name| name.value == "test"); + let scope_kind = if is_test { + ScopeKind::Test + } else { + ScopeKind::Module + }; + self.in_scope(scope_kind, |env| env.items(module.value.items, true))?; return Ok(()); } Item::Words(lines) => lines, @@ -770,7 +777,7 @@ code: format!("Cycle detected importing {}", path.to_string_lossy()), )); } - let import = self.in_scope(ScopeKind::File, |env| { + let import = self.in_scope(ScopeKind::Module, |env| { env.load_str_src(&input, &path).map(drop) })?; self.imports.insert(path.clone(), import); @@ -1504,8 +1511,8 @@ code: } let mut hit_file = false; for scope in self.higher_scopes.iter().rev() { - if scope.kind == ScopeKind::File { - if hit_file || self.scope.kind == ScopeKind::File { + if scope.kind == ScopeKind::Module { + if hit_file || self.scope.kind == ScopeKind::Module { break; } hit_file = true; @@ -2169,7 +2176,7 @@ code: .or_else(|| { self.higher_scopes .last() - .filter(|_| self.scope.kind != ScopeKind::File) + .filter(|_| self.scope.kind != ScopeKind::Module) .and_then(|scope| scope.names.get(name)) }) .map_or(true, |l| l.index != local.index) diff --git a/src/compile/modifier.rs b/src/compile/modifier.rs index a4e6437a..5fb95ae8 100644 --- a/src/compile/modifier.rs +++ b/src/compile/modifier.rs @@ -1290,7 +1290,7 @@ impl Compiler { Item::Import(import) => self .import(import, None) .map_err(|e| e.trace_macro(span.clone()))?, - Item::TestScope(_) => { + Item::Module(_) => { self.add_error(span.clone(), "Macros may not generate test scopes") } }; diff --git a/src/format.rs b/src/format.rs index d2730467..e344d469 100644 --- a/src/format.rs +++ b/src/format.rs @@ -575,11 +575,14 @@ impl<'a> Formatter<'a> { } fn format_item(&mut self, item: &Item) { match item { - Item::TestScope(items) => { + Item::Module(m) => { self.prev_import_function = None; self.output.push_str("---"); + if let Some(name) = &m.value.name { + self.push(&name.span, &name.value); + } self.output.push('\n'); - self.format_items(&items.value); + self.format_items(&m.value.items); self.output.push_str("---"); } Item::Words(lines) => { diff --git a/src/lsp.rs b/src/lsp.rs index cc8c9217..01c9536d 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -173,7 +173,7 @@ impl Spanner { let mut spans = Vec::new(); for item in items { match item { - Item::TestScope(items) => spans.extend(self.items_spans(&items.value)), + Item::Module(m) => spans.extend(self.items_spans(&m.value.items)), Item::Words(lines) => { for line in lines { spans.extend(self.words_spans(line)) diff --git a/src/parse.rs b/src/parse.rs index f7fb80be..413e3f1d 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -321,6 +321,8 @@ impl<'i> Parser<'i> { Item::Words(lines) } else if parse_scopes { let start = self.try_exact(TripleMinus.into())?; + self.try_spaces(); + let name = self.try_ident(); let items = self.items(false); let span = if let Some(end) = self.try_exact(TripleMinus.into()) { start.merge(end) @@ -328,7 +330,8 @@ impl<'i> Parser<'i> { self.errors.push(self.expected([TripleMinus])); start }; - Item::TestScope(span.sp(items)) + let module = ScopedModule { name, items }; + Item::Module(span.sp(module)) } else { return None; }