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); }
/// <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); }