private bool CanUpdateAnalysis(
            PythonAnalyzerEntry entry,
            IDependencyChainNode <PythonAnalyzerEntry> node,
            int version,
            out IPythonModule module,
            out PythonAst ast,
            out IDocumentAnalysis currentAnalysis)
        {
            if (!entry.CanUpdateAnalysis(version, out module, out ast, out currentAnalysis))
            {
                if (IsAnalyzedLibraryInLoop(node, currentAnalysis))
                {
                    // Library analysis exists, don't analyze again
                    return(false);
                }
                if (ast == null)
                {
                    if (currentAnalysis == null)
                    {
                        // Entry doesn't have ast yet. There should be at least one more session.
                        Cancel();
                        _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled (no AST yet).");
                        return(false);
                    }
                    //Debug.Fail($"Library module {module.Name} of type {module.ModuleType} has been analyzed already!");
                    return(false);
                }

                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled. Version: {version}, current: {module.Analysis.Version}.");
                return(false);
            }
            return(true);
        }
Ejemplo n.º 2
0
        public PythonAnalyzerSession(IServiceManager services,
                                     IProgressReporter progress,
                                     AsyncManualResetEvent analysisCompleteEvent,
                                     Action <Task> startNextSession,
                                     CancellationToken analyzerCancellationToken,
                                     IDependencyChainWalker <AnalysisModuleKey, PythonAnalyzerEntry> walker,
                                     int version,
                                     PythonAnalyzerEntry entry)
        {
            _services = services;
            _analysisCompleteEvent     = analysisCompleteEvent;
            _startNextSession          = startNextSession;
            _analyzerCancellationToken = analyzerCancellationToken;
            Version = version;
            AffectedEntriesCount = walker?.AffectedValues.Count ?? 1;
            _walker = walker;
            _entry  = entry;
            _state  = State.NotStarted;

            _diagnosticsService = _services.GetService <IDiagnosticsService>();
            _analyzer           = _services.GetService <IPythonAnalyzer>();
            _log       = _services.GetService <ILogger>();
            _telemetry = _services.GetService <ITelemetryService>();
            _progress  = progress;
        }
        public PythonAnalyzerSession(IServiceContainer services,
                                     IProgressReporter progress,
                                     Action <Task> startNextSession,
                                     CancellationToken analyzerCancellationToken,
                                     IDependencyChainWalker <AnalysisModuleKey, PythonAnalyzerEntry> walker,
                                     int version,
                                     PythonAnalyzerEntry entry,
                                     bool forceGC = false)
        {
            _services         = services;
            _startNextSession = startNextSession;

            _analyzerCancellationToken = analyzerCancellationToken;
            Version = version;
            AffectedEntriesCount = walker?.AffectedValues.Count ?? 1;
            _walker  = walker;
            _entry   = entry;
            _state   = State.NotStarted;
            _forceGC = forceGC;

            _diagnosticsService = _services.GetService <IDiagnosticsService>();
            _platformService    = _services.GetService <IOSPlatform>();
            _analyzer           = _services.GetService <IPythonAnalyzer>();
            _log = _services.GetService <ILogger>();
            _moduleDatabaseService = _services.GetService <IModuleDatabaseService>();
            _progress = progress;

            var interpreter = _services.GetService <IPythonInterpreter>();

            _modulesPathResolver  = interpreter.ModuleResolution.CurrentPathResolver;
            _typeshedPathResolver = interpreter.TypeshedResolution.CurrentPathResolver;
        }
        private void Analyze(PythonAnalyzerEntry entry, int version, CancellationToken cancellationToken)
        {
            var stopWatch = Stopwatch.StartNew();

            try {
                if (!entry.IsValidVersion(version, out var module, out var ast))
                {
                    _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled.");
                    return;
                }

                var startTime = stopWatch.Elapsed;
                AnalyzeEntry(entry, module, ast, version, cancellationToken);

                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) completed in {(stopWatch.Elapsed - startTime).TotalMilliseconds} ms.");
            } catch (OperationCanceledException oce) {
                entry.TryCancel(oce, version);
                var module = entry.Module;
                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) canceled.");
            } catch (Exception exception) {
                var module = entry.Module;
                entry.TrySetException(exception, version);
                _log?.Log(TraceEventType.Verbose, $"Analysis of {module.Name}({module.ModuleType}) failed.");
            } finally {
                stopWatch.Stop();
                Interlocked.Decrement(ref _runningTasks);
            }
        }
        private void AnalyzeEntry(PythonAnalyzerEntry entry, IPythonModule module, PythonAst ast, int version)
        {
            // Now run the analysis.
            var analyzable = module as IAnalyzable;

            analyzable?.NotifyAnalysisBegins();

            var walker = new ModuleWalker(_services, module, ast);

            ast.Walk(walker);

            _analyzerCancellationToken.ThrowIfCancellationRequested();

            walker.Complete();
            _analyzerCancellationToken.ThrowIfCancellationRequested();
            var analysis = new DocumentAnalysis((IDocument)module, version, walker.GlobalScope, walker.Eval, walker.StarImportMemberNames);

            analyzable?.NotifyAnalysisComplete(analysis);
            entry.TrySetAnalysis(analysis, version);

            if (module.ModuleType == ModuleType.User)
            {
                var linterDiagnostics = _analyzer.LintModule(module);
                _diagnosticsService?.Replace(entry.Module.Uri, linterDiagnostics, DiagnosticSource.Linter);
            }
        }
        private void AnalyzeEntry(PythonAnalyzerEntry entry, IPythonModule module, int version, bool isFinalPass)
        {
            if (entry.PreviousAnalysis is LibraryAnalysis)
            {
                _log?.Log(TraceEventType.Verbose, $"Request to re-analyze finalized {module.Name}.");
            }

            // Now run the analysis.
            var analyzable = module as IAnalyzable;

            analyzable?.NotifyAnalysisBegins();

            var ast    = module.GetAst();
            var walker = new ModuleWalker(_services, module);

            ast.Walk(walker);

            _analyzerCancellationToken.ThrowIfCancellationRequested();

            walker.Complete();
            _analyzerCancellationToken.ThrowIfCancellationRequested();

            analyzable?.NotifyAnalysisComplete(version, walker, isFinalPass);
            entry.TrySetAnalysis(module.Analysis, version);

            if (module.ModuleType == ModuleType.User)
            {
                var linterDiagnostics = _analyzer.LintModule(module);
                _diagnosticsService?.Replace(entry.Module.Uri, linterDiagnostics, DiagnosticSource.Linter);
            }
        }
        public async Task <IDocumentAnalysis> GetAnalysisAsync(IPythonModule module, int waitTime, CancellationToken cancellationToken)
        {
            var key = new AnalysisModuleKey(module);
            PythonAnalyzerEntry entry;

            lock (_syncObj) {
                if (!_analysisEntries.TryGetValue(key, out entry))
                {
                    var emptyAnalysis = new EmptyAnalysis(_services, (IDocument)module);
                    entry = new PythonAnalyzerEntry(emptyAnalysis);
                    _analysisEntries[key] = entry;
                }
            }

            if (waitTime < 0 || Debugger.IsAttached)
            {
                return(await GetAnalysisAsync(entry, default, cancellationToken));
            public DependencyWalker(PythonAnalyzerEntry entry, IPythonModule module)
            {
                _entry            = entry;
                _module           = module;
                _isTypeshed       = module is StubPythonModule stub && stub.IsTypeshed;
                _moduleResolution = module.Interpreter.ModuleResolution;
                _pathResolver     = _isTypeshed
                    ? module.Interpreter.TypeshedResolution.CurrentPathResolver
                    : _moduleResolution.CurrentPathResolver;

                Dependencies = new HashSet <AnalysisModuleKey>();

                if (module.Stub != null)
                {
                    Dependencies.Add(new AnalysisModuleKey(module.Stub));
                }
            }
Ejemplo n.º 9
0
        private void AnalyzeEntry(IDependencyChainNode <PythonAnalyzerEntry> node, PythonAnalyzerEntry entry, IPythonModule module, PythonAst ast, int version)
        {
            // Now run the analysis.
            var analyzable = module as IAnalyzable;

            analyzable?.NotifyAnalysisBegins();

            var walker = new ModuleWalker(_services, module, ast);

            ast.Walk(walker);

            _analyzerCancellationToken.ThrowIfCancellationRequested();

            walker.Complete();
            _analyzerCancellationToken.ThrowIfCancellationRequested();

            bool isCanceled;

            lock (_syncObj) {
                isCanceled = _isCanceled;
            }

            if (!isCanceled)
            {
                node?.MarkWalked();
            }

            var analysis = CreateAnalysis(node, (IDocument)module, ast, version, walker, isCanceled);

            analyzable?.NotifyAnalysisComplete(analysis);
            entry.TrySetAnalysis(module.Analysis, version);

            if (module.ModuleType == ModuleType.User)
            {
                var linterDiagnostics = _analyzer.LintModule(module);
                _diagnosticsService?.Replace(entry.Module.Uri, linterDiagnostics, DiagnosticSource.Linter);
            }
        }
        private void AnalyzeEntry(IDependencyChainNode <PythonAnalyzerEntry> node, PythonAnalyzerEntry entry, IPythonModule module, PythonAst ast, int version)
        {
            // Now run the analysis.
            var analyzable = module as IAnalyzable;

            analyzable?.NotifyAnalysisBegins();

            Debug.Assert(ast != null);
            var analysis = DoAnalyzeEntry(node, module, ast, version);

            _analyzerCancellationToken.ThrowIfCancellationRequested();

            if (analysis != null)
            {
                analyzable?.NotifyAnalysisComplete(analysis);
                entry.TrySetAnalysis(analysis, version);

                if (module.ModuleType == ModuleType.User)
                {
                    var linterDiagnostics = _analyzer.LintModule(module);
                    _diagnosticsService?.Replace(entry.Module.Uri, linterDiagnostics, DiagnosticSource.Linter);
                }
            }
        }