internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { ModuleTree module = _table.RequireModule(this, _dependency, _tree); if (module == null) { return; } AddChildVisibilitiesExcludingNodeModules(module); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { base.AnalyzeWorker(ddg, cancel); var list = (ListInfo)Scope.AnalysisValue; var node = (ListComprehension)Ast; list.AddTypes(this, new[] { ddg._eval.Evaluate(node.Item) }); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { base.AnalyzeWorker(ddg, cancel); var dict = (DictionaryInfo)Scope.AnalysisValue; var node = (DictionaryComprehension)Ast; dict.SetIndex(node, this, ddg._eval.Evaluate(node.Key), ddg._eval.Evaluate(node.Value)); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { base.AnalyzeWorker(ddg, cancel); var set = (SetInfo)Scope.AnalysisValue; var node = (SetComprehension)Ast; set.AddTypes(this, ddg._eval.Evaluate(node.Item)); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { base.AnalyzeWorker(ddg, cancel); var generator = (GeneratorInfo)Scope.AnalysisValue; var node = (GeneratorExpression)Ast; generator.AddYield(node, this, ddg._eval.Evaluate(node.Item)); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { InterpreterScope scope; if (!ddg.Scope.TryGetNodeScope(Ast, out scope)) { return; } var classInfo = ((ClassScope)scope).Class; var bases = new List <IAnalysisSet>(); if (Ast.BasesInternal.Length == 0) { if (ddg.ProjectState.LanguageVersion.Is3x()) { // 3.x all classes inherit from object by default bases.Add(ddg.ProjectState.ClassInfos[BuiltinTypeId.Object]); } } else { // Process base classes for (int i = 0; i < Ast.BasesInternal.Length; i++) { var baseClassArg = Ast.BasesInternal[i]; if (baseClassArg.Name == null) { bases.Add(EvaluateBaseClass(ddg, classInfo, i, baseClassArg.Expression)); } else if (baseClassArg.Name == "metaclass") { var metaClass = baseClassArg.Expression; metaClass.Walk(ddg); var metaClassValue = ddg._eval.Evaluate(metaClass); if (metaClassValue.Count > 0) { classInfo.GetOrCreateMetaclassVariable().AddTypes(_outerUnit, metaClassValue); } } } } classInfo.SetBases(bases); foreach (var baseSet in bases) { foreach (var baseClassInfo in baseSet.OfType <ClassInfo>()) { baseClassInfo._mro.AddDependency(this); } } ddg.SetCurrentUnit(this); ddg.WalkBody(Ast.Body, classInfo.AnalysisUnit); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { if (Function.ArgumentsVariable != null && !ddg.Scope.ContainsVariable("arguments")) { ddg.Scope.AddVariable("arguments", Function.ArgumentsVariable); } // Set the scope to within the function ddg.Scope = Environment; Ast.Body.Walk(ddg); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { var comp = (Comprehension)Ast; if (comp.Iterators[0] is ComprehensionFor forComp) { var listTypes = ddg._eval.Evaluate(forComp.List); ddg._eval.AssignTo(comp, forComp.Left, listTypes.GetEnumeratorTypes(comp, this)); } ExpressionEvaluator.WalkComprehension(ddg._eval, (Comprehension)Ast); }
internal virtual void AnalyzeWorker(DDG ddg, CancellationToken cancel) { Debug.Assert(ddg != null, "ddg unexpected null value"); Debug.Assert(Ast != null, "Ast has unexpected null value"); Debug.Assert(ProjectEntry != null, "ProjectEntry has unexpected null value"); Debug.Assert(DeclaringModuleEnvironment != null, "DeclaringModuleEnvironment has unexpected null value"); Debug.Assert(DeclaringModuleEnvironment.GlobalEnvironment != null, "DeclaringModuleEnvironment.GlobalEnvironment has unexpected null value"); Debug.Assert(DeclaringModuleEnvironment.Variables != null, "DeclaringModuleEnvironment.Variables has unexpected null value"); if (ddg == null || Ast == null || ProjectEntry == null || Tree != ProjectEntry.Tree || DeclaringModuleEnvironment?.Variables == null || DeclaringModuleEnvironment?.GlobalEnvironment == null) { // analysis unit properties are invalid or we were enqueued and a new version became available // don't re-analyze against the old version. return; } DeclaringModuleEnvironment.ClearLinkedVariables(); ddg.SetCurrentUnit(this); Ast.Walk(ddg); var toRemove = new List <KeyValuePair <string, VariableDef> >(); foreach (var variableInfo in DeclaringModuleEnvironment.Variables) { var value = variableInfo.Value; if (value == null) { continue; } value.ClearOldValues(ProjectEntry); if (value._dependencies.Count == 0 && value.TypesNoCopy.Count == 0) { toRemove.Add(variableInfo); } } foreach (var nameValue in toRemove) { var globalEnvironment = DeclaringModuleEnvironment.GlobalEnvironment; if (globalEnvironment != null) { globalEnvironment.RemoveVariable(nameValue.Key); } // if anyone read this value it could now be gone (e.g. user // deletes a class definition) so anyone dependent upon it // needs to be updated. nameValue.Value?.EnqueueDependents(); } }
public void AnalyzeQueuedEntries(CancellationToken cancel) { if (cancel.IsCancellationRequested) { return; } var ddg = new DDG(); ddg.Analyze(Queue, cancel, _reportQueueSize, _reportQueueInterval); foreach (var entry in ddg.AnalyzedEntries) { entry.RaiseOnNewAnalysis(); } }
internal static IAnalysisSet EvaluateBaseClass(DDG ddg, ClassInfo newClass, int indexInBaseList, Expression baseClass) { baseClass.Walk(ddg); var bases = ddg._eval.Evaluate(baseClass); foreach (var baseValue in bases) { ClassInfo ci = baseValue as ClassInfo; if (ci != null) { ci.SubClasses.AddTypes(newClass.AnalysisUnit, newClass); } } return(bases); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { var comp = (Comprehension)Ast; var forComp = comp.Iterators[0] as ComprehensionFor; if (forComp != null) { // evaluate the 1st iterator in the outer scope ddg.Scope = _outerUnit.InterpreterScope; var listTypes = ddg._eval.Evaluate(forComp.List); ddg.Scope = InterpreterScope; ddg._eval.AssignTo(comp, forComp.Left, listTypes.GetEnumeratorTypes(comp, this)); } ExpressionEvaluator.WalkComprehension(ddg._eval, (Comprehension)Ast); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { if (_dictInfo._keyValueTuple != null) { if (_dictInfo._keysAndValues.CopyKeysTo(_dictInfo._keyValueTuple.IndexTypes[0]) | _dictInfo._keysAndValues.CopyValuesTo(_dictInfo._keyValueTuple.IndexTypes[1])) { _dictInfo._keyValueTuple.UnionType = null; } } bool updatedKeys = false, updatedValues = false; if (_dictInfo._keysVariable != null) { updatedKeys |= _dictInfo._keysAndValues.CopyKeysTo(_dictInfo._keysVariable); } if (_dictInfo._valuesVariable != null) { updatedValues |= _dictInfo._keysAndValues.CopyValuesTo(_dictInfo._valuesVariable); } if (updatedKeys) { if (_dictInfo._keysIter != null) { _dictInfo._keysIter.UnionType = null; } if (_dictInfo._keysList != null) { _dictInfo._keysList.UnionType = null; } } if (updatedValues) { if (_dictInfo._valuesIter != null) { _dictInfo._valuesIter.UnionType = null; } if (_dictInfo._valuesList != null) { _dictInfo._valuesList.UnionType = null; } } }
private IAnalysisSet ProcessClassDecorators(DDG ddg, ClassInfo classInfo) { var types = classInfo.SelfSet; if (Ast.Decorators != null) { Expression expr = Ast.NameExpression; foreach (var d in Ast.Decorators.DecoratorsInternal) { if (d != null) { var decorator = ddg._eval.Evaluate(d); Expression nextExpr; if (!_decoratorCalls.TryGetValue(d, out nextExpr)) { nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) }); nextExpr.SetLoc(d.IndexSpan); } expr = nextExpr; var decorated = AnalysisSet.Empty; bool anyResults = false; foreach (var ns in decorator) { var fd = ns as FunctionInfo; if (fd != null && Scope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd)) { continue; } decorated = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames)); anyResults = true; } // If processing decorators, update the current // function type. Otherwise, we are acting as if // each decorator returns the function unmodified. if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults) { types = decorated; } } } } return(types); }
public void AnalyzeQueuedEntries(CancellationToken cancel) { if (cancel.IsCancellationRequested) { return; } if (_builtinModule == null) { Debug.Fail("Used analyzer without reloading modules"); ReloadModulesAsync(cancel).WaitAndUnwrapExceptions(); } var ddg = new DDG(); ddg.Analyze(Queue, cancel, _reportQueueSize, _reportQueueInterval); foreach (ProjectEntry entry in ddg.AnalyzedEntries) { entry.SetCompleteAnalysis(); } }
internal override void AnalyzeWorker(DDG ddg, System.Threading.CancellationToken cancel) { base.AnalyzeWorker(ddg, cancel); // perform the callback for the exported function so // we provide intellisense against the grunt parameter. var grunt = Analyzer.Modules.RequireModule( Ast, this, "grunt", DeclaringModuleEnvironment.Name ); ProjectEntry.GetModule(this).Get( Ast, this, "exports", false ).Call( Ast, this, null, new[] { grunt } ); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { ddg.SetCurrentUnit(this); InterpreterScope scope; if (!ddg.Scope.TryGetNodeScope(Ast, out scope)) { return; } var classInfo = ((ClassScope)scope).Class; var bases = ClassAnalysisUnit.EvaluateBaseClass( ddg, classInfo, _indexInBasesList, _baseClassNode ); classInfo.SetBase(_indexInBasesList, bases); _outerUnit.Enqueue(); }
internal virtual void AnalyzeWorker(DDG ddg, CancellationToken cancel) { if (Tree != ProjectEntry.Tree) { // we were enqueued and a new version became available, don't re-analyze against // the old version. return; } DeclaringModuleEnvironment.ClearLinkedVariables(); ddg.SetCurrentUnit(this); Ast.Walk(ddg); var toRemove = new List <KeyValuePair <string, VariableDef> >(); foreach (var variableInfo in DeclaringModuleEnvironment.Variables) { variableInfo.Value.ClearOldValues(ProjectEntry); if (variableInfo.Value._dependencies.Count == 0 && variableInfo.Value.TypesNoCopy.Count == 0) { toRemove.Add(variableInfo); } } foreach (var nameValue in toRemove) { DeclaringModuleEnvironment.GlobalEnvironment.RemoveVariable(nameValue.Key); // if anyone read this value it could now be gone (e.g. user // deletes a class definition) so anyone dependent upon it // needs to be updated. nameValue.Value.EnqueueDependents(); } }
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); }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { // Resolve default parameters and decorators in the outer scope but // continue to associate changes with this unit. ddg.Scope = _declUnit.Scope; AnalyzeDefaultParameters(ddg); if (_decoratorCalls != null) { ProcessFunctionDecorators(ddg); } // Set the scope to within the function ddg.Scope = Scope; Ast.Body.Walk(ddg); }
internal void AnalyzeDefaultParameters(DDG ddg) { VariableDef param; for (int i = 0; i < Ast.Parameters.Count; ++i) { var p = Ast.Parameters[i]; ddg._eval.EvaluateMaybeNull(p.Annotation); if (p.DefaultValue != null && p.Kind != ParameterKind.List && p.Kind != ParameterKind.Dictionary && Scope.TryGetVariable(p.Name, out param)) { var val = ddg._eval.Evaluate(p.DefaultValue); if (val != null) { param.AddTypes(this, val, false); } } } ddg._eval.EvaluateMaybeNull(Ast.ReturnAnnotation); }
internal void ProcessFunctionDecorators(DDG ddg) { if (Ast.Decorators != null) { var types = Function.SelfSet; Expression expr = Ast.NameExpression; foreach (var d in Ast.Decorators.Decorators) { if (d != null) { var decorator = ddg._eval.Evaluate(d); if (decorator.Contains(ProjectState.ClassInfos[BuiltinTypeId.Property])) { Function.IsProperty = true; } else if (decorator.Contains(ProjectState.ClassInfos[BuiltinTypeId.StaticMethod])) { // TODO: Warn if IsClassMethod is set Function.IsStatic = true; } else if (decorator.Contains(ProjectState.ClassInfos[BuiltinTypeId.ClassMethod])) { // TODO: Warn if IsStatic is set Function.IsClassMethod = true; } else { Expression nextExpr; if (!_decoratorCalls.TryGetValue(d, out nextExpr)) { nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) }); } expr = nextExpr; var decorated = AnalysisSet.Empty; foreach (var ns in decorator) { var fd = ns as FunctionInfo; if (fd != null && Scope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd)) { continue; } decorated = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames)); } // If processing decorators, update the current // function type. Otherwise, we are acting as if // each decorator returns the function unmodified. if (ddg.ProjectState.Limits.ProcessCustomDecorators) { types = decorated; } } } } ddg.Scope.AddLocatedVariable(Ast.Name, Ast.NameExpression, this).AddTypes(this, types); } if (!Function.IsStatic && Ast.Parameters.Count > 0) { VariableDef param; IAnalysisSet firstParam; var clsScope = ddg.Scope as ClassScope; if (clsScope == null) { firstParam = Function.IsClassMethod ? ProjectState.ClassInfos[BuiltinTypeId.Type].SelfSet : AnalysisSet.Empty; } else { firstParam = Function.IsClassMethod ? clsScope.Class.SelfSet : clsScope.Class.Instance.SelfSet; } if (Scope.TryGetVariable(Ast.Parameters[0].Name, out param)) { param.AddTypes(this, firstParam, false); } } }
internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { if (((FunctionEnvironmentRecord)_env).AnalysisValue.DeclaringVersion != ProjectEntry.AnalysisVersion) { // we were enqueued and a new version became available, don't re-analyze against // the old version. return; } var args = _callArgs; var funcScope = (FunctionEnvironmentRecord)Environment; var function = Function; // Set the specialized versions of the locals foreach (var local in _specializedLocals) { local.DefiningScope.ReplaceVariable(local.Name, local.Specialized); } var originalThis = funcScope._this; funcScope._this = _this; function._curArgs = args; // Propagate the call types into the variables... AddArgumentTypes(funcScope, _callArgs.This, args.Args); var unifiedReturn = function.ReturnValue; function.ReturnValue = _returnValue; function.FunctionObject.Walk(new FunctionAssignmentWalker(funcScope, ProjectEntry)); try { base.AnalyzeWorker(ddg, cancel); } finally { function._curArgs = null; funcScope._this = originalThis; function.ReturnValue = unifiedReturn; function.ReturnValue.AddTypes(this, _returnValue.GetTypesNoCopy(this), false); _this.CopyTo(originalThis); // restore the locals, merging types back into the shared... foreach (var variable in _specializedLocals) { var newVar = variable.Specialized; var oldVar = variable.Shared; newVar.CopyTo(oldVar); variable.DefiningScope.ReplaceVariable(variable.Name, oldVar); } } }
protected override void AnalyzeWorker(DDG ddg, CancellationToken cancel) { _dictInfo._keysAndValues.CopyKeysTo(_dictInfo._keyValueTuple.IndexTypes[0]); _dictInfo._keysAndValues.CopyValuesTo(_dictInfo._keyValueTuple.IndexTypes[1]); }
internal void ProcessFunctionDecorators(DDG ddg) { if (Ast.Decorators != null) { var types = Function.SelfSet; Expression expr = Ast.NameExpression; foreach (var d in Ast.Decorators.Decorators) { if (d != null) { var decorator = ddg._eval.Evaluate(d); if (decorator.Contains(ProjectState._propertyObj)) { Function.IsProperty = true; } else if (decorator.Contains(ProjectState._staticmethodObj)) { // TODO: Warn if IsClassMethod is set Function.IsStatic = true; } else if (decorator.Contains(ProjectState._classmethodObj)) { // TODO: Warn if IsStatic is set Function.IsClassMethod = true; } else { Expression nextExpr; if (!_decoratorCalls.TryGetValue(d, out nextExpr)) { nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) }); } expr = nextExpr; types = decorator.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames); } } } ddg.Scope.AddLocatedVariable(Ast.Name, Ast.NameExpression, this).AddTypes(this, types); } if (!Function.IsStatic && Ast.Parameters.Count > 0) { VariableDef param; INamespaceSet firstParam; var clsScope = ddg.Scope as ClassScope; if (clsScope == null) { firstParam = Function.IsClassMethod ? ProjectState._typeObj.SelfSet : NamespaceSet.Empty; } else { firstParam = Function.IsClassMethod ? clsScope.Class.SelfSet : clsScope.Class.Instance.SelfSet; } if (Scope.Variables.TryGetValue(Ast.Parameters[0].Name, out param)) { param.AddTypes(this, firstParam, false); } } }