protected AbstractDebuggerIntelliSenseContext(
     IWpfTextView wpfTextView,
     ITextBuffer contextBuffer,
     Microsoft.VisualStudio.TextManager.Interop.TextSpan[] currentStatementSpan,
     IComponentModel componentModel,
     IContentType contentType,
     bool isImmediateWindow
     )
 {
     _textView                           = wpfTextView;
     this.ContextBuffer                  = contextBuffer;
     this.CurrentStatementSpan           = currentStatementSpan[0];
     _contentType                        = contentType;
     this.ProjectionBufferFactoryService =
         componentModel.GetService <IProjectionBufferFactoryService>();
     _bufferGraphFactoryService = componentModel.GetService <IBufferGraphFactoryService>();
     _isImmediateWindow         = isImmediateWindow;
 }
 protected AbstractDebuggerIntelliSenseContext(
     IWpfTextView wpfTextView,
     IVsTextView vsTextView,
     IVsTextLines vsDebuggerTextLines,
     ITextBuffer contextBuffer,
     TextManager.Interop.TextSpan[] currentStatementSpan,
     IComponentModel componentModel,
     IServiceProvider serviceProvider,
     IContentType contentType)
 {
     _textView                           = wpfTextView;
     _debuggerTextLines                  = vsDebuggerTextLines;
     this.ContextBuffer                  = contextBuffer;
     this.CurrentStatementSpan           = currentStatementSpan[0];
     _contentType                        = contentType;
     _originalContentType                = _textView.TextBuffer.ContentType;
     this.ProjectionBufferFactoryService = componentModel.GetService <IProjectionBufferFactoryService>();
     _bufferGraphFactoryService          = componentModel.GetService <IBufferGraphFactoryService>();
     _isImmediateWindow                  = IsImmediateWindow((IVsUIShell)serviceProvider.GetService(typeof(SVsUIShell)), vsTextView);
 }
        private static bool TryAdjustSpanIfNeededForVenus(VisualStudioWorkspaceImpl workspace, DocumentId documentId, int originalLine, int originalColumn, out MappedSpan mappedSpan)
        {
            mappedSpan = default(MappedSpan);

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

            var containedDocument = workspace.GetHostDocument(documentId) as ContainedDocument;

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

            var originalSpanOnSecondaryBuffer = new TextManager.Interop.TextSpan()
            {
                iStartLine  = originalLine,
                iStartIndex = originalColumn,
                iEndLine    = originalLine,
                iEndIndex   = originalColumn
            };

            var containedLanguage     = containedDocument.ContainedLanguage;
            var bufferCoordinator     = containedLanguage.BufferCoordinator;
            var containedLanguageHost = containedLanguage.ContainedLanguageHost;

            var spansOnPrimaryBuffer = new TextManager.Interop.TextSpan[1];

            if (VSConstants.S_OK == bufferCoordinator.MapSecondaryToPrimarySpan(originalSpanOnSecondaryBuffer, spansOnPrimaryBuffer))
            {
                // easy case, we can map span in subject buffer to surface buffer. no need to adjust any span
                mappedSpan = new MappedSpan(originalLine, originalColumn, spansOnPrimaryBuffer[0].iStartLine, spansOnPrimaryBuffer[0].iStartIndex);
                return(true);
            }

            // we can't directly map span in subject buffer to surface buffer. see whether there is any visible span we can use from the subject buffer span
            if (containedLanguageHost != null &&
                VSConstants.S_OK != containedLanguageHost.GetNearestVisibleToken(originalSpanOnSecondaryBuffer, spansOnPrimaryBuffer))
            {
                // no visible span we can use.
                return(false);
            }

            // We need to map both the original and mapped location into visible code so that features such as error list, squiggle, etc. points to user visible area
            // We have the mapped location in the primary buffer.
            var nearestVisibleSpanOnPrimaryBuffer = new TextManager.Interop.TextSpan()
            {
                iStartLine  = spansOnPrimaryBuffer[0].iStartLine,
                iStartIndex = spansOnPrimaryBuffer[0].iStartIndex,
                iEndLine    = spansOnPrimaryBuffer[0].iStartLine,
                iEndIndex   = spansOnPrimaryBuffer[0].iStartIndex
            };

            // Map this location back to the secondary span to re-adjust the original location to be in user-code in secondary buffer.
            var spansOnSecondaryBuffer = new TextManager.Interop.TextSpan[1];

            if (VSConstants.S_OK != bufferCoordinator.MapPrimaryToSecondarySpan(nearestVisibleSpanOnPrimaryBuffer, spansOnSecondaryBuffer))
            {
                // we can't adjust original position but we can adjust mapped one
                mappedSpan = new MappedSpan(originalLine, originalColumn, nearestVisibleSpanOnPrimaryBuffer.iStartLine, nearestVisibleSpanOnPrimaryBuffer.iStartIndex);
                return(true);
            }

            var nearestVisibleSpanOnSecondaryBuffer = spansOnSecondaryBuffer[0];
            var originalLocationMovedAboveInFile    = IsOriginalLocationMovedAboveInFile(originalLine, originalColumn, nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex);

            if (!originalLocationMovedAboveInFile)
            {
                mappedSpan = new MappedSpan(nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex, nearestVisibleSpanOnPrimaryBuffer.iStartLine, nearestVisibleSpanOnPrimaryBuffer.iStartIndex);
                return(true);
            }

            LinePosition adjustedPosition;

            if (TryFixUpNearestVisibleSpan(containedLanguageHost, bufferCoordinator, nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex, out adjustedPosition))
            {
                // span has changed yet again, re-calculate span
                return(TryAdjustSpanIfNeededForVenus(workspace, documentId, adjustedPosition.Line, adjustedPosition.Character, out mappedSpan));
            }

            mappedSpan = new MappedSpan(nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex, nearestVisibleSpanOnPrimaryBuffer.iStartLine, nearestVisibleSpanOnPrimaryBuffer.iStartIndex);
            return(true);
        }
        private static bool TryAdjustSpanIfNeededForVenus(VisualStudioWorkspaceImpl workspace, DocumentId documentId, int originalLine, int originalColumn, out MappedSpan mappedSpan)
        {
            mappedSpan = default(MappedSpan);

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

            var containedDocument = workspace.GetHostDocument(documentId) as ContainedDocument;
            if (containedDocument == null)
            {
                return false;
            }

            var originalSpanOnSecondaryBuffer = new TextManager.Interop.TextSpan()
            {
                iStartLine = originalLine,
                iStartIndex = originalColumn,
                iEndLine = originalLine,
                iEndIndex = originalColumn
            };

            var containedLanguage = containedDocument.ContainedLanguage;
            var bufferCoordinator = containedLanguage.BufferCoordinator;
            var containedLanguageHost = containedLanguage.ContainedLanguageHost;

            var spansOnPrimaryBuffer = new TextManager.Interop.TextSpan[1];
            if (VSConstants.S_OK == bufferCoordinator.MapSecondaryToPrimarySpan(originalSpanOnSecondaryBuffer, spansOnPrimaryBuffer))
            {
                // easy case, we can map span in subject buffer to surface buffer. no need to adjust any span
                mappedSpan = new MappedSpan(originalLine, originalColumn, spansOnPrimaryBuffer[0].iStartLine, spansOnPrimaryBuffer[0].iStartIndex);
                return true;
            }

            // we can't directly map span in subject buffer to surface buffer. see whether there is any visible span we can use from the subject buffer span
            if (containedLanguageHost != null &&
                VSConstants.S_OK != containedLanguageHost.GetNearestVisibleToken(originalSpanOnSecondaryBuffer, spansOnPrimaryBuffer))
            {
                // no visible span we can use.
                return false;
            }

            // We need to map both the original and mapped location into visible code so that features such as error list, squiggle, etc. points to user visible area
            // We have the mapped location in the primary buffer.
            var nearestVisibleSpanOnPrimaryBuffer = new TextManager.Interop.TextSpan()
            {
                iStartLine = spansOnPrimaryBuffer[0].iStartLine,
                iStartIndex = spansOnPrimaryBuffer[0].iStartIndex,
                iEndLine = spansOnPrimaryBuffer[0].iStartLine,
                iEndIndex = spansOnPrimaryBuffer[0].iStartIndex
            };

            // Map this location back to the secondary span to re-adjust the original location to be in user-code in secondary buffer.
            var spansOnSecondaryBuffer = new TextManager.Interop.TextSpan[1];
            if (VSConstants.S_OK != bufferCoordinator.MapPrimaryToSecondarySpan(nearestVisibleSpanOnPrimaryBuffer, spansOnSecondaryBuffer))
            {
                // we can't adjust original position but we can adjust mapped one
                mappedSpan = new MappedSpan(originalLine, originalColumn, nearestVisibleSpanOnPrimaryBuffer.iStartLine, nearestVisibleSpanOnPrimaryBuffer.iStartIndex);
                return true;
            }

            var nearestVisibleSpanOnSecondaryBuffer = spansOnSecondaryBuffer[0];
            var originalLocationMovedAboveInFile = IsOriginalLocationMovedAboveInFile(originalLine, originalColumn, nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex);

            if (!originalLocationMovedAboveInFile)
            {
                mappedSpan = new MappedSpan(nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex, nearestVisibleSpanOnPrimaryBuffer.iStartLine, nearestVisibleSpanOnPrimaryBuffer.iStartIndex);
                return true;
            }

            if (TryFixUpNearestVisibleSpan(containedLanguageHost, bufferCoordinator, nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex, out var adjustedPosition))
            {
                // span has changed yet again, re-calculate span
                return TryAdjustSpanIfNeededForVenus(workspace, documentId, adjustedPosition.Line, adjustedPosition.Character, out mappedSpan);
            }

            mappedSpan = new MappedSpan(nearestVisibleSpanOnSecondaryBuffer.iStartLine, nearestVisibleSpanOnSecondaryBuffer.iStartIndex, nearestVisibleSpanOnPrimaryBuffer.iStartLine, nearestVisibleSpanOnPrimaryBuffer.iStartIndex);
            return true;
        }