diff --git a/src/Compilers/Core/CommandLine/BuildProtocol.cs b/src/Compilers/Core/CommandLine/BuildProtocol.cs index b5124350822e7..49386016f5538 100644 --- a/src/Compilers/Core/CommandLine/BuildProtocol.cs +++ b/src/Compilers/Core/CommandLine/BuildProtocol.cs @@ -60,12 +60,21 @@ public BuildRequest(uint protocolVersion, } } +#if USES_ANNOTATIONS + public static BuildRequest Create(RequestLanguage language, + string workingDirectory, + string tempDirectory, + IList args, + string? keepAlive = null, + string? libDirectory = null) +#else public static BuildRequest Create(RequestLanguage language, string workingDirectory, string tempDirectory, IList args, string keepAlive = null, string libDirectory = null) +#endif { Log("Creating BuildRequest"); Log($"Working directory: {workingDirectory}"); @@ -110,7 +119,11 @@ public static BuildRequest CreateShutdown() /// The total request size must be less than 1MB. /// /// null if the Request was too large, the Request otherwise. +#if USES_ANNOTATIONS + public static async Task ReadAsync(Stream inStream, CancellationToken cancellationToken) +#else public static async Task ReadAsync(Stream inStream, CancellationToken cancellationToken) +#endif { // Read the length of the request var lengthBuffer = new byte[4]; diff --git a/src/Compilers/Core/CommandLine/CompilerServerLogger.cs b/src/Compilers/Core/CommandLine/CompilerServerLogger.cs index faf9adcccb7db..55ddcaaf5a803 100644 --- a/src/Compilers/Core/CommandLine/CompilerServerLogger.cs +++ b/src/Compilers/Core/CommandLine/CompilerServerLogger.cs @@ -24,7 +24,11 @@ internal class CompilerServerLogger // Environment variable, if set, to enable logging and set the file to log to. private const string environmentVariable = "RoslynCommandLineLogFile"; +#if USES_ANNOTATIONS + private static readonly Stream? s_loggingStream; +#else private static readonly Stream s_loggingStream; +#endif private static string s_prefix = "---"; /// @@ -115,9 +119,17 @@ public static void Log(string message) // Because multiple processes might be logging to the same file, we always seek to the end, // write, and flush. +#if USES_ANNOTATIONS + // PROTOTYPE(NullableDogfood): There should be no warning on de-referencing s_loggingStream since checked above + // https://github.com/dotnet/roslyn/issues/26651 + s_loggingStream!.Seek(0, SeekOrigin.End); + s_loggingStream!.Write(bytes, 0, bytes.Length); + s_loggingStream!.Flush(); +#else s_loggingStream.Seek(0, SeekOrigin.End); s_loggingStream.Write(bytes, 0, bytes.Length); s_loggingStream.Flush(); +#endif } } diff --git a/src/Compilers/Core/CommandLine/NativeMethods.cs b/src/Compilers/Core/CommandLine/NativeMethods.cs index 19e5e852fc92e..d4ff1b381bac2 100644 --- a/src/Compilers/Core/CommandLine/NativeMethods.cs +++ b/src/Compilers/Core/CommandLine/NativeMethods.cs @@ -69,7 +69,11 @@ internal static class NativeMethods [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool CreateProcess ( +#if USES_ANNOTATIONS + string? lpApplicationName, +#else string lpApplicationName, +#endif [In, Out]StringBuilder lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, diff --git a/src/Compilers/Core/MSBuildTask/AssemblyResolution.cs b/src/Compilers/Core/MSBuildTask/AssemblyResolution.cs index 3ba10248e1990..8230dd855c398 100644 --- a/src/Compilers/Core/MSBuildTask/AssemblyResolution.cs +++ b/src/Compilers/Core/MSBuildTask/AssemblyResolution.cs @@ -27,7 +27,7 @@ public static void Install() // empty, just to trigger static ctor } - internal static Assembly ResolveAssembly(string assemblyDisplayName, Assembly requestingAssemblyOpt) + internal static Assembly? ResolveAssembly(string assemblyDisplayName, Assembly? requestingAssemblyOpt) { var name = new AssemblyName(assemblyDisplayName); try @@ -115,8 +115,8 @@ private static bool TryRedirect(AssemblyName name, byte[] token, int major, int return false; } - private static readonly string s_assemblyLocation = Utilities.TryGetAssemblyPath(typeof(AssemblyResolution).GetTypeInfo().Assembly); - private static Assembly TryRedirectToRuntimesDir(AssemblyName name) + private static readonly string? s_assemblyLocation = Utilities.TryGetAssemblyPath(typeof(AssemblyResolution).GetTypeInfo().Assembly); + private static Assembly? TryRedirectToRuntimesDir(AssemblyName name) { CompilerServerLogger.Log($"Loading with redirect {name.Name}"); if (s_assemblyLocation == null) diff --git a/src/Compilers/Core/MSBuildTask/CanonicalError.cs b/src/Compilers/Core/MSBuildTask/CanonicalError.cs index 9d49c538ac3ca..b5be8116e7ae2 100644 --- a/src/Compilers/Core/MSBuildTask/CanonicalError.cs +++ b/src/Compilers/Core/MSBuildTask/CanonicalError.cs @@ -173,7 +173,7 @@ internal Parts() /// /// Name of the file or tool (not localized) /// - internal string origin; + internal string? origin; /// /// The line number. @@ -203,17 +203,17 @@ internal Parts() /// /// The sub category (localized) /// - internal string subcategory; + internal string? subcategory; /// /// The error code (not localized) /// - internal string code; + internal string? code; /// /// The error message text (localized) /// - internal string text; + internal string? text; #if NEVER internal new string ToString() @@ -263,7 +263,7 @@ private static int ConvertToIntWithDefault(string value) /// JomoF /// /// Decomposed canonical message, or null. - internal static Parts Parse(string message) + internal static Parts? Parse(string message) { // An unusually long string causes pathologically slow Regex back-tracking. // To avoid that, only scan the first 400 characters. That's enough for diff --git a/src/Compilers/Core/MSBuildTask/CommandLineBuilderExtension.cs b/src/Compilers/Core/MSBuildTask/CommandLineBuilderExtension.cs index 5023505ef26a3..641c66b0ff298 100644 --- a/src/Compilers/Core/MSBuildTask/CommandLineBuilderExtension.cs +++ b/src/Compilers/Core/MSBuildTask/CommandLineBuilderExtension.cs @@ -24,7 +24,7 @@ internal void AppendWhenTrue string parameterName ) { - object obj = bag[parameterName]; + object? obj = bag[parameterName]; // If the switch isn't set, don't add it to the command line. if (obj != null) { @@ -47,7 +47,7 @@ internal void AppendPlusOrMinusSwitch string parameterName ) { - object obj = bag[parameterName]; + object? obj = bag[parameterName]; // If the switch isn't set, don't add it to the command line. if (obj != null) { @@ -70,7 +70,7 @@ internal void AppendByChoiceSwitch string choice2 ) { - object obj = bag[parameterName]; + object? obj = bag[parameterName]; // If the switch isn't set, don't add it to the command line. if (obj != null) { @@ -89,7 +89,7 @@ internal void AppendSwitchWithInteger string parameterName ) { - object obj = bag[parameterName]; + object? obj = bag[parameterName]; // If the switch isn't set, don't add it to the command line. if (obj != null) { @@ -140,7 +140,7 @@ protected string GetQuotedText(string unquotedText) internal void AppendSwitchIfNotNull ( string switchName, - ITaskItem[] parameters, + ITaskItem[]? parameters, string[] attributes ) { @@ -151,7 +151,7 @@ string[] attributes /// Append a switch if 'parameter' is not null. /// Split on the characters provided. /// - internal void AppendSwitchWithSplitting(string switchName, string parameter, string delimiter, params char[] splitOn) + internal void AppendSwitchWithSplitting(string switchName, string? parameter, string delimiter, params char[] splitOn) { if (parameter != null) { @@ -170,7 +170,7 @@ internal void AppendSwitchWithSplitting(string switchName, string parameter, str /// even if it contains the separators and white space only /// Split on the characters provided. /// - internal static bool IsParameterEmpty(string parameter, params char[] splitOn) + internal static bool IsParameterEmpty(string? parameter, params char[] splitOn) { if (parameter != null) { @@ -197,9 +197,9 @@ internal static bool IsParameterEmpty(string parameter, params char[] splitOn) internal void AppendSwitchIfNotNull ( string switchName, - ITaskItem[] parameters, + ITaskItem[]? parameters, string[] metadataNames, - bool[] treatAsFlags // May be null. In this case no metadata are treated as flags. + bool[]? treatAsFlags // May be null. In this case no metadata are treated as flags. ) { Debug.Assert(treatAsFlags == null diff --git a/src/Compilers/Core/MSBuildTask/CopyRefAssembly.cs b/src/Compilers/Core/MSBuildTask/CopyRefAssembly.cs index 13d8eef059494..add60f764853e 100644 --- a/src/Compilers/Core/MSBuildTask/CopyRefAssembly.cs +++ b/src/Compilers/Core/MSBuildTask/CopyRefAssembly.cs @@ -28,6 +28,8 @@ static CopyRefAssembly() public CopyRefAssembly() { TaskResources = ErrorString.ResourceManager; + SourcePath = null!; // PROTOTYPE(NullableDogfood): MSBuild required + DestinationPath = null!; // PROTOTYPE(NullableDogfood): MSBuild required } public override bool Execute() diff --git a/src/Compilers/Core/MSBuildTask/Csc.cs b/src/Compilers/Core/MSBuildTask/Csc.cs index f5d54196a15f9..e4fe948b7140b 100644 --- a/src/Compilers/Core/MSBuildTask/Csc.cs +++ b/src/Compilers/Core/MSBuildTask/Csc.cs @@ -34,16 +34,16 @@ public bool AllowUnsafeBlocks get { return _store.GetOrDefault(nameof(AllowUnsafeBlocks), false); } } - public string ApplicationConfiguration + public string? ApplicationConfiguration { set { _store[nameof(ApplicationConfiguration)] = value; } - get { return (string)_store[nameof(ApplicationConfiguration)]; } + get { return (string?)_store[nameof(ApplicationConfiguration)]; } } - public string BaseAddress + public string? BaseAddress { set { _store[nameof(BaseAddress)] = value; } - get { return (string)_store[nameof(BaseAddress)]; } + get { return (string?)_store[nameof(BaseAddress)]; } } public bool CheckForOverflowUnderflow @@ -52,16 +52,16 @@ public bool CheckForOverflowUnderflow get { return _store.GetOrDefault(nameof(CheckForOverflowUnderflow), false); } } - public string DocumentationFile + public string? DocumentationFile { set { _store[nameof(DocumentationFile)] = value; } - get { return (string)_store[nameof(DocumentationFile)]; } + get { return (string?)_store[nameof(DocumentationFile)]; } } - public string DisabledWarnings + public string? DisabledWarnings { set { _store[nameof(DisabledWarnings)] = value; } - get { return (string)_store[nameof(DisabledWarnings)]; } + get { return (string?)_store[nameof(DisabledWarnings)]; } } public bool ErrorEndLocation @@ -70,10 +70,10 @@ public bool ErrorEndLocation get { return _store.GetOrDefault(nameof(ErrorEndLocation), false); } } - public string ErrorReport + public string? ErrorReport { set { _store[nameof(ErrorReport)] = value; } - get { return (string)_store[nameof(ErrorReport)]; } + get { return (string?)_store[nameof(ErrorReport)]; } } public bool GenerateFullPaths @@ -82,10 +82,10 @@ public bool GenerateFullPaths get { return _store.GetOrDefault(nameof(GenerateFullPaths), false); } } - public string ModuleAssemblyName + public string? ModuleAssemblyName { set { _store[nameof(ModuleAssemblyName)] = value; } - get { return (string)_store[nameof(ModuleAssemblyName)]; } + get { return (string?)_store[nameof(ModuleAssemblyName)]; } } public bool NoStandardLib @@ -94,10 +94,10 @@ public bool NoStandardLib get { return _store.GetOrDefault(nameof(NoStandardLib), false); } } - public string PdbFile + public string? PdbFile { set { _store[nameof(PdbFile)] = value; } - get { return (string)_store[nameof(PdbFile)]; } + get { return (string?)_store[nameof(PdbFile)]; } } /// @@ -107,16 +107,16 @@ public string PdbFile /// If set to null, "/preferreduilang" option is omitted, and csc.exe uses its default setting. /// Otherwise, the value is passed to "/preferreduilang" as is. /// - public string PreferredUILang + public string? PreferredUILang { set { _store[nameof(PreferredUILang)] = value; } - get { return (string)_store[nameof(PreferredUILang)]; } + get { return (string?)_store[nameof(PreferredUILang)]; } } - public string VsSessionGuid + public string? VsSessionGuid { set { _store[nameof(VsSessionGuid)] = value; } - get { return (string)_store[nameof(VsSessionGuid)]; } + get { return (string?)_store[nameof(VsSessionGuid)]; } } public bool UseHostCompilerIfAvailable @@ -131,16 +131,16 @@ public int WarningLevel get { return _store.GetOrDefault(nameof(WarningLevel), 4); } } - public string WarningsAsErrors + public string? WarningsAsErrors { set { _store[nameof(WarningsAsErrors)] = value; } - get { return (string)_store[nameof(WarningsAsErrors)]; } + get { return (string?)_store[nameof(WarningsAsErrors)]; } } - public string WarningsNotAsErrors + public string? WarningsNotAsErrors { set { _store[nameof(WarningsNotAsErrors)] = value; } - get { return (string)_store[nameof(WarningsNotAsErrors)]; } + get { return (string?)_store[nameof(WarningsNotAsErrors)]; } } #endregion @@ -270,7 +270,7 @@ protected internal override void AddResponseFileCommands(CommandLineBuilderExten /// internal static void AddReferencesToCommandLine( CommandLineBuilderExtension commandLine, - ITaskItem[] references, + ITaskItem[]? references, bool isInteractive = false) { // If there were no references passed in, don't add any /reference: switches @@ -371,7 +371,7 @@ internal static void AddReferencesToCommandLine( /// other words, a constant is either defined or not defined ... it can't have /// an actual value. /// - internal static string GetDefineConstantsSwitch(string originalDefineConstants, TaskLoggingHelper log) + internal static string? GetDefineConstantsSwitch(string? originalDefineConstants, TaskLoggingHelper log) { if (originalDefineConstants == null) { @@ -453,7 +453,7 @@ private bool InitializeHostCompiler(ICscHostObject cscHostObject) CheckHostObjectSupport(param = nameof(Sources), cscHostObject.SetSources(Sources)); // For host objects which support it, pass the list of analyzers. - IAnalyzerHostObject analyzerHostObject = cscHostObject as IAnalyzerHostObject; + IAnalyzerHostObject? analyzerHostObject = cscHostObject as IAnalyzerHostObject; if (analyzerHostObject != null) { CheckHostObjectSupport(param = nameof(Analyzers), analyzerHostObject.SetAnalyzers(Analyzers)); @@ -501,7 +501,7 @@ private bool InitializeHostCompiler(ICscHostObject cscHostObject) CheckHostObjectSupport(param = nameof(PdbFile), cscHostObject.SetPdbFile(PdbFile)); // For host objects which support it, set platform with 32BitPreference, HighEntropyVA, and SubsystemVersion - ICscHostObject4 cscHostObject4 = cscHostObject as ICscHostObject4; + ICscHostObject4? cscHostObject4 = cscHostObject as ICscHostObject4; if (cscHostObject4 != null) { CheckHostObjectSupport(param = nameof(PlatformWith32BitPreference), cscHostObject4.SetPlatformWith32BitPreference(PlatformWith32BitPreference)); @@ -514,17 +514,18 @@ private bool InitializeHostCompiler(ICscHostObject cscHostObject) } // For host objects which support it, set the analyzer ruleset and additional files. - IAnalyzerHostObject analyzerHostObject = cscHostObject as IAnalyzerHostObject; + IAnalyzerHostObject? analyzerHostObject = cscHostObject as IAnalyzerHostObject; if (analyzerHostObject != null) { CheckHostObjectSupport(param = nameof(CodeAnalysisRuleSet), analyzerHostObject.SetRuleSet(CodeAnalysisRuleSet)); CheckHostObjectSupport(param = nameof(AdditionalFiles), analyzerHostObject.SetAdditionalFiles(AdditionalFiles)); } - ICscHostObject5 cscHostObject5 = cscHostObject as ICscHostObject5; + ICscHostObject5? cscHostObject5 = cscHostObject as ICscHostObject5; if (cscHostObject5 != null) { - CheckHostObjectSupport(param = nameof(ErrorLog), cscHostObject5.SetErrorLog(ErrorLog)); + // PROTOTYPE(NullableDogfood): Not sure about SetErrorLog API + CheckHostObjectSupport(param = nameof(ErrorLog), cscHostObject5.SetErrorLog(ErrorLog!)); CheckHostObjectSupport(param = nameof(ReportAnalyzer), cscHostObject5.SetReportAnalyzer(ReportAnalyzer)); } @@ -556,8 +557,9 @@ private bool InitializeHostCompiler(ICscHostObject cscHostObject) } } + // PROTOTYPE(NullableDogfood): Why does flow analysis think cscHostObject might be null here?! // This must come after Win32Manifest - CheckHostObjectSupport(param = nameof(Win32Resource), cscHostObject.SetWin32Resource(Win32Resource)); + CheckHostObjectSupport(param = nameof(Win32Resource), cscHostObject!.SetWin32Resource(Win32Resource)); if (cscHostObject is ICscHostObject3) { @@ -722,8 +724,7 @@ protected override bool CallHostObjectToExecute() { Debug.Assert(HostObject != null, "We should not be here if the host object has not been set."); - ICscHostObject cscHostObject = HostObject as ICscHostObject; - Debug.Assert(cscHostObject != null, "Wrong kind of host object passed in!"); + var cscHostObject = (ICscHostObject)HostObject; return cscHostObject.Compile(); } } diff --git a/src/Compilers/Core/MSBuildTask/InteractiveCompiler.cs b/src/Compilers/Core/MSBuildTask/InteractiveCompiler.cs index bafcd66621a91..c56f5f95d5d38 100644 --- a/src/Compilers/Core/MSBuildTask/InteractiveCompiler.cs +++ b/src/Compilers/Core/MSBuildTask/InteractiveCompiler.cs @@ -22,7 +22,7 @@ public InteractiveCompiler() } #region Properties - Please keep these alphabetized. - public string[] AdditionalLibPaths + public string[]? AdditionalLibPaths { set { @@ -31,11 +31,11 @@ public string[] AdditionalLibPaths get { - return (string[])_store[nameof(AdditionalLibPaths)]; + return (string[]?)_store[nameof(AdditionalLibPaths)]; } } - public string[] AdditionalLoadPaths + public string[]? AdditionalLoadPaths { set { @@ -44,12 +44,12 @@ public string[] AdditionalLoadPaths get { - return (string[])_store[nameof(AdditionalLoadPaths)]; + return (string[]?)_store[nameof(AdditionalLoadPaths)]; } } [Output] - public ITaskItem[] CommandLineArgs + public ITaskItem[]? CommandLineArgs { set { @@ -58,11 +58,11 @@ public ITaskItem[] CommandLineArgs get { - return (ITaskItem[])_store[nameof(CommandLineArgs)]; + return (ITaskItem[]?)_store[nameof(CommandLineArgs)]; } } - public string Features + public string? Features { set { @@ -71,11 +71,11 @@ public string Features get { - return (string)_store[nameof(Features)]; + return (string?)_store[nameof(Features)]; } } - public ITaskItem[] Imports + public ITaskItem[]? Imports { set { @@ -84,7 +84,7 @@ public ITaskItem[] Imports get { - return (ITaskItem[])_store[nameof(Imports)]; + return (ITaskItem[]?)_store[nameof(Imports)]; } } @@ -101,7 +101,7 @@ public bool ProvideCommandLineArgs } } - public ITaskItem[] References + public ITaskItem[]? References { set { @@ -110,11 +110,11 @@ public ITaskItem[] References get { - return (ITaskItem[])_store[nameof(References)]; + return (ITaskItem[]?)_store[nameof(References)]; } } - public ITaskItem[] ResponseFiles + public ITaskItem[]? ResponseFiles { set { @@ -123,11 +123,11 @@ public ITaskItem[] ResponseFiles get { - return (ITaskItem[])_store[nameof(ResponseFiles)]; + return (ITaskItem[]?)_store[nameof(ResponseFiles)]; } } - public string[] ScriptArguments + public string[]? ScriptArguments { set { @@ -136,11 +136,11 @@ public string[] ScriptArguments get { - return (string[])_store[nameof(ScriptArguments)]; + return (string[]?)_store[nameof(ScriptArguments)]; } } - public ITaskItem[] ScriptResponseFiles + public ITaskItem[]? ScriptResponseFiles { set { @@ -149,7 +149,7 @@ public ITaskItem[] ScriptResponseFiles get { - return (ITaskItem[])_store[nameof(ScriptResponseFiles)]; + return (ITaskItem[]?)_store[nameof(ScriptResponseFiles)]; } } @@ -166,7 +166,7 @@ public bool SkipInteractiveExecution } } - public ITaskItem Source + public ITaskItem? Source { set { @@ -175,7 +175,7 @@ public ITaskItem Source get { - return (ITaskItem)_store[nameof(Source)]; + return (ITaskItem?)_store[nameof(Source)]; } } #endregion @@ -187,7 +187,8 @@ public ITaskItem Source protected sealed override bool IsManagedTool => !HasToolBeenOverridden; - protected sealed override string PathToManagedTool => Utilities.GenerateFullPathToTool(ToolName); + // PROTOTYPE(NullableDogfood): Need to follow-up, possible compiler bug + protected sealed override string PathToManagedTool => Utilities.GenerateFullPathToTool(ToolName)!; protected sealed override string PathToNativeTool => Path.Combine(ToolPath ?? "", ToolExe); diff --git a/src/Compilers/Core/MSBuildTask/MSBuildTask.csproj b/src/Compilers/Core/MSBuildTask/MSBuildTask.csproj index 552a064b228dc..11f13677e46ee 100644 --- a/src/Compilers/Core/MSBuildTask/MSBuildTask.csproj +++ b/src/Compilers/Core/MSBuildTask/MSBuildTask.csproj @@ -12,6 +12,8 @@ $(RoslynPortableTargetFrameworks46) $(NoWarn);CA1819 + 8.0 + $(DefineConstants);USES_ANNOTATIONS @@ -55,6 +57,7 @@ UnicodeCharacterUtilities.cs + True True @@ -77,4 +80,4 @@ - \ No newline at end of file + diff --git a/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs b/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs index 225cfad7a929b..c0a55a9bf369b 100644 --- a/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs +++ b/src/Compilers/Core/MSBuildTask/ManagedCompiler.cs @@ -13,6 +13,9 @@ using Roslyn.Utilities; using Microsoft.CodeAnalysis.CommandLine; +// PROTOTYPE(NullableDogfood): Where should we place this? +[module: System.Runtime.CompilerServices.NonNullTypes(true)] + namespace Microsoft.CodeAnalysis.BuildTasks { /// @@ -21,7 +24,7 @@ namespace Microsoft.CodeAnalysis.BuildTasks /// public abstract class ManagedCompiler : ManagedToolTask { - private CancellationTokenSource _sharedCompileCts; + private CancellationTokenSource? _sharedCompileCts; internal readonly PropertyDictionary _store = new PropertyDictionary(); internal abstract RequestLanguage Language { get; } @@ -39,28 +42,28 @@ public ManagedCompiler() #region Properties // Please keep these alphabetized. - public string[] AdditionalLibPaths + public string[]? AdditionalLibPaths { set { _store[nameof(AdditionalLibPaths)] = value; } - get { return (string[])_store[nameof(AdditionalLibPaths)]; } + get { return (string[]?)_store[nameof(AdditionalLibPaths)]; } } - public string[] AddModules + public string[]? AddModules { set { _store[nameof(AddModules)] = value; } - get { return (string[])_store[nameof(AddModules)]; } + get { return (string[]?)_store[nameof(AddModules)]; } } - public ITaskItem[] AdditionalFiles + public ITaskItem[]? AdditionalFiles { set { _store[nameof(AdditionalFiles)] = value; } - get { return (ITaskItem[])_store[nameof(AdditionalFiles)]; } + get { return (ITaskItem[]?)_store[nameof(AdditionalFiles)]; } } - public ITaskItem[] EmbeddedFiles + public ITaskItem[]? EmbeddedFiles { set { _store[nameof(EmbeddedFiles)] = value; } - get { return (ITaskItem[])_store[nameof(EmbeddedFiles)]; } + get { return (ITaskItem[]?)_store[nameof(EmbeddedFiles)]; } } public bool EmbedAllSources @@ -69,25 +72,25 @@ public bool EmbedAllSources get { return _store.GetOrDefault(nameof(EmbedAllSources), false); } } - public ITaskItem[] Analyzers + public ITaskItem[]? Analyzers { set { _store[nameof(Analyzers)] = value; } - get { return (ITaskItem[])_store[nameof(Analyzers)]; } + get { return (ITaskItem[]?)_store[nameof(Analyzers)]; } } // We do not support BugReport because it always requires user interaction, // which will cause a hang. - public string ChecksumAlgorithm + public string? ChecksumAlgorithm { set { _store[nameof(ChecksumAlgorithm)] = value; } - get { return (string)_store[nameof(ChecksumAlgorithm)]; } + get { return (string?)_store[nameof(ChecksumAlgorithm)]; } } - public string CodeAnalysisRuleSet + public string? CodeAnalysisRuleSet { set { _store[nameof(CodeAnalysisRuleSet)] = value; } - get { return (string)_store[nameof(CodeAnalysisRuleSet)]; } + get { return (string?)_store[nameof(CodeAnalysisRuleSet)]; } } public int CodePage @@ -97,28 +100,28 @@ public int CodePage } [Output] - public ITaskItem[] CommandLineArgs + public ITaskItem[]? CommandLineArgs { set { _store[nameof(CommandLineArgs)] = value; } - get { return (ITaskItem[])_store[nameof(CommandLineArgs)]; } + get { return (ITaskItem[]?)_store[nameof(CommandLineArgs)]; } } - public string DebugType + public string? DebugType { set { _store[nameof(DebugType)] = value; } - get { return (string)_store[nameof(DebugType)]; } + get { return (string?)_store[nameof(DebugType)]; } } - public string SourceLink + public string? SourceLink { set { _store[nameof(SourceLink)] = value; } - get { return (string)_store[nameof(SourceLink)]; } + get { return (string?)_store[nameof(SourceLink)]; } } - public string DefineConstants + public string? DefineConstants { set { _store[nameof(DefineConstants)] = value; } - get { return (string)_store[nameof(DefineConstants)]; } + get { return (string?)_store[nameof(DefineConstants)]; } } public bool DelaySign @@ -145,16 +148,16 @@ public bool EmitDebugInformation get { return _store.GetOrDefault(nameof(EmitDebugInformation), false); } } - public string ErrorLog + public string? ErrorLog { set { _store[nameof(ErrorLog)] = value; } - get { return (string)_store[nameof(ErrorLog)]; } + get { return (string?)_store[nameof(ErrorLog)]; } } - public string Features + public string? Features { set { _store[nameof(Features)] = value; } - get { return (string)_store[nameof(Features)]; } + get { return (string?)_store[nameof(Features)]; } } public int FileAlignment @@ -172,34 +175,34 @@ public bool HighEntropyVA /// /// Specifies the list of instrumentation kinds to be used during compilation. /// - public string Instrument + public string? Instrument { set { _store[nameof(Instrument)] = value; } - get { return (string)_store[nameof(Instrument)]; } + get { return (string?)_store[nameof(Instrument)]; } } - public string KeyContainer + public string? KeyContainer { set { _store[nameof(KeyContainer)] = value; } - get { return (string)_store[nameof(KeyContainer)]; } + get { return (string?)_store[nameof(KeyContainer)]; } } - public string KeyFile + public string? KeyFile { set { _store[nameof(KeyFile)] = value; } - get { return (string)_store[nameof(KeyFile)]; } + get { return (string?)_store[nameof(KeyFile)]; } } - public ITaskItem[] LinkResources + public ITaskItem[]? LinkResources { set { _store[nameof(LinkResources)] = value; } - get { return (ITaskItem[])_store[nameof(LinkResources)]; } + get { return (ITaskItem[]?)_store[nameof(LinkResources)]; } } - public string MainEntryPoint + public string? MainEntryPoint { set { _store[nameof(MainEntryPoint)] = value; } - get { return (string)_store[nameof(MainEntryPoint)]; } + get { return (string?)_store[nameof(MainEntryPoint)]; } } public bool NoConfig @@ -227,23 +230,23 @@ public bool Optimize } [Output] - public ITaskItem OutputAssembly + public ITaskItem? OutputAssembly { set { _store[nameof(OutputAssembly)] = value; } - get { return (ITaskItem)_store[nameof(OutputAssembly)]; } + get { return (ITaskItem?)_store[nameof(OutputAssembly)]; } } [Output] - public ITaskItem OutputRefAssembly + public ITaskItem? OutputRefAssembly { set { _store[nameof(OutputRefAssembly)] = value; } - get { return (ITaskItem)_store[nameof(OutputRefAssembly)]; } + get { return (ITaskItem?)_store[nameof(OutputRefAssembly)]; } } - public string Platform + public string? Platform { set { _store[nameof(Platform)] = value; } - get { return (string)_store[nameof(Platform)]; } + get { return (string?)_store[nameof(Platform)]; } } public bool Prefer32Bit @@ -258,10 +261,10 @@ public bool ProvideCommandLineArgs get { return _store.GetOrDefault(nameof(ProvideCommandLineArgs), false); } } - public ITaskItem[] References + public ITaskItem[]? References { set { _store[nameof(References)] = value; } - get { return (ITaskItem[])_store[nameof(References)]; } + get { return (ITaskItem[]?)_store[nameof(References)]; } } public bool RefOnly @@ -276,28 +279,28 @@ public bool ReportAnalyzer get { return _store.GetOrDefault(nameof(ReportAnalyzer), false); } } - public ITaskItem[] Resources + public ITaskItem[]? Resources { set { _store[nameof(Resources)] = value; } - get { return (ITaskItem[])_store[nameof(Resources)]; } + get { return (ITaskItem[]?)_store[nameof(Resources)]; } } - public string RuntimeMetadataVersion + public string? RuntimeMetadataVersion { set { _store[nameof(RuntimeMetadataVersion)] = value; } - get { return (string)_store[nameof(RuntimeMetadataVersion)]; } + get { return (string?)_store[nameof(RuntimeMetadataVersion)]; } } - public ITaskItem[] ResponseFiles + public ITaskItem[]? ResponseFiles { set { _store[nameof(ResponseFiles)] = value; } - get { return (ITaskItem[])_store[nameof(ResponseFiles)]; } + get { return (ITaskItem[])_store[nameof(ResponseFiles)]!; } } - public string SharedCompilationId + public string? SharedCompilationId { set { _store[nameof(SharedCompilationId)] = value; } - get { return (string)_store[nameof(SharedCompilationId)]; } + get { return (string?)_store[nameof(SharedCompilationId)]; } } public bool SkipCompilerExecution @@ -306,30 +309,32 @@ public bool SkipCompilerExecution get { return _store.GetOrDefault(nameof(SkipCompilerExecution), false); } } - public ITaskItem[] Sources + public ITaskItem[]? Sources { set { if (UsedCommandLineTool) { - NormalizePaths(value); + // PROTOTYPE(NullableDogfood): property setter should be non-null + // https://github.com/dotnet/roslyn/issues/26621 + NormalizePaths(value!); } _store[nameof(Sources)] = value; } - get { return (ITaskItem[])_store[nameof(Sources)]; } + get { return (ITaskItem[]?)_store[nameof(Sources)]; } } - public string SubsystemVersion + public string? SubsystemVersion { set { _store[nameof(SubsystemVersion)] = value; } - get { return (string)_store[nameof(SubsystemVersion)]; } + get { return (string?)_store[nameof(SubsystemVersion)]; } } - public string TargetType + public string? TargetType { set { _store[nameof(TargetType)] = CultureInfo.InvariantCulture.TextInfo.ToLower(value); } - get { return (string)_store[nameof(TargetType)]; } + get { return (string?)_store[nameof(TargetType)]; } } public bool TreatWarningsAsErrors @@ -344,28 +349,28 @@ public bool Utf8Output get { return _store.GetOrDefault(nameof(Utf8Output), false); } } - public string Win32Icon + public string? Win32Icon { set { _store[nameof(Win32Icon)] = value; } - get { return (string)_store[nameof(Win32Icon)]; } + get { return (string?)_store[nameof(Win32Icon)]; } } - public string Win32Manifest + public string? Win32Manifest { set { _store[nameof(Win32Manifest)] = value; } - get { return (string)_store[nameof(Win32Manifest)]; } + get { return (string?)_store[nameof(Win32Manifest)]; } } - public string Win32Resource + public string? Win32Resource { set { _store[nameof(Win32Resource)] = value; } - get { return (string)_store[nameof(Win32Resource)]; } + get { return (string?)_store[nameof(Win32Resource)]; } } - public string PathMap + public string? PathMap { set { _store[nameof(PathMap)] = value; } - get { return (string)_store[nameof(PathMap)]; } + get { return (string?)_store[nameof(PathMap)]; } } /// @@ -383,11 +388,11 @@ public bool UseSharedCompilation // Map explicit platform of "AnyCPU" or the default platform (null or ""), since it is commonly understood in the // managed build process to be equivalent to "AnyCPU", to platform "AnyCPU32BitPreferred" if the Prefer32Bit // property is set. - internal string PlatformWith32BitPreference + internal string? PlatformWith32BitPreference { get { - string platform = Platform; + string? platform = Platform; if ((string.IsNullOrEmpty(platform) || platform.Equals("anycpu", StringComparison.OrdinalIgnoreCase)) && Prefer32Bit) { platform = "anycpu32bitpreferred"; @@ -407,10 +412,10 @@ protected override Encoding StandardOutputEncoding } } - public string LangVersion + public string? LangVersion { set { _store[nameof(LangVersion)] = value; } - get { return (string)_store[nameof(LangVersion)]; } + get { return (string?)_store[nameof(LangVersion)]; } } #endregion @@ -432,7 +437,8 @@ public string GeneratePathToTool() return GenerateFullPathToTool(); } - protected sealed override string PathToManagedTool => Utilities.GenerateFullPathToTool(ToolName); + // PROTOTYPE(NullableDogfood): Need to follow-up, possible compiler bug + protected sealed override string PathToManagedTool => Utilities.GenerateFullPathToTool(ToolName)!; protected sealed override string PathToNativeTool => Path.Combine(ToolPath ?? "", ToolExe); @@ -464,7 +470,9 @@ protected override int ExecuteTool(string pathToTool, string responseFileCommand CompilerServerLogger.Log($"CommandLine = '{commandLineCommands}'"); CompilerServerLogger.Log($"BuildResponseFile = '{responseFileCommands}'"); - var clientDir = Path.GetDirectoryName(PathToManagedTool); + // PROTOTYPE(NullableDogfood): GetDirectoryName should be annotated (can return null) + // PROTOTYPE(NullableDogfood): The cast should not be grayed out as un-necessary by IDE + var clientDir = (string?)Path.GetDirectoryName(PathToManagedTool); // Note: we can't change the "tool path" printed to the console when we run // the Csc/Vbc task since MSBuild logs it for us before we get here. Instead, @@ -801,14 +809,14 @@ internal void AddResponseFileCommandsForSwitchesSinceInitialReleaseThatAreNeeded /// /// Adds a "/features:" switch to the command line for each provided feature. /// - internal static void AddFeatures(CommandLineBuilderExtension commandLine, string features) + internal static void AddFeatures(CommandLineBuilderExtension commandLine, string? features) { if (string.IsNullOrEmpty(features)) { return; } - foreach (var feature in CompilerOptionParseUtilities.ParseFeatureFromMSBuild(features)) + foreach (var feature in CompilerOptionParseUtilities.ParseFeatureFromMSBuild(features!)) { commandLine.AppendSwitchIfNotNull("/features:", feature.Trim()); } @@ -817,7 +825,7 @@ internal static void AddFeatures(CommandLineBuilderExtension commandLine, string /// /// Adds a "/analyzer:" switch to the command line for each provided analyzer. /// - internal static void AddAnalyzersToCommandLine(CommandLineBuilderExtension commandLine, ITaskItem[] analyzers) + internal static void AddAnalyzersToCommandLine(CommandLineBuilderExtension commandLine, ITaskItem[]? analyzers) { // If there were no analyzers passed in, don't add any /analyzer: switches // on the command-line. @@ -896,7 +904,7 @@ private void ConfigureDebugProperties() if (_store[nameof(DebugType)] != null) { // If debugtype is none then only show debug- else use the debug type and the debugsymbols as is. - if (string.Compare((string)_store[nameof(DebugType)], "none", StringComparison.OrdinalIgnoreCase) == 0) + if (string.Compare((string?)_store[nameof(DebugType)], "none", StringComparison.OrdinalIgnoreCase) == 0) { _store[nameof(DebugType)] = null; _store[nameof(EmitDebugInformation)] = false; @@ -916,7 +924,7 @@ protected override bool ValidateParameters() /// /// Returns true if the provided item list contains duplicate items, false otherwise. /// - internal static bool ListHasNoDuplicateItems(ITaskItem[] itemList, string parameterName, TaskLoggingHelper log) + internal static bool ListHasNoDuplicateItems(ITaskItem[]? itemList, string parameterName, TaskLoggingHelper log) { return ListHasNoDuplicateItems(itemList, parameterName, null, log); } @@ -928,7 +936,7 @@ internal static bool ListHasNoDuplicateItems(ITaskItem[] itemList, string parame /// Optional name of metadata that may legitimately disambiguate items. May be null. /// /// - private static bool ListHasNoDuplicateItems(ITaskItem[] itemList, string parameterName, string disambiguatingMetadataName, TaskLoggingHelper log) + private static bool ListHasNoDuplicateItems(ITaskItem[]? itemList, string parameterName, string? disambiguatingMetadataName, TaskLoggingHelper log) { if (itemList == null || itemList.Length == 0) { @@ -939,7 +947,7 @@ private static bool ListHasNoDuplicateItems(ITaskItem[] itemList, string paramet foreach (ITaskItem item in itemList) { string key; - string disambiguatingMetadataValue = null; + string? disambiguatingMetadataValue = null; if (disambiguatingMetadataName != null) { disambiguatingMetadataValue = item.GetMetadata(disambiguatingMetadataName); @@ -1046,7 +1054,7 @@ bool resultFromHostObjectSetOperation } } - internal void InitializeHostObjectSupportForNewSwitches(ITaskHost hostObject, ref string param) + internal void InitializeHostObjectSupportForNewSwitches(ITaskHost? hostObject, ref string param) { var compilerOptionsHostObject = hostObject as ICompilerOptionsHostObject; @@ -1103,10 +1111,10 @@ protected bool CheckAllReferencesExistOnDisk() /// which is only used during IDE builds. /// /// the path to the win32 manifest to provide to the host object - internal string GetWin32ManifestSwitch + internal string? GetWin32ManifestSwitch ( bool noDefaultWin32Manifest, - string win32Manifest + string? win32Manifest ) { if (!noDefaultWin32Manifest) diff --git a/src/Compilers/Core/MSBuildTask/ManagedToolTask.cs b/src/Compilers/Core/MSBuildTask/ManagedToolTask.cs index b81fbd63ea42d..e2c59b65e5f07 100644 --- a/src/Compilers/Core/MSBuildTask/ManagedToolTask.cs +++ b/src/Compilers/Core/MSBuildTask/ManagedToolTask.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Runtime.CompilerServices; using Microsoft.Build.Utilities; namespace Microsoft.CodeAnalysis.BuildTasks @@ -31,7 +32,7 @@ public abstract class ManagedToolTask : ToolTask protected sealed override string GenerateCommandLineCommands() { var commandLineArguments = ToolArguments; - if (IsManagedTool && IsCliHost(out string pathToDotnet)) + if (IsManagedTool && IsCliHost(out string? pathToDotnet)) { var pathToTool = PathToManagedTool; if (pathToTool is null) @@ -53,7 +54,7 @@ protected sealed override string GenerateFullPathToTool() { if (IsManagedTool) { - if (IsCliHost(out string pathToDotnet)) + if (IsCliHost(out string? pathToDotnet)) { return pathToDotnet; } @@ -83,7 +84,7 @@ protected sealed override string GenerateFullPathToTool() protected sealed override string ToolName => $"{ToolNameWithoutExtension}.{(CoreClrShim.IsRunningOnCoreClr ? "dll" : "exe")}"; - private static bool IsCliHost(out string pathToDotnet) + private static bool IsCliHost([NotNullWhenTrue] out string? pathToDotnet) { if (CoreClrShim.IsRunningOnCoreClr) { @@ -97,7 +98,7 @@ private static bool IsCliHost(out string pathToDotnet) } } - private static string PrependFileToArgs(string pathToTool, string commandLineArgs) + private static string PrependFileToArgs(string? pathToTool, string commandLineArgs) { var builder = new CommandLineBuilderExtension(); builder.AppendFileNameIfNotNull(pathToTool); diff --git a/src/Compilers/Core/MSBuildTask/MapSourceRoots.cs b/src/Compilers/Core/MSBuildTask/MapSourceRoots.cs index 7a4072a5837aa..c63d8933d35fb 100644 --- a/src/Compilers/Core/MSBuildTask/MapSourceRoots.cs +++ b/src/Compilers/Core/MSBuildTask/MapSourceRoots.cs @@ -24,6 +24,8 @@ public sealed class MapSourceRoots : Task { public MapSourceRoots() { + SourceRoots = null!; // PROTOTYPE(NullableDogfood): MSBuild ensures those are set, using [Required] + MappedSourceRoots = null!; // PROTOTYPE(NullableDogfood): MSBuild ensures those are set, using [Required] TaskResources = ErrorString.ResourceManager; } diff --git a/src/Compilers/Core/MSBuildTask/MvidReader.cs b/src/Compilers/Core/MSBuildTask/MvidReader.cs index 878aaca6acfe1..411859a4a6ed6 100755 --- a/src/Compilers/Core/MSBuildTask/MvidReader.cs +++ b/src/Compilers/Core/MSBuildTask/MvidReader.cs @@ -3,6 +3,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Runtime.CompilerServices; namespace Microsoft.CodeAnalysis.BuildTasks { @@ -90,7 +91,11 @@ private static Guid FindMvidInSections(ushort count, BinaryReader reader) for (int i = 0; i < count; i++) { // Section: Name (8) +#if USES_ANNOTATIONS + if (!ReadBytes(reader, 8, out byte[]? name)) +#else if (!ReadBytes(reader, 8, out byte[] name)) +#endif { return s_empty; } @@ -141,11 +146,16 @@ private static Guid ReadMvidSection(BinaryReader reader, uint pointerToMvidSecti return s_empty; } +#if USES_ANNOTATIONS + if (!ReadBytes(reader, 16, out byte[]? guidBytes)) +#else if (!ReadBytes(reader, 16, out byte[] guidBytes)) +#endif { return s_empty; } + // PROTOTYPE(NullableDogfood): Need annotation on Guid constructor (throws on null) return new Guid(guidBytes); } @@ -173,7 +183,11 @@ private static bool ReadUInt32(BinaryReader reader, out uint output) return true; } +#if USES_ANNOTATIONS + private static bool ReadBytes(BinaryReader reader, int count, [NotNullWhenTrue] out byte[]? output) +#else private static bool ReadBytes(BinaryReader reader, int count, out byte[] output) +#endif { if (reader.BaseStream.Position + count >= reader.BaseStream.Length) { diff --git a/src/Compilers/Core/MSBuildTask/PropertyDictionary.cs b/src/Compilers/Core/MSBuildTask/PropertyDictionary.cs index e393e06a3112c..23f629b3b87a7 100644 --- a/src/Compilers/Core/MSBuildTask/PropertyDictionary.cs +++ b/src/Compilers/Core/MSBuildTask/PropertyDictionary.cs @@ -4,11 +4,11 @@ namespace Microsoft.CodeAnalysis.BuildTasks { - internal class PropertyDictionary : Dictionary + internal class PropertyDictionary : Dictionary { public T GetOrDefault(string name, T @default) { - object value; + object? value; if (this.TryGetValue(name, out value)) { return (T)value; @@ -16,11 +16,11 @@ public T GetOrDefault(string name, T @default) return @default; } - public new object this[string name] + public new object? this[string name] { get { - object value; + object? value; return this.TryGetValue(name, out value) ? value : null; } diff --git a/src/Compilers/Core/MSBuildTask/RCWForCurrentContext.cs b/src/Compilers/Core/MSBuildTask/RCWForCurrentContext.cs index 458b8d6755371..2fdcc65e7ff54 100644 --- a/src/Compilers/Core/MSBuildTask/RCWForCurrentContext.cs +++ b/src/Compilers/Core/MSBuildTask/RCWForCurrentContext.cs @@ -17,7 +17,7 @@ internal class RCWForCurrentContext : IDisposable where T : class /// /// The last RCW that was created for the current context. /// - private T _rcwForCurrentCtx; + private T? _rcwForCurrentCtx; /// /// Indicates if we created the RCW and therefore need to release it's com reference. @@ -34,7 +34,7 @@ public RCWForCurrentContext(T rcw) // the caching behavior of the marshaled pointer. // See RCW::GetComIPForMethodTableFromCache in ndp\clr\src\VM\RuntimeCallableWrapper.cpp IntPtr iunknownPtr = Marshal.GetIUnknownForObject(rcw); - Object objInCurrentCtx = null; + Object? objInCurrentCtx = null; try { diff --git a/src/Compilers/Core/MSBuildTask/Utilities.cs b/src/Compilers/Core/MSBuildTask/Utilities.cs index f361a1ede6863..7de35720f17d1 100644 --- a/src/Compilers/Core/MSBuildTask/Utilities.cs +++ b/src/Compilers/Core/MSBuildTask/Utilities.cs @@ -148,7 +148,7 @@ internal static Exception GetLocalizedArgumentException(string errorString, return new ArgumentException(string.Format(CultureInfo.CurrentCulture, errorString, args)); } - internal static string TryGetAssemblyPath(Assembly assembly) + internal static string? TryGetAssemblyPath(Assembly assembly) { if ((bool?)typeof(Assembly).GetTypeInfo() .GetDeclaredProperty("GlobalAssemblyCache") @@ -194,9 +194,9 @@ internal static string TryGetAssemblyPath(Assembly assembly) /// Try to get the directory this assembly is in. Returns null if assembly /// was in the GAC or DLL location can not be retrieved. /// - public static string GenerateFullPathToTool(string toolName) + public static string? GenerateFullPathToTool(string toolName) { - string toolLocation = null; + string? toolLocation = null; var buildTask = typeof(Utilities).GetTypeInfo().Assembly; var assemblyPath = TryGetAssemblyPath(buildTask); diff --git a/src/Compilers/Core/MSBuildTask/ValidateBootstrap.cs b/src/Compilers/Core/MSBuildTask/ValidateBootstrap.cs index e5e6f49b45221..316b2c62b5c7f 100644 --- a/src/Compilers/Core/MSBuildTask/ValidateBootstrap.cs +++ b/src/Compilers/Core/MSBuildTask/ValidateBootstrap.cs @@ -21,9 +21,9 @@ public sealed partial class ValidateBootstrap : Task private static readonly ConcurrentDictionary s_failedLoadSet = new ConcurrentDictionary(); private static int s_failedServerConnectionCount = 0; - private string _bootstrapPath; + private string? _bootstrapPath; - public string BootstrapPath + public string? BootstrapPath { get { return _bootstrapPath; } set { _bootstrapPath = NormalizePath(value); } @@ -52,7 +52,7 @@ public override bool Execute() var comparer = StringComparer.OrdinalIgnoreCase; foreach (var dependency in dependencies) { - var path = GetDirectory(dependency); + string? path = GetDirectory(dependency); path = NormalizePath(path); if (!comparer.Equals(path, toolsPath)) { @@ -87,7 +87,7 @@ public override bool Execute() return allGood; } - private static string NormalizePath(string path) + private static string? NormalizePath(string? path) { if (string.IsNullOrEmpty(path)) { diff --git a/src/Compilers/Core/MSBuildTask/Vbc.cs b/src/Compilers/Core/MSBuildTask/Vbc.cs index 86d6f59480152..fd33cdeb46922 100644 --- a/src/Compilers/Core/MSBuildTask/Vbc.cs +++ b/src/Compilers/Core/MSBuildTask/Vbc.cs @@ -43,28 +43,28 @@ public class Vbc : ManagedCompiler // ones shared between Vbc and Csc are defined in ManagedCompiler.cs, which is // the base class. - public string BaseAddress + public string? BaseAddress { set { _store[nameof(BaseAddress)] = value; } - get { return (string)_store[nameof(BaseAddress)]; } + get { return (string?)_store[nameof(BaseAddress)]; } } - public string DisabledWarnings + public string? DisabledWarnings { set { _store[nameof(DisabledWarnings)] = value; } - get { return (string)_store[nameof(DisabledWarnings)]; } + get { return (string?)_store[nameof(DisabledWarnings)]; } } - public string DocumentationFile + public string? DocumentationFile { set { _store[nameof(DocumentationFile)] = value; } - get { return (string)_store[nameof(DocumentationFile)]; } + get { return (string?)_store[nameof(DocumentationFile)]; } } - public string ErrorReport + public string? ErrorReport { set { _store[nameof(ErrorReport)] = value; } - get { return (string)_store[nameof(ErrorReport)]; } + get { return (string?)_store[nameof(ErrorReport)]; } } public bool GenerateDocumentation @@ -73,16 +73,16 @@ public bool GenerateDocumentation get { return _store.GetOrDefault(nameof(GenerateDocumentation), false); } } - public ITaskItem[] Imports + public ITaskItem[]? Imports { set { _store[nameof(Imports)] = value; } - get { return (ITaskItem[])_store[nameof(Imports)]; } + get { return (ITaskItem[]?)_store[nameof(Imports)]; } } - public string ModuleAssemblyName + public string? ModuleAssemblyName { set { _store[nameof(ModuleAssemblyName)] = value; } - get { return (string)_store[nameof(ModuleAssemblyName)]; } + get { return (string?)_store[nameof(ModuleAssemblyName)]; } } public bool NoStandardLib @@ -108,10 +108,10 @@ public bool NoWarnings get { return _store.GetOrDefault(nameof(NoWarnings), false); } } - public string OptionCompare + public string? OptionCompare { set { _store[nameof(OptionCompare)] = value; } - get { return (string)_store[nameof(OptionCompare)]; } + get { return (string?)_store[nameof(OptionCompare)]; } } public bool OptionExplicit @@ -133,10 +133,10 @@ public bool OptionInfer } // Currently only /optionstrict:custom - public string OptionStrictType + public string? OptionStrictType { set { _store[nameof(OptionStrictType)] = value; } - get { return (string)_store[nameof(OptionStrictType)]; } + get { return (string?)_store[nameof(OptionStrictType)]; } } public bool RemoveIntegerChecks @@ -145,16 +145,16 @@ public bool RemoveIntegerChecks get { return _store.GetOrDefault(nameof(RemoveIntegerChecks), false); } } - public string RootNamespace + public string? RootNamespace { set { _store[nameof(RootNamespace)] = value; } - get { return (string)_store[nameof(RootNamespace)]; } + get { return (string?)_store[nameof(RootNamespace)]; } } - public string SdkPath + public string? SdkPath { set { _store[nameof(SdkPath)] = value; } - get { return (string)_store[nameof(SdkPath)]; } + get { return (string?)_store[nameof(SdkPath)]; } } /// @@ -164,16 +164,16 @@ public string SdkPath /// If set to null, "/preferreduilang" option is omitted, and vbc.exe uses its default setting. /// Otherwise, the value is passed to "/preferreduilang" as is. /// - public string PreferredUILang + public string? PreferredUILang { set { _store[nameof(PreferredUILang)] = value; } - get { return (string)_store[nameof(PreferredUILang)]; } + get { return (string?)_store[nameof(PreferredUILang)]; } } - public string VsSessionGuid + public string? VsSessionGuid { set { _store[nameof(VsSessionGuid)] = value; } - get { return (string)_store[nameof(VsSessionGuid)]; } + get { return (string?)_store[nameof(VsSessionGuid)]; } } public bool TargetCompactFramework @@ -188,40 +188,40 @@ public bool UseHostCompilerIfAvailable get { return _useHostCompilerIfAvailable; } } - public string VBRuntimePath + public string? VBRuntimePath { set { _store[nameof(VBRuntimePath)] = value; } - get { return (string)_store[nameof(VBRuntimePath)]; } + get { return (string?)_store[nameof(VBRuntimePath)]; } } - public string Verbosity + public string? Verbosity { set { _store[nameof(Verbosity)] = value; } - get { return (string)_store[nameof(Verbosity)]; } + get { return (string?)_store[nameof(Verbosity)]; } } - public string WarningsAsErrors + public string? WarningsAsErrors { set { _store[nameof(WarningsAsErrors)] = value; } - get { return (string)_store[nameof(WarningsAsErrors)]; } + get { return (string?)_store[nameof(WarningsAsErrors)]; } } - public string WarningsNotAsErrors + public string? WarningsNotAsErrors { set { _store[nameof(WarningsNotAsErrors)] = value; } - get { return (string)_store[nameof(WarningsNotAsErrors)]; } + get { return (string?)_store[nameof(WarningsNotAsErrors)]; } } - public string VBRuntime + public string? VBRuntime { set { _store[nameof(VBRuntime)] = value; } - get { return (string)_store[nameof(VBRuntime)]; } + get { return (string?)_store[nameof(VBRuntime)]; } } - public string PdbFile + public string? PdbFile { set { _store[nameof(PdbFile)] = value; } - get { return (string)_store[nameof(PdbFile)]; } + get { return (string?)_store[nameof(PdbFile)]; } } #endregion @@ -267,7 +267,8 @@ public override bool Execute() if (!SkipCompilerExecution) { - MovePdbFileIfNecessary(OutputAssembly.ItemSpec); + // PROTOTYPE(NullableDogfood): Not sure + MovePdbFileIfNecessary(OutputAssembly!.ItemSpec); } return !Log.HasLoggedErrors; @@ -281,7 +282,7 @@ public override bool Execute() /// /// If at some future point VBC.exe offers a /pdbfile switch, this function can be removed. /// - internal void MovePdbFileIfNecessary(string outputAssembly) + internal void MovePdbFileIfNecessary(string? outputAssembly) { // Get the name of the output assembly because the pdb will be written beside it and will have the same name if (String.IsNullOrEmpty(PdbFile) || String.IsNullOrEmpty(outputAssembly)) @@ -331,9 +332,9 @@ internal void MovePdbFileIfNecessary(string outputAssembly) /// of the task to pass in the BaseAddress in either decimal or hexadecimal format. /// Examples of supported hex formats include "0x10000000" or "&H10000000". /// - internal string GetBaseAddressInHex() + internal string? GetBaseAddressInHex() { - string originalBaseAddress = this.BaseAddress; + string? originalBaseAddress = this.BaseAddress; if (originalBaseAddress != null) { @@ -406,7 +407,7 @@ protected internal override void AddResponseFileCommands(CommandLineBuilderExten */ // Decide whether we are Option Strict+ or Option Strict:custom - object optionStrictSetting = this._store["OptionStrict"]; + object? optionStrictSetting = this._store["OptionStrict"]; bool optionStrict = optionStrictSetting != null ? (bool)optionStrictSetting : false; if (optionStrict) { @@ -697,7 +698,7 @@ internal void ParseVBErrorOrWarning(string singleLine, MessageImportance message return; } - string newLine = null; + string? newLine = null; newLine = originalVBErrorString.Substring(0, endParenthesisLocation) + "," + column + originalVBErrorString.Substring(endParenthesisLocation); // Output all of the lines of the error, but with the modified first line as well. @@ -712,7 +713,7 @@ internal void ParseVBErrorOrWarning(string singleLine, MessageImportance message } else { - CanonicalError.Parts parts = CanonicalError.Parse(singleLine); + CanonicalError.Parts? parts = CanonicalError.Parse(singleLine); if (parts == null) { base.LogEventsFromTextOutput(singleLine, messageImportance); @@ -749,9 +750,9 @@ internal void ParseVBErrorOrWarning(string singleLine, MessageImportance message /// switch. It does that by quoting the entire string, and escaping the embedded /// quotes. /// - internal static string GetDefineConstantsSwitch + internal static string? GetDefineConstantsSwitch ( - string originalDefineConstants + string? originalDefineConstants ) { if ((originalDefineConstants == null) || (originalDefineConstants.Length == 0)) @@ -812,7 +813,7 @@ private bool InitializeHostCompiler(IVbcHostObject vbcHostObject) CheckHostObjectSupport(param = nameof(AddModules), vbcHostObject.SetAddModules(AddModules)); // For host objects which support them, set the analyzers, ruleset and additional files. - IAnalyzerHostObject analyzerHostObject = vbcHostObject as IAnalyzerHostObject; + IAnalyzerHostObject? analyzerHostObject = vbcHostObject as IAnalyzerHostObject; if (analyzerHostObject != null) { CheckHostObjectSupport(param = nameof(Analyzers), analyzerHostObject.SetAnalyzers(Analyzers)); @@ -844,7 +845,7 @@ private bool InitializeHostCompiler(IVbcHostObject vbcHostObject) CheckHostObjectSupport(param = nameof(OutputAssembly), vbcHostObject.SetOutputAssembly(OutputAssembly?.ItemSpec)); // For host objects which support them, set platform with 32BitPreference, HighEntropyVA, and SubsystemVersion - IVbcHostObject5 vbcHostObject5 = vbcHostObject as IVbcHostObject5; + IVbcHostObject5? vbcHostObject5 = vbcHostObject as IVbcHostObject5; if (vbcHostObject5 != null) { CheckHostObjectSupport(param = nameof(PlatformWith32BitPreference), vbcHostObject5.SetPlatformWith32BitPreference(PlatformWith32BitPreference)); @@ -856,10 +857,11 @@ private bool InitializeHostCompiler(IVbcHostObject vbcHostObject) CheckHostObjectSupport(param = nameof(Platform), vbcHostObject.SetPlatform(Platform)); } - IVbcHostObject6 vbcHostObject6 = vbcHostObject as IVbcHostObject6; + IVbcHostObject6? vbcHostObject6 = vbcHostObject as IVbcHostObject6; if (vbcHostObject6 != null) { - CheckHostObjectSupport(param = nameof(ErrorLog), vbcHostObject6.SetErrorLog(ErrorLog)); + // PROTOTYPE(NullableDogfood): Unsure + CheckHostObjectSupport(param = nameof(ErrorLog), vbcHostObject6.SetErrorLog(ErrorLog!)); CheckHostObjectSupport(param = nameof(ReportAnalyzer), vbcHostObject6.SetReportAnalyzer(ReportAnalyzer)); } @@ -966,7 +968,7 @@ private bool InitializeHostCompiler(IVbcHostObject vbcHostObject) // VbcHostObject doesn't support VB versions beyond 15, // so the LangVersion will be passed through ICompilerOptionsHostObject.SetCompilerOptions instead - private static bool DeferToICompilerOptionsHostObject(string langVersion, IVbcHostObject vbcHostObject) + private static bool DeferToICompilerOptionsHostObject(string? langVersion, IVbcHostObject vbcHostObject) { if (!(vbcHostObject is ICompilerOptionsHostObject)) { @@ -1094,10 +1096,10 @@ protected override bool CallHostObjectToExecute() { Debug.Assert(this.HostObject != null, "We should not be here if the host object has not been set."); - IVbcHostObject vbcHostObject = this.HostObject as IVbcHostObject; + IVbcHostObject vbcHostObject = (IVbcHostObject)this.HostObject; Debug.Assert(vbcHostObject != null, "Wrong kind of host object passed in!"); - IVbcHostObject5 vbcHostObject5 = vbcHostObject as IVbcHostObject5; + IVbcHostObject5 vbcHostObject5 = (IVbcHostObject5)vbcHostObject; Debug.Assert(vbcHostObject5 != null, "Wrong kind of host object passed in!"); // IVbcHostObjectFreeThreaded::Compile is the preferred way to compile the host object diff --git a/src/Compilers/Core/Portable/CorLightup.cs b/src/Compilers/Core/Portable/CorLightup.cs index c1c1428711ae4..82091b42f6897 100644 --- a/src/Compilers/Core/Portable/CorLightup.cs +++ b/src/Compilers/Core/Portable/CorLightup.cs @@ -193,15 +193,27 @@ internal static bool IsAssemblyFromGlobalAssemblyCache(Assembly assembly) private sealed class AssemblyResolveWrapper { +#if USES_ANNOTATIONS + private readonly Func _handler; +#else private readonly Func _handler; +#endif private static readonly MethodInfo s_stubInfo = typeof(AssemblyResolveWrapper).GetTypeInfo().GetDeclaredMethod("Stub"); +#if USES_ANNOTATIONS + public AssemblyResolveWrapper(Func handler) +#else public AssemblyResolveWrapper(Func handler) +#endif { _handler = handler; } +#if USES_ANNOTATIONS + private Assembly? Stub(object sender, object resolveEventArgs) +#else private Assembly Stub(object sender, object resolveEventArgs) +#endif { var name = (string)_ResolveEventArgs.get_Name.Invoke(resolveEventArgs, Array.Empty()); var requestingAssembly = (Assembly)_ResolveEventArgs.get_RequestingAssembly.Invoke(resolveEventArgs, Array.Empty()); @@ -228,7 +240,11 @@ internal static object GetCurrentAppDomain() return _AppDomain.get_CurrentDomain.Invoke(null, Array.Empty()); } +#if USES_ANNOTATIONS + internal static void GetOrRemoveAssemblyResolveHandler(Func handler, MethodInfo handlerOperation) +#else internal static void GetOrRemoveAssemblyResolveHandler(Func handler, MethodInfo handlerOperation) +#endif { if (_AppDomain.add_AssemblyResolve == null) { @@ -241,12 +257,20 @@ internal static void GetOrRemoveAssemblyResolveHandler(Func handler) +#else internal static void AddAssemblyResolveHandler(Func handler) +#endif { GetOrRemoveAssemblyResolveHandler(handler, _AppDomain.add_AssemblyResolve); } +#if USES_ANNOTATIONS + internal static void RemoveAssemblyResolveHandler(Func handler) +#else internal static void RemoveAssemblyResolveHandler(Func handler) +#endif { GetOrRemoveAssemblyResolveHandler(handler, _AppDomain.remove_AssemblyResolve); } diff --git a/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs b/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs index 4aadf112dfc3f..45b3624b73548 100644 --- a/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs +++ b/src/Compilers/Core/Portable/InternalUtilities/ReflectionUtilities.cs @@ -12,7 +12,11 @@ internal static class ReflectionUtilities { private static readonly Type Missing = typeof(void); +#if USES_ANNOTATIONS + public static Type? TryGetType(string assemblyQualifiedName) +#else public static Type TryGetType(string assemblyQualifiedName) +#endif { try { @@ -25,7 +29,11 @@ public static Type TryGetType(string assemblyQualifiedName) } } +#if USES_ANNOTATIONS + public static Type? TryGetType(ref Type lazyType, string assemblyQualifiedName) +#else public static Type TryGetType(ref Type lazyType, string assemblyQualifiedName) +#endif { if (lazyType == null) { @@ -39,7 +47,11 @@ public static Type TryGetType(ref Type lazyType, string assemblyQualifiedName) /// Find a instance by first probing the contract name and then the name as it /// would exist in mscorlib. This helps satisfy both the CoreCLR and Desktop scenarios. /// +#if USES_ANNOTATIONS + public static Type? GetTypeFromEither(string contractName, string desktopName) +#else public static Type GetTypeFromEither(string contractName, string desktopName) +#endif { var type = TryGetType(contractName); @@ -51,7 +63,11 @@ public static Type GetTypeFromEither(string contractName, string desktopName) return type; } +#if USES_ANNOTATIONS + public static Type? GetTypeFromEither(ref Type lazyType, string contractName, string desktopName) +#else public static Type GetTypeFromEither(ref Type lazyType, string contractName, string desktopName) +#endif { if (lazyType == null) { @@ -61,7 +77,11 @@ public static Type GetTypeFromEither(ref Type lazyType, string contractName, str return (lazyType == Missing) ? null : lazyType; } +#if USES_ANNOTATIONS + public static T? FindItem(IEnumerable collection, params Type[] paramTypes) +#else public static T FindItem(IEnumerable collection, params Type[] paramTypes) +#endif where T : MethodBase { foreach (var current in collection) @@ -91,17 +111,30 @@ public static T FindItem(IEnumerable collection, params Type[] paramTypes) return null; } +#if USES_ANNOTATIONS + internal static MethodInfo? GetDeclaredMethod(this TypeInfo typeInfo, string name, params Type[] paramTypes) +#else internal static MethodInfo GetDeclaredMethod(this TypeInfo typeInfo, string name, params Type[] paramTypes) +#endif { return FindItem(typeInfo.GetDeclaredMethods(name), paramTypes); } +#if USES_ANNOTATIONS + internal static ConstructorInfo? GetDeclaredConstructor(this TypeInfo typeInfo, params Type[] paramTypes) +#else internal static ConstructorInfo GetDeclaredConstructor(this TypeInfo typeInfo, params Type[] paramTypes) +#endif { return FindItem(typeInfo.DeclaredConstructors, paramTypes); } +#if USES_ANNOTATIONS + public static T? CreateDelegate(this MethodInfo? methodInfo) + where T : Delegate +#else public static T CreateDelegate(this MethodInfo methodInfo) +#endif { if (methodInfo == null) { @@ -111,26 +144,37 @@ public static T CreateDelegate(this MethodInfo methodInfo) return (T)(object)methodInfo.CreateDelegate(typeof(T)); } +#if USES_ANNOTATIONS + public static T? InvokeConstructor(this ConstructorInfo? constructorInfo, params object[]? args) +#else public static T InvokeConstructor(this ConstructorInfo constructorInfo, params object[] args) +#endif + where T : class { if (constructorInfo == null) { - return default; + return null; } try { + // PROTOTYPE(NullableDogfood): Invoke method needs annotation return (T)constructorInfo.Invoke(args); } catch (TargetInvocationException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); Debug.Assert(false, "Unreachable"); - return default; + + return null; } } +#if USES_ANNOTATIONS + public static object? InvokeConstructor(this ConstructorInfo constructorInfo, params object[] args) +#else public static object InvokeConstructor(this ConstructorInfo constructorInfo, params object[] args) +#endif { return constructorInfo.InvokeConstructor(args); } diff --git a/src/Compilers/Core/Portable/NonNullTypesAttribute.cs b/src/Compilers/Core/Portable/NonNullTypesAttribute.cs index 393461b966362..0481e2559ef26 100644 --- a/src/Compilers/Core/Portable/NonNullTypesAttribute.cs +++ b/src/Compilers/Core/Portable/NonNullTypesAttribute.cs @@ -9,4 +9,10 @@ public NonNullTypesAttribute(bool b = true) { } } + + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal class NotNullWhenTrueAttribute : Attribute + { + public NotNullWhenTrueAttribute() { } + } } diff --git a/src/Compilers/Shared/BuildServerConnection.cs b/src/Compilers/Shared/BuildServerConnection.cs index 370014db69750..cde5fea17f283 100644 --- a/src/Compilers/Shared/BuildServerConnection.cs +++ b/src/Compilers/Shared/BuildServerConnection.cs @@ -37,7 +37,11 @@ internal struct BuildPathsAlt /// The path which contains mscorlib. This can be null when specified by the user or running in a /// CoreClr environment. /// +#if USES_ANNOTATIONS + internal string? SdkDirectory { get; } +#else internal string SdkDirectory { get; } +#endif /// /// The temporary directory a compilation should use instead of . The latter @@ -45,9 +49,13 @@ internal struct BuildPathsAlt /// internal string TempDirectory { get; } +#if USES_ANNOTATIONS + internal BuildPathsAlt(string? clientDir, string workingDir, string? sdkDir, string tempDir) +#else internal BuildPathsAlt(string clientDir, string workingDir, string sdkDir, string tempDir) +#endif { - ClientDirectory = clientDir; + ClientDirectory = clientDir ?? string.Empty; WorkingDirectory = workingDir; SdkDirectory = sdkDir; TempDirectory = tempDir; @@ -71,6 +79,16 @@ internal sealed class BuildServerConnection internal static bool IsCompilerServerSupported => GetPipeNameForPathOpt("") != null; +#if USES_ANNOTATIONS + public static Task RunServerCompilation( + RequestLanguage language, + string? sharedCompilationId, + List arguments, + BuildPathsAlt buildPaths, + string? keepAlive, + string libEnvVariable, + CancellationToken cancellationToken) +#else public static Task RunServerCompilation( RequestLanguage language, string sharedCompilationId, @@ -79,9 +97,9 @@ public static Task RunServerCompilation( string keepAlive, string libEnvVariable, CancellationToken cancellationToken) +#endif { var pipeNameOpt = sharedCompilationId ?? GetPipeNameForPathOpt(buildPaths.ClientDirectory); - return RunServerCompilationCore( language, arguments, @@ -94,6 +112,18 @@ public static Task RunServerCompilation( cancellationToken: cancellationToken); } +#if USES_ANNOTATIONS + internal static async Task RunServerCompilationCore( + RequestLanguage language, + List arguments, + BuildPathsAlt buildPaths, + string? pipeName, + string? keepAlive, + string libEnvVariable, + int? timeoutOverride, + Func tryCreateServerFunc, + CancellationToken cancellationToken) +#else internal static async Task RunServerCompilationCore( RequestLanguage language, List arguments, @@ -104,6 +134,7 @@ internal static async Task RunServerCompilationCore( int? timeoutOverride, Func tryCreateServerFunc, CancellationToken cancellationToken) +#endif { if (pipeName == null) { @@ -118,8 +149,13 @@ internal static async Task RunServerCompilationCore( var clientDir = buildPaths.ClientDirectory; var timeoutNewProcess = timeoutOverride ?? TimeOutMsNewProcess; var timeoutExistingProcess = timeoutOverride ?? TimeOutMsExistingProcess; +#if USES_ANNOTATIONS + Task? pipeTask = null; + Mutex? clientMutex = null; +#else Task pipeTask = null; Mutex clientMutex = null; +#endif var holdsMutex = false; try { @@ -302,10 +338,17 @@ internal static async Task CreateMonitorDisconnectTask( /// /// An open to the server process or null on failure. /// +#if USES_ANNOTATIONS + internal static async Task TryConnectToServerAsync( + string pipeName, + int timeoutMs, + CancellationToken cancellationToken) +#else internal static async Task TryConnectToServerAsync( string pipeName, int timeoutMs, CancellationToken cancellationToken) +#endif { NamedPipeClientStream pipeStream; try @@ -349,8 +392,9 @@ internal static async Task TryConnectToServerAsync( } catch (Exception e) when (!(e is TaskCanceledException || e is OperationCanceledException)) { - LogException(e, "Exception while connecting to process"); - return null; + // PROTOTYPE(NullableDogfood): Filed https://github.com/dotnet/roslyn/issues/29295 + LogException(e!, "Exception while connecting to process"); + return null; } } @@ -526,7 +570,11 @@ private static ObjectSecurity GetPipeSecurity(PipeStream pipeStream) /// /// Null if not enough information was found to create a valid pipe name. /// +#if USES_ANNOTATIONS + internal static string? GetPipeNameForPathOpt(string compilerExeDirectory) +#else internal static string GetPipeNameForPathOpt(string compilerExeDirectory) +#endif { var basePipeName = GetBasePipeName(compilerExeDirectory);