Exemple #1
0
        IAnalysisSet LoadComponent(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames)
        {
            if (args.Length == 2 && unit.ProjectState.Interpreter is IDotNetPythonInterpreter)
            {
                var self = args[0];
                var xaml = args[1];

                foreach (var arg in xaml)
                {
                    var strConst = arg.GetConstantValueAsString();
                    if (string.IsNullOrEmpty(strConst))
                    {
                        continue;
                    }

                    // process xaml file, add attributes to self
                    string           xamlPath = Path.Combine(Path.GetDirectoryName(unit.DeclaringModule.ProjectEntry.FilePath), strConst);
                    XamlProjectEntry xamlProject;
                    if (unit.ProjectState._xamlByFilename.TryGetValue(xamlPath, out xamlProject))
                    {
                        // TODO: Get existing analysis if it hasn't changed.
                        var analysis = xamlProject.Analysis;

                        if (analysis == null)
                        {
                            xamlProject.Analyze(CancellationToken.None);
                            analysis = xamlProject.Analysis;
                            if (analysis == null)
                            {
                                AnalysisLog.Assert(false, "No Xaml analysis");
                                return(self);
                            }
                        }

                        xamlProject.AddDependency(unit.ProjectEntry);

                        var evalUnit = unit.CopyForEval();

                        // add named objects to instance
                        foreach (var keyValue in analysis.NamedObjects)
                        {
                            var type = keyValue.Value;
                            if (type.Type.UnderlyingType != null)
                            {
                                var ns  = unit.ProjectState.GetAnalysisValueFromObjects(((IDotNetPythonInterpreter)unit.ProjectState.Interpreter).GetBuiltinType(type.Type.UnderlyingType));
                                var bci = ns as BuiltinClassInfo;
                                if (bci != null)
                                {
                                    ns = bci.Instance;
                                }
                                self.SetMember(node, evalUnit, keyValue.Key, ns.SelfSet);
                            }

                            // TODO: Better would be if SetMember took something other than a node, then we'd
                            // track references w/o this extra effort.
                            foreach (var inst in self)
                            {
                                InstanceInfo instInfo = inst as InstanceInfo;
                                if (instInfo != null && instInfo.InstanceAttributes != null)
                                {
                                    VariableDef def;
                                    if (instInfo.InstanceAttributes.TryGetValue(keyValue.Key, out def))
                                    {
                                        def.AddAssignment(
                                            new EncodedLocation(
                                                new LocationInfo(xamlProject.FilePath, type.LineNumber, type.LineOffset),
                                                null
                                                ),
                                            xamlProject
                                            );
                                    }
                                }
                            }
                        }

                        // add references to event handlers
                        foreach (var keyValue in analysis.EventHandlers)
                        {
                            // add reference to methods...
                            var member = keyValue.Value;

                            // TODO: Better would be if SetMember took something other than a node, then we'd
                            // track references w/o this extra effort.
                            foreach (var inst in self)
                            {
                                InstanceInfo instInfo = inst as InstanceInfo;
                                if (instInfo != null)
                                {
                                    ClassInfo ci = instInfo.ClassInfo;

                                    VariableDef def;
                                    if (ci.Scope.TryGetVariable(keyValue.Key, out def))
                                    {
                                        def.AddReference(
                                            new EncodedLocation(
                                                new LocationInfo(xamlProject.FilePath, member.LineNumber, member.LineOffset),
                                                null
                                                ),
                                            xamlProject
                                            );
                                    }
                                }
                            }
                        }
                    }
                }
                // load component returns self
                return(self);
            }

            return(AnalysisSet.Empty);
        }
Exemple #2
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()
                );
        }
Exemple #3
0
        private void Parse(bool enqueueOnly, CancellationToken cancel)
        {
#if DEBUG
            Debug.Assert(Monitor.IsEntered(this));
#endif
            var parse  = GetCurrentParse();
            var tree   = parse?.Tree;
            var cookie = parse?.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");
                }

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

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

            MyScope.Scope.Children = new List <InterpreterScope>();
            MyScope.Scope.ClearNodeScopes();
            MyScope.Scope.ClearNodeValues();
            MyScope.Scope.ClearLinkedVariables();
            MyScope.Scope.ClearVariables();
            MyScope.ClearReferencedModules();
            MyScope.ClearUnresolvedModules();
            _unit.State.ClearDiagnostics(this);

            MyScope.EnsureModuleVariables(_unit.State);

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

            // 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 = PathUtils.EnsureEndSeparator(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.StartsWithOrdinal(pathPrefix, ignoreCase: true)
                                   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
            Analysis = new ModuleAnalysis(
                _unit,
                ((ModuleScope)_unit.Scope).CloneForPublish(),
                DocumentUri,
                AnalysisVersion
                );
        }