Add support for converting existing collection-initializers over to collection expressions.#69321
Conversation
| } | ||
| } | ||
|
|
||
| public static CollectionExpressionSyntax ConvertInitializerToCollectionExpression( |
There was a problem hiding this comment.
this helper is used by multiple fixers. SO it moved to this common location.
| SourceText sourceText, | ||
| InitializerExpressionSyntax originalInitializer, | ||
| CollectionExpressionSyntax newCollectionExpression, | ||
| bool newCollectionIsSingleLine) |
There was a problem hiding this comment.
same with this helper.
| IsOnSingleLine(sourceText, initializer))); | ||
| } | ||
|
|
||
| bool ShouldReplaceExistingExpressionEntirely(ExpressionSyntax explicitOrImplicitArray, InitializerExpressionSyntax initializer) |
There was a problem hiding this comment.
this helper moved to a common location.
| } | ||
| currentArrayCreation.Initializer, isOnSingleLine); | ||
|
|
||
| private static CollectionExpressionSyntax ConvertInitializerToCollectionExpression( |
There was a problem hiding this comment.
this helper moved to a common location.
|
|
||
| [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.UseCollectionInitializer), Shared] | ||
| internal class CSharpUseCollectionInitializerCodeFixProvider : | ||
| internal partial class CSharpUseCollectionInitializerCodeFixProvider : |
There was a problem hiding this comment.
this type changed a ton. It is now 3 files. The main one, with common logic. And then two siblings. One sibling is for creating object-initializers, the other for object-creation expressions.
| ImmutableArray<Match<StatementSyntax>> matches) | ||
| { | ||
| var expressions = CreateCollectionInitializerExpressions(); | ||
| var withLineBreaks = AddLineBreaks(expressions); |
There was a problem hiding this comment.
the collection initializer case is pretty simple. We create a list of all the expressions, then add lines breaks between the elements (we always do initializers across multiple lines).
Note: in the future we may want to copy the code that properly indents expressions so that when we move expressions into the collection initializer we do a good job with multi-line exprs.
| List<int> c = | ||
| [ | ||
| 1, 2 | ||
| ]; |
There was a problem hiding this comment.
lots of tests got better now that we rewrote the formatting logic for collection-exprs.
| } | ||
|
|
||
| [Fact] | ||
| public async Task TestReplacementLocation_NoElements_ExistingInitializer1() |
There was a problem hiding this comment.
thus begins a huge swath of tests created to validate a ton of whitespace/newline trivia scenarios.
| /// Creates the final collection-expression <c>[...]</c> that will replace the given <paramref | ||
| /// name="objectCreation"/> expression. | ||
| /// </summary> | ||
| private static async Task<CollectionExpressionSyntax> CreateCollectionExpressionAsync( |
There was a problem hiding this comment.
this logic is effectively entirely new. The code heavily emphasizes trying to match the new collection-expression style against the current code the user has (or infer what would be best for certain situations). I've tried to doc it heavily as to what it's doing.
| return (matches, shouldUseCollectionExpression: true); | ||
| } | ||
|
|
||
| bool AreCollectionExpressionsSupported() |
There was a problem hiding this comment.
just inlined this method.
...s/VisualBasic/Analyzers/UseCollectionInitializer/VisualBasicCollectionInitializerAnalyzer.vb
Show resolved
Hide resolved
…isualBasicCollectionInitializerAnalyzer.vb
|
@akhera99 This is ready for review. THe tests should hopefully help indicate what's going on here and why so much was rewritten :) |
| List<int> c = [|new|] List<int>(); | ||
| // Goo | ||
| // Bar | ||
| if (b1) |
There was a problem hiding this comment.
Can you add a test like so
| if (b1) | |
| if (b1) // Comment |
There was a problem hiding this comment.
yes. i'll add in followup pr. right now that comment will be removed.
Part of #69132
Draft until #69280 goes in.
This means code like
new List<int> { 1, 2, 3 }will get converted to[1, 2, 3]. We also detect this in the long-statement form like:And offer a similar conversion. Additionally we support converting things like:
to:
[1, 2, .. v], and so on.Note: this also works when the initializer already exists. For example:
We try very hard to produce a collection expression that matches the style present, or looks good when no style is present. This involved effectively rewriting the entire core logic taht generates collection expressions to not use the formatting engine at all, but instead manually create everything from scratch. This adds a lot of logic, but makes the end results much higher quality.