/// <summary>
        /// AnalyzeScript: Check if any uninitialized variable is used.
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            // Finds all functionAst
            IEnumerable<Ast> functionAsts = ast.FindAll(testAst => testAst is FunctionDefinitionAst, true);

            foreach (FunctionDefinitionAst funcAst in functionAsts)
            {
                if (funcAst.Body != null && funcAst.Body.ParamBlock != null
                    && funcAst.Body.ParamBlock.Attributes != null && funcAst.Body.ParamBlock.Parameters != null)
                {
                    // only raise this rule for function with cmdletbinding
                    if (!funcAst.Body.ParamBlock.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(CmdletBindingAttribute)))
                    {
                        continue;
                    }

                    foreach (var paramAst in funcAst.Body.ParamBlock.Parameters)
                    {
                        bool mandatory = false;

                        // check that param is mandatory
                        foreach (var paramAstAttribute in paramAst.Attributes)
                        {
                            if (paramAstAttribute is AttributeAst)
                            {
                                var namedArguments = (paramAstAttribute as AttributeAst).NamedArguments;
                                if (namedArguments != null)
                                {
                                    foreach (NamedAttributeArgumentAst namedArgument in namedArguments)
                                    {
                                        if (String.Equals(namedArgument.ArgumentName, "mandatory", StringComparison.OrdinalIgnoreCase))
                                        {
                                            // 2 cases: [Parameter(Mandatory)] and [Parameter(Mandatory=$true)]
                                            if (namedArgument.ExpressionOmitted || (!namedArgument.ExpressionOmitted && String.Equals(namedArgument.Argument.Extent.Text, "$true", StringComparison.OrdinalIgnoreCase)))
                                            {
                                                mandatory = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!mandatory)
                        {
                            break;
                        }

                        if (paramAst.DefaultValue != null)
                        {
                            yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidDefaultValueForMandatoryParameterError, paramAst.Name.VariablePath.UserPath),
                            paramAst.Name.Extent, GetName(), DiagnosticSeverity.Warning, fileName, paramAst.Name.VariablePath.UserPath);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// AnalyzeDSCResource: Analyzes given DSC Resource
        /// </summary>
        /// <param name="ast">The script's ast</param>
        /// <param name="fileName">The name of the script file being analyzed</param>
        /// <returns>The results of the analysis</returns>
        public IEnumerable<DiagnosticRecord> AnalyzeDSCResource(Ast ast, string fileName)
        {
            // we are given a script definition, do not analyze
            if (String.IsNullOrWhiteSpace(fileName))
            {
                yield break;
            }

            String fileNameOnly = Path.GetFileName(fileName);
            String resourceName = Path.GetFileNameWithoutExtension(fileNameOnly);
            String examplesQuery = String.Format("*{0}*", resourceName);
            Boolean examplesPresent = false; 
            String expectedExamplesPath = Path.Combine(new String[] {fileName, "..", "..", "..", "Examples"});

            // Verify examples are present
            if (Directory.Exists(expectedExamplesPath))
            {
                DirectoryInfo examplesFolder = new DirectoryInfo(expectedExamplesPath);
                FileInfo[] exampleFiles = examplesFolder.GetFiles(examplesQuery);
                if (exampleFiles.Length != 0)
                {
                    examplesPresent = true;
                }
            }

            // Return error if no examples present
            if (!examplesPresent)
            {
                yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.DscExamplesPresentNoExamplesError, resourceName),
                            ast.Extent, GetName(), DiagnosticSeverity.Information, fileName);
            }
        }
Пример #3
0
        public void Visit(Ast.DictNode dict)
        {
            IDictionary obj = new Hashtable(dict.Elements.Count);
            foreach(Ast.KeyValueNode kv in dict.Elements)
            {
                kv.Key.Accept(this);
                object key = generated.Pop();
                kv.Value.Accept(this);
                object value = generated.Pop();
                obj[key] = value;
            }

            if(dictToInstance==null || !obj.Contains("__class__"))
            {
                generated.Push(obj);
            }
            else
            {
                object result = dictToInstance(obj);
                if(result==null)
                    generated.Push(obj);
                else
                    generated.Push(result);
            }
        }
        /// <summary>
        /// AnalyzeDSCResource: Analyzes the ast to check that Write-Verbose is called for DSC Resources
        /// <param name="ast">The script's ast</param>
        /// <param name="fileName">The script's file name</param>
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeDSCResource(Ast ast, string fileName)
        {
            if (ast == null)
            {
                throw new ArgumentNullException(Strings.NullAstErrorMessage);
            }            

            IEnumerable<Ast> functionDefinitionAsts = Helper.Instance.DscResourceFunctions(ast);

            foreach (FunctionDefinitionAst functionDefinitionAst in functionDefinitionAsts)
            {
                var commandAsts = functionDefinitionAst.Body.FindAll(testAst => testAst is CommandAst, false);
                bool hasVerbose = false;

                if (null != commandAsts)
                {
                    foreach (CommandAst commandAst in commandAsts)
                    {
                        hasVerbose |= String.Equals(commandAst.GetCommandName(), "Write-Verbose", StringComparison.OrdinalIgnoreCase);
                    }
                }

                if (!hasVerbose)
                {
                    yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.UseVerboseMessageInDSCResourceErrorFunction, functionDefinitionAst.Name),
                        functionDefinitionAst.Extent, GetName(), DiagnosticSeverity.Information, fileName);
                }

            }
        }
        /// <summary>
        /// MisleadingBacktick: Checks that lines don't end with a backtick followed by a whitespace
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            string[] lines = NewlineRegex.Split(ast.Extent.Text);

            if((ast.Extent.EndLineNumber - ast.Extent.StartLineNumber + 1) != lines.Length)
            {
                // Did not match the number of lines that the extent indicated
                yield break;
            }

            foreach (int i in Enumerable.Range(0, lines.Length))
            {
                string line = lines[i];

                Match match = TrailingEscapedWhitespaceRegex.Match(line);

                if(match.Success)
                {
                    int lineNumber = ast.Extent.StartLineNumber + i;

                    ScriptPosition start = new ScriptPosition(fileName, lineNumber, match.Index, line);
                    ScriptPosition end = new ScriptPosition(fileName, lineNumber, match.Index + match.Length, line);

                    yield return new DiagnosticRecord(
                        string.Format(CultureInfo.CurrentCulture, Strings.MisleadingBacktickError),
                            new ScriptExtent(start, end), GetName(), DiagnosticSeverity.Warning, fileName);
                }
            }
        }
        /// <summary>
        /// AnalyzeScript: Analyzes the ast to check for reserved parameters in function definitions.
        /// </summary>
        /// <param name="ast">The script's ast</param>
        /// <param name="fileName">The script's file name</param>
        /// <returns>A List of diagnostic results of this rule</returns>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            IEnumerable<Ast> funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true);

            List<string> commonParamNames = typeof(CommonParameters).GetProperties().Select(param => param.Name).ToList();

            foreach (FunctionDefinitionAst funcAst in funcAsts)
            {
                // this rule only applies to function with param block
                if (funcAst.Body != null && funcAst.Body.ParamBlock != null
                    && funcAst.Body.ParamBlock.Attributes != null && funcAst.Body.ParamBlock.Parameters != null)
                {
                    // no cmdlet binding
                    if (!funcAst.Body.ParamBlock.Attributes.Any(attr => attr.TypeName.GetReflectionType() == typeof(CmdletBindingAttribute)))
                    {
                        continue;
                    }

                    foreach (ParameterAst paramAst in funcAst.Body.ParamBlock.Parameters)
                    {
                        string paramName = paramAst.Name.VariablePath.UserPath;

                        if (commonParamNames.Contains(paramName, StringComparer.OrdinalIgnoreCase))
                        {
                            yield return new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ReservedParamsError, funcAst.Name, paramName),
                                paramAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                        }
                    }
                }
            }
        }
Пример #7
0
 internal Scope(IParameterMetadataProvider ast, ScopeType scopeType)
 {
     _ast = (Ast)ast;
     _scopeType = scopeType;
     _typeTable = new Dictionary<string, TypeLookupResult>(StringComparer.OrdinalIgnoreCase);
     _variableTable = new Dictionary<string, Ast>(StringComparer.OrdinalIgnoreCase);
 }
Пример #8
0
        internal Ast.Expression Visit(Ast.Expression expression)
        {
            switch (expression.CodeType)
            {
                case CodeType.BlockExpression:
                    return VisitBlockExpression((Ast.BlockExpression)expression);
                case CodeType.TypeExpression:
                    return VisitTypeExpression((Ast.TypeExpression)expression);
                case CodeType.LambdaExpresion:
                    return VisitLambdaExpression((Ast.LambdaExpression)expression);
                case CodeType.LogicalExpression:
                    return VisitLogicalExpression((Ast.LogicalExpression)expression);
                case CodeType.BinaryExpression:
                    return VisitBinaryExpression((Ast.BinaryExpression)expression);
                case CodeType.LiteralExpression:
                    return VisitLiteralExpression((Ast.LiteralExpression)expression);
                case CodeType.MemberExpression:
                    return VisitMemberExpression((Ast.MemberExpression)expression);
                case CodeType.OrderbyExpression:
                    return VisitOrderbyExpression((Ast.OrderbyExpression)expression);
                case CodeType.MethodCallExpression:
                    return VisitMethodCallExpression((Ast.MethodCallExpression)expression);
            }

            throw new ArgumentException("Expression type is not supported");
        }
Пример #9
0
        public virtual Ast.Expression VisitBinaryExpression(Ast.BinaryExpression expression)
        {
            this.Visit(expression.Left);
            this.Visit(expression.Right);

            return expression;
        }
        /// <summary>
        /// AnalyzeScript: Check that cmdlets are invoked with the correct mandatory parameter
        /// </summary>
        /// <param name="ast"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            // Finds all CommandAsts.
            IEnumerable<Ast> foundAsts = ast.FindAll(testAst => testAst is CommandAst, true);

            // Iterates all CommandAsts and check the command name.
            foreach (Ast foundAst in foundAsts)
            {
                CommandAst cmdAst = (CommandAst)foundAst;

                // Handles the exception caused by commands like, {& $PLINK $args 2> $TempErrorFile}.
                // You can also review the remark section in following document,
                // MSDN: CommandAst.GetCommandName Method
                if (cmdAst.GetCommandName() == null) continue;

                // Checks mandatory parameters.
                if (!IsMandatoryParameterExisted(cmdAst))
                {
                    yield return new DiagnosticRecord(String.Format(CultureInfo.CurrentCulture, Strings.UseCmdletCorrectlyError, cmdAst.GetCommandName()),
                        cmdAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                }
            }
        }
Пример #11
0
        public virtual Ast.Expression VisitBlockExpression(Ast.BlockExpression blockExpression)
        {
            foreach (var expression in blockExpression.Expressions)
                this.Visit(expression);

            return blockExpression;
        }
        public Ast.Statements.BlockStatement Process(Decompiler.DecompilationContext context, Ast.Statements.BlockStatement body)
        {
            HashSet<Instruction> mappedInstructions = new HashSet<Instruction>(body.UnderlyingSameMethodInstructions);
            if (context.MethodContext.IsMethodBodyChanged)
            {
                context.MethodContext.Method.RefreshBody();
                context.MethodContext.IsMethodBodyChanged = false;
            }

            List<Instruction> unmappedInstructions = new List<Instruction>();
            foreach (Instruction instruction in context.MethodContext.Method.Body.Instructions)
            {
                if (!mappedInstructions.Contains(instruction))
                {
                    unmappedInstructions.Add(instruction);
                }
            }

            if (unmappedInstructions.Count > 0)
            {
                StringBuilder stringBuilder = new StringBuilder("Found unmapped instructions.\n");
                foreach (Instruction unmappedInstruction in unmappedInstructions)
                {
                    stringBuilder.AppendLine(unmappedInstruction.ToString());
                }
                throw new Exception(stringBuilder.ToString());
            }

            return body;
        }
Пример #13
0
        public void AstBuilder_ComplexExpression_Build()
        {
            var tree = new Ast("+", true);
            tree.Operands.Add(new Ast("4"));
            tree.Operands.Add(new Ast("6"));

            var buffer = new Ast("/", true);
            buffer.Operands.Add(new Ast("81"));
            buffer.Operands.Add(new Ast("-3"));

            var anotherBuffer = new Ast("*", true);
            anotherBuffer.Operands.Add(new Ast("3"));
            anotherBuffer.Operands.Add(new Ast("3"));
            buffer.Operands.Add(anotherBuffer);

            tree.Operands.Add(buffer);

            buffer = new Ast("-", true);
            buffer.Operands.Add(new Ast("10"));
            buffer.Operands.Add(new Ast("12"));

            tree.Operands.Add(buffer);
            var input = "(+ 4 6 (/ 81 -3 (* 3 3 ))( - 10 12 ))";

            var actualTree = new AstBuilder().Build(new Tokenizer().GetTokens(input));
            Assert.IsTrue(actualTree.Equals(tree));
        }
        private static List<string> GetSingleAstRequiredModules(Ast ast, Token[] tokens)
        {
            List<string> modules = new List<string>();
            List<string> resources = new List<string>();
            var imports = tokens.Where(token =>
                    String.Compare(token.Text, "Import-DscResource", StringComparison.OrdinalIgnoreCase) == 0);

            //
            // Create a function with the same name as Import-DscResource keyword and use powershell
            // argument function binding to emulate Import-DscResource argument binding.
            //
            InitialSessionState initialSessionState = InitialSessionState.Create();
            SessionStateFunctionEntry importDscResourcefunctionEntry = new SessionStateFunctionEntry(
                "Import-DscResource", @"param($Name, $ModuleName)
                if ($ModuleName) 
                {
                    foreach ($m in $ModuleName) { $global:modules.Add($m) }
                } else {
                    foreach ($n in $Name) { $global:resources.Add($n) }
                }
            ");
            initialSessionState.Commands.Add(importDscResourcefunctionEntry);
            initialSessionState.LanguageMode = PSLanguageMode.RestrictedLanguage;
            var moduleVarEntry = new SessionStateVariableEntry("modules", modules, "");
            var resourcesVarEntry = new SessionStateVariableEntry("resources", resources, "");
            initialSessionState.Variables.Add(moduleVarEntry);
            initialSessionState.Variables.Add(resourcesVarEntry);

            using (System.Management.Automation.PowerShell powerShell = System.Management.Automation.PowerShell.Create(initialSessionState))
            {
                foreach (var import in imports)
                {
                    int startOffset = import.Extent.StartOffset;
                    var asts = ast.FindAll(a => IsCandidateForImportDscResourceAst(a, startOffset), true);
                    int longestLen = -1;
                    Ast longestCandidate = null;
                    foreach (var candidatAst in asts)
                    {
                        int curLen = candidatAst.Extent.EndOffset - candidatAst.Extent.StartOffset;
                        if (curLen > longestLen)
                        {
                            longestCandidate = candidatAst;
                            longestLen = curLen;
                        }
                    }
                    // longestCandidate should contain AST for import-dscresource, like "Import-DSCResource -Module x -Name y".
                    if (longestCandidate != null)
                    {
                        string importText = longestCandidate.Extent.Text;
                        // We invoke-command "importText" here. Script injection is prevented:
                        // We checked that file represents a valid AST without errors.
                        powerShell.AddScript(importText);
                        powerShell.Invoke();
                        powerShell.Commands.Clear();
                    }
                }
            }
            modules.AddRange(resources.Select(GetModuleNameForDscResource));
            return modules;
        }
Пример #15
0
        public override void VisitMethodInvocationExpression(Ast.Expressions.MethodInvocationExpression node)
        {
            MethodDefinition methodDef = node.MethodExpression.MethodDefinition;
            if (methodDef == null)
            {
                base.VisitMethodInvocationExpression(node);
                return;
            }

            Visit(node.MethodExpression);

            for (int i = 0; i < node.Arguments.Count; i++)
            {
                UnaryExpression unaryArgument = node.Arguments[i] as UnaryExpression;
                if (methodDef.Parameters[i].IsOutParameter() && (unaryArgument != null && unaryArgument.Operator == UnaryOperator.AddressReference &&
                     CheckExpression(unaryArgument.Operand) || CheckExpression(node.Arguments[i])))
                {
                    this.searchResult = UsageFinderSearchResult.Assigned;
                    return;
                }
                else
                {
                    Visit(node.Arguments[i]);
                    if (this.searchResult != UsageFinderSearchResult.NotFound)
                    {
                        return;
                    }
                }
            }
        }
        /// <summary>
        /// AvoidUsingPlainTextForPassword: Check that parameter "password", "passphrase" and do not use plaintext.
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            // Finds all ParamAsts.
            IEnumerable<Ast> paramAsts = ast.FindAll(testAst => testAst is ParameterAst, true);

            List<String> passwords = new List<String>() {"Password", "Passphrase", "Auth", "Cred", "Credential"};

            // Iterrates all ParamAsts and check if their names are on the list.
            foreach (ParameterAst paramAst in paramAsts)
            {
                TypeInfo paramType = (TypeInfo) paramAst.StaticType;
                bool hasPwd = false;
                String paramName = paramAst.Name.VariablePath.ToString();

                foreach (String password in passwords)
                {
                    if (paramName.IndexOf(password, StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        hasPwd = true;
                        break;
                    }
                }

                if (hasPwd && ((!paramType.IsArray && (paramType == typeof(String) || paramType == typeof(object)))
                              || (paramType.IsArray && (paramType.GetElementType() == typeof(String) || paramType.GetElementType() == typeof(object)))))
                {
                    yield return new DiagnosticRecord(
                        String.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingPlainTextForPasswordError, paramAst.Name),
                        paramAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                }
            }
        }
Пример #17
0
 internal CompletionAnalysis(Ast ast, Token[] tokens, IScriptPosition cursorPosition, Hashtable options)
 {
     _ast = ast;
     _tokens = tokens;
     _cursorPosition = cursorPosition;
     _options = options;
 }
        private bool IncorrectComparisonWithNull(BinaryExpressionAst binExpressionAst, Ast ast)
        {
            if ((binExpressionAst.Operator.Equals(TokenKind.Equals) || binExpressionAst.Operator.Equals(TokenKind.Ceq) 
                || binExpressionAst.Operator.Equals(TokenKind.Cne) || binExpressionAst.Operator.Equals(TokenKind.Ine) || binExpressionAst.Operator.Equals(TokenKind.Ieq))
                && binExpressionAst.Right.Extent.Text.Equals("$null", StringComparison.OrdinalIgnoreCase)) 
            {
                if (binExpressionAst.Left.StaticType.IsArray)
                {
                    return true;
                }
                else if (binExpressionAst.Left is VariableExpressionAst)
                {
                    // ignores if the variable is a special variable
                    if (!Helper.Instance.HasSpecialVars((binExpressionAst.Left as VariableExpressionAst).VariablePath.UserPath))
                    {
                        Type lhsType = Helper.Instance.GetTypeFromAnalysis(binExpressionAst.Left as VariableExpressionAst, ast);
                        if (lhsType == null)
                        {
                            return true;
                        }
                        else if (lhsType.IsArray || lhsType == typeof(object) || lhsType == typeof(Undetermined) || lhsType == typeof(Unreached))
                        {
                            return true;
                        }
                    }
                }
                else if (binExpressionAst.Left.StaticType == typeof(object))
                {
                    return true;
                }
            }

            return false;
        }
Пример #19
0
        public ClosureExpression(Ast.PythonVariable/*!*/ variable, Expression/*!*/ closureCell, Expression parameter) {
            Assert.NotNull(closureCell);

            _variable = variable;
            _closureCell = closureCell;
            _parameter = parameter;
        }
Пример #20
0
        /// <summary>
        /// AnalyzeScript: Analyze the script to check if cmdlet alias is used.
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            // Finds all CommandAsts.
            IEnumerable<Ast> foundAsts = ast.FindAll(testAst => testAst is CommandAst, true);

            // Iterates all CommandAsts and check the command name.
            foreach (Ast foundAst in foundAsts)
            {
                CommandAst cmdAst = (CommandAst)foundAst;
                string aliasName = cmdAst.GetCommandName();

                // Handles the exception caused by commands like, {& $PLINK $args 2> $TempErrorFile}.
                // You can also review the remark section in following document,
                // MSDN: CommandAst.GetCommandName Method
                if (aliasName == null)
                {
                    continue;
                }
                string cmdletName = Helper.Instance.GetCmdletNameFromAlias(aliasName);
                if (!String.IsNullOrEmpty(cmdletName))
                {
                    yield return new DiagnosticRecord(
                        string.Format(CultureInfo.CurrentCulture, Strings.AvoidUsingCmdletAliasesError, aliasName, cmdletName),
                        cmdAst.Extent,
                        GetName(),
                        DiagnosticSeverity.Warning,
                        fileName,
                        aliasName,
                        suggestedCorrections: GetCorrectionExtent(cmdAst, cmdletName));
                }
            }
        }
        /// <summary>
        /// AnalyzeScript: Analyzes the ast to check that $null is on the left side of any equality comparisons.
        /// <param name="ast">The script's ast</param>
        /// <param name="fileName">The script's file name</param>
        /// <returns>The diagnostic results of this rule</returns>
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName) {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            IEnumerable<Ast> binExpressionAsts = ast.FindAll(testAst => testAst is BinaryExpressionAst, false);

            foreach (BinaryExpressionAst binExpressionAst in binExpressionAsts) {
                if ((binExpressionAst.Operator.Equals(TokenKind.Equals) || binExpressionAst.Operator.Equals(TokenKind.Ceq) 
                    || binExpressionAst.Operator.Equals(TokenKind.Cne) || binExpressionAst.Operator.Equals(TokenKind.Ine) || binExpressionAst.Operator.Equals(TokenKind.Ieq))
                    && binExpressionAst.Right.Extent.Text.Equals("$null", StringComparison.OrdinalIgnoreCase)) 
                {
                    if (IncorrectComparisonWithNull(binExpressionAst, ast))
                    {
                        yield return new DiagnosticRecord(Strings.PossibleIncorrectComparisonWithNullError, binExpressionAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                    }
                }
            }

            IEnumerable<Ast> funcAsts = ast.FindAll(item => item is FunctionDefinitionAst, true).Union(ast.FindAll(item => item is FunctionMemberAst, true));
            foreach (Ast funcAst in funcAsts)
            {
                IEnumerable<Ast> binAsts = funcAst.FindAll(item => item is BinaryExpressionAst, true);
                foreach (BinaryExpressionAst binAst in binAsts)
                {
                    if (IncorrectComparisonWithNull(binAst, funcAst))
                    {
                        yield return new DiagnosticRecord(Strings.PossibleIncorrectComparisonWithNullError, binAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                    }
                }
            }
        }
        /// <summary>
        /// Finds the symbol (always Command type) at a given file location
        /// </summary>
        /// <param name="scriptAst">The abstract syntax tree of the given script</param>
        /// <param name="lineNumber">The line number of the cursor for the given script</param>
        /// <param name="columnNumber">The column number of the cursor for the given script</param>
        /// <returns>SymbolReference of found command</returns>
        public static SymbolReference FindCommandAtPosition(Ast scriptAst, int lineNumber, int columnNumber)
        {
            FindCommandVisitor commandVisitor = new FindCommandVisitor(lineNumber, columnNumber);
            scriptAst.Visit(commandVisitor);

            return commandVisitor.FoundCommandReference;
        }
        /// <summary>
        /// AnalyzeScript: Run Test Module Manifest to check that none of the required fields are missing. From the ILintScriptRule interface.
        /// </summary>
        /// <param name="ast">The script's ast</param>
        /// <param name="fileName">The script's file name</param>
        /// <returns>A List of diagnostic results of this rule</returns>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            if (String.Equals(System.IO.Path.GetExtension(fileName), ".psd1", StringComparison.OrdinalIgnoreCase))
            {
                IEnumerable<ErrorRecord> errorRecords;
                var psModuleInfo = Helper.Instance.GetModuleManifest(fileName, out errorRecords);
                if (errorRecords != null)
                {
                    foreach (var errorRecord in errorRecords)
                    {
                        if (Helper.IsMissingManifestMemberException(errorRecord))
                        {
                            System.Diagnostics.Debug.Assert(
                                errorRecord.Exception != null && !String.IsNullOrWhiteSpace(errorRecord.Exception.Message),
                                Strings.NullErrorMessage);
                            var hashTableAst = ast.Find(x => x is HashtableAst, false);
                            if (hashTableAst == null)
                            {
                                yield break;
                            }
                            yield return new DiagnosticRecord(
                                errorRecord.Exception.Message,
                                hashTableAst.Extent,
                                GetName(),
                                DiagnosticSeverity.Warning,
                                fileName,
                                suggestedCorrections:GetCorrectionExtent(hashTableAst as HashtableAst));
                        }

                    }
                }
            }
        }
Пример #24
0
            public override void Emit(VirtualMachine.InstructionList into, Ast.OperationDestination Destination)
            {
                //Prepare loop control variables
                List.Emit(into, Ast.OperationDestination.Stack);	//__list@
                LengthFunc.Emit(into, Ast.OperationDestination.Stack); //__total@
                into.AddInstructions("MOVE NEXT PUSH # SET __COUNTER@", 0);			//__counter@

                var LoopStart = into.Count;

                into.AddInstructions(
                    "LOAD_PARAMETER NEXT R #" + TotalVariable.Name, TotalVariable.Offset,
                    "GREATER_EQUAL PEEK R R #PEEK = __COUNTER@",
                    "IF_TRUE R",
                    "JUMP NEXT", 0);

                var BreakPoint = into.Count - 1;

                Indexer.Emit(into, Ast.OperationDestination.Stack);
                Body.Emit(into, Ast.OperationDestination.Discard);

                into.AddInstructions(
                    "MOVE POP #REMOVE __VALUE@",
                    "INCREMENT PEEK PEEK",
                    "JUMP NEXT", LoopStart);

                into[BreakPoint] = into.Count;

                into.AddInstructions("CLEANUP NEXT #REMOVE __COUNTER@, __TOTAL@, __LIST@", 3);
            }
        /// <summary>
        /// AnalyzeScript: Analyzes the script to check if any non-constant members have been invoked.
        /// </summary>
        public IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            if (ast == null) throw new ArgumentNullException(Strings.NullAstErrorMessage);

            IEnumerable<Ast> memberExpression = ast.FindAll(testAst => testAst is MemberExpressionAst, true);
            foreach (MemberExpressionAst member in memberExpression)
            {
                string context = member.Member.Extent.ToString();
                if (context.Contains("("))
                {
                    //check if parenthesis and have non-constant members
                    IEnumerable<Ast> binaryExpression = member.FindAll(
                        binaryAst => binaryAst is BinaryExpressionAst, true);
                    if (binaryExpression.Any())
                    {
                        foreach (BinaryExpressionAst bin in binaryExpression)
                        {
                            if (!bin.Operator.Equals(null))
                            {
                                yield return
                                    new DiagnosticRecord(
                                        string.Format(CultureInfo.CurrentCulture,
                                            Strings.AvoidInvokingEmptyMembersError,
                                            context),
                                        member.Extent, GetName(), DiagnosticSeverity.Warning, fileName);
                            }
                        }
                    }
                }
            }
        
        }
 public Ast.Statements.BlockStatement Process(Decompiler.DecompilationContext context, Ast.Statements.BlockStatement body)
 {
     this.methodContext = context.MethodContext;
     mappedInstructions.UnionWith(body.UnderlyingSameMethodInstructions);
     Visit(body);
     return body;
 }
Пример #27
0
 public ForeachIn(Token Source, String VariableName, Ast.Node List, Ast.Node Body)
     : base(Source)
 {
     this.VariableName = VariableName;
     this.List = List;
     this.Body = Body;
 }
Пример #28
0
        public LuaFile Compile(Ast.Chunk c, string name)
        {
            file = new LuaFile();
            block = new Block();
            block.Chunk.Name = name;
            block.Chunk.ArgumentCount = 0;
            block.Chunk.Vararg = 2;

            DoChunk(c);

            file.Main = block.Chunk;
            file.Main.ArgumentCount = 0;
            file.Main.Vararg = 2;
            file.Main.UpvalueCount = file.Main.Upvalues.Count;
            bool addRet = file.Main.Instructions.Count == 0;
            if (addRet == false)
                addRet = file.Main.Instructions[file.Main.Instructions.Count - 1].Opcode != Instruction.LuaOpcode.RETURN;
            if (addRet)
            {
                Instruction ret = new Instruction("RETURN");
                ret.A = 0;
                ret.B = 1;
                ret.C = 0;
                file.Main.Instructions.Add(ret);
            }
            return file;
        }
Пример #29
0
        public static bool IsConstant(Ast ast, out object constantValue, bool forAttribute = false, bool forRequires = false)
        {
            try
            {
                if ((bool)ast.Accept(new IsConstantValueVisitor { CheckingAttributeArgument = forAttribute, CheckingRequiresArgument = forRequires }))
                {
                    Ast parent = ast.Parent;
                    while (parent != null)
                    {
                        if (parent is DataStatementAst)
                        {
                            break;
                        }
                        parent = parent.Parent;
                    }

                    if (parent == null)
                    {
                        constantValue = ast.Accept(new ConstantValueVisitor { AttributeArgument = forAttribute, RequiresArgument = forRequires });
                        return true;
                    }
                }
            }
            catch (Exception e)
            {
                // If we get an exception, ignore it and assume the expression isn't constant.
                // This can happen, e.g. if a cast is invalid:
                //     [int]"zed"
                CommandProcessorBase.CheckForSevereException(e);
            }

            constantValue = null;
            return false;
        }
        /// <summary>
        /// Finds all files dot sourced in a script
        /// </summary>
        /// <param name="scriptAst">The abstract syntax tree of the given script</param>
        /// <returns></returns>
        public static string[] FindDotSourcedIncludes(Ast scriptAst)
        {
            FindDotSourcedVisitor dotSourcedVisitor = new FindDotSourcedVisitor();
            scriptAst.Visit(dotSourcedVisitor);

            return dotSourcedVisitor.DotSourcedFiles.ToArray();
        }
Пример #31
0
 internal MSA.Expression /*!*/ TransformName(AstGenerator /*!*/ gen)
 {
     return(Ast.Constant(_name));
 }
Пример #32
0
        private MSAst.Expression AddModulePublishing(MSAst.Expression body)
        {
            if (_isModule)
            {
                PythonCompilerOptions pco = _compilerContext.Options as PythonCompilerOptions;

                string moduleName = ModuleName;

                if ((pco.Module & ModuleOptions.Initialize) != 0)
                {
                    var tmp = Ast.Variable(typeof(object), "$originalModule");
                    // TODO: Should be try/fault

                    body = Ast.Block(
                        new[] { tmp },
                        AstUtils.Try(
                            Ast.Assign(tmp, Ast.Call(AstMethods.PublishModule, LocalContext, Ast.Constant(moduleName))),
                            body
                            ).Catch(
                            typeof(Exception),
                            Ast.Call(AstMethods.RemoveModule, LocalContext, Ast.Constant(moduleName), tmp),
                            Ast.Rethrow(body.Type)
                            )
                        );
                }
            }
            return(body);
        }
Пример #33
0
        internal MSAst.Expression ReduceWorker()
        {
            var retStmt = _body as ReturnStatement;

            if (retStmt != null &&
                (_languageFeatures == ModuleOptions.None ||
                 _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret) ||
                 _languageFeatures == (ModuleOptions.ExecOrEvalCode | ModuleOptions.Interpret | ModuleOptions.LightThrow)))
            {
                // for simple eval's we can construct a simple tree which just
                // leaves the value on the stack.  Return's can't exist in modules
                // so this is always safe.
                Debug.Assert(!_isModule);

                var ret = (ReturnStatement)_body;
                Ast simpleBody;
                if ((_languageFeatures & ModuleOptions.LightThrow) != 0)
                {
                    simpleBody = LightExceptions.Rewrite(retStmt.Expression.Reduce());
                }
                else
                {
                    simpleBody = retStmt.Expression.Reduce();
                }

                var start = IndexToLocation(ret.Expression.StartIndex);
                var end   = IndexToLocation(ret.Expression.EndIndex);

                return(Ast.Block(
                           Ast.DebugInfo(
                               _document,
                               start.Line,
                               start.Column,
                               end.Line,
                               end.Column
                               ),
                           AstUtils.Convert(simpleBody, typeof(object))
                           ));
            }

            ReadOnlyCollectionBuilder <MSAst.Expression> block = new ReadOnlyCollectionBuilder <MSAst.Expression>();

            AddInitialiation(block);

            if (_isModule)
            {
                block.Add(AssignValue(GetVariableExpression(_docVariable), Ast.Constant(GetDocumentation(_body))));
            }

            if (!(_body is SuiteStatement) && _body.CanThrow)
            {
                // we only initialize line numbers in suite statements but if we don't generate a SuiteStatement
                // at the top level we can miss some line number updates.
                block.Add(UpdateLineNumber(_body.Start.Line));
            }

            block.Add(_body);

            MSAst.Expression body = Ast.Block(block.ToReadOnlyCollection());

            body = WrapScopeStatements(body, Body.CanThrow);   // new ComboActionRewriter().VisitNode(Transform(ag))

            body = AddModulePublishing(body);

            body = AddProfiling(body);

            if ((((PythonCompilerOptions)_compilerContext.Options).Module & ModuleOptions.LightThrow) != 0)
            {
                body = LightExceptions.Rewrite(body);
            }

            body = Ast.Label(FunctionDefinition._returnLabel, AstUtils.Convert(body, typeof(object)));
            if (body.Type == typeof(void))
            {
                body = Ast.Block(body, Ast.Constant(null));
            }

            return(body);
        }
Пример #34
0
        public static Expression MakeRecordTypeDescriptor(Expression[] obj)
        {
            if ((obj.Length == 6 || obj.Length == 7) && IronScheme.Compiler.Generator.VarHint != SymbolId.Empty)
            {
                try
                {
                    var name     = Unwrap(obj[0]);
                    var parent   = Unwrap(obj[1]);
                    var uid      = Unwrap(obj[2]);
                    var issealed = Unwrap(obj[3]);
                    var isopaque = Unwrap(obj[4]);
                    var fields   = obj[5];
                    if (fields is BoundExpression)
                    {
                        return(null);
                    }

                    if (name is BoundExpression)
                    {
                        return(null);
                    }

                    var rname   = ((ConstantExpression)name).Value;
                    var ruid    = ((ConstantExpression)uid).Value;
                    var rsealed = ((ConstantExpression)issealed).Value;
                    var ropaque = ((ConstantExpression)isopaque).Value;

                    object[] rfields = { };

                    if (fields is NewArrayExpression)
                    {
                        var ff      = ((NewArrayExpression)fields).Expressions;
                        var dfields = new Expression[ff.Count];
                        ff.CopyTo(dfields, 0);

                        rfields = Array.ConvertAll(dfields, x => ((ConstantExpression)x).Value);
                    }

                    object[] tfields = Array.ConvertAll(rfields, x => SymbolTable.StringToObject("Object"));

                    if (obj.Length == 7)
                    {
                        var ftypes = obj[6];

                        if (ftypes is NewArrayExpression)
                        {
                            var ff      = ((NewArrayExpression)ftypes).Expressions;
                            var dfields = new Expression[ff.Count];
                            ff.CopyTo(dfields, 0);

                            tfields = Array.ConvertAll(dfields, x => ((ConstantExpression)((UnaryExpression)x).Operand).Value);
                        }
                    }

                    if (!Builtins.IsTrue(ruid))
                    {
                        ruid   = Guid.NewGuid().ToString(); //TODO: recall why this was done :\ Change to gensym if possible
                        obj[2] = Ast.Convert(Ast.Constant(ruid), typeof(object));
                    }

                    object par = null;

                    if (parent is BoundExpression)
                    {
                        par = ((BoundExpression)parent).Variable.Name;
                    }

                    var rtdc = new RecordTypeDescriptorConstant
                    {
                        RecordName = rname,
                        Uid        = ruid,
                        Sealed     = rsealed,
                        Opaque     = ropaque,
                        Parent     = par,
                        Fields     = rfields,
                        FieldTypes = tfields,
                        NameHint   = IronScheme.Compiler.Generator.VarHint,
                    };

                    var at = rtdc.Generate();

                    if (at != null)
                    {
                        ClrGenerator.AddCompileTimeType(at);
                    }

                    var e = Ast.Constant(rtdc);

                    return(Ast.Comma(e, Ast.Call(typeof(Records).GetMethod("MakeRecordTypeDescriptor"), obj)));
                }
                catch
                {
                    throw;
                    //kaboom, redirect to runtime
                }
            }

            return(null);
        }
Пример #35
0
        /// <summary>
        ///     For each spread (named or inline) defined in the document.
        ///     Let fragment be the target of spread
        ///     Let fragmentType be the type condition of fragment
        ///     Let parentType be the type of the selection set containing spread
        ///     Let applicableTypes be the intersection of GetPossibleTypes(fragmentType) and GetPossibleTypes(parentType)
        ///     applicableTypes must not be empty.
        /// </summary>
        /// <returns></returns>
        public static CombineRule R5523FragmentSpreadIsPossible()
        {
            return((context, rule) =>
            {
                var fragments = context.Document.Definitions.OfType <GraphQLFragmentDefinition>()
                                .ToDictionary(f => f.Name.Value);

                rule.EnterFragmentSpread += node =>
                {
                    var fragment = fragments[node.Name.Value];
                    var fragmentType = Ast.TypeFromAst(context.Schema, fragment.TypeCondition);
                    var parentType = context.Tracker.GetParentType();
                    var applicableTypes = GetPossibleTypes(fragmentType, context.Schema)
                                          .Intersect(GetPossibleTypes(parentType, context.Schema));

                    if (!applicableTypes.Any())
                    {
                        context.Error(
                            ValidationErrorCodes.R5523FragmentSpreadIsPossible,
                            "Fragments are declared on a type and will only apply " +
                            "when the runtime object type matches the type condition. They " +
                            "also are spread within the context of a parent type. A fragment " +
                            "spread is only valid if its type condition could ever apply within " +
                            "the parent type. " +
                            $"FragmentSpread: '{node.Name?.Value}'",
                            node);
                    }
                };

                rule.EnterInlineFragment += node =>
                {
                    var fragmentType = Ast.TypeFromAst(context.Schema, node.TypeCondition);
                    var parentType = context.Tracker.GetParentType();
                    var applicableTypes = GetPossibleTypes(fragmentType, context.Schema)
                                          .Intersect(GetPossibleTypes(parentType, context.Schema));

                    if (!applicableTypes.Any())
                    {
                        context.Error(
                            ValidationErrorCodes.R5523FragmentSpreadIsPossible,
                            "Fragments are declared on a type and will only apply " +
                            "when the runtime object type matches the type condition. They " +
                            "also are spread within the context of a parent type. A fragment " +
                            "spread is only valid if its type condition could ever apply within " +
                            "the parent type.",
                            node);
                    }
                };
            });

            ObjectType[] GetPossibleTypes(IType type, ISchema schema)
            {
                switch (type)
                {
                case ObjectType objectType:
                    return(new[] { objectType });

                case InterfaceType interfaceType:
                    return(schema.GetPossibleTypes(interfaceType).ToArray());

                case UnionType unionType:
                    return(schema.GetPossibleTypes(unionType).ToArray());

                default: return(new ObjectType[] { });
                }
            }
        }
Пример #36
0
 protected abstract void VisitTokens(Ast ast);
Пример #37
0
        protected string GetDslInstanceName(ReadOnlyCollection <CommandElementAst> commandElements, Ast parent)
        {
            // todo: what with "configuration" in legacy mode?
            if (commandElements == null || commandElements.Count < 2)
            {
                return(null);
            }


            // in order to be possibly a DSL expression, first element must be StringConstant AND second must not be =
            // AND (first element must start with PSDesiredStateConfiguration - legacy OR (last must be ScriptBlockExpression, and last but 1 must not be CommandParameter))
            if (!(commandElements[0] is StringConstantExpressionAst) ||
                ((commandElements[1] is StringConstantExpressionAst && ((StringConstantExpressionAst)commandElements[1]).Value == "=")))
            {
                return(null);
            }

            string dslTypeName = ((StringConstantExpressionAst)commandElements[0]).Value;

            if (!dslTypeName.StartsWith("PSDesiredStateConfiguration") &&
                !this.dslCustomDictionary.Contains(dslTypeName.ToLowerInvariant()) &&
                (!this.dslAutoDiscovery || (!(commandElements[commandElements.Count - 1] is ScriptBlockExpressionAst || commandElements[commandElements.Count - 1] is HashtableAst) ||
                                            commandElements[commandElements.Count - 2] is CommandParameterAst)))
            {
                return(null);
            }

            // additionally, parent must not be a Pipeline that has more than 1 element
            if (parent is PipelineAst && ((PipelineAst)parent).PipelineElements.Count > 1)
            {
                return(null);
            }

            return(this.TrimQuotes(this.GetDslInstanceName(dslTypeName, commandElements)));
        }
Пример #38
0
        static Statement MakeTailCallReturn(bool allowtailcall, Expression e)
        {
            //if (allowtailcall)
            {
                if (e is MethodCallExpression)
                {
                    MethodCallExpression mce = ((MethodCallExpression)e);
                    mce.TailCall = /*!mce.Method.ReturnType.IsValueType &&*/ allowtailcall;
                }
                else if (e is ConditionalExpression)
                {
                    ConditionalExpression ce        = (ConditionalExpression)e;
                    Statement             truestmt  = OptimizeBody(MakeTailCallReturn(allowtailcall, ce.IfTrue));
                    Statement             falsestmt = OptimizeBody(MakeTailCallReturn(allowtailcall, ce.IfFalse));

                    return(Ast.IfThenElse(ce.Test, truestmt, falsestmt));
                }
                else if (e is CommaExpression)
                {
                    CommaExpression ce = (CommaExpression)e;
                    if (ce.ValueIndex + 1 == ce.Expressions.Count)
                    {
                        List <Statement> ss = new List <Statement>();
                        for (int i = 0; i < ce.Expressions.Count - 1; i++)
                        {
                            ss.Add(Ast.Statement(ce.Expressions[i]));
                        }
                        ss.Add(MakeTailCallReturn(allowtailcall, ce.Expressions[ce.Expressions.Count - 1]));
                        return(OptimizeBody(Ast.Block(ss)));
                    }
                }
                else if (e is NewExpression || e is BoundExpression || e is ConstantExpression || e is MemberExpression)
                {
                    // ignore
                }
                else if (e is UnaryExpression && e.NodeType == AstNodeType.Convert)
                {
                    var op = ((UnaryExpression)e).Operand;

                    if (op is ConditionalExpression)
                    {
                        ConditionalExpression ce        = (ConditionalExpression)op;
                        Statement             truestmt  = OptimizeBody(MakeTailCallReturn(allowtailcall, Ast.ConvertHelper(ce.IfTrue, e.Type)));
                        Statement             falsestmt = OptimizeBody(MakeTailCallReturn(allowtailcall, Ast.ConvertHelper(ce.IfFalse, e.Type)));

                        return(Ast.IfThenElse(ce.Test, truestmt, falsestmt));
                    }
                }
                else if (e is VoidExpression)
                {
                    return(Ast.Return(Ast.Comma(e, Ast.ReadField(null, Unspecified))));
                }
                else
                {
                }
            }

            return(Ast.Return(e));
        }
Пример #39
0
        protected internal static void FillBody(CodeBlock cb, List <Statement> stmts, Cons body, bool allowtailcall)
        {
            Cons c = body;

            while (c != null)
            {
                Expression e = GetAst(c.car, cb, c.cdr == null);
                Statement  s = null;
                if (c.cdr == null)
                {
                    if (e.Type != cb.ReturnType)
                    {
                        Expression ee = e;
                        while (ee is UnaryExpression)
                        {
                            var ue = ee as UnaryExpression;
                            if (ue.NodeType != AstNodeType.Convert)
                            {
                                break;
                            }
                            if (ue.Operand.Type == cb.ReturnType)
                            {
                                e = ue.Operand;
                                break;
                            }
                            ee = ue.Operand;
                        }
                        if (!(e is VoidExpression))
                        {
                            e = Ast.ConvertHelper(e, cb.ReturnType);
                        }
                    }
                    s = MakeTailCallReturn(allowtailcall, e);
                }
                else
                {
                    s = Ast.Statement(e);
                }

                stmts.Add(s);
                c = c.cdr as Cons;
            }

            if (stmts.Count == 0)
            {
                stmts.Add(Ast.Return(Ast.ReadField(null, Unspecified)));
            }

            if (cb.Body != null)
            {
                stmts.InsertRange(0, (cb.Body as BlockStatement).Statements);
            }

            cb.Body = Ast.Block(stmts);
            cb.Body = OptimizeBody(cb.Body);

            if (cb.Parent == null || (cb.Parent.IsGlobal && cb.ParameterCount < 9))
            {
                cb.ExplicitCodeContextExpression = Ast.CodeContext();
            }
        }
        // TODO: BRING THIS BACK
        /// <summary>
        /// Gets completions for the symbol found in the Ast at
        /// the given file offset.
        /// </summary>
        /// <param name="scriptAst">
        /// The Ast which will be traversed to find a completable symbol.
        /// </param>
        /// <param name="currentTokens">
        /// The array of tokens corresponding to the scriptAst parameter.
        /// </param>
        /// <param name="fileOffset">
        /// The 1-based file offset at which a symbol will be located.
        /// </param>
        /// <param name="powerShellContext">
        /// The PowerShellContext to use for gathering completions.
        /// </param>
        /// <param name="logger">An ILogger implementation used for writing log messages.</param>
        /// <param name="cancellationToken">
        /// A CancellationToken to cancel completion requests.
        /// </param>
        /// <returns>
        /// A CommandCompletion instance that contains completions for the
        /// symbol at the given offset.
        /// </returns>
        public static async Task <CommandCompletion> GetCompletionsAsync(
            Ast scriptAst,
            Token[] currentTokens,
            int fileOffset,
            PowerShellContextService powerShellContext,
            ILogger logger,
            CancellationToken cancellationToken)
        {
            if (!s_completionHandle.Wait(0, CancellationToken.None))
            {
                return(null);
            }

            try
            {
                IScriptPosition cursorPosition = (IScriptPosition)s_extentCloneWithNewOffset.Invoke(
                    scriptAst.Extent.StartScriptPosition,
                    new object[] { fileOffset });

                logger.LogTrace(
                    string.Format(
                        "Getting completions at offset {0} (line: {1}, column: {2})",
                        fileOffset,
                        cursorPosition.LineNumber,
                        cursorPosition.ColumnNumber));

                if (!powerShellContext.IsAvailable)
                {
                    return(null);
                }

                var stopwatch = new Stopwatch();

                // If the current runspace is out of process we can use
                // CommandCompletion.CompleteInput because PSReadLine won't be taking up the
                // main runspace.
                if (powerShellContext.IsCurrentRunspaceOutOfProcess())
                {
                    using (RunspaceHandle runspaceHandle = await powerShellContext.GetRunspaceHandleAsync(cancellationToken).ConfigureAwait(false))
                        using (System.Management.Automation.PowerShell powerShell = System.Management.Automation.PowerShell.Create())
                        {
                            powerShell.Runspace = runspaceHandle.Runspace;
                            stopwatch.Start();
                            try
                            {
                                return(CommandCompletion.CompleteInput(
                                           scriptAst,
                                           currentTokens,
                                           cursorPosition,
                                           options: null,
                                           powershell: powerShell));
                            }
                            finally
                            {
                                stopwatch.Stop();
                                logger.LogTrace($"IntelliSense completed in {stopwatch.ElapsedMilliseconds}ms.");
                            }
                        }
                }

                CommandCompletion commandCompletion = null;
                await powerShellContext.InvokeOnPipelineThreadAsync(
                    pwsh =>
                {
                    stopwatch.Start();
                    commandCompletion = CommandCompletion.CompleteInput(
                        scriptAst,
                        currentTokens,
                        cursorPosition,
                        options: null,
                        powershell: pwsh);
                }).ConfigureAwait(false);

                stopwatch.Stop();
                logger.LogTrace($"IntelliSense completed in {stopwatch.ElapsedMilliseconds}ms.");

                return(commandCompletion);
            }
            finally
            {
                s_completionHandle.Release();
            }
        }
Пример #41
0
        protected static Expression MakeCaseClosure(string name, List <CodeBlockDescriptor> cases)
        {
            List <Expression> targets = new List <Expression>();
            List <Expression> arities = new List <Expression>();

            foreach (CodeBlockDescriptor c in cases)
            {
                targets.Add(c.codeblock);
                arities.Add(Ast.Constant(c.arity));
            }

            return(Ast.SimpleCallHelper(Closure_MakeCase,
                                        Ast.NewArrayHelper(typeof(Delegate[]), targets), Ast.NewArrayHelper(typeof(int[]), arities)));
        }
Пример #42
0
        // interesting flow control... :S
        static Expression OptimizeExpression(Expression e, List <Statement> stmts)
        {
            if (e is ConstantExpression)
            {
                return(null);
            }

            if (e is BoundExpression)
            {
                // fails for (begin wtf 1) where wtf is undefined
                //return null;
            }

            if (e is MethodCallExpression)
            {
                //remove methods without side effects
            }

            if (IsUnspecified(e) && !ScriptDomainManager.Options.LightweightDebugging)
            {
                return(null);
            }

            if (e is ConditionalExpression)
            {
                ConditionalExpression ce = e as ConditionalExpression;

                if (IsUnspecified(ce.IfFalse))
                {
                    stmts.Add(Ast.If(ce.Test, OptimizeBody(Ast.Statement(ce.IfTrue))));
                }
                else
                {
                    stmts.Add(Ast.If(ce.Test, OptimizeBody(Ast.Statement(ce.IfTrue))).Else(OptimizeBody(Ast.Statement(ce.IfFalse))));
                }

                return(null);
            }

            return(e);
        }
Пример #43
0
        private void EnsureTracingTarget()
        {
            if (_tracingTarget == null)
            {
                PythonContext pc = (PythonContext)Ast.CompilerContext.SourceUnit.LanguageContext;

                var debugProperties = new PythonDebuggingPayload(null);

                var debugInfo = new Microsoft.Scripting.Debugging.CompilerServices.DebugLambdaInfo(
                    null,           // IDebugCompilerSupport
                    null,           // lambda alias
                    false,          // optimize for leaf frames
                    null,           // hidden variables
                    null,           // variable aliases
                    debugProperties // custom payload
                    );

                var lambda = (Expression <LookupCompilationDelegate>)pc.DebugContext.TransformLambda((MSAst.LambdaExpression)Ast.GetLambda().Reduce(), debugInfo);

                LookupCompilationDelegate func;
                if (ShouldInterpret(pc))
                {
                    func = (LookupCompilationDelegate)CompilerHelpers.LightCompile(lambda, pc.Options.CompilationThreshold);
                }
                else
                {
                    func = (LookupCompilationDelegate)lambda.Compile(pc.EmitDebugSymbols(Ast.CompilerContext.SourceUnit));
                }

                _tracingTarget       = func;
                debugProperties.Code = EnsureFunctionCode(_tracingTarget, true, true);
            }
        }
Пример #44
0
 protected static Expression MakeClosure(CodeBlock cb, bool varargs, bool typed)
 {
     if (varargs)
     {
         return(Ast.SimpleCallHelper(Closure_MakeVarArgsX, Ast.CodeBlockExpression(cb, false, typed),
                                     Ast.Constant(cb.ParameterCount)));
     }
     else
     {
         return(Ast.SimpleCallHelper(Closure_Make, Ast.CodeBlockExpression(cb, false, typed), Ast.Constant(cb.ParameterCount)));
     }
 }
Пример #45
0
        /// <summary>
        /// Report some telemetry about the scripts that are run
        /// </summary>
        internal static void ReportScriptTelemetry(Ast ast, bool dotSourced, long compileTimeInMS)
        {
            if (ast.Parent != null || !TelemetryWrapper.IsEnabled)
            {
                return;
            }

            Task.Run(() =>
            {
                var extent = ast.Extent;
                var text   = extent.Text;
                var hash   = text.GetHashCode();

                // Ignore 'prompt' so we don't generate an event for every 'prompt' that is invoked.
                // (We really should only create 'prompt' once, but we don't.
                if (hash == s_promptHashCode)
                {
                    return;
                }

                var visitor = new ScriptBlockTelemetry();

                ast.Visit(visitor);

                var scriptFileType = ScriptFileType.None;
                var fileName       = extent.File;
                if (fileName != null)
                {
                    var ext = System.IO.Path.GetExtension(fileName);
                    if (".ps1".Equals(ext, StringComparison.OrdinalIgnoreCase))
                    {
                        scriptFileType = ScriptFileType.Ps1;
                    }
                    else if (".psd1".Equals(ext, StringComparison.OrdinalIgnoreCase))
                    {
                        scriptFileType = ScriptFileType.Psd1;
                    }
                    else if (".psm1".Equals(ext, StringComparison.OrdinalIgnoreCase))
                    {
                        scriptFileType = ScriptFileType.Psm1;
                    }
                    else
                    {
                        // Reachable?
                        scriptFileType = ScriptFileType.Other;
                    }
                }

                TelemetryWrapper.TraceMessage("PSScriptDetails", new
                {
                    Hash                        = hash,
                    IsDotSourced                = dotSourced,
                    ScriptFileType              = scriptFileType,
                    Length                      = text.Length,
                    LineCount                   = extent.EndLineNumber - extent.StartLineNumber,
                    CompileTimeInMS             = compileTimeInMS,
                    StatementCount              = visitor.StatementCount,
                    CountOfCommands             = visitor.CountOfCommands,
                    CountOfDotSourcedCommands   = visitor.CountOfDotSourcedCommands,
                    MaxArrayLength              = visitor.MaxArraySize,
                    ArrayLiteralCount           = visitor.ArrayLiteralCount,
                    ArrayLiteralCumulativeSize  = visitor.ArrayLiteralCumulativeSize,
                    MaxStringLength             = visitor.MaxStringSize,
                    StringLiteralCount          = visitor.StringLiteralCount,
                    StringLiteralCumulativeSize = visitor.StringLiteralCumulativeSize,
                    MaxPipelineDepth            = visitor.MaxPipelineDepth,
                    PipelineCount               = visitor.PipelineCount,
                    FunctionCount               = visitor.FunctionCount,
                    ScriptBlockCount            = visitor.ScriptBlockCount,
                    ClassCount                  = visitor.ClassCount,
                    EnumCount                   = visitor.EnumCount,
                    CommandsCalled              = visitor.CommandsCalled,
                });
            });
        }
Пример #46
0
        static Expression Read(SymbolId name, CodeBlock cb, Type type)
        {
            SymbolId sname = name;

            Variable v = cb.Lookup(sname);

            if (v == null)
            {
                if (assigns.ContainsKey(sname))
                {
                    return(Ast.Read(sname));
                }
                else
                {
                    CodeBlock tl = GetTopLevel(cb);
                    v = tl.CreateVariable(sname, Variable.VariableKind.Global, typeof(object), Ast.Read(sname));
                    return(Ast.Read(v));
                }
            }

            return(Ast.ReadDefined(v));
        }
Пример #47
0
 private Expression MakeReturn(Expression expression)
 {
     return(Ast.Return(_return, AstUtils.Convert(expression, _return.Type)));
 }
Пример #48
0
        /// <summary>
        /// AnalyzeScript: Check if any uninitialized variable is used.
        /// </summary>
        public IEnumerable <DiagnosticRecord> AnalyzeScript(Ast ast, string fileName)
        {
            // TODO : We need to find another way for using S.M.A.L.Compiler.GetExpressionValue.
            // Following code are not working for certain scenarios;, like:
            // for ($i=1; $i -le 10; $i++){Write-Host $i}

            if (ast == null)
            {
                throw new ArgumentNullException(Strings.NullAstErrorMessage);
            }

            // Finds all VariableExpressionAst
            IEnumerable <Ast> foundAsts = ast.FindAll(testAst => testAst is VariableExpressionAst, true);

            // Iterates all VariableExpressionAst and check the command name.
            foreach (VariableExpressionAst varAst in foundAsts)
            {
                if (Helper.Instance.IsUninitialized(varAst, ast))
                {
                    yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
                                                      varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath));
                }
            }

            IEnumerable <Ast> funcAsts       = ast.FindAll(item => item is FunctionDefinitionAst, true);
            IEnumerable <Ast> funcMemberAsts = ast.FindAll(item => item is FunctionMemberAst, true);

            // Checks whether this is a dsc resource file (we don't raise this rule for get, set and test-target resource
            bool isDscResourceFile = Helper.Instance.IsDscResourceModule(fileName);

            List <string> targetResourcesFunctions = new List <string>(new string[] { "get-targetresource", "set-targetresource", "test-targetresource" });

            foreach (FunctionDefinitionAst funcAst in funcAsts)
            {
                // Finds all VariableExpressionAst.
                IEnumerable <Ast> varAsts = funcAst.FindAll(testAst => testAst is VariableExpressionAst, true);

                HashSet <string> paramVariables = new HashSet <string>();

                if (isDscResourceFile && targetResourcesFunctions.Contains(funcAst.Name, StringComparer.OrdinalIgnoreCase))
                {
                    // don't raise the rules for variables in the param block.
                    if (funcAst.Body != null && funcAst.Body.ParamBlock != null && funcAst.Body.ParamBlock.Parameters != null)
                    {
                        paramVariables.UnionWith(funcAst.Body.ParamBlock.Parameters.Select(paramAst => paramAst.Name.VariablePath.UserPath));
                    }
                }

                // Iterates all VariableExpressionAst and check the command name.
                foreach (VariableExpressionAst varAst in varAsts)
                {
                    if (Helper.Instance.IsUninitialized(varAst, funcAst) && !paramVariables.Contains(varAst.VariablePath.UserPath))
                    {
                        yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
                                                          varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath));
                    }
                }
            }

            foreach (FunctionMemberAst funcMemAst in funcMemberAsts)
            {
                // Finds all VariableExpressionAst.
                IEnumerable <Ast> varAsts = funcMemAst.FindAll(testAst => testAst is VariableExpressionAst, true);

                // Iterates all VariableExpressionAst and check the command name.
                foreach (VariableExpressionAst varAst in varAsts)
                {
                    if (Helper.Instance.IsUninitialized(varAst, funcMemAst))
                    {
                        yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.AvoidUninitializedVariableError, varAst.VariablePath.UserPath),
                                                          varAst.Extent, GetName(), DiagnosticSeverity.Warning, fileName, varAst.VariablePath.UserPath));
                    }
                }
            }
        }
Пример #49
0
        private DynamicMetaObject TryPythonConversion(DynamicMetaObjectBinder conversion, Type type)
        {
            if (!type.IsEnum())
            {
                switch (type.GetTypeCode())
                {
                case TypeCode.Object:
                    if (type == typeof(Complex))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__complex__", "ConvertToComplex",
                                                      (() => MakeConvertRuleForCall(conversion, type, this, "__float__", "ConvertToFloat",
                                                                                    (() => FallbackConvert(conversion)),
                                                                                    (x) => Ast.Call(null, typeof(PythonOps).GetMethod("ConvertFloatToComplex"), x))),
                                                      (x) => x));
                    }
                    else if (type == typeof(BigInteger))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__long__", "ConvertToLong"));
                    }
                    else if (type == typeof(IEnumerable))
                    {
                        return(PythonConversionBinder.ConvertToIEnumerable(conversion, Restrict(Value.GetType())));
                    }
                    else if (type == typeof(IEnumerator))
                    {
                        return(PythonConversionBinder.ConvertToIEnumerator(conversion, Restrict(Value.GetType())));
                    }
                    else if (type.IsSubclassOf(typeof(Delegate)))
                    {
                        return(MakeDelegateTarget(conversion, type, Restrict(Value.GetType())));
                    }
                    break;

                case TypeCode.Int32:
                    return(MakeConvertRuleForCall(conversion, type, this, "__int__", "ConvertToInt"));

                case TypeCode.Double:
                    return(MakeConvertRuleForCall(conversion, type, this, "__float__", "ConvertToFloat"));

                case TypeCode.Boolean:
                    return(PythonProtocol.ConvertToBool(
                               conversion,
                               this
                               ));

                case TypeCode.String:
                    if (!typeof(Extensible <string>).IsAssignableFrom(this.LimitType))
                    {
                        return(MakeConvertRuleForCall(conversion, type, this, "__str__", "ConvertToString"));
                    }
                    break;
                }
            }

            return(null);
        }
Пример #50
0
        internal static DynamicMetaObject Call(DynamicMetaObjectBinder /*!*/ call, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args)
        {
            Assert.NotNull(call, args);
            Assert.NotNullItems(args);

            if (target.NeedsDeferral())
            {
                return(call.Defer(ArrayUtils.Insert(target, args)));
            }

            foreach (DynamicMetaObject mo in args)
            {
                if (mo.NeedsDeferral())
                {
                    RestrictTypes(args);

                    return(call.Defer(
                               ArrayUtils.Insert(target, args)
                               ));
                }
            }

            DynamicMetaObject self = target.Restrict(target.GetLimitType());

            ValidationInfo valInfo   = BindingHelpers.GetValidationInfo(target);
            PythonType     pt        = DynamicHelpers.GetPythonType(target.Value);
            PythonContext  pyContext = PythonContext.GetPythonContext(call);

            // look for __call__, if it's present dispatch to it.  Otherwise fall back to the
            // default binder
            PythonTypeSlot callSlot;

            if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) &&
                pt.TryResolveSlot(pyContext.SharedContext, "__call__", out callSlot))
            {
                ConditionalBuilder cb = new ConditionalBuilder(call);
                Expression         body;

                callSlot.MakeGetExpression(
                    pyContext.Binder,
                    PythonContext.GetCodeContext(call),
                    self,
                    GetPythonType(self),
                    cb
                    );

                if (!cb.IsFinal)
                {
                    cb.FinishCondition(GetCallError(call, self));
                }

                Expression[] callArgs = ArrayUtils.Insert(
                    PythonContext.GetCodeContext(call),
                    cb.GetMetaObject().Expression,
                    DynamicUtils.GetExpressions(args)
                    );

                body = DynamicExpression.Dynamic(
                    PythonContext.GetPythonContext(call).Invoke(
                        BindingHelpers.GetCallSignature(call)
                        ),
                    typeof(object),
                    callArgs
                    );

                body = Ast.TryFinally(
                    Ast.Block(
                        Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPushFrame)), Ast.Constant(pyContext)),
                        body
                        ),
                    Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPopFrame)))
                    );

                return(BindingHelpers.AddDynamicTestAndDefer(
                           call,
                           new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))),
                           args,
                           valInfo
                           ));
            }

            return(null);
        }
Пример #51
0
        protected override bool Build(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, bool defaultFallback)
        {
            RubyModule currentDeclaringModule;
            string     currentMethodName;

            var scope     = args.Scope;
            var scopeExpr = AstUtils.Convert(args.MetaScope.Expression, typeof(RubyScope));

            RubyScope targetScope;
            int       scopeNesting = scope.GetSuperCallTarget(out currentDeclaringModule, out currentMethodName, out targetScope);

            if (scopeNesting == -1)
            {
                metaBuilder.AddCondition(Methods.IsSuperOutOfMethodScope.OpCall(scopeExpr));
                metaBuilder.SetError(Methods.MakeTopLevelSuperException.OpCall());
                return(true);
            }

            object target           = targetScope.SelfObject;
            var    targetExpression = metaBuilder.GetTemporary(typeof(object), "#super-self");
            var    assignTarget     = Ast.Assign(
                targetExpression,
                Methods.GetSuperCallTarget.OpCall(scopeExpr, AstUtils.Constant(scopeNesting))
                );

            if (_signature.HasImplicitArguments && targetScope.Kind == ScopeKind.BlockMethod)
            {
                metaBuilder.AddCondition(Ast.NotEqual(assignTarget, Ast.Field(null, Fields.NeedsUpdate)));
                metaBuilder.SetError(Methods.MakeImplicitSuperInBlockMethodError.OpCall());
                return(true);
            }

            // If we need to update we return RubyOps.NeedsUpdate instance that will cause the subsequent conditions to fail:
            metaBuilder.AddInitialization(assignTarget);

            args.SetTarget(targetExpression, target);

            Debug.Assert(currentDeclaringModule != null);

            RubyMemberInfo method;
            RubyMemberInfo methodMissing = null;

            // MRI bug: Uses currentDeclaringModule for method look-up so we can end up with an instance method of class C
            // called on a target of another class. See http://redmine.ruby-lang.org/issues/show/2419.

            // we need to lock the hierarchy of the target class:
            var targetClass = scope.RubyContext.GetImmediateClassOf(target);

            using (targetClass.Context.ClassHierarchyLocker()) {
                // initialize all methods in ancestors:
                targetClass.InitializeMethodsNoLock();

                // target is stored in a local, therefore it cannot be part of the restrictions:
                metaBuilder.TreatRestrictionsAsConditions = true;
                metaBuilder.AddTargetTypeTest(target, targetClass, targetExpression, args.MetaContext,
                                              new[] { Symbols.MethodMissing } // currentMethodName is resolved for super, which cannot be an instance singleton
                                              );
                metaBuilder.TreatRestrictionsAsConditions = false;

                method = targetClass.ResolveSuperMethodNoLock(currentMethodName, currentDeclaringModule).InvalidateSitesOnOverride().Info;

                if (_signature.ResolveOnly)
                {
                    metaBuilder.Result = AstUtils.Constant(method != null);
                    return(true);
                }

                if (method == null)
                {
                    // MRI: method_missing is called for the targetClass, not for the super:
                    methodMissing = targetClass.ResolveMethodMissingForSite(currentMethodName, RubyMethodVisibility.None);
                }
            }

            if (method != null)
            {
                method.BuildSuperCall(metaBuilder, args, currentMethodName, currentDeclaringModule);
            }
            else
            {
                return(RubyCallAction.BuildMethodMissingCall(metaBuilder, args, currentMethodName, methodMissing, RubyMethodVisibility.None, true, defaultFallback));
            }

            return(true);
        }
Пример #52
0
        private DynamicMetaObject /*!*/ MakeConvertRuleForCall(DynamicMetaObjectBinder /*!*/ convertToAction, Type toType, DynamicMetaObject /*!*/ self, string name, string returner, Func <DynamicMetaObject> fallback, Func <Expression, Expression> resultConverter)
        {
            PythonType     pt = ((IPythonObject)self.Value).PythonType;
            PythonTypeSlot pts;
            CodeContext    context = PythonContext.GetPythonContext(convertToAction).SharedContext;
            ValidationInfo valInfo = BindingHelpers.GetValidationInfo(this, pt);

            if (pt.TryResolveSlot(context, name, out pts) && !IsBuiltinConversion(context, pts, name, pt))
            {
                ParameterExpression tmp = Ast.Variable(typeof(object), "func");

                Expression callExpr = resultConverter(
                    Ast.Call(
                        PythonOps.GetConversionHelper(returner, GetResultKind(convertToAction)),
                        Ast.Dynamic(
                            PythonContext.GetPythonContext(convertToAction).InvokeNone,
                            typeof(object),
                            PythonContext.GetCodeContext(convertToAction),
                            tmp
                            )
                        )
                    );

                if (typeof(Extensible <>).MakeGenericType(toType).IsAssignableFrom(self.GetLimitType()))
                {
                    // if we're doing a conversion to the underlying type and we're an
                    // Extensible<T> of that type:

                    // if an extensible type returns it's self in a conversion, then we need
                    // to actually return the underlying value.  If an extensible just keeps
                    // returning more instances  of it's self a stack overflow occurs - both
                    // behaviors match CPython.
                    callExpr = AstUtils.Convert(AddExtensibleSelfCheck(convertToAction, toType, self, callExpr), typeof(object));
                }

                return(BindingHelpers.AddDynamicTestAndDefer(
                           convertToAction,
                           new DynamicMetaObject(
                               Ast.Condition(
                                   MakeTryGetTypeMember(
                                       PythonContext.GetPythonContext(convertToAction),
                                       pts,
                                       self.Expression,
                                       tmp
                                       ),
                                   callExpr,
                                   AstUtils.Convert(
                                       ConversionFallback(convertToAction),
                                       typeof(object)
                                       )
                                   ),
                               self.Restrict(self.GetRuntimeType()).Restrictions
                               ),
                           new DynamicMetaObject[] { this },
                           valInfo,
                           tmp
                           ));
            }

            return(fallback());
        }
Пример #53
0
        private DynamicMetaObject TryToCharConversion(DynamicMetaObject /*!*/ self)
        {
            DynamicMetaObject res;
            // we have an implicit conversion to char if the
            // string length == 1, but we can only represent
            // this is implicit via a rule.
            string     strVal  = self.Value as string;
            Expression strExpr = self.Expression;

            if (strVal == null)
            {
                if (self.Value is Extensible <string> extstr)
                {
                    strVal  = extstr.Value;
                    strExpr =
                        Ast.Property(
                            AstUtils.Convert(
                                strExpr,
                                typeof(Extensible <string>)
                                ),
                            typeof(Extensible <string>).GetProperty(nameof(Extensible <string> .Value))
                            );
                }
            }

            // we can only produce a conversion if we have a string value...
            if (strVal != null)
            {
                self = self.Restrict(self.GetRuntimeType());

                Expression getLen = Ast.Property(
                    AstUtils.Convert(
                        strExpr,
                        typeof(string)
                        ),
                    typeof(string).GetProperty("Length")
                    );

                if (strVal.Length == 1)
                {
                    res = new DynamicMetaObject(
                        Ast.Call(
                            AstUtils.Convert(strExpr, typeof(string)),
                            typeof(string).GetMethod("get_Chars", new[] { typeof(int) }),
                            AstUtils.Constant(0)
                            ),
                        self.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Ast.Equal(getLen, AstUtils.Constant(1))))
                        );
                }
                else
                {
                    res = new DynamicMetaObject(
                        this.Throw(
                            Ast.Call(
                                typeof(PythonOps).GetMethod(nameof(PythonOps.TypeError)),
                                AstUtils.Constant("expected string of length 1 when converting to char, got '{0}'"),
                                Ast.NewArrayInit(typeof(object), self.Expression)
                                ),
                            ReturnType
                            ),
                        self.Restrictions.Merge(BindingRestrictions.GetExpressionRestriction(Ast.NotEqual(getLen, AstUtils.Constant(1))))
                        );
                }
            }
            else
            {
                // let the base class produce the rule
                res = null;
            }

            return(res);
        }
Пример #54
0
 public ScriptEntryInfo(Ast script)
 {
     _start = script.Extent.StartOffset;
     _end   = script.Extent.EndOffset;
 }
Пример #55
0
        internal override MSAst.Expression TransformSet(SourceSpan span, MSAst.Expression right, PythonOperationKind op)
        {
            // if we just have a simple named multi-assignment  (e.g. a, b = 1,2)
            // then go ahead and step over the entire statement at once.  If we have a
            // more complex statement (e.g. a.b, c.d = 1, 2) then we'll step over the
            // sets individually as they could be property sets the user wants to step
            // into.  TODO: Enable stepping of the right hand side?
            bool emitIndividualSets = false;

            foreach (Expression e in _items)
            {
                if (IsComplexAssignment(e))
                {
                    emitIndividualSets = true;
                    break;
                }
            }

            SourceSpan rightSpan = SourceSpan.None;
            SourceSpan leftSpan  =
                (Span.Start.IsValid && span.IsValid) ?
                new SourceSpan(Span.Start, span.End) :
                SourceSpan.None;

            SourceSpan totalSpan = SourceSpan.None;

            if (emitIndividualSets)
            {
                rightSpan = span;
                leftSpan  = SourceSpan.None;
                totalSpan = (Span.Start.IsValid && span.IsValid) ?
                            new SourceSpan(Span.Start, span.End) :
                            SourceSpan.None;
            }

            // 1. Evaluate the expression and assign the value to the temp.
            MSAst.ParameterExpression right_temp = Ast.Variable(typeof(object), "unpacking");

            // 2. Add the assignment "right_temp = right" into the suite/block
            MSAst.Expression assignStmt1 = MakeAssignment(right_temp, right);

            int expected    = _items.Length;
            int argcntafter = -1;

            for (var i = 0; i < _items.Length; i++)
            {
                var item = _items[i];
                if (item is StarredExpression)
                {
                    expected    = i;
                    argcntafter = _items.Length - i - 1;
                    break;
                }
            }

            // 3. Call GetEnumeratorValues on the right side (stored in temp)
            MSAst.Expression enumeratorValues = Expression.Convert(LightExceptions.CheckAndThrow(
                                                                       Expression.Call(
                                                                           // method
                                                                           argcntafter != -1 ?
                                                                           AstMethods.UnpackIterable :
                                                                           emitIndividualSets ?
                                                                           AstMethods.GetEnumeratorValues :
                                                                           AstMethods.GetEnumeratorValuesNoComplexSets,
                                                                           // arguments
                                                                           Parent.LocalContext,
                                                                           right_temp,
                                                                           AstUtils.Constant(expected),
                                                                           AstUtils.Constant(argcntafter)
                                                                           )
                                                                       ), typeof(object[]));

            // 4. Create temporary variable for the array
            MSAst.ParameterExpression array_temp = Ast.Variable(typeof(object[]), "array");

            // 5. Assign the value of the method call (mce) into the array temp
            // And add the assignment "array_temp = Ops.GetEnumeratorValues(...)" into the block
            MSAst.Expression assignStmt2 = MakeAssignment(
                array_temp,
                enumeratorValues,
                rightSpan
                );

            ReadOnlyCollectionBuilder <MSAst.Expression> sets = new ReadOnlyCollectionBuilder <MSAst.Expression>(_items.Length + 1);

            for (int i = 0; i < _items.Length; i++)
            {
                // target = array_temp[i]

                Expression target = _items[i];
                if (target == null)
                {
                    continue;
                }

                // 6. array_temp[i]
                MSAst.Expression element = Ast.ArrayAccess(
                    array_temp,                             // array expression
                    AstUtils.Constant(i)                    // index
                    );

                // 7. target = array_temp[i], and add the transformed assignment into the list of sets
                MSAst.Expression set = target.TransformSet(
                    emitIndividualSets ?                    // span
                    target.Span :
                    SourceSpan.None,
                    element,
                    PythonOperationKind.None
                    );
                sets.Add(set);
            }
            // 9. add the sets as their own block so they can be marked as a single span, if necessary.
            sets.Add(AstUtils.Empty());
            MSAst.Expression itemSet = GlobalParent.AddDebugInfo(Ast.Block(sets.ToReadOnlyCollection()), leftSpan);

            // 10. Return the suite statement (block)
            return(GlobalParent.AddDebugInfo(Ast.Block(new[] { array_temp, right_temp }, assignStmt1, assignStmt2, itemSet, AstUtils.Empty()), totalSpan));
        }
Пример #56
0
        internal override void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name)
        {
            var visibleOverloads = GetVisibleOverloads(args, MethodBases, false);

            if (visibleOverloads.Count == 0)
            {
                metaBuilder.SetError(Methods.MakeClrProtectedMethodCalledError.OpCall(
                                         args.MetaContext.Expression, args.MetaTarget.Expression, Ast.Constant(name)
                                         ));
            }
            else
            {
                BuildCallNoFlow(metaBuilder, args, name, visibleOverloads, CallConvention, ImplicitProtocolConversions);
            }
        }
Пример #57
0
        /// <summary>
        /// Used to analyze scriptblock, functionmemberast or functiondefinitionast
        /// </summary>
        /// <param name="ast"></param>
        /// <returns></returns>
        public void AnalyzeImpl(Ast ast, VariableAnalysis outerAnalysis)
        {
            #if PSV3
            if (!(ast is ScriptBlockAst || ast is FunctionDefinitionAst))
            #else
            if (!(ast is ScriptBlockAst || ast is FunctionMemberAst || ast is FunctionDefinitionAst))
            #endif
            {
                return;
            }

            _variables = FindAllVariablesVisitor.Visit(ast);

            Init();

            #if PSV3
            if (ast is FunctionDefinitionAst)
            #else
            if (ast is FunctionMemberAst || ast is FunctionDefinitionAst)
            #endif
            {
                IEnumerable <ParameterAst> parameters = FindParameters(ast, ast.GetType());
                if (parameters != null)
                {
                    ProcessParameters(parameters);
                }
            }
            else
            {
                ScriptBlockAst sbAst = ast as ScriptBlockAst;
                if (sbAst != null && sbAst.ParamBlock != null && sbAst.ParamBlock.Parameters != null)
                {
                    ProcessParameters(sbAst.ParamBlock.Parameters);
                }
            }

            #if PSV3
            if (ast is FunctionDefinitionAst)
            #else
            if (ast is FunctionMemberAst)
            {
                (ast as FunctionMemberAst).Body.Visit(this.Decorator);
            }
            else if (ast is FunctionDefinitionAst)
            #endif

            {
                (ast as FunctionDefinitionAst).Body.Visit(this.Decorator);
            }
            else
            {
                ast.Visit(this.Decorator);
            }

            Ast parent = ast;

            while (parent.Parent != null)
            {
                parent = parent.Parent;
            }

            #if !PSV3
            List <TypeDefinitionAst> classes = parent.FindAll(item =>
                                                              item is TypeDefinitionAst && (item as TypeDefinitionAst).IsClass, true)
                                               .Cast <TypeDefinitionAst>().ToList();
            #endif

            if (outerAnalysis != null)
            {
                // Initialize the variables from outside
                var outerDictionary = outerAnalysis.InternalVariablesDictionary;
                foreach (var details in outerDictionary.Values)
                {
                    if (details.DefinedBlock != null)
                    {
                        var assignTarget = new AssignmentTarget(details.RealName, details.Type);
                        assignTarget.Constant = details.Constant;
                        if (!_variables.ContainsKey(assignTarget.Name))
                        {
                            _variables.Add(assignTarget.Name, new VariableAnalysisDetails
                            {
                                Name     = assignTarget.Name,
                                RealName = assignTarget.Name,
                                Type     = assignTarget.Type
                            });
                        }
                        Entry.AddFirstAst(assignTarget);
                    }
                }

                foreach (var key in _variables.Keys)
                {
                    if (outerDictionary.ContainsKey(key))
                    {
                        var outerItem = outerDictionary[key];
                        var innerItem = _variables[key];
                        innerItem.Constant = outerItem.Constant;
                        innerItem.Name     = outerItem.Name;
                        innerItem.RealName = outerItem.RealName;
                        innerItem.Type     = outerItem.Type;
                    }
                }
            }

            #if PSV3
            var dictionaries = Block.SparseSimpleConstants(_variables, Entry);
            #else
            var dictionaries = Block.SparseSimpleConstants(_variables, Entry, classes);
            #endif
            VariablesDictionary         = dictionaries.Item1;
            InternalVariablesDictionary = new Dictionary <string, VariableAnalysisDetails>(StringComparer.OrdinalIgnoreCase);

            foreach (var KVP in dictionaries.Item2)
            {
                var analysis = KVP.Value;
                if (analysis == null)
                {
                    continue;
                }

                if (!InternalVariablesDictionary.ContainsKey(analysis.RealName))
                {
                    InternalVariablesDictionary.Add(analysis.RealName, analysis);
                }
                else
                {
                    InternalVariablesDictionary[analysis.RealName] = analysis;
                }
            }
        }
Пример #58
0
        internal DynamicMetaObject FallbackConvert(Type returnType, DynamicMetaObject self, DynamicMetaObject errorSuggestion)
        {
            Type type             = Type;
            DynamicMetaObject res = null;

            switch (type.GetTypeCode())
            {
            case TypeCode.Boolean:
                res = MakeToBoolConversion(self);
                break;

            case TypeCode.Char:
                res = TryToCharConversion(self);
                break;

            case TypeCode.String:
                break;

            case TypeCode.Object:
                // !!! Deferral?
                if (type.IsArray && self.Value is PythonTuple && type.GetArrayRank() == 1)
                {
                    res = MakeToArrayConversion(self, type);
                }
                else if (type == typeof(IBufferProtocol) && !type.IsAssignableFrom(self.GetLimitType()))
                {
                    Type fromType = CompilerHelpers.GetType(self.Value);
                    if (fromType == typeof(Memory <byte>))
                    {
                        res = ConvertFromMemoryToBufferProtocol(self.Restrict(self.GetLimitType()), typeof(Memory <byte>));
                    }
                    else if (fromType == typeof(ReadOnlyMemory <byte>))
                    {
                        res = ConvertFromMemoryToBufferProtocol(self.Restrict(self.GetLimitType()), typeof(ReadOnlyMemory <byte>));
                    }
                    else if (Converter.HasImplicitConversion(fromType, typeof(Memory <byte>)))
                    {
                        res = ConvertFromMemoryToBufferProtocol(self.Restrict(self.GetLimitType()), typeof(Memory <byte>));
                    }
                    else if (Converter.HasImplicitConversion(fromType, typeof(ReadOnlyMemory <byte>)))
                    {
                        res = ConvertFromMemoryToBufferProtocol(self.Restrict(self.GetLimitType()), typeof(ReadOnlyMemory <byte>));
                    }
                }
                else if (type.IsGenericType && !type.IsAssignableFrom(CompilerHelpers.GetType(self.Value)))
                {
                    Type genTo = type.GetGenericTypeDefinition();

                    // Interface conversion helpers...
                    if (type == typeof(IReadOnlyList <byte>) && self.Value is IBufferProtocol)
                    {
                        res = ConvertFromBufferProtocolToByteList(self.Restrict(self.GetLimitType()), typeof(IReadOnlyList <byte>));
                    }
                    else if (type == typeof(IList <byte>) && self.Value is IBufferProtocol)
                    {
                        res = ConvertFromBufferProtocolToByteList(self.Restrict(self.GetLimitType()), typeof(IList <byte>));
                    }
                    else if (genTo == typeof(IList <>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IList <object>), typeof(ListGenericWrapper <>));
                    }
                    else if (genTo == typeof(IDictionary <,>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>));
                    }
                    else if (genTo == typeof(IEnumerable <>))
                    {
                        res = TryToGenericInterfaceConversion(self, type, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>));
                    }
                }
                else if (type == typeof(IEnumerable))
                {
                    if (!typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()))
                    {
                        res = ConvertToIEnumerable(this, self.Restrict(self.GetLimitType()));
                    }
                }
                else if (type == typeof(IEnumerator))
                {
                    if (!typeof(IEnumerator).IsAssignableFrom(self.GetLimitType()) &&
                        !typeof(IEnumerable).IsAssignableFrom(self.GetLimitType()))
                    {
                        res = ConvertToIEnumerator(this, self.Restrict(self.GetLimitType()));
                    }
                }
                break;
            }

            if (type.IsEnum && Enum.GetUnderlyingType(type) == self.GetLimitType())
            {
                // numeric type to enum, this is ok if the value is zero
                object value = Activator.CreateInstance(type);

                return(new DynamicMetaObject(
                           Ast.Condition(
                               Ast.Equal(
                                   AstUtils.Convert(self.Expression, Enum.GetUnderlyingType(type)),
                                   AstUtils.Constant(Activator.CreateInstance(self.GetLimitType()))
                                   ),
                               AstUtils.Constant(value),
                               Ast.Call(
                                   typeof(PythonOps).GetMethod(nameof(PythonOps.TypeErrorForBadEnumConversion)).MakeGenericMethod(type),
                                   AstUtils.Convert(self.Expression, typeof(object))
                                   )
                               ),
                           self.Restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(self.Expression, self.GetLimitType())),
                           value
                           ));
            }

            return(res ?? EnsureReturnType(returnType, Context.Binder.ConvertTo(Type, ResultKind, self, _context.SharedOverloadResolverFactory, errorSuggestion)));
        }
        internal override Expression ToExpression(OverloadResolver resolver, IList <ArgBuilder> builders, RestrictedArguments args, Expression ret)
        {
            List <Expression> sets = new List <Expression>();

            ParameterExpression tmp = resolver.GetTemporary(ret.Type, "val");

            sets.Add(
                Ast.Assign(tmp, ret)
                );

            for (int i = 0; i < _indexesUsed.Length; i++)
            {
                Expression value = args.GetObject(args.Length - _kwArgCount + _indexesUsed[i]).Expression;

                PropertyInfo pi;
                FieldInfo    fi;
                if ((fi = _membersSet[i] as FieldInfo) != null)
                {
                    if (!fi.IsLiteral && !fi.IsInitOnly)
                    {
                        sets.Add(
                            Ast.Assign(
                                Ast.Field(tmp, fi),
                                ConvertToHelper(resolver, value, fi.FieldType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Ast.Convert(
                                Ast.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    AstUtils.Constant(true),
                                    AstUtils.Constant(fi.Name)
                                    ),
                                fi.FieldType
                                )
                            );
                    }
                }
                else if ((pi = _membersSet[i] as PropertyInfo) != null)
                {
                    if (pi.GetSetMethod(_privateBinding) != null)
                    {
                        sets.Add(
                            Ast.Assign(
                                Ast.Property(tmp, pi),
                                ConvertToHelper(resolver, value, pi.PropertyType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Ast.Convert(
                                Ast.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    AstUtils.Constant(false),
                                    AstUtils.Constant(pi.Name)
                                    ),
                                pi.PropertyType
                                )
                            );
                    }
                }
            }

            sets.Add(
                tmp
                );

            Expression newCall = Ast.Block(
                sets.ToArray()
                );

            return(_builder.ToExpression(resolver, builders, args, newCall));
        }
Пример #60
0
 public Call(Ast function, params Ast[] parametersValues)
 {
     Function         = function;
     ParametersValues = parametersValues;
 }