提交 1b6bac5b 编写于 作者: C Charles Stoner

Do not suppress warnings within [Experimental] member

上级 03b5f4c3
...@@ -559,52 +559,41 @@ internal static ThreeState ReportDiagnosticsIfObsoleteInternal(DiagnosticBag dia ...@@ -559,52 +559,41 @@ internal static ThreeState ReportDiagnosticsIfObsoleteInternal(DiagnosticBag dia
{ {
Debug.Assert(diagnostics != null); Debug.Assert(diagnostics != null);
if (symbol.ObsoleteState == ThreeState.False) var kind = symbol.ObsoleteKind;
{ switch (kind)
return ThreeState.False; {
} case ObsoleteAttributeKind.None:
return ThreeState.False;
var data = symbol.ObsoleteAttributeData; case ObsoleteAttributeKind.Uninitialized:
if (data == null) // If we haven't cracked attributes on the symbol at all or we haven't
{ // cracked attribute arguments enough to be able to report diagnostics for
// Obsolete attribute has errors. // ObsoleteAttribute, store the symbol so that we can report diagnostics at a
return ThreeState.False; // later stage.
} diagnostics.Add(new LazyObsoleteDiagnosticInfo(symbol, containingMember, location), node.GetLocation());
return ThreeState.Unknown;
// If we haven't cracked attributes on the symbol at all or we haven't }
// cracked attribute arguments enough to be able to report diagnostics for
// ObsoleteAttribute, store the symbol so that we can report diagnostics at a kind = containingMember.GetObsoleteContextKind();
// later stage. switch (kind)
if (symbol.ObsoleteState == ThreeState.Unknown) {
{ case ObsoleteAttributeKind.None:
diagnostics.Add(new LazyObsoleteDiagnosticInfo(symbol, containingMember, location), node.GetLocation()); case ObsoleteAttributeKind.Experimental:
return ThreeState.Unknown; // We have all the information we need to report diagnostics right now. So do it.
} var diagInfo = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol, location);
if (diagInfo != null)
// After this point, always return True. {
diagnostics.Add(diagInfo, node.GetLocation());
var inObsoleteContext = ObsoleteAttributeHelpers.GetObsoleteContextState(containingMember); }
break;
// If we are in a context that is already obsolete, there is no point reporting case ObsoleteAttributeKind.Uninitialized:
// more obsolete diagnostics. // If the context is unknown, then store the symbol so that we can do this check at a
if (inObsoleteContext == ThreeState.True) // later stage
{ diagnostics.Add(new LazyObsoleteDiagnosticInfo(symbol, containingMember, location), node.GetLocation());
return ThreeState.True; break;
} default:
// If the context is unknown, then store the symbol so that we can do this check at a // If we are in a context that is already obsolete, there is no point reporting
// later stage // more obsolete diagnostics.
else if (inObsoleteContext == ThreeState.Unknown) break;
{
diagnostics.Add(new LazyObsoleteDiagnosticInfo(symbol, containingMember, location), node.GetLocation());
return ThreeState.True;
}
// We have all the information we need to report diagnostics right now. So do it.
var diagInfo = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol, location);
if (diagInfo != null)
{
diagnostics.Add(diagInfo, node.GetLocation());
return ThreeState.True;
} }
return ThreeState.True; return ThreeState.True;
......
...@@ -33,10 +33,10 @@ internal override DiagnosticInfo GetResolvedInfo() ...@@ -33,10 +33,10 @@ internal override DiagnosticInfo GetResolvedInfo()
if (_symbol.ObsoleteState == ThreeState.True) if (_symbol.ObsoleteState == ThreeState.True)
{ {
var inObsoleteContext = ObsoleteAttributeHelpers.GetObsoleteContextState(_containingSymbol, forceComplete: true); var kind = _containingSymbol.GetObsoleteContextKind(forceComplete: true);
Debug.Assert(inObsoleteContext != ThreeState.Unknown); Debug.Assert(kind != ObsoleteAttributeKind.Uninitialized);
if (inObsoleteContext == ThreeState.False) if (kind == ObsoleteAttributeKind.None)
{ {
DiagnosticInfo info = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(_symbol, _binderFlags); DiagnosticInfo info = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(_symbol, _binderFlags);
if (info != null) if (info != null)
......
...@@ -39,37 +39,42 @@ internal static ObsoleteAttributeData GetObsoleteDataFromMetadata(EntityHandle t ...@@ -39,37 +39,42 @@ internal static ObsoleteAttributeData GetObsoleteDataFromMetadata(EntityHandle t
/// This method checks to see if the given symbol is Obsolete or if any symbol in the parent hierarchy is Obsolete. /// This method checks to see if the given symbol is Obsolete or if any symbol in the parent hierarchy is Obsolete.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// True if some symbol in the parent hierarchy is known to be Obsolete. Unknown if any /// Uninitialized if attributes have not been cracked yet.
/// symbol's Obsoleteness is Unknown. False, if we are certain that no symbol in the parent
/// hierarchy is Obsolete.
/// </returns> /// </returns>
internal static ThreeState GetObsoleteContextState(Symbol symbol, bool forceComplete = false) internal static ObsoleteAttributeKind GetObsoleteContextKind(this Symbol symbol, bool forceComplete = false)
{ {
if ((object)symbol == null) while ((object)symbol != null)
return ThreeState.False;
// For Property or Event accessors, check the associated property or event instead.
if (symbol.IsAccessor())
{
symbol = ((MethodSymbol)symbol).AssociatedSymbol;
}
// If this is the backing field of an event, look at the event instead.
else if (symbol.Kind == SymbolKind.Field && (object)((FieldSymbol)symbol).AssociatedSymbol != null)
{ {
symbol = ((FieldSymbol)symbol).AssociatedSymbol; // For property or event accessors, check the associated property or event instead.
} if (symbol.IsAccessor())
{
symbol = ((MethodSymbol)symbol).AssociatedSymbol;
}
else if (symbol.Kind == SymbolKind.Field)
{
// If this is the backing field of an event, look at the event instead.
var associatedSymbol = ((FieldSymbol)symbol).AssociatedSymbol;
if ((object)associatedSymbol != null)
{
symbol = associatedSymbol;
}
}
if (forceComplete) if (forceComplete)
{ {
symbol.ForceCompleteObsoleteAttribute(); symbol.ForceCompleteObsoleteAttribute();
} }
if (symbol.ObsoleteState != ThreeState.False) var kind = symbol.ObsoleteKind;
{ if (kind != ObsoleteAttributeKind.None)
return symbol.ObsoleteState; {
return kind;
}
symbol = symbol.ContainingSymbol;
} }
return GetObsoleteContextState(symbol.ContainingSymbol, forceComplete); return ObsoleteAttributeKind.None;
} }
/// <summary> /// <summary>
...@@ -79,10 +84,10 @@ internal static ThreeState GetObsoleteContextState(Symbol symbol, bool forceComp ...@@ -79,10 +84,10 @@ internal static ThreeState GetObsoleteContextState(Symbol symbol, bool forceComp
internal static DiagnosticInfo CreateObsoleteDiagnostic(Symbol symbol, BinderFlags location) internal static DiagnosticInfo CreateObsoleteDiagnostic(Symbol symbol, BinderFlags location)
{ {
var data = symbol.ObsoleteAttributeData; var data = symbol.ObsoleteAttributeData;
Debug.Assert(data != null);
if (data == null) if (data == null)
{ {
// ObsoleteAttribute had errors.
return null; return null;
} }
......
...@@ -1018,22 +1018,28 @@ internal ThreeState ObsoleteState ...@@ -1018,22 +1018,28 @@ internal ThreeState ObsoleteState
{ {
get get
{ {
var data = this.ObsoleteAttributeData; switch (ObsoleteKind)
if (data == null)
{
return ThreeState.False;
}
else if (data.IsUninitialized)
{ {
return ThreeState.Unknown; case ObsoleteAttributeKind.None:
} return ThreeState.False;
else case ObsoleteAttributeKind.Uninitialized:
{ return ThreeState.Unknown;
return ThreeState.True; default:
return ThreeState.True;
} }
} }
} }
internal ObsoleteAttributeKind ObsoleteKind
{
get
{
var data = this.ObsoleteAttributeData;
return (data == null) ? ObsoleteAttributeKind.None : data.Kind;
}
}
/// <summary> /// <summary>
/// Returns data decoded from <see cref="ObsoleteAttribute"/> attribute or null if there is no <see cref="ObsoleteAttribute"/> attribute. /// Returns data decoded from <see cref="ObsoleteAttribute"/> attribute or null if there is no <see cref="ObsoleteAttribute"/> attribute.
/// This property returns <see cref="Microsoft.CodeAnalysis.ObsoleteAttributeData.Uninitialized"/> if attribute arguments haven't been decoded yet. /// This property returns <see cref="Microsoft.CodeAnalysis.ObsoleteAttributeData.Uninitialized"/> if attribute arguments haven't been decoded yet.
......
...@@ -167,8 +167,6 @@ static void Main() ...@@ -167,8 +167,6 @@ static void Main()
Diagnostic(ErrorCode.WRN_Experimental, "((I)o).F()").WithArguments("I.F()").WithLocation(11, 9)); Diagnostic(ErrorCode.WRN_Experimental, "((I)o).F()").WithArguments("I.F()").WithLocation(11, 9));
} }
// [Obsolete] and [Deprecated] diagnostics are not
// suppressed inside [Experimental] type.
[Fact] [Fact]
public void TestExperimentalTypeWithDeprecatedAndObsoleteMembers() public void TestExperimentalTypeWithDeprecatedAndObsoleteMembers()
{ {
...@@ -227,8 +225,62 @@ static void F(A a) ...@@ -227,8 +225,62 @@ static void F(A a)
Diagnostic(ErrorCode.WRN_Experimental, "A.B").WithArguments("A.B").WithLocation(27, 14)); Diagnostic(ErrorCode.WRN_Experimental, "A.B").WithArguments("A.B").WithLocation(27, 14));
} }
// Diagnostics for [Obsolete] members
// are not suppressed in [Experimental] types.
[Fact]
public void TestObsoleteMembersInExperimentalType()
{
var source =
@"using System;
using Windows.Foundation.Metadata;
class A
{
internal void F0() { }
[Deprecated("""", DeprecationType.Deprecate, 0)]
internal void F1() { }
[Deprecated("""", DeprecationType.Remove, 0)]
internal void F2() { }
[Obsolete("""", false)]
internal void F3() { }
[Obsolete("""", true)]
internal void F4() { }
[Experimental]
internal class B { }
}
[Experimental]
class C
{
static void F(A a)
{
a.F0();
a.F1();
a.F2();
a.F3();
a.F4();
(new A.B()).ToString();
}
}";
var comp = CreateCompilationWithMscorlibAndSystemCore(new[] { Parse(DeprecatedAttributeSource), Parse(ExperimentalAttributeSource), Parse(source) });
comp.VerifyDiagnostics(
// (23,9): warning CS0618: 'A.F1()' is obsolete: ''
// a.F1();
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "a.F1()").WithArguments("A.F1()", "").WithLocation(23, 9),
// (24,9): error CS0619: 'A.F2()' is obsolete: ''
// a.F2();
Diagnostic(ErrorCode.ERR_DeprecatedSymbolStr, "a.F2()").WithArguments("A.F2()", "").WithLocation(24, 9),
// (25,9): warning CS0618: 'A.F3()' is obsolete: ''
// a.F3();
Diagnostic(ErrorCode.WRN_DeprecatedSymbolStr, "a.F3()").WithArguments("A.F3()", "").WithLocation(25, 9),
// (26,9): error CS0619: 'A.F4()' is obsolete: ''
// a.F4();
Diagnostic(ErrorCode.ERR_DeprecatedSymbolStr, "a.F4()").WithArguments("A.F4()", "").WithLocation(26, 9),
// (27,14): warning CS8305: 'A.B' is for evaluation purposes only and is subject to change or removal in future updates.
// (new A.B()).ToString();
Diagnostic(ErrorCode.WRN_Experimental, "A.B").WithArguments("A.B").WithLocation(27, 14));
}
// Diagnostics for [Experimental] types // Diagnostics for [Experimental] types
// are suppressed in [Obsolete] members. // are not suppressed in [Obsolete] members.
[Fact] [Fact]
public void TestExperimentalTypeInObsoleteMember() public void TestExperimentalTypeInObsoleteMember()
{ {
......
...@@ -7,6 +7,7 @@ namespace Microsoft.CodeAnalysis ...@@ -7,6 +7,7 @@ namespace Microsoft.CodeAnalysis
internal enum ObsoleteAttributeKind internal enum ObsoleteAttributeKind
{ {
None, None,
Uninitialized,
Obsolete, Obsolete,
Deprecated, Deprecated,
Experimental, Experimental,
...@@ -17,7 +18,7 @@ internal enum ObsoleteAttributeKind ...@@ -17,7 +18,7 @@ internal enum ObsoleteAttributeKind
/// </summary> /// </summary>
internal sealed class ObsoleteAttributeData internal sealed class ObsoleteAttributeData
{ {
public static readonly ObsoleteAttributeData Uninitialized = new ObsoleteAttributeData(ObsoleteAttributeKind.None, null, false); public static readonly ObsoleteAttributeData Uninitialized = new ObsoleteAttributeData(ObsoleteAttributeKind.Uninitialized, null, false);
public static readonly ObsoleteAttributeData Experimental = new ObsoleteAttributeData(ObsoleteAttributeKind.Experimental, null, false); public static readonly ObsoleteAttributeData Experimental = new ObsoleteAttributeData(ObsoleteAttributeKind.Experimental, null, false);
public ObsoleteAttributeData(ObsoleteAttributeKind kind, string message, bool isError) public ObsoleteAttributeData(ObsoleteAttributeKind kind, string message, bool isError)
......
...@@ -895,43 +895,35 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -895,43 +895,35 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Debug.Assert(context IsNot Nothing) Debug.Assert(context IsNot Nothing)
Debug.Assert(symbol IsNot Nothing) Debug.Assert(symbol IsNot Nothing)
If symbol.ObsoleteState = ThreeState.False Then Dim kind = symbol.ObsoleteKind
Return Select Case kind
End If Case ObsoleteAttributeKind.None
Return
Dim data = symbol.ObsoleteAttributeData Case ObsoleteAttributeKind.Uninitialized
If data Is Nothing Then ' If we haven't cracked attributes on the symbol at all or we haven't
' Obsolete attribute has errors. ' cracked attribute arguments enough to be able to report diagnostics for
Return ' ObsoleteAttribute, store the symbol so that we can report diagnostics at a
End If ' later stage.
diagnostics.Add(New LazyObsoleteDiagnosticInfo(symbol, context), node.GetLocation())
' If we haven't cracked attributes on the symbol at all or we haven't Return
' cracked attribute arguments enough to be able to report diagnostics for End Select
' ObsoleteAttribute, store the symbol so that we can report diagnostics at a
' later stage. kind = ObsoleteAttributeHelpers.GetObsoleteContextKind(context)
If symbol.ObsoleteState = ThreeState.Unknown OrElse data.IsUninitialized Then Select Case kind
diagnostics.Add(New LazyObsoleteDiagnosticInfo(symbol, context), node.GetLocation()) Case ObsoleteAttributeKind.None, ObsoleteAttributeKind.Experimental
Return ' We have all the information we need to report diagnostics right now. So do it.
End If Dim info = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol)
If info IsNot Nothing Then
Dim inObsoleteContext = ObsoleteAttributeHelpers.GetObsoleteContextState(context) diagnostics.Add(info, node.GetLocation())
End If
' If we are in a context that is already obsolete, there is no point reporting Case ObsoleteAttributeKind.Uninitialized
' more obsolete diagnostics. ' If the context is unknown, then store the symbol so that we can do this check at a
If inObsoleteContext = ThreeState.True Then ' later stage
Return diagnostics.Add(New LazyObsoleteDiagnosticInfo(symbol, context), node.GetLocation())
ElseIf inObsoleteContext = ThreeState.Unknown Then Case Else
' If the context is unknown, then store the symbol so that we can do this check at a ' If we are in a context that is already obsolete, there is no point reporting
' later stage ' more obsolete diagnostics.
diagnostics.Add(New LazyObsoleteDiagnosticInfo(symbol, context), node.GetLocation()) End Select
Return
End If
' We have all the information we need to report diagnostics right now. So do it.
Dim info = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(symbol)
If info IsNot Nothing Then
diagnostics.Add(info, node.GetLocation())
End If
End Sub End Sub
Friend Overridable ReadOnly Property SuppressObsoleteDiagnostics As Boolean Friend Overridable ReadOnly Property SuppressObsoleteDiagnostics As Boolean
......
...@@ -26,10 +26,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -26,10 +26,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
_symbol.ForceCompleteObsoleteAttribute() _symbol.ForceCompleteObsoleteAttribute()
If _symbol.ObsoleteState = ThreeState.True Then If _symbol.ObsoleteState = ThreeState.True Then
Dim inObsoleteContext = ObsoleteAttributeHelpers.GetObsoleteContextState(_containingSymbol, forceComplete:=True) Dim kind = ObsoleteAttributeHelpers.GetObsoleteContextKind(_containingSymbol, forceComplete:=True)
Debug.Assert(inObsoleteContext <> ThreeState.Unknown) Debug.Assert(kind <> ObsoleteAttributeKind.Uninitialized)
If inObsoleteContext = ThreeState.False Then If kind = ObsoleteAttributeKind.None Then
Dim info As DiagnosticInfo = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(_symbol) Dim info As DiagnosticInfo = ObsoleteAttributeHelpers.CreateObsoleteDiagnostic(_symbol)
If info IsNot Nothing Then If info IsNot Nothing Then
Interlocked.CompareExchange(Me._lazyActualObsoleteDiagnostic, info, Nothing) Interlocked.CompareExchange(Me._lazyActualObsoleteDiagnostic, info, Nothing)
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Diagnostics Imports System.Diagnostics
Imports System.Threading
Imports System.Reflection.Metadata Imports System.Reflection.Metadata
Imports System.Threading
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE Imports Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
...@@ -32,50 +32,39 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -32,50 +32,39 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
''' This method checks to see if the given symbol is Obsolete or if any symbol in the parent hierarchy is Obsolete. ''' This method checks to see if the given symbol is Obsolete or if any symbol in the parent hierarchy is Obsolete.
''' </summary> ''' </summary>
''' <returns> ''' <returns>
''' True if some symbol in the parent hierarchy is known to be Obsolete. Unknown if any ''' Uninitialized if attributes have not been cracked yet.
''' symbol's Obsoleteness is Unknown. False, if we are certain that no symbol in the parent
''' hierarchy is Obsolete.
''' </returns> ''' </returns>
Friend Shared Function GetObsoleteContextState(symbol As Symbol, Optional forceComplete As Boolean = False) As ThreeState Friend Shared Function GetObsoleteContextKind(symbol As Symbol, Optional forceComplete As Boolean = False) As ObsoleteAttributeKind
If symbol Is Nothing Then While symbol IsNot Nothing
Return ThreeState.False ' For property or event accessors, check the associated property or event instead.
End If If symbol.IsAccessor() Then
symbol = DirectCast(symbol, MethodSymbol).AssociatedSymbol
If forceComplete Then End If
symbol.ForceCompleteObsoleteAttribute()
End If
Dim associatedPropertyOrEvent = If(symbol.IsAccessor(), DirectCast(symbol, MethodSymbol).AssociatedSymbol, Nothing) If forceComplete Then
symbol.ForceCompleteObsoleteAttribute()
End If
' If this is an event accessor, then consider the event itself for context since Dim kind = symbol.ObsoleteKind
' event accessors cannot be marked obsolete. If kind <> ObsoleteAttributeKind.None Then
If associatedPropertyOrEvent IsNot Nothing AndAlso associatedPropertyOrEvent.Kind = SymbolKind.Event Then Return kind
symbol = DirectCast(symbol, MethodSymbol).AssociatedSymbol End If
End If
If symbol.ObsoleteState <> ThreeState.False Then symbol = symbol.ContainingSymbol
Return symbol.ObsoleteState End While
End If
' If this is a property accessor then check the property for obsoleteness as well so that we suppress Return ObsoleteAttributeKind.None
' obsolete diagnostics anywhere inside a property.
If associatedPropertyOrEvent IsNot Nothing AndAlso associatedPropertyOrEvent.Kind = SymbolKind.Property Then
Return GetObsoleteContextState(associatedPropertyOrEvent, forceComplete)
Else
Return GetObsoleteContextState(symbol.ContainingSymbol, forceComplete)
End If
End Function End Function
''' <summary> ''' <summary>
''' Create a diagnostic for the given symbol. This could be an error or a warning based on ''' Create a diagnostic for the given symbol. This could be an error or a warning based on
''' the ObsoleteAttribute's arguments. ''' the ObsoleteAttribute's arguments.
''' </summary> ''' </summary>
Friend Shared Function CreateObsoleteDiagnostic(symbol As Symbol) As DiagnosticInfo Friend Shared Function CreateObsoleteDiagnostic(symbol As Symbol) As DiagnosticInfo
Dim data = symbol.ObsoleteAttributeData Dim data = symbol.ObsoleteAttributeData
Debug.Assert(data IsNot Nothing)
If data Is Nothing Then If data Is Nothing Then
' ObsoleteAttribute had errors.
Return Nothing Return Nothing
End If End If
......
...@@ -423,15 +423,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ...@@ -423,15 +423,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' This property returns Unknown if the Obsolete Attribute hasn't been cracked yet. ''' This property returns Unknown if the Obsolete Attribute hasn't been cracked yet.
''' </summary> ''' </summary>
Friend ReadOnly Property ObsoleteState As ThreeState Friend ReadOnly Property ObsoleteState As ThreeState
Get
Select Case ObsoleteKind
Case ObsoleteAttributeKind.None
Return ThreeState.False
Case ObsoleteAttributeKind.Uninitialized
Return ThreeState.Unknown
Case Else
Return ThreeState.True
End Select
End Get
End Property
Friend ReadOnly Property ObsoleteKind As ObsoleteAttributeKind
Get Get
Dim data = Me.ObsoleteAttributeData Dim data = Me.ObsoleteAttributeData
If data Is Nothing Then Return If(data Is Nothing, ObsoleteAttributeKind.None, data.Kind)
Return ThreeState.False
ElseIf data Is ObsoleteAttributeData.Uninitialized Then
Return ThreeState.Unknown
Else
Return ThreeState.True
End If
End Get End Get
End Property End Property
......
...@@ -210,8 +210,6 @@ End Class ...@@ -210,8 +210,6 @@ End Class
</compilation> </compilation>
End Sub End Sub
' <Obsolete> and <Deprecated> diagnostics are not
' suppressed inside <Experimental> type.
<Fact()> <Fact()>
Public Sub TestExperimentalTypeWithDeprecatedAndObsoleteMembers() Public Sub TestExperimentalTypeWithDeprecatedAndObsoleteMembers()
Dim comp0 = CreateCompilationWithMscorlib(DeprecatedAndExperimentalAttributeSource) Dim comp0 = CreateCompilationWithMscorlib(DeprecatedAndExperimentalAttributeSource)
...@@ -282,8 +280,74 @@ BC42380: 'A.B' is for evaluation purposes only and is subject to change or remov ...@@ -282,8 +280,74 @@ BC42380: 'A.B' is for evaluation purposes only and is subject to change or remov
</errors>) </errors>)
End Sub End Sub
' Diagnostics for <Obsolete> members
' are not suppressed in <Experimental> types.
<Fact()>
Public Sub TestObsoleteMembersInExperimentalType()
Dim comp0 = CreateCompilationWithMscorlib(DeprecatedAndExperimentalAttributeSource)
comp0.AssertNoDiagnostics()
Dim ref0 = comp0.EmitToImageReference()
Dim source =
<compilation>
<file><![CDATA[
Imports System
Imports Windows.Foundation.Metadata
Class A
Friend Sub F0()
End Sub
<Deprecated("", DeprecationType.Deprecate, 0)>
Friend Sub F1()
End Sub
<Deprecated("", DeprecationType.Remove, 0)>
Friend Sub F2()
End Sub
<Obsolete("", False)>
Friend Sub F3()
End Sub
<Obsolete("", True)>
Friend Sub F4()
End Sub
<Experimental>
Friend Class B
End Class
End Class
<Experimental>
Class C
Shared Sub F(a As A)
a.F0()
a.F1()
a.F2()
a.F3()
a.F4()
Dim b = New A.B()
End Sub
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlib(source, references:={ref0})
comp.AssertTheseDiagnostics(<errors>
BC40008: 'Friend Sub F1()' is obsolete.
a.F1()
~~~~~~
BC31075: 'Friend Sub F2()' is obsolete.
a.F2()
~~~~~~
BC40008: 'Friend Sub F3()' is obsolete.
a.F3()
~~~~~~
BC31075: 'Friend Sub F4()' is obsolete.
a.F4()
~~~~~~
BC42380: 'A.B' is for evaluation purposes only and is subject to change or removal in future updates.
Dim b = New A.B()
~~~
</errors>)
End Sub
' Diagnostics for <Experimental> types ' Diagnostics for <Experimental> types
' are suppressed in [Obsolete] members. ' are not suppressed in <Obsolete> members.
<Fact()> <Fact()>
Public Sub TestExperimentalTypeInObsoleteMember() Public Sub TestExperimentalTypeInObsoleteMember()
Dim comp0 = CreateCompilationWithMscorlib(DeprecatedAndExperimentalAttributeSource) Dim comp0 = CreateCompilationWithMscorlib(DeprecatedAndExperimentalAttributeSource)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册