public async Task TestRedundantEnableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext)
 {
     await VerifyCodeFixAsync(
         compilationContext,
         $$ "" "
         #nullable {{GetEnableDirectiveContext(codeContext)}}
         [|#nullable {{GetEnableDirectiveContext(codeContext)}}|]
Beispiel #2
0
            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));
            }
Beispiel #3
0
            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;
 }
Beispiel #6
0
        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
            });
        }
Beispiel #9
0
 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;
 }
Beispiel #11
0
 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));
        }
Beispiel #13
0
        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);
        }
Beispiel #16
0
        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));
        }
Beispiel #17
0
        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);
 }
Beispiel #20
0
 public async Task TestUnnecessaryDisableDiffersFromCompilation(NullableContextOptions compilationContext, NullableContextOptions codeContext)
 {
     await VerifyCodeFixAsync(
         compilationContext,
         $$ "" "
Beispiel #21
0
 public static bool AnnotationsEnabled(this NullableContextOptions context) =>
 IsFlagSet(context, NullableContextOptions.Annotations);
Beispiel #22
0
 public static bool WarningsEnabled(this NullableContextOptions context) =>
 IsFlagSet(context, NullableContextOptions.Warnings);
Beispiel #23
0
 private static bool IsFlagSet(NullableContextOptions context, NullableContextOptions flag) =>
 (context & flag) == flag;
Beispiel #24
0
        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);
                }
            }
        }
Beispiel #26
0
 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());
        }