Пример #1
0
        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);
        }
Пример #2
0
        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();
        }
Пример #3
0
        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;
        }
Пример #4
0
        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;
        }
Пример #5
0
 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);
         }
     }
 }