Ejemplo n.º 1
0
 public CallChain(Node call, CallChain preceding, int limit)
 {
     if (limit == 1)
     {
         _chain = call;
     }
     else
     {
         _chain = Enumerable.Repeat(call, 1).Concat(preceding).Concat(EmptyNodes).Take(limit).ToArray();
     }
 }
Ejemplo n.º 2
0
        public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames)
        {
            var callArgs = ArgumentSet.FromArgs(FunctionDefinition, unit, args, keywordArgNames);

            if (keywordArgNames != null && keywordArgNames.Any())
            {
                _analysisUnit.AddNamedParameterReferences(unit, keywordArgNames);
            }

            var res = DoCall(node, unit, _analysisUnit, callArgs);

            if (_callsWithClosure != null)
            {
                var chain     = new CallChain(node, unit, _callDepthLimit);
                var aggregate = GetAggregate(unit);

                if (!_callsWithClosure.TryGetValue(aggregate, chain, _callDepthLimit, out var calledUnit) &&
                    !unit.ForEval)
                {
                    _callsSinceLimitChange += 1;
                    if (_callsSinceLimitChange >= ProjectState.Limits.DecreaseCallDepth && _callDepthLimit > 1)
                    {
                        _callDepthLimit       -= 1;
                        _callsSinceLimitChange = 0;
                        AnalysisLog.ReduceCallDepth(this, _callsWithClosure.Count, _callDepthLimit);

                        _callsWithClosure.Clear();
                        chain = chain.Trim(_callDepthLimit);
                    }

                    calledUnit = new FunctionClosureAnalysisUnit(aggregate, (FunctionAnalysisUnit)AnalysisUnit, chain);
                    _callsWithClosure.Add(aggregate, chain, calledUnit);
                    calledUnit.Enqueue();
                }

                Debug.Assert(calledUnit != null || unit.ForEval);

                res.Split(v => v.IsResolvable(), out _, out var nonLazy);
                res = DoCall(node, unit, calledUnit, callArgs);
                res = res.Union(nonLazy);
            }

            var context = unit.ForEval ? ResolutionContext.Complete : new ResolutionContext {
                Caller   = this,
                CallArgs = callArgs,
                CallSite = node
            };

            var r = res.Resolve(unit, context, out _);

            return(r);
        }
Ejemplo n.º 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;
            }
        }
Ejemplo n.º 4
0
        public void Add(IPythonProjectEntry entry, CallChain chain, T value)
        {
            KeyValuePair <int, Dictionary <CallChain, T> > entryData;

            lock (_data) {
                if (!_data.TryGetValue(entry, out entryData) || entryData.Key != entry.AnalysisVersion)
                {
                    _data[entry] = entryData = new KeyValuePair <int, Dictionary <CallChain, T> >(
                        entry.AnalysisVersion,
                        new Dictionary <CallChain, T>()
                        );
                }
            }

            lock (entryData.Value) {
                entryData.Value[chain] = value;
            }
        }
Ejemplo n.º 5
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));
            }
        }
Ejemplo n.º 6
0
        public bool TryGetValue(IPythonProjectEntry entry, CallChain chain, int prefixLength, out T value)
        {
            value = default(T);

            KeyValuePair <int, Dictionary <CallChain, T> > entryData;

            lock (_data) {
                if (!_data.TryGetValue(entry, out entryData))
                {
                    return(false);
                }
                if (entryData.Key != entry.AnalysisVersion)
                {
                    _data.Remove(entry);
                    return(false);
                }
            }
            lock (entryData.Value) {
                return(entryData.Value.TryGetValue(chain, out value));
            }
        }
Ejemplo n.º 7
0
        public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames)
        {
            var callArgs = ArgumentSet.FromArgs(FunctionDefinition, unit, args, keywordArgNames);

            if (keywordArgNames != null && keywordArgNames.Any())
            {
                _analysisUnit.AddNamedParameterReferences(unit, keywordArgNames);
            }

            var res = DoCall(node, unit, _analysisUnit, callArgs);

            if (_derived != null)
            {
                foreach (FunctionInfo derived in _derived)
                {
                    var derivedResult = derived.DoCall(node, unit, derived._analysisUnit, callArgs);
                    res = res.Union(derivedResult);
                }
            }

            if (_analysisUnit.State.Limits.PropagateParameterTypeToBaseMethods &&
                _analysisUnit.Scope.OuterScope is ClassScope parentClass)
            {
                var baseMethods = DDG.LookupBaseMethods(Name, parentClass.Class.Mro, AnalysisUnit.Ast, AnalysisUnit);
                foreach (FunctionInfo baseMethod in baseMethods.OfType <FunctionInfo>())
                {
                    baseMethod.DoCall(node, unit, baseMethod._analysisUnit, callArgs);
                }
            }

            if (_callsWithClosure != null)
            {
                var chain     = new CallChain(node, unit, _callDepthLimit);
                var aggregate = GetAggregate(unit);

                if (!_callsWithClosure.TryGetValue(aggregate, chain, _callDepthLimit, out var calledUnit) &&
                    !unit.ForEval)
                {
                    _callsSinceLimitChange += 1;
                    if (_callsSinceLimitChange >= ProjectState.Limits.DecreaseCallDepth && _callDepthLimit > 1)
                    {
                        _callDepthLimit       -= 1;
                        _callsSinceLimitChange = 0;
                        AnalysisLog.ReduceCallDepth(this, _callsWithClosure.Count, _callDepthLimit);

                        _callsWithClosure.Clear();
                        chain = chain.Trim(_callDepthLimit);
                    }

                    calledUnit = new FunctionClosureAnalysisUnit(aggregate, (FunctionAnalysisUnit)AnalysisUnit, chain);
                    _callsWithClosure.Add(aggregate, chain, calledUnit);
                    calledUnit.Enqueue();
                }

                Debug.Assert(calledUnit != null || unit.ForEval);

                res.Split(v => v.IsResolvable(), out _, out var nonLazy);
                res = DoCall(node, unit, calledUnit, callArgs);
                res = res.Union(nonLazy);
            }

            var context = unit.ForEval ? ResolutionContext.Complete : new ResolutionContext {
                Caller   = this,
                CallArgs = callArgs,
                CallSite = node
            };

            var r = res.Resolve(unit, context, out _);

            return(r);
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
0
 public bool Equals(CallChain other)
 {
     return(this.SequenceEqual(other));
 }
Ejemplo n.º 10
0
 public bool PrefixMatches(CallChain other, int limit)
 {
     return(this.Take(limit).SequenceEqual(other.Take(limit)));
 }