diff --git a/docs/features/interceptors.md b/docs/features/interceptors.md index 72d340e44641e..c34d5294446b0 100644 --- a/docs/features/interceptors.md +++ b/docs/features/interceptors.md @@ -218,12 +218,14 @@ There is an experimental public API `GetInterceptorMethod(this SemanticModel, In ### User opt-in -To use interceptors, the user project must specify the property ``. This is a list of namespaces which are allowed to contain interceptors. +To use interceptors, the user project must specify the property ``. This is a list of namespaces which are allowed to contain interceptors. ```xml -$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated +$(InterceptorsNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated ``` -It's expected that each entry in the `InterceptorsPreviewNamespaces` list roughly corresponds to one source generator. Well-behaved components are expected to not insert interceptors into namespaces they do not own. +It's expected that each entry in the `InterceptorsNamespaces` list roughly corresponds to one source generator. Well-behaved components are expected to not insert interceptors into namespaces they do not own. + +For compatibility, the property `` can be used as an alias for ``. If both properties have non-empty values, they will be concatenated together in the order `$(InterceptorsNamespaces);$(InterceptorsPreviewNamespaces)` when passed to the compiler. ### Implementation strategy diff --git a/src/Compilers/CSharp/Portable/CSharpParseOptions.cs b/src/Compilers/CSharp/Portable/CSharpParseOptions.cs index 675f7cd9db8ed..8ae7033ac2fd0 100644 --- a/src/Compilers/CSharp/Portable/CSharpParseOptions.cs +++ b/src/Compilers/CSharp/Portable/CSharpParseOptions.cs @@ -22,7 +22,7 @@ public sealed class CSharpParseOptions : ParseOptions, IEquatable _features; - private ImmutableArray> _interceptorsPreviewNamespaces; + private ImmutableArray> _interceptorsNamespaces; /// /// Gets the effective language version, which the compiler uses to select the @@ -177,21 +177,21 @@ public override IReadOnlyDictionary Features } } - internal ImmutableArray> InterceptorsPreviewNamespaces + internal ImmutableArray> InterceptorsNamespaces { get { - if (!_interceptorsPreviewNamespaces.IsDefault) + if (!_interceptorsNamespaces.IsDefault) { - return _interceptorsPreviewNamespaces; + return _interceptorsNamespaces; } // e.g. [["System", "Threading"], ["System", "Collections"]] - ImmutableArray> previewNamespaces = Features.TryGetValue("InterceptorsPreviewNamespaces", out var namespaces) && namespaces.Length > 0 + ImmutableArray> previewNamespaces = Features.TryGetValue("InterceptorsNamespaces", out var namespaces) && namespaces.Length > 0 ? makeNamespaces(namespaces) : ImmutableArray>.Empty; - ImmutableInterlocked.InterlockedInitialize(ref _interceptorsPreviewNamespaces, previewNamespaces); + ImmutableInterlocked.InterlockedInitialize(ref _interceptorsNamespaces, previewNamespaces); return previewNamespaces; static ImmutableArray> makeNamespaces(string namespaces) diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 283e8657cfaac..50301b93c6332 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -7609,7 +7609,7 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ A switch expression arm does not begin with a 'case' keyword. - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. An interceptor cannot be declared in the global namespace. diff --git a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs index 9c1ff91e6ab4a..108c348aa4427 100644 --- a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs +++ b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs @@ -267,7 +267,7 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable ar } else { - // When a features value like "InterceptorsPreviewNamespaces=NS1;NS2" is provided, + // When a features value like "InterceptorsNamespaces=NS1;NS2" is provided, // the build system will quote it so that splitting doesn't occur in the wrong layer. // We need to unquote here so that subsequent layers can properly identify the feature name and value. features.Add(value.Unquote()); diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs index 64791d2be8f46..bb5183e3e9d75 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMethodSymbolWithAttributes.cs @@ -1020,7 +1020,7 @@ private void DecodeInterceptsLocationChecksumBased(DecodeWellKnownAttributeArgum return; } - var interceptorsNamespaces = ((CSharpParseOptions)attributeNameSyntax.SyntaxTree.Options).InterceptorsPreviewNamespaces; + var interceptorsNamespaces = ((CSharpParseOptions)attributeNameSyntax.SyntaxTree.Options).InterceptorsNamespaces; var thisNamespaceNames = getNamespaceNames(this); var foundAnyMatch = interceptorsNamespaces.Any(static (ns, thisNamespaceNames) => isDeclaredInNamespace(thisNamespaceNames, ns), thisNamespaceNames); if (!foundAnyMatch) @@ -1149,7 +1149,7 @@ static void reportFeatureNotEnabled(BindingDiagnosticBag diagnostics, Location a } else { - var recommendedProperty = $"$(InterceptorsPreviewNamespaces);{string.Join(".", namespaceNames)}"; + var recommendedProperty = $"$(InterceptorsNamespaces);{string.Join(".", namespaceNames)}"; diagnostics.Add(ErrorCode.ERR_InterceptorsFeatureNotEnabled, attributeLocation, recommendedProperty); } } @@ -1170,7 +1170,7 @@ private void DecodeInterceptsLocationAttributeExperimentalCompat( const int lineNumberParameterIndex = 1; const int characterNumberParameterIndex = 2; - var interceptorsNamespaces = ((CSharpParseOptions)attributeSyntax.SyntaxTree.Options).InterceptorsPreviewNamespaces; + var interceptorsNamespaces = ((CSharpParseOptions)attributeSyntax.SyntaxTree.Options).InterceptorsNamespaces; var thisNamespaceNames = getNamespaceNames(); var foundAnyMatch = interceptorsNamespaces.Any(ns => isDeclaredInNamespace(thisNamespaceNames, ns)); if (!foundAnyMatch) @@ -1362,7 +1362,7 @@ static void reportFeatureNotEnabled(BindingDiagnosticBag diagnostics, AttributeS } else { - var recommendedProperty = $"$(InterceptorsPreviewNamespaces);{string.Join(".", namespaceNames)}"; + var recommendedProperty = $"$(InterceptorsNamespaces);{string.Join(".", namespaceNames)}"; diagnostics.Add(ErrorCode.ERR_InterceptorsFeatureNotEnabled, attributeSyntax, recommendedProperty); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs index 229f61355c2dd..11a59bf87bafd 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceModuleSymbol.cs @@ -343,7 +343,7 @@ void discoverInterceptors() var toVisit = ArrayBuilder.GetInstance(); // Search the namespaces which were indicated to contain interceptors. - ImmutableArray> interceptorsNamespaces = ((CSharpParseOptions)location.SourceTree.Options).InterceptorsPreviewNamespaces; + ImmutableArray> interceptorsNamespaces = ((CSharpParseOptions)location.SourceTree.Options).InterceptorsNamespaces; foreach (ImmutableArray namespaceParts in interceptorsNamespaces) { if (namespaceParts is ["global"]) diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index b1dea486f3bfe..7eeb92e8f2550 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - Experimentální funkce interceptors není v tomto oboru názvů povolená. Přidejte do projektu {0}. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + Experimentální funkce interceptors není v tomto oboru názvů povolená. Přidejte do projektu {0}. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 9b85a9f212ea1..5103839ac5cfb 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - Das experimentelle Feature "Interceptors" ist nicht in diesem Namespace aktiviert. Fügen Sie Ihrem Projekt "{0}" hinzu. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + Das experimentelle Feature "Interceptors" ist nicht in diesem Namespace aktiviert. Fügen Sie Ihrem Projekt "{0}" hinzu. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index 9f5094c9c1f6d..3cdbfd68c3ed4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - La característica experimental "interceptores" no está habilitada en este espacio de nombres. Agregue '{0}' al proyecto. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + La característica experimental "interceptores" no está habilitada en este espacio de nombres. Agregue '{0}' al proyecto. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index 0556de0512f26..a38956df8bf65 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - La fonctionnalité expérimentale « intercepteurs » n'est pas activée dans cet espace de noms. Ajoutez « {0} » à votre projet. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + La fonctionnalité expérimentale « intercepteurs » n'est pas activée dans cet espace de noms. Ajoutez « {0} » à votre projet. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index 482486f7b95b8..d91e527ec8508 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - La funzionalità sperimentale 'intercettori' non è abilitata in questo spazio dei nomi. Aggiungere '{0}' al progetto. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + La funzionalità sperimentale 'intercettori' non è abilitata in questo spazio dei nomi. Aggiungere '{0}' al progetto. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index 757d82e765440..0db8aef6dd8f8 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - 'インターセプター' の実験的な機能は、この名前空間では有効になっていません。プロジェクトに '{0}' を追加します。 + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + 'インターセプター' の実験的な機能は、この名前空間では有効になっていません。プロジェクトに '{0}' を追加します。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 5997a9a70af03..55d622a071e01 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - 이 네임스페이스에서는 '인터셉터' 실험적 기능을 사용할 수 없습니다. 프로젝트에 '{0}'을(를) 추가하세요. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + 이 네임스페이스에서는 '인터셉터' 실험적 기능을 사용할 수 없습니다. 프로젝트에 '{0}'을(를) 추가하세요. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 841c0f7a71798..f946433f4b555 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - Funkcja eksperymentalna „interceptorów” nie jest włączona w tej przestrzeni nazw. Dodaj „{0}” do swojego projektu. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + Funkcja eksperymentalna „interceptorów” nie jest włączona w tej przestrzeni nazw. Dodaj „{0}” do swojego projektu. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index a6579e5a2a266..5f03a10fc85b7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - O recurso experimental “interceptadores” não está habilitado neste namespace. Adicione “{0}” ao seu projeto. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + O recurso experimental “interceptadores” não está habilitado neste namespace. Adicione “{0}” ao seu projeto. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index e50f92ee9ab29..8c05dda987742 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - Экспериментальная функция "перехватчики" не включена в этом пространстве имен. Добавьте "{0}" в свой проект. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + Экспериментальная функция "перехватчики" не включена в этом пространстве имен. Добавьте "{0}" в свой проект. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index ef7f39cd069dd..2045c2cb60058 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - 'Engelleyiciler' deneysel özelliği bu ad alanında etkin değil. Projenize '{0}' ekleyin. + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + 'Engelleyiciler' deneysel özelliği bu ad alanında etkin değil. Projenize '{0}' ekleyin. diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index c3da2594a2438..c6aa9f6795f8b 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - 此命名空间中未启用“拦截器”实验性功能。请将“{0}”添加到项目。 + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + 此命名空间中未启用“拦截器”实验性功能。请将“{0}”添加到项目。 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index 0d5ff8e552a73..2d4dcfb740382 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -1148,8 +1148,8 @@ - The 'interceptors' experimental feature is not enabled in this namespace. Add '{0}' to your project. - 未在此命名空間中啟用「攔截器」實驗功能。將 '{0}' 新增至您的專案。 + The 'interceptors' feature is not enabled in this namespace. Add '{0}' to your project. + 未在此命名空間中啟用「攔截器」實驗功能。將 '{0}' 新增至您的專案。 diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index 6564948864ebd..f8f1bcbb37b6a 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -12249,9 +12249,9 @@ public void StrongNameProviderWithCustomTempPath() } [Theory] - [InlineData(@"/features:InterceptorsPreviewNamespaces=NS1.NS2;NS3.NS4")] - [InlineData(@"/features:""InterceptorsPreviewNamespaces=NS1.NS2;NS3.NS4""")] - public void FeaturesInterceptorsPreviewNamespaces_OptionParsing(string features) + [InlineData(@"/features:InterceptorsNamespaces=NS1.NS2;NS3.NS4")] + [InlineData(@"/features:""InterceptorsNamespaces=NS1.NS2;NS3.NS4""")] + public void FeaturesInterceptorsNamespaces_OptionParsing(string features) { var tempDir = Temp.CreateDirectory(); var workingDir = Temp.CreateDirectory(); @@ -12262,33 +12262,54 @@ public void FeaturesInterceptorsPreviewNamespaces_OptionParsing(string features) var comp = (CSharpCompilation)csc.CreateCompilation(new StringWriter(), new TouchedFileLogger(), errorLogger: null); var options = comp.SyntaxTrees[0].Options; Assert.Equal(1, options.Features.Count); - Assert.Equal("NS1.NS2;NS3.NS4", options.Features["InterceptorsPreviewNamespaces"]); + Assert.Equal("NS1.NS2;NS3.NS4", options.Features["InterceptorsNamespaces"]); - var previewNamespaces = ((CSharpParseOptions)options).InterceptorsPreviewNamespaces; + var previewNamespaces = ((CSharpParseOptions)options).InterceptorsNamespaces; Assert.Equal(2, previewNamespaces.Length); Assert.Equal(new[] { "NS1", "NS2" }, previewNamespaces[0]); Assert.Equal(new[] { "NS3", "NS4" }, previewNamespaces[1]); } [Fact] - public void FeaturesInterceptorsPreviewNamespaces_Duplicate() + public void FeaturesInterceptorsNamespaces_Duplicate() { var tempDir = Temp.CreateDirectory(); var workingDir = Temp.CreateDirectory(); workingDir.CreateFile("a.cs"); var buildPaths = new BuildPaths(clientDir: "", workingDir: workingDir.Path, sdkDir: null, tempDir: tempDir.Path); - var csc = new MockCSharpCompiler(null, buildPaths, args: new[] { @"/features:InterceptorsPreviewNamespaces=NS1.NS2", @"/features:InterceptorsPreviewNamespaces=NS3.NS4", "a.cs" }); + var csc = new MockCSharpCompiler(null, buildPaths, args: new[] { @"/features:InterceptorsNamespaces=NS1.NS2", @"/features:InterceptorsNamespaces=NS3.NS4", "a.cs" }); var comp = (CSharpCompilation)csc.CreateCompilation(new StringWriter(), new TouchedFileLogger(), errorLogger: null); var options = comp.SyntaxTrees[0].Options; Assert.Equal(1, options.Features.Count); - Assert.Equal("NS3.NS4", options.Features["InterceptorsPreviewNamespaces"]); + Assert.Equal("NS3.NS4", options.Features["InterceptorsNamespaces"]); - var previewNamespaces = ((CSharpParseOptions)options).InterceptorsPreviewNamespaces; + var previewNamespaces = ((CSharpParseOptions)options).InterceptorsNamespaces; Assert.Equal(1, previewNamespaces.Length); Assert.Equal(new[] { "NS3", "NS4" }, previewNamespaces[0]); } + [Fact] + public void FeaturesInterceptorsPreviewNamespaces_NotRecognizedInCommandLine() + { + // '' is recognized in the build task and passed through as a '/features:InterceptorsNamespaces=...' argument. + // '/features:InterceptorsPreviewNamespaces=...' is included in the Features dictionary but does not enable the interceptors feature. + var tempDir = Temp.CreateDirectory(); + var workingDir = Temp.CreateDirectory(); + workingDir.CreateFile("a.cs"); + + var buildPaths = new BuildPaths(clientDir: "", workingDir: workingDir.Path, sdkDir: null, tempDir: tempDir.Path); + var csc = new MockCSharpCompiler(null, buildPaths, args: new[] { @"/features:InterceptorsPreviewNamespaces=NS1.NS2", "a.cs" }); + var comp = (CSharpCompilation)csc.CreateCompilation(new StringWriter(), new TouchedFileLogger(), errorLogger: null); + var options = comp.SyntaxTrees[0].Options; + + Assert.Equal(1, options.Features.Count); + Assert.Equal("NS1.NS2", options.Features["InterceptorsPreviewNamespaces"]); + + Assert.False(options.Features.ContainsKey("InterceptorsNamespaces")); + Assert.Empty(((CSharpParseOptions)options).InterceptorsNamespaces); + } + public class QuotedArgumentTests : CommandLineTestBase { private static readonly string s_rootPath = ExecutionConditionUtil.IsWindows @@ -14372,7 +14393,7 @@ public InterceptsLocationAttribute(string filePath, int line, int character) """; var generator = new SingleFileTestGenerator(generatedSource, "Generated.cs"); - VerifyOutput(dir, src, includeCurrentAssemblyAsAnalyzerReference: false, additionalFlags: ["/langversion:preview", "/out:embed.exe", "/features:InterceptorsPreviewNamespaces=Generated"], generators: [generator], analyzers: null); + VerifyOutput(dir, src, includeCurrentAssemblyAsAnalyzerReference: false, additionalFlags: ["/langversion:preview", "/out:embed.exe", "/features:InterceptorsNamespaces=Generated"], generators: [generator], analyzers: null); ValidateWrittenSources([]); // Clean up temp files @@ -14431,7 +14452,7 @@ public InterceptsLocationAttribute(string filePath, int line, int character) var generator = new SingleFileTestGenerator(generatedSource, "Generated.cs"); var objDir = dir.CreateDirectory("obj"); - VerifyOutput(dir, src, includeCurrentAssemblyAsAnalyzerReference: false, additionalFlags: ["/langversion:preview", $"/out:{objDir.Path}/embed.exe", "/features:InterceptorsPreviewNamespaces=Generated"], generators: [generator], analyzers: null); + VerifyOutput(dir, src, includeCurrentAssemblyAsAnalyzerReference: false, additionalFlags: ["/langversion:preview", $"/out:{objDir.Path}/embed.exe", "/features:InterceptorsNamespaces=Generated"], generators: [generator], analyzers: null); ValidateWrittenSources([]); // Clean up temp files @@ -14501,7 +14522,7 @@ public InterceptsLocationAttribute(string filePath, int line, int character) "/generatedfilesout:" + objDir.Path, "/langversion:preview", "/out:embed.exe", - "/features:InterceptorsPreviewNamespaces=Generated", + "/features:InterceptorsNamespaces=Generated", .. string.IsNullOrEmpty(pathMapArgument) ? default(Span) : [pathMapArgument] ], generators: [generator], diff --git a/src/Compilers/CSharp/Test/EndToEnd/EndToEndTests.cs b/src/Compilers/CSharp/Test/EndToEnd/EndToEndTests.cs index 64cc4a4f131e7..9fc40f7fc40b3 100644 --- a/src/Compilers/CSharp/Test/EndToEnd/EndToEndTests.cs +++ b/src/Compilers/CSharp/Test/EndToEnd/EndToEndTests.cs @@ -583,7 +583,7 @@ public static void M() """, $"C{i}.cs")); } - var verifier = CompileAndVerify(files.ToArrayAndFree(), parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "global"), expectedOutput: makeExpectedOutput()); + var verifier = CompileAndVerify(files.ToArrayAndFree(), parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global"), expectedOutput: makeExpectedOutput()); verifier.VerifyDiagnostics(); string makeExpectedOutput() diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs index 41187c8c9f6de..65e93bb7c829f 100644 --- a/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/Semantics/InterceptorsTests.cs @@ -33,7 +33,7 @@ public InterceptsLocationAttribute(int version, string data) { } } """, "attributes.cs"); - private static readonly CSharpParseOptions RegularWithInterceptors = TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "global"); + private static readonly CSharpParseOptions RegularWithInterceptors = TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global"); private static readonly SyntaxTree s_attributesTree = CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors); @@ -110,41 +110,41 @@ class D } """; - var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS")); + var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS")); comp.VerifyEmitDiagnostics( - // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '$(InterceptorsPreviewNamespaces);NS1' to your project. + // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '$(InterceptorsNamespaces);NS1' to your project. // [InterceptsLocation("Program.cs", 4, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsPreviewNamespaces);NS1").WithLocation(15, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsNamespaces);NS1").WithLocation(15, 10)); - comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS1.NS2")); + comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1.NS2")); comp.VerifyEmitDiagnostics( - // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '$(InterceptorsPreviewNamespaces);NS1' to your project. + // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '$(InterceptorsNamespaces);NS1' to your project. // [InterceptsLocation("Program.cs", 4, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsPreviewNamespaces);NS1").WithLocation(15, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsNamespaces);NS1").WithLocation(15, 10)); - var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS1"), expectedOutput: "1"); + var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1"), expectedOutput: "1"); verifier.VerifyDiagnostics(); - verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS1;NS2"), expectedOutput: "1"); + verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1;NS2"), expectedOutput: "1"); verifier.VerifyDiagnostics(); } [Fact] public void FeatureFlag_Granular_Checksum_01() { - test(TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS"), expectedOutput: null, - // Interceptors.cs(7,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);NS1' to your project. + test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS"), expectedOutput: null, + // Interceptors.cs(7,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);NS1' to your project. // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "eY+urAo7Kg2rsKgGSGjShwIAAABQcm9ncmFtLmNz")] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("$(InterceptorsPreviewNamespaces);NS1").WithLocation(7, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("$(InterceptorsNamespaces);NS1").WithLocation(7, 10)); - test(TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS1.NS2"), expectedOutput: null, - // Interceptors.cs(7,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);NS1' to your project. + test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1.NS2"), expectedOutput: null, + // Interceptors.cs(7,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);NS1' to your project. // [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "eY+urAo7Kg2rsKgGSGjShwIAAABQcm9ncmFtLmNz")] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("$(InterceptorsPreviewNamespaces);NS1").WithLocation(7, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("$(InterceptorsNamespaces);NS1").WithLocation(7, 10)); - test(TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS1"), expectedOutput: "1"); + test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1"), expectedOutput: "1"); - test(TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "NS1;NS2"), expectedOutput: "1"); + test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1;NS2"), expectedOutput: "1"); void test(CSharpParseOptions options, string? expectedOutput, params DiagnosticDescription[] expected) { @@ -237,16 +237,16 @@ class D void sadCase(string featureValue) { - var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", featureValue)); + var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", featureValue)); comp.VerifyEmitDiagnostics( - // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '$(InterceptorsPreviewNamespaces);NS1.NS2' to your project. + // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '$(InterceptorsNamespaces);NS1.NS2' to your project. // [InterceptsLocation("Program.cs", 4, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsPreviewNamespaces);NS1.NS2").WithLocation(15, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsNamespaces);NS1.NS2").WithLocation(15, 10)); } void happyCase(string featureValue) { - var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", featureValue), expectedOutput: "1"); + var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", featureValue), expectedOutput: "1"); verifier.VerifyDiagnostics(); } } @@ -272,7 +272,7 @@ class D } """; - var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "")); + var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "")); comp.VerifyEmitDiagnostics( // Program.cs(13,6): error CS9206: An interceptor cannot be declared in the global namespace. // [InterceptsLocation("Program.cs", 4, 3)] @@ -303,10 +303,10 @@ class D } """; - var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "global"), expectedOutput: "1"); + var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global"), expectedOutput: "1"); verifier.VerifyDiagnostics(); - verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("interceptorspreviewnamespaces", "global"), expectedOutput: "1"); + verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global"), expectedOutput: "1"); verifier.VerifyDiagnostics(); } @@ -334,11 +334,11 @@ class D } """; - var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "global.A")); + var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global.A")); comp.VerifyEmitDiagnostics( - // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);global.B' to your project. + // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);global.B' to your project. // [InterceptsLocation("Program.cs", 4, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsPreviewNamespaces);global.B").WithLocation(15, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("$(InterceptorsNamespaces);global.B").WithLocation(15, 10)); } [Fact] @@ -6302,7 +6302,7 @@ public void M() } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6347,7 +6347,7 @@ static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6358,9 +6358,9 @@ static class D Assert.Null(interceptor); comp.VerifyEmitDiagnostics( - // Interceptor.cs(8,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);NotInterceptors' to your project. + // Interceptor.cs(8,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);NotInterceptors' to your project. // [InterceptsLocation("Program.cs", 1, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsPreviewNamespaces);NotInterceptors").WithLocation(8, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsNamespaces);NotInterceptors").WithLocation(8, 10)); interceptor = model.GetInterceptorMethod(call); Assert.Null(interceptor); @@ -6400,7 +6400,7 @@ public void M() } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6449,7 +6449,7 @@ static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6505,7 +6505,7 @@ static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6515,9 +6515,9 @@ static class D Assert.Equal("void Interceptors.D.Interceptor1()", interceptor.ToTestDisplayString()); comp.VerifyEmitDiagnostics( - // Interceptor.cs(17,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);NotInterceptors' to your project. + // Interceptor.cs(17,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);NotInterceptors' to your project. // [InterceptsLocation("Program.cs", 1, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsPreviewNamespaces);NotInterceptors").WithLocation(17, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsNamespaces);NotInterceptors").WithLocation(17, 10)); interceptor = model.GetInterceptorMethod(call); Assert.Equal("void Interceptors.D.Interceptor1()", interceptor.ToTestDisplayString()); @@ -6553,7 +6553,7 @@ public static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6572,7 +6572,7 @@ public static class D [CombinatorialData] public void GetInterceptorMethod_09(bool featureExists) { - // InterceptorsPreviewNamespaces is empty or does not exist + // InterceptorsNamespaces is empty or does not exist var source = (""" C.M(); @@ -6599,7 +6599,7 @@ public static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: featureExists ? TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "") : TestOptions.Regular); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: featureExists ? TestOptions.Regular.WithFeature("InterceptorsNamespaces", "") : TestOptions.Regular); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6607,16 +6607,16 @@ public static class D Assert.Null(model.GetInterceptorMethod(call)); comp.VerifyEmitDiagnostics( - // Interceptor.cs(10,14): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);Interceptors' to your project. + // Interceptor.cs(10,14): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);Interceptors' to your project. // [InterceptsLocation("Program.cs", 1, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsPreviewNamespaces);Interceptors").WithLocation(10, 14)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsNamespaces);Interceptors").WithLocation(10, 14)); Assert.Null(model.GetInterceptorMethod(call)); } [Fact] public void GetInterceptorMethod_10() { - // InterceptorsPreviewNamespaces has duplicates + // InterceptorsNamespaces has duplicates var source = (""" C.M(); @@ -6643,7 +6643,7 @@ public static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors;Interceptors")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors;Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6671,7 +6671,7 @@ class C } """, "Program.cs"); - var comp = CreateCompilation(new[] { source, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation(new[] { source, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6690,7 +6690,7 @@ class C public void GetInterceptorMethod_12() { // Compilation contains no files - var comp = CreateCompilation([], parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors")); + var comp = CreateCompilation([], parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors")); // We can't use GetInterceptorMethod without a SemanticModel and we can't get a SemanticModel when the compilation contains no trees. // But, we can exercise some internal API for theoretical edge cases to see if it is robust (does not throw, updates expected flags). @@ -6730,7 +6730,7 @@ public static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", @namespace)); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", @namespace)); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6772,7 +6772,7 @@ public static class D } """, "Interceptor.cs"); - var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreviewNamespaces", "Interceptors.Nested")); + var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors.Nested")); var tree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(tree); @@ -6781,9 +6781,9 @@ public static class D Assert.Null(model.GetInterceptorMethod(call)); comp.VerifyEmitDiagnostics( - // Interceptor.cs(8,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsPreviewNamespaces);Interceptors' to your project. + // Interceptor.cs(8,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '$(InterceptorsNamespaces);Interceptors' to your project. // [InterceptsLocation("Program.cs", 1, 3)] - Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsPreviewNamespaces);Interceptors").WithLocation(8, 10)); + Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("$(InterceptorsNamespaces);Interceptors").WithLocation(8, 10)); Assert.Null(model.GetInterceptorMethod(call)); } diff --git a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs index 6a4dacee52380..41a6b4b42a602 100644 --- a/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs +++ b/src/Compilers/CSharp/Test/Semantic/SourceGeneration/GeneratorDriverTests.cs @@ -4108,7 +4108,7 @@ public void GetInterceptsLocationSpecifier_01() { var generator = new IncrementalGeneratorWrapper(new InterceptorGenerator1()); - var parseOptions = TestOptions.RegularPreview.WithFeature("InterceptorsPreviewNamespaces", "global"); + var parseOptions = TestOptions.RegularPreview.WithFeature("InterceptorsNamespaces", "global"); var source1 = (""" public class Program diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs index 3532f3d25bb69..57d82e0f09cfd 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs @@ -65,7 +65,7 @@ public void TestFieldsForEqualsAndGetHashCode() "Features", "Language", "LanguageVersion", - "InterceptorsPreviewNamespaces", + "InterceptorsNamespaces", "PreprocessorSymbolNames", "PreprocessorSymbols", "SpecifiedLanguageVersion"); diff --git a/src/Compilers/Core/MSBuildTask/Csc.cs b/src/Compilers/Core/MSBuildTask/Csc.cs index d4cde85cf8e7a..71e9cfc09f76e 100644 --- a/src/Compilers/Core/MSBuildTask/Csc.cs +++ b/src/Compilers/Core/MSBuildTask/Csc.cs @@ -241,7 +241,7 @@ protected override void AddResponseFileCommands(CommandLineBuilderExtension comm } AddReferencesToCommandLine(commandLine, References); - AddInterceptorsPreviewNamespaces(commandLine, InterceptorsPreviewNamespaces); + AddInterceptorsNamespaces(commandLine, InterceptorsNamespaces, InterceptorsPreviewNamespaces); base.AddResponseFileCommands(commandLine); @@ -280,19 +280,28 @@ protected override void AddResponseFileCommands(CommandLineBuilderExtension comm internal override RequestLanguage Language => RequestLanguage.CSharpCompile; - /// - /// The value of the <InterceptorsPreviewNamespaces> property. - /// - internal static void AddInterceptorsPreviewNamespaces(CommandLineBuilderExtension commandLine, string? interceptorsNamespaces) + internal static void AddInterceptorsNamespaces(CommandLineBuilderExtension commandLine, string? interceptorsNamespaces, string? interceptorsPreviewNamespaces) { - if (string.IsNullOrEmpty(interceptorsNamespaces)) + var interceptorsNamespacesIsNullOrEmpty = string.IsNullOrEmpty(interceptorsNamespaces); + var interceptorsPreviewNamespacesIsNullOrEmpty = string.IsNullOrEmpty(interceptorsPreviewNamespaces); + if (interceptorsNamespacesIsNullOrEmpty && interceptorsPreviewNamespacesIsNullOrEmpty) { return; } - commandLine.AppendSwitchIfNotNull("/features:", $"InterceptorsPreviewNamespaces={interceptorsNamespaces}"); + var featureValue = interceptorsNamespacesIsNullOrEmpty ? interceptorsPreviewNamespaces + : interceptorsPreviewNamespacesIsNullOrEmpty ? interceptorsNamespaces + : $"{interceptorsNamespaces};{interceptorsPreviewNamespaces}"; + commandLine.AppendSwitchIfNotNull("/features:", $"InterceptorsNamespaces={featureValue}"); } + public string? InterceptorsNamespaces + { + set { _store[nameof(InterceptorsNamespaces)] = value; } + get { return (string?)_store[nameof(InterceptorsNamespaces)]; } + } + + /// Alias for . public string? InterceptorsPreviewNamespaces { set { _store[nameof(InterceptorsPreviewNamespaces)] = value; } diff --git a/src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets b/src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets index f2eefe23bec84..ad407778bafb0 100644 --- a/src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets +++ b/src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets @@ -113,6 +113,7 @@ ErrorLog="$(ErrorLog)" ErrorReport="$(ErrorReport)" Features="$(Features)" + InterceptorsNamespaces="$(InterceptorsNamespaces)" InterceptorsPreviewNamespaces="$(InterceptorsPreviewNamespaces)" FileAlignment="$(FileAlignment)" GeneratedFilesOutputPath="$(CompilerGeneratedFilesOutputPath)" diff --git a/src/Compilers/Core/MSBuildTaskTests/CscTests.cs b/src/Compilers/Core/MSBuildTaskTests/CscTests.cs index 7f42e7ac26575..0a434694d8179 100644 --- a/src/Compilers/Core/MSBuildTaskTests/CscTests.cs +++ b/src/Compilers/Core/MSBuildTaskTests/CscTests.cs @@ -213,13 +213,32 @@ public void Features() test(",a,,b,"); } + [Fact] + public void FeaturesInterceptors() + { + var csc = new Csc(); + csc.InterceptorsNamespaces = "NS1.NS2;NS3.NS4"; + csc.Sources = MSBuildUtil.CreateTaskItems("test.cs"); + AssertEx.Equal("""/features:"InterceptorsNamespaces=NS1.NS2;NS3.NS4" /out:test.exe test.cs""", csc.GenerateResponseFileContents()); + } + [Fact] public void FeaturesInterceptorsPreview() { var csc = new Csc(); csc.InterceptorsPreviewNamespaces = "NS1.NS2;NS3.NS4"; csc.Sources = MSBuildUtil.CreateTaskItems("test.cs"); - AssertEx.Equal("""/features:"InterceptorsPreviewNamespaces=NS1.NS2;NS3.NS4" /out:test.exe test.cs""", csc.GenerateResponseFileContents()); + AssertEx.Equal("""/features:"InterceptorsNamespaces=NS1.NS2;NS3.NS4" /out:test.exe test.cs""", csc.GenerateResponseFileContents()); + } + + [Fact] + public void FeaturesInterceptorsPreviewBoth() + { + var csc = new Csc(); + csc.InterceptorsNamespaces = "NS1.NS2;NS3.NS4"; + csc.InterceptorsPreviewNamespaces = "NS5.NS6;NS7.NS8"; + csc.Sources = MSBuildUtil.CreateTaskItems("test.cs"); + AssertEx.Equal("""/features:"InterceptorsNamespaces=NS1.NS2;NS3.NS4;NS5.NS6;NS7.NS8" /out:test.exe test.cs""", csc.GenerateResponseFileContents()); } [Fact]