aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
Commit message (Collapse)AuthorAgeFilesLines
...
* | Merge #7620bors[bot]2021-02-161-9/+50
|\ \ | |/ |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 7620: Support control flow in `extract_function` assist r=matklad a=cpud36 Support `return`ing from outer function, `break`ing and `continue`ing outer loops when extracting function. # Example Transforms ```rust fn foo() -> i32 { let items = [1,2,3]; let mut sum = 0; for &item in items { <|>if item == 42 { break; }<|> sum += item; } sum } ``` Into ```rust fn foo() -> i32 { let items = [1,2,3]; let mut sum = 0; for &item in items { if fun_name(item) { break; } sum += item; } sum } fn fun_name(item: i32) -> bool { if item == 42 { return true; } false } ``` ![add_explicit_type_infer_type](https://user-images.githubusercontent.com/4218373/107544222-0fadf280-6bdb-11eb-9625-ed6194ba92c0.gif) # Features Supported variants - break and function does not return => uses `bool` and plain if - break and function does return => uses `Option<T>` and matches on it - break with value and function does not return => uses `Option<T>` and if let - break with value and function does return => uses `Result<T, U>` and matches on t - same for `return` and `continue`(but we can't continue with value) Assist does handle nested loops and nested items(like functions, modules, impls) Try `expr?` operator is allowed together with `return Err(_)` and `return None`. `return expr` is not allowed. # Not supported ## Mixing `return` with `break` or `continue` If we have e.g. a `return` and a `break` in the selected code, it is unclear what the produced code should look like. We can try `Result<T, Option<U>>` or something like that, but it isn't idiomatic, nor it is established. Otherwise, implementation is relatively simple. ## `break` with label Not sure how to handle different labels for multiple `break`s. [edit] implemented try `expr?` Co-authored-by: Vladyslav Katasonov <[email protected]>
| * allow try expr? when extacting functionVladyslav Katasonov2021-02-131-0/+3
| |
| * handle return, break and continue when extracting functionVladyslav Katasonov2021-02-131-9/+47
| |
* | Don't rename field record patterns directlyLukas Wirth2021-02-131-3/+2
|/
* Refactor reference searching to work with the astLukas Wirth2021-02-121-4/+26
|
* Add parsing benchmarkAleksey Kladov2021-02-091-3/+25
|
* Infra for "unit" benchmarkingAleksey Kladov2021-02-091-3980/+0
|
* Update crateskjeremy2021-02-081-1/+1
| | | | Pulls in https://github.com/rust-lang/chalk/pull/682
* AdtDef -> AdtAleksey Kladov2021-02-071-19/+19
|
* Merge #7535bors[bot]2021-02-051-1/+1
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 <[email protected]>
| * allow modifications of vars from outer scope inside extracted functionVladyslav Katasonov2021-02-031-1/+1
| | | | | | | | | | It currently allows only directly setting variable. No `&mut` references or methods.
* | Add cargo file tidy testEdwin Cheng2021-02-031-2/+2
|/
* Bump rustc_lexerLaurențiu Nicola2021-02-021-1/+1
|
* Fix ast::String::value not properly escaping in some casesLukas Wirth2021-01-301-2/+19
|
* Bump depsLaurențiu Nicola2021-01-271-1/+1
|
* :arrow_up: rowanAleksey Kladov2021-01-251-1/+1
|
* Add validation for mutable const itemsLukas Wirth2021-01-245-24/+39
|
* Up lexerkjeremy2021-01-211-1/+1
|
* :arrow_up: rowanAleksey Kladov2021-01-205-12/+8
| | | | It now stores text inline with tokens
* .Aleksey Kladov2021-01-196-18/+18
|
* :arrow_up: rowanAleksey Kladov2021-01-193-5/+6
|
* Parse `impl const Trait`Lukas Wirth2021-01-182-0/+25
|
* Add `MacroType` syntaxJonas Schievink2021-01-181-2/+31
|
* Merge #7291bors[bot]2021-01-1815-67/+147
|\ | | | | | | | | | | | | | | 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 <[email protected]>
| * Wrap remaining self/super/crate in Name{Ref}Lukas Wirth2021-01-1515-67/+147
| |
* | When building an item-tree, keep fewer nodes in memoryAleksey Kladov2021-01-161-1/+1
| |
* | Add Unmerge Use assistunexge2021-01-151-2/+6
|/
* Merge #7288bors[bot]2021-01-1521-41/+87
|\ | | | | | | | | | | | | | | | | | | 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 <[email protected]>
| * Handle self/super/crate in PathSegment as NameRefLukas Wirth2021-01-1521-41/+87
| |
* | Merge #7287bors[bot]2021-01-151-1/+1
|\ \ | | | | | | | | | | | | | | | | | | | | | | | | 7287: Make SyntaxPtr lookup logarithmic r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
| * | Make SyntaxPtr lookup logarithmicAleksey Kladov2021-01-151-1/+1
| | | | | | | | | | | | | | | | | | closes #3934 cc https://github.com/rust-analyzer/rowan/pull/81
* | | Merge #7286bors[bot]2021-01-152-8/+3
|\ \ \ | |_|/ |/| | | | | | | | | | | | | | | | | | | | 7286: Remove useless wrapper r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
| * | Remove useless wrapperAleksey Kladov2021-01-152-8/+3
| |/
* | Add test for yield_exprDaiki Ihara2021-01-152-0/+32
| |
* | Add support for yiled keywordDaiki Ihara2021-01-151-1/+33
|/
* Introduce more appropriate assertion mechanismAleksey Kladov2021-01-141-1/+1
| | | | | | | rust-analyzer is a long-running program, so we *should* handle assertion failures. See also https://www.sqlite.org/assert.html.
* Merge #7218bors[bot]2021-01-106-58/+58
|\ | | | | | | | | | | | | | | 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 <[email protected]>
| * Updated tests via `cargo xtask codegen`Vincent Esche2021-01-102-50/+50
| |
| * Fixed typos in local bindingsVincent Esche2021-01-091-2/+2
| |
| * Fixed typos in code assertsVincent Esche2021-01-091-1/+1
| |
| * Fixed typos in code commentsVincent Esche2021-01-092-5/+5
| |
* | Merge #7239bors[bot]2021-01-101-1/+1
|\ \ | | | | | | | | | | | | | | | | | | | | | 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 <[email protected]>
| * | Replace SyntaxKind usage with T! macro where applicableLukas Wirth2021-01-101-1/+1
| | |
* | | Fix typo, parentheses is pluralLaurențiu Nicola2021-01-101-2/+2
|/ /
* / Allow `true` and `false` keywords in const genericsCallym2021-01-102-10/+20
|/
* Change <|> to $0 - RebaseKevaundray Wedderburn2021-01-072-29/+29
|
* Rename expr -> tail_exprAleksey Kladov2021-01-052-2/+2
|
* Update crateskjeremy2021-01-041-1/+1
|
* Merge #6587bors[bot]2021-01-0430-0/+227
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 :grin:). 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: https://github.com/rust-analyzer/rust-analyzer/blob/3ae1649c24a689473b874c331f5f176e5839978e/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: https://github.com/rust-analyzer/rust-analyzer/blob/3ae1649c24a689473b874c331f5f176e5839978e/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 <[email protected]>
| * parser,syntax: Add separate parser for stmt with optional semicolonMarijn Suijten2021-01-0313-5/+66
| | | | | | | | | | Adjusting `grammar::fragments::stmt` to Optional or Yes will break original functionality and tests.