Skip to content

Commit 0b70e05

Browse files
committed
Revert "Add Environment::add_rbs and route EnvironmentLoader through it"
This reverts commit fcf2f0f.
1 parent 8df6b4d commit 0b70e05

2 files changed

Lines changed: 66 additions & 70 deletions

File tree

rust/ruby-rbs/src/environment/mod.rs

Lines changed: 12 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,8 @@ pub mod source;
22

33
pub use source::{Source, SourceKind};
44

5-
use std::path::{Path, PathBuf};
6-
7-
use crate::ast::AstConverter;
8-
use crate::buffer::Buffer;
95
use crate::interners::Interners;
106
use crate::loader::{EnvironmentLoader, LoadError};
11-
use crate::node;
127

138
/// Owning the interners here gives a single `Environment` value the same
149
/// role as the Ruby implementation's global name pool: names interned while
@@ -34,56 +29,12 @@ impl Environment {
3429
&self.sources
3530
}
3631

37-
/// Parses `content` with this environment's own [`Interners`] and adds it
38-
/// as a source, without going through an [`EnvironmentLoader`] — the
39-
/// entry point for editor / in-memory callers (`RBS::Environment#add_source`
40-
/// equivalent, e.g. Steep). Parsing always uses this environment's
41-
/// `Interners`, so a `Source` added this way can never carry ids from a
42-
/// different environment.
43-
pub fn add_rbs(
44-
&mut self,
45-
path: PathBuf,
46-
content: String,
47-
kind: SourceKind,
48-
) -> Result<(), LoadError> {
49-
let signature = node::parse(&content).map_err(|message| LoadError::Parse {
50-
path: path.clone(),
51-
message,
52-
})?;
53-
54-
let mut converter =
55-
AstConverter::new(&mut self.interners.strings, &mut self.interners.type_names);
56-
let directives = signature
57-
.directives()
58-
.iter()
59-
.map(|node| converter.convert_directive(&node))
60-
.collect();
61-
let declarations = signature
62-
.declarations()
63-
.iter()
64-
.map(|node| converter.convert_declaration(&node))
65-
.collect();
66-
// SignatureNode borrows `content` and has a Drop impl; drop it
67-
// explicitly before moving `content` into the Buffer.
68-
drop(signature);
69-
70-
self.sources.push(Source {
71-
buffer: Buffer::new(path, content),
72-
directives,
73-
declarations,
74-
kind,
75-
});
76-
Ok(())
32+
pub(crate) fn interners_mut(&mut self) -> &mut Interners {
33+
&mut self.interners
7734
}
7835

79-
/// Reads `path` and adds it as a source; a thin wrapper around
80-
/// [`Environment::add_rbs`].
81-
pub fn add_rbs_file(&mut self, path: &Path, kind: SourceKind) -> Result<(), LoadError> {
82-
let content = std::fs::read_to_string(path).map_err(|source| LoadError::Io {
83-
path: path.to_path_buf(),
84-
source,
85-
})?;
86-
self.add_rbs(path.to_path_buf(), content, kind)
36+
pub(crate) fn add_source(&mut self, source: Source) {
37+
self.sources.push(source);
8738
}
8839

8940
pub fn from_loader(loader: &EnvironmentLoader) -> Result<Environment, LoadError> {
@@ -102,27 +53,21 @@ impl Default for Environment {
10253
#[cfg(test)]
10354
mod tests {
10455
use super::*;
105-
use crate::ast::Declaration;
10656

10757
#[test]
10858
fn environment_owns_interners() {
10959
let mut env = Environment::new();
110-
env.add_rbs(
111-
PathBuf::from("test.rbs"),
112-
"class Foo\nend\n".to_string(),
113-
SourceKind::Dir {
114-
path: PathBuf::from("."),
115-
},
116-
)
117-
.unwrap();
11860

119-
let [Declaration::Class(class)] = env.sources()[0].declarations.as_slice() else {
120-
panic!("expected one class declaration");
121-
};
61+
let interners = env.interners_mut();
62+
let symbol = interners.strings.intern("Foo");
63+
let root = interners.type_names.absolute_root();
64+
let name = interners.type_names.append(root, symbol);
65+
12266
let interners = env.interners();
12367
assert_eq!(
124-
interners.type_names.display(class.name, &interners.strings),
125-
"Foo"
68+
interners.type_names.display(name, &interners.strings),
69+
"::Foo"
12670
);
71+
assert!(env.sources().is_empty());
12772
}
12873
}

rust/ruby-rbs/src/loader/mod.rs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use std::collections::HashSet;
22
use std::fmt;
33
use std::io;
4-
use std::path::PathBuf;
4+
use std::path::{Path, PathBuf};
55

6-
use crate::environment::{Environment, SourceKind};
6+
use crate::ast::AstConverter;
7+
use crate::buffer::Buffer;
8+
use crate::environment::{Environment, Source, SourceKind};
79
use crate::file_finder;
10+
use crate::interners::Interners;
11+
use crate::node;
812

913
#[derive(Debug)]
1014
#[non_exhaustive]
@@ -98,7 +102,8 @@ impl EnvironmentLoader {
98102
if !seen_files.insert(path.clone()) {
99103
continue;
100104
}
101-
env.add_rbs_file(&path, kind.clone())?;
105+
let source = parse_one(&path, &kind, env.interners_mut())?;
106+
env.add_source(source);
102107
loaded.push(LoadedFile {
103108
path,
104109
kind: kind.clone(),
@@ -135,3 +140,49 @@ impl EnvironmentLoader {
135140
result
136141
}
137142
}
143+
144+
/// Deliberately a free function taking only the interners, so the load loop
145+
/// can later be parallelised by handing each worker its own [`Interners`].
146+
/// The parser's `SignatureNode` holds raw pointers and is not `Send`, so it
147+
/// must not escape this function — only the owned `Source` does.
148+
///
149+
/// Crate-private: a caller outside the crate has no way to merge its
150+
/// worker-local [`Interners`] into the environment, so the `Source` it
151+
/// produced would carry ids that environment cannot resolve.
152+
pub(crate) fn parse_one(
153+
path: &Path,
154+
kind: &SourceKind,
155+
interners: &mut Interners,
156+
) -> Result<Source, LoadError> {
157+
let content = std::fs::read_to_string(path).map_err(|source| LoadError::Io {
158+
path: path.to_path_buf(),
159+
source,
160+
})?;
161+
162+
let signature = node::parse(&content).map_err(|message| LoadError::Parse {
163+
path: path.to_path_buf(),
164+
message,
165+
})?;
166+
167+
let mut converter = AstConverter::new(&mut interners.strings, &mut interners.type_names);
168+
let directives = signature
169+
.directives()
170+
.iter()
171+
.map(|node| converter.convert_directive(&node))
172+
.collect();
173+
let declarations = signature
174+
.declarations()
175+
.iter()
176+
.map(|node| converter.convert_declaration(&node))
177+
.collect();
178+
// SignatureNode borrows `content` and has a Drop impl; drop it
179+
// explicitly before moving `content` into the Buffer.
180+
drop(signature);
181+
182+
Ok(Source {
183+
buffer: Buffer::new(path.to_path_buf(), content),
184+
directives,
185+
declarations,
186+
kind: kind.clone(),
187+
})
188+
}

0 commit comments

Comments
 (0)