aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/release.yaml1
-rw-r--r--crates/ra_prof/src/hprof.rs45
-rw-r--r--crates/ra_syntax/src/ast.rs15
-rw-r--r--crates/ra_syntax/src/ast/tokens.rs17
-rw-r--r--xtask/src/dist.rs8
5 files changed, 46 insertions, 40 deletions
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 2c1192f07..3f52f31f8 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -39,7 +39,6 @@ jobs:
39 with: 39 with:
40 toolchain: stable 40 toolchain: stable
41 profile: minimal 41 profile: minimal
42 target: x86_64-unknown-linux-musl
43 override: true 42 override: true
44 43
45 - name: Install Nodejs 44 - name: Install Nodejs
diff --git a/crates/ra_prof/src/hprof.rs b/crates/ra_prof/src/hprof.rs
index 2b8a90363..a3f5321fb 100644
--- a/crates/ra_prof/src/hprof.rs
+++ b/crates/ra_prof/src/hprof.rs
@@ -30,8 +30,9 @@ pub fn init_from(spec: &str) {
30pub type Label = &'static str; 30pub type Label = &'static str;
31 31
32/// This function starts a profiling scope in the current execution stack with a given description. 32/// This function starts a profiling scope in the current execution stack with a given description.
33/// It returns a Profile structure and measure elapsed time between this method invocation and Profile structure drop. 33/// It returns a `Profile` struct that measures elapsed time between this method invocation and `Profile` struct drop.
34/// It supports nested profiling scopes in case when this function invoked multiple times at the execution stack. In this case the profiling information will be nested at the output. 34/// It supports nested profiling scopes in case when this function is invoked multiple times at the execution stack.
35/// In this case the profiling information will be nested at the output.
35/// Profiling information is being printed in the stderr. 36/// Profiling information is being printed in the stderr.
36/// 37///
37/// # Example 38/// # Example
@@ -58,36 +59,35 @@ pub type Label = &'static str;
58/// ``` 59/// ```
59pub fn profile(label: Label) -> Profiler { 60pub fn profile(label: Label) -> Profiler {
60 assert!(!label.is_empty()); 61 assert!(!label.is_empty());
61 let enabled = PROFILING_ENABLED.load(Ordering::Relaxed) 62
62 && PROFILE_STACK.with(|stack| stack.borrow_mut().push(label)); 63 if PROFILING_ENABLED.load(Ordering::Relaxed)
63 let label = if enabled { Some(label) } else { None }; 64 && PROFILE_STACK.with(|stack| stack.borrow_mut().push(label))
64 Profiler { label, detail: None } 65 {
66 Profiler(Some(ProfilerImpl { label, detail: None }))
67 } else {
68 Profiler(None)
69 }
65} 70}
66 71
67pub struct Profiler { 72pub struct Profiler(Option<ProfilerImpl>);
68 label: Option<Label>, 73
74struct ProfilerImpl {
75 label: Label,
69 detail: Option<String>, 76 detail: Option<String>,
70} 77}
71 78
72impl Profiler { 79impl Profiler {
73 pub fn detail(mut self, detail: impl FnOnce() -> String) -> Profiler { 80 pub fn detail(mut self, detail: impl FnOnce() -> String) -> Profiler {
74 if self.label.is_some() { 81 if let Some(profiler) = &mut self.0 {
75 self.detail = Some(detail()) 82 profiler.detail = Some(detail())
76 } 83 }
77 self 84 self
78 } 85 }
79} 86}
80 87
81impl Drop for Profiler { 88impl Drop for ProfilerImpl {
82 fn drop(&mut self) { 89 fn drop(&mut self) {
83 match self { 90 PROFILE_STACK.with(|it| it.borrow_mut().pop(self.label, self.detail.take()));
84 Profiler { label: Some(label), detail } => {
85 PROFILE_STACK.with(|stack| {
86 stack.borrow_mut().pop(label, detail.take());
87 });
88 }
89 Profiler { label: None, .. } => (),
90 }
91 } 91 }
92} 92}
93 93
@@ -179,21 +179,18 @@ impl ProfileStack {
179 pub fn pop(&mut self, label: Label, detail: Option<String>) { 179 pub fn pop(&mut self, label: Label, detail: Option<String>) {
180 let start = self.starts.pop().unwrap(); 180 let start = self.starts.pop().unwrap();
181 let duration = start.elapsed(); 181 let duration = start.elapsed();
182 let level = self.starts.len();
183 self.messages.finish(Message { duration, label, detail }); 182 self.messages.finish(Message { duration, label, detail });
184 if level == 0 { 183 if self.starts.is_empty() {
185 let longer_than = self.filter.longer_than; 184 let longer_than = self.filter.longer_than;
186 // Convert to millis for comparison to avoid problems with rounding 185 // Convert to millis for comparison to avoid problems with rounding
187 // (otherwise we could print `0ms` despite user's `>0` filter when 186 // (otherwise we could print `0ms` despite user's `>0` filter when
188 // `duration` is just a few nanos). 187 // `duration` is just a few nanos).
189 if duration.as_millis() > longer_than.as_millis() { 188 if duration.as_millis() > longer_than.as_millis() {
190 let stderr = stderr();
191 if let Some(root) = self.messages.root() { 189 if let Some(root) = self.messages.root() {
192 print(&self.messages, root, 0, longer_than, &mut stderr.lock()); 190 print(&self.messages, root, 0, longer_than, &mut stderr().lock());
193 } 191 }
194 } 192 }
195 self.messages.clear(); 193 self.messages.clear();
196 assert!(self.starts.is_empty())
197 } 194 }
198 } 195 }
199} 196}
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 7fca5661e..a716e525b 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -243,6 +243,21 @@ fn test_comments_preserve_trailing_whitespace() {
243} 243}
244 244
245#[test] 245#[test]
246fn test_four_slash_line_comment() {
247 let file = SourceFile::parse(
248 r#"
249 //// too many slashes to be a doc comment
250 /// doc comment
251 mod foo {}
252 "#,
253 )
254 .ok()
255 .unwrap();
256 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
257 assert_eq!("doc comment", module.doc_comment_text().unwrap());
258}
259
260#[test]
246fn test_where_predicates() { 261fn test_where_predicates() {
247 fn assert_bound(text: &str, bound: Option<TypeBound>) { 262 fn assert_bound(text: &str, bound: Option<TypeBound>) {
248 assert_eq!(text, bound.unwrap().syntax().text().to_string()); 263 assert_eq!(text, bound.unwrap().syntax().text().to_string());
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs
index 3865729b8..74906d8a6 100644
--- a/crates/ra_syntax/src/ast/tokens.rs
+++ b/crates/ra_syntax/src/ast/tokens.rs
@@ -13,7 +13,12 @@ impl Comment {
13 } 13 }
14 14
15 pub fn prefix(&self) -> &'static str { 15 pub fn prefix(&self) -> &'static str {
16 prefix_by_kind(self.kind()) 16 for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() {
17 if *k == self.kind() && self.text().starts_with(prefix) {
18 return prefix;
19 }
20 }
21 unreachable!()
17 } 22 }
18} 23}
19 24
@@ -48,6 +53,7 @@ pub enum CommentPlacement {
48const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = { 53const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = {
49 use {CommentPlacement::*, CommentShape::*}; 54 use {CommentPlacement::*, CommentShape::*};
50 &[ 55 &[
56 ("////", CommentKind { shape: Line, doc: None }),
51 ("///", CommentKind { shape: Line, doc: Some(Outer) }), 57 ("///", CommentKind { shape: Line, doc: Some(Outer) }),
52 ("//!", CommentKind { shape: Line, doc: Some(Inner) }), 58 ("//!", CommentKind { shape: Line, doc: Some(Inner) }),
53 ("/**", CommentKind { shape: Block, doc: Some(Outer) }), 59 ("/**", CommentKind { shape: Block, doc: Some(Outer) }),
@@ -69,15 +75,6 @@ fn kind_by_prefix(text: &str) -> CommentKind {
69 panic!("bad comment text: {:?}", text) 75 panic!("bad comment text: {:?}", text)
70} 76}
71 77
72fn prefix_by_kind(kind: CommentKind) -> &'static str {
73 for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() {
74 if *k == kind {
75 return prefix;
76 }
77 }
78 unreachable!()
79}
80
81impl Whitespace { 78impl Whitespace {
82 pub fn spans_multiple_lines(&self) -> bool { 79 pub fn spans_multiple_lines(&self) -> bool {
83 let text = self.text(); 80 let text = self.text();
diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs
index a56eeef8d..aef68089e 100644
--- a/xtask/src/dist.rs
+++ b/xtask/src/dist.rs
@@ -50,21 +50,19 @@ fn dist_server(nightly: bool) -> Result<()> {
50 if cfg!(target_os = "linux") { 50 if cfg!(target_os = "linux") {
51 std::env::set_var("CC", "clang"); 51 std::env::set_var("CC", "clang");
52 run!( 52 run!(
53 "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release 53 "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release"
54 --target x86_64-unknown-linux-musl
55 "
56 // We'd want to add, but that requires setting the right linker somehow 54 // We'd want to add, but that requires setting the right linker somehow
57 // --features=jemalloc 55 // --features=jemalloc
58 )?; 56 )?;
59 if !nightly { 57 if !nightly {
60 run!("strip ./target/x86_64-unknown-linux-musl/release/rust-analyzer")?; 58 run!("strip ./target/release/rust-analyzer")?;
61 } 59 }
62 } else { 60 } else {
63 run!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release")?; 61 run!("cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --release")?;
64 } 62 }
65 63
66 let (src, dst) = if cfg!(target_os = "linux") { 64 let (src, dst) = if cfg!(target_os = "linux") {
67 ("./target/x86_64-unknown-linux-musl/release/rust-analyzer", "./dist/rust-analyzer-linux") 65 ("./target/release/rust-analyzer", "./dist/rust-analyzer-linux")
68 } else if cfg!(target_os = "windows") { 66 } else if cfg!(target_os = "windows") {
69 ("./target/release/rust-analyzer.exe", "./dist/rust-analyzer-windows.exe") 67 ("./target/release/rust-analyzer.exe", "./dist/rust-analyzer-windows.exe")
70 } else if cfg!(target_os = "macos") { 68 } else if cfg!(target_os = "macos") {