提交 75a042bf 编写于 作者: V VSadov

require the attribute unconditionally

上级 a2b6cff5
......@@ -455,19 +455,18 @@ private TypeSymbol BindTupleType(TupleTypeSyntax syntax, DiagnosticBag diagnosti
if (hasExplicitNames)
{
// If the tuple type with names is bound in a declaration
// context then we must have the TupleElementNamesAttribute to emit
if (syntax.IsTypeInContextWhichNeedsTupleNamesAttribute())
{
// Report diagnostics if System.String doesn't exist
this.GetSpecialType(SpecialType.System_String, diagnostics, syntax);
// If the tuple type with names is bound we must have the TupleElementNamesAttribute to emit
// it is typically there though, if we have ValueTuple at all
// and we need System.String as well
if (!Compilation.HasTupleNamesAttributes)
{
var info = new CSDiagnosticInfo(ErrorCode.ERR_TupleElementNamesAttributeMissing,
AttributeDescription.TupleElementNamesAttribute.FullName);
Error(diagnostics, info, syntax);
}
// Report diagnostics if System.String doesn't exist
this.GetSpecialType(SpecialType.System_String, diagnostics, syntax);
if (!Compilation.HasTupleNamesAttributes)
{
var info = new CSDiagnosticInfo(ErrorCode.ERR_TupleElementNamesAttributeMissing,
AttributeDescription.TupleElementNamesAttribute.FullName);
Error(diagnostics, info, syntax);
}
}
......
......@@ -214,12 +214,6 @@ internal static bool IsTypeInContextWhichNeedsDynamicAttribute(this IdentifierNa
return SyntaxFacts.IsInTypeOnlyContext(typeNode) && IsInContextWhichNeedsDynamicAttribute(typeNode);
}
internal static bool IsTypeInContextWhichNeedsTupleNamesAttribute(this TupleTypeSyntax syntax)
{
Debug.Assert(syntax != null);
return SyntaxFacts.IsInTypeOnlyContext(syntax) && IsInContextWhichNeedsTupleNamesAttribute(syntax);
}
internal static SyntaxNode SkipParens(this SyntaxNode expression)
{
while (expression != null && expression.Kind() == SyntaxKind.ParenthesizedExpression)
......@@ -262,45 +256,6 @@ private static bool IsInContextWhichNeedsDynamicAttribute(CSharpSyntaxNode node)
}
}
private static bool IsInContextWhichNeedsTupleNamesAttribute(CSharpSyntaxNode node)
{
Debug.Assert(node != null);
var current = node;
do
{
switch (current.Kind())
{
case SyntaxKind.Parameter:
case SyntaxKind.FieldDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.IndexerDeclaration:
case SyntaxKind.OperatorDeclaration:
case SyntaxKind.ConversionOperatorDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.DelegateDeclaration:
case SyntaxKind.EventDeclaration:
case SyntaxKind.EventFieldDeclaration:
case SyntaxKind.BaseList:
case SyntaxKind.SimpleBaseType:
case SyntaxKind.TypeParameterConstraintClause:
return true;
case SyntaxKind.Block:
case SyntaxKind.VariableDeclarator:
case SyntaxKind.Attribute:
case SyntaxKind.EqualsValueClause:
return false;
default:
break;
}
current = current.Parent;
} while (current != null);
return false;
}
public static IndexerDeclarationSyntax Update(
this IndexerDeclarationSyntax syntax,
SyntaxList<AttributeListSyntax> attributeLists,
......
......@@ -160,9 +160,11 @@ static void Main()
var ref0 = comp.EmitToImageReference();
comp = CreateCompilation(source1,
references: s_attributeRefs.Concat(new[] { ref0 }));
comp.VerifyDiagnostics();
// Make sure we emit without errors when System.String is missing.
CompileAndVerify(comp, verify: false);
comp.VerifyDiagnostics(
// (6,11): error CS0518: Predefined type 'System.String' is not defined or imported
// D<(int x, int y)> d = o => { };
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "(int x, int y)").WithArguments("System.String").WithLocation(6, 11)
);
}
[Fact]
......
......@@ -23120,7 +23120,20 @@ struct ValueTuple<T1, T2>
public T2 Item2;
public ValueTuple(T1 item1, T2 item2) { Item1 = item1; Item2 = item2; }
}
}";
}
namespace System.Runtime.CompilerServices
{
/// <summary>
/// Indicates that the use of <see cref=""System.ValueTuple""/> on a member is meant to be treated as a tuple with element names.
/// </summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue | AttributeTargets.Class | AttributeTargets.Struct )]
public sealed class TupleElementNamesAttribute : Attribute
{
public TupleElementNamesAttribute(string[] transformNames) { }
}
}
";
var compilation = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugExe);
compilation.VerifyDiagnostics(
// (10,59): error CS8198: An expression tree may not contain an out argument variable declaration.
......
......@@ -3273,7 +3273,6 @@ internal static bool IsSynthesizedAttributeOptional(WellKnownMember attributeMem
case WellKnownMember.System_STAThreadAttribute__ctor:
case WellKnownMember.System_Runtime_CompilerServices_AsyncStateMachineAttribute__ctor:
case WellKnownMember.System_Runtime_CompilerServices_IteratorStateMachineAttribute__ctor:
case WellKnownMember.System_Runtime_CompilerServices_TupleElementNamesAttribute__ctorTransformNames:
return true;
default:
......
......@@ -695,6 +695,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' set of names already used
Dim uniqueFieldNames = New HashSet(Of String)(IdentifierComparison.Comparer)
Dim hasExplicitNames = False
For i As Integer = 0 To numElements - 1
Dim argumentSyntax = syntax.Elements(i)
......@@ -713,6 +714,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
name = nameSyntax.Identifier.ValueText
' validate name if we have one
hasExplicitNames = True
Binder.CheckTupleMemberName(name, i, nameSyntax, diagnostics, uniqueFieldNames)
locations.Add(nameSyntax.GetLocation)
Else
......@@ -722,6 +724,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Binder.CollectTupleFieldMemberNames(name, i + 1, numElements, elementNames)
Next
If hasExplicitNames Then
' If the tuple type with names is bound then we must have the TupleElementNamesAttribute to emit
' it is typically there though, if we have ValueTuple at all
' and we need System.String as well
' Report diagnostics if System.String doesn't exist
binder.GetSpecialType(SpecialType.System_String, syntax, diagnostics)
If Not binder.Compilation.HasTupleNamesAttributes Then
Binder.ReportDiagnostic(diagnostics, syntax, ERRID.ERR_TupleElementNamesAttributeMissing, AttributeDescription.TupleElementNamesAttribute.FullName)
End If
End If
Dim typesArray As ImmutableArray(Of TypeSymbol) = types.ToImmutableAndFree()
Dim locationsArray As ImmutableArray(Of Location) = locations.ToImmutableAndFree()
......
......@@ -1702,6 +1702,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ERR_ValueTupleTypeRefResolutionError = 37267
ERR_TupleElementNamesAttributeMissing = 37268
ERR_ExplicitTupleElementNames = 37269
'// WARNINGS BEGIN HERE
WRN_UseOfObsoleteSymbol2 = 40000
WRN_MustOverloadBase4 = 40003
......
......@@ -4457,6 +4457,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Cannot reference &apos;System.Runtime.CompilerServices.TupleElementNamesAttribute&apos; explicitly. Use the tuple syntax to define tuple names..
'''</summary>
Friend ReadOnly Property ERR_ExplicitTupleElementNames() As String
Get
Return ResourceManager.GetString("ERR_ExplicitTupleElementNames", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Type &apos;{0}&apos; exported from module &apos;{1}&apos; conflicts with type declared in primary module of this assembly..
'''</summary>
......@@ -10388,6 +10397,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Cannot define a class or member that utilizes tuples because the compiler required type &apos;{0}&apos; cannot be found. Are you missing a reference?.
'''</summary>
Friend ReadOnly Property ERR_TupleElementNamesAttributeMissing() As String
Get
Return ResourceManager.GetString("ERR_TupleElementNamesAttributeMissing", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Tuple member name &apos;{0}&apos; is only allowed at position {1}..
'''</summary>
......
......@@ -5391,6 +5391,12 @@
<data name="ERR_TupleTooFewElements" xml:space="preserve">
<value>Tuple must contain at least two elements.</value>
</data>
<data name="ERR_TupleElementNamesAttributeMissing" xml:space="preserve">
<value>Cannot define a class or member that utilizes tuples because the compiler required type '{0}' cannot be found. Are you missing a reference?</value>
</data>
<data name="ERR_ExplicitTupleElementNames" xml:space="preserve">
<value>Cannot reference 'System.Runtime.CompilerServices.TupleElementNamesAttribute' explicitly. Use the tuple syntax to define tuple names.</value>
</data>
<data name="ERR_RefReturningCallInExpressionTree" xml:space="preserve">
<value>An expression tree may not contain a call to a method or property that returns by reference.</value>
</data>
......
......@@ -35,6 +35,15 @@ Namespace System
End Sub
End Structure
End Namespace
namespace System.Runtime.CompilerServices
<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Parameter Or AttributeTargets.Property Or AttributeTargets.ReturnValue Or AttributeTargets.Class Or AttributeTargets.Struct )>
public class TupleElementNamesAttribute : Inherits Attribute
public Sub New(transformNames As String())
End Sub
End Class
End Namespace
"
ReadOnly s_trivialRemainingTuples As String = "
Namespace System
......@@ -64,6 +73,7 @@ Namespace System
End Structure
End Namespace
"
<Fact>
Public Sub TupleTypeBinding()
......@@ -143,6 +153,9 @@ BC37267: Predefined type 'ValueTuple(Of ,)' is not defined or imported.
BC37267: Predefined type 'ValueTuple(Of ,)' is not defined or imported.
Dim t1 as (A As Integer, B As Integer)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC37268: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?
Dim t1 as (A As Integer, B As Integer)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
</errors>)
End Sub
......@@ -710,6 +723,14 @@ Namespace System
End Structure
End Namespace
namespace System.Runtime.CompilerServices
&lt;AttributeUsage(AttributeTargets.Field Or AttributeTargets.Parameter Or AttributeTargets.Property Or AttributeTargets.ReturnValue Or AttributeTargets.Class Or AttributeTargets.Struct )>
public class TupleElementNamesAttribute : Inherits Attribute
public Sub New(transformNames As String())
End Sub
End Class
End Namespace
</file>
</compilation>, expectedOutput:=<![CDATA[
42
......@@ -966,6 +987,14 @@ Namespace System
End Structure
End Namespace
namespace System.Runtime.CompilerServices
&lt;AttributeUsage(AttributeTargets.Field Or AttributeTargets.Parameter Or AttributeTargets.Property Or AttributeTargets.ReturnValue Or AttributeTargets.Class Or AttributeTargets.Struct )>
public class TupleElementNamesAttribute : Inherits Attribute
public Sub New(transformNames As String())
End Sub
End Class
End Namespace
</file>
</compilation>, useLatestFramework:=True, expectedOutput:="42
123
......@@ -4250,6 +4279,9 @@ BC37267: Predefined type 'ValueTuple(Of ,)' is not defined or imported.
BC37267: Predefined type 'ValueTuple(Of ,)' is not defined or imported.
Public Shared Function M(Of T1, T2)() As (first As T1, second As T2)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC37268: Cannot define a class or member that utilizes tuples because the compiler required type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' cannot be found. Are you missing a reference?
Public Shared Function M(Of T1, T2)() As (first As T1, second As T2)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
BC37267: Predefined type 'ValueTuple(Of ,)' is not defined or imported.
return (Nothing, Nothing)
~~~~~~~~~~~~~~~~~~
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册