예제 #1
0
        public static void Generate(PythonTypeDatabaseCreationRequest request)
        {
            var onExit = request.OnExit;

            GenerateAsync(request).ContinueWith(t => {
                var exc = t.Exception;
                if (exc == null)
                {
                    return;
                }

                try {
                    var message = string.Format(
                        "ERROR_STDLIB: {0}\\{1}{2}",
                        request.Factory.Configuration.Id,
                        Environment.NewLine,
                        (exc.InnerException ?? exc).ToString()
                        );

                    Debug.WriteLine(message);

                    var glogPath = Path.Combine(CompletionDatabasePath, "AnalysisLog.txt");
                    File.AppendAllText(glogPath, message);
                } catch (IOException) {
                } catch (ArgumentException) {
                } catch (SecurityException) {
                } catch (UnauthorizedAccessException) {
                }

                if (onExit != null)
                {
                    onExit(PythonTypeDatabase.InvalidOperationExitCode);
                }
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
        public virtual void GenerateDatabase(GenerateDatabaseOptions options, Action <int> onExit = null)
        {
            var req = new PythonTypeDatabaseCreationRequest {
                Factory           = this,
                OutputPath        = DatabasePath,
                SkipUnchanged     = options.HasFlag(GenerateDatabaseOptions.SkipUnchanged),
                DetectLibraryPath = !AssumeSimpleLibraryLayout
            };

            GenerateDatabase(req, onExit);
        }
예제 #3
0
        public override void GenerateDatabase(GenerateDatabaseOptions options, Action <int> onExit = null)
        {
            if (!Directory.Exists(Configuration.LibraryPath))
            {
                return;
            }

            // Create and mark the DB directory as hidden
            try {
                var dbDir = Directory.CreateDirectory(DatabasePath);
                dbDir.Attributes |= FileAttributes.Hidden;
            } catch (ArgumentException) {
            } catch (IOException) {
            } catch (UnauthorizedAccessException) {
            }

            var req = new PythonTypeDatabaseCreationRequest {
                Factory           = this,
                OutputPath        = DatabasePath,
                SkipUnchanged     = options.HasFlag(GenerateDatabaseOptions.SkipUnchanged),
                DetectLibraryPath = !AssumeSimpleLibraryLayout
            };

            req.ExtraInputDatabases.Add(_base.DatabasePath);

            _baseHasRefreshed = false;

            if (_base.IsCurrent)
            {
                base.GenerateDatabase(req, onExit);
            }
            else
            {
                req.WaitFor       = _base;
                req.SkipUnchanged = false;

                // Clear out the existing base database, since we're going to
                // need to reload it again. This also means that when
                // NewDatabaseAvailable is raised, we are expecting it and won't
                // incorrectly set _baseHasRefreshed to true again.
                _baseDb = null;

                // Start our analyzer first, since we will wait up to a minute
                // for our base analyzer to start (which may cause a one minute
                // delay if it completes before we start, but that is unlikely).
                base.GenerateDatabase(req, onExit);
                _base.GenerateDatabase(GenerateDatabaseOptions.SkipUnchanged);
            }
        }
        public virtual void GenerateDatabase(GenerateDatabaseOptions options, Action <int> onExit = null)
        {
            if (string.IsNullOrEmpty(DatabasePath))
            {
                onExit?.Invoke(PythonTypeDatabase.NotSupportedExitCode);
                return;
            }

            var req = new PythonTypeDatabaseCreationRequest {
                Factory       = this,
                OutputPath    = DatabasePath,
                SkipUnchanged = options.HasFlag(GenerateDatabaseOptions.SkipUnchanged)
            };

            GenerateDatabase(req, onExit);
        }
        protected virtual void GenerateDatabase(PythonTypeDatabaseCreationRequest request, Action <int> onExit = null)
        {
            WatchingLibrary = false;
            _generating     = true;

            PythonTypeDatabase.GenerateAsync(request).ContinueWith(t => {
                int exitCode;
                try {
                    exitCode = t.Result;
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                    exitCode = PythonTypeDatabase.InvalidOperationExitCode;
                }

                if (exitCode != PythonTypeDatabase.AlreadyGeneratingExitCode)
                {
                    _generating = false;
                }
                if (onExit != null)
                {
                    onExit(exitCode);
                }
            });
        }
        protected virtual void GenerateDatabase(PythonTypeDatabaseCreationRequest request, Action <int> onExit = null)
        {
            // Use the NoPackageManager instance if we don't have a package
            // manager, so that we still get a valid disposable object while we
            // are generating.
            var generating = _generating = (request.Factory.PackageManager ?? NoPackageManager.Instance).SuppressNotifications();

            PythonTypeDatabase.GenerateAsync(request).ContinueWith(t => {
                int exitCode;
                try {
                    exitCode = t.Result;
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                    exitCode = PythonTypeDatabase.InvalidOperationExitCode;
                }

                if (exitCode != PythonTypeDatabase.AlreadyGeneratingExitCode)
                {
                    generating.Dispose();
                    Interlocked.CompareExchange(ref _generating, null, generating);
                }
                onExit?.Invoke(exitCode);
            });
        }
예제 #7
0
        public static void Generate(PythonTypeDatabaseCreationRequest request) {
            var onExit = request.OnExit;

            GenerateAsync(request).ContinueWith(t => {
                var exc = t.Exception;
                if (exc == null) {
                    return;
                }

                try {
                    var message = string.Format(
                        "ERROR_STDLIB: {0}\\{1}{2}{3}",
                        request.Factory.Id,
                        request.Factory.Configuration.Version,
                        Environment.NewLine,
                        (exc.InnerException ?? exc).ToString()
                    );

                    Debug.WriteLine(message);

                    var glogPath = Path.Combine(CompletionDatabasePath, "AnalysisLog.txt");
                    File.AppendAllText(glogPath, message);
                } catch (IOException) {
                } catch (ArgumentException) {
                } catch (SecurityException) {
                } catch (UnauthorizedAccessException) {
                }

                if (onExit != null) {
                    onExit(PythonTypeDatabase.InvalidOperationExitCode);
                }
            }, TaskContinuationOptions.OnlyOnFaulted);
        }
예제 #8
0
        public static async Task<int> GenerateAsync(PythonTypeDatabaseCreationRequest request) {
            var fact = request.Factory;
            var evt = request.OnExit;
            if (fact == null || !Directory.Exists(fact.Configuration.LibraryPath)) {
                if (evt != null) {
                    evt(NotSupportedExitCode);
                }
                return NotSupportedExitCode;
            }
            var outPath = request.OutputPath;

            var analyzerPath = PythonToolsInstallPath.GetFile("Microsoft.PythonTools.Analyzer.exe");

            Directory.CreateDirectory(CompletionDatabasePath);

            var baseDb = BaselineDatabasePath;
            if (request.ExtraInputDatabases.Any()) {
                baseDb = baseDb + ";" + string.Join(";", request.ExtraInputDatabases);
            }

            var logPath = Path.Combine(outPath, "AnalysisLog.txt");
            var glogPath = Path.Combine(CompletionDatabasePath, "AnalysisLog.txt");

            using (var output = ProcessOutput.RunHiddenAndCapture(
                analyzerPath,
                "/id", fact.Id.ToString("B"),
                "/version", fact.Configuration.Version.ToString(),
                "/python", fact.Configuration.InterpreterPath,
                request.DetectLibraryPath ? null : "/library",
                request.DetectLibraryPath ? null : fact.Configuration.LibraryPath,
                "/outdir", outPath,
                "/basedb", baseDb,
                (request.SkipUnchanged ? null : "/all"),  // null will be filtered out; empty strings are quoted
                "/log", logPath,
                "/glog", glogPath,
                "/wait", (request.WaitFor != null ? AnalyzerStatusUpdater.GetIdentifier(request.WaitFor) : "")
            )) {
                output.PriorityClass = ProcessPriorityClass.BelowNormal;
                int exitCode = await output;

                if (exitCode > -10 && exitCode < 0) {
                    try {
                        File.AppendAllLines(
                            glogPath,
                            new[] { string.Format("FAIL_STDLIB: ({0}) {1}", exitCode, output.Arguments) }
                                .Concat(output.StandardErrorLines)
                        );
                    } catch (IOException) {
                    } catch (ArgumentException) {
                    } catch (SecurityException) {
                    } catch (UnauthorizedAccessException) {
                    }
                }

                if (evt != null) {
                    evt(exitCode);
                }
                return exitCode;
            }
        }
예제 #9
0
        public static async Task <int> GenerateAsync(PythonTypeDatabaseCreationRequest request)
        {
            var fact = request.Factory;
            var evt  = request.OnExit;

            if (fact == null || !Directory.Exists(fact.Configuration.LibraryPath))
            {
                if (evt != null)
                {
                    evt(NotSupportedExitCode);
                }
                return(NotSupportedExitCode);
            }
            var outPath = request.OutputPath;

            var analyzerPath = PythonToolsInstallPath.GetFile("Microsoft.PythonTools.Analyzer.exe");

            Directory.CreateDirectory(CompletionDatabasePath);

            var baseDb = BaselineDatabasePath;

            if (request.ExtraInputDatabases.Any())
            {
                baseDb = baseDb + ";" + string.Join(";", request.ExtraInputDatabases);
            }

            var logPath  = Path.Combine(outPath, "AnalysisLog.txt");
            var glogPath = Path.Combine(CompletionDatabasePath, "AnalysisLog.txt");

            using (var output = ProcessOutput.RunHiddenAndCapture(
                       analyzerPath,
                       "/id", fact.Configuration.Id,
                       "/version", fact.Configuration.Version.ToString(),
                       "/python", fact.Configuration.InterpreterPath,
                       request.DetectLibraryPath ? null : "/library",
                       request.DetectLibraryPath ? null : fact.Configuration.LibraryPath,
                       "/outdir", outPath,
                       "/basedb", baseDb,
                       (request.SkipUnchanged ? null : "/all"), // null will be filtered out; empty strings are quoted
                       "/log", logPath,
                       "/glog", glogPath,
                       "/wait", (request.WaitFor != null ? AnalyzerStatusUpdater.GetIdentifier(request.WaitFor) : "")
                       )) {
                output.PriorityClass = ProcessPriorityClass.BelowNormal;
                int exitCode = await output;

                if (exitCode > -10 && exitCode < 0)
                {
                    try {
                        File.AppendAllLines(
                            glogPath,
                            new[] { string.Format("FAIL_STDLIB: ({0}) {1}", exitCode, output.Arguments) }
                            .Concat(output.StandardErrorLines)
                            );
                    } catch (IOException) {
                    } catch (ArgumentException) {
                    } catch (SecurityException) {
                    } catch (UnauthorizedAccessException) {
                    }
                }

                if (evt != null)
                {
                    evt(exitCode);
                }
                return(exitCode);
            }
        }
        protected virtual void GenerateDatabase(PythonTypeDatabaseCreationRequest request, Action<int> onExit = null) {
            WatchingLibrary = false;
            _generating = true;

            PythonTypeDatabase.GenerateAsync(request).ContinueWith(t => {
                int exitCode;
                try {
                    exitCode = t.Result;
                } catch (Exception ex) {
                    Debug.Fail(ex.ToString());
                    exitCode = PythonTypeDatabase.InvalidOperationExitCode;
                }

                if (exitCode != PythonTypeDatabase.AlreadyGeneratingExitCode) {
                    _generating = false;
                }
                if (onExit != null) {
                    onExit(exitCode);
                }
            });
        }
        public virtual void GenerateDatabase(GenerateDatabaseOptions options, Action<int> onExit = null) {
            var req = new PythonTypeDatabaseCreationRequest {
                Factory = this,
                OutputPath = DatabasePath,
                SkipUnchanged = options.HasFlag(GenerateDatabaseOptions.SkipUnchanged),
                DetectLibraryPath = !AssumeSimpleLibraryLayout
            };

            GenerateDatabase(req, onExit);
        }
예제 #12
0
        public void CheckObsoleteGenerateFunction() {
            var path = PythonPaths.Versions.LastOrDefault(p => p != null && p.IsCPython);
            path.AssertInstalled();

            var factory = InterpreterFactoryCreator.CreateInterpreterFactory(new InterpreterFactoryCreationOptions {
                Id = path.Id,
                LanguageVersion = path.Version.ToVersion(),
                Description = "Test Interpreter",
                Architecture = path.Isx64 ? ProcessorArchitecture.Amd64 : ProcessorArchitecture.X86,
                LibraryPath = path.LibPath,
                PrefixPath = path.PrefixPath,
                InterpreterPath = path.InterpreterPath,
                WatchLibraryForNewModules = false
            });

            var tcs = new TaskCompletionSource<int>();
            var beforeProc = Process.GetProcessesByName("Microsoft.PythonTools.Analyzer");

            var request = new PythonTypeDatabaseCreationRequest {
                Factory = factory,
                OutputPath = TestData.GetTempPath(randomSubPath: true),
                SkipUnchanged = true,
                OnExit = tcs.SetResult
            };
            Console.WriteLine("OutputPath: {0}", request.OutputPath);

#pragma warning disable 618
            PythonTypeDatabase.Generate(request);
#pragma warning restore 618

            int expected = 0;

            if (!tcs.Task.Wait(TimeSpan.FromMinutes(1.0))) {
                var proc = Process.GetProcessesByName("Microsoft.PythonTools.Analyzer")
                    .Except(beforeProc)
                    .ToArray();
                
                // Ensure we actually started running
                Assert.AreNotEqual(0, proc.Length, "Process is not running");

                expected = -1;

                // Kill the process
                foreach (var p in proc) {
                    Console.WriteLine("Killing process {0}", p.Id);
                    p.Kill();
                }

                Assert.IsTrue(tcs.Task.Wait(TimeSpan.FromMinutes(1.0)), "Process did not die");
            }

            Assert.AreEqual(expected, tcs.Task.Result, "Incorrect exit code");
        }
예제 #13
0
        public override void GenerateDatabase(GenerateDatabaseOptions options, Action<int> onExit = null) {
            if (!Directory.Exists(Configuration.LibraryPath)) {
                return;
            }

            // Create and mark the DB directory as hidden
            try {
                var dbDir = Directory.CreateDirectory(DatabasePath);
                dbDir.Attributes |= FileAttributes.Hidden;
            } catch (ArgumentException) {
            } catch (IOException) {
            } catch (UnauthorizedAccessException) {
            }

            var req = new PythonTypeDatabaseCreationRequest {
                Factory = this,
                OutputPath = DatabasePath,
                SkipUnchanged = options.HasFlag(GenerateDatabaseOptions.SkipUnchanged),
                DetectLibraryPath = !AssumeSimpleLibraryLayout
            };

            req.ExtraInputDatabases.Add(_base.DatabasePath);

            _baseHasRefreshed = false;

            if (_base.IsCurrent) {
                base.GenerateDatabase(req, onExit);
            } else {
                req.WaitFor = _base;
                req.SkipUnchanged = false;

                // Clear out the existing base database, since we're going to
                // need to reload it again. This also means that when
                // NewDatabaseAvailable is raised, we are expecting it and won't
                // incorrectly set _baseHasRefreshed to true again.
                _baseDb = null;

                // Start our analyzer first, since we will wait up to a minute
                // for our base analyzer to start (which may cause a one minute
                // delay if it completes before we start, but that is unlikely).
                base.GenerateDatabase(req, onExit);
                _base.GenerateDatabase(GenerateDatabaseOptions.SkipUnchanged);
            }
        }
예제 #14
0
        /// <summary>
        /// Regenerates the database for this environment. If the base
        /// interpreter needs regenerating, it will also be regenerated.
        /// </summary>
        public override void GenerateDatabase(GenerateDatabaseOptions options, Action<int> onExit = null) {
            if (!Directory.Exists(Configuration.LibraryPath)) {
                return;
            }

            var req = new PythonTypeDatabaseCreationRequest {
                Factory = this,
                OutputPath = DatabasePath,
                SkipUnchanged = options.HasFlag(GenerateDatabaseOptions.SkipUnchanged)
            };

            req.ExtraInputDatabases.Add(_base.DatabasePath);

            _baseHasRefreshed = false;

            if (_base.IsCurrent) {
                // The App database is already up to date, so start analyzing
                // the User database immediately.
                base.GenerateDatabase(req, onExit);
            } else {
                // The App database needs to be updated, so start both and wait
                // for the base to finish before analyzing User.

                // Specifying our base interpreter as 'WaitFor' allows the UI to
                // forward progress and status messages to the user, even though
                // the factory is not visible.
                req.WaitFor = _base;

                // Because the underlying analysis of the standard library has
                // changed, we must reanalyze the entire database.
                req.SkipUnchanged = false;

                // Clear out the existing base database, since we're going to
                // need to reload it again. This also means that when
                // NewDatabaseAvailable is raised, we are expecting it and won't
                // incorrectly set _baseHasRefreshed to true again.
                _baseDb = null;

                // Start our analyzer first, since we will wait up to a minute
                // for the base analyzer to start (which may cause a one minute
                // delay if it completes before we start, but that is unlikely).
                base.GenerateDatabase(req, onExit);
                _base.GenerateDatabase(GenerateDatabaseOptions.SkipUnchanged);
            }
        }