internal FunctionInfo(FunctionDefinition node, AnalysisUnit declUnit, InterpreterScope declScope) { ProjectEntry = declUnit.ProjectEntry; FunctionDefinition = node; _declVersion = declUnit.ProjectEntry.AnalysisVersion; if (FunctionDefinition.Name == "__new__") { IsClassMethod = true; } _doc = node.Body?.Documentation?.TrimDocumentation(); if (!ProjectEntry.Properties.TryGetValue(AnalysisLimits.CallDepthKey, out object value) || (_callDepthLimit = (value as int?) ?? -1) < 0) { _callDepthLimit = declUnit.State.Limits.CallDepth; } if (!CanBeClosure(ProjectState, ProjectEntry)) { _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope, ProjectEntry, true); } else if ((node.Parameters.Any() && node.ContainsNestedFreeVariables || node.IsGenerator)) { _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope, ProjectEntry, true); _callsWithClosure = new CallChainSet(); } else { _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope, ProjectEntry, false); } }
private IAnalysisSet DoCall(Node node, AnalysisUnit callingUnit, FunctionAnalysisUnit calledUnit, ArgumentSet callArgs) { if (calledUnit == null) { return(AnalysisSet.Empty); } calledUnit.UpdateParameters(callArgs); calledUnit.ReturnValue.AddDependency(callingUnit); return(calledUnit.ReturnValue.Types); }
public void Add(IVersioned entry, CallChain chain, FunctionAnalysisUnit value) { CallChainEntry entryData; lock (_data) { if (!_data.TryGetValue(entry, out entryData) || entryData.AnalysisVersion != entry.AnalysisVersion) { _data[entry] = entryData = new CallChainEntry( entry.AnalysisVersion, new Dictionary <CallChain, FunctionAnalysisUnit>() ); } } lock (entryData.Calls) { entryData.Calls[chain] = value; } }
public UserFunctionValue(FunctionObject node, AnalysisUnit declUnit, EnvironmentRecord declScope, bool isNested = false) : base(declUnit.ProjectEntry, null, node.Name ?? node.NameGuess) { ReturnValue = new VariableDef(); _funcObject = node; _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope, ProjectEntry); declUnit.Analyzer.AnalysisValueCreated(typeof(UserFunctionValue)); var argsWalker = new ArgumentsWalker(); FunctionObject.Body.Walk(argsWalker); if (argsWalker.UsesArguments) { Arguments = new ArgumentsValue(this); ArgumentsVariable = new VariableDef(); ArgumentsVariable.AddTypes(_analysisUnit, Arguments.SelfSet); } }
internal FunctionInfo(FunctionDefinition node, AnalysisUnit declUnit, InterpreterScope declScope) { _projectEntry = declUnit.ProjectEntry; _functionDefinition = node; _declVersion = declUnit.ProjectEntry.AnalysisVersion; if (_functionDefinition.Name == "__new__") { IsClassMethod = true; } object value; if (!ProjectEntry.Properties.TryGetValue(AnalysisLimits.CallDepthKey, out value) || (_callDepthLimit = (value as int?) ?? -1) < 0) { _callDepthLimit = declUnit.ProjectState.Limits.CallDepth; } _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope, _projectEntry); }
public bool TryGetValue(IVersioned entry, CallChain chain, int prefixLength, out FunctionAnalysisUnit value) { value = null; CallChainEntry entryData; lock (_data) { if (!_data.TryGetValue(entry, out entryData)) { return(false); } if (entryData.AnalysisVersion != entry.AnalysisVersion) { _data.Remove(entry); return(false); } } lock (entryData.Calls) { return(entryData.Calls.TryGetValue(chain, out value)); } }
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); }