提交 e0487a73 编写于 作者: J Jason Malinowski

Fix generate constructor throwing in a cross-language case

We tried to locate a constructor to delegate to; in that case we would
grab the types of the constructor and make sure the original call site
actually can use those types. In the cross-language case, we'd mix up
types from different languages. The correct behavior here is to map
the candiate type back to the language of the call site, since it's
the call site's language rules that matter.

Fixes https://github.com/dotnet/roslyn/issues/49850
上级 92b04c0a
......@@ -1866,6 +1866,45 @@ End Class",
End Class")
End Function
<WorkItem(49850, "https://github.com/dotnet/roslyn/issues/49850")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function TestDelegateConstructorCrossLanguage() As Task
Await TestInRegularAndScriptAsync(
<Workspace>
<Project Language="C#" Name="CSharpProject" CommonReferences="true">
<Document>
public class BaseType
{
public BaseType(string x) { }
}</Document>
</Project>
<Project Language="Visual Basic" CommonReferences="true">
<ProjectReference>CSharpProject</ProjectReference>
<Document>
Option Strict On
Public Class B
Public Sub M()
Dim x = [|New BaseType(42)|]
End Sub
End Class
</Document>
</Project>
</Workspace>.ToString(),
"
public class BaseType
{
private int v;
public BaseType(string x) { }
public BaseType(int v)
{
this.v = v;
}
}")
End Function
<WorkItem(14077, "https://github.com/dotnet/roslyn/issues/14077")>
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)>
Public Async Function CreateFieldDefaultNamingStyle() As Task
......
......@@ -9,6 +9,7 @@
using System.Linq;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.GenerateMember.GenerateConstructor
{
......@@ -77,9 +78,17 @@ private static bool IsSymbolAccessible(Compilation compilation, ISymbol symbol)
{
Debug.Assert(constructor.Parameters.Length == expressions.Length);
for (var i = 0; i < constructor.Parameters.Length; i++)
// Resolve the constructor into our semantic model's compilation; if the constructor we're looking at is from
// another project with a different language.
var constructorInCompilation = (IMethodSymbol?)SymbolKey.Create(constructor).Resolve(semanticModel.Compilation).Symbol;
Contract.ThrowIfNull(constructorInCompilation);
for (var i = 0; i < constructorInCompilation.Parameters.Length; i++)
{
var constructorParameter = constructor.Parameters[i];
var constructorParameter = constructorInCompilation.Parameters[i];
if (constructorParameter == null)
return false;
var conversion = semanticFacts.ClassifyConversion(semanticModel, expressions[i], constructorParameter.Type);
if (!conversion.IsIdentity && !conversion.IsImplicit)
return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册