Report a level 7 warning for lower-cased type names#56905
Report a level 7 warning for lower-cased type names#56905jcouv merged 14 commits intodotnet:mainfrom
Conversation
d25d9c7 to
4e9ec71
Compare
| { | ||
| if (!GetName(decl.SyntaxReference.GetSyntax()).Text.StartsWith("@")) | ||
| { | ||
| diagnostics.Add(ErrorCode.WRN_LowerCaseTypeName, decl.Location, declaration.Name); |
There was a problem hiding this comment.
Worth adding a code fix provider (IDE-side) for this warning? I'm not sure.
|
@333fred On the day of LDM I'd updated the notes in OP to include types, aliases and namespaces. But the meeting notes only mention types, so I'm having doubts on whether I misunderstood the decision. Do you remember? |
I honestly don't remember whether we'd said anything about namespaces or aliases. I do think we should, but I don't remember if we did. |
|
Can this implementation share any code/codepaths with https://sourceroslyn.io/#Microsoft.CodeAnalysis.CSharp/Symbols/Source/SourceMemberContainerSymbol.cs,455? IE, for records it'll give that specific warning, otherwise it'll give the general warning? Would give us less places to worry about duplicating checks. |
Indeed. We're already checking all these cases (type/type parameter/alias) for special name "record". Thanks |
| internal static void ReportTypeNamedRecord(string? name, CSharpCompilation compilation, DiagnosticBag? diagnostics, Location location) | ||
| internal static bool IsReservedTypeName(string? name) | ||
| { | ||
| return name is { Length: > 0 } && name.All(c => char.IsLower(c) && c < 128); |
There was a problem hiding this comment.
Why not just do c is >= 'a' and <= 'z'? #Resolved
There was a problem hiding this comment.
I don't see a benefit (prefer readability over premature optimization). If anything, I wanted to use char.IsAscii instead of doing a lower-level check, but surprisingly it was introduced in .NET 6.
There was a problem hiding this comment.
I specifically asked because I find the current code less clear than a simple character comparison. What is 128? I don't have the ascii table memorized. Far easier to avoid the confusion and simply say "is it between 'a' and 'z'?"
There was a problem hiding this comment.
I don't think it's simpler. I can extract an isAscii local function (since char.IsAscii isn't available) if you'd like. Let me know.
There was a problem hiding this comment.
I do not think the current code is at all clear, mainly because of the use of an unnamed constant 128. I think this code will be much simpler we do a standard char comparison.
There was a problem hiding this comment.
It seems like c is >= 'a' and <= 'z' is checking something different than c < 128. It might be worth digging a bit to see if constant 128 is anywhere in our character encoding helpers, if you haven't already. Otherwise I think a local variable or function isAscii with a brief comment like "128 is the top of the ascii range" would be fine.
edit: It looks like I'm behind on the latest changes in this conversation. The current implementation which entirely elides the < 128 check seems fine.
| | CS8898 | 5 | [Static class used as the return type of a method in an interface type](https://github.com/dotnet/roslyn/issues/38256) | | ||
| | CS8981 | 7 | [Type names only containing lower-cased ascii characters may become reserved for the language](https://github.com/dotnet/roslyn/issues/56653) | |
There was a problem hiding this comment.
Is warnlevel 6 not documented? Is there a tracking issue for that? #Resolved
src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs
Show resolved
Hide resolved
| var compilation = CreateCompilationWithMscorlib40AndSystemCore(@" | ||
| using System; | ||
| static class m | ||
| static class @m |
There was a problem hiding this comment.
Do you use an automation tool when a change affects many tests like this PR, or are these all manual changes? and if there is a tool, is it publicly available? (I hope this kind of unrelated questions don't bother you :) )
There was a problem hiding this comment.
Manual changes.
If the IDE decides to add automation for this, it would still not help inside our tests unfortunately.
| var text = @" | ||
| using System; | ||
| interface i1 | ||
| interface @i1 |
There was a problem hiding this comment.
Why this is required? The character 1 isn't in the [a-z] range. #Fixed
There was a problem hiding this comment.
Good catch. Those indeed can be left unescaped.
There was a problem hiding this comment.
Note that the #Resolved and similar edits are inserted into our comments by an internal tool. If the goal is to match the conventions of that tool, then:
- we commonly use the tag
#Closedto indicate that the original author of the comment has confirmed the issue to be addressed - the tag
#Resolvedindicates the PR author has made changes to address someone's comment, but the original author of the comment must confirm that the issue was addressed before changing the state to#Closed.
| var text = @" | ||
| using System; | ||
| public interface i1 | ||
| public interface @i1 |
|
|
||
| class A { } | ||
| class Z { } | ||
|
|
There was a problem hiding this comment.
Consider testing class abcdefghijklmnopqrstuvwxyz { }
| class A { } | ||
| class Z { } | ||
|
|
||
| // first lower-case letter outside ascii range |
There was a problem hiding this comment.
Perhaps split these cases that include parse errors into a separate test.
|
Did we test this change against runtime to see how many violations it found? |
|
@jaredpar Haven't tried that. Let me get back to you later today. |
|
@jaredpar Here's the impact on |
Fixes #56653
LDM discussion 10/13/2021.
See test
OnlyOneParse_WithReservedTypeNamefor why the check was moved out of symbol creation (we want to avoid pulling on the syntax tree more than once).