public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames) { var callArgs = ArgumentSet.FromArgs(FunctionDefinition, unit, args, keywordArgNames); FunctionAnalysisUnit calledUnit; bool updateArguments = true; if (callArgs.Count == 0 || (ProjectState.Limits.UnifyCallsToNew && Name == "__new__") || _callDepthLimit == 0) { calledUnit = (FunctionAnalysisUnit)AnalysisUnit; } else { if (_allCalls == null) { _allCalls = new CallChainSet <FunctionAnalysisUnit>(); } var chain = new CallChain(node, unit, _callDepthLimit); if (!_allCalls.TryGetValue(unit.ProjectEntry, chain, _callDepthLimit, out calledUnit)) { if (unit.ForEval) { // Call expressions that weren't analyzed get the union result // of all calls to this function. var res = AnalysisSet.Empty; foreach (var call in _allCalls.Values) { res = res.Union(call.ReturnValue.TypesNoCopy); } return(res); } else { _callsSinceLimitChange += 1; if (_callsSinceLimitChange >= ProjectState.Limits.DecreaseCallDepth && _callDepthLimit > 1) { _callDepthLimit -= 1; _callsSinceLimitChange = 0; AnalysisLog.ReduceCallDepth(this, _allCalls.Count, _callDepthLimit); _allCalls.Clear(); chain = chain.Trim(_callDepthLimit); } calledUnit = new FunctionAnalysisUnit((FunctionAnalysisUnit)AnalysisUnit, chain, callArgs); _allCalls.Add(unit.ProjectEntry, chain, calledUnit); updateArguments = false; } } } if (updateArguments && calledUnit.UpdateParameters(callArgs)) { AnalysisLog.UpdateUnit(calledUnit); } if (keywordArgNames != null && keywordArgNames.Any()) { calledUnit.AddNamedParameterReferences(unit, keywordArgNames); } calledUnit.ReturnValue.AddDependency(unit); return(calledUnit.ReturnValue.Types); }