Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix generate type with file-scoped namespaces #55826

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System.Collections.Immutable;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.GenerateType;
Expand Down Expand Up @@ -78,6 +76,74 @@ class Goo
isNewFile: false);
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)]
public async Task GenerateTypeInsideFileScopedNamespace1()
{
await TestWithMockedGenerateTypeDialog(
initial: @"
namespace A;

class Program
{
void Main()
{
[|A.Goo$$|] f;
}
}
",
languageName: LanguageNames.CSharp,
typeName: "Goo",
expected: @"
namespace A;

class Program
{
void Main()
{
A.Goo f;
}
}

class Goo
{
}",
isNewFile: false);
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)]
public async Task GenerateTypeInsideFileScopedNamespace2()
{
await TestWithMockedGenerateTypeDialog(
initial: @"
namespace A;

class Program
{
void Main()
{
[|Goo$$|] f;
}
}
",
languageName: LanguageNames.CSharp,
typeName: "Goo",
expected: @"
namespace A;

class Program
{
void Main()
{
Goo f;
}
}

class Goo
{
}",
isNewFile: false);
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateType)]
public async Task GenerateTypeInsideQualifiedNamespace()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,11 @@ private static CompilationUnitSyntax MoveMembersFromGlobalToNamespace(Compilatio

var node = compilationUnit.FindNode(span, getInnermostNodeForTie: true);

var namespaceDecl = node.AncestorsAndSelf().OfType<BaseNamespaceDeclarationSyntax>().SingleOrDefault();
var namespaceDecls = node.AncestorsAndSelf().OfType<BaseNamespaceDeclarationSyntax>().ToImmutableArray();
if (namespaceDecls.Length != 1)
return null;

var namespaceDecl = namespaceDecls[0];
if (namespaceDecl == null)
return null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,12 +574,8 @@ protected override bool IsConversionImplicit(Compilation compilation, ITypeSymbo
if (enclosingNamespace != null)
{
var enclosingNamespaceSymbol = semanticModel.GetSymbolInfo(enclosingNamespace.Name, cancellationToken);
if (enclosingNamespaceSymbol.Symbol != null)
{
return ((INamespaceSymbol)enclosingNamespaceSymbol.Symbol,
namedTypeSymbol,
enclosingNamespace.CloseBraceToken.GetLocation());
}
if (enclosingNamespaceSymbol.Symbol is INamespaceSymbol namespaceSymbol)
return (namespaceSymbol, namedTypeSymbol, enclosingNamespace.GetLastToken().GetLocation());
}
}

Expand All @@ -593,11 +589,11 @@ protected override bool IsConversionImplicit(Compilation compilation, ITypeSymbo
return (globalNamespace, rootNamespaceOrType, afterThisLocation);
}

private NamespaceDeclarationSyntax FindNamespaceInMemberDeclarations(SyntaxList<MemberDeclarationSyntax> members, int indexDone, List<string> containers)
private BaseNamespaceDeclarationSyntax FindNamespaceInMemberDeclarations(SyntaxList<MemberDeclarationSyntax> members, int indexDone, List<string> containers)
{
foreach (var member in members)
{
if (member is NamespaceDeclarationSyntax namespaceDeclaration)
if (member is BaseNamespaceDeclarationSyntax namespaceDeclaration)
{
var found = FindNamespaceInNamespace(namespaceDeclaration, indexDone, containers);
if (found != null)
Expand All @@ -608,7 +604,7 @@ private NamespaceDeclarationSyntax FindNamespaceInMemberDeclarations(SyntaxList<
return null;
}

private NamespaceDeclarationSyntax FindNamespaceInNamespace(NamespaceDeclarationSyntax namespaceDecl, int indexDone, List<string> containers)
private BaseNamespaceDeclarationSyntax FindNamespaceInNamespace(BaseNamespaceDeclarationSyntax namespaceDecl, int indexDone, List<string> containers)
{
if (namespaceDecl.Name is AliasQualifiedNameSyntax)
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,7 @@ private async Task<IEnumerable<CodeActionOperation>> GetGenerateIntoExistingDocu
enclosingNamespaceGeneratedTypeToAddAndLocation.Item1,
enclosingNamespaceGeneratedTypeToAddAndLocation.Item2,
new CodeGenerationOptions(afterThisLocation: enclosingNamespaceGeneratedTypeToAddAndLocation.Item3),
_cancellationToken)
.ConfigureAwait(false);
_cancellationToken).ConfigureAwait(false);
var newRoot = await codeGenResult.GetSyntaxRootAsync(_cancellationToken).ConfigureAwait(false);
var updatedSolution = solution.WithDocumentSyntaxRoot(generateTypeOptionsResult.ExistingDocument.Id, newRoot, PreservationMode.PreserveIdentity);

Expand Down