提交 c30102b3 编写于 作者: J Jonathon Marolf

Allow correct type to be used when generating a variable

Fixes #642
上级 4d9f9269
......@@ -2784,5 +2784,31 @@ public void TestGenerateLocalInDictionaryInitializer3()
@"using System . Collections . Generic ; class Program { static void Main ( string [ ] args ) { int i = 0 ; var x = new Dictionary < string , int > { [ ""Zero"" ] = i } ; } } ",
index: 3);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public void TestGenerateVariableFromLambda()
{
Test(
@"using System ; class Program { static void Main ( string [ ] args ) { [|foo|] = ( ) => { return 0 ; } ; } } ",
@"using System ; class Program { private static Func < int > foo ; static void Main ( string [ ] args ) { foo = ( ) => { return 0 ; } ; } } ");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public void TestGenerateVariableFromLambda2()
{
Test(
@"using System ; class Program { static void Main ( string [ ] args ) { [|foo|] = ( ) => { return 0 ; } ; } } ",
@"using System ; class Program { public static Func < int > foo { get ; private set ; } static void Main ( string [ ] args ) { foo = ( ) => { return 0 ; } ; } } ",
index: 1);
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)]
public void TestGenerateVariableFromLambda3()
{
Test(
@"using System ; class Program { static void Main ( string [ ] args ) { [|foo|] = ( ) => { return 0 ; } ; } } ",
@"using System ; class Program { static void Main ( string [ ] args ) { Func < int > foo = ( ) => { return 0 ; } ; } } ",
index: 2);
}
}
}
......@@ -909,5 +909,29 @@ NewLines("Module C \n Sub Test() \n If TypeOf [|B|] Is String Then \n End If \n
NewLines("Module C \n Sub Test() \n Dim B As String = Nothing \n If TypeOf B Is String Then \n End If \n End Sub \n End Module"),
index:=3)
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)>
Public Sub TestGenerateVariableFromLambda()
Test(
NewLines("Class [Class] \n Private Sub Method(i As Integer) \n [|foo|] = Function() \n Return 2 \n End Function \n End Sub \n End Class"),
NewLines("Imports System\n\nClass [Class]\n Private foo As Func(Of Integer)\n\n Private Sub Method(i As Integer)\n foo = Function()\n Return 2\n End Function\n End Sub\nEnd Class"),
index:=0)
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)>
Public Sub TestGenerateVariableFromLambda2()
Test(
NewLines("Class [Class] \n Private Sub Method(i As Integer) \n [|foo|] = Function() \n Return 2 \n End Function \n End Sub \n End Class"),
NewLines("Imports System\n\nClass [Class]\n Public Property foo As Func(Of Integer)\n\n Private Sub Method(i As Integer)\n foo = Function()\n Return 2\n End Function\n End Sub\nEnd Class"),
index:=1)
End Sub
<Fact(), Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)>
Public Sub TestGenerateVariableFromLambda3()
Test(
NewLines("Class [Class] \n Private Sub Method(i As Integer) \n [|foo|] = Function() \n Return 2 \n End Function \n End Sub \n End Class"),
NewLines("Class [Class] \n Private Sub Method(i As Integer)\n Dim foo As System.Func(Of Integer)\n foo = Function() \n Return 2 \n End Function \n End Sub \n End Class"),
index:=2)
End Sub
End Class
End Namespace
......@@ -273,8 +273,9 @@ internal bool CanGenerateLocal()
document.SemanticModel, this.SimpleNameOrMemberAccessExpressionOpt,
objectAsDefault: true,
cancellationToken: cancellationToken);
var compilation = document.SemanticModel.Compilation;
inferredType = inferredType.SpecialType == SpecialType.System_Void
? document.SemanticModel.Compilation.ObjectType
? compilation.ObjectType
: inferredType;
if (this.IsInConditionalAccessExpression)
......@@ -282,17 +283,26 @@ internal bool CanGenerateLocal()
inferredType = inferredType.RemoveNullableIfPresent();
}
if (inferredType.IsDelegateType() && !inferredType.CanBeReferencedByName)
{
var namedDelegateType = inferredType.GetDelegateType(compilation)?.DelegateInvokeMethod?.ConvertToType(compilation);
if (namedDelegateType != null)
{
inferredType = namedDelegateType;
}
}
// Substitute 'object' for all captured method type parameters. Note: we may need to
// do this for things like anonymous types, as well as captured type parameters that
// aren't in scope in the destination type.
var capturedMethodTypeParameters = inferredType.GetReferencedMethodTypeParameters();
var mapping = capturedMethodTypeParameters.ToDictionary(tp => tp,
tp => document.SemanticModel.Compilation.ObjectType);
tp => compilation.ObjectType);
this.TypeMemberType = inferredType.SubstituteTypes(mapping, document.SemanticModel.Compilation);
this.TypeMemberType = inferredType.SubstituteTypes(mapping, compilation);
var availableTypeParameters = this.TypeToGenerateIn.GetAllTypeParameters();
this.TypeMemberType = TypeMemberType.RemoveUnavailableTypeParameters(
document.SemanticModel.Compilation, availableTypeParameters);
compilation, availableTypeParameters);
var enclosingMethodSymbol = document.SemanticModel.GetEnclosingSymbol<IMethodSymbol>(this.SimpleNameOrMemberAccessExpressionOpt.SpanStart, cancellationToken);
if (enclosingMethodSymbol != null && enclosingMethodSymbol.TypeParameters != null && enclosingMethodSymbol.TypeParameters.Count() != 0)
......@@ -301,7 +311,7 @@ internal bool CanGenerateLocal()
combinedTypeParameters.AddRange(availableTypeParameters);
combinedTypeParameters.AddRange(enclosingMethodSymbol.TypeParameters);
this.LocalType = inferredType.RemoveUnavailableTypeParameters(
document.SemanticModel.Compilation, combinedTypeParameters);
compilation, combinedTypeParameters);
}
else
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册