Пример #1
0
        public AstPythonType(PythonAst ast, IPythonModule declModule, ClassDefinition def, string doc, LocationInfo loc) {
            _members = new Dictionary<string, IMember>();

            Name = def.Name;
            Documentation = doc;
            DeclaringModule = declModule;
            Mro = new IPythonType[0];
            Locations = new[] { loc };
        }
Пример #2
0
 public AstAnalysisWalker(
     IPythonInterpreter interpreter,
     PythonAst ast,
     IPythonModule module,
     string filePath,
     Dictionary<string, IMember> members
 ) {
     _interpreter = interpreter;
     _ast = ast;
     _module = module;
     _filePath = filePath;
     _members = members;
     _scope = new Stack<Dictionary<string, IMember>>();
     _noneInst = new AstPythonConstant(_interpreter.GetBuiltinType(BuiltinTypeId.NoneType));
 }
Пример #3
0
        public AstPythonFunction(PythonAst ast, IPythonModule declModule, IPythonType declType, FunctionDefinition def, string doc) {
            DeclaringModule = declModule;
            DeclaringType = declType;

            Name = def.Name;
            Documentation = doc;

            foreach (var dec in (def.Decorators?.Decorators).MaybeEnumerate().OfType<NameExpression>()) {
                if (dec.Name == "classmethod") {
                    IsClassMethod = true;
                } else if (dec.Name == "staticmethod") {
                    IsStatic = true;
                }
            }

            _overloads = new List<AstPythonFunctionOverload> {
                new AstPythonFunctionOverload(Documentation, "", MakeParameters(ast, def), MakeReturns(def))
            };
        }
Пример #4
0
        private IEnumerable<IAnalysisItemView> CalculateChildren() {
            if (_module == null) {
                _module = _interpreter.ImportModule(Name);
            }

            if (File.Exists(_idbPath)) {
                yield return RawView.FromFile(_idbPath);
            }

            var cpm = _module as CPythonModule;
            if (cpm != null) {
                cpm.EnsureLoaded();
            }

            if (cpm != null && cpm._hiddenMembers != null) {
                foreach (var keyValue in cpm._hiddenMembers) {
                    yield return MemberView.Make(_context, keyValue.Key, keyValue.Value);
                }
            }

            foreach (var memberName in _module.GetMemberNames(_context)) {
                yield return MemberView.Make(_context, _module, memberName);
            }
        }
Пример #5
0
 protected LocatedMember(IPythonModule module) : this(new Location(module, default))
        public static IMember TypeInfo(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 ? args[0].GetPythonType() : module.Interpreter.GetBuiltinType(BuiltinTypeId.Type));
        }
        public static IMember Next(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 && args[0] is IPythonIterator it ? it.Next : null);
        }
Пример #8
0
 public bool BeginModuleLoad(IPythonModule module, int millisecondsTimeout)
 {
     return(_sharedState.BeginModuleLoad(module, millisecondsTimeout));
 }
        public static IMember CollectionItem(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 && args[0] is PythonCollection c?c.Contents.FirstOrDefault() : null);
        }
Пример #10
0
 internal void AddChildModule(string name, IPythonModule module) {
     _childModules.Add(name);
     _members[name] = module;
 }
 protected AnalysisWalker(IServiceContainer services, IPythonModule module, PythonAst ast)
     : this(new ExpressionEval(services, module, ast))
 {
 }
Пример #12
0
 public void Deconstruct(out IPythonModule module, out IndexSpan indexSpan) => (module, indexSpan) = (Module, IndexSpan);
Пример #13
0
 public GlobalScope(IPythonModule module, PythonAst ast) : base(null, null, module)
 {
     _ast = ast;
     DeclareBuiltinVariables();
 }
 public ModuleType(IPythonModule module)
 {
     DeclaringModule = module;
 }
Пример #15
0
 public Location(IPythonModule module, IndexSpan indexSpan = default)
 {
     Module    = module;
     IndexSpan = indexSpan;
 }
        private static bool BuiltinModuleContainsMember(IModuleContext context, string name, IPythonModule module)
        {
            var member = module.GetMember(context, name);

            if (member == null)
            {
                return(false);
            }

            if (IsExcludedBuiltin(module, member))
            {
                // if a module imports a builtin and exposes it don't report it for purposes of adding imports
                return(false);
            }

            // if something non-excludable aliased w/ something excludable we probably only care about the excludable
            // (for example a module and None - timeit.py does this in the std lib)
            if (member is IPythonMultipleMembers multipleMembers)
            {
                foreach (var innerMember in multipleMembers.GetMembers())
                {
                    if (IsExcludedBuiltin(module, innerMember))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
 public AstPythonProperty(FunctionDefinition fd, IPythonModule declaringModule, IPythonType declaringType, ILocationInfo location)
     : base(fd.Name, declaringModule, null, location)
 {
     FunctionDefinition = fd;
     DeclaringType      = declaringType;
 }
Пример #18
0
        protected override IPythonModule CreateModule(string name)
        {
            var moduleImport = CurrentPathResolver.GetModuleImportFromModuleName(name);

            if (moduleImport == null)
            {
                Log?.Log(TraceEventType.Verbose, "Import not found: ", name);
                return(null);
            }

            if (moduleImport.ModulePath != null)
            {
                var module = GetRdt().GetDocument(new Uri(moduleImport.ModulePath));
                if (module != null)
                {
                    GetRdt().LockDocument(module.Uri);
                    return(module);
                }
            }

            var moduleType = moduleImport.IsBuiltin ? ModuleType.CompiledBuiltin
                : moduleImport.IsCompiled ? ModuleType.Compiled
                : moduleImport.IsLibrary ? ModuleType.Library
                : ModuleType.User;

            var dbs = GetDbService();

            moduleImport.IsPersistent = dbs != null && dbs.ModuleExistsInStorage(name, moduleImport.ModulePath, moduleType);

            IPythonModule stub = null;

            if (!moduleImport.IsPersistent)
            {
                // If there is a stub, make sure it is loaded and attached
                // First check stub next to the module.
                if (TryCreateModuleStub(name, moduleImport.ModulePath, out stub))
                {
                    Analyzer.InvalidateAnalysis(stub);
                }
                else
                {
                    // If nothing found, try Typeshed.
                    stub = Interpreter.TypeshedResolution.GetOrLoadModule(moduleImport.IsBuiltin ? name : moduleImport.FullName);
                }

                // If stub is created and its path equals to module, return that stub as module
                if (stub != null && stub.FilePath.PathEquals(moduleImport.ModulePath))
                {
                    return(stub);
                }
            }

            if (moduleImport.IsBuiltin)
            {
                Log?.Log(TraceEventType.Verbose, "Create built-in compiled (scraped) module: ", name, Configuration.InterpreterPath);
                return(new CompiledBuiltinPythonModule(name, stub, moduleImport.IsPersistent, Services));
            }

            if (moduleImport.IsCompiled)
            {
                Log?.Log(TraceEventType.Verbose, "Create compiled (scraped): ", moduleImport.FullName, moduleImport.ModulePath, moduleImport.RootPath);
                return(new CompiledPythonModule(moduleImport.FullName, moduleType, moduleImport.ModulePath, stub, moduleImport.IsPersistent, false, Services));
            }

            Log?.Log(TraceEventType.Verbose, "Import: ", moduleImport.FullName, moduleImport.ModulePath);
            // Module inside workspace == user code.

            var mco = new ModuleCreationOptions {
                ModuleName   = moduleImport.FullName,
                ModuleType   = moduleType,
                FilePath     = moduleImport.ModulePath,
                Stub         = stub,
                IsPersistent = moduleImport.IsPersistent
            };

            return(GetRdt().AddModule(mco));
        }
Пример #19
0
 public ModuleRefView(IModuleContext context, string name, IPythonModule module)
     : base(context, name, module) {
 }
 /// <summary>
 /// Creates delegate type wrapper over an existing type.
 /// Use dedicated constructor for wrapping builtin types.
 /// </summary>
 public PythonTypeWrapper(IPythonType type, IPythonModule declaringModule)
 {
     _innerType      = type ?? throw new ArgumentNullException(nameof(type));
     DeclaringModule = declaringModule;
 }
Пример #21
0
 public void EndModuleLoad(IPythonModule module) {
     _sharedState.EndModuleLoad(module);
 }
 /// <summary>
 /// Creates type wrapper for a built-in type. This is preferable way to
 /// wrap builtins since it can be done when builtins module is not loaded
 /// yet - such as when builtins module itself is being imported or specialized.
 /// </summary>
 public PythonTypeWrapper(BuiltinTypeId builtinTypeId, IPythonModule declaringModule)
 {
     DeclaringModule = declaringModule ?? throw new ArgumentNullException(nameof(declaringModule));
     _builtinTypeId  = builtinTypeId;
 }
Пример #23
0
 public EmptyIterator(IPythonModule declaringModule) : base(declaringModule, PythonMemberType.Class)
 {
     Type = declaringModule.Interpreter.UnknownType;
 }
 public void RemoveReferences(IPythonModule module) => InnerType?.RemoveReferences(module);
Пример #25
0
 public void AddModule(string moduleName, IPythonModule module)
 {
     _sharedState.Modules[moduleName] = module;
 }
 public ModuleInfo With(IPythonModule module)
 {
     return(new ModuleInfo(CurrentFileAnalysis, module, NameParts, moduleImported: true));
 }
Пример #27
0
 public void EndModuleLoad(IPythonModule module)
 {
     _sharedState.EndModuleLoad(module);
 }
 public FunctionCallEvaluator(IPythonModule declaringModule, FunctionDefinition fd, ExpressionEval eval) : base(eval)
 {
     _declaringModule = declaringModule ?? throw new ArgumentNullException(nameof(declaringModule));
     _eval            = eval ?? throw new ArgumentNullException(nameof(eval));
     _function        = fd ?? throw new ArgumentNullException(nameof(fd));
 }
        public static IMember Identity(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var args = argSet.Values <IMember>();

            return(args.Count > 0 ? args.FirstOrDefault(a => !a.IsUnknown()) ?? args[0] : null);
        }
Пример #30
0
        public bool BeginModuleLoad(IPythonModule module, int millisecondsTimeout) {
#if DEBUG
            var stopwatch = new Stopwatch();
            stopwatch.Start();
#endif
            bool needUnlock = false;
            try {
                Monitor.TryEnter(_moduleLoadLock, millisecondsTimeout, ref needUnlock);
                if (!needUnlock) {
                    return false;
                }
#if DEBUG
                stopwatch.Stop();
                if (stopwatch.ElapsedMilliseconds > 100) {
                    string heldByMessage = "";
                    if (_moduleLoadLockThread != null) {
                        heldByMessage = string.Format(" (held by {0}:{1})",
                            _moduleLoadLockThread.Name, _moduleLoadLockThread.ManagedThreadId
                        );
                    }
                    Console.WriteLine(
                        "Waited {0}ms for module loader lock on thread {1}:{2}{3}",
                        stopwatch.ElapsedMilliseconds,
                        Thread.CurrentThread.Name, Thread.CurrentThread.ManagedThreadId,
                        heldByMessage
                    );
                }
                _moduleLoadLockThread = Thread.CurrentThread;
#endif
                _modulesLoading.Add(module);
                needUnlock = false;
            } finally {
                if (needUnlock) {
                    Monitor.Exit(_moduleLoadLock);
                }
            }
            return true;
        }
        public static IMember ListOfStrings(IPythonModule module, IPythonFunctionOverload overload, IArgumentSet argSet)
        {
            var type = new TypingListType("List", module.Interpreter.GetBuiltinType(BuiltinTypeId.Str), module.Interpreter, false);

            return(new TypingList(type));
        }
        public override void TestInitialize()
        {
            base.TestInitialize();

            _module = Python.ImportModule(ModulePath, ModuleMain);
        }
Пример #33
0
        public TryImportModuleResult TryImportModule(
            string name,
            out IPythonModule module,
            TryImportModuleContext context
            )
        {
            module = null;
            if (string.IsNullOrEmpty(name))
            {
                return(TryImportModuleResult.ModuleNotFound);
            }

            Debug.Assert(!name.EndsWithOrdinal("."), $"{name} should not end with '.'");

            // Handle builtins explicitly
            if (name == BuiltinModuleName)
            {
                Debug.Fail($"Interpreters must handle import {name} explicitly");
                return(TryImportModuleResult.NotSupported);
            }

            var            modules       = context?.ModuleCache;
            int            importTimeout = context?.Timeout ?? 5000;
            SentinelModule sentinalValue = null;

            if (modules != null)
            {
                // Return any existing module
                if (modules.TryGetValue(name, out module) && module != null)
                {
                    if (module is SentinelModule smod)
                    {
                        // If we are importing this module on another thread, allow
                        // time for it to complete. This does not block if we are
                        // importing on the current thread or the module is not
                        // really being imported.
                        var newMod = smod.WaitForImport(importTimeout);
                        if (newMod is SentinelModule)
                        {
                            _log?.Log(TraceLevel.Warning, "RecursiveImport", name);
                            module = newMod;
                        }
                        else if (newMod == null)
                        {
                            _log?.Log(TraceLevel.Warning, "ImportTimeout", name);
                            module = null;
                            return(TryImportModuleResult.Timeout);
                        }
                        else
                        {
                            module = newMod;
                        }
                    }
                    return(TryImportModuleResult.Success);
                }

                // Set up a sentinel so we can detect recursive imports
                sentinalValue = new SentinelModule(name, true);
                if (!modules.TryAdd(name, sentinalValue))
                {
                    // Try to get the new module, in case we raced with a .Clear()
                    if (modules.TryGetValue(name, out module) && !(module is SentinelModule))
                    {
                        return(module == null ? TryImportModuleResult.ModuleNotFound : TryImportModuleResult.Success);
                    }
                    // If we reach here, the race is too complicated to recover
                    // from. Signal the caller to try importing again.
                    _log?.Log(TraceLevel.Warning, "RetryImport", name);
                    return(TryImportModuleResult.NeedRetry);
                }
            }

            // Do normal searches
            if (!string.IsNullOrEmpty(Configuration?.InterpreterPath))
            {
                var importTask = ImportFromSearchPathsAsync(name, context);
                if (importTask.Wait(importTimeout))
                {
                    module = importTask.Result;
                }
                else
                {
                    _log?.Log(TraceLevel.Error, "ImportTimeout", name, "ImportFromSearchPaths");
                    module = null;
                }
                module = module ?? ImportFromBuiltins(name, context.BuiltinModule as AstBuiltinsPythonModule);
            }
            if (module == null)
            {
                module = ImportFromCache(name);
            }

            if (modules != null)
            {
                // Replace our sentinel, or if we raced, get the current
                // value and abandon the one we just created.
                if (!modules.TryUpdate(name, module, sentinalValue))
                {
                    // Try to get the new module, in case we raced
                    if (modules.TryGetValue(name, out module) && !(module is SentinelModule))
                    {
                        return(module == null ? TryImportModuleResult.ModuleNotFound : TryImportModuleResult.Success);
                    }
                    // If we reach here, the race is too complicated to recover
                    // from. Signal the caller to try importing again.
                    _log?.Log(TraceLevel.Warning, "RetryImport", name);
                    return(TryImportModuleResult.NeedRetry);
                }
                sentinalValue.Complete(module);
                sentinalValue.Dispose();
            }

            // Also search for type stub packages if enabled and we are not a blacklisted module
            if (module != null && context.IncludeTypeStubPackages && module.Name != "typing")
            {
                // Note that this currently only looks in the typeshed package, as type stub
                // packages are not yet standardised so we don't know where to look.
                // The details will be in PEP 561.
                var typeShedPaths = GetTypeShedPaths(importTimeout);
                if (typeShedPaths?.Any() == true)
                {
                    var mtsp = FindModuleInSearchPath(typeShedPaths, null, module.Name);
                    if (mtsp.HasValue)
                    {
                        var mp = mtsp.Value;
                        if (mp.IsCompiled)
                        {
                            Debug.Fail("Unsupported native module in typeshed");
                        }
                        else
                        {
                            _log?.Log(TraceLevel.Verbose, "ImportTypeShed", mp.FullName, FastRelativePath(mp.SourceFile));
                            var tsModule = PythonModuleLoader.FromFile(context.Interpreter, mp.SourceFile, LanguageVersion, mp.FullName);

                            if (tsModule != null)
                            {
                                if (context.MergeTypeStubPackages)
                                {
                                    module = AstPythonMultipleModules.Combine(module, tsModule);
                                }
                                else
                                {
                                    module = tsModule;
                                }
                            }
                        }
                    }
                }
            }

            return(module == null ? TryImportModuleResult.ModuleNotFound : TryImportModuleResult.Success);
        }
Пример #34
0
 public void RemoveReferences(IPythonModule module)
 {
 }
Пример #35
0
        private void AssignMemberFromModule(IPythonModule module, string typeName, IMember memb, List<object> indexTypes, Action<IPythonType> assign, bool addFixups) {
            if (memb == null) {
                IBuiltinPythonModule builtin;
                if ((builtin = module as IBuiltinPythonModule) != null) {
                    memb = builtin.GetAnyMember(typeName);
                } else {
                    memb = module.GetMember(null, typeName);
                }
            }

            IPythonType type;
            CPythonMultipleMembers mm;
            if (memb == null) {
                if (addFixups) {
                    AddFixup(() => {
                        // Fixup 2: Type was not found in module
                        AssignMemberFromModule(module, typeName, null, indexTypes, assign, false);
                    });
                    return;
                } else {
                    // TODO: Maybe skip this to reduce noise in loaded database
                    AddObjectTypeFixup(assign);
                    return;
                }
            } else if ((type = memb as IPythonType) != null) {
                if (indexTypes != null) {
                    assign(new CPythonSequenceType(type, this, indexTypes));
                } else {
                    assign(type);
                }
            } else if ((mm = memb as CPythonMultipleMembers) != null) {
                mm.AssignTypes(this, assign);
            }
        }
 public void DeclareVariable(string name, IMember value, VariableSource source, IPythonModule module)
 => DeclareVariable(name, value, source, new Location(module));
Пример #37
0
 public void EndModuleLoad(IPythonModule module) {
     try {
         bool wasRemoved = _modulesLoading.Remove(module);
         Debug.Assert(wasRemoved);
         if (_modulesLoading.Count == 0) {
             RunFixups();
         }
     } finally {
         Monitor.Exit(_moduleLoadLock);
     }
 }
Пример #38
0
 public GlobalScope(IPythonModule module) : base(null, null, module)
 {
     DeclareBuiltinVariables();
 }
Пример #39
0
 public void AddModule(string name, IPythonModule module)
 {
     _modules[name] = module;
     ModuleNamesChanged?.Invoke(this, EventArgs.Empty);
 }
 public DependencyWalker(IPythonModule module, PythonAst ast = null)
 {
     _dependencyCollector = new DependencyCollector(module);
     ast = ast ?? module.GetAst();
     ast.Walk(this);
 }
Пример #41
0
 public bool BeginModuleLoad(IPythonModule module, int millisecondsTimeout) {
     return _sharedState.BeginModuleLoad(module, millisecondsTimeout);
 }
 /// <summary>
 /// Creates function for specializations
 /// </summary>
 public static PythonFunctionType ForSpecialization(string name, IPythonModule declaringModule)
 => new PythonFunctionType(name, new Location(declaringModule, default), true);
Пример #43
0
        /// <summary>
        /// Creates set of arguments for a function call based on the call expression
        /// and the function signature. The result contains expressions
        /// for arguments, but not actual values. <see cref="Evaluate"/> on how to
        /// get values for actual parameters.
        /// </summary>
        /// <param name="fn">Function type.</param>
        /// <param name="overloadIndex">Function overload to call.</param>
        /// <param name="instance">Type instance the function is bound to. For derived classes it is different from the declared type.</param>
        /// <param name="callExpr">Call expression that invokes the function.</param>
        /// <param name="module">Module that contains the call expression.</param>
        /// <param name="eval">Evaluator that can calculate values of arguments from their respective expressions.</param>
        public ArgumentSet(IPythonFunctionType fn, int overloadIndex, IPythonInstance instance, CallExpression callExpr, IPythonModule module, IExpressionEvaluator eval)
        {
            Eval            = eval;
            OverloadIndex   = overloadIndex;
            DeclaringModule = fn.DeclaringModule;

            if (callExpr == null)
            {
                // Typically invoked by specialization code without call expression in the code.
                // Caller usually does not care about arguments.
                _evaluated = true;
                return;
            }

            var overload = fn.Overloads[overloadIndex];
            var fd       = overload.FunctionDefinition;

            if (fn.IsSpecialized)
            {
                // Typically specialized function, like TypeVar() that does not actually have AST definition.
                // Make the arguments from the call expression. If argument does not have name,
                // try using name from the function definition based on the argument position.
                _arguments = new List <Argument>();
                for (var i = 0; i < callExpr.Args.Count; i++)
                {
                    var name = callExpr.Args[i].Name;
                    if (string.IsNullOrEmpty(name))
                    {
                        name = i < overload.Parameters.Count ? overload.Parameters[i].Name : $"arg{i}";
                    }
                    var node = fd != null && i < fd.Parameters.Length ? fd.Parameters[i] : null;
                    _arguments.Add(new Argument(name, ParameterKind.Normal, callExpr.Args[i].Expression, null, node));
                }
                return;
            }

            var callLocation = callExpr.GetLocation(module);

            // https://www.python.org/dev/peps/pep-3102/#id5
            // For each formal parameter, there is a slot which will be used to contain
            // the value of the argument assigned to that parameter. Slots which have
            // had values assigned to them are marked as 'filled'.Slots which have
            // no value assigned to them yet are considered 'empty'.

            var slots = new Argument[overload.Parameters.Count];

            for (var i = 0; i < overload.Parameters.Count; i++)
            {
                var node = fd != null && i < fd.Parameters.Length ? fd.Parameters[i] : null;
                slots[i] = new Argument(overload.Parameters[i], node);
            }

            // Locate sequence argument, if any
            var sa = slots.Where(s => s.Kind == ParameterKind.List).ToArray();

            if (sa.Length > 1)
            {
                // Error should have been reported at the function definition location by the parser.
                return;
            }

            var da = slots.Where(s => s.Kind == ParameterKind.Dictionary).ToArray();

            if (da.Length > 1)
            {
                // Error should have been reported at the function definition location by the parser.
                return;
            }

            _listArgument = sa.Length == 1 && sa[0].Name.Length > 0 ? new ListArg(sa[0].Name, sa[0].ValueExpression, sa[0].Location) : null;
            _dictArgument = da.Length == 1 ? new DictArg(da[0].Name, da[0].ValueExpression, da[0].Location) : null;

            // Class methods
            var formalParamIndex = 0;

            if (fn.DeclaringType != null && fn.HasClassFirstArgument() && slots.Length > 0)
            {
                slots[0].Value = instance != null?instance.GetPythonType() : fn.DeclaringType;

                formalParamIndex++;
            }

            try {
                // Positional arguments
                var callParamIndex = 0;
                for (; callParamIndex < callExpr.Args.Count; callParamIndex++, formalParamIndex++)
                {
                    var arg = callExpr.Args[callParamIndex];

                    if (!string.IsNullOrEmpty(arg.Name) && !arg.Name.StartsWithOrdinal("**"))
                    {
                        // Keyword argument. Done with positionals.
                        break;
                    }

                    if (formalParamIndex >= overload.Parameters.Count)
                    {
                        // We ran out of formal parameters and yet haven't seen
                        // any sequence or dictionary ones. This looks like an error.
                        _errors.Add(new DiagnosticsEntry(Resources.Analysis_TooManyFunctionArguments, arg.GetLocation(module).Span,
                                                         ErrorCodes.TooManyFunctionArguments, Severity.Warning, DiagnosticSource.Analysis));
                        return;
                    }

                    var formalParam = overload.Parameters[formalParamIndex];
                    if (formalParam.Kind == ParameterKind.List)
                    {
                        if (string.IsNullOrEmpty(formalParam.Name))
                        {
                            // If the next unfilled slot is a vararg slot, and it does not have a name, then it is an error.
                            _errors.Add(new DiagnosticsEntry(Resources.Analysis_TooManyPositionalArgumentBeforeStar, arg.GetLocation(module).Span,
                                                             ErrorCodes.TooManyPositionalArgumentsBeforeStar, Severity.Warning, DiagnosticSource.Analysis));
                            return;
                        }

                        // If the next unfilled slot is a vararg slot then all remaining
                        // non-keyword arguments are placed into the vararg slot.
                        if (_listArgument == null)
                        {
                            _errors.Add(new DiagnosticsEntry(Resources.Analysis_TooManyFunctionArguments, arg.GetLocation(module).Span,
                                                             ErrorCodes.TooManyFunctionArguments, Severity.Warning, DiagnosticSource.Analysis));
                            return;
                        }

                        for (; callParamIndex < callExpr.Args.Count; callParamIndex++)
                        {
                            arg = callExpr.Args[callParamIndex];
                            if (!string.IsNullOrEmpty(arg.Name))
                            {
                                // Keyword argument. Done here.
                                break;
                            }

                            _listArgument._Expressions.Add(arg.Expression);
                        }

                        break; // Sequence or dictionary parameter found. Done here.
                    }

                    if (formalParam.Kind == ParameterKind.Dictionary)
                    {
                        // Next slot is a dictionary slot, but we have positional arguments still.
                        _errors.Add(new DiagnosticsEntry(Resources.Analysis_TooManyPositionalArgumentBeforeStar, arg.GetLocation(module).Span,
                                                         ErrorCodes.TooManyPositionalArgumentsBeforeStar, Severity.Warning, DiagnosticSource.Analysis));
                        return;
                    }

                    // Regular parameter
                    slots[formalParamIndex].ValueExpression = arg.Expression;
                }

                // Keyword arguments
                for (; callParamIndex < callExpr.Args.Count; callParamIndex++)
                {
                    var arg = callExpr.Args[callParamIndex];

                    if (string.IsNullOrEmpty(arg.Name))
                    {
                        _errors.Add(new DiagnosticsEntry(Resources.Analysis_PositionalArgumentAfterKeyword, arg.GetLocation(module).Span,
                                                         ErrorCodes.PositionalArgumentAfterKeyword, Severity.Warning, DiagnosticSource.Analysis));
                        return;
                    }

                    var nvp = slots.FirstOrDefault(s => s.Name.EqualsOrdinal(arg.Name));
                    if (nvp == null)
                    {
                        // 'def f(a, b)' and then 'f(0, c=1)'. Per spec:
                        // if there is a 'keyword dictionary' argument, the argument is added
                        // to the dictionary using the keyword name as the dictionary key,
                        // unless there is already an entry with that key, in which case it is an error.
                        if (_dictArgument == null)
                        {
                            _errors.Add(new DiagnosticsEntry(Resources.Analysis_UnknownParameterName, arg.GetLocation(module).Span,
                                                             ErrorCodes.UnknownParameterName, Severity.Warning, DiagnosticSource.Analysis));
                            return;
                        }

                        if (_dictArgument.Arguments.ContainsKey(arg.Name))
                        {
                            _errors.Add(new DiagnosticsEntry(Resources.Analysis_ParameterAlreadySpecified.FormatUI(arg.Name), arg.GetLocation(module).Span,
                                                             ErrorCodes.ParameterAlreadySpecified, Severity.Warning, DiagnosticSource.Analysis));
                            return;
                        }

                        _dictArgument._Expressions[arg.Name] = arg.Expression;
                        continue;
                    }

                    if (nvp.ValueExpression != null || nvp.Value != null)
                    {
                        // Slot is already filled.
                        _errors.Add(new DiagnosticsEntry(Resources.Analysis_ParameterAlreadySpecified.FormatUI(arg.Name), arg.GetLocation(module).Span,
                                                         ErrorCodes.ParameterAlreadySpecified, Severity.Warning, DiagnosticSource.Analysis));
                        return;
                    }

                    // OK keyword parameter
                    nvp.ValueExpression = arg.Expression;
                }

                // We went through all positionals and keywords.
                // For each remaining empty slot: if there is a default value for that slot,
                // then fill the slot with the default value. If there is no default value,
                // then it is an error.
                foreach (var slot in slots.Where(s => s.Kind != ParameterKind.List && s.Kind != ParameterKind.Dictionary && s.Value == null))
                {
                    if (slot.ValueExpression == null)
                    {
                        var parameter = overload.Parameters.First(p => p.Name == slot.Name);
                        if (parameter.DefaultValue == null)
                        {
                            // TODO: parameter is not assigned and has no default value.
                            _errors.Add(new DiagnosticsEntry(Resources.Analysis_ParameterMissing.FormatUI(slot.Name), callLocation.Span,
                                                             ErrorCodes.ParameterMissing, Severity.Warning, DiagnosticSource.Analysis));
                        }
                        // Note that parameter default value expression is from the function definition AST
                        // while actual argument values are from the calling file AST.
                        slot.ValueExpression = CreateExpression(parameter.Name, parameter.DefaultValueString);
                        slot.Value           = parameter.DefaultValue;
                        slot.ValueIsDefault  = true;
                    }
                }
            } finally {
                // Optimistically return what we gathered, even if there are errors.
                _arguments = slots.Where(s => s.Kind != ParameterKind.List && s.Kind != ParameterKind.Dictionary).ToList();
            }
        }
Пример #44
0
 public void AddModule(string moduleName, IPythonModule module) {
     _sharedState.Modules[moduleName] = module;
 }