示例#1
0
        /// <summary>
        /// Determines value of the variable and declares it. Value depends if source module has submodule
        /// that is named the same as the variable and/or it has internal variables named same as the submodule.
        /// </summary>
        /// <example>'from a.b import c' when 'c' is both submodule of 'b' and a variable declared inside 'b'.</example>
        /// <param name="variableModule">Source module of the variable such as 'a.b' in 'from a.b import c as d'.</param>
        /// <param name="memberName">Module member name such as 'c' in 'from a.b import c as d'.</param>
        /// <param name="imports">Import search result.</param>
        /// <param name="variableName">Name of the variable to declare, such as 'd' in 'from a.b import c as d'.</param>
        /// <param name="importPosition">Position of the import statement.</param>
        /// <param name="nameLocation">Location of the variable name expression.</param>
        private void DeclareVariable(PythonVariableModule variableModule, string memberName, IImportSearchResult imports, string variableName, int importPosition, Node nameLocation)
        {
            // First try imports since child modules should win, i.e. in 'from a.b import c'
            // 'c' should be a submodule if 'b' has one, even if 'b' also declares 'c = 1'.
            var value = GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);

            // First try exported or child submodules.
            value = value ?? variableModule.GetMember(memberName);

            // Value may be variable or submodule. If it is variable, we need it in order to add reference.
            var variable = variableModule.Analysis?.GlobalScope?.Variables[memberName];

            value = variable?.Value?.Equals(value) == true ? variable : value;

            // If nothing is exported, variables are still accessible.
            value = value ?? variableModule.Analysis?.GlobalScope?.Variables[memberName]?.Value ?? Eval.UnknownType;

            // Do not allow imported variables to override local declarations
            var canOverwrite = CanOverwriteVariable(variableName, importPosition, value);

            // Do not declare references to '*'
            var locationExpression = nameLocation is NameExpression nex && nex.Name == "*" ? null : nameLocation;

            Eval.DeclareVariable(variableName, value, VariableSource.Import, locationExpression, canOverwrite);

            // Make sure module is loaded and analyzed.
            if (value is IPythonModule m)
            {
                ModuleResolution.GetOrLoadModule(m.Name);
            }
        }
示例#2
0
        private void HandleModuleImportStar(PythonVariableModule variableModule)
        {
            if (variableModule.Module == Module)
            {
                // from self import * won't define any new members
                return;
            }

            foreach (var memberName in variableModule.GetMemberNames())
            {
                var member = variableModule.GetMember(memberName);
                if (member == null)
                {
                    Log?.Log(TraceEventType.Verbose, $"Undefined import: {variableModule.Name}, {memberName}");
                }
                else if (member.MemberType == PythonMemberType.Unknown)
                {
                    Log?.Log(TraceEventType.Verbose, $"Unknown import: {variableModule.Name}, {memberName}");
                }

                member = member ?? Eval.UnknownType;
                if (member is IPythonModule m)
                {
                    ModuleResolution.GetOrLoadModule(m.Name);
                }

                Eval.DeclareVariable(memberName, member, VariableSource.Import, variableModule.Location);
            }
        }
        private void HandleModuleImportStar(PythonVariableModule variableModule, bool isImplicitPackage)
        {
            if (variableModule.Module == Module)
            {
                // from self import * won't define any new members
                return;
            }

            // If __all__ is present, take it, otherwise declare all members from the module that do not begin with an underscore.
            var memberNames = isImplicitPackage
                ? variableModule.GetMemberNames()
                : variableModule.Analysis.StarImportMemberNames ?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_"));

            foreach (var memberName in memberNames)
            {
                var member = variableModule.GetMember(memberName);
                if (member == null)
                {
                    Log?.Log(TraceEventType.Verbose, $"Undefined import: {variableModule.Name}, {memberName}");
                }
                else if (member.MemberType == PythonMemberType.Unknown)
                {
                    Log?.Log(TraceEventType.Verbose, $"Unknown import: {variableModule.Name}, {memberName}");
                }

                member = member ?? Eval.UnknownType;
                if (member is IPythonModule m)
                {
                    ModuleResolution.GetOrLoadModule(m.Name);
                }

                var variable = variableModule.Analysis?.GlobalScope?.Variables[memberName];
                Eval.DeclareVariable(memberName, variable ?? member, VariableSource.Import);
            }
        }
示例#4
0
        private void HandleModuleImportStar(PythonVariableModule variableModule, IImportSearchResult imports, int importPosition, NameExpression nameExpression)
        {
            if (variableModule.Module == Module)
            {
                // from self import * won't define any new members
                return;
            }
            // If __all__ is present, take it, otherwise declare all members from the module that do not begin with an underscore.
            var memberNames = imports is ImplicitPackageImport
                ? variableModule.GetMemberNames()
                : variableModule.Analysis.StarImportMemberNames ?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_"));

            foreach (var memberName in memberNames)
            {
                DeclareVariable(variableModule, memberName, imports, memberName, importPosition, nameExpression);
            }
        }
        /// <summary>
        /// Determines value of the variable and declares it. Value depends if source module has submodule
        /// that is named the same as the variable and/or it has internal variables named same as the submodule.
        /// </summary>
        /// <example>'from a.b import c' when 'c' is both submodule of 'b' and a variable declared inside 'b'.</example>
        /// <param name="variableModule">Source module of the variable such as 'a.b' in 'from a.b import c as d'. May be null if the module was not found.</param>
        /// <param name="memberName">Module member name such as 'c' in 'from a.b import c as d'.</param>
        /// <param name="imports">Import search result.</param>
        /// <param name="variableName">Name of the variable to declare, such as 'd' in 'from a.b import c as d'.</param>
        /// <param name="importPosition">Position of the import statement.</param>
        /// <param name="nameLocation">Location of the variable name expression.</param>
        private void DeclareVariable(PythonVariableModule variableModule, string memberName, IImportSearchResult imports, string variableName, int importPosition, Node nameLocation)
        {
            IMember value = Eval.UnknownType;

            if (variableModule != null)
            {
                // First try imports since child modules should win, i.e. in 'from a.b import c'
                // 'c' should be a submodule if 'b' has one, even if 'b' also declares 'c = 1'.
                value = GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);

                // First try exported or child submodules.
                var member = variableModule.GetMember(memberName);

                // Value may be variable or submodule. If it is variable, we need it in order to add reference.
                var variable = _importedVariableHandler.GetVariable(variableModule, memberName);

                if (member is PythonVariableModule vm && vm.Equals(variable?.Value))
                {
                    // If member is submodule, use actual variable so it can be linked through for goto definition.
                    value = variable;
                }
                else if (value == null)
                {
                    if (member is PythonVariableModule)
                    {
                        // If member is submodule, use it.
                        value = member;
                    }
                    else if (variable?.Value != null)
                    {
                        // Otherwise use variable, if available so references can be linked.
                        value = variable;
                    }
                    else if (member != null)
                    {
                        value = member;
                    }
                    else
                    {
                        value = Eval.UnknownType;
                    }
                }
            }
示例#6
0
        private IMember GetValueFromImports(PythonVariableModule parentModule, IImportChildrenSource childrenSource, string memberName)
        {
            if (childrenSource == null || !childrenSource.TryGetChildImport(memberName, out var childImport))
            {
                return(Interpreter.UnknownType);
            }

            switch (childImport)
            {
            case ModuleImport moduleImport:
                var module = ModuleResolution.GetOrLoadModule(moduleImport.FullName);
                return(module != null?GetOrCreateVariableModule(module, parentModule, moduleImport.Name) : Interpreter.UnknownType);

            case ImplicitPackageImport packageImport:
                return(GetOrCreateVariableModule(packageImport.FullName, parentModule, memberName));

            default:
                return(Interpreter.UnknownType);
            }
        }
示例#7
0
        private void AssignVariables(FromImportStatement node, IImportSearchResult imports, PythonVariableModule variableModule)
        {
            if (variableModule == null)
            {
                return;
            }

            var names   = node.Names;
            var asNames = node.AsNames;

            if (names.Count == 1 && names[0].Name == "*")
            {
                // TODO: warn this is not a good style per
                // TODO: https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module
                // TODO: warn this is invalid if not in the global scope.
                HandleModuleImportStar(variableModule, imports is ImplicitPackageImport, node.StartIndex);
                return;
            }

            for (var i = 0; i < names.Count; i++)
            {
                var memberName = names[i].Name;
                if (!string.IsNullOrEmpty(memberName))
                {
                    var nameExpression = asNames[i] ?? names[i];
                    var variableName   = nameExpression?.Name ?? memberName;
                    var variable       = variableModule.Analysis?.GlobalScope?.Variables[memberName];
                    var exported       = variable ?? variableModule.GetMember(memberName);
                    var value          = exported ?? GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);
                    // Do not allow imported variables to override local declarations
                    Eval.DeclareVariable(variableName, value, VariableSource.Import, nameExpression, CanOverwriteVariable(variableName, node.StartIndex));
                }
            }
        }
        private void AssignVariables(FromImportStatement node, IImportSearchResult imports, PythonVariableModule variableModule)
        {
            var names   = node.Names;
            var asNames = node.AsNames;

            if (variableModule != null && names.Count == 1 && names[0].Name == "*")
            {
                // TODO: warn this is not a good style per
                // TODO: https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module
                // TODO: warn this is invalid if not in the global scope.
                HandleModuleImportStar(variableModule, imports, node.StartIndex, names[0]);
                return;
            }

            for (var i = 0; i < names.Count; i++)
            {
                var memberName = names[i].Name;
                if (string.IsNullOrEmpty(memberName))
                {
                    continue;
                }

                var nameExpression = asNames[i] ?? names[i];
                var variableName   = nameExpression?.Name ?? memberName;
                if (!string.IsNullOrEmpty(variableName))
                {
                    DeclareVariable(variableModule, memberName, imports, variableName, node.StartIndex, nameExpression);
                }

                if (imports is IImportChildrenSource cs &&
                    cs.TryGetChildImport(memberName, out var csr) &&
                    HandleImportSearchResult(csr, variableModule, null, names[i], out var childModule))
                {
                    _importedVariableHandler.EnsureModule(childModule);
                }
            }
        }
示例#9
0
        private void AssignVariables(FromImportStatement node, IImportSearchResult imports, PythonVariableModule variableModule)
        {
            if (variableModule == null)
            {
                return;
            }

            var names   = node.Names;
            var asNames = node.AsNames;

            if (names.Count == 1 && names[0].Name == "*")
            {
                // TODO: warn this is not a good style per
                // TODO: https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module
                // TODO: warn this is invalid if not in the global scope.
                HandleModuleImportStar(variableModule, imports, node.StartIndex, names[0]);
                return;
            }

            for (var i = 0; i < names.Count; i++)
            {
                var memberName = names[i].Name;
                if (!string.IsNullOrEmpty(memberName))
                {
                    var nameExpression = asNames[i] ?? names[i];
                    var variableName   = nameExpression?.Name ?? memberName;
                    if (!string.IsNullOrEmpty(variableName))
                    {
                        DeclareVariable(variableModule, memberName, imports, variableName, node.StartIndex, nameExpression);
                    }
                }
            }
        }
示例#10
0
        private void AssignVariables(FromImportStatement node, IImportSearchResult imports, PythonVariableModule variableModule)
        {
            if (variableModule == null)
            {
                return;
            }

            var names   = node.Names;
            var asNames = node.AsNames;

            if (names.Count == 1 && names[0].Name == "*")
            {
                // TODO: warn this is not a good style per
                // TODO: https://docs.python.org/3/faq/programming.html#what-are-the-best-practices-for-using-import-in-a-module
                // TODO: warn this is invalid if not in the global scope.
                HandleModuleImportStar(variableModule);
                return;
            }

            for (var i = 0; i < names.Count; i++)
            {
                var memberName = names[i].Name;
                if (!string.IsNullOrEmpty(memberName))
                {
                    var variableName = asNames[i]?.Name ?? memberName;
                    var value        = variableModule.GetMember(memberName) ?? GetValueFromImports(variableModule, imports as IImportChildrenSource, memberName);

                    Eval.DeclareVariable(variableName, value, VariableSource.Import, names[i]);
                }
            }
        }
 public IEnumerable <string> GetMemberNames(PythonVariableModule variableModule)
 => variableModule.Analysis.StarImportMemberNames ?? variableModule.GetMemberNames().Where(s => !s.StartsWithOrdinal("_"));