Esempio n. 1
0
        public async Task HoverGenericClass()
        {
            const string code     = @"
from typing import TypeVar, Generic

_T = TypeVar('_T')

class Box(Generic[_T]):
    def __init__(self, v: _T):
        self.v = v

    def get(self) -> _T:
        return self.v

boxedint = Box(1234)
x = boxedint.get()

boxedstr = Box('str')
y = boxedstr.get()
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(14, 15), "Box.get() -> int", new SourceSpan(14, 13, 14, 17));
            AssertHover(hs, analysis, new SourceLocation(17, 15), "Box.get() -> str", new SourceSpan(17, 13, 17, 17));
        }
Esempio n. 2
0
 public void OnPointerEnter(PointerEventData eventData)
 {
     if (enableHoverSound == true)
     {
         HoverSource.PlayOneShot(hoverSound);
     }
 }
        public async Task AssignmentExpressions()
        {
            const string code     = @"
(a := 1)
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.Required_Python38X);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(2, 2), @"a: int", new SourceSpan(2, 2, 2, 3));
        }
Esempio n. 4
0
        public async Task ImportAsNameHover()
        {
            const string code     = @"
import datetime as d123
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(2, 11), "module datetime*", new SourceSpan(2, 8, 2, 16));
            AssertHover(hs, analysis, new SourceLocation(2, 21), "module datetime*", new SourceSpan(2, 20, 2, 24));
        }
Esempio n. 5
0
        public async Task FromImportParts()
        {
            const string code     = @"
from time import time
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(2, 7), @"module time*", new SourceSpan(2, 6, 2, 10));
            AssertHover(hs, analysis, new SourceLocation(2, 22), @"time() -> float*", new SourceSpan(2, 18, 2, 22));
        }
Esempio n. 6
0
        public async Task FromImportHover()
        {
            const string code     = @"
from os import path as p
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(2, 6), "module os*", new SourceSpan(2, 6, 2, 8));
            AssertHover(hs, analysis, new SourceLocation(2, 16), "module*", new SourceSpan(2, 16, 2, 20));
            AssertHover(hs, analysis, new SourceLocation(2, 24), "module*", new SourceSpan(2, 24, 2, 25));
        }
        public async Task ImmediateClassScopeVar()
        {
            const string code     = @"
class A:
  x = 1
  y = x
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(4, 7), @"x: int", new SourceSpan(4, 7, 4, 8));
        }
        public async Task CompiledCode()
        {
            const string code     = @"
import os
os.mkdir()
";
            var          analysis = await GetAnalysisAsync(code);

            var hs    = new HoverSource(new PlainTextDocumentationSource());
            var hover = hs.GetHover(analysis, new SourceLocation(3, 6));

            hover.contents.value.Should().Contain("Create a directory");
        }
Esempio n. 9
0
        public async Task HoverSpanCheck(bool is3x)
        {
            const string code     = @"
import datetime
datetime.datetime.now().day
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(3, 2), "module datetime*", new SourceSpan(3, 1, 3, 9));
            AssertHover(hs, analysis, new SourceLocation(3, 11), "class datetime*", new SourceSpan(3, 9, 3, 18));
            AssertHover(hs, analysis, new SourceLocation(3, 20), @"datetime.now(tz: tzinfo) -> datetime*", new SourceSpan(3, 18, 3, 22));
        }
Esempio n. 10
0
        public async Task OsPath()
        {
            const string code     = @"
import os.path as PATH
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(2, 9), @"module os*", new SourceSpan(2, 8, 2, 10));
            var name = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"ntpath" : @"posixpath";

            AssertHover(hs, analysis, new SourceLocation(2, 12), $"module {name}*", new SourceSpan(2, 11, 2, 15));
            AssertHover(hs, analysis, new SourceLocation(2, 20), $"module {name}*", new SourceSpan(2, 19, 2, 23));
        }
Esempio n. 11
0
        public async Task BasicTypes()
        {
            const string code     = @"
x = 'str'

class C:
    '''Class C is awesome'''
    def method(self, a:int, b) -> float:
        '''Returns a float!!!'''
        return 1.0

def func(a, b):
    '''Does nothing useful'''
    return 1

y = func(1, 2)
string = str
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            var hover = hs.GetHover(analysis, new SourceLocation(2, 2));

            hover.contents.value.Should().Be("x: str");

            hover = hs.GetHover(analysis, new SourceLocation(2, 7));
            hover.Should().BeNull();

            hover = hs.GetHover(analysis, new SourceLocation(4, 7));
            hover.contents.value.Should().Be("class C\n\nClass C is awesome");

            hover = hs.GetHover(analysis, new SourceLocation(6, 9));
            hover.contents.value.Should().Be("C.method(a: int, b) -> float\n\nReturns a float!!!");

            hover = hs.GetHover(analysis, new SourceLocation(6, 22));
            hover.contents.value.Should().Be("a: int");

            hover = hs.GetHover(analysis, new SourceLocation(10, 7));
            hover.contents.value.Should().Be("func(a, b)\n\nDoes nothing useful");

            hover = hs.GetHover(analysis, new SourceLocation(14, 2));
            hover.contents.value.Should().Be("y: int");

            hover = hs.GetHover(analysis, new SourceLocation(15, 2));
            hover.contents.value.Should().StartWith("class str\n\nstr(object='') -> str");
        }
Esempio n. 12
0
        public async Task FromOsPath()
        {
            const string code     = @"
from os.path import join as JOIN
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(2, 7), @"module os*", new SourceSpan(2, 6, 2, 8));

            var name = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"ntpath" : @"posixpath";

            AssertHover(hs, analysis, new SourceLocation(2, 10), $"module {name}*", new SourceSpan(2, 9, 2, 13));

            AssertHover(hs, analysis, new SourceLocation(2, 22), @"join(path: str, paths: str) -> str", new SourceSpan(2, 21, 2, 25));
            AssertHover(hs, analysis, new SourceLocation(2, 30), @"join(path: str, paths: str) -> str", new SourceSpan(2, 29, 2, 33));
        }
        public async Task MissingSelf()
        {
            const string code     = @"
class A:
    def __init__(self):
        self.instance_var = 1

    def do(self):
        y = instance_var
        y = do()
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertNoHover(hs, analysis, new SourceLocation(7, 15));
            AssertNoHover(hs, analysis, new SourceLocation(8, 14));
        }
Esempio n. 14
0
        public async Task FStringExpressions()
        {
            const string code     = @"
some = ''
f'{some'
Fr'{some'
f'{some}'
f'hey {some}'
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(3, 4), @"some: str", new SourceSpan(3, 4, 3, 8));
            AssertHover(hs, analysis, new SourceLocation(4, 5), @"some: str", new SourceSpan(4, 5, 4, 9));
            AssertHover(hs, analysis, new SourceLocation(5, 4), @"some: str", new SourceSpan(5, 4, 5, 8));
            hs.GetHover(analysis, new SourceLocation(6, 3)).Should().BeNull();
            AssertHover(hs, analysis, new SourceLocation(6, 8), @"some: str", new SourceSpan(6, 8, 6, 12));
        }
Esempio n. 15
0
        public async Task SelfHover()
        {
            const string code     = @"
class Base(object):
    def fob_base(self):
       pass

class Derived(Base):
    def fob_derived(self):
       self.fob_base()
       pass
";
            var          analysis = await GetAnalysisAsync(code, PythonVersions.LatestAvailable3X);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(3, 19), "class Base*", new SourceSpan(3, 18, 3, 22));
            AssertHover(hs, analysis, new SourceLocation(8, 8), "class Derived*", new SourceSpan(8, 8, 8, 12));
        }
Esempio n. 16
0
        private static void AssertHover(HoverSource hs, IDocumentAnalysis analysis, SourceLocation position, string hoverText, SourceSpan?span = null)
        {
            var hover = hs.GetHover(analysis, position);

            if (hoverText.EndsWith("*"))
            {
                // Check prefix first, but then show usual message for mismatched value
                if (!hover.contents.value.StartsWith(hoverText.Remove(hoverText.Length - 1)))
                {
                    Assert.AreEqual(hoverText, hover.contents.value);
                }
            }
            else
            {
                Assert.AreEqual(hoverText, hover.contents.value);
            }
            if (span.HasValue)
            {
                hover.range.Should().Be((Range)span.Value);
            }
        }
        public async Task MemberWithSelf()
        {
            const string code     = @"
class A:
    def __init__(self):
        self.instance_var = 1

    def do(self):
        y = self.instance_var
        z1 = func()
        z2 = self.func()

    def func(self): ...
";
            var          analysis = await GetAnalysisAsync(code);

            var hs = new HoverSource(new PlainTextDocumentationSource());

            AssertHover(hs, analysis, new SourceLocation(7, 19), @"instance_var: int", new SourceSpan(7, 17, 7, 30));
            AssertNoHover(hs, analysis, new SourceLocation(8, 15));
            AssertHover(hs, analysis, new SourceLocation(9, 20), @"A.func()", new SourceSpan(9, 18, 9, 23));
        }
Esempio n. 18
0
        public async Task InitializedAsync(InitializedParams @params, CancellationToken cancellationToken = default, IReadOnlyList <string> userConfiguredPaths = null)
        {
            var initializationOptions = _initParams?.initializationOptions;

            _services.AddService(new DiagnosticsService(_services));

            _analyzer = new PythonAnalyzer(_services);
            _services.AddService(_analyzer);

            _analyzer.AnalysisComplete += OnAnalysisComplete;
            _disposableBag.Add(() => _analyzer.AnalysisComplete -= OnAnalysisComplete);

            _services.AddService(new RunningDocumentTable(_services));
            _rdt = _services.GetService <IRunningDocumentTable>();

            var     interpeterPath = initializationOptions?.interpreter.properties?.InterpreterPath;
            Version version        = null;

            if (!string.IsNullOrWhiteSpace(interpeterPath))
            {
                Version.TryParse(initializationOptions?.interpreter.properties?.Version, out version);
            }
            else
            {
                var fs      = _services.GetService <IFileSystem>();
                var exePath = PathUtils.LookPath(fs, "python");
                if (exePath != null && TryGetPythonVersion(exePath, out version))
                {
                    _log?.Log(TraceEventType.Information, Resources.UsingPythonFromPATH);
                    interpeterPath = exePath;
                }
                else
                {
                    interpeterPath = null;
                }
            }

            var configuration = new InterpreterConfiguration(
                interpreterPath: interpeterPath,
                version: version
                );
            //_services.AddService(new ModuleDatabase(_services));

            var typeshedPath = initializationOptions?.typeStubSearchPaths.FirstOrDefault();

            userConfiguredPaths = userConfiguredPaths ?? initializationOptions?.searchPaths;
            _interpreter        = await PythonInterpreter.CreateAsync(configuration, Root, _services, typeshedPath, userConfiguredPaths.ToImmutableArray(), cancellationToken);

            _log?.Log(TraceEventType.Information,
                      string.IsNullOrEmpty(_interpreter.Configuration.InterpreterPath)
                ? Resources.InitializingForGenericInterpreter
                : Resources.InitializingForPythonInterpreter.FormatInvariant(_interpreter.Configuration.InterpreterPath));

            var fileSystem = _services.GetService <IFileSystem>();

            _indexManager = new IndexManager(fileSystem, _interpreter.LanguageVersion, Root,
                                             initializationOptions?.includeFiles,
                                             initializationOptions?.excludeFiles,
                                             _services.GetService <IIdleTimeService>());

            _indexManager.IndexWorkspace().DoNotWait();
            _analyzer.AnalysisComplete += IndexLibraries;
            _disposableBag.Add(() => _analyzer.AnalysisComplete -= IndexLibraries);
            _services.AddService(_indexManager);
            _disposableBag.Add(_indexManager);

            var textDocCaps = _initParams?.capabilities?.textDocument;

            _completionSource = new CompletionSource(
                ChooseDocumentationSource(textDocCaps?.completion?.completionItem?.documentationFormat),
                Settings.completion, Services
                );

            _hoverSource = new HoverSource(
                ChooseDocumentationSource(textDocCaps?.hover?.contentFormat)
                );

            var sigInfo = textDocCaps?.signatureHelp?.signatureInformation;

            _signatureSource = new SignatureSource(
                ChooseDocumentationSource(sigInfo?.documentationFormat),
                sigInfo?.parameterInformation?.labelOffsetSupport == true
                );

            _initialized = true;
        }
Esempio n. 19
0
        public async Task <InitializeResult> InitializeAsync(InitializeParams @params, CancellationToken cancellationToken)
        {
            _disposableBag.ThrowIfDisposed();
            _clientCaps = @params.capabilities;
            _log        = _services.GetService <ILogger>();

            _services.AddService(new DiagnosticsService(_services));

            var analyzer = new PythonAnalyzer(_services);

            _services.AddService(analyzer);

            _services.AddService(new RunningDocumentTable(_services));
            _rdt = _services.GetService <IRunningDocumentTable>();

            // TODO: multi-root workspaces.
            var rootDir = @params.rootUri != null? @params.rootUri.ToAbsolutePath() : PathUtils.NormalizePath(@params.rootPath);

            Version.TryParse(@params.initializationOptions.interpreter.properties?.Version, out var version);

            var configuration = new InterpreterConfiguration(null, null,
                                                             interpreterPath: @params.initializationOptions.interpreter.properties?.InterpreterPath,
                                                             moduleCachePath: @params.initializationOptions.interpreter.properties?.DatabasePath,
                                                             version: version
                                                             )
            {
                // TODO: Remove this split once the extension is updated and no longer passes the interpreter search paths directly.
                // This is generally harmless to keep around.
                SearchPaths  = @params.initializationOptions.searchPaths.Select(p => p.Split(';', StringSplitOptions.RemoveEmptyEntries)).SelectMany().ToList(),
                TypeshedPath = @params.initializationOptions.typeStubSearchPaths.FirstOrDefault()
            };

            _interpreter = await PythonInterpreter.CreateAsync(configuration, rootDir, _services, cancellationToken);

            _services.AddService(_interpreter);

            var fileSystem = _services.GetService <IFileSystem>();

            _indexManager = new IndexManager(fileSystem, _interpreter.LanguageVersion, rootDir,
                                             @params.initializationOptions.includeFiles,
                                             @params.initializationOptions.excludeFiles,
                                             _services.GetService <IIdleTimeService>());
            _indexManager.IndexWorkspace().DoNotWait();
            _services.AddService(_indexManager);
            _disposableBag.Add(_indexManager);

            DisplayStartupInfo();

            _completionSource = new CompletionSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.completion?.completionItem?.documentationFormat),
                Settings.completion
                );

            _hoverSource = new HoverSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.hover?.contentFormat)
                );

            _signatureSource = new SignatureSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.signatureHelp?.signatureInformation?.documentationFormat)
                );

            return(GetInitializeResult());
        }
Esempio n. 20
0
        public async Task <InitializeResult> InitializeAsync(InitializeParams @params, CancellationToken cancellationToken)
        {
            _disposableBag.ThrowIfDisposed();
            _clientCaps = @params.capabilities;
            _log        = _services.GetService <ILogger>();

            _services.AddService(new DiagnosticsService(_services));

            var cacheFolderPath = @params.initializationOptions.cacheFolderPath;
            var fs = _services.GetService <IFileSystem>();

            if (cacheFolderPath != null && !fs.DirectoryExists(cacheFolderPath))
            {
                _log?.Log(TraceEventType.Warning, Resources.Error_InvalidCachePath);
                cacheFolderPath = null;
            }

            var analyzer = new PythonAnalyzer(_services, cacheFolderPath);

            _services.AddService(analyzer);

            analyzer.AnalysisComplete += OnAnalysisComplete;
            _disposableBag.Add(() => analyzer.AnalysisComplete -= OnAnalysisComplete);

            _services.AddService(new RunningDocumentTable(_services));
            _rdt = _services.GetService <IRunningDocumentTable>();

            _rootDir = @params.rootUri != null? @params.rootUri.ToAbsolutePath() : @params.rootPath;

            if (_rootDir != null)
            {
                _rootDir = PathUtils.NormalizePathAndTrim(_rootDir);
            }

            Version.TryParse(@params.initializationOptions.interpreter.properties?.Version, out var version);

            var configuration = new InterpreterConfiguration(null, null,
                                                             interpreterPath: @params.initializationOptions.interpreter.properties?.InterpreterPath,
                                                             version: version
                                                             )
            {
                // Split on ';' to support older VS Code extension versions which send paths as a single entry separated by ';'. TODO: Eventually remove.
                // Note that the actual classification of these paths as user/library is done later in MainModuleResolution.ReloadAsync.
                SearchPaths = @params.initializationOptions.searchPaths
                              .Select(p => p.Split(';', StringSplitOptions.RemoveEmptyEntries)).SelectMany()
                              .ToList(),
                TypeshedPath = @params.initializationOptions.typeStubSearchPaths.FirstOrDefault()
            };

            _interpreter = await PythonInterpreter.CreateAsync(configuration, _rootDir, _services, cancellationToken);

            _services.AddService(_interpreter);

            var fileSystem = _services.GetService <IFileSystem>();

            _indexManager = new IndexManager(fileSystem, _interpreter.LanguageVersion, _rootDir,
                                             @params.initializationOptions.includeFiles,
                                             @params.initializationOptions.excludeFiles,
                                             _services.GetService <IIdleTimeService>());
            _indexManager.IndexWorkspace().DoNotWait();
            _services.AddService(_indexManager);
            _disposableBag.Add(_indexManager);

            DisplayStartupInfo();

            _completionSource = new CompletionSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.completion?.completionItem?.documentationFormat),
                Settings.completion
                );

            _hoverSource = new HoverSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.hover?.contentFormat)
                );

            var sigInfo = _clientCaps?.textDocument?.signatureHelp?.signatureInformation;

            _signatureSource = new SignatureSource(
                ChooseDocumentationSource(sigInfo?.documentationFormat),
                sigInfo?.parameterInformation?.labelOffsetSupport == true
                );

            return(GetInitializeResult());
        }
Esempio n. 21
0
        public async Task <InitializeResult> InitializeAsync(InitializeParams @params, CancellationToken cancellationToken)
        {
            _disposableBag.ThrowIfDisposed();
            _clientCaps = @params.capabilities;
            _log        = _services.GetService <ILogger>();

            _services.AddService(new DiagnosticsService(_services));

            var analyzer = new PythonAnalyzer(_services);

            _services.AddService(analyzer);

            _services.AddService(new RunningDocumentTable(_services));
            _rdt = _services.GetService <IRunningDocumentTable>();

            _rootDir = @params.rootUri != null? @params.rootUri.ToAbsolutePath() : @params.rootPath;

            if (_rootDir != null)
            {
                _rootDir = PathUtils.NormalizePath(_rootDir);
                _rootDir = PathUtils.TrimEndSeparator(_rootDir);
            }

            Version.TryParse(@params.initializationOptions.interpreter.properties?.Version, out var version);

            var configuration = new InterpreterConfiguration(null, null,
                                                             interpreterPath: @params.initializationOptions.interpreter.properties?.InterpreterPath,
                                                             moduleCachePath: @params.initializationOptions.interpreter.properties?.DatabasePath,
                                                             version: version
                                                             )
            {
                // 1) Split on ';' to support older VS Code extension versions which send paths as a single entry separated by ';'. TODO: Eventually remove.
                // 2) Normalize paths.
                // 3) If a path isn't rooted, then root it relative to the workspace root. If _rootDir is null, then accept the path as-is.
                // 4) Trim off any ending separator for a consistent style.
                // 5) Filter out any entries which are the same as the workspace root; they are redundant. Also ignore "/" to work around the extension (for now).
                // 6) Remove duplicates.
                SearchPaths = @params.initializationOptions.searchPaths
                              .Select(p => p.Split(';', StringSplitOptions.RemoveEmptyEntries)).SelectMany()
                              .Select(PathUtils.NormalizePath)
                              .Select(p => _rootDir == null || Path.IsPathRooted(p) ? p : Path.GetFullPath(p, _rootDir))
                              .Select(PathUtils.TrimEndSeparator)
                              .Where(p => !string.IsNullOrWhiteSpace(p) && p != "/" && !p.PathEquals(_rootDir))
                              .Distinct(PathEqualityComparer.Instance)
                              .ToList(),
                TypeshedPath = @params.initializationOptions.typeStubSearchPaths.FirstOrDefault()
            };

            _interpreter = await PythonInterpreter.CreateAsync(configuration, _rootDir, _services, cancellationToken);

            _services.AddService(_interpreter);

            var fileSystem = _services.GetService <IFileSystem>();

            _indexManager = new IndexManager(fileSystem, _interpreter.LanguageVersion, _rootDir,
                                             @params.initializationOptions.includeFiles,
                                             @params.initializationOptions.excludeFiles,
                                             _services.GetService <IIdleTimeService>());
            _indexManager.IndexWorkspace().DoNotWait();
            _services.AddService(_indexManager);
            _disposableBag.Add(_indexManager);

            DisplayStartupInfo();

            _completionSource = new CompletionSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.completion?.completionItem?.documentationFormat),
                Settings.completion
                );

            _hoverSource = new HoverSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.hover?.contentFormat)
                );

            _signatureSource = new SignatureSource(
                ChooseDocumentationSource(_clientCaps?.textDocument?.signatureHelp?.signatureInformation?.documentationFormat)
                );

            return(GetInitializeResult());
        }
        private static void AssertNoHover(HoverSource hs, IDocumentAnalysis analysis, SourceLocation position)
        {
            var hover = hs.GetHover(analysis, position);

            hover.Should().BeNull();
        }
Esempio n. 23
0
        public async Task InitializedAsync(InitializedParams @params, CancellationToken cancellationToken = default, IReadOnlyList <string> userConfiguredPaths = null)
        {
            var initializationOptions = _initParams?.initializationOptions;

            _services.AddService(new DiagnosticsService(_services));

            var cacheFolderPath = initializationOptions?.cacheFolderPath;
            var fs = _services.GetService <IFileSystem>();

            if (cacheFolderPath != null && !fs.DirectoryExists(cacheFolderPath))
            {
                _log?.Log(TraceEventType.Warning, Resources.Error_InvalidCachePath);
                cacheFolderPath = null;
            }

            var analyzer = new PythonAnalyzer(_services, cacheFolderPath);

            _services.AddService(analyzer);

            analyzer.AnalysisComplete += OnAnalysisComplete;
            _disposableBag.Add(() => analyzer.AnalysisComplete -= OnAnalysisComplete);

            _services.AddService(new RunningDocumentTable(_services));
            _rdt = _services.GetService <IRunningDocumentTable>();

            Version.TryParse(initializationOptions?.interpreter.properties?.Version, out var version);

            var configuration = new InterpreterConfiguration(null, null,
                                                             interpreterPath: initializationOptions?.interpreter.properties?.InterpreterPath,
                                                             version: version
                                                             );

            var typeshedPath = initializationOptions?.typeStubSearchPaths.FirstOrDefault();

            userConfiguredPaths = userConfiguredPaths ?? initializationOptions?.searchPaths;
            _interpreter        = await PythonInterpreter.CreateAsync(configuration, Root, _services, typeshedPath, userConfiguredPaths.ToImmutableArray(), cancellationToken);

            _services.AddService(_interpreter);

            _log?.Log(TraceEventType.Information,
                      string.IsNullOrEmpty(_interpreter.Configuration.InterpreterPath)
                ? Resources.InitializingForGenericInterpreter
                : Resources.InitializingForPythonInterpreter.FormatInvariant(_interpreter.Configuration.InterpreterPath));

            var fileSystem = _services.GetService <IFileSystem>();

            _indexManager = new IndexManager(fileSystem, _interpreter.LanguageVersion, Root,
                                             initializationOptions?.includeFiles,
                                             initializationOptions?.excludeFiles,
                                             _services.GetService <IIdleTimeService>());
            _indexManager.IndexWorkspace().DoNotWait();
            _services.AddService(_indexManager);
            _disposableBag.Add(_indexManager);

            var textDocCaps = _initParams?.capabilities?.textDocument;

            _completionSource = new CompletionSource(
                ChooseDocumentationSource(textDocCaps?.completion?.completionItem?.documentationFormat),
                Settings.completion
                );

            _hoverSource = new HoverSource(
                ChooseDocumentationSource(textDocCaps?.hover?.contentFormat)
                );

            var sigInfo = textDocCaps?.signatureHelp?.signatureInformation;

            _signatureSource = new SignatureSource(
                ChooseDocumentationSource(sigInfo?.documentationFormat),
                sigInfo?.parameterInformation?.labelOffsetSupport == true
                );
        }