From c7f782546d79493da235525eaca6a5ea903bc6ca Mon Sep 17 00:00:00 2001 From: Ilya Date: Wed, 15 May 2019 14:03:10 +0500 Subject: [PATCH 1/4] Block type update in Add-Type cmdlet --- .../commands/utility/AddType.cs | 20 +++++-------------- .../Add-Type.Tests.ps1 | 8 +++++++- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs index 20cca320883..818f87b234a 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs @@ -625,7 +625,7 @@ protected override void EndProcessing() // These dictionaries prevent reloading already loaded and unchanged code. // We don't worry about unbounded growing of the cache because in .Net Core 2.0 we can not unload assemblies. // TODO: review if we will be able to unload assemblies after migrating to .Net Core 2.1. - private static readonly Dictionary s_sourceTypesCache = new Dictionary(); + private static readonly HashSet s_sourceTypesCache = new HashSet(); private static readonly Dictionary s_sourceAssemblyCache = new Dictionary(); private static readonly string s_defaultSdkDirectory = Utils.DefaultPowerShellAppBase; @@ -1052,7 +1052,7 @@ private void CompileToAssembly(List syntaxTrees, CompilationOptions private void CheckDuplicateTypes(Compilation compilation, out ConcurrentBag newTypes) { - AllNamedTypeSymbolsVisitor visitor = new AllNamedTypeSymbolsVisitor(_syntaxTreesHash); + AllNamedTypeSymbolsVisitor visitor = new AllNamedTypeSymbolsVisitor(); visitor.Visit(compilation.Assembly.GlobalNamespace); foreach (var symbolName in visitor.DuplicateSymbols) @@ -1084,16 +1084,9 @@ private void CheckDuplicateTypes(Compilation compilation, out ConcurrentBag DuplicateSymbols = new ConcurrentBag(); public readonly ConcurrentBag UniqueSymbols = new ConcurrentBag(); - public AllNamedTypeSymbolsVisitor(int hash) - { - _hash = hash; - } - public override void VisitNamespace(INamespaceSymbol symbol) { // Main cycle. @@ -1109,12 +1102,9 @@ public override void VisitNamedType(INamedTypeSymbol symbol) // It is namespace-fully-qualified name var symbolFullName = symbol.ToString(); - if (s_sourceTypesCache.TryGetValue(symbolFullName, out int hash)) + if (s_sourceTypesCache.TryGetValue(symbolFullName, out _)) { - if (hash == _hash) - { - DuplicateSymbols.Add(symbolFullName); - } + DuplicateSymbols.Add(symbolFullName); } else { @@ -1127,7 +1117,7 @@ private void CacheNewTypes(ConcurrentBag newTypes) { foreach (var typeName in newTypes) { - s_sourceTypesCache.Add(typeName, _syntaxTreesHash); + s_sourceTypesCache.Add(typeName); } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 index 20ed4b0afad..4591acdd488 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 @@ -65,7 +65,7 @@ Describe "Add-Type" -Tags "CI" { $code = @" using System.Management.Automation; [System.Management.Automation.Cmdlet("Get", "Thing$guid", ConfirmImpact = System.Management.Automation.ConfirmImpact.High, SupportsPaging = true)] -public class AttributeTest$guid : PSCmdlet +public class SMAAttributeTest$guid : PSCmdlet { protected override void EndProcessing() @@ -207,6 +207,12 @@ public class AttributeTest$guid : PSCmdlet { Add-Type -CompilerOptions "/platform:anycpuERROR" -Language CSharp -MemberDefinition "public static string TestString() { return ""}" -Name "TestType1" -Namespace "TestNS" -ErrorAction Stop } | Should -Throw -ErrorId "SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand" } + It "Throw if the type already exists" { + Add-Type -TypeDefinition "public class Foo$guid {}" + { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand" + $error[1].FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand" + } + It "OutputType parameter requires that the OutputAssembly parameter be specified." { $code = "public static string TestString() {}" { Add-Type -TypeDefinition $code -OutputType Library } | Should -Throw -ErrorId "OUTPUTTYPE_REQUIRES_ASSEMBLY,Microsoft.PowerShell.Commands.AddTypeCommand" From a813d5b99f58b69aa31b950251c751c9752160ff Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 9 Jul 2019 11:26:24 +0500 Subject: [PATCH 2/4] Use -PassThru in test --- .../Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 index 4591acdd488..16bd8d3e52e 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 @@ -209,8 +209,8 @@ public class AttributeTest$guid : PSCmdlet It "Throw if the type already exists" { Add-Type -TypeDefinition "public class Foo$guid {}" - { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand" - $error[1].FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand" + $exc = { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -PassThru -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand" + $exc.FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand" } It "OutputType parameter requires that the OutputAssembly parameter be specified." { From 5bb086b520e3d64d019c4b7ff8c777e4534a7457 Mon Sep 17 00:00:00 2001 From: Ilya Date: Tue, 9 Jul 2019 11:54:08 +0500 Subject: [PATCH 3/4] Revert "Use -PassThru in test" This reverts commit a813d5b99f58b69aa31b950251c751c9752160ff. --- .../Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 index 16bd8d3e52e..4591acdd488 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 @@ -209,8 +209,8 @@ public class AttributeTest$guid : PSCmdlet It "Throw if the type already exists" { Add-Type -TypeDefinition "public class Foo$guid {}" - $exc = { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -PassThru -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand" - $exc.FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand" + { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand" + $error[1].FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand" } It "OutputType parameter requires that the OutputAssembly parameter be specified." { From 1eee5c50647224f8de17b164448706857d0753d3 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 26 Jul 2019 10:23:38 +0500 Subject: [PATCH 4/4] Add comment --- .../Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 index 4591acdd488..6d0fadbc69b 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Add-Type.Tests.ps1 @@ -1,5 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. + Describe "Add-Type" -Tags "CI" { BeforeAll { $guid = [Guid]::NewGuid().ToString().Replace("-","") @@ -209,6 +210,9 @@ public class AttributeTest$guid : PSCmdlet It "Throw if the type already exists" { Add-Type -TypeDefinition "public class Foo$guid {}" + + # The cmdlet writes TYPE_ALREADY_EXISTS for every duplicated type and then terminates with COMPILER_ERRORS. + # So here we check 2 errors. { Add-Type -TypeDefinition "public class Foo$guid { public int Bar {get {return 42;} }" -ErrorAction SilentlyContinue } | Should -Throw -ErrorId "COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand" $error[1].FullyQualifiedErrorId | Should -BeExactly "TYPE_ALREADY_EXISTS,Microsoft.PowerShell.Commands.AddTypeCommand" }