Remove AddTypeCommandBase class (#5407)
It is technically a breaking change but it is only a public api surface of a cmdlet _implementation_ and don't documented class.
This commit is contained in:
parent
381134ba59
commit
7e3a2a23e4
|
@ -2,29 +2,27 @@
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
--********************************************************************/
|
--********************************************************************/
|
||||||
|
|
||||||
#region Using directives
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Management.Automation;
|
using System.Management.Automation;
|
||||||
using System.Management.Automation.Internal;
|
using System.Management.Automation.Internal;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Security;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
using Microsoft.CodeAnalysis;
|
using Microsoft.CodeAnalysis;
|
||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using System.IO;
|
|
||||||
using Microsoft.CodeAnalysis.Emit;
|
using Microsoft.CodeAnalysis.Emit;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Security;
|
|
||||||
using PathType = System.IO.Path;
|
using PathType = System.IO.Path;
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace Microsoft.PowerShell.Commands
|
namespace Microsoft.PowerShell.Commands
|
||||||
{
|
{
|
||||||
|
@ -143,14 +141,15 @@ namespace Microsoft.PowerShell.Commands
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Base class that contains logic for Add-Type cmdlet based on
|
/// Adds a new type to the Application Domain.
|
||||||
/// - CodeDomProvider
|
/// This version is based on CodeAnalysis (Roslyn).
|
||||||
/// - CodeAnalysis(Roslyn)
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The source code of this type
|
/// The source code of this type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromSource")]
|
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromSource")]
|
||||||
public String TypeDefinition
|
public String TypeDefinition
|
||||||
|
@ -166,13 +165,13 @@ namespace Microsoft.PowerShell.Commands
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the type used for auto-generated types
|
/// The name of the type used for auto-generated types.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromMember")]
|
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromMember")]
|
||||||
public String Name { get; set; }
|
public String Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The source code of this method / member
|
/// The source code of this method / member.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(Mandatory = true, Position = 1, ParameterSetName = "FromMember")]
|
[Parameter(Mandatory = true, Position = 1, ParameterSetName = "FromMember")]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||||
|
@ -188,19 +187,15 @@ namespace Microsoft.PowerShell.Commands
|
||||||
|
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
for (int counter = 0; counter < value.Length; counter++)
|
sourceCode = String.Join("\n", value);
|
||||||
{
|
|
||||||
sourceCode += value[counter] + "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String sourceCode;
|
internal String sourceCode;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The namespaced used for the auto-generated type
|
/// The namespaced used for the auto-generated type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(ParameterSetName = "FromMember")]
|
[Parameter(ParameterSetName = "FromMember")]
|
||||||
[Alias("NS")]
|
[Alias("NS")]
|
||||||
|
@ -213,26 +208,22 @@ namespace Microsoft.PowerShell.Commands
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
typeNamespace = value;
|
typeNamespace = value?.Trim();
|
||||||
if (typeNamespace != null)
|
|
||||||
{
|
|
||||||
typeNamespace = typeNamespace.Trim();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal string typeNamespace = "Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes";
|
internal string typeNamespace = "Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Any using statements required by the auto-generated type
|
/// Any using statements required by the auto-generated type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(ParameterSetName = "FromMember")]
|
[Parameter(ParameterSetName = "FromMember")]
|
||||||
[Alias("Using")]
|
[Alias("Using")]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||||
public String[] UsingNamespace { get; set; } = Utils.EmptyArray<string>();
|
public String[] UsingNamespace { get; set; } = Utils.EmptyArray<string>();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path to the source code or DLL to load
|
/// The path to the source code or DLL to load.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromPath")]
|
[Parameter(Mandatory = true, Position = 0, ParameterSetName = "FromPath")]
|
||||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||||
|
@ -278,7 +269,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The literal path to the source code or DLL to load
|
/// The literal path to the source code or DLL to load.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(Mandatory = true, ParameterSetName = "FromLiteralPath")]
|
[Parameter(Mandatory = true, ParameterSetName = "FromLiteralPath")]
|
||||||
[Alias("PSPath")]
|
[Alias("PSPath")]
|
||||||
|
@ -377,7 +368,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
internal string[] paths;
|
internal string[] paths;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the assembly to load
|
/// The name of the assembly to load.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(Mandatory = true, ParameterSetName = "FromAssemblyName")]
|
[Parameter(Mandatory = true, ParameterSetName = "FromAssemblyName")]
|
||||||
[Alias("AN")]
|
[Alias("AN")]
|
||||||
|
@ -396,45 +387,17 @@ namespace Microsoft.PowerShell.Commands
|
||||||
}
|
}
|
||||||
|
|
||||||
internal String[] assemblyNames;
|
internal String[] assemblyNames;
|
||||||
|
|
||||||
internal bool loadAssembly = false;
|
internal bool loadAssembly = false;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The language used to generate source code
|
/// The language used to generate source code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(ParameterSetName = "FromSource")]
|
[Parameter(ParameterSetName = "FromSource")]
|
||||||
[Parameter(ParameterSetName = "FromMember")]
|
[Parameter(ParameterSetName = "FromMember")]
|
||||||
public Language Language
|
public Language Language { get; set; } = Language.CSharp;
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return language;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
language = value;
|
|
||||||
languageSpecified = true;
|
|
||||||
|
|
||||||
PostSetLanguage(language);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Post-action for Language setter.
|
/// Any reference DLLs to use in the compilation.
|
||||||
/// </summary>
|
|
||||||
/// <param name="language"></param>
|
|
||||||
internal virtual void PostSetLanguage(Language language)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal bool languageSpecified = false;
|
|
||||||
internal Language language = Language.CSharp;
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Any reference DLLs to use in the compilation
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(ParameterSetName = "FromSource")]
|
[Parameter(ParameterSetName = "FromSource")]
|
||||||
[Parameter(ParameterSetName = "FromMember")]
|
[Parameter(ParameterSetName = "FromMember")]
|
||||||
|
@ -453,7 +416,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
internal string[] referencedAssemblies = Utils.EmptyArray<string>();
|
internal string[] referencedAssemblies = Utils.EmptyArray<string>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path to the output assembly
|
/// The path to the output assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(ParameterSetName = "FromSource")]
|
[Parameter(ParameterSetName = "FromSource")]
|
||||||
[Parameter(ParameterSetName = "FromMember")]
|
[Parameter(ParameterSetName = "FromMember")]
|
||||||
|
@ -533,7 +496,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
internal string outputAssembly = null;
|
internal string outputAssembly = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The output type of the assembly
|
/// The output type of the assembly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter(ParameterSetName = "FromSource")]
|
[Parameter(ParameterSetName = "FromSource")]
|
||||||
[Parameter(ParameterSetName = "FromMember")]
|
[Parameter(ParameterSetName = "FromMember")]
|
||||||
|
@ -557,40 +520,16 @@ namespace Microsoft.PowerShell.Commands
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Flag to pass the resulting types along
|
/// Flag to pass the resulting types along.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter()]
|
[Parameter()]
|
||||||
public SwitchParameter PassThru
|
public SwitchParameter PassThru { get; set; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return passThru;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
passThru = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal SwitchParameter passThru;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Flag to ignore warnings during compilation
|
/// Flag to ignore warnings during compilation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Parameter()]
|
[Parameter()]
|
||||||
public SwitchParameter IgnoreWarnings
|
public SwitchParameter IgnoreWarnings { get; set; }
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return ignoreWarnings;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
ignoreWarnings = value;
|
|
||||||
ignoreWarningsSpecified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal bool ignoreWarningsSpecified;
|
|
||||||
internal SwitchParameter ignoreWarnings;
|
|
||||||
|
|
||||||
internal string GenerateTypeSource(string typeNamespace, string name, string sourceCode, Language language)
|
internal string GenerateTypeSource(string typeNamespace, string name, string sourceCode, Language language)
|
||||||
{
|
{
|
||||||
|
@ -757,62 +696,6 @@ namespace Microsoft.PowerShell.Commands
|
||||||
return usingNamespaceSet.ToString();
|
return usingNamespaceSet.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Perform common error checks.
|
|
||||||
/// Populate source code.
|
|
||||||
/// We only keep the code for backward compatibility.
|
|
||||||
/// </summary>
|
|
||||||
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)
|
internal void HandleCompilerErrors(AddTypeCompilerError[] compilerErrors)
|
||||||
{
|
{
|
||||||
// Get the source code that corresponds to their type in the case of errors
|
// Get the source code that corresponds to their type in the case of errors
|
||||||
|
@ -898,20 +781,11 @@ namespace Microsoft.PowerShell.Commands
|
||||||
WriteError(errorRecord);
|
WriteError(errorRecord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds a new type to the Application Domain.
|
|
||||||
/// This version is based on CodeAnalysis (Roslyn).
|
|
||||||
/// </summary>
|
|
||||||
[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<string, int> s_sourceCache = new Dictionary<string, int>();
|
private static Dictionary<string, int> s_sourceCache = new Dictionary<string, int>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate the type(s)
|
/// Generate the type(s).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void EndProcessing()
|
protected override void EndProcessing()
|
||||||
{
|
{
|
||||||
|
@ -985,7 +859,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
}
|
}
|
||||||
else if (String.Equals(ParameterSetName, "FromMember", StringComparison.OrdinalIgnoreCase))
|
else if (String.Equals(ParameterSetName, "FromMember", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, language);
|
sourceCode = GenerateTypeSource(typeNamespace, Name, sourceCode, Language);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompileSourceToAssembly(this.sourceCode);
|
CompileSourceToAssembly(this.sourceCode);
|
||||||
|
@ -1004,7 +878,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
assembly = Assembly.LoadFrom(ResolveAssemblyName(assemblyName, false));
|
assembly = Assembly.LoadFrom(ResolveAssemblyName(assemblyName, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (passThru)
|
if (PassThru)
|
||||||
{
|
{
|
||||||
WriteTypes(assembly);
|
WriteTypes(assembly);
|
||||||
}
|
}
|
||||||
|
@ -1232,9 +1106,9 @@ namespace Microsoft.PowerShell.Commands
|
||||||
private void CompileSourceToAssembly(string source)
|
private void CompileSourceToAssembly(string source)
|
||||||
{
|
{
|
||||||
CSharpParseOptions parseOptions;
|
CSharpParseOptions parseOptions;
|
||||||
if (IsCSharp(language))
|
if (IsCSharp(Language))
|
||||||
{
|
{
|
||||||
switch (language)
|
switch (Language)
|
||||||
{
|
{
|
||||||
case Language.CSharpVersion1:
|
case Language.CSharpVersion1:
|
||||||
parseOptions = new CSharpParseOptions(LanguageVersion.CSharp1);
|
parseOptions = new CSharpParseOptions(LanguageVersion.CSharp1);
|
||||||
|
@ -1268,10 +1142,10 @@ namespace Microsoft.PowerShell.Commands
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ErrorRecord errorRecord = new ErrorRecord(
|
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",
|
"LANGUAGE_NOT_SUPPORTED",
|
||||||
ErrorCategory.InvalidArgument,
|
ErrorCategory.InvalidArgument,
|
||||||
language);
|
Language);
|
||||||
|
|
||||||
ThrowTerminatingError(errorRecord);
|
ThrowTerminatingError(errorRecord);
|
||||||
parseOptions = null;
|
parseOptions = null;
|
||||||
|
@ -1318,7 +1192,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
ms.Seek(0, SeekOrigin.Begin);
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
Assembly assembly = Assembly.Load(ms.ToArray());
|
Assembly assembly = Assembly.Load(ms.ToArray());
|
||||||
CheckTypesForDuplicates(assembly);
|
CheckTypesForDuplicates(assembly);
|
||||||
if (passThru)
|
if (PassThru)
|
||||||
{
|
{
|
||||||
WriteTypes(assembly);
|
WriteTypes(assembly);
|
||||||
}
|
}
|
||||||
|
@ -1330,7 +1204,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
emitResult = compilation.Emit(outputAssembly);
|
emitResult = compilation.Emit(outputAssembly);
|
||||||
if (emitResult.Success)
|
if (emitResult.Success)
|
||||||
{
|
{
|
||||||
if (passThru)
|
if (PassThru)
|
||||||
{
|
{
|
||||||
Assembly assembly = Assembly.LoadFrom(outputAssembly);
|
Assembly assembly = Assembly.LoadFrom(outputAssembly);
|
||||||
CheckTypesForDuplicates(assembly);
|
CheckTypesForDuplicates(assembly);
|
||||||
|
|
Loading…
Reference in a new issue