Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
ast.cs10846 linesDownload Raw Back to parser
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4//5// This file contains all of the publicly visible parts of the PowerShell abstract syntax tree.6// Any private/internal methods or properties are found in the file AstCompile.cs.7//8 9using System.Collections;10using System.Diagnostics.CodeAnalysis;11using System.Globalization;12using System.Collections.ObjectModel;13using System.Collections.Generic;14using System.Linq;15using System.Linq.Expressions;16using System.Reflection;17using System.Text;18using System.Threading;19using Microsoft.PowerShell;20using Microsoft.PowerShell.Commands;21 22#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings23 24namespace System.Management.Automation.Language25{26    using KeyValuePair = Tuple<ExpressionAst, StatementAst>;27    using IfClause = Tuple<PipelineBaseAst, StatementBlockAst>;28    using SwitchClause = Tuple<ExpressionAst, StatementBlockAst>;29    using System.Runtime.CompilerServices;30    using System.Reflection.Emit;31 32#nullable enable33 34    internal interface ISupportsAssignment35    {36        IAssignableValue GetAssignableValue();37    }38 39    internal interface IAssignableValue40    {41        /// <summary>42        /// GetValue is only called for pre/post increment/decrement or for read/modify/write assignment operators (+=, -=, etc.)43        /// It returns the expressions that holds the value of the ast.  It may append the exprs or temps lists if the return44        /// value relies on temps and other expressions.45        /// </summary>46        Expression? GetValue(Compiler compiler, List<Expression> exprs, List<ParameterExpression> temps);47 48        /// <summary>49        /// SetValue is called to set the result of an assignment (=) or to write back the result of50        /// a pre/post increment/decrement.  It needs to use potentially cached temps if GetValue was called first.51        /// </summary>52        Expression SetValue(Compiler compiler, Expression rhs);53    }54#nullable restore55 56    internal interface IParameterMetadataProvider57    {58        bool HasAnyScriptBlockAttributes();59 60        RuntimeDefinedParameterDictionary GetParameterMetadata(bool automaticPositions, ref bool usesCmdletBinding);61 62        IEnumerable<Attribute> GetScriptBlockAttributes();63 64        IEnumerable<ExperimentalAttribute> GetExperimentalAttributes();65 66        bool UsesCmdletBinding();67 68        ReadOnlyCollection<ParameterAst> Parameters { get; }69 70        ScriptBlockAst Body { get; }71 72        #region Remoting/Invoke Command73 74        PowerShell GetPowerShell(ExecutionContext context, Dictionary<string, object> variables, bool isTrustedInput,75            bool filterNonUsingVariables, bool? createLocalScope, params object[] args);76 77        string GetWithInputHandlingForInvokeCommand();78 79        /// <summary>80        /// Return value is Tuple[paramText, scriptBlockText]81        /// </summary>82        Tuple<string, string> GetWithInputHandlingForInvokeCommandWithUsingExpression(Tuple<List<VariableExpressionAst>, string> usingVariablesTuple);83 84        #endregion Remoting/Invoke Command85    }86 87    /// <summary>88    /// The abstract base class for all PowerShell abstract syntax tree nodes.89    /// </summary>90    [SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")]91    public abstract class Ast92    {93        /// <summary>94        /// Initialize the common fields of an ast.95        /// </summary>96        /// <param name="extent">The extent of the expression.</param>97        /// <exception cref="PSArgumentNullException">98        /// If <paramref name="extent"/> is null.99        /// </exception>100        protected Ast(IScriptExtent extent)101        {102            if (extent == null)103            {104                throw PSTraceSource.NewArgumentNullException(nameof(extent));105            }106 107            this.Extent = extent;108        }109 110        /// <summary>111        /// The extent in the source this ast represents.112        /// </summary>113        public IScriptExtent Extent { get; }114 115        /// <summary>116        /// The parent tree for this node.117        /// </summary>118        public Ast Parent { get; private set; }119 120        /// <summary>121        /// Visit the Ast using a visitor that can choose how the tree traversal is performed.  This visit method is122        /// for advanced uses of the visitor pattern where an <see cref="AstVisitor"/> is insufficient.123        /// </summary>124        /// <param name="astVisitor">The visitor.</param>125        /// <returns>Returns the value returned by the visitor.</returns>126        public object Visit(ICustomAstVisitor astVisitor)127        {128            if (astVisitor == null)129            {130                throw PSTraceSource.NewArgumentNullException(nameof(astVisitor));131            }132 133            return this.Accept(astVisitor);134        }135 136        /// <summary>137        /// Visit each node in the Ast, calling the methods in <paramref name="astVisitor"/> for each node in the ast.138        /// </summary>139        /// <param name="astVisitor">The visitor.</param>140        public void Visit(AstVisitor astVisitor)141        {142            if (astVisitor == null)143            {144                throw PSTraceSource.NewArgumentNullException(nameof(astVisitor));145            }146 147            this.InternalVisit(astVisitor);148        }149 150        /// <summary>151        /// Traverse the entire Ast, returning all nodes in the tree for which <paramref name="predicate"/> returns true.152        /// </summary>153        /// <param name="predicate">The predicate function.</param>154        /// <param name="searchNestedScriptBlocks">Search nested functions and script block expressions.</param>155        /// <returns>A possibly empty collection of matching Ast nodes.</returns>156        public IEnumerable<Ast> FindAll(Func<Ast, bool> predicate, bool searchNestedScriptBlocks)157        {158            if (predicate == null)159            {160                throw PSTraceSource.NewArgumentNullException(nameof(predicate));161            }162 163            return AstSearcher.FindAll(this, predicate, searchNestedScriptBlocks);164        }165 166        /// <summary>167        /// Traverse the entire Ast, returning the first node in the tree for which <paramref name="predicate"/> returns true.168        /// </summary>169        /// <param name="predicate">The predicate.</param>170        /// <param name="searchNestedScriptBlocks">Search nested functions and script block expressions.</param>171        /// <returns>The first matching node, or null if there is no match.</returns>172        public Ast Find(Func<Ast, bool> predicate, bool searchNestedScriptBlocks)173        {174            if (predicate == null)175            {176                throw PSTraceSource.NewArgumentNullException(nameof(predicate));177            }178 179            return AstSearcher.FindFirst(this, predicate, searchNestedScriptBlocks);180        }181 182        /// <summary>183        /// Formats the ast and returns a string.184        /// </summary>185        public override string ToString()186        {187            return Extent.Text;188        }189 190        /// <summary>191        /// Duplicates the AST, allowing it to be composed into other ASTs.192        /// </summary>193        /// <returns>A copy of the AST, with the link to the previous parent removed.</returns>194        public abstract Ast Copy();195 196        /// <summary>197        /// Constructs the resultant object from the AST and returns it if it is safe.198        /// </summary>199        /// <returns>The object represented by the AST as a safe object.</returns>200        /// <exception cref="InvalidOperationException">201        /// If <paramref name="extent"/> is deemed unsafe202        /// </exception>203        public object SafeGetValue()204        {205            return SafeGetValue(skipHashtableSizeCheck: false);206        }207 208        /// <summary>209        /// Constructs the resultant object from the AST and returns it if it is safe.210        /// </summary>211        /// <param name="skipHashtableSizeCheck">Set to skip hashtable limit validation.</param>212        /// <returns>The object represented by the AST as a safe object.</returns>213        /// <exception cref="InvalidOperationException">214        /// If <paramref name="extent"/> is deemed unsafe.215        /// </exception>216        public object SafeGetValue(bool skipHashtableSizeCheck)217        {218            try219            {220                ExecutionContext context = null;221                if (System.Management.Automation.Runspaces.Runspace.DefaultRunspace != null)222                {223                    context = System.Management.Automation.Runspaces.Runspace.DefaultRunspace.ExecutionContext;224                }225 226                return GetSafeValueVisitor.GetSafeValue(this, context, skipHashtableSizeCheck ? GetSafeValueVisitor.SafeValueContext.SkipHashtableSizeCheck : GetSafeValueVisitor.SafeValueContext.Default);227            }228            catch229            {230                throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, AutomationExceptions.CantConvertWithDynamicExpression, this.Extent.Text));231            }232        }233 234        /// <summary>235        /// Copy a collection of AST elements.236        /// </summary>237        /// <typeparam name="T">The actual AST type</typeparam>238        /// <param name="elements">Collection of ASTs.</param>239        /// <returns></returns>240        internal static T[] CopyElements<T>(ReadOnlyCollection<T> elements) where T : Ast241        {242            if (elements == null || elements.Count == 0) { return null; }243 244            var result = new T[elements.Count];245            for (int i = 0; i < result.Length; i++)246            {247                result[i] = (T)elements[i].Copy();248            }249 250            return result;251        }252 253        /// <summary>254        /// Copy a single AST element.255        /// </summary>256        /// <typeparam name="T">The actual AST type</typeparam>257        /// <param name="element">An AST instance.</param>258        /// <returns></returns>259        internal static T CopyElement<T>(T element) where T : Ast260        {261            if (element == null) { return null; }262 263            return (T)element.Copy();264        }265 266        // Should be protected AND internal, but C# doesn't support that.267        internal void SetParents<T>(ReadOnlyCollection<T> children)268            where T : Ast269        {270            for (int index = 0; index < children.Count; index++)271            {272                var child = children[index];273                SetParent(child);274            }275        }276 277        // Should be protected AND internal, but C# doesn't support that.278        internal void SetParents<T1, T2>(ReadOnlyCollection<Tuple<T1, T2>> children)279            where T1 : Ast280            where T2 : Ast281        {282            for (int index = 0; index < children.Count; index++)283            {284                var child = children[index];285                SetParent(child.Item1);286                SetParent(child.Item2);287            }288        }289 290        // Should be protected AND internal, but C# doesn't support that.291        internal void SetParent(Ast child)292        {293            if (child.Parent != null)294            {295                throw new InvalidOperationException(ParserStrings.AstIsReused);296            }297 298            Diagnostics.Assert(child.Parent == null, "Parent can only be set once");299            child.Parent = this;300        }301 302        internal void ClearParent()303        {304            this.Parent = null;305        }306 307        internal abstract object Accept(ICustomAstVisitor visitor);308 309        internal abstract AstVisitAction InternalVisit(AstVisitor visitor);310 311        internal static readonly PSTypeName[] EmptyPSTypeNameArray = Array.Empty<PSTypeName>();312 313        internal bool IsInWorkflow()314        {315            // Scan up the AST's parents, looking for a script block that is either316            // a workflow, or has a job definition attribute.317            // Stop scanning when we encounter a FunctionDefinitionAst318            Ast current = this;319            bool stopScanning = false;320 321            while (current != null && !stopScanning)322            {323                if (current is ScriptBlockAst scriptBlock)324                {325                    // See if this uses the workflow keyword326                    if (scriptBlock.Parent is FunctionDefinitionAst functionDefinition)327                    {328                        stopScanning = true;329                        if (functionDefinition.IsWorkflow)330                        {331                            return true;332                        }333                    }334                }335 336                if (current is CommandAst commandAst &&337                    string.Equals(TokenKind.InlineScript.Text(), commandAst.GetCommandName(), StringComparison.OrdinalIgnoreCase) &&338                    this != commandAst)339                {340                    return false;341                }342 343                current = current.Parent;344            }345 346            return false;347        }348 349        internal bool HasSuspiciousContent { get; set; }350 351        #region Search Ancestor Ast352 353        internal static ConfigurationDefinitionAst GetAncestorConfigurationDefinitionAstAndDynamicKeywordStatementAst(354            Ast ast,355            out DynamicKeywordStatementAst keywordAst)356        {357            ConfigurationDefinitionAst configAst = null;358            keywordAst = GetAncestorAst<DynamicKeywordStatementAst>(ast);359            configAst = (keywordAst != null) ? GetAncestorAst<ConfigurationDefinitionAst>(keywordAst) : GetAncestorAst<ConfigurationDefinitionAst>(ast);360            return configAst;361        }362 363        internal static HashtableAst GetAncestorHashtableAst(Ast ast, out Ast lastChildOfHashtable)364        {365            HashtableAst hashtableAst = null;366            lastChildOfHashtable = null;367            while (ast != null)368            {369                hashtableAst = ast as HashtableAst;370                if (hashtableAst != null)371                    break;372                lastChildOfHashtable = ast;373                ast = ast.Parent;374            }375 376            return hashtableAst;377        }378 379        internal static TypeDefinitionAst GetAncestorTypeDefinitionAst(Ast ast)380        {381            TypeDefinitionAst typeDefinitionAst = null;382 383            while (ast != null)384            {385                typeDefinitionAst = ast as TypeDefinitionAst;386                if (typeDefinitionAst != null)387                    break;388 389                // Nested function isn't really a member of the type so stop looking390                // Anonymous script blocks are though391                if (ast is FunctionDefinitionAst functionDefinitionAst && functionDefinitionAst.Parent is not FunctionMemberAst)392                    break;393                ast = ast.Parent;394            }395 396            return typeDefinitionAst;397        }398 399        /// <summary>400        /// Get ancestor Ast of the given type of the given ast.401        /// </summary>402        /// <param name="ast"></param>403        /// <returns></returns>404        internal static T GetAncestorAst<T>(Ast ast) where T : Ast405        {406            T targetAst = null;407            var parent = ast;408            while (parent != null)409            {410                targetAst = parent as T;411                if (targetAst != null)412                    break;413                parent = parent.Parent;414            }415 416            return targetAst;417        }418 419        #endregion420    }421 422    // A dummy class to hold an extent for open/close curlies so we can step in the debugger.423    // This Ast is never produced by the parser, only from the compiler.424    internal class SequencePointAst : Ast425    {426        public SequencePointAst(IScriptExtent extent)427            : base(extent)428        {429        }430 431        /// <summary>432        /// Copy the SequencePointAst instance.433        /// </summary>434        public override Ast Copy()435        {436            Diagnostics.Assert(false, "code should be unreachable");437            return null;438        }439 440        internal override object Accept(ICustomAstVisitor visitor)441        {442            Diagnostics.Assert(false, "code should be unreachable");443            return null;444        }445 446        internal override AstVisitAction InternalVisit(AstVisitor visitor)447        {448            Diagnostics.Assert(false, "code should be unreachable");449            return visitor.CheckForPostAction(this, AstVisitAction.Continue);450        }451    }452 453    /// <summary>454    /// A placeholder statement used when there are syntactic errors in the source script.455    /// </summary>456    public class ErrorStatementAst : PipelineBaseAst457    {458        internal ErrorStatementAst(IScriptExtent extent, IEnumerable<Ast> nestedAsts = null)459            : base(extent)460        {461            if (nestedAsts != null && nestedAsts.Any())462            {463                NestedAst = new ReadOnlyCollection<Ast>(nestedAsts.ToArray());464                SetParents(NestedAst);465            }466        }467 468        internal ErrorStatementAst(IScriptExtent extent, Token kind, IEnumerable<Ast> nestedAsts = null)469            : base(extent)470        {471            if (kind == null)472            {473                throw PSTraceSource.NewArgumentNullException(nameof(kind));474            }475 476            Kind = kind;477            if (nestedAsts != null && nestedAsts.Any())478            {479                NestedAst = new ReadOnlyCollection<Ast>(nestedAsts.ToArray());480                SetParents(NestedAst);481            }482        }483 484        internal ErrorStatementAst(IScriptExtent extent, Token kind, IEnumerable<KeyValuePair<string, Tuple<Token, Ast>>> flags, IEnumerable<Ast> conditions, IEnumerable<Ast> bodies)485            : base(extent)486        {487            if (kind == null)488            {489                throw PSTraceSource.NewArgumentNullException(nameof(kind));490            }491 492            Kind = kind;493            if (flags != null && flags.Any())494            {495                Flags = new Dictionary<string, Tuple<Token, Ast>>(StringComparer.OrdinalIgnoreCase);496                foreach (KeyValuePair<string, Tuple<Token, Ast>> entry in flags)497                {498                    if (Flags.ContainsKey(entry.Key))499                        continue;500 501                    Flags.Add(entry.Key, entry.Value);502                    if (entry.Value.Item2 != null)503                    {504                        SetParent(entry.Value.Item2);505                    }506                }507            }508 509            if (conditions != null && conditions.Any())510            {511                Conditions = new ReadOnlyCollection<Ast>(conditions.ToArray());512                SetParents(Conditions);513            }514 515            if (bodies != null && bodies.Any())516            {517                Bodies = new ReadOnlyCollection<Ast>(bodies.ToArray());518                SetParents(Bodies);519            }520        }521 522        /// <summary>523        /// Indicate the kind of the ErrorStatement. e.g. Kind == Switch means that this error statement is generated524        /// when parsing a switch statement.525        /// </summary>526        public Token Kind { get; }527 528        /// <summary>529        /// The flags specified and their value. The value is null if it's not specified.530        /// e.g. switch -regex -file c:\demo.txt  --->   regex -- null531        ///                                              file  -- { c:\demo.txt }532        /// </summary>533        /// TODO, Changing this to an IDictionary because ReadOnlyDictionary is available only in .NET 4.5534        /// This is a temporary workaround and will be fixed later. Tracked by Win8: 354135535        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]536        public Dictionary<string, Tuple<Token, Ast>> Flags { get; }537 538        /// <summary>539        /// The conditions specified.540        /// </summary>541        public ReadOnlyCollection<Ast> Conditions { get; }542 543        /// <summary>544        /// The bodies specified.545        /// </summary>546        public ReadOnlyCollection<Ast> Bodies { get; }547 548        /// <summary>549        /// Sometimes a valid ast is parsed successfully within the extent that this error statement represents.  Those550        /// asts are contained in this collection.  This collection may contain other error asts.  This collection may551        /// be null when no asts were successfully constructed within the extent of this error ast.552        /// </summary>553        public ReadOnlyCollection<Ast> NestedAst { get; }554 555        /// <summary>556        /// Copy the ErrorStatementAst instance.557        /// </summary>558        public override Ast Copy()559        {560            if (this.Kind == null)561            {562                var newNestedAst = CopyElements(this.NestedAst);563                return new ErrorStatementAst(this.Extent, newNestedAst);564            }565            else if (Flags != null || Conditions != null || Bodies != null)566            {567                var newConditions = CopyElements(this.Conditions);568                var newBodies = CopyElements(this.Bodies);569                Dictionary<string, Tuple<Token, Ast>> newFlags = null;570 571                if (this.Flags != null)572                {573                    newFlags = new Dictionary<string, Tuple<Token, Ast>>(StringComparer.OrdinalIgnoreCase);574                    foreach (KeyValuePair<string, Tuple<Token, Ast>> entry in this.Flags)575                    {576                        var newAst = CopyElement(entry.Value.Item2);577                        newFlags.Add(entry.Key, new Tuple<Token, Ast>(entry.Value.Item1, newAst));578                    }579                }580 581                return new ErrorStatementAst(this.Extent, this.Kind, newFlags, newConditions, newBodies);582            }583            else584            {585                var newNestedAst = CopyElements(this.NestedAst);586                return new ErrorStatementAst(this.Extent, this.Kind, newNestedAst);587            }588        }589 590        #region Visitors591 592        internal override object Accept(ICustomAstVisitor visitor)593        {594            return visitor.VisitErrorStatement(this);595        }596 597        internal override AstVisitAction InternalVisit(AstVisitor visitor)598        {599            var action = visitor.VisitErrorStatement(this);600            if (action == AstVisitAction.SkipChildren)601                return visitor.CheckForPostAction(this, AstVisitAction.Continue);602            if (action == AstVisitAction.Continue && NestedAst != null)603            {604                for (int index = 0; index < NestedAst.Count; index++)605                {606                    var ast = NestedAst[index];607                    action = ast.InternalVisit(visitor);608                    if (action != AstVisitAction.Continue) break;609                }610            }611 612            if (action == AstVisitAction.Continue && Flags != null)613            {614                foreach (var tuple in Flags.Values)615                {616                    if (tuple.Item2 == null)617                        continue;618 619                    action = tuple.Item2.InternalVisit(visitor);620                    if (action != AstVisitAction.Continue) break;621                }622            }623 624            if (action == AstVisitAction.Continue && Conditions != null)625            {626                for (int index = 0; index < Conditions.Count; index++)627                {628                    var ast = Conditions[index];629                    action = ast.InternalVisit(visitor);630                    if (action != AstVisitAction.Continue) break;631                }632            }633 634            if (action == AstVisitAction.Continue && Bodies != null)635            {636                for (int index = 0; index < Bodies.Count; index++)637                {638                    var ast = Bodies[index];639                    action = ast.InternalVisit(visitor);640                    if (action != AstVisitAction.Continue) break;641                }642            }643 644            return visitor.CheckForPostAction(this, action);645        }646 647        #endregion Visitors648    }649 650    /// <summary>651    /// A placeholder expression used when there are syntactic errors in the source script.652    /// </summary>653    public class ErrorExpressionAst : ExpressionAst654    {655        internal ErrorExpressionAst(IScriptExtent extent, IEnumerable<Ast> nestedAsts = null)656            : base(extent)657        {658            if (nestedAsts != null && nestedAsts.Any())659            {660                NestedAst = new ReadOnlyCollection<Ast>(nestedAsts.ToArray());661                SetParents(NestedAst);662            }663        }664 665        /// <summary>666        /// Sometimes a valid ast is parsed successfully within the extent that this error expression represents.  Those667        /// asts are contained in this collection.  This collection may contain other error asts.  This collection may668        /// be null when no asts were successfully constructed within the extent of this error ast.669        /// </summary>670        public ReadOnlyCollection<Ast> NestedAst { get; }671 672        /// <summary>673        /// Copy the ErrorExpressionAst instance.674        /// </summary>675        public override Ast Copy()676        {677            var newNestedAst = CopyElements(this.NestedAst);678            return new ErrorExpressionAst(this.Extent, newNestedAst);679        }680 681        #region Visitors682 683        internal override object Accept(ICustomAstVisitor visitor)684        {685            return visitor.VisitErrorExpression(this);686        }687 688        internal override AstVisitAction InternalVisit(AstVisitor visitor)689        {690            var action = visitor.VisitErrorExpression(this);691            if (action == AstVisitAction.SkipChildren)692                return visitor.CheckForPostAction(this, AstVisitAction.Continue);693            if (action == AstVisitAction.Continue && NestedAst != null)694            {695                for (int index = 0; index < NestedAst.Count; index++)696                {697                    var ast = NestedAst[index];698                    action = ast.InternalVisit(visitor);699                    if (action != AstVisitAction.Continue) break;700                }701            }702 703            return visitor.CheckForPostAction(this, action);704        }705 706        #endregion Visitors707    }708 709    #region Script Blocks710 711    /// <summary>712    /// </summary>713    public class ScriptRequirements714    {715        internal static readonly ReadOnlyCollection<PSSnapInSpecification> EmptySnapinCollection =716            Utils.EmptyReadOnlyCollection<PSSnapInSpecification>();717 718        internal static readonly ReadOnlyCollection<string> EmptyAssemblyCollection =719            Utils.EmptyReadOnlyCollection<string>();720 721        internal static readonly ReadOnlyCollection<ModuleSpecification> EmptyModuleCollection =722            Utils.EmptyReadOnlyCollection<ModuleSpecification>();723 724        internal static readonly ReadOnlyCollection<string> EmptyEditionCollection =725            Utils.EmptyReadOnlyCollection<string>();726 727        /// <summary>728        /// The application id this script requires, specified like:729        ///     <code>#requires -Shellid Shell</code>730        /// If no application id has been specified, this property is null.731        /// </summary>732        public string RequiredApplicationId { get; internal set; }733 734        /// <summary>735        /// The PowerShell version this script requires, specified like:736        ///     <code>#requires -Version 3</code>737        /// If no version has been specified, this property is null.738        /// </summary>739        public Version RequiredPSVersion { get; internal set; }740 741        /// <summary>742        /// The PowerShell Edition this script requires, specified like:743        ///     <code>#requires -PSEdition Desktop</code>744        /// If no PSEdition has been specified, this property is an empty collection.745        /// </summary>746        public ReadOnlyCollection<string> RequiredPSEditions { get; internal set; }747 748        /// <summary>749        /// The modules this script requires, specified like:750        ///     <code>#requires -Module NetAdapter</code>751        ///     <code>#requires -Module @{Name="NetAdapter"; Version="1.0.0.0"}</code>752        /// If no modules are required, this property is an empty collection.753        /// </summary>754        public ReadOnlyCollection<ModuleSpecification> RequiredModules { get; internal set; }755 756        /// <summary>757        /// The assemblies this script requires, specified like:758        ///     <code>#requires -Assembly path\to\foo.dll</code>759        ///     <code>#requires -Assembly "System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</code>760        /// If no assemblies are required, this property is an empty collection.761        /// </summary>762        public ReadOnlyCollection<string> RequiredAssemblies { get; internal set; }763 764        /// <summary>765        /// Specifies if this script requires elevated privileges, specified like:766        ///     <code>#requires -RunAsAdministrator</code>767        /// If nothing is specified, this property is false.768        /// </summary>769        public bool IsElevationRequired { get; internal set; }770    }771 772    /// <summary>773    /// A ScriptBlockAst is the root ast node for a complete script.774    /// </summary>775    public class ScriptBlockAst : Ast, IParameterMetadataProvider776    {777        private static readonly ReadOnlyCollection<AttributeAst> s_emptyAttributeList =778            Utils.EmptyReadOnlyCollection<AttributeAst>();779 780        private static readonly ReadOnlyCollection<UsingStatementAst> s_emptyUsingStatementList =781            Utils.EmptyReadOnlyCollection<UsingStatementAst>();782 783        internal bool HadErrors { get; set; }784 785        internal bool IsConfiguration { get; private set; }786 787        internal bool PostParseChecksPerformed { get; set; }788 789        /// <summary>790        /// Construct a ScriptBlockAst that uses explicitly named begin/process/end blocks.791        /// </summary>792        /// <param name="extent">The extent of the script block.</param>793        /// <param name="usingStatements">The list of using statements, may be null.</param>794        /// <param name="attributes">The set of attributes for the script block.</param>795        /// <param name="paramBlock">The ast for the param block, may be null.</param>796        /// <param name="beginBlock">The ast for the begin block, may be null.</param>797        /// <param name="processBlock">The ast for the process block, may be null.</param>798        /// <param name="endBlock">The ast for the end block, may be null.</param>799        /// <param name="dynamicParamBlock">The ast for the dynamicparam block, may be null.</param>800        /// <exception cref="PSArgumentNullException">801        /// If <paramref name="extent"/> is null.802        /// </exception>803        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]804        public ScriptBlockAst(IScriptExtent extent,805                              IEnumerable<UsingStatementAst> usingStatements,806                              IEnumerable<AttributeAst> attributes,807                              ParamBlockAst paramBlock,808                              NamedBlockAst beginBlock,809                              NamedBlockAst processBlock,810                              NamedBlockAst endBlock,811                              NamedBlockAst dynamicParamBlock)812            : this(813                extent,814                usingStatements,815                attributes,816                paramBlock,817                beginBlock,818                processBlock,819                endBlock,820                cleanBlock: null,821                dynamicParamBlock)822        {823        }824 825        /// <summary>826        /// Initializes a new instance of the <see cref="ScriptBlockAst"/> class.827        /// This construction uses explicitly named begin/process/end/clean blocks.828        /// </summary>829        /// <param name="extent">The extent of the script block.</param>830        /// <param name="usingStatements">The list of using statements, may be null.</param>831        /// <param name="attributes">The set of attributes for the script block.</param>832        /// <param name="paramBlock">The ast for the param block, may be null.</param>833        /// <param name="beginBlock">The ast for the begin block, may be null.</param>834        /// <param name="processBlock">The ast for the process block, may be null.</param>835        /// <param name="endBlock">The ast for the end block, may be null.</param>836        /// <param name="cleanBlock">The ast for the clean block, may be null.</param>837        /// <param name="dynamicParamBlock">The ast for the dynamicparam block, may be null.</param>838        /// <exception cref="PSArgumentNullException">839        /// If <paramref name="extent"/> is null.840        /// </exception>841        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]842        public ScriptBlockAst(843            IScriptExtent extent,844            IEnumerable<UsingStatementAst> usingStatements,845            IEnumerable<AttributeAst> attributes,846            ParamBlockAst paramBlock,847            NamedBlockAst beginBlock,848            NamedBlockAst processBlock,849            NamedBlockAst endBlock,850            NamedBlockAst cleanBlock,851            NamedBlockAst dynamicParamBlock)852            : base(extent)853        {854            SetUsingStatements(usingStatements);855 856            if (attributes != null)857            {858                this.Attributes = new ReadOnlyCollection<AttributeAst>(attributes.ToArray());859                SetParents(Attributes);860            }861            else862            {863                this.Attributes = s_emptyAttributeList;864            }865 866            if (paramBlock != null)867            {868                this.ParamBlock = paramBlock;869                SetParent(paramBlock);870            }871 872            if (beginBlock != null)873            {874                this.BeginBlock = beginBlock;875                SetParent(beginBlock);876            }877 878            if (processBlock != null)879            {880                this.ProcessBlock = processBlock;881                SetParent(processBlock);882            }883 884            if (endBlock != null)885            {886                this.EndBlock = endBlock;887                SetParent(endBlock);888            }889 890            if (cleanBlock != null)891            {892                this.CleanBlock = cleanBlock;893                SetParent(cleanBlock);894            }895 896            if (dynamicParamBlock != null)897            {898                this.DynamicParamBlock = dynamicParamBlock;899                SetParent(dynamicParamBlock);900            }901        }902 903        /// <summary>904        /// Construct a ScriptBlockAst that uses explicitly named begin/process/end blocks.905        /// </summary>906        /// <param name="extent">The extent of the script block.</param>907        /// <param name="usingStatements">The list of using statements, may be null.</param>908        /// <param name="paramBlock">The ast for the param block, may be null.</param>909        /// <param name="beginBlock">The ast for the begin block, may be null.</param>910        /// <param name="processBlock">The ast for the process block, may be null.</param>911        /// <param name="endBlock">The ast for the end block, may be null.</param>912        /// <param name="dynamicParamBlock">The ast for the dynamicparam block, may be null.</param>913        /// <exception cref="PSArgumentNullException">914        /// If <paramref name="extent"/> is null.915        /// </exception>916        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]917        public ScriptBlockAst(IScriptExtent extent,918                              IEnumerable<UsingStatementAst> usingStatements,919                              ParamBlockAst paramBlock,920                              NamedBlockAst beginBlock,921                              NamedBlockAst processBlock,922                              NamedBlockAst endBlock,923                              NamedBlockAst dynamicParamBlock)924            : this(extent, usingStatements, null, paramBlock, beginBlock, processBlock, endBlock, dynamicParamBlock)925        {926        }927 928        /// <summary>929        /// Initializes a new instance of the <see cref="ScriptBlockAst"/> class.930        /// This construction uses explicitly named begin/process/end/clean blocks.931        /// </summary>932        /// <param name="extent">The extent of the script block.</param>933        /// <param name="usingStatements">The list of using statements, may be null.</param>934        /// <param name="paramBlock">The ast for the param block, may be null.</param>935        /// <param name="beginBlock">The ast for the begin block, may be null.</param>936        /// <param name="processBlock">The ast for the process block, may be null.</param>937        /// <param name="endBlock">The ast for the end block, may be null.</param>938        /// <param name="cleanBlock">The ast for the clean block, may be null.</param>939        /// <param name="dynamicParamBlock">The ast for the dynamicparam block, may be null.</param>940        /// <exception cref="PSArgumentNullException">941        /// If <paramref name="extent"/> is null.942        /// </exception>943        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]944        public ScriptBlockAst(945            IScriptExtent extent,946            IEnumerable<UsingStatementAst> usingStatements,947            ParamBlockAst paramBlock,948            NamedBlockAst beginBlock,949            NamedBlockAst processBlock,950            NamedBlockAst endBlock,951            NamedBlockAst cleanBlock,952            NamedBlockAst dynamicParamBlock)953            : this(extent, usingStatements, null, paramBlock, beginBlock, processBlock, endBlock, cleanBlock, dynamicParamBlock)954        {955        }956 957        /// <summary>958        /// Construct a ScriptBlockAst that uses explicitly named begin/process/end blocks.959        /// </summary>960        /// <param name="extent">The extent of the script block.</param>961        /// <param name="paramBlock">The ast for the param block, may be null.</param>962        /// <param name="beginBlock">The ast for the begin block, may be null.</param>963        /// <param name="processBlock">The ast for the process block, may be null.</param>964        /// <param name="endBlock">The ast for the end block, may be null.</param>965        /// <param name="dynamicParamBlock">The ast for the dynamicparam block, may be null.</param>966        /// <exception cref="PSArgumentNullException">967        /// If <paramref name="extent"/> is null.968        /// </exception>969        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]970        public ScriptBlockAst(IScriptExtent extent,971                              ParamBlockAst paramBlock,972                              NamedBlockAst beginBlock,973                              NamedBlockAst processBlock,974                              NamedBlockAst endBlock,975                              NamedBlockAst dynamicParamBlock)976            : this(extent, null, paramBlock, beginBlock, processBlock, endBlock, dynamicParamBlock)977        {978        }979 980        /// <summary>981        /// Initializes a new instance of the <see cref="ScriptBlockAst"/> class.982        /// This construction uses explicitly named begin/process/end/clean blocks.983        /// </summary>984        /// <param name="extent">The extent of the script block.</param>985        /// <param name="paramBlock">The ast for the param block, may be null.</param>986        /// <param name="beginBlock">The ast for the begin block, may be null.</param>987        /// <param name="processBlock">The ast for the process block, may be null.</param>988        /// <param name="endBlock">The ast for the end block, may be null.</param>989        /// <param name="cleanBlock">The ast for the clean block, may be null.</param>990        /// <param name="dynamicParamBlock">The ast for the dynamicparam block, may be null.</param>991        /// <exception cref="PSArgumentNullException">992        /// If <paramref name="extent"/> is null.993        /// </exception>994        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]995        public ScriptBlockAst(996            IScriptExtent extent,997            ParamBlockAst paramBlock,998            NamedBlockAst beginBlock,999            NamedBlockAst processBlock,1000            NamedBlockAst endBlock,1001            NamedBlockAst cleanBlock,1002            NamedBlockAst dynamicParamBlock)1003            : this(extent, null, paramBlock, beginBlock, processBlock, endBlock, cleanBlock, dynamicParamBlock)1004        {1005        }1006 1007        /// <summary>1008        /// Construct a ScriptBlockAst that does not use explicitly named blocks.1009        /// </summary>1010        /// <param name="extent">The extent of the script block.</param>1011        /// <param name="usingStatements">The list of using statements, may be null.</param>1012        /// <param name="paramBlock">The ast for the param block, may be null.</param>1013        /// <param name="statements">1014        /// The statements that go in the end block if <paramref name="isFilter"/> is false, or the1015        /// process block if <paramref name="isFilter"/> is true.1016        /// </param>1017        /// <param name="isFilter">True if the script block is a filter, false if it is a function or workflow.</param>1018        /// <exception cref="PSArgumentNullException">1019        /// If <paramref name="extent"/> or <paramref name="statements"/> is null.1020        /// </exception>1021        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]1022        public ScriptBlockAst(IScriptExtent extent, List<UsingStatementAst> usingStatements, ParamBlockAst paramBlock, StatementBlockAst statements, bool isFilter)1023            : this(extent, usingStatements, null, paramBlock, statements, isFilter, false)1024        {1025        }1026 1027        /// <summary>1028        /// Construct a ScriptBlockAst that does not use explicitly named blocks.1029        /// </summary>1030        /// <param name="extent">The extent of the script block.</param>1031        /// <param name="paramBlock">The ast for the param block, may be null.</param>1032        /// <param name="statements">1033        /// The statements that go in the end block if <paramref name="isFilter"/> is false, or the1034        /// process block if <paramref name="isFilter"/> is true.1035        /// </param>1036        /// <param name="isFilter">True if the script block is a filter, false if it is a function or workflow.</param>1037        /// <exception cref="PSArgumentNullException">1038        /// If <paramref name="extent"/> or <paramref name="statements"/> is null.1039        /// </exception>1040        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]1041        public ScriptBlockAst(IScriptExtent extent, ParamBlockAst paramBlock, StatementBlockAst statements, bool isFilter)1042            : this(extent, null, null, paramBlock, statements, isFilter, false)1043        {1044        }1045 1046        /// <summary>1047        /// Construct a ScriptBlockAst that does not use explicitly named blocks.1048        /// </summary>1049        /// <param name="extent">The extent of the script block.</param>1050        /// <param name="paramBlock">The ast for the param block, may be null.</param>1051        /// <param name="statements">1052        /// The statements that go in the end block if <paramref name="isFilter"/> is false, or the1053        /// process block if <paramref name="isFilter"/> is true.1054        /// </param>1055        /// <param name="isFilter">True if the script block is a filter, false if it is a function or workflow.</param>1056        /// <param name="isConfiguration">True if the script block is a configuration.</param>1057        /// <exception cref="PSArgumentNullException">1058        /// If <paramref name="extent"/> or <paramref name="statements"/> is null.1059        /// </exception>1060        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]1061        public ScriptBlockAst(IScriptExtent extent, ParamBlockAst paramBlock, StatementBlockAst statements, bool isFilter, bool isConfiguration)1062            : this(extent, null, null, paramBlock, statements, isFilter, isConfiguration)1063        {1064        }1065 1066        /// <summary>1067        /// Construct a ScriptBlockAst that does not use explicitly named blocks.1068        /// </summary>1069        /// <param name="extent">The extent of the script block.</param>1070        /// <param name="usingStatements">The list of using statements, may be null.</param>1071        /// <param name="paramBlock">The ast for the param block, may be null.</param>1072        /// <param name="statements">1073        /// The statements that go in the end block if <paramref name="isFilter"/> is false, or the1074        /// process block if <paramref name="isFilter"/> is true.1075        /// </param>1076        /// <param name="isFilter">True if the script block is a filter, false if it is a function or workflow.</param>1077        /// <param name="isConfiguration">True if the script block is a configuration.</param>1078        /// <exception cref="PSArgumentNullException">1079        /// If <paramref name="extent"/> or <paramref name="statements"/> is null.1080        /// </exception>1081        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]1082        public ScriptBlockAst(IScriptExtent extent, IEnumerable<UsingStatementAst> usingStatements, ParamBlockAst paramBlock, StatementBlockAst statements, bool isFilter, bool isConfiguration)1083            : this(extent, usingStatements, null, paramBlock, statements, isFilter, isConfiguration)1084        {1085        }1086 1087        /// <summary>1088        /// Construct a ScriptBlockAst that does not use explicitly named blocks.1089        /// </summary>1090        /// <param name="extent">The extent of the script block.</param>1091        /// <param name="attributes">The attributes for the script block.</param>1092        /// <param name="paramBlock">The ast for the param block, may be null.</param>1093        /// <param name="statements">1094        /// The statements that go in the end block if <paramref name="isFilter"/> is false, or the1095        /// process block if <paramref name="isFilter"/> is true.1096        /// </param>1097        /// <param name="isFilter">True if the script block is a filter, false if it is a function or workflow.</param>1098        /// <param name="isConfiguration">True if the script block is a configuration.</param>1099        /// <exception cref="PSArgumentNullException">1100        /// If <paramref name="extent"/> or <paramref name="statements"/> is null.1101        /// </exception>1102        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]1103        public ScriptBlockAst(IScriptExtent extent, IEnumerable<AttributeAst> attributes, ParamBlockAst paramBlock, StatementBlockAst statements, bool isFilter, bool isConfiguration)1104            : this(extent, null, attributes, paramBlock, statements, isFilter, isConfiguration)1105        {1106        }1107 1108        /// <summary>1109        /// Construct a ScriptBlockAst that does not use explicitly named blocks.1110        /// </summary>1111        /// <param name="extent">The extent of the script block.</param>1112        /// <param name="usingStatements">The list of using statements, may be null.</param>1113        /// <param name="attributes">The attributes for the script block.</param>1114        /// <param name="paramBlock">The ast for the param block, may be null.</param>1115        /// <param name="statements">1116        /// The statements that go in the end block if <paramref name="isFilter"/> is false, or the1117        /// process block if <paramref name="isFilter"/> is true.1118        /// </param>1119        /// <param name="isFilter">True if the script block is a filter, false if it is a function or workflow.</param>1120        /// <param name="isConfiguration">True if the script block is a configuration.</param>1121        /// <exception cref="PSArgumentNullException">1122        /// If <paramref name="extent"/> or <paramref name="statements"/> is null.1123        /// </exception>1124        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "param")]1125        public ScriptBlockAst(IScriptExtent extent, IEnumerable<UsingStatementAst> usingStatements, IEnumerable<AttributeAst> attributes, ParamBlockAst paramBlock, StatementBlockAst statements, bool isFilter, bool isConfiguration)1126            : base(extent)1127        {1128            SetUsingStatements(usingStatements);1129 1130            if (attributes != null)1131            {1132                this.Attributes = new ReadOnlyCollection<AttributeAst>(attributes.ToArray());1133                SetParents(Attributes);1134            }1135            else1136            {1137                this.Attributes = s_emptyAttributeList;1138            }1139 1140            if (statements == null)1141            {1142                throw PSTraceSource.NewArgumentNullException(nameof(statements));1143            }1144 1145            if (paramBlock != null)1146            {1147                this.ParamBlock = paramBlock;1148                SetParent(paramBlock);1149            }1150 1151            if (isFilter)1152            {1153                this.ProcessBlock = new NamedBlockAst(statements.Extent, TokenKind.Process, statements, true);1154                SetParent(ProcessBlock);1155            }1156            else1157            {1158                this.EndBlock = new NamedBlockAst(statements.Extent, TokenKind.End, statements, true);1159                this.IsConfiguration = isConfiguration;1160                SetParent(EndBlock);1161            }1162        }1163 1164        private void SetUsingStatements(IEnumerable<UsingStatementAst> usingStatements)1165        {1166            if (usingStatements != null)1167            {1168                this.UsingStatements = new ReadOnlyCollection<UsingStatementAst>(usingStatements.ToArray());1169                SetParents(UsingStatements);1170            }1171            else1172            {1173                this.UsingStatements = s_emptyUsingStatementList;1174            }1175        }1176 1177        /// <summary>1178        /// The asts for attributes (such as [DscLocalConfigurationManager()]) used before the scriptblock.1179        /// This property is never null.1180        /// </summary>1181        public ReadOnlyCollection<AttributeAst> Attributes { get; }1182 1183        /// <summary>1184        /// The asts for any using statements.  This property is never null.1185        /// Elements of the collection are instances of either <see cref="UsingStatementAst"/>1186        /// or (only in error cases) <see cref="ErrorStatementAst"/>.1187        /// </summary>1188        public ReadOnlyCollection<UsingStatementAst> UsingStatements { get; private set; }1189 1190        /// <summary>1191        /// The ast representing the parameters for a script block, or null if no param block was specified.1192        /// </summary>1193        [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Param")]1194        public ParamBlockAst ParamBlock { get; }1195 1196        /// <summary>1197        /// The ast representing the begin block for a script block, or null if no begin block was specified.1198        /// </summary>1199        public NamedBlockAst BeginBlock { get; }1200 

Showing the first 1,200 of 10846 lines. Download the file for the rest.