Centralize recognized feature flags#81591
Conversation
There was a problem hiding this comment.
This file makes it clear that we have sinned in our naming.
| } | ||
| } | ||
|
|
||
| /// <remarks>Known feature flags should use <see cref="FeatureFlag"/></remarks> |
There was a problem hiding this comment.
Is there a reflection-based assert we could write to verify this? #Resolved
There was a problem hiding this comment.
We have some tests that pass arbitrary feature flags into the APIs, so I didn't tighten this with assertions.
Let me take a look at how many tests would need updating.
| var testData0 = new CompilationTestData(); | ||
| var bytes0 = compilation0.EmitToArray(testData: testData0); | ||
| var generation0 = CreateInitialBaseline(compilation0, | ||
| ModuleMetadata.CreateFromImage(bytes0), |
There was a problem hiding this comment.
Thanks. Will revert.
No sure what's happening here. For some reason the file after update looks correct in VS... Stupid mistake, confused two worktrees
|
|
||
| namespace Microsoft.CodeAnalysis; | ||
|
|
||
| internal static class FeatureFlag |
There was a problem hiding this comment.
BTW, the members do not look like flags. I think we used to refer to them simply as features or "compiler features".
There was a problem hiding this comment.
Renamed to "Feature" to remove "Flag"
For comments, that's beyond what I intend for this PR. There's more work we could do here, for instance we have an open issue to remove pdb-path-determinism, but I'll leave that for later.
|
Done with review pass (commit 1) |
| if (!_lazyEmitNullablePublicOnly.HasValue()) | ||
| { | ||
| bool value = SyntaxTrees.FirstOrDefault()?.Options?.Features?.ContainsKey("nullablePublicOnly") == true; | ||
| bool value = SyntaxTrees.FirstOrDefault()?.Options?.HasFeature(CodeAnalysis.Feature.NullablePublicOnly) == true; |
There was a problem hiding this comment.
This doesn't seem strictly equivalent to the previous code - null value in the feature dictionary would previously be accepted.
There are other changes like this in the PR (replacing Features?.ContainsKey with HasFeature).
But I guess the new behavior is better, just wanted to point out this is a small breaking change. #Resolved
There was a problem hiding this comment.
Yup, that's correct. That's intended. I normalized the behavior
| Assert.Equal("experimental-data-section-string-literals", Feature.ExperimentalDataSectionStringLiterals); | ||
| var expectedDiagnostics = new[] | ||
| { | ||
| // (15,26): error CS8103: Combined length of user strings used by the program exceeds allowed limit. Try to decrease use of string literals or try the EXPERIMENTAL feature flag 'experimental-data-section-string-literals'. |
There was a problem hiding this comment.
Probably orthogonal to this PR, but consider adding a parameter for the feature flag name in the error message (instead of just the assert above), so we also ensure it's not getting localized. #WontFix
| new[] { ".cctor", "F1" }; | ||
| #endif | ||
|
|
||
| Assert.Equal("run-nullable-analysis", Feature.RunNullableAnalysis); |
There was a problem hiding this comment.
This assert looks unnecessary. #Resolved
| internal bool HasFeature(string feature) | ||
| { | ||
| CodeAnalysis.Feature.AssertValidFeature(feature); | ||
| return _features.TryGetValue(feature, out var value) && value is not null; |
There was a problem hiding this comment.
Perhaps we could simplify this to just:
internal bool HasFeature(string feature) => Feature(feature) != null;
``` #Resolved| internal const string InterceptorsNamespaces = "InterceptorsNamespaces"; | ||
| internal const string NoRefSafetyRulesAttribute = "noRefSafetyRulesAttribute"; | ||
| internal const string DisableLengthBasedSwitch = "disable-length-based-switch"; | ||
| internal const string ExperimentalDataSectionStringLiterals = "experimental-data-section-string-literals"; |
There was a problem hiding this comment.
Just curious, was there any specific reason for the ordering? Was this maybe the order the flags were encountered during your refactoring pass? #Resolved
| /// <summary> | ||
| /// Enable some experimental language features for testing. | ||
| /// </summary> | ||
| // Note: use Feature entry for known feature flags. |
There was a problem hiding this comment.
I guess this is intentionally not included in the doc comment, since this is talking about an internal API with respect to this public API? #Resolved
There was a problem hiding this comment.
Right, the known values are only internal but this API is public
|
Thank you! |
The compiler recognizes some magic feature flag strings. This PR moves those known strings to a centralized location and funnels most of the feature flag checks through common helpers.