Пример #1
0
        // Visit one the other variations:
        //  - Dotting scripts
        //  - Setting aliases
        //  - Importing modules
        //  - Exporting module members
        public override AstVisitAction VisitCommand(CommandAst commandAst)
        {
            string commandName =
                commandAst.GetCommandName() ??
                GetSafeValueVisitor.GetSafeValue(commandAst.CommandElements[0], null, GetSafeValueVisitor.SafeValueContext.ModuleAnalysis) as string;

            if (commandName == null)
            {
                return(AstVisitAction.SkipChildren);
            }

            // They are trying to dot a script
            if (commandAst.InvocationOperator == TokenKind.Dot)
            {
                // . Foo-Bar4.ps1
                // . $psScriptRoot\Foo-Bar.ps1 -Bing Baz
                // . ""$psScriptRoot\Support Files\Foo-Bar2.ps1"" -Bing Baz
                // . '$psScriptRoot\Support Files\Foo-Bar3.ps1' -Bing Baz

                DiscoveredModules.Add(
                    new RequiredModuleInfo {
                    Name = commandName, CommandsToPostFilter = new List <string>()
                });
                ModuleIntrinsics.Tracer.WriteLine("Module dots {0}", commandName);
            }

            // They are setting an alias.
            if (string.Equals(commandName, "New-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Microsoft.PowerShell.Utility\\New-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Set-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Microsoft.PowerShell.Utility\\Set-Alias", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "nal", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "sal", StringComparison.OrdinalIgnoreCase))
            {
                // Set-Alias Foo-Bar5 Foo-Bar
                // Set-Alias -Name Foo-Bar6 -Value Foo-Bar
                // sal Foo-Bar7 Foo-Bar
                // sal -Value Foo-Bar -Name Foo-Bar8

                var boundParameters = DoPsuedoParameterBinding(commandAst, commandName);

                var name = boundParameters["Name"] as string;
                if (!string.IsNullOrEmpty(name))
                {
                    var value = boundParameters["Value"] as string;
                    if (!string.IsNullOrEmpty(value))
                    {
                        // These aren't stored in DiscoveredExports, as they are only
                        // exported after the user calls Export-ModuleMember.
                        DiscoveredAliases[name] = value;
                        ModuleIntrinsics.Tracer.WriteLine("Module defines alias: {0} = {1}", name, value);
                    }
                }

                return(AstVisitAction.SkipChildren);
            }

            // They are importing a module
            if (string.Equals(commandName, "Import-Module", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "ipmo", StringComparison.OrdinalIgnoreCase))
            {
                // Import-Module Module1
                // Import-Module Module2 -Function Foo-Module2*, Foo-Module2Second* -Cmdlet Foo-Module2Cmdlet,Foo-Module2Cmdlet*
                // Import-Module Module3 -Function Foo-Module3Command1, Foo-Module3Command2
                // Import-Module Module4,
                //    Module5
                // Import-Module -Name Module6,
                //    Module7 -Global

                var boundParameters = DoPsuedoParameterBinding(commandAst, commandName);

                List <string> commandsToPostFilter = new List <string>();

                Action <string> onEachCommand = importedCommandName =>
                {
                    commandsToPostFilter.Add(importedCommandName);
                };

                // Process any exports from the module that we determine from
                // the -Function, -Cmdlet, or -Alias parameters
                ProcessCmdletArguments(boundParameters["Function"], onEachCommand);
                ProcessCmdletArguments(boundParameters["Cmdlet"], onEachCommand);
                ProcessCmdletArguments(boundParameters["Alias"], onEachCommand);

                // Now, go through all of the discovered modules on Import-Module
                // and register them for deeper investigation.
                Action <string> onEachModule = moduleName =>
                {
                    ModuleIntrinsics.Tracer.WriteLine("Discovered module import: {0}", moduleName);
                    DiscoveredModules.Add(
                        new RequiredModuleInfo
                    {
                        Name = moduleName,
                        CommandsToPostFilter = commandsToPostFilter
                    });
                };
                ProcessCmdletArguments(boundParameters["Name"], onEachModule);

                return(AstVisitAction.SkipChildren);
            }

            // They are exporting a module member
            if (string.Equals(commandName, "Export-ModuleMember", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "Microsoft.PowerShell.Core\\Export-ModuleMember", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(commandName, "$script:ExportModuleMember", StringComparison.OrdinalIgnoreCase))
            {
                // Export-ModuleMember *
                // Export-ModuleMember Exported-UnNamedModuleMember
                // Export-ModuleMember -Function Exported-FunctionModuleMember1, Exported-FunctionModuleMember2 -Cmdlet Exported-CmdletModuleMember `
                //    -Alias Exported-AliasModuleMember
                // & $script:ExportModuleMember -Function (...)

                var boundParameters = DoPsuedoParameterBinding(commandAst, commandName);

                Action <string> onEachFunction = exportedCommandName =>
                {
                    DiscoveredCommandFilters.Add(exportedCommandName);
                    ModuleIntrinsics.Tracer.WriteLine("Discovered explicit export: {0}", exportedCommandName);

                    // If the export doesn't contain wildcards, then add it to the
                    // discovered commands as well. It is likely that they created
                    // the command dynamically
                    if ((!WildcardPattern.ContainsWildcardCharacters(exportedCommandName)) &&
                        (!DiscoveredExports.Contains(exportedCommandName)))
                    {
                        DiscoveredExports.Add(exportedCommandName);
                    }
                };
                ProcessCmdletArguments(boundParameters["Function"], onEachFunction);
                ProcessCmdletArguments(boundParameters["Cmdlet"], onEachFunction);

                Action <string> onEachAlias = exportedAlias =>
                {
                    DiscoveredCommandFilters.Add(exportedAlias);

                    // If the export doesn't contain wildcards, then add it to the
                    // discovered commands as well. It is likely that they created
                    // the command dynamically
                    if (!WildcardPattern.ContainsWildcardCharacters(exportedAlias))
                    {
                        DiscoveredAliases[exportedAlias] = null;
                    }
                };
                ProcessCmdletArguments(boundParameters["Alias"], onEachAlias);

                return(AstVisitAction.SkipChildren);
            }

            // They are exporting a module member using our advanced 'public' function
            // that we've presented in many demos
            if ((string.Equals(commandName, "public", StringComparison.OrdinalIgnoreCase)) &&
                (commandAst.CommandElements.Count > 2))
            {
                // public function Publicly-ExportedFunction
                // public alias Publicly-ExportedAlias
                string publicCommandName = commandAst.CommandElements[2].ToString().Trim();
                DiscoveredExports.Add(publicCommandName);
                DiscoveredCommandFilters.Add(publicCommandName);
            }

            return(AstVisitAction.SkipChildren);
        }