public RazorLSPSpanMappingService(
            LSPDocumentMappingProvider lspDocumentMappingProvider,
            LSPDocumentSnapshot documentSnapshot,
            ITextSnapshot textSnapshot)
        {
            if (lspDocumentMappingProvider is null)
            {
                throw new ArgumentNullException(nameof(lspDocumentMappingProvider));
            }

            if (textSnapshot == null)
            {
                throw new ArgumentNullException(nameof(textSnapshot));
            }

            if (documentSnapshot is null)
            {
                throw new ArgumentNullException(nameof(documentSnapshot));
            }

            _lspDocumentMappingProvider = lspDocumentMappingProvider;

            _textSnapshot     = textSnapshot;
            _documentSnapshot = documentSnapshot;
        }
        // Internal for testing
        internal static ImmutableArray <RazorMappedSpanResult> GetMappedSpanResults(
            LSPDocumentSnapshot documentSnapshot,
            SourceText sourceTextRazor,
            RazorMapToDocumentRangesResponse mappedResult)
        {
            var results = ImmutableArray.CreateBuilder <RazorMappedSpanResult>();

            if (mappedResult is null)
            {
                return(results.ToImmutable());
            }

            foreach (var mappedRange in mappedResult.Ranges)
            {
                if (Extensions.RangeExtensions.IsUndefined(mappedRange))
                {
                    // Couldn't remap the range correctly. Add default placeholder to indicate to C# that there were issues.
                    results.Add(new RazorMappedSpanResult());
                    continue;
                }

                var mappedSpan       = mappedRange.AsTextSpan(sourceTextRazor);
                var linePositionSpan = sourceTextRazor.Lines.GetLinePositionSpan(mappedSpan);
                var filePath         = documentSnapshot.Uri.LocalPath;
                results.Add(new RazorMappedSpanResult(filePath, linePositionSpan, mappedSpan));
            }

            return(results.ToImmutable());
        }
Esempio n. 3
0
        // Internal for testing
        public override void Changed(LSPDocumentSnapshot old, LSPDocumentSnapshot @new, VirtualDocumentSnapshot virtualOld, VirtualDocumentSnapshot virtualNew, LSPDocumentChangeKind kind)
        {
            // We need the below check to address a race condition between when a request is sent to the C# server
            // for a generated document and when the C# server receives a document/didOpen notification. This race
            // condition may occur when the Razor server finishes initializing before C# receives and processes the
            // document open request.
            // This workaround adds the Razor client name to the generated document so the C# server will recognize
            // it, despite the document not being formally opened. Note this is meant to only be a temporary
            // workaround until a longer-term solution is implemented in the future.
            if (kind == LSPDocumentChangeKind.Added && _dynamicFileInfoProvider is DefaultRazorDynamicFileInfoProvider defaultProvider)
            {
                defaultProvider.PromoteBackgroundDocument(@new.Uri, CSharpDocumentPropertiesService.Instance);
            }

            if (kind != LSPDocumentChangeKind.VirtualDocumentChanged)
            {
                return;
            }

            if (virtualNew is CSharpVirtualDocumentSnapshot)
            {
                var csharpContainer = new CSharpVirtualDocumentContainer(_lspDocumentMappingProvider, @new, virtualNew.Snapshot);
                _dynamicFileInfoProvider.UpdateLSPFileInfo(@new.Uri, csharpContainer);
            }
        }
Esempio n. 4
0
        public override LSPDocumentSnapshot UpdateVirtualDocument <TVirtualDocument>(IReadOnlyList <TextChange> changes, long hostDocumentVersion)
        {
            if (!TryGetVirtualDocument <TVirtualDocument>(out var virtualDocument))
            {
                throw new InvalidOperationException($"Cannot update virtual document of type {typeof(TVirtualDocument)} because LSP document {Uri} does not contain a virtual document of that type.");
            }

            virtualDocument.Update(changes, hostDocumentVersion);

            _currentSnapshot = UpdateSnapshot();

            return(CurrentSnapshot);
        }
 public LSPDocumentChangeEventArgs(
     LSPDocumentSnapshot old,
     LSPDocumentSnapshot @new,
     VirtualDocumentSnapshot virtualOld,
     VirtualDocumentSnapshot virtualNew,
     LSPDocumentChangeKind kind)
 {
     Old        = old;
     New        = @new;
     VirtualOld = virtualOld;
     VirtualNew = virtualNew;
     Kind       = kind;
 }
Esempio n. 6
0
        public override bool TryGetDocument(Uri uri, out LSPDocumentSnapshot lspDocumentSnapshot)
        {
            Debug.Assert(_joinableTaskContext.IsOnMainThread);

            if (!_documents.TryGetValue(uri, out var lspDocument))
            {
                // This should never happen in practice but return `null` so our tests can validate
                lspDocumentSnapshot = null;
                return(false);
            }

            lspDocumentSnapshot = lspDocument.CurrentSnapshot;
            return(true);
        }
        public CSharpDocumentExcerptService(
            IRazorSpanMappingService mappingService,
            LSPDocumentSnapshot documentSnapshot)
        {
            if (mappingService is null)
            {
                throw new ArgumentNullException(nameof(mappingService));
            }

            if (documentSnapshot is null)
            {
                throw new ArgumentNullException(nameof(documentSnapshot));
            }

            _mappingService   = mappingService;
            _documentSnapshot = documentSnapshot;
        }
        public async override Task <bool> TrySynchronizeVirtualDocumentAsync(LSPDocumentSnapshot document, VirtualDocumentSnapshot virtualDocument, CancellationToken cancellationToken)
        {
            if (document is null)
            {
                throw new ArgumentNullException(nameof(document));
            }

            if (virtualDocument is null)
            {
                throw new ArgumentNullException(nameof(virtualDocument));
            }

            if (!document.VirtualDocuments.Contains(virtualDocument))
            {
                throw new InvalidOperationException("Virtual document snapshot must belong to the provided LSP document snapshot.");
            }

            if (document.Version == virtualDocument.HostDocumentSyncVersion)
            {
                // Already synchronized
                return(true);
            }

            var synchronizingContext = _synchronizingContexts.AddOrUpdate(
                virtualDocument.Uri,
                (uri) => new DocumentSynchronizingContext(virtualDocument, document.Version, _synchronizationTimeout, cancellationToken),
                (uri, existingContext) =>
            {
                if (virtualDocument == existingContext.VirtualDocument &&
                    document.Version == existingContext.ExpectedHostDocumentVersion)
                {
                    // Already contain a synchronizing context that represents this request and it's in-process of being calculated.
                    return(existingContext);
                }

                // Cancel old request
                existingContext.SetSynchronized(false);
                return(new DocumentSynchronizingContext(virtualDocument, document.Version, _synchronizationTimeout, cancellationToken));
            });

            var result = await _joinableTaskFactory.RunAsync(() => synchronizingContext.OnSynchronizedAsync);

            _synchronizingContexts.TryRemove(virtualDocument.Uri, out _);

            return(result);
        }
            public CSharpVirtualDocumentContainer(LSPDocumentMappingProvider lspDocumentMappingProvider, LSPDocumentSnapshot documentSnapshot, ITextSnapshot textSnapshot)
            {
                if (lspDocumentMappingProvider is null)
                {
                    throw new ArgumentNullException(nameof(lspDocumentMappingProvider));
                }

                if (textSnapshot is null)
                {
                    throw new ArgumentNullException(nameof(textSnapshot));
                }

                if (documentSnapshot is null)
                {
                    throw new ArgumentNullException(nameof(documentSnapshot));
                }

                _lspDocumentMappingProvider = lspDocumentMappingProvider;

                _textSnapshot     = textSnapshot;
                _documentSnapshot = documentSnapshot;
            }
Esempio n. 10
0
            public void AddDocument(Uri uri, LSPDocumentSnapshot documentSnapshot)
            {
                _documents.Add(uri, documentSnapshot);

                Changed?.Invoke(this, null);
            }
Esempio n. 11
0
 public override bool TryGetDocument(Uri uri, out LSPDocumentSnapshot lspDocumentSnapshot)
 {
     return(_documents.TryGetValue(uri, out lspDocumentSnapshot));
 }
 public abstract Task <bool> TrySynchronizeVirtualDocumentAsync(LSPDocumentSnapshot document, VirtualDocumentSnapshot virtualDocument, CancellationToken cancellationToken);
Esempio n. 13
0
        private static void NotifyLSPDocumentAdded(LSPDocumentSnapshot lspDocument, DefaultLSPDocumentSynchronizer synchronizer)
        {
            var args = new LSPDocumentChangeEventArgs(old: null, @new: lspDocument, LSPDocumentChangeKind.Added);

            synchronizer.DocumentManager_Changed(sender: null, args);
        }
Esempio n. 14
0
        public static bool TryGetDocument(this LSPDocumentManager documentManager, string filePath, out LSPDocumentSnapshot lspDocumentSnapshot)
        {
            if (documentManager is null)
            {
                throw new ArgumentNullException(nameof(documentManager));
            }

            if (filePath is null)
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (filePath.StartsWith("/", StringComparison.Ordinal) && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                filePath = filePath.Substring(1);
            }

            var uri = new Uri(filePath, UriKind.Absolute);

            return(documentManager.TryGetDocument(uri, out lspDocumentSnapshot));
        }
 public LSPDocumentChangeEventArgs(LSPDocumentSnapshot old, LSPDocumentSnapshot @new, LSPDocumentChangeKind kind)
     : this(old, @new, virtualOld : null, virtualNew : null, kind)
 {
 }
Esempio n. 16
0
 public abstract bool TryGetDocument(Uri uri, out LSPDocumentSnapshot lspDocumentSnapshot);