22Copyright (c) Microsoft Corporation. All rights reserved.
33--********************************************************************/
44
5- #region Using directives
6-
75using System ;
86
97using System . Collections . Generic ;
8+ using System . Collections . Immutable ;
109using System . Collections . ObjectModel ;
1110using System . Diagnostics . CodeAnalysis ;
1211using System . Globalization ;
12+ using System . IO ;
1313using System . Linq ;
1414using System . Management . Automation ;
1515using System . Management . Automation . Internal ;
1616using System . Reflection ;
17+ using System . Security ;
1718using System . Text ;
1819
1920using Microsoft . CodeAnalysis ;
2021using Microsoft . CodeAnalysis . CSharp ;
21- using System . IO ;
2222using Microsoft . CodeAnalysis . Emit ;
23- using System . Collections . Immutable ;
24- using System . Security ;
23+
2524using PathType = System . IO . Path ;
2625
27- #endregion
2826
2927namespace Microsoft . PowerShell . Commands
3028{
@@ -143,14 +141,15 @@ public class AddTypeCompilerError
143141 }
144142
145143 /// <summary>
146- /// Base class that contains logic for Add-Type cmdlet based on
147- /// - CodeDomProvider
148- /// - CodeAnalysis(Roslyn)
144+ /// Adds a new type to the Application Domain.
145+ /// This version is based on CodeAnalysis (Roslyn).
149146 /// </summary>
150- public abstract class AddTypeCommandBase : PSCmdlet
147+ [ Cmdlet ( VerbsCommon . Add , "Type" , DefaultParameterSetName = "FromSource" , HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135195" ) ]
148+ [ OutputType ( typeof ( Type ) ) ]
149+ public sealed class AddTypeCommand : PSCmdlet
151150 {
152151 /// <summary>
153- /// The source code of this type
152+ /// The source code of this type.
154153 /// </summary>
155154 [ Parameter ( Mandatory = true , Position = 0 , ParameterSetName = "FromSource" ) ]
156155 public String TypeDefinition
@@ -166,13 +165,13 @@ public String TypeDefinition
166165 }
167166
168167 /// <summary>
169- /// The name of the type used for auto-generated types
168+ /// The name of the type used for auto-generated types.
170169 /// </summary>
171170 [ Parameter ( Mandatory = true , Position = 0 , ParameterSetName = "FromMember" ) ]
172171 public String Name { get ; set ; }
173172
174173 /// <summary>
175- /// The source code of this method / member
174+ /// The source code of this method / member.
176175 /// </summary>
177176 [ Parameter ( Mandatory = true , Position = 1 , ParameterSetName = "FromMember" ) ]
178177 [ SuppressMessage ( "Microsoft.Performance" , "CA1819:PropertiesShouldNotReturnArrays" ) ]
@@ -188,6 +187,7 @@ public String[] MemberDefinition
188187
189188 if ( value != null )
190189 {
190+ String . Join ( "\n " , value ) ;
191191 for ( int counter = 0 ; counter < value . Length ; counter ++ )
192192 {
193193 sourceCode += value [ counter ] + "\n " ;
@@ -198,9 +198,8 @@ public String[] MemberDefinition
198198
199199 internal String sourceCode ;
200200
201-
202201 /// <summary>
203- /// The namespaced used for the auto-generated type
202+ /// The namespaced used for the auto-generated type.
204203 /// </summary>
205204 [ Parameter ( ParameterSetName = "FromMember" ) ]
206205 [ Alias ( "NS" ) ]
@@ -213,26 +212,22 @@ public String Namespace
213212 }
214213 set
215214 {
216- typeNamespace = value ;
217- if ( typeNamespace != null )
218- {
219- typeNamespace = typeNamespace . Trim ( ) ;
220- }
215+ typeNamespace = value ? . Trim ( ) ;
221216 }
222217 }
218+
223219 internal string typeNamespace = "Microsoft.PowerShell.Commands.AddType.AutoGeneratedTypes" ;
224220
225221 /// <summary>
226- /// Any using statements required by the auto-generated type
222+ /// Any using statements required by the auto-generated type.
227223 /// </summary>
228224 [ Parameter ( ParameterSetName = "FromMember" ) ]
229225 [ Alias ( "Using" ) ]
230226 [ SuppressMessage ( "Microsoft.Performance" , "CA1819:PropertiesShouldNotReturnArrays" ) ]
231227 public String [ ] UsingNamespace { get ; set ; } = Utils . EmptyArray < string > ( ) ;
232228
233-
234229 /// <summary>
235- /// The path to the source code or DLL to load
230+ /// The path to the source code or DLL to load.
236231 /// </summary>
237232 [ Parameter ( Mandatory = true , Position = 0 , ParameterSetName = "FromPath" ) ]
238233 [ SuppressMessage ( "Microsoft.Performance" , "CA1819:PropertiesShouldNotReturnArrays" ) ]
@@ -278,7 +273,7 @@ public string[] Path
278273 }
279274
280275 /// <summary>
281- /// The literal path to the source code or DLL to load
276+ /// The literal path to the source code or DLL to load.
282277 /// </summary>
283278 [ Parameter ( Mandatory = true , ParameterSetName = "FromLiteralPath" ) ]
284279 [ Alias ( "PSPath" ) ]
@@ -377,7 +372,7 @@ private void ProcessPaths(List<string> resolvedPaths)
377372 internal string [ ] paths ;
378373
379374 /// <summary>
380- /// The name of the assembly to load
375+ /// The name of the assembly to load.
381376 /// </summary>
382377 [ Parameter ( Mandatory = true , ParameterSetName = "FromAssemblyName" ) ]
383378 [ Alias ( "AN" ) ]
@@ -396,45 +391,17 @@ public String[] AssemblyName
396391 }
397392
398393 internal String [ ] assemblyNames ;
399-
400394 internal bool loadAssembly = false ;
401395
402-
403396 /// <summary>
404- /// The language used to generate source code
397+ /// The language used to generate source code.
405398 /// </summary>
406399 [ Parameter ( ParameterSetName = "FromSource" ) ]
407400 [ Parameter ( ParameterSetName = "FromMember" ) ]
408- public Language Language
409- {
410- get
411- {
412- return language ;
413- }
414- set
415- {
416- language = value ;
417- languageSpecified = true ;
418-
419- PostSetLanguage ( language ) ;
420- }
421- }
422-
423- /// <summary>
424- /// Post-action for Language setter.
425- /// </summary>
426- /// <param name="language"></param>
427- internal virtual void PostSetLanguage ( Language language )
428- {
429- }
430-
431-
432- internal bool languageSpecified = false ;
433- internal Language language = Language . CSharp ;
434-
401+ public Language Language { get ; set ; } = Language . CSharp ;
435402
436403 /// <summary>
437- /// Any reference DLLs to use in the compilation
404+ /// Any reference DLLs to use in the compilation.
438405 /// </summary>
439406 [ Parameter ( ParameterSetName = "FromSource" ) ]
440407 [ Parameter ( ParameterSetName = "FromMember" ) ]
@@ -453,7 +420,7 @@ public String[] ReferencedAssemblies
453420 internal string [ ] referencedAssemblies = Utils . EmptyArray < string > ( ) ;
454421
455422 /// <summary>
456- /// The path to the output assembly
423+ /// The path to the output assembly.
457424 /// </summary>
458425 [ Parameter ( ParameterSetName = "FromSource" ) ]
459426 [ Parameter ( ParameterSetName = "FromMember" ) ]
@@ -533,7 +500,7 @@ public string OutputAssembly
533500 internal string outputAssembly = null ;
534501
535502 /// <summary>
536- /// The output type of the assembly
503+ /// The output type of the assembly.
537504 /// </summary>
538505 [ Parameter ( ParameterSetName = "FromSource" ) ]
539506 [ Parameter ( ParameterSetName = "FromMember" ) ]
@@ -557,40 +524,16 @@ public OutputAssemblyType OutputType
557524
558525
559526 /// <summary>
560- /// Flag to pass the resulting types along
527+ /// Flag to pass the resulting types along.
561528 /// </summary>
562529 [ Parameter ( ) ]
563- public SwitchParameter PassThru
564- {
565- get
566- {
567- return passThru ;
568- }
569- set
570- {
571- passThru = value ;
572- }
573- }
574- internal SwitchParameter passThru ;
530+ public SwitchParameter PassThru { get ; set ; }
575531
576532 /// <summary>
577- /// Flag to ignore warnings during compilation
533+ /// Flag to ignore warnings during compilation.
578534 /// </summary>
579535 [ Parameter ( ) ]
580- public SwitchParameter IgnoreWarnings
581- {
582- get
583- {
584- return ignoreWarnings ;
585- }
586- set
587- {
588- ignoreWarnings = value ;
589- ignoreWarningsSpecified = true ;
590- }
591- }
592- internal bool ignoreWarningsSpecified ;
593- internal SwitchParameter ignoreWarnings ;
536+ public SwitchParameter IgnoreWarnings { get ; set ; }
594537
595538 internal string GenerateTypeSource ( string typeNamespace , string name , string sourceCode , Language language )
596539 {
@@ -757,62 +700,6 @@ internal string GetUsingSet(Language language)
757700 return usingNamespaceSet . ToString ( ) ;
758701 }
759702
760- /// <summary>
761- /// Perform common error checks.
762- /// Populate source code.
763- /// We only keep the code for backward compatibility.
764- /// </summary>
765- protected override void EndProcessing ( )
766- {
767- // Generate an error if they've specified an output
768- // assembly type without an output assembly
769- if ( String . IsNullOrEmpty ( outputAssembly ) && outputTypeSpecified )
770- {
771- ErrorRecord errorRecord = new ErrorRecord (
772- new Exception (
773- String . Format (
774- CultureInfo . CurrentCulture ,
775- AddTypeStrings . OutputTypeRequiresOutputAssembly ) ) ,
776- "OUTPUTTYPE_REQUIRES_ASSEMBLY" ,
777- ErrorCategory . InvalidArgument ,
778- outputType ) ;
779-
780- ThrowTerminatingError ( errorRecord ) ;
781- return ;
782- }
783-
784- PopulateSource ( ) ;
785- }
786-
787- // We only keep the code for backward compatibility.
788- internal void PopulateSource ( )
789- {
790- // Prevent code compilation in ConstrainedLanguage mode
791- if ( SessionState . LanguageMode == PSLanguageMode . ConstrainedLanguage )
792- {
793- ThrowTerminatingError (
794- new ErrorRecord (
795- new PSNotSupportedException ( AddTypeStrings . CannotDefineNewType ) , "CannotDefineNewType" , ErrorCategory . PermissionDenied , null ) ) ;
796- }
797-
798- // Load the source if they want to load from a file
799- if ( String . Equals ( ParameterSetName , "FromPath" , StringComparison . OrdinalIgnoreCase ) ||
800- String . Equals ( ParameterSetName , "FromLiteralPath" , StringComparison . OrdinalIgnoreCase )
801- )
802- {
803- sourceCode = "" ;
804- foreach ( string file in paths )
805- {
806- sourceCode += System . IO . File . ReadAllText ( file ) + "\n " ;
807- }
808- }
809-
810- if ( String . Equals ( ParameterSetName , "FromMember" , StringComparison . OrdinalIgnoreCase ) )
811- {
812- sourceCode = GenerateTypeSource ( typeNamespace , Name , sourceCode , language ) ;
813- }
814- }
815-
816703 internal void HandleCompilerErrors ( AddTypeCompilerError [ ] compilerErrors )
817704 {
818705 // Get the source code that corresponds to their type in the case of errors
@@ -898,20 +785,11 @@ private void OutputError(AddTypeCompilerError error, string[] actualSource)
898785 WriteError ( errorRecord ) ;
899786 }
900787 }
901- }
902788
903- /// <summary>
904- /// Adds a new type to the Application Domain.
905- /// This version is based on CodeAnalysis (Roslyn).
906- /// </summary>
907- [ Cmdlet ( VerbsCommon . Add , "Type" , DefaultParameterSetName = "FromSource" , HelpUri = "https://go.microsoft.com/fwlink/?LinkID=135195" ) ]
908- [ OutputType ( typeof ( Type ) ) ]
909- public sealed class AddTypeCommand : AddTypeCommandBase
910- {
911789 private static Dictionary < string , int > s_sourceCache = new Dictionary < string , int > ( ) ;
912790
913791 /// <summary>
914- /// Generate the type(s)
792+ /// Generate the type(s).
915793 /// </summary>
916794 protected override void EndProcessing ( )
917795 {
@@ -985,7 +863,7 @@ protected override void EndProcessing()
985863 }
986864 else if ( String . Equals ( ParameterSetName , "FromMember" , StringComparison . OrdinalIgnoreCase ) )
987865 {
988- sourceCode = GenerateTypeSource ( typeNamespace , Name , sourceCode , language ) ;
866+ sourceCode = GenerateTypeSource ( typeNamespace , Name , sourceCode , Language ) ;
989867 }
990868
991869 CompileSourceToAssembly ( this . sourceCode ) ;
@@ -1004,7 +882,7 @@ private void LoadAssemblies(IEnumerable<string> assemblies)
1004882 assembly = Assembly . LoadFrom ( ResolveAssemblyName ( assemblyName , false ) ) ;
1005883 }
1006884
1007- if ( passThru )
885+ if ( PassThru )
1008886 {
1009887 WriteTypes ( assembly ) ;
1010888 }
@@ -1232,9 +1110,9 @@ private void WriteTypes(Assembly assembly)
12321110 private void CompileSourceToAssembly ( string source )
12331111 {
12341112 CSharpParseOptions parseOptions ;
1235- if ( IsCSharp ( language ) )
1113+ if ( IsCSharp ( Language ) )
12361114 {
1237- switch ( language )
1115+ switch ( Language )
12381116 {
12391117 case Language . CSharpVersion1 :
12401118 parseOptions = new CSharpParseOptions ( LanguageVersion . CSharp1 ) ;
@@ -1268,10 +1146,10 @@ private void CompileSourceToAssembly(string source)
12681146 else
12691147 {
12701148 ErrorRecord errorRecord = new ErrorRecord (
1271- new Exception ( String . Format ( CultureInfo . CurrentCulture , AddTypeStrings . SpecialNetVersionRequired , language . ToString ( ) , string . Empty ) ) ,
1149+ new Exception ( String . Format ( CultureInfo . CurrentCulture , AddTypeStrings . SpecialNetVersionRequired , Language . ToString ( ) , string . Empty ) ) ,
12721150 "LANGUAGE_NOT_SUPPORTED" ,
12731151 ErrorCategory . InvalidArgument ,
1274- language ) ;
1152+ Language ) ;
12751153
12761154 ThrowTerminatingError ( errorRecord ) ;
12771155 parseOptions = null ;
@@ -1318,7 +1196,7 @@ private void CompileSourceToAssembly(string source)
13181196 ms . Seek ( 0 , SeekOrigin . Begin ) ;
13191197 Assembly assembly = Assembly . Load ( ms . ToArray ( ) ) ;
13201198 CheckTypesForDuplicates ( assembly ) ;
1321- if ( passThru )
1199+ if ( PassThru )
13221200 {
13231201 WriteTypes ( assembly ) ;
13241202 }
@@ -1330,7 +1208,7 @@ private void CompileSourceToAssembly(string source)
13301208 emitResult = compilation . Emit ( outputAssembly ) ;
13311209 if ( emitResult . Success )
13321210 {
1333- if ( passThru )
1211+ if ( PassThru )
13341212 {
13351213 Assembly assembly = Assembly . LoadFrom ( outputAssembly ) ;
13361214 CheckTypesForDuplicates ( assembly ) ;
0 commit comments