private static ISet<Namespace> EvaluateListComprehension(ExpressionEvaluator ee, Node node) { ListComprehension listComp = (ListComprehension)node; for(int i = 0; i<listComp.Iterators.Count;i++) { ComprehensionFor compFor = listComp.Iterators[i] as ComprehensionFor; if (compFor != null) { foreach (var listType in ee.Evaluate(compFor.List)) { //ee.AssignTo(node, node.Left, listType.GetEnumeratorTypes(node, _unit)); } } } /* return ee.GlobalScope.GetOrMakeNodeVariable( node, (x) => new ListInfo(new[] { ee.Evaluate(listComp.Item) }, ee._unit.ProjectState._listType).SelfSet);*/ return ee.GlobalScope.GetOrMakeNodeVariable( node, (x) => new ListInfo(new ISet<Namespace>[0], ee._unit.ProjectState._listType).SelfSet); }
private static ISet<Namespace> EvaluateMember(ExpressionEvaluator ee, Node node) { var n = (MemberExpression)node; return ee.Evaluate(n.Target).GetMember(node, ee._unit, n.Name); }
private static ISet<Namespace> MakeLambdaFunction(LambdaExpression node, ExpressionEvaluator ee) { return ee.GlobalScope.NodeVariables[node.Function]; }
/// <summary> /// Evaluates the given expression in at the provided line number and returns the values /// that the expression can evaluate to. /// </summary> /// <param name="exprText">The expression to determine the result of.</param> /// <param name="lineNumber">The line number to evaluate at within the module.</param> public IEnumerable<IAnalysisValue> GetValues(string exprText, int lineNumber) { var expr = GetExpressionFromText(exprText); var scopes = FindScopes(lineNumber); var eval = new ExpressionEvaluator(_unit.CopyForEval(), scopes.ToArray()); var res = eval.Evaluate(expr); foreach (var v in res) { yield return v; } }
private static ISet<Namespace> EvaluateSet(ExpressionEvaluator ee, Node node) { var n = (SetExpression)node; ISet<Namespace> result; if (!ee.GlobalScope.NodeVariables.TryGetValue(node, out result)) { var values = new HashSet<Namespace>(); foreach (var x in n.Items) { values.Union(ee.Evaluate(x)); } result = new DictionaryInfo(values, values, ee.ProjectState, ee.GlobalScope.ShowClr).SelfSet; ee.GlobalScope.NodeVariables[node] = result; } return result; }
private static ISet<Namespace> EvaluateUnary(ExpressionEvaluator ee, Node node) { var n = (UnaryExpression)node; return ee.Evaluate(n.Expression).UnaryOperation(node, ee._unit, n.Op); ; }
private static ISet<Namespace> EvaluateConditional(ExpressionEvaluator ee, Node node) { var n = (ConditionalExpression)node; ee.Evaluate(n.Test); var result = ee.Evaluate(n.TrueExpression); return result.Union(ee.Evaluate(n.FalseExpression)); }
private static ISet<Namespace> EvaluateParenthesis(ExpressionEvaluator ee, Node node) { var n = (ParenthesisExpression)node; return ee.Evaluate(n.Expression); }
private static ISet<Namespace> EvaluateBinary(ExpressionEvaluator ee, Node node) { var n = (BinaryExpression)node; return ee.Evaluate(n.Left).BinaryOperation(node, ee._unit, n.Operator, ee.Evaluate(n.Right)); }
private static ISet<Namespace> EvaluateCall(ExpressionEvaluator ee, Node node) { // TODO: Splatting, keyword args // Get the argument types that we're providing at this call site var n = (CallExpression)node; var argTypes = ee.Evaluate(n.Args); // Then lookup the possible methods we're calling var targetRefs = ee.Evaluate(n.Target); ISet<Namespace> res = EmptySet<Namespace>.Instance; bool madeSet = false; foreach (var target in targetRefs) { res = res.Union(target.Call(node, ee._unit, argTypes, GetNamedArguments(n.Args)), ref madeSet); } return res; }
private static ISet<Namespace> EvaluateBackQuote(ExpressionEvaluator ee, Node node) { var strType = ee.ProjectState.GetNamespaceFromObjects(typeof(string)); return strType.SelfSet; }
private static ISet<Namespace> EvaluateAnd(ExpressionEvaluator ee, Node node) { var n = (AndExpression)node; var result = ee.Evaluate(n.Left); return result.Union(ee.Evaluate(n.Right)); }
/// <summary> /// Gets the variables the given expression evaluates to. Variables include parameters, locals, and fields assigned on classes, modules and instances. /// /// Variables are classified as either definitions or references. Only parameters have unique definition points - all other types of variables /// have only one or more references. /// </summary> public IEnumerable<IAnalysisVariable> GetVariables(string exprText, int lineNumber) { var expr = GetExpressionFromText(exprText); var scopes = FindScopes(lineNumber); var eval = new ExpressionEvaluator(_unit.CopyForEval(), FindScopes(lineNumber).ToArray()); NameExpression name = expr as NameExpression; if (name != null) { for (int i = scopes.Count - 1; i >= 0; i--) { VariableDef def; if (IncludeScope(scopes, i, lineNumber) && scopes[i].Variables.TryGetValue(name.Name, out def)) { foreach (var res in ToVariables(def)) { yield return res; } if (scopes[i] is FunctionScope) { // if this is a parameter or a local indicate any values which we know are assigned to it. foreach (var type in def.Types) { if (type.Location != null) { yield return new AnalysisVariable(VariableType.Value, type.Location); } } } else if (scopes[i] is ModuleScope) { foreach (var type in def.Types) { if (type.Location != null) { yield return new AnalysisVariable(VariableType.Definition, type.Location); } foreach (var reference in type.References) { yield return new AnalysisVariable(VariableType.Reference, reference); } } } } } var variables = _unit.ProjectState.BuiltinModule.GetDefinitions(name.Name); foreach (var referenceable in variables) { foreach (var res in ToVariables(referenceable)) { yield return res; } } } MemberExpression member = expr as MemberExpression; if (member != null) { var objects = eval.Evaluate(member.Target); foreach (var v in objects) { var container = v as IReferenceableContainer; if (container != null) { var defs = container.GetDefinitions(member.Name); foreach (var def in defs) { foreach (var reference in def.Definitions) { yield return new AnalysisVariable(VariableType.Definition, new LocationInfo(reference.Key, reference.Value.Line, reference.Value.Column, reference.Value.Length)); } foreach (var reference in def.References) { yield return new AnalysisVariable(VariableType.Reference, new LocationInfo(reference.Key, reference.Value.Line, reference.Value.Column, reference.Value.Length)); } } } } } }
private static ISet<Namespace> EvaluateName(ExpressionEvaluator ee, Node node) { var n = (NameExpression)node; var res = ee.LookupNamespaceByName(node, n.Name); foreach (var value in res) { value.AddReference(node, ee._unit); } return res; }
private static ISet<Namespace> EvaluateConstant(ExpressionEvaluator ee, Node node) { var n = (ConstantExpression)node; return ee.ProjectState.GetConstant(n.Value); }
private static ISet<Namespace> EvaluateOr(ExpressionEvaluator ee, Node node) { // TODO: Warn if lhs is always false var n = (OrExpression)node; var result = ee.Evaluate(n.Left); return result.Union(ee.Evaluate(n.Right)); }
private static ISet<Namespace> EvaluateDictionary(ExpressionEvaluator ee, Node node) { var n = (DictionaryExpression)node; ISet<Namespace> result; if (!ee.GlobalScope.NodeVariables.TryGetValue(node, out result)) { var keys = new HashSet<Namespace>(); var values = new HashSet<Namespace>(); foreach (var x in n.Items) { foreach (var keyVal in ee.Evaluate(x.SliceStart)) { keys.Add(keyVal); } foreach (var itemVal in ee.Evaluate(x.SliceStop)) { values.Add(itemVal); } } result = new DictionaryInfo(keys, values, ee.ProjectState, ee.GlobalScope.ShowClr).SelfSet; ee.GlobalScope.NodeVariables[node] = result; } return result; }
private static ISet<Namespace> EvaluateSequence(ExpressionEvaluator ee, Node node) { // Covers both ListExpression and TupleExpression return ee.GlobalScope.GetOrMakeNodeVariable(node, (n) => ee.MakeSequence(ee, n)); }
private static ISet<Namespace> EvaluateGenerator(ExpressionEvaluator ee, Node node) { GeneratorExpression gen = (GeneratorExpression)node; ee.Evaluate(gen.Iterable); // TODO: Implement return EmptySet<Namespace>.Instance; }
private static ISet<Namespace> EvaluateSlice(ExpressionEvaluator ee, Node node) { SliceExpression se = node as SliceExpression; return ee.GlobalScope.GetOrMakeNodeVariable( node, (n) => new SliceInfo( ee.EvaluateMaybeNull(se.SliceStart), ee.EvaluateMaybeNull(se.SliceStop), se.StepProvided ? ee.EvaluateMaybeNull(se.SliceStep) : null ) ); }
private static ISet<Namespace> EvaluateIndex(ExpressionEvaluator ee, Node node) { var n = (IndexExpression)node; return ee.Evaluate(n.Target).GetIndex(n, ee._unit, ee.Evaluate(n.Index)); }
private static ISet<Namespace> EvaluateYield(ExpressionEvaluator ee, Node node) { var yield = (YieldExpression)node; var funcDef = ee._currentScopes[ee._currentScopes.Length - 1].Namespace as FunctionInfo; if (funcDef != null) { var gen = funcDef.Generator; gen.AddYield(ee.Evaluate(yield.Expression)); return gen.Sends.Types; } return EmptySet<Namespace>.Instance; }
private static ISet<Namespace> EvaluateLambda(ExpressionEvaluator ee, Node node) { var lambda = (LambdaExpression)node; return ee.GlobalScope.GetOrMakeNodeVariable(node, n => MakeLambdaFunction(lambda, ee)); }
private ISet<Namespace> MakeSequence(ExpressionEvaluator ee, Node node) { ISet<Namespace> result; if (!ee.GlobalScope.NodeVariables.TryGetValue(node, out result)) { var seqItems = ((SequenceExpression)node).Items; var indexValues = new ISet<Namespace>[seqItems.Count]; for (int i = 0; i < seqItems.Count; i++) { indexValues[i] = Evaluate(seqItems[i]); } ISet<Namespace> sequence; if (node is ListExpression) { sequence = new ListInfo(indexValues, _unit.ProjectState._listType).SelfSet; } else { Debug.Assert(node is TupleExpression); sequence = new SequenceInfo(indexValues, _unit.ProjectState._tupleType).SelfSet; } ee.GlobalScope.NodeVariables[node] = result = sequence; } return result; }
/// <summary> /// Gets information about the available signatures for the given expression. /// </summary> /// <param name="exprText">The expression to get signatures for.</param> /// <param name="lineNumber">The line number to use for the context of looking up members.</param> public IEnumerable<IOverloadResult> GetSignatures(string exprText, int lineNumber) { try { var eval = new ExpressionEvaluator(_unit.CopyForEval(), FindScopes(lineNumber).ToArray()); var sourceUnit = ProjectState.GetSourceUnitForExpression(exprText); using (var parser = Utils.CreateParser(sourceUnit, new CollectingErrorSink())) { var expr = GetExpression(parser.ParseTopExpression().Body); if (expr is ListExpression || expr is TupleExpression || expr is DictionaryExpression) { return new OverloadResult[0]; } var lookup = eval.Evaluate(expr); var result = new List<OverloadResult>(); // TODO: Include relevant type info on the parameter... foreach (var ns in lookup) { result.AddRange(ns.Overloads); } return result.ToArray(); } } catch (Exception) { // TODO: log exception return new[] { new SimpleOverloadResult(new ParameterResult[0], "Unknown", "IntellisenseError_Sigs") }; } }