diff --git a/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs b/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs index b6772e370d40d..c887155ce8f3a 100644 --- a/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs +++ b/src/Compilers/CSharp/Portable/CSharpCompilationOptions.cs @@ -192,6 +192,11 @@ public CSharpCompilationOptions WithCryptoKeyFile(string path) public CSharpCompilationOptions WithCryptoPublicKey(ImmutableArray value) { + if (value.IsDefault) + { + value = ImmutableArray.Empty; + } + if (value == this.CryptoPublicKey) { return this; @@ -526,7 +531,7 @@ internal override void ValidateOptions(ArrayBuilder builder) // (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') && // (version >= "6.2") - if (!CryptoPublicKey.IsDefault) + if (!CryptoPublicKey.IsEmpty) { if (CryptoKeyFile != null) { diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs index 73378ce364b80..6477efccd8ac8 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceAssemblySymbol.cs @@ -133,7 +133,7 @@ internal SourceAssemblySymbol( _modules = moduleBuilder.ToImmutableAndFree(); - if (!compilation.Options.CryptoPublicKey.IsDefault) + if (!compilation.Options.CryptoPublicKey.IsEmpty) { _lazyStrongNameKeys = StrongNameKeys.Create(compilation.Options.CryptoPublicKey, MessageProvider.Instance); } @@ -551,7 +551,7 @@ private void ValidateAttributeSemantics(DiagnosticBag diagnostics) // Consider: should we allow to OSS sign if the key file only contains public key? if (DeclaringCompilation.Options.OutputKind != OutputKind.NetModule && - DeclaringCompilation.Options.CryptoPublicKey.IsDefault&& + DeclaringCompilation.Options.CryptoPublicKey.IsEmpty && Identity.HasPublicKey&& !IsDelaySigned && !StrongNameKeys.CanSign&& diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/CSharpCompilationOptionsTests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/CSharpCompilationOptionsTests.cs index aa78274e16c64..d3700245a42d1 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/CSharpCompilationOptionsTests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/CSharpCompilationOptionsTests.cs @@ -388,5 +388,17 @@ public void Serializability2() Assert.Equal(compilationOptions.ConcurrentBuild, deserializedCompilationOptions.ConcurrentBuild); Assert.Equal(compilationOptions.ExtendedCustomDebugInformation, deserializedCompilationOptions.ExtendedCustomDebugInformation); } + + [Fact] + public void WithCryptoPublicKey() + { + var options = new CSharpCompilationOptions(OutputKind.ConsoleApplication); + + Assert.Equal(ImmutableArray.Empty, options.CryptoPublicKey); + Assert.Equal(ImmutableArray.Empty, options.WithCryptoPublicKey(default(ImmutableArray)).CryptoPublicKey); + + Assert.Same(options, options.WithCryptoPublicKey(default(ImmutableArray))); + Assert.Same(options, options.WithCryptoPublicKey(ImmutableArray.Empty)); + } } } diff --git a/src/Compilers/Core/Desktop/SerializableCompilationOptions.cs b/src/Compilers/Core/Desktop/SerializableCompilationOptions.cs index 1e825148951c7..683a114228953 100644 --- a/src/Compilers/Core/Desktop/SerializableCompilationOptions.cs +++ b/src/Compilers/Core/Desktop/SerializableCompilationOptions.cs @@ -45,7 +45,7 @@ protected static void CommonGetObjectData(CompilationOptions options, Serializat info.AddValue(ScriptClassNameString, options.ScriptClassName); info.AddValue(CryptoKeyContainerString, options.CryptoKeyContainer); info.AddValue(CryptoKeyFileString, options.CryptoKeyFile); - info.AddValue(CryptoPublicKeyString, options.CryptoPublicKey.IsDefault ? null : options.CryptoPublicKey.ToArray()); + info.AddValue(CryptoPublicKeyString, options.CryptoPublicKey.ToArray()); info.AddValue(DelaySignString, options.DelaySign); info.AddValue(CheckOverflowString, options.CheckOverflow); info.AddValue(PlatformString, (int)options.Platform); diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs index 5fb9635806af6..ac508f7fe5055 100644 --- a/src/Compilers/Core/Portable/Compilation/Compilation.cs +++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs @@ -133,7 +133,7 @@ internal static void CheckSubmissionOptions(CompilationOptions options) throw new ArgumentException(CodeAnalysisResources.InvalidOutputKindForSubmission, "options"); } - if (options.CryptoKeyContainer != null || options.CryptoKeyFile != null || options.DelaySign != null || !options.CryptoPublicKey.IsDefault) + if (options.CryptoKeyContainer != null || options.CryptoKeyFile != null || options.DelaySign != null || !options.CryptoPublicKey.IsEmpty) { throw new ArgumentException(CodeAnalysisResources.InvalidCompilationOptions, "options"); } diff --git a/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs b/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs index d093a238639b0..4a6a7bc075428 100644 --- a/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs +++ b/src/Compilers/Core/Portable/Compilation/CompilationOptions.cs @@ -42,8 +42,11 @@ public abstract class CompilationOptions /// public string MainTypeName { get; protected set; } + // Note that we avoid using default(ImmutableArray) for unspecified value since + // such value is currently not serializable by JSON serializer. + /// - /// Specifies public key used to generate strong name for the compilation assembly, or null of not specified. + /// Specifies public key used to generate strong name for the compilation assembly, or empty of not specified. /// /// /// If specified the values of and must be null. @@ -220,7 +223,7 @@ internal CompilationOptions( this.ScriptClassName = scriptClassName ?? WellKnownMemberNames.DefaultScriptClassName; this.CryptoKeyContainer = cryptoKeyContainer; this.CryptoKeyFile = cryptoKeyFile; - this.CryptoPublicKey = cryptoPublicKey; + this.CryptoPublicKey = cryptoPublicKey.NullToEmpty(); this.DelaySign = delaySign; this.CheckOverflow = checkOverflow; this.Platform = platform; @@ -404,7 +407,7 @@ protected bool EqualsHelper(CompilationOptions other) this.ExtendedCustomDebugInformation == other.ExtendedCustomDebugInformation && string.Equals(this.CryptoKeyContainer, other.CryptoKeyContainer, StringComparison.Ordinal) && string.Equals(this.CryptoKeyFile, other.CryptoKeyFile, StringComparison.Ordinal) && - (this.CryptoPublicKey.IsDefault && other.CryptoPublicKey.IsDefault || !this.CryptoPublicKey.IsDefault && !other.CryptoPublicKey.IsDefault && this.CryptoPublicKey.SequenceEqual(other.CryptoPublicKey)) && + this.CryptoPublicKey.SequenceEqual(other.CryptoPublicKey) && this.DelaySign == other.DelaySign && this.GeneralDiagnosticOption == other.GeneralDiagnosticOption && string.Equals(this.MainTypeName, other.MainTypeName, StringComparison.Ordinal) && diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceAssemblySymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceAssemblySymbol.vb index 0c66ce9f4aa3d..cd824c7a292fc 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceAssemblySymbol.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Source/SourceAssemblySymbol.vb @@ -98,7 +98,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols m_Modules = moduleBuilder.ToImmutableAndFree() - If Not compilation.Options.CryptoPublicKey.IsDefault Then + If Not compilation.Options.CryptoPublicKey.IsEmpty Then m_lazyStrongNameKeys = StrongNameKeys.Create(compilation.Options.CryptoPublicKey, MessageProvider.Instance) End If End Sub @@ -1185,7 +1185,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ' Consider: should we allow to OSS sign if the key file only contains public key? If DeclaringCompilation.Options.OutputKind <> OutputKind.NetModule AndAlso - DeclaringCompilation.Options.CryptoPublicKey.IsDefault AndAlso + DeclaringCompilation.Options.CryptoPublicKey.IsEmpty AndAlso Identity.HasPublicKey AndAlso Not IsDelaySigned AndAlso Not StrongNameKeys.CanSign Then diff --git a/src/Compilers/VisualBasic/Portable/VisualBasicCompilationOptions.vb b/src/Compilers/VisualBasic/Portable/VisualBasicCompilationOptions.vb index 93bd27741d66d..3b0cc25b73aea 100644 --- a/src/Compilers/VisualBasic/Portable/VisualBasicCompilationOptions.vb +++ b/src/Compilers/VisualBasic/Portable/VisualBasicCompilationOptions.vb @@ -587,6 +587,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ''' The cryptography key file path. ''' A new instance of VisualBasicCompilationOptions, if the public key is different; otherwise current instance. Public Shadows Function WithCryptoPublicKey(value As ImmutableArray(Of Byte)) As VisualBasicCompilationOptions + If value.IsDefault Then + value = ImmutableArray(Of Byte).Empty + End If + If value = Me.CryptoPublicKey Then Return Me End If @@ -839,7 +843,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ' (kind == 'arm' || kind == 'appcontainer' || kind == 'winmdobj') && ' (version >= "6.2") - If Not CryptoPublicKey.IsDefault Then + If Not CryptoPublicKey.IsEmpty Then If CryptoKeyFile IsNot Nothing Then builder.Add(Diagnostic.Create(MessageProvider.Instance, ERRID.ERR_MutuallyExclusiveOptions, NameOf(CryptoPublicKey), NameOf(CryptoKeyFile))) End If diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/VisualBasicCompilationOptionsTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/VisualBasicCompilationOptionsTests.vb index 180a1a3f67ea2..d3432a98afc30 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/VisualBasicCompilationOptionsTests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/VisualBasicCompilationOptionsTests.vb @@ -558,5 +558,16 @@ BC2042: The options /vbruntime* and /target:module cannot be combined. deserializedCompilationOptions.ExtendedCustomDebugInformation) End Sub + + Public Sub WithCryptoPublicKey() + Dim options = New VisualBasicCompilationOptions(OutputKind.ConsoleApplication) + + Assert.Equal(ImmutableArray(Of Byte).Empty, options.CryptoPublicKey) + Assert.Equal(ImmutableArray(Of Byte).Empty, options.WithCryptoPublicKey(Nothing).CryptoPublicKey) + + Assert.Same(options, options.WithCryptoPublicKey(Nothing)) + Assert.Same(options, options.WithCryptoPublicKey(ImmutableArray(Of Byte).Empty)) + End Sub + End Class End Namespace