Skip to content

Commit 2155895

Browse files
committed
Preemptively added suggestions from previous PR feedback
1 parent e42ee5f commit 2155895

File tree

2 files changed

+44
-56
lines changed

2 files changed

+44
-56
lines changed

src/Razor/src/Microsoft.AspNetCore.Razor.LanguageServer/CodeActions/Razor/ExtractToComponentCodeActionResolver.cs

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
using ICSharpCode.Decompiler.CSharp.Syntax;
4040
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
4141
using System.Reflection.Metadata.Ecma335;
42+
using Microsoft.VisualStudio.Utilities;
4243

4344
namespace Microsoft.AspNetCore.Razor.LanguageServer.CodeActions;
4445

@@ -117,7 +118,7 @@ internal sealed class ExtractToComponentCodeActionResolver(
117118
}.Uri;
118119

119120
var componentName = Path.GetFileNameWithoutExtension(componentPath);
120-
var newComponentResult = await GenerateNewComponentAsync(selectionAnalysis, codeDocument, actionParams.Uri, newComponentUri, documentContext, removeRange, cancellationToken).ConfigureAwait(false);
121+
var newComponentResult = await GenerateNewComponentAsync(selectionAnalysis, codeDocument, actionParams.Uri, documentContext, removeRange, cancellationToken).ConfigureAwait(false);
121122

122123
if (newComponentResult is null)
123124
{
@@ -164,6 +165,7 @@ internal sealed class ExtractToComponentCodeActionResolver(
164165
DocumentChanges = documentChanges,
165166
};
166167
}
168+
167169
private static ExtractToComponentCodeActionParams? DeserializeActionParams(JsonElement data)
168170
{
169171
return data.ValueKind == JsonValueKind.Undefined
@@ -445,13 +447,9 @@ private static HashSet<string> AddComponentDependenciesInRange(SyntaxNode root,
445447
// Only analyze nodes within the extract span
446448
foreach (var node in root.DescendantNodes().Where(node => extractSpan.Contains(node.Span)))
447449
{
448-
if (node is MarkupTagHelperElementSyntax)
450+
if (node is MarkupTagHelperElementSyntax { TagHelperInfo: { } tagHelperInfo })
449451
{
450-
var tagHelperInfo = GetTagHelperInfo(node);
451-
if (tagHelperInfo is not null)
452-
{
453-
AddDependenciesFromTagHelperInfo(tagHelperInfo, ref dependencies);
454-
}
452+
AddDependenciesFromTagHelperInfo(tagHelperInfo, dependencies);
455453
}
456454
}
457455

@@ -480,40 +478,24 @@ private static HashSet<string> AddVariableDependenciesInRange(SyntaxNode root, i
480478
return dependencies;
481479
}
482480

483-
private static TagHelperInfo? GetTagHelperInfo(SyntaxNode node)
484-
{
485-
if (node is MarkupTagHelperElementSyntax markupElement)
486-
{
487-
return markupElement.TagHelperInfo;
488-
}
489-
490-
return null;
491-
}
492-
493-
private static void AddDependenciesFromTagHelperInfo(TagHelperInfo tagHelperInfo, ref HashSet<string> dependencies)
481+
private static void AddDependenciesFromTagHelperInfo(TagHelperInfo tagHelperInfo, HashSet<string> dependencies)
494482
{
495483
foreach (var descriptor in tagHelperInfo.BindingResult.Descriptors)
496484
{
497-
if (descriptor is not null)
485+
if (descriptor is null)
498486
{
499-
foreach (var metadata in descriptor.Metadata)
500-
{
501-
if (metadata.Key == TagHelperMetadata.Common.TypeNamespace &&
502-
metadata.Value is not null &&
503-
!dependencies.Contains($"@using {metadata.Value}"))
504-
{
505-
dependencies.Add($"@using {metadata.Value}");
506-
}
507-
}
487+
continue;
508488
}
489+
490+
var typeNamespace = descriptor.GetTypeNamespace();
491+
dependencies.Add(typeNamespace);
509492
}
510493
}
511494

512495
private async Task<NewRazorComponentInfo?> GenerateNewComponentAsync(
513496
SelectionAnalysisResult selectionAnalysis,
514497
RazorCodeDocument razorCodeDocument,
515498
Uri componentUri,
516-
Uri newComponentUri,
517499
DocumentContext documentContext,
518500
Range relevantRange,
519501
CancellationToken cancellationToken)
@@ -524,31 +506,48 @@ metadata.Value is not null &&
524506
return null;
525507
}
526508

527-
var dependencies = selectionAnalysis.ComponentDependencies is not null
528-
? string.Join(Environment.NewLine, selectionAnalysis.ComponentDependencies)
529-
: string.Empty;
509+
var inst = PooledStringBuilder.GetInstance();
510+
var newFileContentBuilder = inst.Builder;
511+
if (selectionAnalysis.ComponentDependencies is not null)
512+
{
513+
foreach (var dependency in selectionAnalysis.ComponentDependencies)
514+
{
515+
newFileContentBuilder.AppendLine($"@using {dependency}");
516+
}
530517

531-
var extractedContents = contents.GetSubTextString(new CodeAnalysis.Text.TextSpan(selectionAnalysis.ExtractStart, selectionAnalysis.ExtractEnd - selectionAnalysis.ExtractStart)).Trim();
532-
var newFileContent = $"{dependencies}{(dependencies.Length > 0 ? Environment.NewLine + Environment.NewLine : "")}{extractedContents}";
518+
if (newFileContentBuilder.Length > 0)
519+
{
520+
newFileContentBuilder.AppendLine();
521+
}
522+
}
523+
524+
var extractedContents = contents.GetSubTextString(
525+
new TextSpan(selectionAnalysis.ExtractStart,
526+
selectionAnalysis.ExtractEnd - selectionAnalysis.ExtractStart))
527+
.Trim();
528+
529+
newFileContentBuilder.Append(extractedContents);
533530

534531
// Get CSharpStatements within component
535532
var syntaxTree = razorCodeDocument.GetSyntaxTree();
536533
var cSharpCodeBlocks = GetCSharpCodeBlocks(syntaxTree, selectionAnalysis.ExtractStart, selectionAnalysis.ExtractEnd);
537534

538535
var result = new NewRazorComponentInfo
539536
{
540-
NewContents = newFileContent,
537+
NewContents = newFileContentBuilder.ToString(),
541538
Methods = []
542539
};
543540

544541
// Only make the Roslyn call if there is valid CSharp in the selected code.
545542
if (cSharpCodeBlocks.Count == 0)
546543
{
544+
inst.Free();
547545
return result;
548546
}
549547

550548
if (!_documentVersionCache.TryGetDocumentVersion(documentContext.Snapshot, out var version))
551549
{
550+
inst.Free();
552551
return result;
553552
}
554553

@@ -586,11 +585,6 @@ metadata.Value is not null &&
586585
{
587586
Uri = componentUri
588587
},
589-
NewDocument = new TextDocumentIdentifier
590-
{
591-
Uri = newComponentUri
592-
},
593-
NewContents = newFileContent,
594588
HostDocumentVersion = version.Value,
595589
IntersectingRangesInGeneratedMappings = intersectingGeneratedRanges
596590
};
@@ -610,18 +604,21 @@ metadata.Value is not null &&
610604

611605
if (componentInfo is null)
612606
{
607+
inst.Free();
613608
return result;
614609
}
615610

616611
var codeBlockAtEnd = GetCodeBlockAtEnd(syntaxTree);
617612
if (codeBlockAtEnd is null)
618613
{
614+
inst.Free();
619615
return result;
620616
}
621617

622618
var identifiersInCodeBlock = GetIdentifiersInContext(codeBlockAtEnd, cSharpCodeBlocks);
623619
if (componentInfo.Methods is null)
624620
{
621+
inst.Free();
625622
return result;
626623
}
627624

@@ -635,12 +632,13 @@ metadata.Value is not null &&
635632

636633
var newFileCodeBlock = GenerateNewFileCodeBlock(promotedMethods, forwardedFields);
637634

638-
newFileContent = ReplaceMethodInvocations(newFileContent, methodsInContext);
639-
newFileContent += newFileCodeBlock;
635+
ReplaceMethodInvocations(newFileContentBuilder, methodsInContext);
636+
newFileContentBuilder.Append(newFileCodeBlock);
640637

641-
result.NewContents = newFileContent;
638+
result.NewContents = newFileContentBuilder.ToString();
642639
result.Methods = methodsInContext;
643640

641+
inst.Free();
644642
return result;
645643
}
646644

@@ -852,17 +850,15 @@ private static string GenerateNewFileCodeBlock(string promotedMethods, string ca
852850
return builder.ToString();
853851
}
854852

855-
// Method invocations in the new file must be replaced with their respective parameter name. This is simply a case of replacing each string.
856-
private static string ReplaceMethodInvocations(string newFileContent, HashSet<MethodSymbolicInfo> methods)
853+
// Method invocations in the new file must be replaced with their respective parameter name.
854+
private static void ReplaceMethodInvocations(StringBuilder newFileContentBuilder, HashSet<MethodSymbolicInfo> methods)
857855
{
858856
var parameterCount = 0;
859857
foreach (var method in methods)
860858
{
861-
newFileContent = newFileContent.Replace(method.Name, $"Parameter{(parameterCount > 0 ? parameterCount : "")}");
859+
newFileContentBuilder.Replace(method.Name, $"Parameter{(parameterCount > 0 ? parameterCount : "")}");
862860
parameterCount++;
863861
}
864-
865-
return newFileContent;
866862
}
867863

868864
private static string GenerateComponentNameAndParameters(HashSet<MethodSymbolicInfo>? methods, string componentName)

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Protocol/CodeActions/GetSymbolicInfoParams.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ internal record GetSymbolicInfoParams
1515
[JsonPropertyName("document")]
1616
public required TextDocumentIdentifier Document { get; set; }
1717

18-
[DataMember(Name = "newDocument")]
19-
[JsonPropertyName("newDocument")]
20-
public required TextDocumentIdentifier NewDocument { get; set; }
21-
2218
[DataMember(Name = "project")]
2319
[JsonPropertyName("project")]
2420
public required TextDocumentIdentifier Project { get; set; }
@@ -27,10 +23,6 @@ internal record GetSymbolicInfoParams
2723
[JsonPropertyName("hostDocumentVersion")]
2824
public required int HostDocumentVersion { get; set; }
2925

30-
[DataMember(Name = "newContents")]
31-
[JsonPropertyName("newContents")]
32-
public required string NewContents { get; set; }
33-
3426
[DataMember(Name = "intersectingRangesInGeneratedMappings")]
3527
[JsonPropertyName("intersectingRangesInGeneratedMappings")]
3628

0 commit comments

Comments
 (0)