public static ModuleModel FromAnalysis()

in src/Caching/Impl/Models/ModuleModel.cs [59:152]


        public static ModuleModel FromAnalysis(IDocumentAnalysis analysis, IServiceContainer services, AnalysisCachingLevel options) {
            var uniqueId = analysis.Document.GetUniqueId(services, options);
            if (uniqueId == null) {
                // Caching level setting does not permit this module to be persisted.
                return null;
            }

            var variables = new Dictionary<string, VariableModel>();
            var functions = new Dictionary<string, FunctionModel>();
            var classes = new Dictionary<string, ClassModel>();
            var typeVars = new Dictionary<string, TypeVarModel>();
            var namedTuples = new Dictionary<string, NamedTupleModel>();
            // Go directly through variables which names are listed in GetMemberNames
            // as well as variables that are declarations.
            var exportedNames = new HashSet<string>(analysis.Document.GetMemberNames());
            foreach (var v in analysis.GlobalScope.Variables
                .Where(v => exportedNames.Contains(v.Name) ||
                            v.Source == VariableSource.Declaration ||
                            v.Source == VariableSource.Builtin ||
                            v.Source == VariableSource.Generic)) {

                if (v.Value is IGenericTypeParameter && !typeVars.ContainsKey(v.Name)) {
                    typeVars[v.Name] = TypeVarModel.FromGeneric(v);
                    continue;
                }

                switch (v.Value) {
                    case ITypingNamedTupleType nt:
                        namedTuples[nt.Name] = new NamedTupleModel(nt);
                        continue;
                    case IPythonFunctionType ft when ft.IsLambda():
                        // No need to persist lambdas.
                        continue;
                    case IPythonFunctionType ft when v.Name != ft.Name:
                        // Variable assigned to type info of the function like
                        //    def func(): ...
                        //    x = type(func)
                        break;
                    case IPythonFunctionType ft:
                        var fm = GetFunctionModel(analysis, v, ft);
                        if (fm != null && !functions.ContainsKey(ft.Name)) {
                            functions[ft.Name] = fm;
                            continue;
                        }
                        break;
                    case IPythonClassType cls when v.Name != cls.Name:
                        // Variable assigned to type info of the class.
                        break;
                    case IPythonClassType cls
                        when cls.DeclaringModule.Equals(analysis.Document) || cls.DeclaringModule.Equals(analysis.Document.Stub):
                        if (!classes.ContainsKey(cls.Name)) {
                            classes[cls.Name] = new ClassModel(cls);
                            continue;
                        }
                        break;
                }

                // Do not re-declare classes and functions as variables in the model.
                if (!variables.ContainsKey(v.Name)) {
                    variables[v.Name] = VariableModel.FromVariable(v);
                }
            }

            // Take dependencies from imports. If module has stub we should also take
            // dependencies from there since persistent state is based on types that
            // are combination of stub and the module. Sometimes stub may import more
            // and we must make sure dependencies are restored before the module.
            var primaryDependencyWalker = new DependencyWalker(analysis.Ast);
            var stubDependencyWalker = analysis.Document.Stub != null ? new DependencyWalker(analysis.Document.Stub.Analysis.Ast) : null;
            var stubImports = stubDependencyWalker?.Imports ?? Enumerable.Empty<ImportModel>();
            var stubFromImports = stubDependencyWalker?.FromImports ?? Enumerable.Empty<FromImportModel>();

            return new ModuleModel {
                Id = uniqueId.GetStableHash(),
                UniqueId = uniqueId,
                Name = analysis.Document.Name,
                QualifiedName = analysis.Document.QualifiedName,
                Documentation = analysis.Document.Documentation,
                Functions = functions.Values.ToArray(),
                Variables = variables.Values.ToArray(),
                Classes = classes.Values.ToArray(),
                TypeVars = typeVars.Values.ToArray(),
                NamedTuples = namedTuples.Values.ToArray(),
                NewLines = analysis.Ast.NewLineLocations.Select(l => new NewLineModel {
                    EndIndex = l.EndIndex,
                    Kind = l.Kind
                }).ToArray(),
                FileSize = analysis.Ast.EndIndex,
                Imports = primaryDependencyWalker.Imports.ToArray(),
                FromImports = primaryDependencyWalker.FromImports.ToArray(),
                StubImports = stubImports.ToArray(),
                StubFromImports = stubFromImports.ToArray()
            };
        }