提交 0195188e 编写于 作者: V VSadov

Merge pull request #11629 from VSadov/deprecatedWithString

Port two Update3 changes to stabilization.
......@@ -7702,7 +7702,7 @@ int P1
}
[Fact]
public void TestDeprecatedAttribute1()
public void TestDeprecatedAttributeTH1()
{
var source1 = @"
using System;
......@@ -7717,6 +7717,8 @@ public DeprecatedAttribute(System.String message, DeprecationType type, System.U
{
}
// this signature is only used in TH1 metadata
// see: https://github.com/dotnet/roslyn/issues/10630
public DeprecatedAttribute(System.String message, DeprecationType type, System.UInt32 version, Type contract)
{
}
......@@ -7760,6 +7762,93 @@ static void Main(string[] args)
}
";
var compilation2 = CreateCompilationWithMscorlibAndSystemCore(source2, new[] { compilation1.EmitToImageReference() });
compilation2.VerifyDiagnostics(
// (8,13): warning CS0618: 'Test.Foo()' is obsolete: 'hello'
// Test.Foo();
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "Test.Foo()").WithArguments("Test.Foo()", "hello").WithLocation(8, 13),
// (9,13): warning CS0618: 'Test.Bar()' is obsolete: 'hi'
// Test.Bar();
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "Test.Bar()").WithArguments("Test.Bar()", "hi").WithLocation(9, 13)
);
var compilation3 = CreateCompilationWithMscorlibAndSystemCore(source2, new[] { new CSharpCompilationReference(compilation1) });
compilation3.VerifyDiagnostics(
// (8,13): warning CS0618: 'Test.Foo()' is obsolete: 'hello'
// Test.Foo();
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "Test.Foo()").WithArguments("Test.Foo()", "hello").WithLocation(8, 13),
// (9,13): warning CS0618: 'Test.Bar()' is obsolete: 'hi'
// Test.Bar();
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "Test.Bar()").WithArguments("Test.Bar()", "hi").WithLocation(9, 13)
);
}
[Fact]
public void TestDeprecatedAttributeTH2()
{
var source1 = @"
using System;
using Windows.Foundation.Metadata;
namespace Windows.Foundation.Metadata
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true)]
public sealed class DeprecatedAttribute : Attribute
{
public DeprecatedAttribute(System.String message, DeprecationType type, System.UInt32 version)
{
}
// this signature is only used in TH2 metadata and onwards
// see: https://github.com/dotnet/roslyn/issues/10630
public DeprecatedAttribute(System.String message, DeprecationType type, System.UInt32 version, String contract)
{
}
}
public enum DeprecationType
{
Deprecate = 0,
Remove = 1
}
}
public class Test
{
[Deprecated(""hello"", DeprecationType.Deprecate, 1, ""hello"")]
public static void Foo()
{
}
[Deprecated(""hi"", DeprecationType.Deprecate, 1)]
public static void Bar()
{
}
}
";
var compilation1 = CreateCompilationWithMscorlibAndSystemCore(source1);
var source2 = @"
namespace ConsoleApplication74
{
class Program
{
static void Main(string[] args)
{
Test.Foo();
Test.Bar();
}
}
}
";
var compilation2 = CreateCompilationWithMscorlibAndSystemCore(source2, new[] { compilation1.EmitToImageReference() });
......
......@@ -1154,6 +1154,7 @@ private bool TryExtractDeprecatedDataFromAttribute(AttributeInfo attributeInfo,
case 0: // DeprecatedAttribute(String, DeprecationType, UInt32)
case 1: // DeprecatedAttribute(String, DeprecationType, UInt32, Platform)
case 2: // DeprecatedAttribute(String, DeprecationType, UInt32, Type)
case 3: // DeprecatedAttribute(String, DeprecationType, UInt32, String)
return TryExtractValueFromAttribute(attributeInfo.Handle, out obsoleteData, s_attributeDeprecatedDataExtractor);
default:
......
......@@ -189,6 +189,7 @@ static AttributeDescription()
private static readonly byte[] s_signature_HasThis_Void_String_DeprecationType_UInt32 = new byte[] { (byte)SignatureAttributes.Instance, 3, Void, String, TypeHandle, (byte)TypeHandleTarget.DeprecationType, UInt32 };
private static readonly byte[] s_signature_HasThis_Void_String_DeprecationType_UInt32_Platform = new byte[] { (byte)SignatureAttributes.Instance, 4, Void, String, TypeHandle, (byte)TypeHandleTarget.DeprecationType, UInt32, TypeHandle, (byte)TypeHandleTarget.Platform };
private static readonly byte[] s_signature_HasThis_Void_String_DeprecationType_UInt32_Type = new byte[] { (byte)SignatureAttributes.Instance, 4, Void, String, TypeHandle, (byte)TypeHandleTarget.DeprecationType, UInt32, TypeHandle, (byte)TypeHandleTarget.SystemType };
private static readonly byte[] s_signature_HasThis_Void_String_DeprecationType_UInt32_String = new byte[] { (byte)SignatureAttributes.Instance, 4, Void, String, TypeHandle, (byte)TypeHandleTarget.DeprecationType, UInt32, String };
// TODO: We should reuse the byte arrays for well-known attributes with same signatures.
......@@ -386,7 +387,8 @@ static AttributeDescription()
{
s_signature_HasThis_Void_String_DeprecationType_UInt32,
s_signature_HasThis_Void_String_DeprecationType_UInt32_Platform,
s_signature_HasThis_Void_String_DeprecationType_UInt32_Type
s_signature_HasThis_Void_String_DeprecationType_UInt32_Type,
s_signature_HasThis_Void_String_DeprecationType_UInt32_String,
};
// early decoded attributes:
......
......@@ -239,6 +239,7 @@ internal ObsoleteAttributeData DecodeDeprecatedAttribute()
{
// DeprecatedAttribute(String, DeprecationType, UInt32)
// DeprecatedAttribute(String, DeprecationType, UInt32, Platform)
// DeprecatedAttribute(String, DeprecationType, UInt32, String)
message = (string)args[0].Value;
isError = ((int)args[1].Value == 1);
......
......@@ -96,10 +96,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
If node.RelaxationLambdaOpt IsNot Nothing Then
returnValue = node.Update(VisitExpressionNode(node.RelaxationLambdaOpt),
node.ConversionKind, node.Checked, node.ExplicitCastInCode,
node.ConstantValueOpt, node.ConstructorOpt,
relaxationLambdaOpt:=Nothing, relaxationReceiverPlaceholderOpt:=Nothing, type:=node.Type)
returnValue = RewriteLambdaRelaxationConversion(node)
ElseIf node.ConversionKind = ConversionKind.InterpolatedString Then
returnValue = RewriteInterpolatedStringConversion(node)
......@@ -115,6 +112,88 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return returnValue
End Function
Private Function RewriteLambdaRelaxationConversion(node As BoundConversion) As BoundNode
Dim returnValue As BoundNode
If _inExpressionLambda AndAlso
NoParameterRelaxation(node.Operand, node.RelaxationLambdaOpt.LambdaSymbol) Then
' COMPAT: skip relaxation in this case. ET can drop the return value of the inner lambda.
returnValue = MyBase.VisitConversion(
node.Update(node.Operand,
node.ConversionKind, node.Checked, node.ExplicitCastInCode,
node.ConstantValueOpt, node.ConstructorOpt,
relaxationLambdaOpt:=Nothing, relaxationReceiverPlaceholderOpt:=Nothing, type:=node.Type))
returnValue = TransformRewrittenConversion(DirectCast(returnValue, BoundConversion))
Else
returnValue = node.Update(VisitExpressionNode(node.RelaxationLambdaOpt),
node.ConversionKind, node.Checked, node.ExplicitCastInCode,
node.ConstantValueOpt, node.ConstructorOpt,
relaxationLambdaOpt:=Nothing, relaxationReceiverPlaceholderOpt:=Nothing, type:=node.Type)
End If
Return returnValue
End Function
Private Function RewriteLambdaRelaxationConversion(node As BoundDirectCast) As BoundNode
Dim returnValue As BoundNode
If _inExpressionLambda AndAlso
NoParameterRelaxation(node.Operand, node.RelaxationLambdaOpt.LambdaSymbol) Then
' COMPAT: skip relaxation in this case. ET can drop the return value of the inner lambda.
returnValue = MyBase.VisitDirectCast(
node.Update(node.Operand,
node.ConversionKind, node.SuppressVirtualCalls,
node.ConstantValueOpt,
relaxationLambdaOpt:=Nothing, type:=node.Type))
Else
returnValue = node.Update(VisitExpressionNode(node.RelaxationLambdaOpt),
node.ConversionKind, node.SuppressVirtualCalls,
node.ConstantValueOpt,
relaxationLambdaOpt:=Nothing, type:=node.Type)
End If
Return returnValue
End Function
Private Function RewriteLambdaRelaxationConversion(node As BoundTryCast) As BoundNode
Dim returnValue As BoundNode
If _inExpressionLambda AndAlso
NoParameterRelaxation(node.Operand, node.RelaxationLambdaOpt.LambdaSymbol) Then
' COMPAT: skip relaxation in this case. ET can drop the return value of the inner lambda.
returnValue = MyBase.VisitTryCast(
node.Update(node.Operand,
node.ConversionKind,
node.ConstantValueOpt,
relaxationLambdaOpt:=Nothing, type:=node.Type))
Else
returnValue = node.Update(VisitExpressionNode(node.RelaxationLambdaOpt),
node.ConversionKind,
node.ConstantValueOpt,
relaxationLambdaOpt:=Nothing, type:=node.Type)
End If
Return returnValue
End Function
Private Shared Function NoParameterRelaxation(from As BoundExpression, toLambda As LambdaSymbol) As Boolean
Dim fromLambda As LambdaSymbol = TryCast(from, BoundLambda)?.LambdaSymbol
' are we are relaxing for the purpose of dropping return?
Return fromLambda IsNot Nothing AndAlso
Not fromLambda.IsSub AndAlso
toLambda.IsSub AndAlso
MethodSignatureComparer.HaveSameParameterTypes(fromLambda.Parameters, Nothing, toLambda.Parameters, Nothing, considerByRef:=True, considerCustomModifiers:=False)
End Function
' Rewrite Anonymous Delegate conversion into a delegate creation
Private Function RewriteAnonymousDelegateConversion(node As BoundConversion) As BoundNode
Debug.Assert(Not Conversions.IsIdentityConversion(node.ConversionKind))
......@@ -1198,9 +1277,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If node.RelaxationLambdaOpt Is Nothing Then
returnValue = MyBase.VisitDirectCast(node)
Else
returnValue = node.Update(VisitExpressionNode(node.RelaxationLambdaOpt),
node.ConversionKind, node.SuppressVirtualCalls, node.ConstantValueOpt,
relaxationLambdaOpt:=Nothing, type:=node.Type)
returnValue = RewriteLambdaRelaxationConversion(node)
End If
_inExpressionLambda = wasInExpressionlambda
......@@ -1250,9 +1327,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Else
returnValue = node.Update(VisitExpressionNode(node.RelaxationLambdaOpt),
node.ConversionKind, node.ConstantValueOpt,
relaxationLambdaOpt:=Nothing, type:=node.Type)
returnValue = RewriteLambdaRelaxationConversion(node)
End If
_inExpressionLambda = wasInExpressionlambda
......
......@@ -2807,6 +2807,451 @@ Lambda(
]]>)
End Sub
<Fact()>
Public Sub Relaxation01()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of C0)
End Sub
End Module
Class C0
Public Function Process() As Boolean
Return False
End Function
Public Sub ProcessSub()
End Sub
End Class
Class C1(Of T As {New, C0})
Public ProcessMethodSub As MethodInfo = RegisterMethod(Sub(c) c.ProcessSub())
Public ProcessMethod As MethodInfo = RegisterMethod(Function(c) c.Process)
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of T))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(new T())
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
c => c.ProcessSub()
c => c.Process()
]]>)
End Sub
<Fact()>
Public Sub Relaxation02()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process(x As Integer) As Boolean
Return False
End Function
Public Shared Sub ProcessSub(x As Integer)
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(Sub(c As String) C0.ProcessSub(c))
Public ProcessMethod As MethodInfo = RegisterMethod(Function(c) C0.Process(c))
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of String))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(1)
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
c => ProcessSub(ConvertChecked(c))
c => Process(ConvertChecked(c))
]]>)
End Sub
<Fact()>
Public Sub Relaxation03()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process() As Boolean
Return False
End Function
Public Shared Sub ProcessSub()
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(Sub(c As String) C0.ProcessSub())
Public ProcessMethod As MethodInfo = RegisterMethod(Function(c As String) C0.Process())
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of String))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()("qq")
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
c => ProcessSub()
c => Process()
]]>)
End Sub
<Fact()>
Public Sub Relaxation04()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process() As Boolean
Return False
End Function
Public Shared Sub ProcessSub()
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(Sub() C0.ProcessSub())
Public ProcessMethod As MethodInfo = RegisterMethod(Function() C0.Process())
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of Integer))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(1)
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
a0 => Invoke(() => ProcessSub())
a0 => Invoke(() => Process())
]]>)
End Sub
<Fact()>
Public Sub Relaxation05()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process(arg As Action(Of Integer)) As Boolean
Return False
End Function
Public Shared Sub ProcessSub(arg As Action(Of Integer))
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(Sub(t As Integer) C0.ProcessSub(Sub(tt As Integer) C0.ProcessSub(Nothing)))
Public ProcessMethod As MethodInfo = RegisterMethod(Function(t As Integer) C0.Process(Function(tt As Integer) C0.Process(Nothing)))
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of Integer))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(Nothing)
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
t => ProcessSub(tt => ProcessSub(null))
t => Process(tt => Process(null))
]]>)
End Sub
<Fact()>
Public Sub Relaxation05ET()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process(arg As Expression(Of Action(Of Integer))) As Boolean
Return False
End Function
Public Shared Sub ProcessSub(arg As Expression(Of Action(Of Integer)))
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(Sub(t As Integer) C0.ProcessSub(Sub(tt As Integer) C0.ProcessSub(Nothing)))
Public ProcessMethod As MethodInfo = RegisterMethod(Function(t As Integer) C0.Process(Function(tt As Integer) C0.Process(Nothing)))
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of Integer))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(Nothing)
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
t => ProcessSub(tt => ProcessSub(null))
t => Process(tt => Process(null))
]]>)
End Sub
<Fact()>
Public Sub Relaxation06()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process(arg As Action(Of Integer)) As Boolean
Return False
End Function
Public Shared Sub ProcessSub(arg As Action(Of Integer))
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(DirectCast(
Sub(t As Integer) C0.ProcessSub(Sub(tt As Integer) C0.ProcessSub(Nothing)),
Expression(Of Action(Of Integer))))
Public ProcessMethod As MethodInfo = RegisterMethod(DirectCast(
Function(t As Integer) C0.Process(Function(tt As Integer) C0.Process(Nothing)),
Expression(Of Action(Of Integer))))
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of Integer))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(Nothing)
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
t => ProcessSub(tt => ProcessSub(null))
t => Process(tt => Process(null))
]]>)
End Sub
<Fact()>
Public Sub Relaxation07()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
End Sub
End Module
Class C0
Public Shared Function Process(arg As Action(Of Integer)) As Boolean
Return False
End Function
Public Shared Sub ProcessSub(arg As Action(Of Integer))
End Sub
End Class
Class C1(Of T)
Public ProcessMethodSub As MethodInfo = RegisterMethod(TryCast(
Sub(t As Integer) C0.ProcessSub(Sub(tt As Integer) C0.ProcessSub(Nothing)),
Expression(Of Action(Of Integer))))
Public ProcessMethod As MethodInfo = RegisterMethod(TryCast(
Function(t As Integer) C0.Process(Function(tt As Integer) C0.Process(Nothing)),
Expression(Of Action(Of Integer))))
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action(Of Integer))) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()(Nothing)
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
t => ProcessSub(tt => ProcessSub(null))
t => Process(tt => Process(null))
]]>)
End Sub
<Fact()>
Public Sub Relaxation08()
Dim file = <file name="expr.vb"><![CDATA[
Imports System
Imports System.Linq.Expressions
Imports System.Reflection
Module Module1
Sub Main()
Dim o As New C1(Of String)
o.Test()
End Sub
End Module
Class C1(Of T)
Sub Test()
Dim anonymousDelegate = Function(x As Integer) x
RegisterMethod(Sub() M1(anonymousDelegate))
End Sub
Shared Sub M1(y As Action(Of Integer))
End Sub
Public Function RegisterMethod(methodLambdaExpression As Expression(Of Action)) As MethodInfo
System.Console.WriteLine(methodLambdaExpression.ToString())
methodLambdaExpression.Compile()()
Return Nothing
End Function
End Class
]]></file>
TestExpressionTrees(file,
<![CDATA[
() => M1(a0 => Invoke(value(C1`1+_Closure$__1-0[System.String]).$VB$Local_anonymousDelegate, a0))
]]>)
End Sub
#End Region
#Region "Xml Literals"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册