public override void PostWalk(CallExpression node)
        {
            if (IsInRange(node) && node.Target != null)
            {
                // For call nodes, we don't want either the call nor the called function to show up,
                // but if it is a method, then we do want to show the object on which it is called.
                // For example, given A.B.C(42), we want A.B to show. By the time we get here, we
                // already have A.B.C in the list, so we need to remove it and reinstate A.B, which
                // will be stored as a value in the dictionary with A.B.C as key.
                Expression oldNode;
                _expressions.TryGetValue(node.Target, out oldNode);
                _expressions.Remove(node.Target);
                if (oldNode != null)
                {
                    _expressions.Add(oldNode, null);
                }

                // Hardcode some commonly used side-effect-free builtins to show even in calls.
                var name = node.Target as NameExpression;
                if (name != null && DetectSideEffectsWalker.IsSideEffectFreeCall(name.Name) && node.Args.All(arg => IsValidTarget(arg.Expression)))
                {
                    _expressions.Add(node, null);
                }
            }
        }
Example #2
0
        private bool IsValidTarget(Node node)
        {
            if (node == null || node is ConstantExpression || node is NameExpression)
            {
                return(true);
            }

            var expr = node as Expression;

            if (expr != null && _expressions.ContainsKey(expr))
            {
                return(true);
            }

            var walker = new DetectSideEffectsWalker();

            node.Walk(walker);
            return(!walker.HasSideEffects);
        }
Example #3
0
        private Response ExpressionForDataTip(AP.ExpressionForDataTipRequest request) {
            var pyEntry = _projectFiles[request.fileId] as IPythonProjectEntry;

            string dataTipExpression = null;
            var options = new CodeFormattingOptions() {
                UseVerbatimImage = false
            };

            if (pyEntry != null && pyEntry.Analysis != null) {
                var ast = pyEntry.Analysis.GetAstFromText(request.expr, new SourceLocation(request.index, request.line, request.column));
                var expr = Statement.GetExpression(ast.Body);

                if (ast != null) {
                    var walker = new DetectSideEffectsWalker();
                    ast.Walk(walker);
                    if (!walker.HasSideEffects) {
                        dataTipExpression = expr?.ToCodeString(ast, new CodeFormattingOptions() { UseVerbatimImage = false });
                    }
                }
            }

            return new AP.ExpressionForDataTipResponse() {
                expression = dataTipExpression
            };
        }
        private bool IsValidTarget(Node node) {
            if (node == null || node is ConstantExpression || node is NameExpression) {
                return true;
            }

            var expr = node as Expression;
            if (expr != null && _expressions.ContainsKey(expr)) {
                return true;
            }

            var walker = new DetectSideEffectsWalker();
            node.Walk(walker);
            return !walker.HasSideEffects;
        }