Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit cd74134

Browse files
committed
Merge branch 'master' of github.com:rust-lang-nursery/rls
2 parents 3e9cdcc + 1b4a6e3 commit cd74134

14 files changed

+139
-75
lines changed

contributing.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ temporary logging you may find the `eprintln` macro useful.
123123
Test using `cargo test`.
124124

125125
Testing is unfortunately minimal. There is support for regression tests, but not
126-
many actual tests exists yet. There is signifcant [work to do](https://github.com/rust-lang-nursery/rls/issues/12)
126+
many actual tests exists yet. There is significant [work to do](https://github.com/rust-lang-nursery/rls/issues/12)
127127
before we have a comprehensive testing story.
128128

129129
You can run the RLS in command line mode by running with an argument (any
130130
argument), e.g., `cargo run -- foo`. You need to run it in the root directory of
131-
the project to be analysed. This should initialise the RLS (which will take some
131+
the project to be analyzed. This should initialize the RLS (which will take some
132132
time for large projects) and then give you a `>` prompt. Type `help` (or just
133133
`h`) to see the commands available.
134134

@@ -223,7 +223,7 @@ inside your project's target directory.
223223

224224
The goal of the RLS project is to provide an awesome IDE experience *now*. That
225225
means not waiting for incremental compilation support in the compiler. However,
226-
Rust is a somewhat complex language to analyse and providing precise and
226+
Rust is a somewhat complex language to analyze and providing precise and
227227
complete information about programs requires using the compiler.
228228

229229
The RLS has two data sources - the compiler and Racer. The compiler is always
@@ -271,7 +271,7 @@ change](https://github.com/rust-lang-nursery/rls/issues/25)).
271271

272272
### Analysis data
273273

274-
From the compiler, we get a serialised dump of its analysis data (from name
274+
From the compiler, we get a serialized dump of its analysis data (from name
275275
resolution and type checking). We combine data from all crates and the standard
276276
libraries and combine this into an index for the whole project. We cross-
277277
reference and store this data in HashMaps and use it to look up data for the

debugging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ Some crates can have surprisingly large data files. Large data files can slow
149149
down the RLS to the point of crashing (or appearing to crash). Check the json
150150
files in the `target/rls/deps/save-analysis` directory. Anything over 1mb is
151151
suspicious. You can test if this is important by deleting the json file(s) and
152-
restating the extension (you'd have to do this every time you do a full build,
152+
restarting the extension (you'd have to do this every time you do a full build,
153153
for example after `cargo clean` or updating the toolchain).
154154

155155
If you find such large data files, please report an issue on this repo. We can

src/actions/mod.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use analysis::AnalysisHost;
1212
use vfs::Vfs;
1313
use config::{Config, FmtConfig};
14+
use serde_json;
15+
use url::Url;
1416
use span;
1517
use Span;
1618

@@ -211,6 +213,51 @@ fn find_word_at_pos(line: &str, pos: &Column) -> (Column, Column) {
211213
(span::Column::new_zero_indexed(start), span::Column::new_zero_indexed(end))
212214
}
213215

216+
// TODO include workspace Cargo.tomls in watchers / relevant
217+
/// Client file-watching request / filtering logic
218+
/// We want to watch workspace 'Cargo.toml', root 'Cargo.lock' & the root 'target' dir
219+
pub struct FileWatch<'ctx> {
220+
project_str: &'ctx str,
221+
project_uri: String,
222+
}
223+
224+
impl<'ctx> FileWatch<'ctx> {
225+
pub fn new(ctx: &'ctx InitActionContext) -> Self {
226+
Self {
227+
project_str: ctx.current_project.to_str().unwrap(),
228+
project_uri: Url::from_file_path(&ctx.current_project).unwrap().into_string(),
229+
}
230+
}
231+
232+
/// Returns json config for desired file watches
233+
pub fn watchers_config(&self) -> serde_json::Value {
234+
let pattern = format!("{}/Cargo{{.toml,.lock}}", self.project_str);
235+
let target_pattern = format!("{}/target", self.project_str);
236+
// For target, we only watch if it gets deleted.
237+
json!({
238+
"watchers": [{ "globPattern": pattern }, { "globPattern": target_pattern, "kind": 4 }]
239+
})
240+
}
241+
242+
/// Returns if a file change is relevant to the files we actually wanted to watch
243+
// Implementation note: This is expected to be called a large number of times in a loop
244+
// so should be fast / avoid allocation.
245+
#[inline]
246+
pub fn is_relevant(&self, change: &FileEvent) -> bool {
247+
let path = change.uri.as_str();
248+
249+
if !path.starts_with(&self.project_uri) {
250+
return false;
251+
}
252+
253+
let local = &path[self.project_uri.len()..];
254+
255+
local == "/Cargo.lock" || local == "/Cargo.toml"
256+
|| local == "/target" && change.typ == FileChangeType::Deleted
257+
}
258+
}
259+
260+
214261
#[cfg(test)]
215262
mod test {
216263
use super::*;
@@ -244,4 +291,4 @@ mod test {
244291
assert_range("span::Position<|T>", (15, 16));
245292
assert_range("span::Position<T|>", (15, 16));
246293
}
247-
}
294+
}

src/actions/notifications.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use actions::ActionContext;
12+
use actions::FileWatch;
1213
use vfs::Change;
1314
use config::Config;
1415
use serde::Deserialize;
@@ -42,13 +43,7 @@ impl<'a> NotificationAction<'a> for Initialized {
4243

4344
let ctx = ctx.inited();
4445

45-
// TODO we should watch for workspace Cargo.tomls too
46-
let pattern = format!("{}/Cargo{{.toml,.lock}}", ctx.current_project.to_str().unwrap());
47-
let target_pattern = format!("{}/target", ctx.current_project.to_str().unwrap());
48-
// For target, we only watch if it gets deleted.
49-
let options = json!({
50-
"watchers": [{ "globPattern": pattern }, { "globPattern": target_pattern, "kind": 4 }]
51-
});
46+
let options = FileWatch::new(&ctx).watchers_config();
5247
let output = serde_json::to_string(
5348
&RequestMessage::new(out.provide_id(),
5449
NOTIFICATION__RegisterCapability.to_owned(),
@@ -271,10 +266,20 @@ impl<'a> Action<'a> for DidChangeWatchedFiles {
271266
}
272267

273268
impl<'a> NotificationAction<'a> for DidChangeWatchedFiles {
274-
fn handle<O: Output>(&mut self, _params: DidChangeWatchedFilesParams, ctx: &mut ActionContext, out: O) -> Result<(), ()> {
269+
fn handle<O: Output>(
270+
&mut self,
271+
params: DidChangeWatchedFilesParams,
272+
ctx: &mut ActionContext,
273+
out: O,
274+
) -> Result<(), ()> {
275275
trace!("on_cargo_change: thread: {:?}", thread::current().id());
276+
276277
let ctx = ctx.inited();
277-
ctx.build_current_project(BuildPriority::Cargo, out);
278+
let file_watch = FileWatch::new(&ctx);
279+
280+
if params.changes.iter().any(|c| file_watch.is_relevant(c)) {
281+
ctx.build_current_project(BuildPriority::Cargo, out);
282+
}
278283

279284
Ok(())
280285
}

src/actions/requests.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -795,10 +795,10 @@ fn pos_to_racer_location(pos: Position) -> racer::Location {
795795
racer::Location::Coords(racer_coord(pos.row.one_indexed(), pos.col))
796796
}
797797

798-
fn location_from_racer_match(mtch: racer::Match) -> Option<Location> {
799-
let source_path = &mtch.filepath;
798+
fn location_from_racer_match(a_match: racer::Match) -> Option<Location> {
799+
let source_path = &a_match.filepath;
800800

801-
mtch.coords.map(|coord| {
801+
a_match.coords.map(|coord| {
802802
let (row, col) = from_racer_coord(coord);
803803
let loc = span::Location::new(row.zero_indexed(), col, source_path);
804804
ls_util::rls_location_to_location(&loc)

src/build/cargo.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ pub(super) fn cargo(internals: &Internals) -> BuildResult {
3939

4040
let diagnostics = Arc::new(Mutex::new(vec![]));
4141
let diagnostics_clone = diagnostics.clone();
42-
let analyses = Arc::new(Mutex::new(vec![]));
43-
let analyses_clone = analyses.clone();
42+
let analysis = Arc::new(Mutex::new(vec![]));
43+
let analysis_clone = analysis.clone();
4444
let out = Arc::new(Mutex::new(vec![]));
4545
let out_clone = out.clone();
4646

@@ -49,13 +49,13 @@ pub(super) fn cargo(internals: &Internals) -> BuildResult {
4949
// However, if Cargo doesn't run a separate thread, then we'll just wait
5050
// forever. Therefore, we spawn an extra thread here to be safe.
5151
let handle = thread::spawn(|| run_cargo(compilation_cx, config, vfs, env_lock,
52-
diagnostics, analyses, out));
52+
diagnostics, analysis, out));
5353

5454
match handle.join().map_err(|_| "thread panicked".into()).and_then(|res| res) {
5555
Ok(_) if workspace_mode => {
5656
let diagnostics = Arc::try_unwrap(diagnostics_clone).unwrap().into_inner().unwrap();
57-
let analyses = Arc::try_unwrap(analyses_clone).unwrap().into_inner().unwrap();
58-
BuildResult::Success(diagnostics, analyses)
57+
let analysis = Arc::try_unwrap(analysis_clone).unwrap().into_inner().unwrap();
58+
BuildResult::Success(diagnostics, analysis)
5959
},
6060
Ok(_) => BuildResult::Success(vec![], vec![]),
6161
Err(err) => {
@@ -71,7 +71,7 @@ fn run_cargo(compilation_cx: Arc<Mutex<CompilationContext>>,
7171
vfs: Arc<Vfs>,
7272
env_lock: Arc<EnvironmentLock>,
7373
compiler_messages: Arc<Mutex<Vec<String>>>,
74-
analyses: Arc<Mutex<Vec<Analysis>>>,
74+
analysis: Arc<Mutex<Vec<Analysis>>>,
7575
out: Arc<Mutex<Vec<u8>>>) -> CargoResult<()> {
7676
// Lock early to guarantee synchronized access to env var for the scope of Cargo routine.
7777
// Additionally we need to pass inner lock to RlsExecutor, since it needs to hand it down
@@ -169,7 +169,7 @@ fn run_cargo(compilation_cx: Arc<Mutex<CompilationContext>>,
169169
inner_lock,
170170
vfs,
171171
compiler_messages,
172-
analyses);
172+
analysis);
173173

174174
compile_with_exec(&ws, &compile_opts, Arc::new(exec))?;
175175

@@ -188,7 +188,7 @@ struct RlsExecutor {
188188
/// env var access during underlying `rustc()` calls during parallel `exec()` callback threads.
189189
env_lock: environment::InnerLock,
190190
vfs: Arc<Vfs>,
191-
analyses: Arc<Mutex<Vec<Analysis>>>,
191+
analysis: Arc<Mutex<Vec<Analysis>>>,
192192
workspace_mode: bool,
193193
/// Packages which are directly a member of the workspace, for which
194194
/// analysis and diagnostics will be provided
@@ -204,7 +204,7 @@ impl RlsExecutor {
204204
env_lock: environment::InnerLock,
205205
vfs: Arc<Vfs>,
206206
compiler_messages: Arc<Mutex<Vec<String>>>,
207-
analyses: Arc<Mutex<Vec<Analysis>>>)
207+
analysis: Arc<Mutex<Vec<Analysis>>>)
208208
-> RlsExecutor {
209209
let workspace_mode = config.lock().unwrap().workspace_mode;
210210
let (cur_package_id, member_packages) = if workspace_mode {
@@ -225,21 +225,21 @@ impl RlsExecutor {
225225
config,
226226
env_lock,
227227
vfs,
228-
analyses,
228+
analysis,
229229
workspace_mode,
230230
member_packages: Mutex::new(member_packages),
231231
compiler_messages,
232232
}
233233
}
234234

235-
/// Returns wheter a given package is a primary one (every member of the
235+
/// Returns whether a given package is a primary one (every member of the
236236
/// workspace is considered as such).
237237
fn is_primary_crate(&self, id: &PackageId) -> bool {
238238
if self.workspace_mode {
239239
self.member_packages.lock().unwrap().contains(id)
240240
} else {
241241
let cur_package_id = self.cur_package_id.lock().unwrap();
242-
id == cur_package_id.as_ref().expect("Executor has not been initialised")
242+
id == cur_package_id.as_ref().expect("Executor has not been initialized")
243243
}
244244
}
245245
}
@@ -352,7 +352,7 @@ impl Executor for RlsExecutor {
352352
{
353353
let config = self.config.lock().unwrap();
354354
let crate_type = parse_arg(cargo_args, "--crate-type");
355-
// Becase we only try to emulate `cargo test` using `cargo check`, so for now
355+
// Because we only try to emulate `cargo test` using `cargo check`, so for now
356356
// assume crate_type arg (i.e. in `cargo test` it isn't specified for --test targets)
357357
// and build test harness only for final crate type
358358
let crate_type = crate_type.expect("no crate-type in rustc command line");
@@ -417,7 +417,7 @@ impl Executor for RlsExecutor {
417417
BuildResult::Success(mut messages, mut analysis) |
418418
BuildResult::Failure(mut messages, mut analysis) => {
419419
self.compiler_messages.lock().unwrap().append(&mut messages);
420-
self.analyses.lock().unwrap().append(&mut analysis);
420+
self.analysis.lock().unwrap().append(&mut analysis);
421421
}
422422
_ => {}
423423
}

src/build/environment.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl<'a> Drop for Environment<'a> {
6767
/// It uses two locks instead of one, because RLS, while executing a Cargo build routine, not only
6868
/// needs to guarantee consistent env vars across the Cargo invocation, but also, while holding it,
6969
/// it needs to provide a more fine-grained way to synchronize env vars across different inner
70-
/// compiler invokations, for which Cargo sets specific env vars.
70+
/// compiler invocations, for which Cargo sets specific env vars.
7171
/// To enforce proper env var guarantees, regular rustc and Cargo build routines must first acquire
7272
/// the first, outer lock. Only then, if needed, nested rustc calls inside Cargo routine can
7373
/// acquire the second, inner lock.

src/build/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ struct Internals {
8888

8989
#[derive(Debug)]
9090
pub enum BuildResult {
91-
// Build was succesful, argument is warnings.
91+
// Build was successful, argument is warnings.
9292
Success(Vec<String>, Vec<Analysis>),
9393
// Build finished with errors, argument is errors and warnings.
9494
Failure(Vec<String>, Vec<Analysis>),
95-
// Build was coelesced with another build.
95+
// Build was coalesced with another build.
9696
Squashed,
9797
// There was an error attempting to build.
9898
Err,
@@ -320,11 +320,11 @@ impl BuildQueue {
320320
thread::sleep(Duration::from_millis(wait_to_build));
321321

322322
// Check if a new build arrived while we were sleeping.
323-
let interupt = {
323+
let interrupt = {
324324
let queued = queued.lock().unwrap();
325325
queued.0.is_pending() || queued.1.is_pending()
326326
};
327-
if interupt {
327+
if interrupt {
328328
and_then(BuildResult::Squashed);
329329
continue;
330330
}
@@ -398,7 +398,7 @@ impl Internals {
398398
}
399399

400400
let result = self.build();
401-
// On a successful build, clear dirty files that were successfuly built
401+
// On a successful build, clear dirty files that were successfully built
402402
// now. It's possible that a build was scheduled with given files, but
403403
// user later changed them. These should still be left as dirty (not built).
404404
match *&result {

src/build/rustc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub fn rustc(vfs: &Vfs, args: &[String], envs: &HashMap<String, Option<OsString>
7373
});
7474

7575
// FIXME(#25) given that we are running the compiler directly, there is no need
76-
// to serialise the error messages - we should pass them in memory.
76+
// to serialize the error messages - we should pass them in memory.
7777
let err_buf = Arc::try_unwrap(err_buf).unwrap().into_inner().unwrap();
7878
let err_buf = String::from_utf8(err_buf).unwrap();
7979
let stderr_json_msgs: Vec<_> = err_buf.lines().map(String::from).collect();

src/cmd.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,8 @@ impl server::MessageReader for ChannelMsgReader {
228228
}
229229
}
230230

231-
// Initialise a server, returns the sender end of a channel for posting messages.
232-
// The initialised server will live on its own thread and look after the receiver.
231+
// Initialize a server, returns the sender end of a channel for posting messages.
232+
// The initialized server will live on its own thread and look after the receiver.
233233
fn init() -> Sender<String> {
234234
let analysis = Arc::new(AnalysisHost::new(Target::Debug));
235235
let vfs = Arc::new(Vfs::new());
@@ -243,7 +243,7 @@ fn init() -> Sender<String> {
243243
thread::spawn(move || LsService::run(service));
244244

245245
sender.send(initialize(::std::env::current_dir().unwrap().to_str().unwrap().to_owned()).to_string()).expect("Error sending init");
246-
println!("Initialising (look for `diagnosticsEnd` message)...");
246+
println!("Initializing (look for `diagnosticsEnd` message)...");
247247

248248
sender
249249
}

src/server/io.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub trait Output: Sync + Send + Clone + 'static {
107107
let data = match serde_json::to_string(data) {
108108
Ok(data) => data,
109109
Err(e) => {
110-
debug!("Could not serialise data for success message. ");
110+
debug!("Could not serialize data for success message. ");
111111
debug!(" Data: `{:?}`", data);
112112
debug!(" Error: {:?}", e);
113113
return;

0 commit comments

Comments
 (0)