diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-11-03 17:34:59 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-11-03 17:34:59 +0000 |
commit | 060c8b2c96a0de4a131c4d780d2aac80afe13de8 (patch) | |
tree | 1c9c4d8b4134418dcf0dcfaf97d43c97d391f246 /crates/syntax/src | |
parent | 5e622332774fbd57c12addd46b058c8feb2b08a6 (diff) | |
parent | cd349dbbc4a39342fd54e46fc9d70e3e649a2fda (diff) |
Merge #6287
6287: Don't replace entire module and file nodes when inserting imports r=matklad a=Veykril
This change minifies the resulting diff of import insertions by inserting or replacing the produced use tree directly through an `action` return value instead replacing the entire container node. This action has to be applied by the caller now. This unfortunately pulls the `AssistBuilder` into scope of `insert_use` back again but I tried to at least keep it away from the `insert_use` fn itself.
I'm open to more/better ideas regarding this :)
Fixes #6196
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/ast/make.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 5b06cb767..2cf436e7a 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -351,6 +351,23 @@ pub fn visibility_pub_crate() -> ast::Visibility { | |||
351 | ast_from_text("pub(crate) struct S") | 351 | ast_from_text("pub(crate) struct S") |
352 | } | 352 | } |
353 | 353 | ||
354 | pub fn visibility_pub() -> ast::Visibility { | ||
355 | ast_from_text("pub struct S") | ||
356 | } | ||
357 | |||
358 | pub fn tuple_field_list(fields: impl IntoIterator<Item = ast::TupleField>) -> ast::TupleFieldList { | ||
359 | let fields = fields.into_iter().join(", "); | ||
360 | ast_from_text(&format!("struct f({});", fields)) | ||
361 | } | ||
362 | |||
363 | pub fn tuple_field(visibility: Option<ast::Visibility>, ty: ast::Type) -> ast::TupleField { | ||
364 | let visibility = match visibility { | ||
365 | None => String::new(), | ||
366 | Some(it) => format!("{} ", it), | ||
367 | }; | ||
368 | ast_from_text(&format!("struct f({}{});", visibility, ty)) | ||
369 | } | ||
370 | |||
354 | pub fn fn_( | 371 | pub fn fn_( |
355 | visibility: Option<ast::Visibility>, | 372 | visibility: Option<ast::Visibility>, |
356 | fn_name: ast::Name, | 373 | fn_name: ast::Name, |
@@ -373,6 +390,26 @@ pub fn fn_( | |||
373 | )) | 390 | )) |
374 | } | 391 | } |
375 | 392 | ||
393 | pub fn struct_( | ||
394 | visibility: Option<ast::Visibility>, | ||
395 | strukt_name: ast::Name, | ||
396 | type_params: Option<ast::GenericParamList>, | ||
397 | field_list: ast::FieldList, | ||
398 | ) -> ast::Struct { | ||
399 | let semicolon = if matches!(field_list, ast::FieldList::TupleFieldList(_)) { ";" } else { "" }; | ||
400 | let type_params = | ||
401 | if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() }; | ||
402 | let visibility = match visibility { | ||
403 | None => String::new(), | ||
404 | Some(it) => format!("{} ", it), | ||
405 | }; | ||
406 | |||
407 | ast_from_text(&format!( | ||
408 | "{}struct {}{}{}{}", | ||
409 | visibility, strukt_name, type_params, field_list, semicolon | ||
410 | )) | ||
411 | } | ||
412 | |||
376 | fn ast_from_text<N: AstNode>(text: &str) -> N { | 413 | fn ast_from_text<N: AstNode>(text: &str) -> N { |
377 | let parse = SourceFile::parse(text); | 414 | let parse = SourceFile::parse(text); |
378 | let node = match parse.tree().syntax().descendants().find_map(N::cast) { | 415 | let node = match parse.tree().syntax().descendants().find_map(N::cast) { |