예제 #1
0
        public FunctionAnalysisUnit(FunctionAnalysisUnit originalUnit, CallChain callChain, ArgumentSet callArgs)
            : base(originalUnit.Ast, null) {
            _originalUnit = originalUnit;
            _declUnit = originalUnit._declUnit;
            Function = originalUnit.Function;

            CallChain = callChain;

            var scope = new FunctionScope(
                Function,
                Ast,
                originalUnit.Scope.OuterScope,
                originalUnit.DeclaringModule.ProjectEntry
            );
            scope.UpdateParameters(this, callArgs, false, originalUnit.Scope as FunctionScope);
            _scope = scope;

            var walker = new OverviewWalker(_originalUnit.ProjectEntry, this, Tree);
            if (Ast.Body != null) {
                Ast.Body.Walk(walker);
            }

            AnalysisLog.NewUnit(this);
            Enqueue();
        }
        private static IAnalysisSet MakeLambdaFunction(LambdaExpression node, ExpressionEvaluator ee)
        {
            var res = OverviewWalker.AddFunction(node.Function, ee._unit, ee.Scope);

            if (res != null)
            {
                return(res.SelfSet);
            }
            return(AnalysisSet.Empty);
        }
예제 #3
0
        private void TryPushIsInstanceScope(Node node, Expression test)
        {
            InterpreterScope newScope;

            if (Scope.TryGetNodeScope(node, out newScope))
            {
                var outerScope      = Scope;
                var isInstanceScope = (IsInstanceScope)newScope;

                // magic assert isinstance statement alters the type information for a node
                var namesAndExpressions = OverviewWalker.GetIsInstanceNamesAndExpressions(test);
                foreach (var nameAndExpr in namesAndExpressions)
                {
                    var name = nameAndExpr.Key;
                    var type = nameAndExpr.Value;

                    var typeObj = _eval.EvaluateMaybeNull(type);
                    isInstanceScope.CreateTypedVariable(name, _unit, name.Name, typeObj);
                }

                // push the scope, it will be popped when we leave the current SuiteStatement.
                Scope = newScope;
            }
        }
예제 #4
0
        private void Parse(bool enqueueOnly, CancellationToken cancel)
        {
            PythonAst tree;
            IAnalysisCookie cookie;
            GetTreeAndCookie(out tree, out cookie);
            if (tree == null) {
                return;
            }

            var oldParent = _myScope.ParentPackage;
            if (_filePath != null) {
                ProjectState.ModulesByFilename[_filePath] = _myScope;
            }

            if (oldParent != null) {
                // update us in our parent package
                oldParent.AddChildPackage(_myScope, _unit);
            } else if (_filePath != null) {
                // we need to check and see if our parent is a package for the case where we're adding a new
                // file but not re-analyzing our parent package.
                string parentFilename;
                if (ModulePath.IsInitPyFile(_filePath)) {
                    // subpackage
                    parentFilename = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(_filePath)), "__init__.py");
                } else {
                    // just a module
                    parentFilename = Path.Combine(Path.GetDirectoryName(_filePath), "__init__.py");
                }

                ModuleInfo parentPackage;
                if (ProjectState.ModulesByFilename.TryGetValue(parentFilename, out parentPackage)) {
                    parentPackage.AddChildPackage(_myScope, _unit);
                }
            }

            _unit = new AnalysisUnit(tree, _myScope.Scope);
            AnalysisLog.NewUnit(_unit);

            foreach (var value in MyScope.Scope.AllVariables) {
                value.Value.EnqueueDependents();
            }

            MyScope.Scope.Children.Clear();
            MyScope.Scope.ClearNodeScopes();
            MyScope.Scope.ClearNodeValues();
            MyScope.ClearUnresolvedModules();

            // collect top-level definitions first
            var walker = new OverviewWalker(this, _unit, tree);
            tree.Walk(walker);

            _myScope.Specialize();

            // It may be that we have analyzed some child packages of this package already, but because it wasn't analyzed,
            // the children were not registered. To handle this possibility, scan analyzed packages for children of this
            // package (checked by module name first, then sanity-checked by path), and register any that match.
            if (ModulePath.IsInitPyFile(_filePath)) {
                string pathPrefix = Path.GetDirectoryName(_filePath) + "\\";
                var children =
                    from pair in _projectState.ModulesByFilename
                    // Is the candidate child package in a subdirectory of our package?
                    let fileName = pair.Key
                    where fileName.StartsWith(pathPrefix)
                    let moduleName = pair.Value.Name
                    // Is the full name of the candidate child package qualified with the name of our package?
                    let lastDot = moduleName.LastIndexOf('.')
                    where lastDot > 0
                    let parentModuleName = moduleName.Substring(0, lastDot)
                    where parentModuleName == _myScope.Name
                    select pair.Value;
                foreach (var child in children) {
                    _myScope.AddChildPackage(child, _unit);
                }
            }

            _unit.Enqueue();

            if (!enqueueOnly) {
                _projectState.AnalyzeQueuedEntries(cancel);
            }

            // publish the analysis now that it's complete/running
            _currentAnalysis = new ModuleAnalysis(
                _unit,
                ((ModuleScope)_unit.Scope).CloneForPublish()
            );
        }