diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs
index 3d389c9a84c..50d406dc934 100644
--- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs
+++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/AddType.cs
@@ -2,29 +2,27 @@
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
-#region Using directives
-
using System;
using System.Collections.Generic;
+using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
+using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Reflection;
+using System.Security;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
-using System.IO;
using Microsoft.CodeAnalysis.Emit;
-using System.Collections.Immutable;
-using System.Security;
+
using PathType = System.IO.Path;
-#endregion
namespace Microsoft.PowerShell.Commands
{
@@ -143,14 +141,15 @@ public class AddTypeCompilerError
}
///
- /// Base class that contains logic for Add-Type cmdlet based on
- /// - CodeDomProvider
- /// - CodeAnalysis(Roslyn)
+ /// Adds a new type to the Application Domain.
+ /// This version is based on CodeAnalysis (Roslyn).
///
- public abstract class AddTypeCommandBase : PSCmdlet
+ [Cmdlet(VerbsCommon.Add, "Type", DefaultParameterSetName = "FromSource", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135195")]
+ [OutputType(typeof(Type))]
+ public sealed class AddTypeCommand : PSCmdlet
{
///
- /// The source code of this type
+ /// The source code of this type.
///
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromSource")]
public String TypeDefinition
@@ -166,13 +165,13 @@ public String TypeDefinition
}
///
- /// The name of the type used for auto-generated types
+ /// The name of the type used for auto-generated types.
///
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromMember")]
public String Name { get; set; }
///
- /// The source code of this method / member
+ /// The source code of this method / member.
///
[Parameter(Mandatory = true, Position = 1, ParameterSetName = "FromMember")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
@@ -188,19 +187,15 @@ public String[] MemberDefinition
if (value != null)
{
- for (int counter = 0; counter < value.Length; counter++)
- {
- sourceCode += value[counter] + "\n";
- }
+ sourceCode = String.Join("\n", value);
}
}
}
internal String sourceCode;
-
///
- /// The namespaced used for the auto-generated type
+ /// The namespaced used for the auto-generated type.
///
[Parameter(ParameterSetName = "FromMember")]
[Alias("NS")]
@@ -213,26 +208,22 @@ public String Namespace
}
set
{
- typeNamespace = value;
- if (typeNamespace != null)
- {
- typeNamespace = typeNamespace.Trim();
- }
+ typeNamespace = value?.Trim();
}
}
+
internal string typeNamespace = "Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes";
///
- /// Any using statements required by the auto-generated type
+ /// Any using statements required by the auto-generated type.
///
[Parameter(ParameterSetName = "FromMember")]
[Alias("Using")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
public String[] UsingNamespace { get; set; } = Utils.EmptyArray();
-
///
- /// The path to the source code or DLL to load
+ /// The path to the source code or DLL to load.
///
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromPath")]
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
@@ -278,7 +269,7 @@ public string[] Path
}
///
- /// The literal path to the source code or DLL to load
+ /// The literal path to the source code or DLL to load.
///
[Parameter(Mandatory = true, ParameterSetName = "FromLiteralPath")]
[Alias("PSPath")]
@@ -377,7 +368,7 @@ private void ProcessPaths(List resolvedPaths)
internal string[] paths;
///
- /// The name of the assembly to load
+ /// The name of the assembly to load.
///
[Parameter(Mandatory = true, ParameterSetName = "FromAssemblyName")]
[Alias("AN")]
@@ -396,45 +387,17 @@ public String[] AssemblyName
}
internal String[] assemblyNames;
-
internal bool loadAssembly = false;
-
///
- /// The language used to generate source code
+ /// The language used to generate source code.
///
[Parameter(ParameterSetName = "FromSource")]
[Parameter(ParameterSetName = "FromMember")]
- public Language Language
- {
- get
- {
- return language;
- }
- set
- {
- language = value;
- languageSpecified = true;
-
- PostSetLanguage(language);
- }
- }
-
- ///
- /// Post-action for Language setter.
- ///
- ///
- internal virtual void PostSetLanguage(Language language)
- {
- }
-
-
- internal bool languageSpecified = false;
- internal Language language = Language.CSharp;
-
+ public Language Language { get; set; } = Language.CSharp;
///
- /// Any reference DLLs to use in the compilation
+ /// Any reference DLLs to use in the compilation.
///
[Parameter(ParameterSetName = "FromSource")]
[Parameter(ParameterSetName = "FromMember")]
@@ -453,7 +416,7 @@ public String[] ReferencedAssemblies
internal string[] referencedAssemblies = Utils.EmptyArray();
///
- /// The path to the output assembly
+ /// The path to the output assembly.
///
[Parameter(ParameterSetName = "FromSource")]
[Parameter(ParameterSetName = "FromMember")]
@@ -533,7 +496,7 @@ public string OutputAssembly
internal string outputAssembly = null;
///
- /// The output type of the assembly
+ /// The output type of the assembly.
///
[Parameter(ParameterSetName = "FromSource")]
[Parameter(ParameterSetName = "FromMember")]
@@ -557,40 +520,16 @@ public OutputAssemblyType OutputType
///
- /// Flag to pass the resulting types along
+ /// Flag to pass the resulting types along.
///
[Parameter()]
- public SwitchParameter PassThru
- {
- get
- {
- return passThru;
- }
- set
- {
- passThru = value;
- }
- }
- internal SwitchParameter passThru;
+ public SwitchParameter PassThru { get; set; }
///
- /// Flag to ignore warnings during compilation
+ /// Flag to ignore warnings during compilation.
///
[Parameter()]
- public SwitchParameter IgnoreWarnings
- {
- get
- {
- return ignoreWarnings;
- }
- set
- {
- ignoreWarnings = value;
- ignoreWarningsSpecified = true;
- }
- }
- internal bool ignoreWarningsSpecified;
- internal SwitchParameter ignoreWarnings;
+ public SwitchParameter IgnoreWarnings { get; set; }
internal string GenerateTypeSource(string typeNamespace, string name, string sourceCode, Language language)
{
@@ -757,62 +696,6 @@ internal string GetUsingSet(Language language)
return usingNamespaceSet.ToString();
}
- ///
- /// Perform common error checks.
- /// Populate source code.
- /// We only keep the code for backward compatibility.
- ///
- protected override void EndProcessing()
- {
- // Generate an error if they've specified an output
- // assembly type without an output assembly
- if (String.IsNullOrEmpty(outputAssembly) && outputTypeSpecified)
- {
- ErrorRecord errorRecord = new ErrorRecord(
- new Exception(
- String.Format(
- CultureInfo.CurrentCulture,
- AddTypeStrings.OutputTypeRequiresOutputAssembly)),
- "OUTPUTTYPE_REQUIRES_ASSEMBLY",
- ErrorCategory.InvalidArgument,
- outputType);
-
- ThrowTerminatingError(errorRecord);
- return;
- }
-
- PopulateSource();
- }
-
- // We only keep the code for backward compatibility.
- internal void PopulateSource()
- {
- // Prevent code compilation in ConstrainedLanguage mode
- if (SessionState.LanguageMode == PSLanguageMode.ConstrainedLanguage)
- {
- ThrowTerminatingError(
- new ErrorRecord(
- new PSNotSupportedException(AddTypeStrings.CannotDefineNewType), "CannotDefineNewType", ErrorCategory.PermissionDenied, null));
- }
-
- // Load the source if they want to load from a file
- if (String.Equals(ParameterSetName, "FromPath", StringComparison.OrdinalIgnoreCase) ||
- String.Equals(ParameterSetName, "FromLiteralPath", StringComparison.OrdinalIgnoreCase)
- )
- {
- sourceCode = "";
- foreach (string file in paths)
- {
- sourceCode += System.IO.File.ReadAllText(file) + "\n";
- }
- }
-
- if (String.Equals(ParameterSetName, "FromMember", StringComparison.OrdinalIgnoreCase))
- {
- sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, language);
- }
- }
-
internal void HandleCompilerErrors(AddTypeCompilerError[] compilerErrors)
{
// Get the source code that corresponds to their type in the case of errors
@@ -898,20 +781,11 @@ private void OutputError(AddTypeCompilerError error, string[] actualSource)
WriteError(errorRecord);
}
}
- }
- ///
- /// Adds a new type to the Application Domain.
- /// This version is based on CodeAnalysis (Roslyn).
- ///
- [Cmdlet(VerbsCommon.Add, "Type", DefaultParameterSetName = "FromSource", HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135195")]
- [OutputType(typeof(Type))]
- public sealed class AddTypeCommand : AddTypeCommandBase
- {
private static Dictionary s_sourceCache = new Dictionary();
///
- /// Generate the type(s)
+ /// Generate the type(s).
///
protected override void EndProcessing()
{
@@ -985,7 +859,7 @@ protected override void EndProcessing()
}
else if (String.Equals(ParameterSetName, "FromMember", StringComparison.OrdinalIgnoreCase))
{
- sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, language);
+ sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, Language);
}
CompileSourceToAssembly(this.sourceCode);
@@ -1004,7 +878,7 @@ private void LoadAssemblies(IEnumerable assemblies)
assembly = Assembly.LoadFrom(ResolveAssemblyName(assemblyName, false));
}
- if (passThru)
+ if (PassThru)
{
WriteTypes(assembly);
}
@@ -1232,9 +1106,9 @@ private void WriteTypes(Assembly assembly)
private void CompileSourceToAssembly(string source)
{
CSharpParseOptions parseOptions;
- if (IsCSharp(language))
+ if (IsCSharp(Language))
{
- switch (language)
+ switch (Language)
{
case Language.CSharpVersion1:
parseOptions = new CSharpParseOptions(LanguageVersion.CSharp1);
@@ -1268,10 +1142,10 @@ private void CompileSourceToAssembly(string source)
else
{
ErrorRecord errorRecord = new ErrorRecord(
- new Exception(String.Format(CultureInfo.CurrentCulture, AddTypeStrings.SpecialNetVersionRequired, language.ToString(), string.Empty)),
+ new Exception(String.Format(CultureInfo.CurrentCulture, AddTypeStrings.SpecialNetVersionRequired, Language.ToString(), string.Empty)),
"LANGUAGE_NOT_SUPPORTED",
ErrorCategory.InvalidArgument,
- language);
+ Language);
ThrowTerminatingError(errorRecord);
parseOptions = null;
@@ -1318,7 +1192,7 @@ private void CompileSourceToAssembly(string source)
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(ms.ToArray());
CheckTypesForDuplicates(assembly);
- if (passThru)
+ if (PassThru)
{
WriteTypes(assembly);
}
@@ -1330,7 +1204,7 @@ private void CompileSourceToAssembly(string source)
emitResult = compilation.Emit(outputAssembly);
if (emitResult.Success)
{
- if (passThru)
+ if (PassThru)
{
Assembly assembly = Assembly.LoadFrom(outputAssembly);
CheckTypesForDuplicates(assembly);