Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
 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);
 }
Beispiel #3
0
        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);
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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));
            }
        }
Beispiel #7
0
        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);
        }