Esempio n. 1
0
        public int GetOffset(ISymUnmanagedDocument document, int line, int column, out int offset)
        {
            if (line <= 0)
            {
                offset = 0;
                return(HResult.E_INVALIDARG);
            }

            // Note that DiaSymReader completely ignores column parameter.

            var symDocument = SymReader.AsSymDocument(document);

            if (symDocument == null)
            {
                offset = 0;
                return(HResult.E_INVALIDARG);
            }

            // DiaSymReader uses DiaSession::findLinesByLinenum, which results in bad results for lines shared across multiple methods
            // and for lines outside of the current method.

            var documentHandle = symDocument.Handle;

            if (!SymReader.TryGetLineDeltas(GetId(), out var deltas))
            {
                deltas = default(MethodLineDeltas);
            }

            int sequencePointIndex = 0;

            foreach (var sp in GetSequencePoints())
            {
                if (!sp.IsHidden && sp.Document == documentHandle)
                {
                    int delta = deltas.GetDeltaForSequencePoint(sequencePointIndex);
                    if (line >= sp.StartLine + delta && line <= sp.EndLine + delta)
                    {
                        // Return the first matching IL offset. In common cases there will be a single one
                        // since sequence points of a single method don't overlap unless forced by #line.
                        offset = sp.Offset;
                        return(HResult.S_OK);
                    }
                }

                sequencePointIndex++;
            }

            offset = 0;
            return(HResult.E_FAIL);
        }
Esempio n. 2
0
        /// <summary>
        /// Get the line information associated with <paramref name="offset"/>.
        /// </summary>
        /// <remarks>
        /// If <paramref name="offset"/> is not a sequence point it is associated with the previous one.
        /// <paramref name="sequencePointOffset"/> provides the associated sequence point.
        /// </remarks>
        public int GetLineFromOffset(
            int offset,
            out int startLine,
            out int startColumn,
            out int endLine,
            out int endColumn,
            out int sequencePointOffset)
        {
            if (offset < 0)
            {
                offset = int.MaxValue;
            }

            var candidate      = default(SequencePoint);
            int candidateIndex = -1;

            int sequencePointIndex = 0;

            foreach (var sp in GetSequencePoints())
            {
                if (sp.Offset <= offset)
                {
                    candidate      = sp;
                    candidateIndex = sequencePointIndex;
                }
                else if (sp.Offset > offset)
                {
                    break;
                }

                sequencePointIndex++;
            }

            if (candidateIndex < 0)
            {
                startLine = startColumn = endLine = endColumn = sequencePointOffset = 0;
                return(HResult.E_FAIL);
            }

            int delta = !candidate.IsHidden && SymReader.TryGetLineDeltas(GetId(), out var deltas) ?
                        deltas.GetDeltaForSequencePoint(candidateIndex) : 0;

            startLine           = candidate.StartLine + delta;
            startColumn         = candidate.StartColumn;
            endLine             = candidate.EndLine + delta;
            endColumn           = candidate.EndColumn;
            sequencePointOffset = candidate.Offset;
            return(HResult.S_OK);
        }