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); } } }
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); }
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; }