Example #1
0
        /// <summary>
        /// Get all the sequence points, possibly mapping them using #line/ExternalSource directives, and mapping
        /// file names to debug documents with the given mapping function.
        /// </summary>
        /// <param name="documentProvider">Function that maps file paths to CCI debug documents</param>
        /// <param name="builder">where sequence points should be deposited</param>
        public void GetSequencePoints(
            DebugDocumentProvider documentProvider,
            ArrayBuilder <Cci.SequencePoint> builder)
        {
            bool   lastPathIsMapped = false;
            string lastPath         = null;

            Cci.DebugSourceDocument lastDebugDocument = null;

            FileLinePositionSpan?firstReal = FindFirstRealSequencePoint();

            if (!firstReal.HasValue)
            {
                return;
            }
            lastPath          = firstReal.Value.Path;
            lastPathIsMapped  = firstReal.Value.HasMappedPath;
            lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? this._tree.FilePath : null);

            SequencePointList current = this;

            while (current != null)
            {
                SyntaxTree currentTree = current._tree;

                foreach (var offsetAndSpan in current._points)
                {
                    TextSpan span = offsetAndSpan.Span;

                    // if it's a hidden sequence point, or a sequence point with syntax that points to a position that is inside
                    // of a hidden region (can be defined with #line hidden (C#) or implicitly by #ExternalSource (VB), make it
                    // a hidden sequence point.

                    bool isHidden = span == RawSequencePoint.HiddenSequencePointSpan;
                    FileLinePositionSpan fileLinePositionSpan = default;
                    if (!isHidden)
                    {
                        fileLinePositionSpan = currentTree.GetMappedLineSpanAndVisibility(span, out isHidden);
                    }

                    if (isHidden)
                    {
                        if (lastPath == null)
                        {
                            lastPath          = currentTree.FilePath;
                            lastDebugDocument = documentProvider(lastPath, basePath: null);
                        }

                        if (lastDebugDocument != null)
                        {
                            builder.Add(new Cci.SequencePoint(
                                            lastDebugDocument,
                                            offset: offsetAndSpan.Offset,
                                            startLine: Cci.SequencePoint.HiddenLine,
                                            startColumn: 0,
                                            endLine: Cci.SequencePoint.HiddenLine,
                                            endColumn: 0));
                        }
                    }
                    else
                    {
                        if (lastPath != fileLinePositionSpan.Path || lastPathIsMapped != fileLinePositionSpan.HasMappedPath)
                        {
                            lastPath          = fileLinePositionSpan.Path;
                            lastPathIsMapped  = fileLinePositionSpan.HasMappedPath;
                            lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? currentTree.FilePath : null);
                        }

                        if (lastDebugDocument != null)
                        {
                            int startLine   = (fileLinePositionSpan.StartLinePosition.Line == -1) ? 0 : fileLinePositionSpan.StartLinePosition.Line + 1;
                            int endLine     = (fileLinePositionSpan.EndLinePosition.Line == -1) ? 0 : fileLinePositionSpan.EndLinePosition.Line + 1;
                            int startColumn = fileLinePositionSpan.StartLinePosition.Character + 1;
                            int endColumn   = fileLinePositionSpan.EndLinePosition.Character + 1;

                            // Trim column number if necessary.
                            // Column must be in range [0, 0xffff) and end column must be greater than start column if on the same line.
                            // The Portable PDB specifies 0x10000, but StarkPlatform.Reflection.Metadata reader has an off-by-one error.
                            // Windows PDBs allow the same range.
                            const int MaxColumn = ushort.MaxValue - 1;

                            if (startColumn > MaxColumn)
                            {
                                startColumn = (startLine == endLine) ? MaxColumn - 1 : MaxColumn;
                            }

                            if (endColumn > MaxColumn)
                            {
                                endColumn = MaxColumn;
                            }

                            builder.Add(new Cci.SequencePoint(
                                            lastDebugDocument,
                                            offset: offsetAndSpan.Offset,
                                            startLine: startLine,
                                            startColumn: (ushort)startColumn,
                                            endLine: endLine,
                                            endColumn: (ushort)endColumn
                                            ));
                        }
                    }
                }

                current = current._next;
            }
        }
 internal int GetOrAddDocument(DebugSourceDocument document)
 {
     return(GetOrAddDocument(document, _documentIndex));
 }