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); }
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)); } }