예제 #1
0
        public IAnalysisSet GetValue(Node node, AnalysisUnit unit, ProjectEntry declaringScope, IAnalysisSet @this, bool addRef)
        {
            if (Values == null)
            {
                Values = new EphemeralVariableDef();
            }

            var res = Values.GetTypes(unit, declaringScope);

            if (res.Count > 0)
            {
                // Don't add references to ephemeral values...  If they
                // gain types we'll re-enqueue and the reference will be
                // added then.
                if (addRef && !Values.IsEphemeral)
                {
                    Values.AddReference(node, unit);
                }
            }

            if (Getter != null)
            {
                res = res.Union(Getter.GetTypesNoCopy(unit, declaringScope).Call(node, unit, @this, ExpressionEvaluator.EmptySets));
            }

            return(res);
        }
예제 #2
0
        public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet @this, IAnalysisSet[] args)
        {
            // if the arguments are complex then we'll do a merged analysis, otherwise we'll analyze
            // this set of arguments independently.
            bool skipDeepAnalysis = false;

            if (@this != null)
            {
                skipDeepAnalysis |= CheckTooManyValues(unit, @this);
            }

            if (!skipDeepAnalysis)
            {
                for (int i = 0; i < args.Length; i++)
                {
                    skipDeepAnalysis |= CheckTooManyValues(unit, args[i]);
                    if (skipDeepAnalysis)
                    {
                        break;
                    }
                }
            }

            if (skipDeepAnalysis || _overflowed == OverflowState.OverflowedBigTime)
            {
                // start merging all arguments into a single call analysis
                if (_analysisUnit.AddArgumentTypes(
                        (FunctionEnvironmentRecord)_analysisUnit._env,
                        @this,
                        args,
                        _analysisUnit.Analyzer.Limits.MergedArgumentTypes
                        ))
                {
                    _analysisUnit.Enqueue();
                }
                _analysisUnit.ReturnValue.AddDependency(unit);
                return(_analysisUnit.ReturnValue.GetTypes(unit, ProjectEntry));
            }

            var callArgs = new CallArgs(@this, args, _overflowed == OverflowState.OverflowedOnce);

            CallInfo callInfo;

            if (_allCalls == null)
            {
                _allCalls = new Dictionary <CallArgs, CallInfo>();
            }

            if (!_allCalls.TryGetValue(callArgs, out callInfo))
            {
                if (unit.ForEval)
                {
                    return(ReturnValue.GetTypes(unit, ProjectEntry));
                }

                _allCalls[callArgs] = callInfo = new CallInfo(
                    this,
                    _analysisUnit.Environment,
                    _analysisUnit._declUnit,
                    callArgs
                    );

                if (_allCalls.Count > MaximumCallCount)
                {
                    // try and compress args using UnionEquality...
                    if (_overflowed == OverflowState.None)
                    {
                        _overflowed = OverflowState.OverflowedOnce;
                        var newAllCalls = new Dictionary <CallArgs, CallInfo>();
                        foreach (var keyValue in _allCalls)
                        {
                            newAllCalls[new CallArgs(@this, keyValue.Key.Args, overflowed: true)] = keyValue.Value;
                        }
                        _allCalls = newAllCalls;
                    }

                    if (_allCalls.Count > MaximumCallCount)
                    {
                        _overflowed = OverflowState.OverflowedBigTime;
                        _analysisUnit.ReturnValue.AddDependency(unit);
                        return(_analysisUnit.ReturnValue.GetTypes(unit, ProjectEntry));
                    }
                }

                callInfo.ReturnValue.AddDependency(unit);
                callInfo.AnalysisUnit.Enqueue();
                return(AnalysisSet.Empty);
            }
            else
            {
                callInfo.ReturnValue.AddDependency(unit);
                return(callInfo.ReturnValue.GetTypes(unit, ProjectEntry));
            }
        }