private void AfterCall(Guid id, RelinqScriptExpression e, TypeInferenceCache cache) { var startedEntry = History.Single(entry2 => entry2.Id == id); var finishedEntry = new TypeInferenceHistoryEntry(startedEntry); finishedEntry.InferredType = cache.ContainsKey(e) ? cache[e] : null; if (e.IsCall()) { RelinqScriptExpression invtarget = null; if (e is InvokeExpression) { invtarget = e.Children.ElementAt(0); } else if (e is IndexerExpression || e is OperatorExpression) { invtarget = e; } if (invtarget != null && cache.Invocations.ContainsKey(invtarget)) { finishedEntry.InferredInvocation = cache.Invocations[invtarget]; } } History.Add(finishedEntry); if (History.Count % 20000 == 0) DumpHistory(); }
private Guid BeforeCall(RelinqScriptExpression e, TypeInferenceCache cache) { var startedEntry = new TypeInferenceHistoryEntry{Expression = e}; startedEntry.InferredType = cache.ContainsKey(e) ? cache[e] : null; History.Add(startedEntry); Func<LambdaExpression, String, RelinqScriptType> argType = (lambda, arg) => { var argIndex = Array.IndexOf(lambda.Args.ToArray(), arg); var lambdaType = ((Lambda)cache[lambda]).Type.GetFunctionSignature(); return lambdaType.GetParameters()[argIndex].ParameterType; }; e.GetClosure().ForEach(kvp => startedEntry.Closure.Add(kvp.Key, cache.ContainsKey(kvp.Value) ? argType(kvp.Value, kvp.Key) : null)); return startedEntry.Id; }
private void InferLambda(LambdaExpression le, TypeInferenceCache cache) { // lambda is the only one expression that can have its type set from outside if (!cache.ContainsKey(le)) { var lambdaType = Enumerable.Repeat(typeof(Variant), 1 + le.Args.Count()).ForgeFuncType(); cache.Add(le, new Lambda(le, lambdaType)); } // detect overlapping variables var closure = le.Parent == null ? null : le.Parent.GetClosure(); if (closure != null) { var overlapping = closure.Keys.Intersect(le.Args); if (overlapping.IsNotEmpty()) { throw new RedeclaredVariableException(Root, le, closure); } } // detect overriding keywords foreach (var arg in le.Args) { if (Integration.IsRegisteredJS(arg)) { throw new VariableOverridesKeywordException(Root, le, arg); } } InferTypes(le.Body, cache); }