public async Task TestRedundantEnableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) { await VerifyCodeFixAsync( compilationContext, $$ "" " #nullable {{GetEnableDirectiveContext(codeContext)}} [|#nullable {{GetEnableDirectiveContext(codeContext)}}|]
public static SyntaxTreeState Create(bool defaultCompleted, NullableContextOptions compilationOptions, SyntaxTree tree, CancellationToken cancellationToken) { var root = tree.GetCompilationUnitRoot(cancellationToken); // This analyzer only needs to process syntax trees that contain at least one #nullable directive that // reduces the nullable analysis scope. int?positionOfFirstReducingNullableDirective = null; NullableContextOptions?currentOptions = compilationOptions; for (var directive = root.GetFirstDirective(); directive is not null; directive = directive.GetNextDirective()) { cancellationToken.ThrowIfCancellationRequested(); if (directive.IsKind(SyntaxKind.NullableDirectiveTrivia, out NullableDirectiveTriviaSyntax? nullableDirectiveTrivia)) { var newOptions = CSharpRemoveRedundantNullableDirectiveDiagnosticAnalyzer.GetNullableContextOptions(compilationOptions, currentOptions, nullableDirectiveTrivia); if (IsReducing(currentOptions, newOptions)) { positionOfFirstReducingNullableDirective = directive.SpanStart; break; } currentOptions = newOptions; } } return(new SyntaxTreeState(completed: defaultCompleted || positionOfFirstReducingNullableDirective is null, positionOfFirstReducingNullableDirective)); }
private ProjectData( Guid guid, string name, string assemblyName, string targetPath, string outputPath, string intermediateOutputPath, string projectAssetsFile, string configuration, string platform, FrameworkName targetFramework, ImmutableArray <string> targetFrameworks, OutputKind outputKind, LanguageVersion languageVersion, NullableContextOptions nullableContextOptions, bool allowUnsafeCode, bool checkForOverflowUnderflow, string documentationFile, ImmutableArray <string> preprocessorSymbolNames, ImmutableArray <string> suppressedDiagnosticIds, ImmutableArray <string> warningsAsErrors, ImmutableArray <string> warningsNotAsErrors, bool signAssembly, string assemblyOriginatorKeyFile, bool treatWarningsAsErrors, string defaultNamespace, bool runAnalyzers, bool runAnalyzersDuringLiveAnalysis, RuleSet ruleset) : this() { Guid = guid; Name = name; AssemblyName = assemblyName; TargetPath = targetPath; OutputPath = outputPath; IntermediateOutputPath = intermediateOutputPath; ProjectAssetsFile = projectAssetsFile; Configuration = configuration; Platform = platform; TargetFramework = targetFramework; TargetFrameworks = targetFrameworks.EmptyIfDefault(); OutputKind = outputKind; LanguageVersion = languageVersion; NullableContextOptions = nullableContextOptions; AllowUnsafeCode = allowUnsafeCode; CheckForOverflowUnderflow = checkForOverflowUnderflow; DocumentationFile = documentationFile; PreprocessorSymbolNames = preprocessorSymbolNames.EmptyIfDefault(); SuppressedDiagnosticIds = suppressedDiagnosticIds.EmptyIfDefault(); WarningsAsErrors = warningsAsErrors.EmptyIfDefault(); WarningsNotAsErrors = warningsNotAsErrors.EmptyIfDefault(); SignAssembly = signAssembly; AssemblyOriginatorKeyFile = assemblyOriginatorKeyFile; TreatWarningsAsErrors = treatWarningsAsErrors; RuleSet = ruleset; DefaultNamespace = defaultNamespace; RunAnalyzers = runAnalyzers; RunAnalyzersDuringLiveAnalysis = runAnalyzersDuringLiveAnalysis; }
private static async Task <System.Reflection.TypeInfo> RunSourceGeneratorAsync( string typeName, string testFile, NullableContextOptions nullableContext = NullableContextOptions.Enable, [CallerMemberName] string caller = null ) { var serializer = new SerializerGenerator(); var(producedCompilation, diagnostics) = await SourceGeneratorTestHelper.RunSourceGeneratorAsync(testFile, serializer, nullableContext, caller); Assert.Empty(diagnostics); var outputFile = Path.GetTempFileName(); var res = producedCompilation.Emit(outputFile); Assert.Empty(res.Diagnostics); Assert.True(res.Success); var asm = Assembly.LoadFile(outputFile); var ret = Assert.Single(asm.GetTypes().Where(t => t.FullName == typeName)); return(ret.GetTypeInfo()); }
private ProjectData( Guid guid, string name, string assemblyName, string targetPath, string outputPath, string intermediateOutputPath, string projectAssetsFile, string configuration, string platform, FrameworkName targetFramework, ImmutableArray <string> targetFrameworks, OutputKind outputKind, LanguageVersion languageVersion, NullableContextOptions nullableContextOptions, bool allowUnsafeCode, string documentationFile, ImmutableArray <string> preprocessorSymbolNames, ImmutableArray <string> suppressedDiagnosticIds, bool signAssembly, string assemblyOriginatorKeyFile, ImmutableArray <string> sourceFiles, ImmutableArray <string> projectReferences, ImmutableArray <string> references, ImmutableArray <PackageReference> packageReferences, ImmutableArray <string> analyzers, bool treatWarningsAsErrors, RuleSet ruleset, ImmutableDictionary <string, string> referenceAliases) : this(guid, name, assemblyName, targetPath, outputPath, intermediateOutputPath, projectAssetsFile, configuration, platform, targetFramework, targetFrameworks, outputKind, languageVersion, nullableContextOptions, allowUnsafeCode, documentationFile, preprocessorSymbolNames, suppressedDiagnosticIds, signAssembly, assemblyOriginatorKeyFile, treatWarningsAsErrors, ruleset) { SourceFiles = sourceFiles.EmptyIfDefault(); ProjectReferences = projectReferences.EmptyIfDefault(); References = references.EmptyIfDefault(); PackageReferences = packageReferences.EmptyIfDefault(); Analyzers = analyzers.EmptyIfDefault(); ReferenceAliases = referenceAliases; }
public void VerifyMapPropertyAttribute(NullableContextOptions nullableContextOptions) { // Arrange const string source = ""; var nullableSyntax = nullableContextOptions == NullableContextOptions.Enable ? "?" : string.Empty; var languageVersion = nullableContextOptions == NullableContextOptions.Enable ? LanguageVersion.CSharp8 : LanguageVersion.CSharp7_3; var expectedInterface = $@" {Constants.GeneratedFilesHeader} {(nullableContextOptions == NullableContextOptions.Enable ? $"#nullable enable{Environment.NewLine}" : string.Empty)} using System; namespace MapTo {{ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true)] public sealed class MapPropertyAttribute : Attribute {{ public string{nullableSyntax} SourcePropertyName {{ get; set; }} }} }} ".Trim(); // Act var(compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions, nullableContextOptions: nullableContextOptions, languageVersion: languageVersion); // Assert diagnostics.ShouldBeSuccessful(); compilation.SyntaxTrees.ShouldContainSource(MapPropertyAttributeSource.AttributeName, expectedInterface); }
internal static NullableContextOptions?GetNullableContextOptions(NullableContextOptions compilationOptions, NullableContextOptions?options, NullableDirectiveTriviaSyntax directive) { if (!directive.TargetToken.IsKind(SyntaxKind.None)) { if (options is not { } knownState) { return(null); } NullableContextOptions flagToChange; if (directive.TargetToken.IsKind(SyntaxKind.AnnotationsKeyword)) { flagToChange = NullableContextOptions.Annotations; } else if (directive.TargetToken.IsKind(SyntaxKind.WarningsKeyword)) { flagToChange = NullableContextOptions.Warnings; } else { return(null); } if (directive.SettingToken.IsKind(SyntaxKind.EnableKeyword)) { return(knownState | flagToChange); } else if (directive.SettingToken.IsKind(SyntaxKind.DisableKeyword)) { return(knownState & (~flagToChange)); } else { return(null); } } if (directive.SettingToken.IsKind(SyntaxKind.EnableKeyword)) { return(NullableContextOptions.Annotations | NullableContextOptions.Warnings); } else if (directive.SettingToken.IsKind(SyntaxKind.DisableKeyword)) { return(NullableContextOptions.Disable); } else if (directive.SettingToken.IsKind(SyntaxKind.RestoreKeyword)) { return(compilationOptions); } else { return(null); } }
public CSharpCompilationOptions WithNullableContextOptions(NullableContextOptions options) { if (options == this.NullableContextOptions) { return(this); } return(new CSharpCompilationOptions(this) { NullableContextOptions = options }); }
public CSharpCompilationOptions( OutputKind outputKind, bool reportSuppressedDiagnostics = false, string?moduleName = null, string?mainTypeName = null, string?scriptClassName = null, IEnumerable <string>?usings = null, OptimizationLevel optimizationLevel = OptimizationLevel.Debug, bool checkOverflow = false, bool allowUnsafe = false, string?cryptoKeyContainer = null, string?cryptoKeyFile = null, ImmutableArray <byte> cryptoPublicKey = default, bool?delaySign = null, Platform platform = Platform.AnyCpu, ReportDiagnostic generalDiagnosticOption = ReportDiagnostic.Default, int warningLevel = 4, IEnumerable <KeyValuePair <string, ReportDiagnostic> >?specificDiagnosticOptions = null, bool concurrentBuild = true, bool deterministic = false, XmlReferenceResolver?xmlReferenceResolver = null, SourceReferenceResolver?sourceReferenceResolver = null, MetadataReferenceResolver?metadataReferenceResolver = null, AssemblyIdentityComparer?assemblyIdentityComparer = null, StrongNameProvider?strongNameProvider = null, bool publicSign = false, MetadataImportOptions metadataImportOptions = MetadataImportOptions.Public, NullableContextOptions nullableContextOptions = NullableContextOptions.Disable, decimal warningVersion = 0m) : this(outputKind, reportSuppressedDiagnostics, moduleName, mainTypeName, scriptClassName, usings, optimizationLevel, checkOverflow, allowUnsafe, cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign, platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions, concurrentBuild, deterministic, currentLocalTime : default, debugPlusMode : false, xmlReferenceResolver : xmlReferenceResolver, sourceReferenceResolver : sourceReferenceResolver, metadataReferenceResolver : metadataReferenceResolver, assemblyIdentityComparer : assemblyIdentityComparer, strongNameProvider : strongNameProvider, metadataImportOptions : metadataImportOptions, referencesSupersedeLowerVersions : false, publicSign : publicSign, topLevelBinderFlags : BinderFlags.None, nullableContextOptions : nullableContextOptions, warningVersion : warningVersion) { }
private ProjectData( Guid guid, string name, string assemblyName, string targetPath, string outputPath, string intermediateOutputPath, string projectAssetsFile, string configuration, string platform, string platformTarget, FrameworkName targetFramework, ImmutableArray <string> targetFrameworks, OutputKind outputKind, LanguageVersion languageVersion, NullableContextOptions nullableContextOptions, bool allowUnsafeCode, bool checkForOverflowUnderflow, string documentationFile, ImmutableArray <string> preprocessorSymbolNames, ImmutableArray <string> suppressedDiagnosticIds, ImmutableArray <string> warningsAsErrors, ImmutableArray <string> warningsNotAsErrors, bool signAssembly, string assemblyOriginatorKeyFile, ImmutableArray <string> sourceFiles, ImmutableArray <string> projectReferences, ImmutableArray <string> references, ImmutableArray <PackageReference> packageReferences, ImmutableArray <string> analyzers, ImmutableArray <string> additionalFiles, ImmutableArray <string> analyzerConfigFiles, bool treatWarningsAsErrors, string defaultNamespace, bool runAnalyzers, bool runAnalyzersDuringLiveAnalysis, RuleSet ruleset, ImmutableDictionary <string, string> referenceAliases, ImmutableDictionary <string, string> projectReferenceAliases, ImmutableArray <IMSBuildGlob> fileInclusionGlobs) : this(guid, name, assemblyName, targetPath, outputPath, intermediateOutputPath, projectAssetsFile, configuration, platform, platformTarget, targetFramework, targetFrameworks, outputKind, languageVersion, nullableContextOptions, allowUnsafeCode, checkForOverflowUnderflow, documentationFile, preprocessorSymbolNames, suppressedDiagnosticIds, warningsAsErrors, warningsNotAsErrors, signAssembly, assemblyOriginatorKeyFile, treatWarningsAsErrors, defaultNamespace, runAnalyzers, runAnalyzersDuringLiveAnalysis, ruleset) { SourceFiles = sourceFiles.EmptyIfDefault(); ProjectReferences = projectReferences.EmptyIfDefault(); References = references.EmptyIfDefault(); PackageReferences = packageReferences.EmptyIfDefault(); Analyzers = analyzers.EmptyIfDefault(); AdditionalFiles = additionalFiles.EmptyIfDefault(); AnalyzerConfigFiles = analyzerConfigFiles.EmptyIfDefault(); ReferenceAliases = referenceAliases; ProjectReferenceAliases = projectReferenceAliases; FileInclusionGlobs = fileInclusionGlobs; }
internal CSharpCompilationOptions( OutputKind outputKind, bool reportSuppressedDiagnostics, string?moduleName, string?mainTypeName, string?scriptClassName, IEnumerable <string>?usings, OptimizationLevel optimizationLevel, bool checkOverflow, bool allowUnsafe, string?cryptoKeyContainer, string?cryptoKeyFile, ImmutableArray <byte> cryptoPublicKey, bool?delaySign, Platform platform, ReportDiagnostic generalDiagnosticOption, int warningLevel, IEnumerable <KeyValuePair <string, ReportDiagnostic> >?specificDiagnosticOptions, bool concurrentBuild, bool deterministic, DateTime currentLocalTime, bool debugPlusMode, XmlReferenceResolver?xmlReferenceResolver, SourceReferenceResolver?sourceReferenceResolver, MetadataReferenceResolver?metadataReferenceResolver, AssemblyIdentityComparer?assemblyIdentityComparer, StrongNameProvider?strongNameProvider, MetadataImportOptions metadataImportOptions, bool referencesSupersedeLowerVersions, bool publicSign, BinderFlags topLevelBinderFlags, NullableContextOptions nullableContextOptions, decimal warningVersion = 0m) : base(outputKind, reportSuppressedDiagnostics, moduleName, mainTypeName, scriptClassName, cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign, publicSign, optimizationLevel, checkOverflow, platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions.ToImmutableDictionaryOrEmpty(), concurrentBuild, deterministic, currentLocalTime, debugPlusMode, xmlReferenceResolver, sourceReferenceResolver, metadataReferenceResolver, assemblyIdentityComparer, strongNameProvider, metadataImportOptions, referencesSupersedeLowerVersions) { this.Usings = usings.AsImmutableOrEmpty(); this.AllowUnsafe = allowUnsafe; this.TopLevelBinderFlags = topLevelBinderFlags; this.NullableContextOptions = nullableContextOptions; this.WarningVersion = warningVersion; }
private static CSharpCompilationOptions CreateCSharpCompilationOptions() { string moduleName = null; string mainTypeName = null; string scriptClassName = null; IEnumerable <string> usings = null; OptimizationLevel optimizationLevel = OptimizationLevel.Debug; bool checkOverflow = false; bool allowUnsafe = false; string cryptoKeyContainer = null; string cryptoKeyFile = null; ImmutableArray <byte> cryptoPublicKey = default(ImmutableArray <byte>); bool? delaySign = null; Platform platform = 0; ReportDiagnostic generalDiagnosticOption = 0; int warningLevel = 0; IEnumerable <KeyValuePair <string, ReportDiagnostic> > specificDiagnosticOptions = null; bool concurrentBuild = false; bool deterministic = false; DateTime currentLocalTime = default(DateTime); bool debugPlusMode = false; XmlReferenceResolver xmlReferenceResolver = new XmlFileResolver(null); SourceReferenceResolver sourceReferenceResolver = new SourceFileResolver(ImmutableArray <string> .Empty, null); SyntaxTreeOptionsProvider syntaxTreeOptionsProvider = null; MetadataReferenceResolver metadataReferenceResolver = new MetadataReferenceResolverWithEquality(); AssemblyIdentityComparer assemblyIdentityComparer = AssemblyIdentityComparer.Default; // Currently uses reference equality StrongNameProvider strongNameProvider = new DesktopStrongNameProvider(); MetadataImportOptions metadataImportOptions = 0; bool referencesSupersedeLowerVersions = false; bool reportSuppressedDiagnostics = false; var topLevelBinderFlags = BinderFlags.None; var publicSign = false; NullableContextOptions nullableContextOptions = NullableContextOptions.Disable; return(new CSharpCompilationOptions(OutputKind.ConsoleApplication, reportSuppressedDiagnostics, moduleName, mainTypeName, scriptClassName, usings, optimizationLevel, checkOverflow, allowUnsafe, cryptoKeyContainer, cryptoKeyFile, cryptoPublicKey, delaySign, platform, generalDiagnosticOption, warningLevel, specificDiagnosticOptions, concurrentBuild, deterministic, currentLocalTime, debugPlusMode, xmlReferenceResolver, sourceReferenceResolver, syntaxTreeOptionsProvider, metadataReferenceResolver, assemblyIdentityComparer, strongNameProvider, metadataImportOptions, referencesSupersedeLowerVersions, publicSign, topLevelBinderFlags, nullableContextOptions)); }
public async Task DisabledIfSetInProject(NullableContextOptions nullableContextOptions) { var code = @" #nullable enable$$ "; await new VerifyCS.Test { TestCode = code, FixedCode = code, SolutionTransforms = { (solution, projectId) => { var compilationOptions = (CSharpCompilationOptions)solution.GetRequiredProject(projectId).CompilationOptions !; return(solution.WithProjectCompilationOptions(projectId, compilationOptions.WithNullableContextOptions(nullableContextOptions))); }, }, }.RunAsync();
internal static async Task <(Compilation Compilation, ImmutableArray <Diagnostic> Diagnostic)> RunSourceGeneratorAsync( string testFile, ISourceGenerator generator, NullableContextOptions nullableContext = NullableContextOptions.Enable, [CallerMemberName] string caller = null ) { var compilation = await GetCompilationAsync(testFile, caller, nullableContext); var parseOptions = (CSharpParseOptions)compilation.SyntaxTrees.ElementAt(0).Options; var generators = ImmutableArray.Create(generator); GeneratorDriver driver = CSharpGeneratorDriver.Create(generators, parseOptions: parseOptions); driver.RunGeneratorsAndUpdateCompilation(compilation, out var producedCompilation, out var diagnostics); return(producedCompilation, diagnostics); }
private string GetGeneratedOutput(string source, NullableContextOptions nullableContextOptions) { var syntaxTree = CSharpSyntaxTree.ParseText(source); var references = new List <MetadataReference>(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { if (!assembly.IsDynamic && !string.IsNullOrWhiteSpace(assembly.Location)) { references.Add(MetadataReference.CreateFromFile(assembly.Location)); } } var compilation = CSharpCompilation.Create( "foo", new SyntaxTree[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, nullableContextOptions: nullableContextOptions)); // var compileDiagnostics = compilation.GetDiagnostics(); // Assert.IsFalse(compileDiagnostics.Any(d => d.Severity == DiagnosticSeverity.Error), "Failed: " + compileDiagnostics.FirstOrDefault()?.GetMessage()); ISourceGenerator generator = new Generator(); var driver = CSharpGeneratorDriver.Create(generator); driver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var generateDiagnostics); Assert.IsFalse(generateDiagnostics.Any(d => d.Severity == DiagnosticSeverity.Error), "Failed: " + generateDiagnostics.FirstOrDefault()?.GetMessage()); string output = outputCompilation.SyntaxTrees.Last().ToString(); Console.WriteLine(output); return(output); }
internal static Diagnostic?Filter( Diagnostic d, int warningLevelOption, NullableContextOptions nullableOption, ReportDiagnostic generalDiagnosticOption, IDictionary <string, ReportDiagnostic> specificDiagnosticOptions, SyntaxTreeOptionsProvider?syntaxTreeOptions, CancellationToken cancellationToken) { if (d == null) { return(d); } else if (d.IsNotConfigurable()) { if (d.IsEnabledByDefault) { // Enabled NotConfigurable should always be reported as it is. return(d); } else { // Disabled NotConfigurable should never be reported. return(null); } } else if (d.Severity == InternalDiagnosticSeverity.Void) { return(null); } //In the native compiler, all warnings originating from alink.dll were issued //under the id WRN_ALinkWarn - 1607. If a customer used nowarn:1607 they would get //none of those warnings. In Roslyn, we've given each of these warnings their //own number, so that they may be configured independently. To preserve compatibility //if a user has specifically configured 1607 and we are reporting one of the alink warnings, use //the configuration specified for 1607. As implemented, this could result in customers //specifying warnaserror:1607 and getting a message saying "warning as error CS8012..." //We don't permit configuring 1607 and independently configuring the new warnings. ReportDiagnostic reportAction; bool hasPragmaSuppression; if (s_alinkWarnings.Contains((ErrorCode)d.Code) && specificDiagnosticOptions.Keys.Contains(CSharp.MessageProvider.Instance.GetIdForErrorCode((int)ErrorCode.WRN_ALinkWarn))) { reportAction = GetDiagnosticReport(ErrorFacts.GetSeverity(ErrorCode.WRN_ALinkWarn), d.IsEnabledByDefault, CSharp.MessageProvider.Instance.GetIdForErrorCode((int)ErrorCode.WRN_ALinkWarn), ErrorFacts.GetWarningLevel(ErrorCode.WRN_ALinkWarn), d.Location, d.Category, warningLevelOption, nullableOption, generalDiagnosticOption, specificDiagnosticOptions, syntaxTreeOptions, cancellationToken, out hasPragmaSuppression); } else { reportAction = GetDiagnosticReport(d.Severity, d.IsEnabledByDefault, d.Id, d.WarningLevel, d.Location, d.Category, warningLevelOption, nullableOption, generalDiagnosticOption, specificDiagnosticOptions, syntaxTreeOptions, cancellationToken, out hasPragmaSuppression); } if (hasPragmaSuppression) { d = d.WithIsSuppressed(true); } return(d.WithReportDiagnostic(reportAction)); }
internal static ReportDiagnostic GetDiagnosticReport( DiagnosticSeverity severity, bool isEnabledByDefault, string id, int diagnosticWarningLevel, Location location, string category, int warningLevelOption, NullableContextOptions nullableOption, ReportDiagnostic generalDiagnosticOption, IDictionary <string, ReportDiagnostic> specificDiagnosticOptions, SyntaxTreeOptionsProvider?syntaxTreeOptions, CancellationToken cancellationToken, out bool hasPragmaSuppression) { hasPragmaSuppression = false; Debug.Assert(location.SourceTree is null || location.SourceTree is CSharpSyntaxTree); var tree = location.SourceTree as CSharpSyntaxTree; var position = location.SourceSpan.Start; bool isNullableFlowAnalysisWarning = ErrorFacts.NullableWarnings.Contains(id); if (isNullableFlowAnalysisWarning) { Syntax.NullableContextState.State?warningsState = tree?.GetNullableContextState(position).WarningsState; var nullableWarningsEnabled = warningsState switch { Syntax.NullableContextState.State.Enabled => true, Syntax.NullableContextState.State.Disabled => false, Syntax.NullableContextState.State.ExplicitlyRestored => nullableOption.WarningsEnabled(), Syntax.NullableContextState.State.Unknown => tree?.IsGeneratedCode(syntaxTreeOptions, cancellationToken) != true && nullableOption.WarningsEnabled(), null => nullableOption.WarningsEnabled(), _ => throw ExceptionUtilities.UnexpectedValue(warningsState) }; if (!nullableWarningsEnabled) { return(ReportDiagnostic.Suppress); } } // 1. Warning level if (diagnosticWarningLevel > warningLevelOption) // honor the warning level { return(ReportDiagnostic.Suppress); } ReportDiagnostic report; bool isSpecified = false; if (tree != null && syntaxTreeOptions != null && syntaxTreeOptions.TryGetDiagnosticValue(tree, id, cancellationToken, out report)) { // 2. Syntax tree level isSpecified = true; } else if (specificDiagnosticOptions.TryGetValue(id, out report)) { // 3. Compilation level isSpecified = true; } else { report = isEnabledByDefault ? ReportDiagnostic.Default : ReportDiagnostic.Suppress; } if (report == ReportDiagnostic.Suppress) { return(ReportDiagnostic.Suppress); } // If location.SourceTree is available, check out pragmas var pragmaWarningState = tree?.GetPragmaDirectiveWarningState(id, position) ?? Syntax.PragmaWarningState.Default; if (pragmaWarningState == Syntax.PragmaWarningState.Disabled) { hasPragmaSuppression = true; } // NOTE: this may be removed as part of https://github.com/dotnet/roslyn/issues/36550 if (pragmaWarningState == Syntax.PragmaWarningState.Enabled) { switch (report) { case ReportDiagnostic.Error: case ReportDiagnostic.Hidden: case ReportDiagnostic.Info: case ReportDiagnostic.Warn: // No need to adjust the current report state, it already means "enabled" return(report); case ReportDiagnostic.Suppress: // Enable the warning return(ReportDiagnostic.Default); case ReportDiagnostic.Default: if (generalDiagnosticOption == ReportDiagnostic.Error && promoteToAnError()) { return(ReportDiagnostic.Error); } return(ReportDiagnostic.Default); default: throw ExceptionUtilities.UnexpectedValue(report); } } else if (report == ReportDiagnostic.Suppress) // check options (/nowarn) { return(ReportDiagnostic.Suppress); } // 4. Global options // Unless specific warning options are defined (/warnaserror[+|-]:<n> or /nowarn:<n>, // follow the global option (/warnaserror[+|-] or /nowarn). if (report == ReportDiagnostic.Default) { switch (generalDiagnosticOption) { case ReportDiagnostic.Error: if (promoteToAnError()) { return(ReportDiagnostic.Error); } break; case ReportDiagnostic.Suppress: // When doing suppress-all-warnings, don't lower severity for anything other than warning and info. // We shouldn't suppress hidden diagnostics here because then features that use hidden diagnostics to // display a lightbulb would stop working if someone has suppress-all-warnings (/nowarn) specified in their project. if (severity == DiagnosticSeverity.Warning || severity == DiagnosticSeverity.Info) { report = ReportDiagnostic.Suppress; } break; } } return(report); bool promoteToAnError() { Debug.Assert(report == ReportDiagnostic.Default); Debug.Assert(generalDiagnosticOption == ReportDiagnostic.Error); // If we've been asked to do warn-as-error then don't raise severity for anything below warning (info or hidden). return(severity == DiagnosticSeverity.Warning && // In the case where /warnaserror+ is followed by /warnaserror-:<n> on the command line, // do not promote the warning specified in <n> to an error. !isSpecified); } } }
/// <summary> /// Take a warning and return the final disposition of the given warning, /// based on both command line options and pragmas. The diagnostic options /// have precedence in the following order: /// 1. Warning level /// 2. Syntax tree level /// 3. Compilation level /// 4. Global warning level /// /// Pragmas are considered seperately. If a diagnostic would not otherwise /// be suppressed, but is suppressed by a pragma, <paramref name="hasPragmaSuppression"/> /// is true but the diagnostic is not reported as suppressed. /// </summary> internal static ReportDiagnostic GetDiagnosticReport( DiagnosticSeverity severity, bool isEnabledByDefault, string id, int diagnosticWarningLevel, Location location, string category, int warningLevelOption, NullableContextOptions nullableOption, ReportDiagnostic generalDiagnosticOption, IDictionary <string, ReportDiagnostic> specificDiagnosticOptions, out bool hasPragmaSuppression) { hasPragmaSuppression = false; // 1. Warning level if (diagnosticWarningLevel > warningLevelOption) // honor the warning level { return(ReportDiagnostic.Suppress); } ReportDiagnostic report; SyntaxTree tree = location?.SourceTree; bool isSpecified = false; if (tree != null && tree.DiagnosticOptions.TryGetValue(id, out var treeReport)) { // 2. Syntax tree level report = treeReport; isSpecified = true; } else if (specificDiagnosticOptions.TryGetValue(id, out var specificReport)) { // 3. Compilation level report = specificReport; isSpecified = true; } else { report = isEnabledByDefault ? ReportDiagnostic.Default : ReportDiagnostic.Suppress; } bool isNullableFlowAnalysisWarning = ErrorFacts.NullableFlowAnalysisWarnings.Contains(id); if (report == ReportDiagnostic.Suppress && // check options (/nowarn) !isNullableFlowAnalysisWarning) { return(ReportDiagnostic.Suppress); } // If location.SourceTree is available, check out pragmas var pragmaWarningState = tree?.GetPragmaDirectiveWarningState(id, location.SourceSpan.Start) ?? Syntax.PragmaWarningState.Default; if (pragmaWarningState == Syntax.PragmaWarningState.Disabled) { hasPragmaSuppression = true; } if (pragmaWarningState == Syntax.PragmaWarningState.Enabled) { switch (report) { case ReportDiagnostic.Error: case ReportDiagnostic.Hidden: case ReportDiagnostic.Info: case ReportDiagnostic.Warn: // No need to adjust the current report state, it already means "enabled" return(report); case ReportDiagnostic.Suppress: // Enable the warning return(ReportDiagnostic.Default); case ReportDiagnostic.Default: if (generalDiagnosticOption == ReportDiagnostic.Error && promoteToAnError()) { return(ReportDiagnostic.Error); } return(ReportDiagnostic.Default); default: throw ExceptionUtilities.UnexpectedValue(report); } } else if (report == ReportDiagnostic.Suppress) // check options (/nowarn) { return(ReportDiagnostic.Suppress); } // Nullable flow analysis warnings cannot be turned on by specific diagnostic options. // They can be turned on by nullable options and specific diagnostic options // can either turn them off, or adjust the way they are reported. switch (nullableOption) { case NullableContextOptions.Disable: if (isNullableFlowAnalysisWarning) { return(ReportDiagnostic.Suppress); } break; case NullableContextOptions.Enable: case NullableContextOptions.Warnings: break; default: throw ExceptionUtilities.UnexpectedValue(nullableOption); } // 4. Global options // Unless specific warning options are defined (/warnaserror[+|-]:<n> or /nowarn:<n>, // follow the global option (/warnaserror[+|-] or /nowarn). if (report == ReportDiagnostic.Default) { switch (generalDiagnosticOption) { case ReportDiagnostic.Error: if (promoteToAnError()) { return(ReportDiagnostic.Error); } break; case ReportDiagnostic.Suppress: // When doing suppress-all-warnings, don't lower severity for anything other than warning and info. // We shouldn't suppress hidden diagnostics here because then features that use hidden diagnostics to // display a lightbulb would stop working if someone has suppress-all-warnings (/nowarn) specified in their project. if (severity == DiagnosticSeverity.Warning || severity == DiagnosticSeverity.Info) { report = ReportDiagnostic.Suppress; } break; } } return(report); bool promoteToAnError() { Debug.Assert(report == ReportDiagnostic.Default); Debug.Assert(generalDiagnosticOption == ReportDiagnostic.Error); // If we've been asked to do warn-as-error then don't raise severity for anything below warning (info or hidden). return(severity == DiagnosticSeverity.Warning && // In the case where /warnaserror+ is followed by /warnaserror-:<n> on the command line, // do not promote the warning specified in <n> to an error. !isSpecified); } }
public NatashaCSharpCompilerOptions SetNullableCompile(NullableContextOptions flag) { _nullableCompileOption = flag; return(this); }
public async Task TestUnnecessaryDisableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext) { await VerifyCodeFixAsync( compilationContext, $$ "" "
public static bool AnnotationsEnabled(this NullableContextOptions context) => IsFlagSet(context, NullableContextOptions.Annotations);
public static bool WarningsEnabled(this NullableContextOptions context) => IsFlagSet(context, NullableContextOptions.Warnings);
private static bool IsFlagSet(NullableContextOptions context, NullableContextOptions flag) => (context & flag) == flag;
public void NullableContextExplicitlySpecifiedAndRestoredInFile(string pragma, NullableContextOptions globalContext, NullableContext expectedContext) { var source = $@" {pragma} class C {{ #nullable restore void M() {{}} }}"; var comp = CreateCompilation(source, options: WithNonNullTypes(globalContext)); var syntaxTree = comp.SyntaxTrees[0]; var model = comp.GetSemanticModel(syntaxTree); var classDeclPosition = syntaxTree.GetRoot().DescendantNodes().OfType <ClassDeclarationSyntax>().Single().SpanStart; var methodDeclPosition = syntaxTree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().Single().SpanStart; Assert.Equal(expectedContext, model.GetNullableContext(classDeclPosition)); // The context at the start of the file should always be inherited and match the global context var restoredContext = ((NullableContext)globalContext) | NullableContext.ContextInherited; Assert.Equal(restoredContext, model.GetNullableContext(0)); Assert.Equal(restoredContext, model.GetNullableContext(methodDeclPosition)); }
public static CompileSummary TryCompileCapnp(NullableContextOptions nullableContextOptions, params string[] code) { var options = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Debug, nullableContextOptions: nullableContextOptions); string assemblyRoot = Path.GetDirectoryName(typeof(object).Assembly.Location); string capnpRuntimePath = Path.GetFullPath(Path.Combine( Assembly.GetExecutingAssembly().Location, "..", "..", "..", "..", "..", "Capnp.Net.Runtime", "bin", "Debug", "netcoreapp3.0", "Capnp.Net.Runtime.dll")); var parseOptions = CSharpParseOptions.Default; if (nullableContextOptions == NullableContextOptions.Disable) { parseOptions = parseOptions.WithLanguageVersion(LanguageVersion.CSharp7_1); } var compilation = CSharpCompilation.Create( "CompilationTestAssembly", options: options, references: new MetadataReference[] { MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "mscorlib.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Core.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Diagnostics.Tools.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Runtime.dll")), MetadataReference.CreateFromFile(Path.Combine(assemblyRoot, "System.Private.CoreLib.dll")), MetadataReference.CreateFromFile(capnpRuntimePath) }, syntaxTrees: Array.ConvertAll(code, new Converter <string, SyntaxTree>(c => CSharpSyntaxTree.ParseText(c, parseOptions)))); using (var stream = new MemoryStream()) { var emitResult = compilation.Emit(stream); foreach (var diag in emitResult.Diagnostics) { Console.WriteLine($"{diag}"); } if (!emitResult.Success) { foreach (var c in code) { string path = Path.ChangeExtension(Path.GetTempFileName(), ".capnp.cs"); File.WriteAllText(path, c); Console.WriteLine($"[See {path} for generated code]"); } } if (emitResult.Success) { if (emitResult.Diagnostics.Any(diag => diag.Severity == DiagnosticSeverity.Warning)) { return(CompileSummary.SuccessWithWarnings); } else { return(CompileSummary.Success); } } else { return(CompileSummary.Error); } } }
internal static (Compilation compilation, ImmutableArray <Diagnostic> diagnostics) GetOutputCompilation( string source, bool assertCompilation = false, IDictionary <string, string>?analyzerConfigOptions = null, NullableContextOptions nullableContextOptions = NullableContextOptions.Disable, LanguageVersion languageVersion = LanguageVersion.CSharp7_3) =>
internal static Task <Compilation> GetCompilationAsync( string testFile, string caller, NullableContextOptions nullableContext, bool addCesilReferences = true, IEnumerable <string> doNotAddReferences = null ) { var trustedAssemblies = ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator); var systemAssemblies = trustedAssemblies.Where(p => Path.GetFileName(p).StartsWith("System.")).ToList(); var references = systemAssemblies.Select(s => MetadataReference.CreateFromFile(s)).ToList(); var projectName = $"Cesil.Tests.{nameof(SourceGeneratorTestHelper)}"; var projectId = ProjectId.CreateNewId(projectName); var compilationOptions = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true, nullableContextOptions: nullableContext ); var parseOptions = new CSharpParseOptions(LanguageVersion.CSharp9); var projectInfo = ProjectInfo.Create( projectId, VersionStamp.Create(), projectName, projectName, LanguageNames.CSharp, compilationOptions: compilationOptions, parseOptions: parseOptions ); var workspace = new AdhocWorkspace(); var solution = workspace .CurrentSolution .AddProject(projectInfo); var x = references.Where(r => r.FilePath.Contains("Serialization")).ToList(); foreach (var reference in references) { var path = reference.Display ?? ""; var ix = path.LastIndexOf('\\'); if (ix != -1) { path = path.Substring(ix + 1); } var iy = path.LastIndexOf('.'); if (iy != -1) { path = path.Substring(0, iy); } if (doNotAddReferences?.Contains(path) ?? false) { continue; } solution = solution.AddMetadataReference(projectId, reference); } var csFile = $"{caller}.cs"; var docId = DocumentId.CreateNewId(projectId, csFile); var project = solution.GetProject(projectId); project = project.AddDocument(csFile, testFile).Project; // find the Cesil folder to include code from if (addCesilReferences) { var cesilRef = GetCesilReference(); project = project.AddMetadataReference(cesilRef); } var netstandardRef = GetNetStandard20Reference(); project = project.AddMetadataReference(netstandardRef); return(project.GetCompilationAsync()); }