aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/libanalysis/src/lib.rs12
-rw-r--r--crates/libsyntax2/src/parser_impl/mod.rs10
-rw-r--r--crates/server/src/main.rs2
3 files changed, 21 insertions, 3 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs
index 7a34d354e..fe2c3c2e6 100644
--- a/crates/libanalysis/src/lib.rs
+++ b/crates/libanalysis/src/lib.rs
@@ -15,6 +15,7 @@ mod module_map;
15use std::{ 15use std::{
16 fmt, 16 fmt,
17 path::{Path, PathBuf}, 17 path::{Path, PathBuf},
18 panic,
18 sync::{ 19 sync::{
19 Arc, 20 Arc,
20 atomic::{AtomicBool, Ordering::SeqCst}, 21 atomic::{AtomicBool, Ordering::SeqCst},
@@ -307,8 +308,15 @@ impl FileData {
307 } 308 }
308 309
309 fn syntax(&self) -> &File { 310 fn syntax(&self) -> &File {
310 self.syntax 311 let text = &self.text;
311 .get_or_init(|| File::parse(&self.text)) 312 let syntax = &self.syntax;
313 match panic::catch_unwind(panic::AssertUnwindSafe(|| syntax.get_or_init(|| File::parse(text)))) {
314 Ok(file) => file,
315 Err(err) => {
316 error!("Parser paniced on:\n------\n{}\n------\n", &self.text);
317 panic::resume_unwind(err)
318 }
319 }
312 } 320 }
313 321
314 fn syntax_transient(&self) -> File { 322 fn syntax_transient(&self) -> File {
diff --git a/crates/libsyntax2/src/parser_impl/mod.rs b/crates/libsyntax2/src/parser_impl/mod.rs
index f60ef80f0..b343b404f 100644
--- a/crates/libsyntax2/src/parser_impl/mod.rs
+++ b/crates/libsyntax2/src/parser_impl/mod.rs
@@ -1,6 +1,8 @@
1mod event; 1mod event;
2mod input; 2mod input;
3 3
4use std::cell::Cell;
5
4use { 6use {
5 lexer::Token, 7 lexer::Token,
6 parser_api::Parser, 8 parser_api::Parser,
@@ -51,6 +53,7 @@ pub(crate) struct ParserImpl<'t> {
51 53
52 pos: InputPosition, 54 pos: InputPosition,
53 events: Vec<Event>, 55 events: Vec<Event>,
56 steps: Cell<u32>,
54} 57}
55 58
56impl<'t> ParserImpl<'t> { 59impl<'t> ParserImpl<'t> {
@@ -60,6 +63,7 @@ impl<'t> ParserImpl<'t> {
60 63
61 pos: InputPosition::new(), 64 pos: InputPosition::new(),
62 events: Vec::new(), 65 events: Vec::new(),
66 steps: Cell::new(0),
63 } 67 }
64 } 68 }
65 69
@@ -91,6 +95,12 @@ impl<'t> ParserImpl<'t> {
91 } 95 }
92 96
93 pub(super) fn nth(&self, n: u32) -> SyntaxKind { 97 pub(super) fn nth(&self, n: u32) -> SyntaxKind {
98 let steps = self.steps.get();
99 if steps > 10_000_000 {
100 panic!("the parser seems stuck");
101 }
102 self.steps.set(steps + 1);
103
94 self.inp.kind(self.pos + n) 104 self.inp.kind(self.pos + n)
95 } 105 }
96 106
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs
index 5e4c0fe7e..615dd082c 100644
--- a/crates/server/src/main.rs
+++ b/crates/server/src/main.rs
@@ -40,7 +40,7 @@ use ::{
40pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 40pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
41 41
42fn main() -> Result<()> { 42fn main() -> Result<()> {
43 Logger::with_env() 43 Logger::with_env_or_str("m=error")
44 .duplicate_to_stderr(Duplicate::All) 44 .duplicate_to_stderr(Duplicate::All)
45 .log_to_file() 45 .log_to_file()
46 .directory("log") 46 .directory("log")