Commit graph

187 commits

Author SHA1 Message Date
Arnaud
95d239da99 Specialization for async traits 2021-02-15 18:33:12 +01:00
Lukas Wirth
7b64622780 Don't rename field record patterns directly 2021-02-13 23:47:21 +01:00
Lukas Wirth
d644728d82 Refactor reference searching to work with the ast 2021-02-12 18:58:28 +01:00
Aleksey Kladov
61f15b72ac Add parsing benchmark 2021-02-09 21:52:34 +03:00
Aleksey Kladov
4b1279d0b1 Infra for "unit" benchmarking 2021-02-09 20:25:39 +03:00
kjeremy
0c3b38695a Update crates
Pulls in https://github.com/rust-lang/chalk/pull/682
2021-02-08 11:38:51 -05:00
Aleksey Kladov
7022ea52b5 AdtDef -> Adt 2021-02-07 14:15:02 +03:00
bors[bot]
ac5958485e
Merge #7535
7535: Extract function assist r=cpud36 a=cpud36

This PR adds `extract function/method` assist. closes #5409.

# Supported features
Assist should support extracting from expressions(`1`, `2 + 2`, `loop { }`) and from a series of statements, e.g.:
```rust
foo();
$0bar();
baz();$0
quix();
```
Assist also supports extracting parameters, like:
```rust
fn foo() -> i32 {
  let n = 1;
  $0n + 1$0
}

// -
fn foo() -> i32 {
  let n = 1;
  fun_name(n)
}

fn fun_name(n: i32) -> i32 {
  n + 1
}
```

Extracting methods also generally works.

Assist allows referencing outer variables, both mutably and immutably, and handles handles access to variables local to extracted function:
```rust
fn foo() {
  let mut n = 1;
  let mut m = 2;
  let mut moved_v = Vec::new();
  let mut ref_mut_v = Vec::new();
  $0
  n += 1;
  let k = 1;
  moved_v.push(n);
  let r = &mut m;
  ref_mut_v.push(*r);
  let h = 3;
  $0
  n = ref_mut_v.len() + k;
  n -= h + m;
}

// -
fn foo() {
  let mut n = 1;
  let mut m = 2;
  let mut moved_v = Vec::new();
  let mut ref_mut_v = Vec::new();
 
  let (k, h) =  fun_name(&mut n, moved_v, &mut m, &mut ref_mut_v);

  n = ref_mut_v.len() + k;
  n -= h + m;
}

fn fun_name(n: &mut i32, mut moved_v: Vec<i32>, m: &mut i32, ref_mut_v: &mut Vec<i32>) -> (i32, i32) {
  *n += 1;
  let k = 1;
  moved_v.push(*n);
  let r = m;
  ref_mut_v.push(*r);
  let h = 3;
  (k, h)
}
```

So we handle both input and output paramters

# Showcase

![extract_cursor_in_range_3](https://user-images.githubusercontent.com/4218373/106980190-c9870800-6770-11eb-83d9-3d36b2550ff6.gif)
![fill_match_arms_discard_wildcard](https://user-images.githubusercontent.com/4218373/106980197-cbe96200-6770-11eb-96b0-14c27894fac0.gif)
![ide_db_helpers_handle_kind](https://user-images.githubusercontent.com/4218373/106980201-cdb32580-6770-11eb-9e6e-6ac8155d65ac.gif)
![ide_db_imports_location_local_query](https://user-images.githubusercontent.com/4218373/106980205-cf7ce900-6770-11eb-8516-653c8fcca807.gif)

# Working with non-`Copy` types

Consider the following example:
```rust
fn foo() {
  let v = Vec::new();
  $0
  let n = v.len();
  $0
  let is_empty = v.is_empty();
}
```
`v` must be a parameter to extracted function. 
The question is, what type should it have.
It could be `v: Vec<i32>`, or `v: &Vec<i32>`. 
The former is incorrect for `Vec<i32>`, but the later is silly for `i32`.

To resolve this we need to know if the type implements `Copy` trait.

I didn't find any api available from assists to query this. 
`hir_ty::method_resolution::implements` seems relevant, but is isn't publicly re-exported from `hir`.

# Star(`*`) token and pointer dereference

If I understand correctly, in order to create expression like `*p`, one should use `ast::make::expr_prefix(T![*], ...)`, which
in turn calls `token(T![*])`.

`token` does not have star in `tokens::SOURCE_FILE`, so this panics.
I had to add `*` to `SOURCE_FILE` to make it work.

Correct me if this is not intended way to do this.

# Lowering access `value -> mut ref -> shared ref`

Consider the following example:
```rust
fn foo() {
  let v = Vec::new();
  $0 let n = v.len(); $0
}
```
`v` is not used after extracted function body, so both `v: &Vec<i32>` and `v: Vec<i32>` would work.
Currently the later would be chosen.

We can however check the body of extracted function and conclude that `v: &Vec<i32>` is sufficient.
Using `v: &Vec<i32>`(that is a minimal required access level) might be a better default.
I am unsure.

# Cleanup
The assist seems to be reasonably handling most of common cases.
If there are no concerns with code it produces(i.e. with test cases), I will start cleaning up

[edit]
added showcase


Co-authored-by: Vladyslav Katasonov <cpud47@gmail.com>
2021-02-05 02:55:56 +00:00
Vladyslav Katasonov
f102616aae allow modifications of vars from outer scope inside extracted function
It currently allows only directly setting variable.
No `&mut` references or methods.
2021-02-03 23:45:03 +03:00
Edwin Cheng
e73ffbf1e5 Add cargo file tidy test 2021-02-03 22:01:09 +08:00
Laurențiu Nicola
6b60206669 Bump rustc_lexer 2021-02-02 17:40:01 +02:00
Lukas Wirth
6c2ce55150 Fix ast::String::value not properly escaping in some cases 2021-01-30 16:31:19 +01:00
Laurențiu Nicola
efafcf2428 Bump deps 2021-01-27 14:22:19 +02:00
Aleksey Kladov
1df711b95c ⬆️ rowan 2021-01-25 12:32:35 +03:00
Lukas Wirth
70d43c3faf Add validation for mutable const items 2021-01-24 02:17:41 +01:00
kjeremy
f006517857 Up lexer 2021-01-21 09:31:06 -05:00
Aleksey Kladov
3429b32ad1 ⬆️ rowan
It now stores text inline with tokens
2021-01-20 14:04:53 +03:00
Aleksey Kladov
46b4f89c92 . 2021-01-20 01:56:11 +03:00
Aleksey Kladov
cd21b0e9c1 ⬆️ rowan 2021-01-19 22:11:42 +03:00
Lukas Wirth
b26002410b Parse impl const Trait 2021-01-18 20:18:02 +01:00
Jonas Schievink
872bf09381 Add MacroType syntax 2021-01-18 17:56:35 +01:00
bors[bot]
9daba961f2
Merge #7291
7291: Wrap remaining self/super/crate in Name{Ref} r=matklad a=Veykril

That should be the remaining special casing for `self` 🎉 

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2021-01-18 16:13:06 +00:00
Aleksey Kladov
b38414c7f4 When building an item-tree, keep fewer nodes in memory 2021-01-16 23:07:28 +03:00
Lukas Wirth
98718e0544 Wrap remaining self/super/crate in Name{Ref} 2021-01-15 22:18:43 +01:00
unexge
a3a722de9f Add Unmerge Use assist 2021-01-15 22:14:51 +03:00
bors[bot]
8a869e870a
Merge #7288
7288: Handle self/super/crate in PathSegment as NameRef r=matklad a=Veykril

Wrapping self/super/crate in NameRef as per https://github.com/rust-analyzer/rust-analyzer/pull/7261#issuecomment-760023172



Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2021-01-15 18:40:47 +00:00
Lukas Wirth
cb863390f2 Handle self/super/crate in PathSegment as NameRef 2021-01-15 19:21:23 +01:00
bors[bot]
148e3d0f6a
Merge #7287
7287: Make SyntaxPtr lookup logarithmic r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2021-01-15 17:46:36 +00:00
Aleksey Kladov
26ef7e39f4 Make SyntaxPtr lookup logarithmic
closes #3934

cc https://github.com/rust-analyzer/rowan/pull/81
2021-01-15 20:40:40 +03:00
bors[bot]
a8587f153b
Merge #7286
7286: Remove useless wrapper r=matklad a=matklad

bors r+
🤖

Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2021-01-15 17:16:27 +00:00
Aleksey Kladov
6dbba4d75d Remove useless wrapper 2021-01-15 20:15:33 +03:00
Daiki Ihara
138514bea2 Add test for yield_expr 2021-01-15 23:35:17 +09:00
Daiki Ihara
85cd3524e2 Add support for yiled keyword 2021-01-15 23:35:17 +09:00
Aleksey Kladov
8dc68ecdfc Introduce more appropriate assertion mechanism
rust-analyzer is a long-running program, so we *should* handle assertion
failures.

See also https://www.sqlite.org/assert.html.
2021-01-14 18:25:19 +03:00
bors[bot]
607b9ea160
Merge #7218
7218: Fix typos r=Veykril a=regexident

Apart from the very last commit on this PR (which fixes a public type's name) all changes are non-breaking.

Co-authored-by: Vincent Esche <regexident@gmail.com>
2021-01-10 18:16:29 +00:00
Vincent Esche
d462119744 Updated tests via cargo xtask codegen 2021-01-10 18:36:27 +01:00
bors[bot]
b3ae7974af
Merge #7239
7239: Replace SyntaxKind usage with T! macro where applicable r=lnicola a=Veykril

https://github.com/rust-analyzer/rust-analyzer/blob/master/docs/dev/style.md#token-names

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2021-01-10 16:31:32 +00:00
Lukas Wirth
e618d12903 Replace SyntaxKind usage with T! macro where applicable 2021-01-10 17:14:01 +01:00
Laurențiu Nicola
10e7fd25fe Fix typo, parentheses is plural 2021-01-10 17:56:53 +02:00
Callym
dcb4c0ada6 Allow true and false keywords in const generics 2021-01-10 13:58:09 +00:00
Vincent Esche
c8c2bd097a Fixed typos in local bindings 2021-01-09 15:41:29 +01:00
Vincent Esche
6cd93db8a5 Fixed typos in code asserts 2021-01-09 15:41:29 +01:00
Vincent Esche
21f8239ac8 Fixed typos in code comments 2021-01-09 15:41:29 +01:00
Kevaundray Wedderburn
72b9a4fbd3 Change <|> to $0 - Rebase 2021-01-07 12:09:23 +00:00
Aleksey Kladov
f9707cde68 Rename expr -> tail_expr 2021-01-05 15:51:13 +03:00
kjeremy
f2d1144b4a Update crates 2021-01-04 11:12:42 -05:00
bors[bot]
ac123ac9e4
Merge #6587
6587: SSR: Support statement matching and replacing r=davidlattimore a=MarijnS95


For #3186

Hi!

This is a smaller initial patchset that came up while working on support for statement lists (and my first time working on RA 😁). It has me stuck on trailing semicolons for which I hope to receive some feedback. Matching (and replacing) `let` bindings with a trailing semicolon works fine, but trying to omit these (to make patterns more ergonomic) turns out more complex than expected.

The "optional trailing semicolon solution" implemented in this PR is ugly because `Matcher::attempt_match_token` should only consume a trailing `;` when parsing `let` bindings to prevent other code from breaking. That at the same time has a nasty side-effect of `;` ending up in the matched code: any replacements on that should include the trailing semicolon as well even if it was not in the pattern. A better example is in the tests:

3ae1649c24/crates/ssr/src/tests.rs (L178-L184)

The end result to achieve is (I guess) allowing replacement of let bindings without trailing semicolon like `let x = $a ==>> let x = 1` (but including them on both sides is still fine), and should make replacement in a macro call (where `foo!(let a = 2;)` for a `$x:stmt` is invalid syntax) possible as well. That should allow to enable/fix these tests:

3ae1649c24/crates/ssr/src/tests.rs (L201-L214)

A possible MVP of this PR might be to drop this optional `;' handling entirely and only allow an SSR pattern/template with semicolons on either side.

Co-authored-by: Marijn Suijten <marijn@traverseresearch.nl>
2021-01-04 11:14:40 +00:00
Jesse Bakker
c7e0c7f43a Upgrade expect-test to 1.1 2021-01-03 14:43:29 +01:00
Marijn Suijten
42da26e959 parser,syntax: Add separate parser for stmt with optional semicolon
Adjusting `grammar::fragments::stmt` to Optional or Yes will break
original functionality and tests.
2021-01-03 12:05:52 +01:00
Marijn Suijten
cc081b7e1c syntax,ssr: Implement statement parsing 2021-01-03 11:29:33 +01:00