Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NullableContextAttribute #36152

Merged
merged 25 commits into from
Jun 25, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Report error for explicit use of attributes
cston committed Jun 25, 2019
commit 6db60433db56bc0c3f644e82d627b464932b2415
Original file line number Diff line number Diff line change
@@ -2357,6 +2357,10 @@ private void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArguments<Attr

arguments.GetOrCreateData<CommonAssemblyWellKnownAttributeData>().AssemblyAlgorithmIdAttributeSetting = algorithmId;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NullablePublicOnlyAttribute))
{
ReportExplicitUseOfNullabilityAttribute(in arguments, AttributeDescription.NullablePublicOnlyAttribute);
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReportExplicitUseOfNullabilityAttribute(in arguments, AttributeDescription.NullablePublicOnlyAttribute); [](start = 16, length = 104)

Isn't this attribute a module level attribute? I do not think we should duplicate what the attribute usage attribute is for. #Closed

Copy link
Member Author

@cston cston Jun 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check should have been on SourceModuleSymbol. Moved.


In reply to: 296890713 [](ancestors = 296890713)

}
}

// Checks that the integral arguments for the given well-known attribute are non-negative.
Original file line number Diff line number Diff line change
@@ -1226,6 +1226,10 @@ private void DecodeWellKnownAttributeAppliedToMethod(ref DecodeWellKnownAttribut
// [Extension] attribute should not be set explicitly.
arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitExtension, arguments.AttributeSyntaxOpt.Location);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NullableContextAttribute))
{
ReportExplicitUseOfNullabilityAttribute(in arguments, AttributeDescription.NullableContextAttribute);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.SecurityCriticalAttribute)
|| attribute.IsTargetAttribute(this, AttributeDescription.SecuritySafeCriticalAttribute))
{
Original file line number Diff line number Diff line change
@@ -523,6 +523,10 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu
arguments.GetOrCreateData<CommonModuleWellKnownAttributeData>().DefaultCharacterSet = charSet;
}
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NullableContextAttribute))
{
ReportExplicitUseOfNullabilityAttribute(in arguments, AttributeDescription.NullableContextAttribute);
}
}

private bool EmitNullablePublicOnlyAttribute
Original file line number Diff line number Diff line change
@@ -920,6 +920,10 @@ internal sealed override void DecodeWellKnownAttribute(ref DecodeWellKnownAttrib
// NullableAttribute should not be set explicitly.
arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NullableContextAttribute))
{
ReportExplicitUseOfNullabilityAttribute(in arguments, AttributeDescription.NullableContextAttribute);
}
else
{
var compilation = this.DeclaringCompilation;
6 changes: 6 additions & 0 deletions src/Compilers/CSharp/Portable/Symbols/Symbol.cs
Original file line number Diff line number Diff line change
@@ -1156,6 +1156,12 @@ internal static void CheckForBlockAndExpressionBody(
}
}

internal void ReportExplicitUseOfNullabilityAttribute(in DecodeWellKnownAttributeArguments<AttributeSyntax, CSharpAttributeData, AttributeLocation> arguments, AttributeDescription attributeDescription)
{
// Attribute should not be set explicitly.
arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitReservedAttr, arguments.AttributeSyntaxOpt.Location, attributeDescription.FullName);
}

internal byte? GetNullableContextValue()
{
var symbol = this;
Original file line number Diff line number Diff line change
@@ -95,6 +95,54 @@ public sealed class NullableContextAttribute : Attribute
Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "F").WithArguments("System.Runtime.CompilerServices.NullableContextAttribute", ".ctor").WithLocation(3, 19));
}

[Fact]
public void ExplicitAttribute_ReferencedInSource()
{
var sourceAttribute =
@"namespace System.Runtime.CompilerServices
{
internal class NullableContextAttribute : System.Attribute
{
internal NullableContextAttribute(byte b) { }
}
}";
var source =
@"#pragma warning disable 169
using System.Runtime.CompilerServices;
[assembly: NullableContext(0)]
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we get an error for this attribute? #Closed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only if AttributeTargets is set.


In reply to: 296932110 [](ancestors = 296932110)

[module: NullableContext(0)]
[NullableContext(0)]
class Program
{
[NullableContext(0)]object F;
[NullableContext(0)]static object M1() => throw null;
[return: NullableContext(0)]static object M2() => throw null;
static void M3([NullableContext(0)]object arg) { }
}";

// C#7
var comp = CreateCompilation(new[] { sourceAttribute, source }, parseOptions: TestOptions.Regular7);
verifyDiagnostics(comp);

// C#8
comp = CreateCompilation(new[] { sourceAttribute, source });
verifyDiagnostics(comp);

static void verifyDiagnostics(CSharpCompilation comp)
{
comp.VerifyDiagnostics(
// (4,10): error CS8335: Do not use 'System.Runtime.CompilerServices.NullableContextAttribute'. This is reserved for compiler usage.
// [module: NullableContext(0)]
Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "NullableContext(0)").WithArguments("System.Runtime.CompilerServices.NullableContextAttribute").WithLocation(4, 10),
// (5,2): error CS8335: Do not use 'System.Runtime.CompilerServices.NullableContextAttribute'. This is reserved for compiler usage.
// [NullableContext(0)]
Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "NullableContext(0)").WithArguments("System.Runtime.CompilerServices.NullableContextAttribute").WithLocation(5, 2),
// (9,6): error CS8335: Do not use 'System.Runtime.CompilerServices.NullableContextAttribute'. This is reserved for compiler usage.
// [NullableContext(0)]static object M1() => throw null;
Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "NullableContext(0)").WithArguments("System.Runtime.CompilerServices.NullableContextAttribute").WithLocation(9, 6));
}
}

[Fact]
public void ExplicitAttribute_WithNullableContext()
{
Original file line number Diff line number Diff line change
@@ -195,5 +195,54 @@ private static void AssertAttributes(ImmutableArray<CSharpAttributeData> attribu
var actualNames = attributes.Select(a => a.AttributeClass.ToTestDisplayString()).ToArray();
AssertEx.SetEqual(actualNames, expectedNames);
}

[Fact]
[WorkItem(36457, "https://github.com/dotnet/roslyn/issues/36457")]
public void ExplicitAttribute_ReferencedInSource_Assembly()
{
var sourceAttribute =
@"namespace System.Runtime.CompilerServices
{
internal class NullablePublicOnlyAttribute : System.Attribute { }
}";
var source =
@"using System.Runtime.CompilerServices;
[assembly: NullablePublicOnly]";

// C#7
var comp = CreateCompilation(new[] { sourceAttribute, source }, parseOptions: TestOptions.Regular7);
verifyDiagnostics(comp);

// C#8
comp = CreateCompilation(new[] { sourceAttribute, source });
verifyDiagnostics(comp);

static void verifyDiagnostics(CSharpCompilation comp)
{
comp.VerifyDiagnostics(
// (2,12): error CS8335: Do not use 'System.Runtime.CompilerServices.NullablePublicOnlyAttribute'. This is reserved for compiler usage.
// [assembly: NullablePublicOnly]
Diagnostic(ErrorCode.ERR_ExplicitReservedAttr, "NullablePublicOnly").WithArguments("System.Runtime.CompilerServices.NullablePublicOnlyAttribute").WithLocation(2, 12));
}
}

[Fact]
[WorkItem(36457, "https://github.com/dotnet/roslyn/issues/36457")]
public void ExplicitAttribute_ReferencedInSource_Other()
{
var sourceAttribute =
@"namespace System.Runtime.CompilerServices
{
internal class NullablePublicOnlyAttribute : System.Attribute { }
}";
var source =
@"using System.Runtime.CompilerServices;
[NullablePublicOnly]
class Program
{
}";
var comp = CreateCompilation(new[] { sourceAttribute, source });
comp.VerifyDiagnostics();
}
}
}