internal FunctionInfo(FunctionDefinition node, AnalysisUnit declUnit, InterpreterScope declScope) { _projectEntry = declUnit.ProjectEntry; _functionDefinition = node; _declVersion = declUnit.ProjectEntry.AnalysisVersion; if (Name == "__new__") { IsClassMethod = true; } _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope); }
public FunctionAnalysisUnit(FunctionAnalysisUnit originalUnit, CallChain callChain, ArgumentSet callArgs) : base(originalUnit.Ast, null) { _originalUnit = originalUnit; _declUnit = originalUnit._declUnit; Function = originalUnit.Function; _decoratorCalls = originalUnit._decoratorCalls; CallChain = callChain; var scope = new FunctionScope(Function, Ast, originalUnit.Scope.OuterScope); scope.UpdateParameters(this, callArgs, false, originalUnit.Scope as FunctionScope); _scope = scope; var walker = new OverviewWalker(originalUnit.ProjectEntry, this); if (Ast.Body != null) { Ast.Body.Walk(walker); } AnalysisLog.NewUnit(this); Enqueue(); }
public override INamespaceSet Call(Node node, AnalysisUnit unit, INamespaceSet[] args, NameExpression[] keywordArgNames) { var callArgs = ArgumentSet.FromArgs(FunctionDefinition, unit, args, keywordArgNames); if (_allCalls == null) { _allCalls = new Dictionary<CallChain, FunctionAnalysisUnit>(); } FunctionAnalysisUnit calledUnit; bool updateArguments = true; if (callArgs.Count == 0 || (ProjectState.Limits.UnifyCallsToNew && Name == "__new__")) { calledUnit = (FunctionAnalysisUnit)AnalysisUnit; } else { var chain = new CallChain(node, unit, unit.ProjectState.Limits.CallDepth); if (!_allCalls.TryGetValue(chain, out calledUnit)) { if (unit.ForEval) { // Call expressions that weren't analyzed get the union result // of all calls to this function. var res = NamespaceSet.Empty; foreach (var call in _allCalls.Values) { res = res.Union(call.ReturnValue.TypesNoCopy); } return res; } else { _allCalls[chain] = calledUnit = new FunctionAnalysisUnit((FunctionAnalysisUnit)AnalysisUnit, chain, callArgs); updateArguments = false; } } } if (updateArguments && calledUnit.UpdateParameters(callArgs)) { #if DEBUG // Checks whether these arguments can be added ad nauseum. if (calledUnit.UpdateParameters(callArgs) && calledUnit.UpdateParameters(callArgs) && calledUnit.UpdateParameters(callArgs)) { AnalysisLog.Add("BadArgs", calledUnit, callArgs); } #endif AnalysisLog.UpdateUnit(calledUnit); } calledUnit.ReturnValue.AddDependency(unit); return calledUnit.ReturnValue.Types; }
internal bool UpdateParameters(FunctionAnalysisUnit unit, ArgumentSet others, bool enqueue = true, FunctionScope scopeWithDefaultParameters = null) { EnsureParameters(unit, scopeWithDefaultParameters); var astParams = Function.FunctionDefinition.Parameters; bool added = false; var entry = unit.ProjectEntry; var state = unit.ProjectState; var limits = state.Limits; for (int i = 0; i < others.Args.Length && i < astParams.Count; ++i) { VariableDef param; if (!Variables.TryGetValue(astParams[i].Name, out param)) { Debug.Assert(false, "Parameter " + astParams[i].Name + " has no variable in this scope"); } param.MakeUnionStrongerIfMoreThan(limits.NormalArgumentTypes, others.Args[i]); added |= param.AddTypes(entry, others.Args[i], false); } if (_seqParameters != null) { _seqParameters.List.MakeUnionStrongerIfMoreThan(limits.ListArgumentTypes, others.SequenceArgs); added |= _seqParameters.List.AddTypes(unit, new[] { others.SequenceArgs }); } if (_dictParameters != null) { _dictParameters.Dict.MakeUnionStrongerIfMoreThan(limits.DictArgumentTypes, others.DictArgs); added |= _dictParameters.Dict.AddTypes(Function.FunctionDefinition, unit, state.GetConstant(""), others.DictArgs); } if (enqueue && added) { unit.Enqueue(); } return added; }
internal void EnsureParameters(FunctionAnalysisUnit unit, FunctionScope scopeWithDefaultParameters = null) { var astParams = Function.FunctionDefinition.Parameters; for (int i = 0; i < astParams.Count; ++i) { VariableDef param, defParam; if (!Variables.TryGetValue(astParams[i].Name, out param)) { if (astParams[i].Kind == ParameterKind.List) { param = _seqParameters = _seqParameters ?? new ListParameterVariableDef(unit, astParams[i]); } else if (astParams[i].Kind == ParameterKind.Dictionary) { param = _dictParameters = _dictParameters ?? new DictParameterVariableDef(unit, astParams[i]); } else { param = new LocatedVariableDef(unit.ProjectEntry, astParams[i]); } if (scopeWithDefaultParameters != null && scopeWithDefaultParameters != this && scopeWithDefaultParameters.Variables.TryGetValue(astParams[i].Name, out defParam)) { defParam.CopyTo(param); } AddVariable(astParams[i].Name, param); } } }